s390/css: move subchannel lock allocation
cio_validate_subchannel is used to do some basic checks to find out if it's worth to further investigate a subchannel. Move the allocation and initialization of the subchannels locks to css_alloc_subchannel. Clean up the functions involved while at it. Reviewed-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com> 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
0ad8f714a1
commit
e5dcf0025d
|
@ -471,15 +471,6 @@ int cio_disable_subchannel(struct subchannel *sch)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(cio_disable_subchannel);
|
EXPORT_SYMBOL_GPL(cio_disable_subchannel);
|
||||||
|
|
||||||
int cio_create_sch_lock(struct subchannel *sch)
|
|
||||||
{
|
|
||||||
sch->lock = kmalloc(sizeof(spinlock_t), GFP_KERNEL);
|
|
||||||
if (!sch->lock)
|
|
||||||
return -ENOMEM;
|
|
||||||
spin_lock_init(sch->lock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cio_check_devno_blacklisted(struct subchannel *sch)
|
static int cio_check_devno_blacklisted(struct subchannel *sch)
|
||||||
{
|
{
|
||||||
if (is_blacklisted(sch->schid.ssid, sch->schib.pmcw.dev)) {
|
if (is_blacklisted(sch->schid.ssid, sch->schib.pmcw.dev)) {
|
||||||
|
@ -536,28 +527,19 @@ int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid)
|
||||||
sprintf(dbf_txt, "valsch%x", schid.sch_no);
|
sprintf(dbf_txt, "valsch%x", schid.sch_no);
|
||||||
CIO_TRACE_EVENT(4, dbf_txt);
|
CIO_TRACE_EVENT(4, dbf_txt);
|
||||||
|
|
||||||
/* Nuke all fields. */
|
|
||||||
memset(sch, 0, sizeof(struct subchannel));
|
|
||||||
|
|
||||||
sch->schid = schid;
|
|
||||||
err = cio_create_sch_lock(sch);
|
|
||||||
if (err)
|
|
||||||
goto out;
|
|
||||||
mutex_init(&sch->reg_mutex);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The first subchannel that is not-operational (ccode==3)
|
* The first subchannel that is not-operational (ccode==3)
|
||||||
* indicates that there aren't any more devices available.
|
* indicates that there aren't any more devices available.
|
||||||
* If stsch gets an exception, it means the current subchannel set
|
* If stsch gets an exception, it means the current subchannel set
|
||||||
* is not valid.
|
* is not valid.
|
||||||
*/
|
*/
|
||||||
ccode = stsch_err (schid, &sch->schib);
|
ccode = stsch_err(schid, &sch->schib);
|
||||||
if (ccode) {
|
if (ccode) {
|
||||||
err = (ccode == 3) ? -ENXIO : ccode;
|
err = (ccode == 3) ? -ENXIO : ccode;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
/* Copy subchannel type from path management control word. */
|
|
||||||
sch->st = sch->schib.pmcw.st;
|
sch->st = sch->schib.pmcw.st;
|
||||||
|
sch->schid = schid;
|
||||||
|
|
||||||
switch (sch->st) {
|
switch (sch->st) {
|
||||||
case SUBCHANNEL_TYPE_IO:
|
case SUBCHANNEL_TYPE_IO:
|
||||||
|
@ -574,10 +556,7 @@ int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid)
|
||||||
|
|
||||||
CIO_MSG_EVENT(4, "Subchannel 0.%x.%04x reports subchannel type %04X\n",
|
CIO_MSG_EVENT(4, "Subchannel 0.%x.%04x reports subchannel type %04X\n",
|
||||||
sch->schid.ssid, sch->schid.sch_no, sch->st);
|
sch->schid.ssid, sch->schid.sch_no, sch->st);
|
||||||
return 0;
|
|
||||||
out:
|
out:
|
||||||
kfree(sch->lock);
|
|
||||||
sch->lock = NULL;
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,7 +121,6 @@ extern int cio_commit_config(struct subchannel *sch);
|
||||||
int cio_tm_start_key(struct subchannel *sch, struct tcw *tcw, u8 lpm, u8 key);
|
int cio_tm_start_key(struct subchannel *sch, struct tcw *tcw, u8 lpm, u8 key);
|
||||||
int cio_tm_intrg(struct subchannel *sch);
|
int cio_tm_intrg(struct subchannel *sch);
|
||||||
|
|
||||||
int cio_create_sch_lock(struct subchannel *);
|
|
||||||
void do_adapter_IO(u8 isc);
|
void do_adapter_IO(u8 isc);
|
||||||
void do_IRQ(struct pt_regs *);
|
void do_IRQ(struct pt_regs *);
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,18 @@ out:
|
||||||
|
|
||||||
static void css_sch_todo(struct work_struct *work);
|
static void css_sch_todo(struct work_struct *work);
|
||||||
|
|
||||||
|
static int css_sch_create_locks(struct subchannel *sch)
|
||||||
|
{
|
||||||
|
sch->lock = kmalloc(sizeof(*sch->lock), GFP_KERNEL);
|
||||||
|
if (!sch->lock)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
spin_lock_init(sch->lock);
|
||||||
|
mutex_init(&sch->reg_mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void css_subchannel_release(struct device *dev)
|
static void css_subchannel_release(struct device *dev)
|
||||||
{
|
{
|
||||||
struct subchannel *sch = to_subchannel(dev);
|
struct subchannel *sch = to_subchannel(dev);
|
||||||
|
@ -152,18 +164,26 @@ struct subchannel *css_alloc_subchannel(struct subchannel_id schid)
|
||||||
struct subchannel *sch;
|
struct subchannel *sch;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
sch = kmalloc (sizeof (*sch), GFP_KERNEL | GFP_DMA);
|
sch = kzalloc(sizeof(*sch), GFP_KERNEL | GFP_DMA);
|
||||||
if (sch == NULL)
|
if (!sch)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
ret = cio_validate_subchannel (sch, schid);
|
|
||||||
if (ret < 0) {
|
ret = cio_validate_subchannel(sch, schid);
|
||||||
kfree(sch);
|
if (ret < 0)
|
||||||
return ERR_PTR(ret);
|
goto err;
|
||||||
}
|
|
||||||
|
ret = css_sch_create_locks(sch);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
|
||||||
INIT_WORK(&sch->todo_work, css_sch_todo);
|
INIT_WORK(&sch->todo_work, css_sch_todo);
|
||||||
sch->dev.release = &css_subchannel_release;
|
sch->dev.release = &css_subchannel_release;
|
||||||
device_initialize(&sch->dev);
|
device_initialize(&sch->dev);
|
||||||
return sch;
|
return sch;
|
||||||
|
|
||||||
|
err:
|
||||||
|
kfree(sch);
|
||||||
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int css_sch_device_register(struct subchannel *sch)
|
static int css_sch_device_register(struct subchannel *sch)
|
||||||
|
@ -756,7 +776,7 @@ static int __init setup_css(int nr)
|
||||||
css->pseudo_subchannel->dev.release = css_subchannel_release;
|
css->pseudo_subchannel->dev.release = css_subchannel_release;
|
||||||
dev_set_name(&css->pseudo_subchannel->dev, "defunct");
|
dev_set_name(&css->pseudo_subchannel->dev, "defunct");
|
||||||
mutex_init(&css->pseudo_subchannel->reg_mutex);
|
mutex_init(&css->pseudo_subchannel->reg_mutex);
|
||||||
ret = cio_create_sch_lock(css->pseudo_subchannel);
|
ret = css_sch_create_locks(css->pseudo_subchannel);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
kfree(css->pseudo_subchannel);
|
kfree(css->pseudo_subchannel);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in New Issue