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

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

 



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 easy 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>
---
There are probably better ways to do this, but this at least
gives a rough idea of the desired functionality.

The initial hunk near the top of sysfs.c is a whitespace fix that
I cleaned up while I was in the file.

 lib/pci.h   |    1 +
 lib/sysfs.c |   49 ++++++++++++++++++++++++++++++++++++++++++++++++-
 lspci.c     |    3 +++
 3 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/lib/pci.h b/lib/pci.h
index 452e1d8..c7db6d5 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;
diff --git a/lib/sysfs.c b/lib/sysfs.c
index 6ebabe1..bdef931 100644
--- a/lib/sysfs.c
+++ b/lib/sysfs.c
@@ -1,7 +1,7 @@
 /*
  *	The PCI Library -- Configuration Access via /sys/bus/pci
  *
- * 	Copyright (c) 2003 Matthew Wilcox <willy@xxxxxxxxx>
+ *	Copyright (c) 2003 Matthew Wilcox <willy@xxxxxxxxx>
  *	Copyright (c) 1997--2008 Martin Mares <mj@xxxxxx>
  *
  *	Can be freely distributed and used under the terms of the GNU GPL.
@@ -130,6 +130,52 @@ sysfs_get_resources(struct pci_dev *d)
   fclose(file);
 }
 
+static void
+sysfs_find_slot(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;
+      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);
+      if (dom == d->domain && bus == d->bus && dev == d->dev) {
+	d->phy_slot = pci_malloc(a, strlen(entry->d_name) + 1);
+	sprintf(d->phy_slot, "%s", entry->d_name);
+	fclose(file);
+	break;
+      }
+      fclose(file);
+    }
+  closedir(dir);
+}
+
 static void sysfs_scan(struct pci_access *a)
 {
   char dirname[1024];
@@ -162,6 +208,7 @@ static void sysfs_scan(struct pci_access *a)
       if (!a->buscentric)
 	{
 	  sysfs_get_resources(d);
+	  sysfs_find_slot(d);
 	  d->irq = sysfs_get_value(d, "irq");
 	  /*
 	   *  We could read these faster from the config registers, but we want to give
diff --git a/lspci.c b/lspci.c
index d872c75..4d2e77b 100644
--- a/lspci.c
+++ b/lspci.c
@@ -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",
--
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