[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 86105efb4eb6cb948314a69b3b754ffdc290771a..0ecac7e532f6b70372c84b6cc52638cc8edcfb7e 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 3234e90bd7f99b6bc632c9844e53e4e479f0aae2..89ece1c235aa7d4919a5efd505196137a156409c 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 c20a4fe6da514d4f079d859b8c0775b3f9589272..d1a142fa3eb46c000fe00654aa43a1c5253102f3 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 3e5f304ad88fea3d10598c2e88223472f8a4d113..40002830d48a83030cf3158201f43e3d0bc14885 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 0a3ce6522f0bfce9c68913c6aad8d804955b4cb9..45858f3b731887833777474362ca5c4ffde0cdd1 100644 (file)
@@ -151,18 +151,6 @@ css_alloc_subchannel(struct subchannel_id schid)
        return sch;
 }
 
-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)
 {
@@ -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 ed3dcdea7fe10cb7b521f7ccdb78a1bb5bfc86cc..ae9ab240c7f13f5dd612564f7795c31d243d9782 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 8c36eafcfbfeb5957460196f4fca9a387ca2bdbb..87dff11061b0cc4cc91c1076afa30bffd81115ee 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 e76a320d373baeb99e32b16a9ac954ad65a00380..102000d1af6f9d8912e325f9796d4caf3028d1a8 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;