summaryrefslogtreecommitdiff
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.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 3b45bbe6cce0..595e327d2f76 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -533,6 +533,12 @@ void css_schedule_eval_all(void)
spin_unlock_irqrestore(&slow_subchannel_lock, flags);
}
+void css_wait_for_slow_path(void)
+{
+ flush_workqueue(ccw_device_notify_work);
+ flush_workqueue(slow_path_wq);
+}
+
/* Reprobe subchannel if unregistered. */
static int reprobe_subchannel(struct subchannel_id schid, void *data)
{
@@ -683,10 +689,14 @@ css_cm_enable_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct channel_subsystem *css = to_css(dev);
+ int ret;
if (!css)
return 0;
- return sprintf(buf, "%x\n", css->cm_enabled);
+ mutex_lock(&css->mutex);
+ ret = sprintf(buf, "%x\n", css->cm_enabled);
+ mutex_unlock(&css->mutex);
+ return ret;
}
static ssize_t
@@ -695,17 +705,23 @@ css_cm_enable_store(struct device *dev, struct device_attribute *attr,
{
struct channel_subsystem *css = to_css(dev);
int ret;
+ unsigned long val;
- switch (buf[0]) {
- case '0':
+ ret = strict_strtoul(buf, 16, &val);
+ if (ret)
+ return ret;
+ mutex_lock(&css->mutex);
+ switch (val) {
+ case 0:
ret = css->cm_enabled ? chsc_secm(css, 0) : 0;
break;
- case '1':
+ case 1:
ret = css->cm_enabled ? 0 : chsc_secm(css, 1);
break;
default:
ret = -EINVAL;
}
+ mutex_unlock(&css->mutex);
return ret < 0 ? ret : count;
}
@@ -752,9 +768,11 @@ static int css_reboot_event(struct notifier_block *this,
struct channel_subsystem *css;
css = channel_subsystems[i];
+ mutex_lock(&css->mutex);
if (css->cm_enabled)
if (chsc_secm(css, 0))
ret = NOTIFY_BAD;
+ mutex_unlock(&css->mutex);
}
return ret;