aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/css.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio/css.c')
-rw-r--r--drivers/s390/cio/css.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 3c77d65960dbf..5b304dbacaeb3 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -452,15 +452,50 @@ channel_subsystem_release(struct device *dev)
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 @@ init_channel_subsystem (void)
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_free:
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: