]> mj.ucw.cz Git - pciutils.git/commitdiff
Merged more PCI Express updates.
authorMartin Mares <mj@ucw.cz>
Mon, 5 Jul 2004 15:41:26 +0000 (15:41 +0000)
committerMartin Mares <mj@ucw.cz>
Fri, 5 May 2006 12:18:22 +0000 (14:18 +0200)
git-archimport-id: mj@ucw.cz--public/pciutils--main--2.2--patch-53

ChangeLog
README
common.c
lib/header.h
lib/proc.c
lspci.c
lspci.man
pciutils.h

index 691e45913a7447d4892bf7b12b78adaa602bbd85..02b3a2ab82ca80cda999333c6d7ae89083285023 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2004-07-05  Martin Mares  <mj@ucw.cz>
+
+       * lspci.c (config_fetch): Wanted to merge Matthew's bug fix, but
+       ended up with rewriting the fetching mechanism to be fully dynamic,
+       but avoid reading config space registers not explicitly requested.
+
+2004-06-29  Matthew Wilcox <willy@debian.org>
+
+       * lspci.c: More work on PCI Express dumping.
+
+       * lib/header.h: Updated PCI Express capability definitions.
+
+       * lib/proc.c (proc_read): Removed bogus warning.
+
+       * common.c (xrealloc): Introduced.
+
+       * lspci.man: Added -xxxx.
+
 2004-06-27  Martin Mares  <mj@ucw.cz>
 
        * Released as 2.1.99-test6.
diff --git a/README b/README
index 9dd8dc6fc363601f9e5f1cd080b8dc58d908a62e..44f836a588fdf459249c165157fde57bed343774 100644 (file)
--- a/README
+++ b/README
@@ -15,6 +15,7 @@ Some more things I intend to merge before the 2.2.0 release:
 
    o  pcimodules and possibly other Linux module related stuff
    o  New ID's from the pciids project
+   o  Avoid calling show_ext_caps() for non-ext devices.
 
 ############################################################################
 
index a8d39d52f73ede2c225188efdc0637fb99ee6d2f..9181e4e14ddcd55a4335b94abf44618662d207da 100644 (file)
--- a/common.c
+++ b/common.c
@@ -35,6 +35,15 @@ xmalloc(unsigned int howmuch)
   return p;
 }
 
+void *
+xrealloc(void *ptr, unsigned int howmuch)
+{
+  void *p = realloc(ptr, howmuch);
+  if (!p)
+    die("Unable to allocate %d bytes of memory", howmuch);
+  return p;
+}
+
 int
 parse_generic_option(int i, struct pci_access *pacc, char *optarg)
 {
index 9d7643a200d46214c7067942e4a7a288e67be890..54b845dfdd1dfb0986b075565c415188351be5e8 100644 (file)
 #define  PCI_EXP_DEVCAP_ATN_BUT        0x1000  /* Attention Button Present */
 #define  PCI_EXP_DEVCAP_ATN_IND        0x2000  /* Attention Indicator Present */
 #define  PCI_EXP_DEVCAP_PWR_IND        0x4000  /* Power Indicator Present */
-#define  PCI_EXP_DEVCAP_READRQ 0x38000 /* Max_Read_Request_Size */
 #define  PCI_EXP_DEVCAP_PWR_VAL        0x3fc0000 /* Slot Power Limit Value */
 #define  PCI_EXP_DEVCAP_PWR_SCL        0xc000000 /* Slot Power Limit Scale */
 #define PCI_EXP_DEVCTL         0x8     /* Device Control */
 #define  PCI_EXP_DEVCTL_NFERE  0x0002  /* Non-Fatal Error Reporting Enable */
 #define  PCI_EXP_DEVCTL_FERE   0x0004  /* Fatal Error Reporting Enable */
 #define  PCI_EXP_DEVCTL_URRE   0x0008  /* Unsupported Request Reporting En. */
-#define  PCI_EXP_DEVCTL_URS    0x0010  /* Unsupported Request Severity */
+#define  PCI_EXP_DEVCTL_RELAXED        0x0010  /* Enable Relaxed Ordering */
 #define  PCI_EXP_DEVCTL_PAYLOAD        0x00e0  /* Max_Payload_Size */
 #define  PCI_EXP_DEVCTL_EXT_TAG        0x0100  /* Extended Tag Field Enable */
 #define  PCI_EXP_DEVCTL_PHANTOM        0x0200  /* Phantom Functions Enable */
 #define  PCI_EXP_DEVCTL_AUX_PME        0x0400  /* Auxiliary Power PM Enable */
-#define  PCI_EXP_DEVCTL_STOP   0x0800  /* Complete Pending Transactions */
+#define  PCI_EXP_DEVCTL_NOSNOOP        0x0800  /* Enable No Snoop */
 #define  PCI_EXP_DEVCTL_READRQ 0x7000  /* Max_Read_Request_Size */
 #define PCI_EXP_DEVSTA         0xa     /* Device Status */
 #define  PCI_EXP_DEVSTA_CED    0x01    /* Correctable Error Detected */
 #define  PCI_EXP_DEVSTA_AUXPD  0x10    /* AUX Power Detected */
 #define  PCI_EXP_DEVSTA_TRPND  0x20    /* Transactions Pending */
 #define PCI_EXP_LNKCAP         0xc     /* Link Capabilities */
+#define  PCI_EXP_LNKCAP_SPEED  0x0000f /* Maximum Link Speed */
+#define  PCI_EXP_LNKCAP_WIDTH  0x003f0 /* Maximum Link Width */
+#define  PCI_EXP_LNKCAP_ASPM   0x00c00 /* Active State Power Management */
+#define  PCI_EXP_LNKCAP_L0S    0x07000 /* L0s Acceptable Latency */
+#define  PCI_EXP_LNKCAP_L1     0x38000 /* L1 Acceptable Latency */
+#define  PCI_EXP_LNKCAP_PORT   0xff000000 /* Port Number */
 #define PCI_EXP_LNKCTL         0x10    /* Link Control */
+#define  PCI_EXP_LNKCTL_ASPM   0x0003  /* ASPM Control */
+#define  PCI_EXP_LNKCTL_RCB    0x0008  /* Read Completion Boundary */
+#define  PCI_EXP_LNKCTL_DISABLE        0x0010  /* Link Disable */
+#define  PCI_EXP_LNKCTL_RETRAIN        0x0020  /* Retrain Link */
+#define  PCI_EXP_LNKCTL_CLOCK  0x0040  /* Common Clock Configuration */
+#define  PCI_EXP_LNKCTL_XSYNCH 0x0080  /* Extended Synch */
 #define PCI_EXP_LNKSTA         0x12    /* Link Status */
+#define  PCI_EXP_LNKSTA_SPEED  0x000f  /* Negotiated Link Speed */
+#define  PCI_EXP_LNKSTA_WIDTH  0x03f0  /* Negotiated Link Width */
+#define  PCI_EXP_LNKSTA_TR_ERR 0x0400  /* Training Error */
+#define  PCI_EXP_LNKSTA_TRAIN  0x0800  /* Link Training */
+#define  PCI_EXP_LNKSTA_SL_CLK 0x1000  /* Slot Clock Configuration */
 #define PCI_EXP_SLTCAP         0x14    /* Slot Capabilities */
+#define  PCI_EXP_SLTCAP_ATNB   0x0001  /* Attention Button Present */
+#define  PCI_EXP_SLTCAP_PWRC   0x0002  /* Power Controller Present */
+#define  PCI_EXP_SLTCAP_MRL    0x0004  /* MRL Sensor Present */
+#define  PCI_EXP_SLTCAP_ATNI   0x0008  /* Attention Indicator Present */
+#define  PCI_EXP_SLTCAP_PWRI   0x0010  /* Power Indicator Present */
+#define  PCI_EXP_SLTCAP_HPS    0x0020  /* Hot-Plug Surprise */
+#define  PCI_EXP_SLTCAP_HPC    0x0040  /* Hot-Plug Capable */
+#define  PCI_EXP_SLTCAP_PWR_VAL        0x00007f80 /* Slot Power Limit Value */
+#define  PCI_EXP_SLTCAP_PWR_SCL        0x00018000 /* Slot Power Limit Scale */
+#define  PCI_EXP_SLTCAP_PSN    0xfff80000 /* Physical Slot Number */
 #define PCI_EXP_SLTCTL         0x18    /* Slot Control */
+#define  PCI_EXP_SLTCTL_ATNB   0x0001  /* Attention Button Pressed Enable */
+#define  PCI_EXP_SLTCTL_PWRF   0x0002  /* Power Fault Detected Enable */
+#define  PCI_EXP_SLTCTL_MRLS   0x0004  /* MRL Sensor Changed Enable */
+#define  PCI_EXP_SLTCTL_PRSD   0x0008  /* Presence Detect Changed Enable */
+#define  PCI_EXP_SLTCTL_CMDC   0x0010  /* Command Completed Interrupt Enable */
+#define  PCI_EXP_SLTCTL_HPIE   0x0020  /* Hot-Plug Interrupt Enable */
+#define  PCI_EXP_SLTCTL_ATNI   0x00C0  /* Attention Indicator Control */
+#define  PCI_EXP_SLTCTL_PWRI   0x0300  /* Power Indicator Control */
+#define  PCI_EXP_SLTCTL_PWRC   0x0400  /* Power Controller Control */
 #define PCI_EXP_SLTSTA         0x1a    /* Slot Status */
 #define PCI_EXP_RTCTL          0x1c    /* Root Control */
+#define  PCI_EXP_RTCTL_SECEE   0x1     /* System Error on Correctable Error */
+#define  PCI_EXP_RTCTL_SENFEE  0x1     /* System Error on Non-Fatal Error */
+#define  PCI_EXP_RTCTL_SEFEE   0x1     /* System Error on Fatal Error */
+#define  PCI_EXP_RTCTL_PMEIE   0x1     /* PME Interrupt Enable */
 #define PCI_EXP_RTSTA          0x20    /* Root Status */
 
 /* MSI-X */
index 9d02b4107d5dc9781c2b4bb10556c63d0ecce655..ebc66e4c9e200b1b92f395170da1244bad98a482 100644 (file)
@@ -153,7 +153,7 @@ proc_read(struct pci_dev *d, int pos, byte *buf, int len)
       return 0;
     }
   else if (res != len)
-    d->access->warning("proc_read: tried to read %d bytes at %d, but got only %d", len, pos, res);
+    return 0;
   return 1;
 }
 
diff --git a/lspci.c b/lspci.c
index 6d89e912f9becf350822af66b88f2345549abc0b..dec904d4ccbdc5c840e5633197fae904c4cecb30 100644 (file)
--- a/lspci.c
+++ b/lspci.c
@@ -63,12 +63,31 @@ static struct pci_access *pacc;
 struct device {
   struct device *next;
   struct pci_dev *dev;
-  unsigned int config_cnt;
-  byte config[256];
+  unsigned int config_cnt, config_bufsize;
+  byte *config;
 };
 
 static struct device *first_dev;
 
+static int
+config_fetch(struct device *d, unsigned int pos, unsigned int len)
+{
+  unsigned int end = pos+len;
+  int result;
+  if (end <= d->config_cnt)
+    return 1;
+  if (end > d->config_bufsize)
+    {
+      while (end > d->config_bufsize)
+       d->config_bufsize *= 2;
+      d->config = xrealloc(d->config, d->config_bufsize);
+    }
+  result = pci_read_block(d->dev, pos, d->config + pos, len);
+  if (result && pos == d->config_cnt)
+    d->config_cnt = end;
+  return result;
+}
+
 static struct device *
 scan_device(struct pci_dev *p)
 {
@@ -79,15 +98,16 @@ scan_device(struct pci_dev *p)
   d = xmalloc(sizeof(struct device));
   bzero(d, sizeof(*d));
   d->dev = p;
-  d->config_cnt = 64;
+  d->config_cnt = d->config_bufsize = 64;
+  d->config = xmalloc(64);
   if (!pci_read_block(p, 0, d->config, 64))
     die("Unable to read the configuration space header.");
   if ((d->config[PCI_HEADER_TYPE] & 0x7f) == PCI_HEADER_TYPE_CARDBUS)
     {
-      /* For cardbus bridges, we need to fetch 64 bytes more to get the full standard header... */
-      if (!pci_read_block(p, 64, d->config+64, 64))
+      /* For cardbus bridges, we need to fetch 64 bytes more to get the
+       * full standard header... */
+      if (!config_fetch(d, 64, 64))
        die("Unable to read cardbus bridge extension data.");
-      d->config_cnt = 128;
     }
   pci_setup_cache(p, d->config, d->config_cnt);
   pci_fill_info(p, PCI_FILL_IDENT | PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES);
@@ -109,14 +129,6 @@ scan_devices(void)
       }
 }
 
-static int
-config_fetch(struct device *d, unsigned int pos, unsigned int len)
-{
-  if (pos + len < d->config_cnt)
-    return 1;
-  return pci_read_block(d->dev, pos, d->config + pos, len);
-}
-
 /* Config space accesses */
 
 static inline byte
@@ -921,16 +933,172 @@ static void show_debug(void)
 
 static float power_limit(int value, int scale)
 {
-  float scales[4] = { 1.0, 0.1, 0.01, 0.001 };
+  static const float scales[4] = { 1.0, 0.1, 0.01, 0.001 };
   return value * scales[scale];
 }
 
-static void
-show_express(struct device *d, int where, int cap)
+static const char *latency_l0s(int value)
+{
+  static const char *latencies[] = { "<64ns", "<128ns", "<256ns", "<512ns", "<1us", "<2us", "<4us", "unlimited" };
+  return latencies[value];
+}
+
+static const char *latency_l1(int value)
+{
+  static const char *latencies[] = { "<1us", "<2us", "<4us", "<8us", "<16us", "<32us", "<64us", "unlimited" };
+  return latencies[value];
+}
+
+static void show_express_dev(struct device *d, int where, int type)
+{
+  u32 t;
+  u16 w;
+
+  t = get_conf_long(d, where + PCI_EXP_DEVCAP);
+  printf("\t\tDevice: Supported: MaxPayload %d bytes, PhantFunc %d, ExtTag%c\n",
+       128 << (t & PCI_EXP_DEVCAP_PAYLOAD),
+       (1 << ((t & PCI_EXP_DEVCAP_PHANTOM) >> 3)) - 1,
+       FLAG(t, PCI_EXP_DEVCAP_EXT_TAG));
+  printf("\t\tDevice: Latency L0s %s, L1 %s\n",
+       latency_l0s((t & PCI_EXP_DEVCAP_L0S) >> 6),
+       latency_l1((t & PCI_EXP_DEVCAP_L1) >> 9));
+  if ((type == PCI_EXP_TYPE_ENDPOINT) || (type == PCI_EXP_TYPE_LEG_END) ||
+      (type == PCI_EXP_TYPE_UPSTREAM) || (type == PCI_EXP_TYPE_PCI_BRIDGE))
+    printf("\t\tDevice: AtnBtn%c AtnInd%c PwrInd%c\n",
+       FLAG(t, PCI_EXP_DEVCAP_ATN_BUT),
+       FLAG(t, PCI_EXP_DEVCAP_ATN_IND), FLAG(t, PCI_EXP_DEVCAP_PWR_IND));
+  if (type == PCI_EXP_TYPE_UPSTREAM)
+    printf("\t\tDevice: SlotPowerLimit %f\n",
+       power_limit((t & PCI_EXP_DEVCAP_PWR_VAL) >> 18,
+                   (t & PCI_EXP_DEVCAP_PWR_SCL) >> 26));
+
+  w = get_conf_word(d, where + PCI_EXP_DEVCTL);
+  printf("\t\tDevice: Errors: Correctable%c Non-Fatal%c Fatal%c Unsupported%c\n",
+       FLAG(w, PCI_EXP_DEVCTL_CERE), 
+       FLAG(w, PCI_EXP_DEVCTL_NFERE), 
+       FLAG(w, PCI_EXP_DEVCTL_FERE), 
+       FLAG(w, PCI_EXP_DEVCTL_URRE));
+  printf("\t\tDevice: RlxdOrd%c ExtTag%c PhantFunc%c AuxPwr%c NoSnoop%c\n",
+       FLAG(w, PCI_EXP_DEVCTL_RELAXED),
+       FLAG(w, PCI_EXP_DEVCTL_EXT_TAG),
+       FLAG(w, PCI_EXP_DEVCTL_PHANTOM),
+       FLAG(w, PCI_EXP_DEVCTL_AUX_PME),
+       FLAG(w, PCI_EXP_DEVCTL_NOSNOOP));
+  printf("\t\tDevice: MaxPayload %d bytes, MaxReadReq %d bytes\n",
+       128 << ((w & PCI_EXP_DEVCTL_PAYLOAD) >> 5),
+       128 << ((w & PCI_EXP_DEVCTL_READRQ) >> 12));
+}
+
+static char *link_speed(int speed)
+{
+  switch (speed)
+    {
+      case 1:
+       return "2.5Gb/s";
+      default:
+       return "unknown";
+    }
+}
+
+static char *aspm_support(int code)
+{
+  switch (code)
+    {
+      case 1:
+       return "L0s";
+      case 3:
+       return "L0s L1";
+      default:
+       return "unknown";
+    }
+}
+
+static const char *aspm_enabled(int code)
+{
+  static const char *desc[] = { "Disabled", "L0s Enabled", "L1 Enabled", "L0s L1 Enabled" };
+  return desc[code];
+}
+
+static void show_express_link(struct device *d, int where, int type)
 {
   u32 t;
   u16 w;
+
+  t = get_conf_long(d, where + PCI_EXP_LNKCAP);
+  printf("\t\tLink: Supported Speed %s, Width x%d, ASPM %s, Port %d\n",
+       link_speed(t & PCI_EXP_LNKCAP_SPEED), (t & PCI_EXP_LNKCAP_WIDTH) >> 4,
+       aspm_support((t & PCI_EXP_LNKCAP_ASPM) >> 10),
+       t >> 24);
+  printf("\t\tLink: Latency L0s %s, L1 %s\n",
+       latency_l0s((t & PCI_EXP_LNKCAP_L0S) >> 12),
+       latency_l1((t & PCI_EXP_LNKCAP_L1) >> 15));
+  w = get_conf_word(d, where + PCI_EXP_LNKCTL);
+  printf("\t\tLink: ASPM %s", aspm_enabled(w & PCI_EXP_LNKCTL_ASPM));
+  if ((type == PCI_EXP_TYPE_ROOT_PORT) || (type == PCI_EXP_TYPE_ENDPOINT) ||
+      (type == PCI_EXP_TYPE_LEG_END))
+    printf(" RCB %d bytes", w & PCI_EXP_LNKCTL_RCB ? 128 : 64);
+  if (w & PCI_EXP_LNKCTL_DISABLE)
+    printf(" Disabled");
+  printf(" CommClk%c ExtSynch%c\n", FLAG(w, PCI_EXP_LNKCTL_CLOCK),
+       FLAG(w, PCI_EXP_LNKCTL_XSYNCH));
+  w = get_conf_word(d, where + PCI_EXP_LNKSTA);
+  printf("\t\tLink: Speed %s, Width x%d\n",
+       link_speed(t & PCI_EXP_LNKSTA_SPEED), (t & PCI_EXP_LNKSTA_WIDTH) >> 4);
+}
+
+static const char *indicator(int code)
+{
+  static const char *names[] = { "Unknown", "On", "Blink", "Off" };
+  return names[code];
+}
+
+static void show_express_slot(struct device *d, int where)
+{
+  u32 t;
+  u16 w;
+
+  t = get_conf_long(d, where + PCI_EXP_SLTCAP);
+  printf("\t\tSlot: AtnBtn%c PwrCtrl%c MRL%c AtnInd%c PwrInd%c HotPlug%c Surpise%c\n",
+       FLAG(t, PCI_EXP_SLTCAP_ATNB),
+       FLAG(t, PCI_EXP_SLTCAP_PWRC),
+       FLAG(t, PCI_EXP_SLTCAP_MRL),
+       FLAG(t, PCI_EXP_SLTCAP_ATNI),
+       FLAG(t, PCI_EXP_SLTCAP_PWRI),
+       FLAG(t, PCI_EXP_SLTCAP_HPC),
+       FLAG(t, PCI_EXP_SLTCAP_HPS));
+  printf("\t\tSlot: Number %d, PowerLimit %f\n", t >> 19,
+               power_limit((t & PCI_EXP_SLTCAP_PWR_VAL) >> 7,
+                       (t & PCI_EXP_SLTCAP_PWR_SCL) >> 15));
+  w = get_conf_word(d, where + PCI_EXP_SLTCTL);
+  printf("\t\tSlot: Enabled AtnBtn%c PwrFlt%c MRL%c PresDet%c CmdCplt%c HPIrq%c\n",
+       FLAG(w, PCI_EXP_SLTCTL_ATNB),
+       FLAG(w, PCI_EXP_SLTCTL_PWRF),
+       FLAG(w, PCI_EXP_SLTCTL_MRLS),
+       FLAG(w, PCI_EXP_SLTCTL_PRSD),
+       FLAG(w, PCI_EXP_SLTCTL_CMDC),
+       FLAG(w, PCI_EXP_SLTCTL_HPIE));
+  printf("\t\tSlot: AttnInd %s, PwrInd %s, Power%c\n",
+       indicator((w & PCI_EXP_SLTCTL_ATNI) >> 6),
+       indicator((w & PCI_EXP_SLTCTL_PWRI) >> 8),
+       FLAG(w, w & PCI_EXP_SLTCTL_PWRC));
+}
+
+static void show_express_root(struct device *d, int where)
+{
+  u16 w = get_conf_word(d, where + PCI_EXP_RTCTL);
+  printf("\t\tRoot: Correctable%c Non-Fatal%c Fatal%c PME%c\n",
+       FLAG(w, PCI_EXP_RTCTL_SECEE),
+       FLAG(w, PCI_EXP_RTCTL_SENFEE),
+       FLAG(w, PCI_EXP_RTCTL_SEFEE),
+       FLAG(w, PCI_EXP_RTCTL_PMEIE));
+}
+
+static void
+show_express(struct device *d, int where, int cap)
+{
   int type = (cap & PCI_EXP_FLAGS_TYPE) >> 4;
+  int size;
+  int slot = 0;
 
   printf("Express ");
   switch (type)
@@ -942,16 +1110,18 @@ show_express(struct device *d, int where, int cap)
       printf("Legacy Endpoint");
       break;
     case PCI_EXP_TYPE_ROOT_PORT:
+      slot = cap & PCI_EXP_FLAGS_SLOT;
       printf("Root Port (Slot%c)", FLAG(cap, PCI_EXP_FLAGS_SLOT));
       break;
     case PCI_EXP_TYPE_UPSTREAM:
       printf("Upstream Port");
       break;
     case PCI_EXP_TYPE_DOWNSTREAM:
+      slot = cap & PCI_EXP_FLAGS_SLOT;
       printf("Downstream Port (Slot%c)", FLAG(cap, PCI_EXP_FLAGS_SLOT));
       break;
     case PCI_EXP_TYPE_PCI_BRIDGE:
-      printf("PCI Bridge");
+      printf("PCI/PCI-X Bridge");
       break;
     default:
       printf("Unknown type");
@@ -960,28 +1130,20 @@ show_express(struct device *d, int where, int cap)
   if (verbose < 2)
     return;
 
-  t = get_conf_long(d, where + PCI_EXP_DEVCAP);
-  printf("\t\tMaxPayloadSizeSupported %d\n", 128 << (t & PCI_EXP_DEVCAP_PAYLOAD));
-  printf("\t\tPhantomFunctions %d\n", 1 << ((t & PCI_EXP_DEVCAP_PHANTOM) >> 3));
-  printf("\t\tExtendedTags%c\n", FLAG(t, PCI_EXP_DEVCAP_EXT_TAG));
-  printf("\t\tL0sLatency <%dns\n", 64 << ((t & PCI_EXP_DEVCAP_L0S) >> 6));
-  printf("\t\tL1Latency <%dus\n", 1 << ((t & PCI_EXP_DEVCAP_L1) >> 9));
-  if ((type == PCI_EXP_TYPE_ENDPOINT) || (type == PCI_EXP_TYPE_LEG_END))
-    printf("\t\tAtnBtn%c AtnInd%c PwrInd%c\n", FLAG(t, PCI_EXP_DEVCAP_ATN_BUT),
-       FLAG(t, PCI_EXP_DEVCAP_ATN_IND), FLAG(t, PCI_EXP_DEVCAP_PWR_IND));
+  size = 16;
+  if (slot)
+    size = 24;
   if (type == PCI_EXP_TYPE_ROOT_PORT)
-    printf("\t\tMaxReadRequestSizeSupported %d\n", 128 << ((t & PCI_EXP_DEVCAP_READRQ) >> 15));
-  if (type == PCI_EXP_TYPE_UPSTREAM)
-    printf("\t\tSlotPowerLimit %f\n",
-       power_limit((t & PCI_EXP_DEVCAP_PWR_VAL) >> 18,
-                   (t & PCI_EXP_DEVCAP_PWR_SCL) >> 26));
+    size = 32;
+  if (!config_fetch(d, where + PCI_EXP_DEVCAP, size))
+    return;
 
-  w = get_conf_word(d, where + PCI_EXP_DEVCTL);
-  printf("\t\tError Reporting: Correctable%c Non-Fatal%c Fatal%c Unsupported%c\n",
-       FLAG(w, PCI_EXP_DEVCTL_CERE), 
-       FLAG(w, PCI_EXP_DEVCTL_NFERE), 
-       FLAG(w, PCI_EXP_DEVCTL_FERE), 
-       FLAG(w, PCI_EXP_DEVCTL_URRE));
+  show_express_dev(d, where, type);
+  show_express_link(d, where, type);
+  if (slot)
+    show_express_slot(d, where);
+  if (type == PCI_EXP_TYPE_ROOT_PORT)
+    show_express_root(d, where);
 }
 
 static void
@@ -1016,6 +1178,75 @@ show_slotid(int cap)
         chs);
 }
 
+static void
+show_aer(struct device *d, int where)
+{
+  printf("Advanced Error Reporting\n");
+}
+
+static void
+show_vc(struct device *d, int where)
+{
+  printf("Virtual Channel\n");
+}
+
+static void
+show_dsn(struct device *d, int where)
+{
+  u32 t1, t2;
+  if (!config_fetch(d, where + 4, 8))
+    return;
+  t1 = get_conf_long(d, where + 4);
+  t2 = get_conf_long(d, where + 8);
+  printf("Device Serial Number %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n",
+       t1 & 0xff, (t1 >> 8) & 0xff, (t1 >> 16) & 0xff, t1 >> 24,
+       t2 & 0xff, (t2 >> 8) & 0xff, (t2 >> 16) & 0xff, t2 >> 24);
+}
+
+static void
+show_pb(struct device *d, int where)
+{
+  printf("Power Budgeting\n");
+}
+
+static void
+show_ext_caps(struct device *d)
+{
+  int where = 0x100;
+  do
+    {
+      u32 header;
+      int id;
+
+      if (!config_fetch(d, where, 4))
+       break;
+      header = get_conf_long(d, where);
+      if (!header)
+       break;
+      id = header & 0xffff;
+      printf("\tCapabilities: [%03x] ", where);
+      switch (id)
+       {
+         case PCI_EXT_CAP_ID_AER:
+           show_aer(d, where);
+           break;
+         case PCI_EXT_CAP_ID_VC:
+           show_vc(d, where);
+           break;
+         case PCI_EXT_CAP_ID_DSN:
+           show_dsn(d, where);
+           break;
+         case PCI_EXT_CAP_ID_PB:
+           show_pb(d, where);
+           break;
+         default:
+           printf("Unknown (%d)\n", id);
+           break;
+       }
+      where = header >> 20;
+    } while (where);
+}
+
 static void
 show_caps(struct device *d)
 {
@@ -1081,6 +1312,7 @@ show_caps(struct device *d)
          where = next;
        }
     }
+  show_ext_caps(d);
 }
 
 static void
index 58cfbd7811281e9fbb39500bf178b566497e4dc6..a5112d2ff701c52ad0d34a99ae6e1d906a02cc22 100644 (file)
--- a/lspci.man
+++ b/lspci.man
@@ -47,6 +47,9 @@ as several PCI devices
 when you try to read undefined portions of the config space (this behavior probably
 doesn't violate the PCI standard, but it's at least very stupid).
 .TP
+.B -xxxx
+Show hexadecimal dump of the extended PCI configuration space.
+.TP
 .B -b
 Bus-centric view. Show all IRQ numbers and addresses as seen by the cards on the
 PCI bus instead of as seen by the kernel.
index 31a4ce1b2d25bdc445b9948d78c72293c78cc521..dcedbe683f256404962b134cf66c24d0bac093b2 100644 (file)
@@ -19,6 +19,7 @@
 
 void die(char *msg, ...) NONRET;
 void *xmalloc(unsigned int howmuch);
+void *xrealloc(void *ptr, unsigned int howmuch);
 int parse_generic_option(int i, struct pci_access *pacc, char *optarg);
 
 #ifdef HAVE_PM_LINUX_PROC