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)
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;
#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
*/
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)
{
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);
}