[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>
This commit is contained in:
parent
74b6127e6c
commit
b730f3a933
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* 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,
|
||||||
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,
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* 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 @@
|
||||||
|
|
||||||
#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)
|
||||||
|
|
||||||
|
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue