aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2010-10-25 10:10:27 -0400
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2010-10-25 10:10:18 -0400
commitb730f3a933958362ee1080c257f2cc158149310a (patch)
treea86a6f49209447fafa866f846ed5258690892b79 /drivers
parent74b6127e6c35abf06364468636dd261850639f8b (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.c35
-rw-r--r--drivers/s390/cio/chp.h6
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
251static ssize_t chp_status_write(struct device *dev, 253static 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
275static DEVICE_ATTR(status, 0644, chp_status_show, chp_status_write); 280static 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
324static DEVICE_ATTR(type, 0444, chp_type_show, NULL); 331static 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
42struct channel_path { 43struct 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
53int chp_get_status(struct chp_id chpid); 55int chp_get_status(struct chp_id chpid);