From 51610718fd45b65d4cf458371e4d3b243dd8631f Mon Sep 17 00:00:00 2001
From: Dan Callaghan <dcallagh@redhat.com>
Date: Mon, 13 Jul 2015 14:32:12 +1000
Subject: [PATCH 17/26] scan S/390 devices in sysfs (#693)
---
src/core/Makefile | 6 +--
src/core/dasd.cc | 83 -----------------------------
src/core/dasd.h | 7 ---
src/core/main.cc | 7 +--
src/core/s390.cc | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/core/s390.h | 7 +++
src/core/sysfs.cc | 11 ++++
7 files changed, 181 insertions(+), 96 deletions(-)
delete mode 100644 src/core/dasd.cc
delete mode 100644 src/core/dasd.h
create mode 100644 src/core/s390.cc
create mode 100644 src/core/s390.h
diff --git a/src/core/Makefile b/src/core/Makefile
index 643067b..2d95a80 100644
--- a/src/core/Makefile
+++ b/src/core/Makefile
@@ -8,7 +8,7 @@ LDFLAGS=
LDSTATIC=
LIBS=
-OBJS = hw.o main.o print.o mem.o dmi.o device-tree.o cpuinfo.o osutils.o pci.o version.o cpuid.o ide.o cdrom.o pcmcia-legacy.o scsi.o dasd.o disk.o spd.o network.o isapnp.o pnp.o fb.o options.o usb.o sysfs.o display.o heuristics.o parisc.o cpufreq.o partitions.o blockio.o lvm.o ideraid.o pcmcia.o volumes.o mounts.o smp.o abi.o jedec.o dump.o fat.o virtio.o vio.o
+OBJS = hw.o main.o print.o mem.o dmi.o device-tree.o cpuinfo.o osutils.o pci.o version.o cpuid.o ide.o cdrom.o pcmcia-legacy.o scsi.o s390.o disk.o spd.o network.o isapnp.o pnp.o fb.o options.o usb.o sysfs.o display.o heuristics.o parisc.o cpufreq.o partitions.o blockio.o lvm.o ideraid.o pcmcia.o volumes.o mounts.o smp.o abi.o jedec.o dump.o fat.o virtio.o vio.o
ifeq ($(SQLITE), 1)
OBJS+= db.o
endif
@@ -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 pnp.h vio.h
+main.o: ideraid.h mounts.h smp.h abi.h s390.h virtio.h pnp.h vio.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
@@ -75,6 +75,6 @@ mounts.o: version.h mounts.h hw.h osutils.h
smp.o: version.h smp.h hw.h osutils.h
abi.o: version.h abi.h hw.h osutils.h
jedec.o: jedec.h
-dasd.o: dasd.h disk.h hw.h osutils.h
+s390.o: hw.h sysfs.h disk.h s390.h
virtio.o: version.h hw.h sysfs.h disk.h virtio.h
vio.o: version.h hw.h sysfs.h vio.h
diff --git a/src/core/dasd.cc b/src/core/dasd.cc
deleted file mode 100644
index 626b8a8..0000000
--- a/src/core/dasd.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-#include "disk.h"
-#include "osutils.h"
-#include "dasd.h"
-#include <glob.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <sys/ioctl.h>
-#include <linux/fs.h>
-#include <map>
-
-using namespace std;
-
-/*Read only block devices, not partitions*/
-#define DEV_PATTERN "/dev/dasd[a-z]"
-#define SYSFS_PREFIX "/sys/block/"
-
-bool scan_dasd(hwNode & n)
-{
- size_t dev_num;
- char *dev_name;
- glob_t devices;
- uint64_t capacity;
-
- /* These correspond to filenames in the device/ sub-directory
- of each device
- To read other attributes, simply add the attribute here and modify the device object
- appropriately.
- */
- const char* attribs[] = {"devtype", "vendor"};
-
- std::vector<std::string> sysfs_attribs(attribs, attribs+2);
- std::map<std::string, std::string> dasd_attribs;
-
- hwNode *core = n.getChild("core");
-
- /* Probe the sysfs for this device*/
- if(glob(DEV_PATTERN, 0, NULL, &devices)!=0)
- return false;
- else
- {
- for(dev_num=0;dev_num<devices.gl_pathc;dev_num++)
- {
- dev_name = basename(devices.gl_pathv[dev_num]);
- for (std::vector<std::string>::iterator it = sysfs_attribs.begin(); it != sysfs_attribs.end(); ++it)
- {
- std::string attrib_fname = std::string(SYSFS_PREFIX) + dev_name + "/device/" + *it;
- std::vector<std::string> lines;
- if (loadfile(attrib_fname, lines) && (lines.size() > 0))
- {
- dasd_attribs[*it] = lines[0];
- }
- else
- {
- dasd_attribs[*it] = " ";
- }
- }
-
- hwNode device = hwNode("disk", hw::disk);
- device.setDescription("DASD Device");
- device.setVendor(dasd_attribs["vendor"]);
- device.setProduct(dasd_attribs["devtype"]);
- device.setLogicalName(devices.gl_pathv[dev_num]);
-
- /* Get the capacity*/
- int fd = open(devices.gl_pathv[dev_num], O_RDONLY|O_NONBLOCK);
- if (ioctl(fd, BLKGETSIZE64, &capacity) != 0)
- capacity=0;
- close(fd);
-
- device.setSize(capacity);
-
- /* Non-determinant*/
- device.setPhysId(0);
- scan_disk(device);
-
- hwNode *parent = core->addChild(device);
- parent->claim();
- }
- }
- return true;
-}
diff --git a/src/core/dasd.h b/src/core/dasd.h
deleted file mode 100644
index ad11c18..0000000
--- a/src/core/dasd.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _DASD_H_
-#define _DASD_H_
-
-#include "hw.h"
-
-bool scan_dasd(hwNode & n);
-#endif
diff --git a/src/core/main.cc b/src/core/main.cc
index 3c88f4c..c9a6e44 100644
--- a/src/core/main.cc
+++ b/src/core/main.cc
@@ -45,7 +45,7 @@
#include "vio.h"
#include "smp.h"
#include "abi.h"
-#include "dasd.h"
+#include "s390.h"
#include <unistd.h>
#include <stdio.h>
@@ -132,8 +132,9 @@ bool scan_system(hwNode & system)
status("SCSI");
if (enabled("scsi"))
scan_scsi(computer);
- if (enabled("dasd"))
- scan_dasd(computer);
+ status("S/390 devices");
+ if (enabled("s390"))
+ scan_s390_devices(computer);
if (enabled("mounts"))
scan_mounts(computer);
status("Network interfaces");
diff --git a/src/core/s390.cc b/src/core/s390.cc
new file mode 100644
index 0000000..81b2740
--- /dev/null
+++ b/src/core/s390.cc
@@ -0,0 +1,156 @@
+#include "hw.h"
+#include "sysfs.h"
+#include "disk.h"
+#include "s390.h"
+#include <string.h>
+
+using namespace std;
+
+struct ccw_device_def {
+ const char *cutype;
+ const char *devtype;
+ const char *description;
+ hw::hwClass hwClass;
+};
+struct ccw_device_def ccw_device_defs[] =
+{
+ {"1403", "", "Line printer", hw::printer},
+ {"1731/01", "1732/01", "OSA-Express QDIO channel", hw::network},
+ {"1731/02", "1732/02", "OSA-Express intraensemble data network (IEDN) channel", hw::network},
+ {"1731/02", "1732/03", "OSA-Express intranode management network (NMN) channel", hw::network},
+ {"1731/05", "1732/05", "HiperSockets network", hw::network},
+ {"1731/06", "1732/06", "OSA-Express Network Control Program channel", hw::network},
+ {"1731", "1732", "Network adapter", hw::network},
+ {"1750", "3380", "Direct attached storage device (ECKD mode)", hw::disk},
+ {"1750", "3390", "Direct attached storage device (ECKD mode)", hw::disk},
+ {"2105", "3380", "Direct attached storage device (ECKD mode)", hw::disk},
+ {"2105", "3390", "Direct attached storage device (ECKD mode)", hw::disk},
+ {"2107", "3380", "Direct attached storage device (ECKD mode)", hw::disk},
+ {"2107", "3390", "Direct attached storage device (ECKD mode)", hw::disk},
+ {"2540", "", "Card reader/punch", hw::generic},
+ {"3088/01", "", "P/390 LAN channel station card", hw::communication},
+ {"3088/08", "", "Channel-to-Channel device", hw::network},
+ {"3088/1e", "", "Channel-to-Channel FICON adapter", hw::network},
+ {"3088/1f", "", "Channel-to-Channel ESCON adapter", hw::network},
+ {"3088/60", "", "LAN channel station OSA-2 card", hw::network},
+ {"3174", "", "3174 Establishment Controller", hw::generic},
+ {"3215", "", "3215 terminal", hw::communication},
+ {"3270", "", "3270 terminal", hw::communication},
+ {"3271", "", "3270 terminal", hw::communication},
+ {"3272", "", "3270 terminal", hw::communication},
+ {"3273", "", "3270 terminal", hw::communication},
+ {"3274", "", "3270 terminal", hw::communication},
+ {"3275", "", "3270 terminal", hw::communication},
+ {"3276", "", "3270 terminal", hw::communication},
+ {"3277", "", "3270 terminal", hw::communication},
+ {"3278", "", "3270 terminal", hw::communication},
+ {"3279", "", "3270 terminal", hw::communication},
+ {"3480", "3480", "3480 tape drive", hw::storage},
+ {"3490", "3490", "3490 tape drive", hw::storage},
+ {"3590", "3590", "3590 tape drive", hw::storage},
+ {"3592", "3592", "3592 tape drive", hw::storage},
+ {"3832", "", "Virtual network device", hw::network},
+ {"3880", "3370", "Direct attached storage device (FBA mode)", hw::disk},
+ {"3880", "3380", "Direct attached storage device (ECKD mode)", hw::disk},
+ {"3990", "3380", "Direct attached storage device (ECKD mode)", hw::disk},
+ {"3990", "3390", "Direct attached storage device (ECKD mode)", hw::disk},
+ {"6310", "9336", "Direct attached storage device (FBA mode)", hw::disk},
+ {"9343", "9345", "Direct attached storage device (ECKD mode)", hw::disk},
+};
+
+static void ccw_devtype(hwNode & device, string cutype, string devtype)
+{
+ for (size_t i = 0; i < sizeof(ccw_device_defs) / sizeof(ccw_device_def); i ++)
+ {
+ ccw_device_def d = ccw_device_defs[i];
+ if (cutype.compare(0, strlen(d.cutype), d.cutype) == 0 &&
+ devtype.compare(0, strlen(d.devtype), d.devtype) == 0)
+ {
+ device.setClass(d.hwClass);
+ device.setDescription(d.description);
+ break;
+ }
+ }
+ if (!devtype.empty() && devtype != "n/a")
+ device.setProduct(devtype);
+}
+
+static bool scan_ccw(hwNode & n)
+{
+ vector < sysfs::entry > entries = sysfs::entries_by_bus("ccw");
+
+ if (entries.empty())
+ return false;
+
+ for (vector < sysfs::entry >::iterator it = entries.begin();
+ it != entries.end(); ++it)
+ {
+ const sysfs::entry & e = *it;
+
+ hwNode device("device");
+
+ ccw_devtype(device, e.string_attr("cutype"), e.string_attr("devtype"));
+ string vendor = hw::strip(e.string_attr("vendor"));
+ if (!vendor.empty())
+ device.setVendor(vendor);
+
+ string businfo = e.businfo();
+ if (!businfo.empty())
+ device.setBusInfo(businfo);
+
+ if (e.string_attr("online") != "1")
+ device.disable();
+
+ string driver = e.driver();
+ if (!driver.empty())
+ device.setConfig("driver", driver);
+
+ string devname = e.name_in_class("block");
+ if (!devname.empty())
+ {
+ device.setLogicalName(devname);
+ scan_disk(device);
+ }
+
+ device.claim();
+ n.addChild(device);
+ }
+
+ return true;
+}
+
+static bool scan_iucv(hwNode & n)
+{
+ vector < sysfs::entry > entries = sysfs::entries_by_bus("iucv");
+
+ if (entries.empty())
+ return false;
+
+ for (vector < sysfs::entry >::iterator it = entries.begin();
+ it != entries.end(); ++it)
+ {
+ const sysfs::entry & e = *it;
+
+ hwNode device(e.name());
+
+ string driver = e.driver();
+ if (!driver.empty())
+ device.setConfig("driver", driver);
+ if (driver == "hvc_iucv")
+ device.setDescription("z/VM IUCV hypervisor console");
+ else
+ device.setDescription("z/VM IUCV device");
+
+ device.claim();
+ n.addChild(device);
+ }
+
+ return true;
+}
+
+bool scan_s390_devices(hwNode & n)
+{
+ scan_ccw(n);
+ scan_iucv(n);
+ return true;
+}
diff --git a/src/core/s390.h b/src/core/s390.h
new file mode 100644
index 0000000..11aaec4
--- /dev/null
+++ b/src/core/s390.h
@@ -0,0 +1,7 @@
+#ifndef _S390_H_
+#define _S390_H_
+
+#include "hw.h"
+
+bool scan_s390_devices(hwNode & n);
+#endif
diff --git a/src/core/sysfs.cc b/src/core/sysfs.cc
index a2eca6c..fb7f2bb 100644
--- a/src/core/sysfs.cc
+++ b/src/core/sysfs.cc
@@ -149,6 +149,17 @@ static string sysfstobusinfo(const string & path)
if (bustype == "vio")
return string("vio@") + basename(path.c_str());
+ if (bustype == "ccw")
+ return string("ccw@") + basename(path.c_str());
+
+ if (bustype == "ccwgroup")
+ {
+ // just report businfo for the first device in the group
+ // because the group doesn't really fit into lshw's tree model
+ string firstdev = realpath(path + "/cdev0");
+ return sysfstobusinfo(firstdev);
+ }
+
return "";
}
--
2.10.2