aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/chp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio/chp.c')
-rw-r--r--drivers/s390/cio/chp.c41
1 files changed, 23 insertions, 18 deletions
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c
index 6c9fa15aac7b..2d32233943a9 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>
@@ -54,12 +54,6 @@ static struct work_struct cfg_work;
54/* Wait queue for configure completion events. */ 54/* Wait queue for configure completion events. */
55static wait_queue_head_t cfg_wait_queue; 55static wait_queue_head_t cfg_wait_queue;
56 56
57/* Return channel_path struct for given chpid. */
58static inline struct channel_path *chpid_to_chp(struct chp_id chpid)
59{
60 return channel_subsystems[chpid.cssid]->chps[chpid.id];
61}
62
63/* Set vary state for given chpid. */ 57/* Set vary state for given chpid. */
64static void set_chp_logically_online(struct chp_id chpid, int onoff) 58static void set_chp_logically_online(struct chp_id chpid, int onoff)
65{ 59{
@@ -241,11 +235,13 @@ static ssize_t chp_status_show(struct device *dev,
241 struct device_attribute *attr, char *buf) 235 struct device_attribute *attr, char *buf)
242{ 236{
243 struct channel_path *chp = to_channelpath(dev); 237 struct channel_path *chp = to_channelpath(dev);
238 int status;
244 239
245 if (!chp) 240 mutex_lock(&chp->lock);
246 return 0; 241 status = chp->state;
247 return (chp_get_status(chp->chpid) ? sprintf(buf, "online\n") : 242 mutex_unlock(&chp->lock);
248 sprintf(buf, "offline\n")); 243
244 return status ? sprintf(buf, "online\n") : sprintf(buf, "offline\n");
249} 245}
250 246
251static ssize_t chp_status_write(struct device *dev, 247static ssize_t chp_status_write(struct device *dev,
@@ -261,15 +257,18 @@ static ssize_t chp_status_write(struct device *dev,
261 if (!num_args) 257 if (!num_args)
262 return count; 258 return count;
263 259
264 if (!strnicmp(cmd, "on", 2) || !strcmp(cmd, "1")) 260 if (!strnicmp(cmd, "on", 2) || !strcmp(cmd, "1")) {
261 mutex_lock(&cp->lock);
265 error = s390_vary_chpid(cp->chpid, 1); 262 error = s390_vary_chpid(cp->chpid, 1);
266 else if (!strnicmp(cmd, "off", 3) || !strcmp(cmd, "0")) 263 mutex_unlock(&cp->lock);
264 } else if (!strnicmp(cmd, "off", 3) || !strcmp(cmd, "0")) {
265 mutex_lock(&cp->lock);
267 error = s390_vary_chpid(cp->chpid, 0); 266 error = s390_vary_chpid(cp->chpid, 0);
268 else 267 mutex_unlock(&cp->lock);
268 } else
269 error = -EINVAL; 269 error = -EINVAL;
270 270
271 return error < 0 ? error : count; 271 return error < 0 ? error : count;
272
273} 272}
274 273
275static DEVICE_ATTR(status, 0644, chp_status_show, chp_status_write); 274static DEVICE_ATTR(status, 0644, chp_status_show, chp_status_write);
@@ -315,10 +314,12 @@ static ssize_t chp_type_show(struct device *dev, struct device_attribute *attr,
315 char *buf) 314 char *buf)
316{ 315{
317 struct channel_path *chp = to_channelpath(dev); 316 struct channel_path *chp = to_channelpath(dev);
317 u8 type;
318 318
319 if (!chp) 319 mutex_lock(&chp->lock);
320 return 0; 320 type = chp->desc.desc;
321 return sprintf(buf, "%x\n", chp->desc.desc); 321 mutex_unlock(&chp->lock);
322 return sprintf(buf, "%x\n", type);
322} 323}
323 324
324static DEVICE_ATTR(type, 0444, chp_type_show, NULL); 325static DEVICE_ATTR(type, 0444, chp_type_show, NULL);
@@ -395,6 +396,7 @@ int chp_new(struct chp_id chpid)
395 chp->state = 1; 396 chp->state = 1;
396 chp->dev.parent = &channel_subsystems[chpid.cssid]->device; 397 chp->dev.parent = &channel_subsystems[chpid.cssid]->device;
397 chp->dev.release = chp_release; 398 chp->dev.release = chp_release;
399 mutex_init(&chp->lock);
398 400
399 /* Obtain channel path description and fill it in. */ 401 /* Obtain channel path description and fill it in. */
400 ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc); 402 ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc);
@@ -464,7 +466,10 @@ void *chp_get_chp_desc(struct chp_id chpid)
464 desc = kmalloc(sizeof(struct channel_path_desc), GFP_KERNEL); 466 desc = kmalloc(sizeof(struct channel_path_desc), GFP_KERNEL);
465 if (!desc) 467 if (!desc)
466 return NULL; 468 return NULL;
469
470 mutex_lock(&chp->lock);
467 memcpy(desc, &chp->desc, sizeof(struct channel_path_desc)); 471 memcpy(desc, &chp->desc, sizeof(struct channel_path_desc));
472 mutex_unlock(&chp->lock);
468 return desc; 473 return desc;
469} 474}
470 475