diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2010-10-25 10:10:27 -0400 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2010-10-25 10:10:18 -0400 |
commit | b730f3a933958362ee1080c257f2cc158149310a (patch) | |
tree | a86a6f49209447fafa866f846ed5258690892b79 /drivers/s390/cio/chp.c | |
parent | 74b6127e6c35abf06364468636dd261850639f8b (diff) |
[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 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/s390/cio/chp.c | 2 | * drivers/s390/cio/chp.c |
3 | * | 3 | * |
4 | * Copyright IBM Corp. 1999,2007 | 4 | * Copyright IBM Corp. 1999,2010 |
5 | * Author(s): Cornelia Huck (cornelia.huck@de.ibm.com) | 5 | * Author(s): Cornelia Huck (cornelia.huck@de.ibm.com) |
6 | * Arnd Bergmann (arndb@de.ibm.com) | 6 | * Arnd Bergmann (arndb@de.ibm.com) |
7 | * Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | 7 | * Peter Oberparleiter <peter.oberparleiter@de.ibm.com> |
@@ -241,11 +241,13 @@ static ssize_t chp_status_show(struct device *dev, | |||
241 | struct device_attribute *attr, char *buf) | 241 | struct device_attribute *attr, char *buf) |
242 | { | 242 | { |
243 | struct channel_path *chp = to_channelpath(dev); | 243 | struct channel_path *chp = to_channelpath(dev); |
244 | int status; | ||
244 | 245 | ||
245 | if (!chp) | 246 | mutex_lock(&chp->lock); |
246 | return 0; | 247 | status = chp->state; |
247 | return (chp_get_status(chp->chpid) ? sprintf(buf, "online\n") : | 248 | mutex_unlock(&chp->lock); |
248 | sprintf(buf, "offline\n")); | 249 | |
250 | return status ? sprintf(buf, "online\n") : sprintf(buf, "offline\n"); | ||
249 | } | 251 | } |
250 | 252 | ||
251 | static ssize_t chp_status_write(struct device *dev, | 253 | static ssize_t chp_status_write(struct device *dev, |
@@ -261,15 +263,18 @@ static ssize_t chp_status_write(struct device *dev, | |||
261 | if (!num_args) | 263 | if (!num_args) |
262 | return count; | 264 | return count; |
263 | 265 | ||
264 | if (!strnicmp(cmd, "on", 2) || !strcmp(cmd, "1")) | 266 | if (!strnicmp(cmd, "on", 2) || !strcmp(cmd, "1")) { |
267 | mutex_lock(&cp->lock); | ||
265 | error = s390_vary_chpid(cp->chpid, 1); | 268 | error = s390_vary_chpid(cp->chpid, 1); |
266 | else if (!strnicmp(cmd, "off", 3) || !strcmp(cmd, "0")) | 269 | mutex_unlock(&cp->lock); |
270 | } else if (!strnicmp(cmd, "off", 3) || !strcmp(cmd, "0")) { | ||
271 | mutex_lock(&cp->lock); | ||
267 | error = s390_vary_chpid(cp->chpid, 0); | 272 | error = s390_vary_chpid(cp->chpid, 0); |
268 | else | 273 | mutex_unlock(&cp->lock); |
274 | } else | ||
269 | error = -EINVAL; | 275 | error = -EINVAL; |
270 | 276 | ||
271 | return error < 0 ? error : count; | 277 | return error < 0 ? error : count; |
272 | |||
273 | } | 278 | } |
274 | 279 | ||
275 | static DEVICE_ATTR(status, 0644, chp_status_show, chp_status_write); | 280 | 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, | |||
315 | char *buf) | 320 | char *buf) |
316 | { | 321 | { |
317 | struct channel_path *chp = to_channelpath(dev); | 322 | struct channel_path *chp = to_channelpath(dev); |
323 | u8 type; | ||
318 | 324 | ||
319 | if (!chp) | 325 | mutex_lock(&chp->lock); |
320 | return 0; | 326 | type = chp->desc.desc; |
321 | return sprintf(buf, "%x\n", chp->desc.desc); | 327 | mutex_unlock(&chp->lock); |
328 | return sprintf(buf, "%x\n", type); | ||
322 | } | 329 | } |
323 | 330 | ||
324 | static DEVICE_ATTR(type, 0444, chp_type_show, NULL); | 331 | static DEVICE_ATTR(type, 0444, chp_type_show, NULL); |
@@ -395,6 +402,7 @@ int chp_new(struct chp_id chpid) | |||
395 | chp->state = 1; | 402 | chp->state = 1; |
396 | chp->dev.parent = &channel_subsystems[chpid.cssid]->device; | 403 | chp->dev.parent = &channel_subsystems[chpid.cssid]->device; |
397 | chp->dev.release = chp_release; | 404 | chp->dev.release = chp_release; |
405 | mutex_init(&chp->lock); | ||
398 | 406 | ||
399 | /* Obtain channel path description and fill it in. */ | 407 | /* Obtain channel path description and fill it in. */ |
400 | ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc); | 408 | ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc); |
@@ -464,7 +472,10 @@ void *chp_get_chp_desc(struct chp_id chpid) | |||
464 | desc = kmalloc(sizeof(struct channel_path_desc), GFP_KERNEL); | 472 | desc = kmalloc(sizeof(struct channel_path_desc), GFP_KERNEL); |
465 | if (!desc) | 473 | if (!desc) |
466 | return NULL; | 474 | return NULL; |
475 | |||
476 | mutex_lock(&chp->lock); | ||
467 | memcpy(desc, &chp->desc, sizeof(struct channel_path_desc)); | 477 | memcpy(desc, &chp->desc, sizeof(struct channel_path_desc)); |
478 | mutex_unlock(&chp->lock); | ||
468 | return desc; | 479 | return desc; |
469 | } | 480 | } |
470 | 481 | ||