Messages in this thread Patch in this message | | | Date | Mon, 16 Jul 2007 22:51:38 +0900 | From | Akinobu Mita <> | Subject | [PATCH 2/10] sysdev: add error check in sysdev_register() |
| |
This patch enables to catch the errors returned by add() procedure of sysdev driver in sysdev_register.
Cc: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
--- drivers/base/sys.c | 48 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 10 deletions(-)
Index: 2.6-mm/drivers/base/sys.c =================================================================== --- 2.6-mm.orig/drivers/base/sys.c +++ 2.6-mm/drivers/base/sys.c @@ -220,10 +220,13 @@ EXPORT_SYMBOL_GPL(sysdev_driver_unregist * @sysdev: device in question * */ -int sysdev_register(struct sys_device * sysdev) +int sysdev_register(struct sys_device *sysdev) { int error; - struct sysdev_class * cls = sysdev->cls; + struct sysdev_class *cls = sysdev->cls; + struct sysdev_driver *drv; + int added_sysdev = 0; + int added_cls = 0; if (!cls) return -EINVAL; @@ -244,8 +247,6 @@ int sysdev_register(struct sys_device * error = kobject_register(&sysdev->kobj); if (!error) { - struct sysdev_driver * drv; - mutex_lock(&sysdev_drivers_lock); /* Generic notification is implicit, because it's that * code that should have called us. @@ -253,23 +254,50 @@ int sysdev_register(struct sys_device * /* Notify global drivers */ list_for_each_entry(drv, &sysdev_drivers, entry) { - if (drv->add) - drv->add(sysdev); + if (drv->add) { + error = drv->add(sysdev); + if (error) + goto error_sysdev; + } + added_sysdev++; } /* Notify class auxillary drivers */ list_for_each_entry(drv, &cls->drivers, entry) { - if (drv->add) - drv->add(sysdev); + if (drv->add) { + error = drv->add(sysdev); + if (error) + goto error_cls; + } + added_cls++; } mutex_unlock(&sysdev_drivers_lock); } return error; + +error_cls: + list_for_each_entry(drv, &cls->drivers, entry) { + if (added_sysdev--) + break; + if (drv->add && drv->remove) + drv->remove(sysdev); + } +error_sysdev: + list_for_each_entry(drv, &sysdev_drivers, entry) { + if (added_cls--) + break; + if (drv->add && drv->remove) + drv->remove(sysdev); + } + mutex_unlock(&sysdev_drivers_lock); + kobject_unregister(&sysdev->kobj); + + return error; } -void sysdev_unregister(struct sys_device * sysdev) +void sysdev_unregister(struct sys_device *sysdev) { - struct sysdev_driver * drv; + struct sysdev_driver *drv; mutex_lock(&sysdev_drivers_lock); list_for_each_entry(drv, &sysdev_drivers, entry) { - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |