diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2010-10-25 18:10:27 +0400 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2010-10-25 18:10:18 +0400 |
commit | b730f3a933958362ee1080c257f2cc158149310a (patch) | |
tree | a86a6f49209447fafa866f846ed5258690892b79 /drivers/s390/cio/chp.c | |
parent | 74b6127e6c35abf06364468636dd261850639f8b (diff) | |
download | linux-b730f3a933958362ee1080c257f2cc158149310a.tar.xz |
[S390] cio: add lock to struct channel_path
Serialize access to members of struct channel_path with a mutex.
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/chp.c')
-rw-r--r-- | drivers/s390/cio/chp.c | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index 6c9fa15aac7b..b1addd78689d 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -1,7 +1,7 @@ /* * drivers/s390/cio/chp.c * - * Copyright IBM Corp. 1999,2007 + * Copyright IBM Corp. 1999,2010 * Author(s): Cornelia Huck (cornelia.huck@de.ibm.com) * Arnd Bergmann (arndb@de.ibm.com) * Peter Oberparleiter <peter.oberparleiter@de.ibm.com> @@ -241,11 +241,13 @@ static ssize_t chp_status_show(struct device *dev, struct device_attribute *attr, char *buf) { struct channel_path *chp = to_channelpath(dev); + int status; - if (!chp) - return 0; - return (chp_get_status(chp->chpid) ? sprintf(buf, "online\n") : - sprintf(buf, "offline\n")); + mutex_lock(&chp->lock); + status = chp->state; + mutex_unlock(&chp->lock); + + return status ? sprintf(buf, "online\n") : sprintf(buf, "offline\n"); } static ssize_t chp_status_write(struct device *dev, @@ -261,15 +263,18 @@ static ssize_t chp_status_write(struct device *dev, if (!num_args) return count; - if (!strnicmp(cmd, "on", 2) || !strcmp(cmd, "1")) + if (!strnicmp(cmd, "on", 2) || !strcmp(cmd, "1")) { + mutex_lock(&cp->lock); error = s390_vary_chpid(cp->chpid, 1); - else if (!strnicmp(cmd, "off", 3) || !strcmp(cmd, "0")) + mutex_unlock(&cp->lock); + } else if (!strnicmp(cmd, "off", 3) || !strcmp(cmd, "0")) { + mutex_lock(&cp->lock); error = s390_vary_chpid(cp->chpid, 0); - else + mutex_unlock(&cp->lock); + } else error = -EINVAL; return error < 0 ? error : count; - } static DEVICE_ATTR(status, 0644, chp_status_show, chp_status_write); @@ -315,10 +320,12 @@ static ssize_t chp_type_show(struct device *dev, struct device_attribute *attr, char *buf) { struct channel_path *chp = to_channelpath(dev); + u8 type; - if (!chp) - return 0; - return sprintf(buf, "%x\n", chp->desc.desc); + mutex_lock(&chp->lock); + type = chp->desc.desc; + mutex_unlock(&chp->lock); + return sprintf(buf, "%x\n", type); } static DEVICE_ATTR(type, 0444, chp_type_show, NULL); @@ -395,6 +402,7 @@ int chp_new(struct chp_id chpid) chp->state = 1; chp->dev.parent = &channel_subsystems[chpid.cssid]->device; chp->dev.release = chp_release; + mutex_init(&chp->lock); /* Obtain channel path description and fill it in. */ ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc); @@ -464,7 +472,10 @@ void *chp_get_chp_desc(struct chp_id chpid) desc = kmalloc(sizeof(struct channel_path_desc), GFP_KERNEL); if (!desc) return NULL; + + mutex_lock(&chp->lock); memcpy(desc, &chp->desc, sizeof(struct channel_path_desc)); + mutex_unlock(&chp->lock); return desc; } |