Hi Martin, I never heard if v3 was acceptable. If not, what else would you like to see? Thanks. /ac * Alex Chiang <achiang@xxxxxx>: > We've been exposing slot information in /sys/bus/pci/slots for a > long time now (as long as a hotplug driver or slot detection > driver like pci_slot is loaded). > > Let's make life better for our users and display that information > in lspci. If slot entries appear in /sys/bus/pci/slots/, > correlate them to PCI devices, and display the information when > lspci -v is issued. > > If no slot entries appear in sysfs (due to no modules loaded), do > nothing. > > Now you'll see sample output like the following: > > 23:01.1 Class 0c04: Device 10df:fd00 (rev 01) > Subsystem: Device 10df:fd00 > Physical Slot: 3 > Flags: bus master, 66MHz, medium devsel, latency 248, IRQ 60 > ... > > Signed-off-by: Alex Chiang <achiang@xxxxxx> > --- > v2 -> v3: > - fixed indentation / style issues > - fixed another memory leak > - move pci_mfree(d->phy_slot) to more obvious location > - set PCI_FILL_PHYS_SLOT for all devices after looking > for slot info > > v1-> v2: > - sysfs-specific fill_info > - fix memory leak > - document in man page > > lib/access.c | 1 > lib/pci.h | 2 + > lib/sysfs.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- > lspci.c | 7 +++++- > lspci.man | 4 +++ > 5 files changed, 76 insertions(+), 2 deletions(-) > --- > diff --git a/lib/access.c b/lib/access.c > index 23a821c..691df39 100644 > --- a/lib/access.c > +++ b/lib/access.c > @@ -59,6 +59,7 @@ void pci_free_dev(struct pci_dev *d) > if (d->methods->cleanup_dev) > d->methods->cleanup_dev(d); > pci_free_caps(d); > + pci_mfree(d->phy_slot); > pci_mfree(d); > } > > diff --git a/lib/pci.h b/lib/pci.h > index 452e1d8..be62297 100644 > --- a/lib/pci.h > +++ b/lib/pci.h > @@ -129,6 +129,7 @@ struct pci_dev { > pciaddr_t rom_base_addr; /* Expansion ROM base address */ > pciaddr_t rom_size; /* Expansion ROM size */ > struct pci_cap *first_cap; /* List of capabilities */ > + char *phy_slot; /* Physical slot */ > > /* Fields used internally: */ > struct pci_access *access; > @@ -162,6 +163,7 @@ int pci_fill_info(struct pci_dev *, int flags) PCI_ABI; /* Fill in device inform > #define PCI_FILL_CLASS 32 > #define PCI_FILL_CAPS 64 > #define PCI_FILL_EXT_CAPS 128 > +#define PCI_FILL_PHYS_SLOT 256 > #define PCI_FILL_RESCAN 0x10000 > > void pci_setup_cache(struct pci_dev *, u8 *cache, int len) PCI_ABI; > diff --git a/lib/sysfs.c b/lib/sysfs.c > index ca43562..5949ff1 100644 > --- a/lib/sysfs.c > +++ b/lib/sysfs.c > @@ -177,6 +177,68 @@ static void sysfs_scan(struct pci_access *a) > closedir(dir); > } > > +static void > +sysfs_fill_slots(struct pci_dev *d) > +{ > + struct pci_access *a = d->access; > + char dirname[1024]; > + DIR *dir; > + struct dirent *entry; > + int n; > + > + n = snprintf(dirname, sizeof(dirname), "%s/slots", sysfs_name(a)); > + if (n < 0 || n >= (int) sizeof(dirname)) > + a->error("Directory name too long"); > + dir = opendir(dirname); > + if (!dir) > + a->error("Cannot open %s", dirname); > + while ((entry = readdir(dir))) > + { > + char namebuf[OBJNAMELEN], buf[16]; > + FILE *file; > + unsigned int dom, bus, dev; > + struct pci_dev *pd; > + int n = snprintf(namebuf, OBJNAMELEN, "%s/%s/%s", dirname, entry->d_name, "address"); > + > + /* ".", ".." or a special non-device perhaps */ > + if (entry->d_name[0] == '.') > + continue; > + > + if (n < 0 || n >= OBJNAMELEN) > + d->access->error("File name too long"); > + file = fopen(namebuf, "r"); > + if (!file) > + a->error("Cannot open %s: %s", namebuf, strerror(errno)); > + if (!fgets(buf, sizeof(buf), file)) > + break; > + if (sscanf(buf, "%x:%x:%x", &dom, &bus, &dev) < 3) > + a->error("sysfs_scan: Couldn't parse entry address %s", buf); > + for (pd = a->devices; pd; pd = pd->next) > + { > + if (dom == pd->domain && bus == pd->bus && dev == pd->dev && !pd->phy_slot) > + { > + pd->phy_slot = pci_malloc(a, strlen(entry->d_name) + 1); > + sprintf(pd->phy_slot, "%s", entry->d_name); > + } > + pd->known_fields |= PCI_FILL_PHYS_SLOT; > + } > + fclose(file); > + } > + closedir(dir); > +} > + > +static int > +sysfs_fill_info(struct pci_dev *d, int flags) > +{ > + int ret; > + > + ret = pci_generic_fill_info(d, flags); > + if (flags & PCI_FILL_PHYS_SLOT && !(d->known_fields & PCI_FILL_PHYS_SLOT)) > + sysfs_fill_slots(d); > + > + return ret; > +} > + > /* Intent of the sysfs_setup() caller */ > enum > { > @@ -306,7 +368,7 @@ struct pci_methods pm_linux_sysfs = { > sysfs_init, > sysfs_cleanup, > sysfs_scan, > - pci_generic_fill_info, > + sysfs_fill_info, > sysfs_read, > sysfs_write, > sysfs_read_vpd, > diff --git a/lspci.c b/lspci.c > index d872c75..9958ef6 100644 > --- a/lspci.c > +++ b/lspci.c > @@ -140,7 +140,7 @@ scan_device(struct pci_dev *p) > d->config_cached += 64; > } > pci_setup_cache(p, d->config, d->config_cached); > - pci_fill_info(p, PCI_FILL_IDENT | PCI_FILL_CLASS | PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES); > + pci_fill_info(p, PCI_FILL_IDENT | PCI_FILL_CLASS | PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES | PCI_FILL_PHYS_SLOT); > return d; > } > > @@ -685,6 +685,9 @@ show_verbose(struct device *d) > return; > } > > + if (p->phy_slot) > + printf("\tPhysical Slot: %s\n", p->phy_slot); > + > if (verbose > 1) > { > 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", > @@ -850,6 +853,8 @@ show_machine(struct device *d) > printf("SDevice:\t%s\n", > pci_lookup_name(pacc, sdbuf, sizeof(sdbuf), PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_DEVICE, p->vendor_id, p->device_id, sv_id, sd_id)); > } > + if (p->phy_slot) > + printf("PhySlot:\t%s\n", p->phy_slot); > if (c = get_conf_byte(d, PCI_REVISION_ID)) > printf("Rev:\t%02x\n", c); > if (c = get_conf_byte(d, PCI_CLASS_PROG)) > diff --git a/lspci.man b/lspci.man > index dfddacd..441bc2b 100644 > --- a/lspci.man > +++ b/lspci.man > @@ -286,6 +286,10 @@ Name of the subsystem vendor (optional). > Name of the subsystem (optional). > > .TP > +.B PhySlot > +The physical slot where the device resides (optional, Linux only). > + > +.TP > .B Rev > Revision number (optional). > > -- > To unsubscribe from this list: send the line "unsubscribe linux-pci" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html