]> mj.ucw.cz Git - pciutils.git/blobdiff - lib/generic.c
CXL3.0: Add DVSEC CXLCtrl3 and missing CXLCtl2
[pciutils.git] / lib / generic.c
index e80158fb9b14c82768b60d9018a0d6a9d4f1a9ed..6211c90fbe607d76177925b58049fbae22237fec 100644 (file)
@@ -11,7 +11,7 @@
 #include "internal.h"
 
 void
-pci_generic_scan_bus(struct pci_access *a, byte *busmap, int bus)
+pci_generic_scan_bus(struct pci_access *a, byte *busmap, int domain, int bus)
 {
   int dev, multi, ht;
   struct pci_dev *t;
@@ -24,6 +24,7 @@ pci_generic_scan_bus(struct pci_access *a, byte *busmap, int bus)
     }
   busmap[bus] = 1;
   t = pci_alloc_dev(a);
+  t->domain = domain;
   t->bus = bus;
   for (dev=0; dev<32; dev++)
     {
@@ -41,6 +42,7 @@ pci_generic_scan_bus(struct pci_access *a, byte *busmap, int bus)
            multi = ht & 0x80;
          ht &= 0x7f;
          d = pci_alloc_dev(a);
+         d->domain = t->domain;
          d->bus = t->bus;
          d->dev = t->dev;
          d->func = t->func;
@@ -55,7 +57,7 @@ pci_generic_scan_bus(struct pci_access *a, byte *busmap, int bus)
              break;
            case PCI_HEADER_TYPE_BRIDGE:
            case PCI_HEADER_TYPE_CARDBUS:
-             pci_generic_scan_bus(a, busmap, pci_read_byte(t, PCI_SECONDARY_BUS));
+             pci_generic_scan_bus(a, busmap, domain, pci_read_byte(t, PCI_SECONDARY_BUS));
              break;
            default:
              a->debug("Device %04x:%02x:%02x.%d has unknown header type %02x.\n", d->domain, d->bus, d->dev, d->func, ht);
@@ -66,12 +68,18 @@ pci_generic_scan_bus(struct pci_access *a, byte *busmap, int bus)
 }
 
 void
-pci_generic_scan(struct pci_access *a)
+pci_generic_scan_domain(struct pci_access *a, int domain)
 {
   byte busmap[256];
 
   memset(busmap, 0, sizeof(busmap));
-  pci_generic_scan_bus(a, busmap, 0);
+  pci_generic_scan_bus(a, busmap, domain, 0);
+}
+
+void
+pci_generic_scan(struct pci_access *a)
+{
+  pci_generic_scan_domain(a, 0);
 }
 
 static int
@@ -86,6 +94,7 @@ void
 pci_generic_fill_info(struct pci_dev *d, unsigned int flags)
 {
   struct pci_access *a = d->access;
+  struct pci_cap *cap;
 
   if (want_fill(d, flags, PCI_FILL_IDENT))
     {
@@ -96,6 +105,37 @@ pci_generic_fill_info(struct pci_dev *d, unsigned int flags)
   if (want_fill(d, flags, PCI_FILL_CLASS))
     d->device_class = pci_read_word(d, PCI_CLASS_DEVICE);
 
+  if (want_fill(d, flags, PCI_FILL_CLASS_EXT))
+    {
+      d->prog_if = pci_read_byte(d, PCI_CLASS_PROG);
+      d->rev_id = pci_read_byte(d, PCI_REVISION_ID);
+    }
+
+  if (want_fill(d, flags, PCI_FILL_SUBSYS))
+    {
+      switch (get_hdr_type(d))
+        {
+        case PCI_HEADER_TYPE_NORMAL:
+          d->subsys_vendor_id = pci_read_word(d, PCI_SUBSYSTEM_VENDOR_ID);
+          d->subsys_id = pci_read_word(d, PCI_SUBSYSTEM_ID);
+          break;
+        case PCI_HEADER_TYPE_BRIDGE:
+          cap = pci_find_cap(d, PCI_CAP_ID_SSVID, PCI_CAP_NORMAL);
+          if (cap)
+            {
+              d->subsys_vendor_id = pci_read_word(d, cap->addr + PCI_SSVID_VENDOR);
+              d->subsys_id = pci_read_word(d, cap->addr + PCI_SSVID_DEVICE);
+            }
+          break;
+        case PCI_HEADER_TYPE_CARDBUS:
+          d->subsys_vendor_id = pci_read_word(d, PCI_CB_SUBSYSTEM_VENDOR_ID);
+          d->subsys_id = pci_read_word(d, PCI_CB_SUBSYSTEM_ID);
+          break;
+        default:
+          clear_fill(d, PCI_FILL_SUBSYS);
+        }
+    }
+
   if (want_fill(d, flags, PCI_FILL_IRQ))
     d->irq = pci_read_byte(d, PCI_INTERRUPT_LINE);