diff mbox series

[pciutils,2/5] libpci: generic: Implement PROGIF, REVID and SUBSYS support

Message ID 20220121135718.27172-3-pali@kernel.org
State New
Headers show
Series Support for PROGIF, REVID and SUBSYS | expand

Commit Message

Pali Rohár Jan. 21, 2022, 1:57 p.m. UTC
PCI_FILL_SUBSYS is implemented only for PCI_HEADER_TYPE_NORMAL and
PCI_HEADER_TYPE_CARDBUS like in lspci.
---
 lib/generic.c | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/lib/generic.c b/lib/generic.c
index ef9e2a34b4f4..f4b6918cb55b 100644
--- a/lib/generic.c
+++ b/lib/generic.c
@@ -80,7 +80,7 @@  pci_generic_fill_info(struct pci_dev *d, unsigned int flags)
   struct pci_access *a = d->access;
   unsigned int done = 0;
 
-  if ((flags & (PCI_FILL_BASES | PCI_FILL_ROM_BASE)) && d->hdrtype < 0)
+  if ((flags & (PCI_FILL_SUBSYS | PCI_FILL_BASES | PCI_FILL_ROM_BASE)) && d->hdrtype < 0)
     d->hdrtype = pci_read_byte(d, PCI_HEADER_TYPE) & 0x7f;
 
   if (flags & PCI_FILL_IDENT)
@@ -96,6 +96,35 @@  pci_generic_fill_info(struct pci_dev *d, unsigned int flags)
       done |= PCI_FILL_CLASS;
     }
 
+  if (flags & PCI_FILL_PROGIF)
+    {
+      d->prog_if = pci_read_byte(d, PCI_CLASS_PROG);
+      done |= PCI_FILL_PROGIF;
+    }
+
+  if (flags & PCI_FILL_REVID)
+    {
+      d->rev_id = pci_read_byte(d, PCI_REVISION_ID);
+      done |= PCI_FILL_REVID;
+    }
+
+  if (flags & PCI_FILL_SUBSYS)
+    {
+      switch (d->hdrtype)
+        {
+        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);
+          done |= PCI_FILL_SUBSYS;
+          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);
+          done |= PCI_FILL_SUBSYS;
+          break;
+        }
+    }
+
   if (flags & PCI_FILL_IRQ)
     {
       d->irq = pci_read_byte(d, PCI_INTERRUPT_LINE);