[S390] proper use of device register
authorSebastian Ott <sebott@linux.vnet.ibm.com>
Fri, 11 Sep 2009 08:28:38 +0000 (10:28 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Fri, 11 Sep 2009 08:29:45 +0000 (10:29 +0200)
Don't use kfree directly after device registration started.

Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
drivers/char/hvc_iucv.c
drivers/s390/char/monreader.c
drivers/s390/char/vmlogrdr.c
drivers/s390/cio/chp.c
drivers/s390/cio/css.c
drivers/s390/crypto/ap_bus.c
drivers/s390/net/netiucv.c
drivers/s390/net/smsgiucv.c

index 86105ef..0ecac7e 100644 (file)
@@ -1006,7 +1006,7 @@ static int __init hvc_iucv_alloc(int id, unsigned int is_console)
        priv->dev->release = (void (*)(struct device *)) kfree;
        rc = device_register(priv->dev);
        if (rc) {
-               kfree(priv->dev);
+               put_device(priv->dev);
                goto out_error_dev;
        }
 
index 3234e90..89ece1c 100644 (file)
@@ -581,7 +581,7 @@ static int __init mon_init(void)
        monreader_device->release = (void (*)(struct device *))kfree;
        rc = device_register(monreader_device);
        if (rc) {
-               kfree(monreader_device);
+               put_device(monreader_device);
                goto out_driver;
        }
 
index c20a4fe..d1a142f 100644 (file)
@@ -765,8 +765,10 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv)
        } else
                return -ENOMEM;
        ret = device_register(dev);
-       if (ret)
+       if (ret) {
+               put_device(dev);
                return ret;
+       }
 
        ret = sysfs_create_group(&dev->kobj, &vmlogrdr_attr_group);
        if (ret) {
index 3e5f304..4000283 100644 (file)
@@ -417,7 +417,8 @@ int chp_new(struct chp_id chpid)
        if (ret) {
                CIO_MSG_EVENT(0, "Could not register chp%x.%02x: %d\n",
                              chpid.cssid, chpid.id, ret);
-               goto out_free;
+               put_device(&chp->dev);
+               goto out;
        }
        ret = sysfs_create_group(&chp->dev.kobj, &chp_attr_group);
        if (ret) {
index 0a3ce65..45858f3 100644 (file)
@@ -152,18 +152,6 @@ css_alloc_subchannel(struct subchannel_id schid)
 }
 
 static void
-css_free_subchannel(struct subchannel *sch)
-{
-       if (sch) {
-               /* Reset intparm to zeroes. */
-               sch->config.intparm = 0;
-               cio_commit_config(sch);
-               kfree(sch->lock);
-               kfree(sch);
-       }
-}
-
-static void
 css_subchannel_release(struct device *dev)
 {
        struct subchannel *sch;
@@ -332,7 +320,7 @@ int css_probe_device(struct subchannel_id schid)
                return PTR_ERR(sch);
        ret = css_register_subchannel(sch);
        if (ret)
-               css_free_subchannel(sch);
+               put_device(&sch->dev);
        return ret;
 }
 
@@ -649,7 +637,10 @@ __init_channel_subsystem(struct subchannel_id schid, void *data)
         * not working) so we do it now. This is true e.g. for the
         * console subchannel.
         */
-       css_register_subchannel(sch);
+       if (css_register_subchannel(sch)) {
+               if (!cio_is_console(schid))
+                       put_device(&sch->dev);
+       }
        return 0;
 }
 
@@ -925,8 +916,10 @@ init_channel_subsystem (void)
                                goto out_device;
                }
                ret = device_register(&css->pseudo_subchannel->dev);
-               if (ret)
+               if (ret) {
+                       put_device(&css->pseudo_subchannel->dev);
                        goto out_file;
+               }
        }
        ret = register_reboot_notifier(&css_reboot_notifier);
        if (ret)
index ed3dcde..ae9ab24 100644 (file)
@@ -1114,7 +1114,7 @@ static void ap_scan_bus(struct work_struct *unused)
                ap_dev->device.release = ap_device_release;
                rc = device_register(&ap_dev->device);
                if (rc) {
-                       kfree(ap_dev);
+                       put_device(&ap_dev->device);
                        continue;
                }
                /* Add device attributes. */
index 8c36eaf..87dff11 100644 (file)
@@ -1839,9 +1839,10 @@ static int netiucv_register_device(struct net_device *ndev)
                return -ENOMEM;
 
        ret = device_register(dev);
-
-       if (ret)
+       if (ret) {
+               put_device(dev);
                return ret;
+       }
        ret = netiucv_add_files(dev);
        if (ret)
                goto out_unreg;
@@ -2226,8 +2227,10 @@ static int __init netiucv_init(void)
        netiucv_dev->release = (void (*)(struct device *))kfree;
        netiucv_dev->driver = &netiucv_driver;
        rc = device_register(netiucv_dev);
-       if (rc)
+       if (rc) {
+               put_device(netiucv_dev);
                goto out_driver;
+       }
        netiucv_banner();
        return rc;
 
index e76a320..102000d 100644 (file)
@@ -219,13 +219,13 @@ static int __init smsg_init(void)
        smsg_dev->driver = &smsg_driver;
        rc = device_register(smsg_dev);
        if (rc)
-               goto out_free_dev;
+               goto out_put;
 
        cpcmd("SET SMSG IUCV", NULL, 0, NULL);
        return 0;
 
-out_free_dev:
-       kfree(smsg_dev);
+out_put:
+       put_device(smsg_dev);
 out_free_path:
        iucv_path_free(smsg_path);
        smsg_path = NULL;