[PATCH] s390: channel path measurements

Gather extended measurements for channel paths from the channel subsystem and
expose them to userspace via a sysfs attribute.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 3c77d65..5b304db 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -452,15 +452,50 @@
 	struct channel_subsystem *css;
 
 	css = to_css(dev);
+	mutex_destroy(&css->mutex);
 	kfree(css);
 }
 
+static ssize_t
+css_cm_enable_show(struct device *dev, struct device_attribute *attr,
+		   char *buf)
+{
+	struct channel_subsystem *css = to_css(dev);
+
+	if (!css)
+		return 0;
+	return sprintf(buf, "%x\n", css->cm_enabled);
+}
+
+static ssize_t
+css_cm_enable_store(struct device *dev, struct device_attribute *attr,
+		    const char *buf, size_t count)
+{
+	struct channel_subsystem *css = to_css(dev);
+	int ret;
+
+	switch (buf[0]) {
+	case '0':
+		ret = css->cm_enabled ? chsc_secm(css, 0) : 0;
+		break;
+	case '1':
+		ret = css->cm_enabled ? 0 : chsc_secm(css, 1);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+	return ret < 0 ? ret : count;
+}
+
+static DEVICE_ATTR(cm_enable, 0644, css_cm_enable_show, css_cm_enable_store);
+
 static inline void __init
 setup_css(int nr)
 {
 	u32 tod_high;
 
 	memset(css[nr], 0, sizeof(struct channel_subsystem));
+	mutex_init(&css[nr]->mutex);
 	css[nr]->valid = 1;
 	css[nr]->cssid = nr;
 	sprintf(css[nr]->device.bus_id, "css%x", nr);
@@ -507,6 +542,9 @@
 		ret = device_register(&css[i]->device);
 		if (ret)
 			goto out_free;
+		if (css_characteristics_avail && css_chsc_characteristics.secm)
+			device_create_file(&css[i]->device,
+					   &dev_attr_cm_enable);
 	}
 	css_init_done = 1;
 
@@ -519,6 +557,9 @@
 out_unregister:
 	while (i > 0) {
 		i--;
+		if (css_characteristics_avail && css_chsc_characteristics.secm)
+			device_remove_file(&css[i]->device,
+					   &dev_attr_cm_enable);
 		device_unregister(&css[i]->device);
 	}
 out_bus: