Search code examples
clinux-kernel

How does lspci find out physical slot number of a PCI(E) device?


lspci is capable to show physical slot number in the verbose presentation:

I'd like to find out how it does it. I am going to apply this method in the driver that I would like to modify, so it would enumerate the devices (with the same ID) and disambiguate the device files according to physical slot. Like /dev/device_physslot . The driver will run on Ubuntu 18

I tried to dig in the source code. I found the relevant line 775 in https://github.com/pciutils/pciutils/blob/master/lspci.c:

if (p->phy_slot)
    printf("\tPhysical Slot: %s\n", p->phy_slot);

p is struct pci_dev. That had been quite confusing because standard linux/pci.h does not have field phy_slot until I figured out that is their own (re)definition

The structure is filled by the function

int
pci_fill_info_v38(struct pci_dev *d, int flags)
{
  unsigned int uflags = flags;
  if (uflags & PCI_FILL_RESCAN)
    {
      uflags &= ~PCI_FILL_RESCAN;
      pci_reset_properties(d);
    }
  if (uflags & ~d->known_fields)
    d->methods->fill_info(d, uflags);
  return d->known_fields;
}

fill_info is a function pointer defined in https://github.com/pciutils/pciutils/blob/master/lib/internal.h (line 44)

And that's where I lost track.


Solution

  • After digging deeper in the source and succeeding to run lspci in the debugger (thanks to Netbeans) I found out that lspci uses sysfs to gather information. In particular /sys/bus/pci/slots/slot_num/address file contains the bus address of the slot. And that's what lspci uses to attribute slots to bus addresses in the function sysfs_fill_slots (in sysfs.c)

    Unfortunately this method turns out to be unsuitable for my purposes, since it is not possible to perform file I/O from kernel module.