mirror of https://gitee.com/openkylin/linux.git
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);
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
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)
|
||||
* 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
|
||||
* is not valid.
|
||||
* is not valid.
|
||||
*/
|
||||
ccode = stsch_err (schid, &sch->schib);
|
||||
ccode = stsch_err(schid, &sch->schib);
|
||||
if (ccode) {
|
||||
err = (ccode == 3) ? -ENXIO : ccode;
|
||||
goto out;
|
||||
}
|
||||
/* Copy subchannel type from path management control word. */
|
||||
sch->st = sch->schib.pmcw.st;
|
||||
sch->schid = schid;
|
||||
|
||||
switch (sch->st) {
|
||||
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",
|
||||
sch->schid.ssid, sch->schid.sch_no, sch->st);
|
||||
return 0;
|
||||
out:
|
||||
kfree(sch->lock);
|
||||
sch->lock = NULL;
|
||||
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_intrg(struct subchannel *sch);
|
||||
|
||||
int cio_create_sch_lock(struct subchannel *);
|
||||
void do_adapter_IO(u8 isc);
|
||||
void do_IRQ(struct pt_regs *);
|
||||
|
||||
|
|
|
@ -137,6 +137,18 @@ int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *),
|
|||
|
||||
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)
|
||||
{
|
||||
struct subchannel *sch = to_subchannel(dev);
|
||||
|
@ -152,18 +164,26 @@ struct subchannel *css_alloc_subchannel(struct subchannel_id schid)
|
|||
struct subchannel *sch;
|
||||
int ret;
|
||||
|
||||
sch = kmalloc (sizeof (*sch), GFP_KERNEL | GFP_DMA);
|
||||
if (sch == NULL)
|
||||
sch = kzalloc(sizeof(*sch), GFP_KERNEL | GFP_DMA);
|
||||
if (!sch)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
ret = cio_validate_subchannel (sch, schid);
|
||||
if (ret < 0) {
|
||||
kfree(sch);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
ret = cio_validate_subchannel(sch, schid);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = css_sch_create_locks(sch);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
INIT_WORK(&sch->todo_work, css_sch_todo);
|
||||
sch->dev.release = &css_subchannel_release;
|
||||
device_initialize(&sch->dev);
|
||||
return sch;
|
||||
|
||||
err:
|
||||
kfree(sch);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
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;
|
||||
dev_set_name(&css->pseudo_subchannel->dev, "defunct");
|
||||
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) {
|
||||
kfree(css->pseudo_subchannel);
|
||||
return ret;
|
||||
|
|
Loading…
Reference in New Issue