]> xenbits.xensource.com Git - people/andrewcoop/hwloc.git/commitdiff
linuxpci: read hardware revision and linkspeed ...
authorBrice Goglin <brice.goglin@inria.fr>
Wed, 15 May 2013 12:33:55 +0000 (12:33 +0000)
committerBrice Goglin <brice.goglin@inria.fr>
Wed, 15 May 2013 12:33:55 +0000 (12:33 +0000)
linuxpci: read hardware revision and linkspeed from the config cache

This brings linuxpci to almost the same features as the full PCI component.
Only bridges and names are now missing.

This commit was SVN r5626.

NEWS
doc/hwloc.doxy
src/topology-linux.c

diff --git a/NEWS b/NEWS
index 6fa5f76b57dd72247bac45591288ef955023d269..37591e6ed84f60025af10bd5f3d555c1e5dc3e95 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -22,7 +22,7 @@ Version 1.8.0
 * New components
   + Add the "linuxpci" component to fallback to basic PCI discovery on
     Linux when full discovery with libpciaccess or libpci isn't available.
-    It misses bridges and some device attributes.
+    It misses bridges and device names.
 * Misc
   + Add --with-hwloc-plugins-path to specify the install/load directories
     of plugins.
index c148fd90f068b1ea24ef269280b7c0353d3c0009..a90c85d7438287644e920f3e6af84112b38a776f 100644 (file)
@@ -1200,8 +1200,7 @@ devices, see \ref faq_privileged for details.
 On Linux, a minimalistic PCI discovery may still be performed even
 if neither <tt>libpciaccess</tt> nor <tt>pciutils</tt> can be used.
 It only probes PCI devices and guesses hostbridges, and it also
-misses some attributes such as PCI device names, hardware revision
-or link speed.
+misses PCI device names.
 
 \section iodevices_hierarchy I/O object hierarchy
 
@@ -2250,7 +2249,7 @@ environment variable (see \ref envvar).
  This component can probe PCI devices on Linux without the help of external
  libraries such as libpciaccess. Its priority is lower than the pci component
  since it does not detect bridges (only guesses fake hostbridges)
- and misses some device attributes.
+ and misses device names.
 </dd>
 <dt>opencl</dt>
 <dd>
index fcc7563b903e8800113ce66b933142f84eb321a1..512417842c14f7c6d05e6d4f38999891d9a2dd0f 100644 (file)
@@ -4247,6 +4247,9 @@ const struct hwloc_component hwloc_linux_component = {
  ******* Linux PCI component *******
  ***********************************/
 
+#define HWLOC_PCI_REVISION_ID 0x08
+#define HWLOC_PCI_CAP_ID_EXP 0x10
+
 static int
 hwloc_look_linuxfs_pci(struct hwloc_backend *backend)
 {
@@ -4361,6 +4364,29 @@ hwloc_look_linuxfs_pci(struct hwloc_backend *backend)
       }
     }
 
+    snprintf(path, sizeof(path), "/sys/bus/pci/devices/%s/config", dirent->d_name);
+    file = fopen(path, "r");
+    if (file) {
+#define CONFIG_SPACE_CACHESIZE_TRY 256
+      unsigned char config_space_cache[CONFIG_SPACE_CACHESIZE_TRY];
+      unsigned config_space_cachesize = CONFIG_SPACE_CACHESIZE_TRY;
+      unsigned offset;
+
+      config_space_cachesize = fread(config_space_cache, 1, CONFIG_SPACE_CACHESIZE_TRY, file);
+      fclose(file);
+      if (config_space_cachesize >= 64) {
+       /* cannot do anything without base config space */
+
+       /* get the revision */
+       obj->attr->pcidev.revision = config_space_cache[HWLOC_PCI_REVISION_ID];
+
+       /* try to get the link speed */
+       offset = hwloc_pci_find_cap(config_space_cache, config_space_cachesize, HWLOC_PCI_CAP_ID_EXP);
+       if (offset > 0)
+         hwloc_pci_find_linkspeed(config_space_cache, config_space_cachesize, offset, &obj->attr->pcidev.linkspeed);
+      }
+    }
+
     /* find a hostbridge with same cpuset and domain or create one */
     hostbridge = hostbridges;
     while (hostbridge