]> git.ipfire.org Git - thirdparty/pciutils.git/commitdiff
sysfs: Parse MSI routing if available
authorMartin Mareš <mj@ucw.cz>
Sun, 5 Apr 2026 18:49:52 +0000 (20:49 +0200)
committerMartin Mareš <mj@ucw.cz>
Sun, 5 Apr 2026 18:49:52 +0000 (20:49 +0200)
lib/access.c
lib/pci.h
lib/sysfs.c

index d157de52a43e2bb0a9ff4676cde17b075d5e9c3f..182657f5d11c9c20f99ef2d3a4c1b34bc3609252 100644 (file)
@@ -79,6 +79,13 @@ pci_free_properties(struct pci_dev *d)
       d->properties = p->next;
       pci_mfree(p);
     }
+
+  while (d->msi_routing)
+    {
+      struct pci_msi_routing *mr = d->msi_routing;
+      d->msi_routing = mr->next;
+      free(mr);
+    }
 }
 
 void pci_free_dev(struct pci_dev *d)
index 787a4bbd22de610bb31330debdabe07994da0bd8..e54c2447639638af341715dd54a76abd2049fb1b 100644 (file)
--- a/lib/pci.h
+++ b/lib/pci.h
@@ -167,6 +167,7 @@ struct pci_dev {
   u32 rcd_link_cap;                    /* Link Capabilities register for Restricted CXL Devices */
   u16 rcd_link_status;                 /* Link Status register for RCD */
   u16 rcd_link_ctrl;                   /* Link Control register for RCD */
+  struct pci_msi_routing *msi_routing; /* Routing of MSI or MSI-X interrupts */
 
   /* Fields used internally */
   struct pci_access *access;
@@ -240,9 +241,15 @@ char *pci_get_string_property(struct pci_dev *d, u32 prop) PCI_ABI;
 #define PCI_FILL_PARENT                0x00080000
 #define PCI_FILL_DRIVER                0x00100000      /* OS driver currently in use (string property) */
 #define PCI_FILL_RCD_LNK       0x00200000      /* CXL RCD Link status properties (rcd_*) */
+#define PCI_FILL_MSI_ROUTING   0x00400000      /* MSI interrupt routing (msi_routing) */
 
 void pci_setup_cache(struct pci_dev *, u8 *cache, int len) PCI_ABI;
 
+struct pci_msi_routing {
+  struct pci_msi_routing *next;
+  int irq;
+};
+
 /*
  *     Capabilities
  */
index 382f2afef729bc5897bb29585d524f5aff569129..55ac7a6f0699ffb8515924b94f49b7899b0283d5 100644 (file)
@@ -338,6 +338,37 @@ sysfs_fill_slots(struct pci_access *a)
   closedir(dir);
 }
 
+static void
+sysfs_fill_msi_routing(struct pci_dev *d)
+{
+  char namebuf[OBJNAMELEN];
+
+  sysfs_obj_name(d, "msi_irqs", namebuf);
+  DIR *dir = opendir(namebuf);
+  if (!dir)
+    {
+      clear_fill(d, PCI_FILL_MSI_ROUTING);
+      return;
+    }
+
+  struct pci_msi_routing **plast = &d->msi_routing;
+  struct dirent *de;
+  while (de = readdir(dir))
+    {
+      int irq;
+      if (sscanf(de->d_name, "%d", &irq) == 1)
+       {
+         struct pci_msi_routing *mr = pci_malloc(d->access, sizeof(*mr));
+         *plast = mr;
+         plast = &mr->next;
+         mr->next = NULL;
+         mr->irq = irq;
+       }
+    }
+
+  closedir(dir);
+}
+
 static void
 sysfs_fill_info(struct pci_dev *d, unsigned int flags)
 {
@@ -505,6 +536,9 @@ sysfs_fill_info(struct pci_dev *d, unsigned int flags)
         d->rcd_link_status = strtoul(buf, NULL, 16);
     }
 
+  if (want_fill(d, flags, PCI_FILL_MSI_ROUTING))
+    sysfs_fill_msi_routing(d);
+
   pci_generic_fill_info(d, flags);
 }