From: Martin Mareš Date: Sun, 5 Apr 2026 18:49:52 +0000 (+0200) Subject: sysfs: Parse MSI routing if available X-Git-Tag: v3.15.0~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b1173ec3eefe0bd4cc80f481ee816453240a412f;p=thirdparty%2Fpciutils.git sysfs: Parse MSI routing if available --- diff --git a/lib/access.c b/lib/access.c index d157de5..182657f 100644 --- a/lib/access.c +++ b/lib/access.c @@ -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) diff --git a/lib/pci.h b/lib/pci.h index 787a4bb..e54c244 100644 --- 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 */ diff --git a/lib/sysfs.c b/lib/sysfs.c index 382f2af..55ac7a6 100644 --- a/lib/sysfs.c +++ b/lib/sysfs.c @@ -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); }