Commit b730f3a9 authored by Sebastian Ott's avatar Sebastian Ott Committed by Martin Schwidefsky

[S390] cio: add lock to struct channel_path

Serialize access to members of struct channel_path with a mutex.
Signed-off-by: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 74b6127e
/* /*
* drivers/s390/cio/chp.c * drivers/s390/cio/chp.c
* *
* Copyright IBM Corp. 1999,2007 * Copyright IBM Corp. 1999,2010
* Author(s): Cornelia Huck (cornelia.huck@de.ibm.com) * Author(s): Cornelia Huck (cornelia.huck@de.ibm.com)
* Arnd Bergmann (arndb@de.ibm.com) * Arnd Bergmann (arndb@de.ibm.com)
* Peter Oberparleiter <peter.oberparleiter@de.ibm.com> * Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
...@@ -241,11 +241,13 @@ static ssize_t chp_status_show(struct device *dev, ...@@ -241,11 +241,13 @@ static ssize_t chp_status_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct channel_path *chp = to_channelpath(dev); struct channel_path *chp = to_channelpath(dev);
int status;
if (!chp) mutex_lock(&chp->lock);
return 0; status = chp->state;
return (chp_get_status(chp->chpid) ? sprintf(buf, "online\n") : mutex_unlock(&chp->lock);
sprintf(buf, "offline\n"));
return status ? sprintf(buf, "online\n") : sprintf(buf, "offline\n");
} }
static ssize_t chp_status_write(struct device *dev, static ssize_t chp_status_write(struct device *dev,
...@@ -261,15 +263,18 @@ 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) if (!num_args)
return count; 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); 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); error = s390_vary_chpid(cp->chpid, 0);
else mutex_unlock(&cp->lock);
} else
error = -EINVAL; error = -EINVAL;
return error < 0 ? error : count; return error < 0 ? error : count;
} }
static DEVICE_ATTR(status, 0644, chp_status_show, chp_status_write); 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,10 +320,12 @@ static ssize_t chp_type_show(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
struct channel_path *chp = to_channelpath(dev); struct channel_path *chp = to_channelpath(dev);
u8 type;
if (!chp) mutex_lock(&chp->lock);
return 0; type = chp->desc.desc;
return sprintf(buf, "%x\n", chp->desc.desc); mutex_unlock(&chp->lock);
return sprintf(buf, "%x\n", type);
} }
static DEVICE_ATTR(type, 0444, chp_type_show, NULL); static DEVICE_ATTR(type, 0444, chp_type_show, NULL);
...@@ -395,6 +402,7 @@ int chp_new(struct chp_id chpid) ...@@ -395,6 +402,7 @@ int chp_new(struct chp_id chpid)
chp->state = 1; chp->state = 1;
chp->dev.parent = &channel_subsystems[chpid.cssid]->device; chp->dev.parent = &channel_subsystems[chpid.cssid]->device;
chp->dev.release = chp_release; chp->dev.release = chp_release;
mutex_init(&chp->lock);
/* Obtain channel path description and fill it in. */ /* Obtain channel path description and fill it in. */
ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc); ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc);
...@@ -464,7 +472,10 @@ void *chp_get_chp_desc(struct chp_id chpid) ...@@ -464,7 +472,10 @@ void *chp_get_chp_desc(struct chp_id chpid)
desc = kmalloc(sizeof(struct channel_path_desc), GFP_KERNEL); desc = kmalloc(sizeof(struct channel_path_desc), GFP_KERNEL);
if (!desc) if (!desc)
return NULL; return NULL;
mutex_lock(&chp->lock);
memcpy(desc, &chp->desc, sizeof(struct channel_path_desc)); memcpy(desc, &chp->desc, sizeof(struct channel_path_desc));
mutex_unlock(&chp->lock);
return desc; return desc;
} }
......
/* /*
* drivers/s390/cio/chp.h * drivers/s390/cio/chp.h
* *
* Copyright IBM Corp. 2007 * Copyright IBM Corp. 2007,2010
* Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
*/ */
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/mutex.h>
#include <asm/chpid.h> #include <asm/chpid.h>
#include "chsc.h" #include "chsc.h"
#include "css.h" #include "css.h"
...@@ -40,14 +41,15 @@ static inline int chp_test_bit(u8 *bitmap, int num) ...@@ -40,14 +41,15 @@ static inline int chp_test_bit(u8 *bitmap, int num)
struct channel_path { struct channel_path {
struct device dev;
struct chp_id chpid; struct chp_id chpid;
struct mutex lock; /* Serialize access to below members. */
int state; int state;
struct channel_path_desc desc; struct channel_path_desc desc;
/* Channel-measurement related stuff: */ /* Channel-measurement related stuff: */
int cmg; int cmg;
int shared; int shared;
void *cmg_chars; void *cmg_chars;
struct device dev;
}; };
int chp_get_status(struct chp_id chpid); int chp_get_status(struct chp_id chpid);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment