From: Oliver O'Halloran Date: Tue, 15 May 2018 05:39:05 +0000 (+1000) Subject: Add device-tree node path to the verbose output X-Git-Tag: v3.6.0~4 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=6d701ce33eb2a420ce196be731ddf11d2d1fcc7f;p=pciutils.git Add device-tree node path to the verbose output Adds the path of the device-tree node of a PCI device to the lspci -v output, like so: 0021:00:00.0 PCI bridge: IBM Device 03dc (prog-if 00 [Normal decode]) DT Node: /sys/firmware/devicetree/base/pciex@3fffe41100000/pci@0 This is added as a generic property to struct pci_device and populated by the sysfs backend. Other platforms may find it useful though. Signed-off-by: Oliver O'Halloran --- diff --git a/lib/access.c b/lib/access.c index d991129..9475a84 100644 --- a/lib/access.c +++ b/lib/access.c @@ -75,6 +75,7 @@ void pci_free_dev(struct pci_dev *d) pci_mfree(d->module_alias); pci_mfree(d->label); pci_mfree(d->phy_slot); + pci_mfree(d->dt_node); pci_mfree(d); } diff --git a/lib/pci.h b/lib/pci.h index d4d436f..3abb5d5 100644 --- a/lib/pci.h +++ b/lib/pci.h @@ -137,6 +137,7 @@ struct pci_dev { char *phy_slot; /* Physical slot */ char *module_alias; /* Linux kernel module alias */ char *label; /* Device name as exported by BIOS */ + char *dt_node; /* Path to the device-tree node for this device */ int numa_node; /* NUMA node */ pciaddr_t flags[6]; /* PCI_IORESOURCE_* flags for regions */ pciaddr_t rom_flags; /* PCI_IORESOURCE_* flags for expansion ROM */ @@ -180,6 +181,7 @@ int pci_fill_info(struct pci_dev *, int flags) PCI_ABI; /* Fill in device inform #define PCI_FILL_LABEL 0x0400 #define PCI_FILL_NUMA_NODE 0x0800 #define PCI_FILL_IO_FLAGS 0x1000 +#define PCI_FILL_DT_NODE 0x2000 #define PCI_FILL_RESCAN 0x00010000 void pci_setup_cache(struct pci_dev *, u8 *cache, int len) PCI_ABI; diff --git a/lib/sysfs.c b/lib/sysfs.c index 5779824..9eba5c5 100644 --- a/lib/sysfs.c +++ b/lib/sysfs.c @@ -119,6 +119,23 @@ sysfs_get_string(struct pci_dev *d, char *object, char *buf, int mandatory) return 1; } +static char * +sysfs_deref_link(struct pci_dev *d, char *link_name) +{ + char path[2*OBJNAMELEN], rel_path[OBJNAMELEN]; + + sysfs_obj_name(d, link_name, path); + memset(rel_path, 0, sizeof(rel_path)); + + if (readlink(path, rel_path, sizeof(rel_path)) < 0) + return NULL; + + sysfs_obj_name(d, "", path); + strcat(path, rel_path); + + return canonicalize_file_name(path); +} + static int sysfs_get_value(struct pci_dev *d, char *object, int mandatory) { @@ -311,6 +328,9 @@ sysfs_fill_info(struct pci_dev *d, int flags) if ((flags & PCI_FILL_NUMA_NODE) && !(d->known_fields & PCI_FILL_NUMA_NODE)) d->numa_node = sysfs_get_value(d, "numa_node", 0); + if ((flags & PCI_FILL_DT_NODE) && !(d->known_fields & PCI_FILL_DT_NODE)) + d->dt_node = sysfs_deref_link(d, "of_node"); + return pci_generic_fill_info(d, flags); } diff --git a/lspci.c b/lspci.c index 3bf1925..e207e03 100644 --- a/lspci.c +++ b/lspci.c @@ -686,7 +686,7 @@ show_verbose(struct device *d) show_terse(d); pci_fill_info(p, PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES | - PCI_FILL_PHYS_SLOT | PCI_FILL_NUMA_NODE); + PCI_FILL_PHYS_SLOT | PCI_FILL_NUMA_NODE | PCI_FILL_DT_NODE); irq = p->irq; switch (htype) @@ -717,6 +717,8 @@ show_verbose(struct device *d) if (verbose > 1) { + if (p->dt_node) + printf("\tDT Node: %s\n", p->dt_node); printf("\tControl: I/O%c Mem%c BusMaster%c SpecCycle%c MemWINV%c VGASnoop%c ParErr%c Stepping%c SERR%c FastB2B%c DisINTx%c\n", FLAG(cmd, PCI_COMMAND_IO), FLAG(cmd, PCI_COMMAND_MEMORY), @@ -770,6 +772,8 @@ show_verbose(struct device *d) } else { + if (p->dt_node) + printf("\tDT Node: %s\n", p->dt_node); printf("\tFlags: "); if (cmd & PCI_COMMAND_MASTER) printf("bus master, "); @@ -868,7 +872,7 @@ show_machine(struct device *d) if (verbose) { - pci_fill_info(p, PCI_FILL_PHYS_SLOT | PCI_FILL_NUMA_NODE); + pci_fill_info(p, PCI_FILL_PHYS_SLOT | PCI_FILL_NUMA_NODE | PCI_FILL_DT_NODE); printf((opt_machine >= 2) ? "Slot:\t" : "Device:\t"); show_slot_name(d); putchar('\n'); @@ -895,6 +899,8 @@ show_machine(struct device *d) show_kernel_machine(d); if (p->numa_node != -1) printf("NUMANode:\t%d\n", p->numa_node); + if (p->dt_node) + printf("DTNode:\t%s\n", p->dt_node); } else {