diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2013-04-13 13:08:01 +0200 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-04-17 14:07:34 +0200 |
commit | e5dcf0025d7af58f525590ac86ac27cb44714e8d (patch) | |
tree | bfe935769fcb4c647a3add3587c088b9f835cac7 /drivers/s390/cio/css.c | |
parent | 0ad8f714a135cf993606c21fc1ed0e303ef17c0d (diff) |
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>
Diffstat (limited to 'drivers/s390/cio/css.c')
-rw-r--r-- | drivers/s390/cio/css.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 054fb428531f..1ebe5d3ddebb 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -137,6 +137,18 @@ out: 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; |