Blob Blame History Raw
From 73707308d0c17fffdad2086686135c9cfd179a60 Mon Sep 17 00:00:00 2001
From: Dan Callaghan <dcallagh@redhat.com>
Date: Tue, 30 Jun 2015 16:08:22 +1000
Subject: [PATCH 11/26] scan PnP devices in sysfs (#691)

---
 src/core/Makefile |  4 ++--
 src/core/main.cc  |  4 ++++
 src/core/pnp.cc   | 41 +++++++++++++++++++++++++++++++++++++++++
 src/core/pnp.h    |  2 ++
 src/core/sysfs.cc | 14 ++++++++++++++
 src/core/sysfs.h  |  2 ++
 6 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/src/core/Makefile b/src/core/Makefile
index 5bf5a69..92c34d4 100644
--- a/src/core/Makefile
+++ b/src/core/Makefile
@@ -37,7 +37,7 @@ hw.o: hw.h osutils.h version.h config.h options.h heuristics.h
 main.o: hw.h print.h version.h options.h mem.h dmi.h cpuinfo.h cpuid.h
 main.o: device-tree.h pci.h pcmcia.h pcmcia-legacy.h ide.h scsi.h spd.h
 main.o: network.h isapnp.h fb.h usb.h sysfs.h display.h parisc.h cpufreq.h
-main.o: ideraid.h mounts.h smp.h abi.h dasd.h virtio.h
+main.o: ideraid.h mounts.h smp.h abi.h dasd.h virtio.h pnp.h
 print.o: print.h hw.h options.h version.h osutils.h config.h
 mem.o: version.h config.h mem.h hw.h
 dmi.o: version.h config.h dmi.h hw.h osutils.h
@@ -56,7 +56,7 @@ spd.o: version.h spd.h hw.h osutils.h
 network.o: version.h config.h network.h hw.h osutils.h sysfs.h options.h
 network.o: heuristics.h
 isapnp.o: version.h isapnp.h hw.h pnp.h
-pnp.o: version.h pnp.h hw.h
+pnp.o: version.h pnp.h hw.h sysfs.h
 fb.o: version.h fb.h hw.h
 options.o: version.h options.h osutils.h
 usb.o: version.h usb.h hw.h osutils.h heuristics.h options.h
diff --git a/src/core/main.cc b/src/core/main.cc
index 03848da..7008933 100644
--- a/src/core/main.cc
+++ b/src/core/main.cc
@@ -32,6 +32,7 @@
 #include "spd.h"
 #include "network.h"
 #include "isapnp.h"
+#include "pnp.h"
 #include "fb.h"
 #include "usb.h"
 #include "sysfs.h"
@@ -101,6 +102,9 @@ bool scan_system(hwNode & system)
     status("ISA PnP");
     if (enabled("isapnp"))
       scan_isapnp(computer);
+    status("PnP (sysfs)");
+    if (enabled("pnp"))
+      scan_pnp(computer);
     status("PCMCIA");
     if (enabled("pcmcia"))
       scan_pcmcia(computer);
diff --git a/src/core/pnp.cc b/src/core/pnp.cc
index 6f60a76..0e01f7a 100644
--- a/src/core/pnp.cc
+++ b/src/core/pnp.cc
@@ -8,6 +8,7 @@
  */
 #include "version.h"
 #include "pnp.h"
+#include "sysfs.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -149,3 +150,43 @@ hw::hwClass pnp_class(const string & pnpid)
 
   return hw::generic;
 }
+
+bool scan_pnp(hwNode & n)
+{
+  vector < sysfs::entry > entries = sysfs::entries_by_bus("pnp");
+
+  if (entries.empty())
+    return false;
+
+  hwNode *core = n.getChild("core");
+  if (!core)
+  {
+    n.addChild(hwNode("core", hw::bus));
+    core = n.getChild("core");
+  }
+
+  for (vector < sysfs::entry >::iterator it = entries.begin();
+      it != entries.end(); ++it)
+  {
+    const sysfs::entry & e = *it;
+
+    vector < string > pnpids = e.multiline_attr("id");
+    if (pnpids.empty())
+      continue;
+    // devices can report multiple PnP IDs, just pick the first
+    string pnpid = pnpids[0];
+
+    hwNode device("pnp" + e.name(), pnp_class(pnpid));
+    device.addCapability("pnp");
+    string driver = e.driver();
+    if (!driver.empty())
+      device.setConfig("driver", driver);
+    string vendor = vendorname(pnpid.c_str());
+    if (!vendor.empty())
+      device.setVendor(vendor);
+    device.claim();
+
+    core->addChild(device);
+  }
+  return true;
+}
diff --git a/src/core/pnp.h b/src/core/pnp.h
index 6406583..dfc5159 100644
--- a/src/core/pnp.h
+++ b/src/core/pnp.h
@@ -7,4 +7,6 @@
 const char * vendorname(const char * id);
 
 hw::hwClass pnp_class(const string & pnpid);
+
+bool scan_pnp(hwNode &);
 #endif
diff --git a/src/core/sysfs.cc b/src/core/sysfs.cc
index acc9d00..ed2c600 100644
--- a/src/core/sysfs.cc
+++ b/src/core/sysfs.cc
@@ -298,6 +298,20 @@ entry entry::parent() const
   return e;
 }
 
+string entry::string_attr(const string & name, const string & def) const
+{
+  return hw::strip(get_string(This->devpath + "/" + name, def));
+}
+
+
+vector < string > entry::multiline_attr(const string & name) const
+{
+  vector < string > lines;
+  loadfile(This->devpath + "/" + name, lines);
+  return lines;
+}
+
+
 string entry::modalias() const
 {
   return get_string(This->devpath+"/modalias");
diff --git a/src/core/sysfs.h b/src/core/sysfs.h
index a9dc573..7ceb395 100644
--- a/src/core/sysfs.h
+++ b/src/core/sysfs.h
@@ -27,6 +27,8 @@ namespace sysfs
       string modalias() const;
       entry parent() const;
       string name_in_class(const string &) const;
+      string string_attr(const string & name, const string & def = "") const;
+      vector < string > multiline_attr(const string & name) const;
 
       struct entry_i * This;
 
-- 
2.10.2