Re: [PATCH v3] pciutils: Display physical slot information in lspci -v

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux