]> mj.ucw.cz Git - pciutils.git/blobdiff - lspci.c
Add basic support for AGP3 fields.
[pciutils.git] / lspci.c
diff --git a/lspci.c b/lspci.c
index 6b9b982a444e13a27b7aa6743b924a8c00ae1aa4..14825a8969cab5f8ed2363082df57d1be71dc308 100644 (file)
--- a/lspci.c
+++ b/lspci.c
@@ -1,9 +1,9 @@
 /*
- *     $Id: lspci.c,v 1.39 2002/03/24 12:24:34 mj Exp $
+ *     $Id: lspci.c,v 1.43 2002/12/26 20:24:50 mj Exp $
  *
  *     Linux PCI Utilities -- List All PCI Devices
  *
- *     Copyright (c) 1997--1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ *     Copyright (c) 1997--2002 Martin Mares <mj@ucw.cz>
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
  */
@@ -34,7 +34,8 @@ Usage: lspci [<switches>]\n\
 -v\t\tBe verbose\n\
 -n\t\tShow numeric ID's\n\
 -b\t\tBus-centric view (PCI addresses and IRQ's instead of those seen by the CPU)\n\
--x\t\tShow hex-dump of config space\n\
+-x\t\tShow hex-dump of the standard portion of config space\n\
+-xxx\t\tShow hex-dump of the whole config space (dangerous; root only)\n\
 -s [[<bus>]:][<slot>][.[<func>]]\tShow only devices in selected slots\n\
 -d [<vendor>]:[<device>]\tShow only selected devices\n\
 -t\t\tShow bus tree\n\
@@ -408,7 +409,7 @@ show_pm(struct device *d, int where, int cap)
 }
 
 static void
-format_agp_rate(int rate, char *buf)
+format_agp_rate(int rate, char *buf, int agp3)
 {
   char *c = buf;
   int i;
@@ -419,7 +420,7 @@ format_agp_rate(int rate, char *buf)
        if (c != buf)
          *c++ = ',';
        *c++ = 'x';
-       *c++ = '0' + (1 << i);
+       *c++ = '0' + (1 << (i + 2*agp3));
       }
   if (c != buf)
     *c = 0;
@@ -432,31 +433,126 @@ show_agp(struct device *d, int where, int cap)
 {
   u32 t;
   char rate[8];
+  int ver, rev;
+  int agp3 = 0;
 
-  t = cap & 0xff;
-  printf("AGP version %x.%x\n", cap/16, cap%16);
+  ver = (cap >> 4) & 0x0f;
+  rev = cap & 0x0f;
+  printf("AGP version %x.%x\n", ver, rev);
   if (verbose < 2)
     return;
   config_fetch(d, where + PCI_AGP_STATUS, PCI_AGP_SIZEOF - PCI_AGP_STATUS);
   t = get_conf_long(d, where + PCI_AGP_STATUS);
-  format_agp_rate(t & 7, rate);
-  printf("\t\tStatus: RQ=%d SBA%c 64bit%c FW%c Rate=%s\n",
-        (t & PCI_AGP_STATUS_RQ_MASK) >> 24U,
+  if (ver >= 3 && (t & PCI_AGP_STATUS_AGP3))
+    agp3 = 1;
+  format_agp_rate(t & 7, rate, agp3);
+  printf("\t\tStatus: RQ=%d Iso%c ArqSz=%d Cal=%d SBA%c ITACoh%c GART64%c HTrans%c 64bit%c FW%c AGP3%c Rate=%s\n",
+        ((t & PCI_AGP_STATUS_RQ_MASK) >> 24U) + 1,
+        FLAG(t, PCI_AGP_STATUS_ISOCH),
+        ((t & PCI_AGP_STATUS_ARQSZ_MASK) >> 13),
+        ((t & PCI_AGP_STATUS_CAL_MASK) >> 10),
         FLAG(t, PCI_AGP_STATUS_SBA),
+        FLAG(t, PCI_AGP_STATUS_ITA_COH),
+        FLAG(t, PCI_AGP_STATUS_GART64),
+        FLAG(t, PCI_AGP_STATUS_HTRANS),
         FLAG(t, PCI_AGP_STATUS_64BIT),
         FLAG(t, PCI_AGP_STATUS_FW),
+        FLAG(t, PCI_AGP_STATUS_AGP3),
         rate);
   t = get_conf_long(d, where + PCI_AGP_COMMAND);
-  format_agp_rate(t & 7, rate);
-  printf("\t\tCommand: RQ=%d SBA%c AGP%c 64bit%c FW%c Rate=%s\n",
-        (t & PCI_AGP_COMMAND_RQ_MASK) >> 24U,
+  format_agp_rate(t & 7, rate, agp3);
+  printf("\t\tCommand: RQ=%d ArqSz=%d Cal=%d SBA%c AGP%c GART64%c 64bit%c FW%c Rate=%s\n",
+        ((t & PCI_AGP_COMMAND_RQ_MASK) >> 24U) + 1,
+        ((t & PCI_AGP_COMMAND_ARQSZ_MASK) >> 13),
+        ((t & PCI_AGP_COMMAND_CAL_MASK) >> 10),
         FLAG(t, PCI_AGP_COMMAND_SBA),
         FLAG(t, PCI_AGP_COMMAND_AGP),
+        FLAG(t, PCI_AGP_COMMAND_GART64),
         FLAG(t, PCI_AGP_COMMAND_64BIT),
         FLAG(t, PCI_AGP_COMMAND_FW),
         rate);
 }
 
+static void
+show_pcix_nobridge(struct device *d, int where)
+{
+  u16 command = get_conf_word(d, where + PCI_PCIX_COMMAND);
+  u32 status = get_conf_long(d, where + PCI_PCIX_STATUS);
+  printf("PCI-X non-bridge device.\n");
+  if (verbose < 2)
+    return;
+  printf("\t\tCommand: DPERE%c ERO%c RBC=%d OST=%d\n",
+        FLAG(command, PCI_PCIX_COMMAND_DPERE),
+        FLAG(command, PCI_PCIX_COMMAND_ERO),
+        ((command & PCI_PCIX_COMMAND_MAX_MEM_READ_BYTE_COUNT) >> 2U),
+        ((command & PCI_PCIX_COMMAND_MAX_OUTSTANDING_SPLIT_TRANS) >> 4U));
+  printf("\t\tStatus: Bus=%u Dev=%u Func=%u 64bit%c 133MHz%c SCD%c USC%c, DC=%s, DMMRBC=%u, DMOST=%u, DMCRS=%u, RSCEM%c",
+        ((status >> 8) & 0xffU), // bus
+        ((status >> 3) & 0x1fU), // dev
+        (status & PCI_PCIX_BRIDGE_STATUS_FUNCTION), // function
+        FLAG(status, PCI_PCIX_STATUS_64BIT),
+        FLAG(status, PCI_PCIX_STATUS_133MHZ),
+        FLAG(status, PCI_PCIX_STATUS_SC_DISCARDED),
+        FLAG(status, PCI_PCIX_STATUS_UNEXPECTED_SC),
+        ((status & PCI_PCIX_STATUS_DEVICE_COMPLEXITY) ? "bridge" : "simple"),
+        ((status >> 21) & 3U),
+        ((status >> 23) & 7U),
+        ((status >> 26) & 7U),
+        FLAG(status, PCI_PCIX_STATUS_RCVD_SC_ERR_MESS));
+}
+
+static void
+show_pcix_bridge(struct device *d, int where)
+{
+  u16 secstatus;
+  u32 status, upstcr, downstcr;
+  printf("PCI-X bridge device.\n");
+  if (verbose < 2)
+    return;
+  secstatus = get_conf_word(d, where + PCI_PCIX_BRIDGE_SEC_STATUS);
+  printf("\t\tSecondary Status: 64bit%c, 133MHz%c, SCD%c, USC%c, SCO%c, SRD%c Freq=%d\n",
+        FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_64BIT),
+        FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_133MHZ),
+        FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_SC_DISCARDED),
+        FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_UNEXPECTED_SC),
+        FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_SC_OVERRUN),
+        FLAG(secstatus, PCI_PCIX_BRIDGE_SEC_STATUS_SPLIT_REQUEST_DELAYED),
+        ((secstatus >> 6) & 7));
+  status = get_conf_long(d, where + PCI_PCIX_BRIDGE_STATUS);
+  printf("\t\tStatus: Bus=%u Dev=%u Func=%u 64bit%c 133MHz%c SCD%c USC%c, SCO%c, SRD%c\n", 
+        ((status >> 8) & 0xff), // bus
+        ((status >> 3) & 0x1f), // dev
+        (status & PCI_PCIX_BRIDGE_STATUS_FUNCTION), // function
+        FLAG(status, PCI_PCIX_BRIDGE_STATUS_64BIT),
+        FLAG(status, PCI_PCIX_BRIDGE_STATUS_133MHZ),
+        FLAG(status, PCI_PCIX_BRIDGE_STATUS_SC_DISCARDED),
+        FLAG(status, PCI_PCIX_BRIDGE_STATUS_UNEXPECTED_SC),
+        FLAG(status, PCI_PCIX_BRIDGE_STATUS_SC_OVERRUN),
+        FLAG(status, PCI_PCIX_BRIDGE_STATUS_SPLIT_REQUEST_DELAYED));
+  upstcr = get_conf_long(d, where + PCI_PCIX_BRIDGE_UPSTREAM_SPLIT_TRANS_CTRL);
+  printf("\t\t: Upstream: Capacity=%u, Commitment Limit=%u\n",
+        (upstcr & PCI_PCIX_BRIDGE_STR_CAPACITY),
+        (upstcr >> 16) & 0xffff);
+  downstcr = get_conf_long(d, where + PCI_PCIX_BRIDGE_DOWNSTREAM_SPLIT_TRANS_CTRL);
+  printf("\t\t: Downstream: Capacity=%u, Commitment Limit=%u\n",
+        (downstcr & PCI_PCIX_BRIDGE_STR_CAPACITY),
+        (downstcr >> 16) & 0xffff);
+}
+
+static void
+show_pcix(struct device *d, int where)
+{
+  switch (d->dev->hdrtype)
+    {
+    case PCI_HEADER_TYPE_NORMAL:
+      show_pcix_nobridge(d, where);
+      break;
+    case PCI_HEADER_TYPE_BRIDGE:
+      show_pcix_bridge(d, where);
+      break;
+    }
+}
+
 static void
 show_rom(struct device *d)
 {
@@ -559,6 +655,9 @@ show_caps(struct device *d)
            case PCI_CAP_ID_MSI:
              show_msi(d, where, cap);
              break;
+           case PCI_CAP_ID_PCIX:
+             show_pcix(d, where);
+             break;
            default:
              printf("#%02x [%04x]\n", id, cap);
            }