s390/css: move subchannel lock allocation
authorSebastian Ott <sebott@linux.vnet.ibm.com>
Sat, 13 Apr 2013 11:08:01 +0000 (13:08 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Wed, 17 Apr 2013 12:07:34 +0000 (14:07 +0200)
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>
drivers/s390/cio/cio.c
drivers/s390/cio/cio.h
drivers/s390/cio/css.c

index 3ab99d88388802e3aaf0866f15aae97ccce868fc..af5fd716449fee27a8416df88e19b650c842b27c 100644 (file)
@@ -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;
 }
 
index 57b41ec2ed40d2b88b4ed0438c9369db4ea83450..d62f5e7f3cf100c217718614edabea5d5470a151 100644 (file)
@@ -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 *);
 
index 054fb428531f1260a26604d026aaf9cb41fd3d92..1ebe5d3ddebb28e7caddb0ec742bc76ce1307f78 100644 (file)
@@ -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;