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 | |
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')
-rw-r--r-- | drivers/s390/cio/chp.c | 35 | ||||
-rw-r--r-- | drivers/s390/cio/chp.h | 6 |
2 files changed, 27 insertions, 14 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 | ||
diff --git a/drivers/s390/cio/chp.h b/drivers/s390/cio/chp.h index 26c3d2246176..695ec20f1c59 100644 --- a/drivers/s390/cio/chp.h +++ b/drivers/s390/cio/chp.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/s390/cio/chp.h | 2 | * drivers/s390/cio/chp.h |
3 | * | 3 | * |
4 | * Copyright IBM Corp. 2007 | 4 | * Copyright IBM Corp. 2007,2010 |
5 | * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | 5 | * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> |
6 | */ | 6 | */ |
7 | 7 | ||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
12 | #include <linux/device.h> | 12 | #include <linux/device.h> |
13 | #include <linux/mutex.h> | ||
13 | #include <asm/chpid.h> | 14 | #include <asm/chpid.h> |
14 | #include "chsc.h" | 15 | #include "chsc.h" |
15 | #include "css.h" | 16 | #include "css.h" |
@@ -40,14 +41,15 @@ static inline int chp_test_bit(u8 *bitmap, int num) | |||
40 | 41 | ||
41 | 42 | ||
42 | struct channel_path { | 43 | struct channel_path { |
44 | struct device dev; | ||
43 | struct chp_id chpid; | 45 | struct chp_id chpid; |
46 | struct mutex lock; /* Serialize access to below members. */ | ||
44 | int state; | 47 | int state; |
45 | struct channel_path_desc desc; | 48 | struct channel_path_desc desc; |
46 | /* Channel-measurement related stuff: */ | 49 | /* Channel-measurement related stuff: */ |
47 | int cmg; | 50 | int cmg; |
48 | int shared; | 51 | int shared; |
49 | void *cmg_chars; | 52 | void *cmg_chars; |
50 | struct device dev; | ||
51 | }; | 53 | }; |
52 | 54 | ||
53 | int chp_get_status(struct chp_id chpid); | 55 | int chp_get_status(struct chp_id chpid); |