[POWERPC] iSeries: improve viodasd initialisation

On error, make sure that we undo all necessary operations.

This also gets rid of a must_check warning.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
Stephen Rothwell 2006-11-13 14:43:17 +11:00 коммит произвёл Paul Mackerras
Родитель 6ad4e70caf
Коммит f9df68ec7b
1 изменённых файлов: 36 добавлений и 13 удалений

Просмотреть файл

@ -759,6 +759,8 @@ static struct vio_driver viodasd_driver = {
} }
}; };
static int need_delete_probe;
/* /*
* Initialize the whole device driver. Handle module and non-module * Initialize the whole device driver. Handle module and non-module
* versions * versions
@ -773,46 +775,67 @@ static int __init viodasd_init(void)
if (viopath_hostLp == HvLpIndexInvalid) { if (viopath_hostLp == HvLpIndexInvalid) {
printk(VIOD_KERN_WARNING "invalid hosting partition\n"); printk(VIOD_KERN_WARNING "invalid hosting partition\n");
return -EIO; rc = -EIO;
goto early_fail;
} }
printk(VIOD_KERN_INFO "vers " VIOD_VERS ", hosting partition %d\n", printk(VIOD_KERN_INFO "vers " VIOD_VERS ", hosting partition %d\n",
viopath_hostLp); viopath_hostLp);
/* register the block device */ /* register the block device */
if (register_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME)) { rc = register_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME);
if (rc) {
printk(VIOD_KERN_WARNING printk(VIOD_KERN_WARNING
"Unable to get major number %d for %s\n", "Unable to get major number %d for %s\n",
VIODASD_MAJOR, VIOD_GENHD_NAME); VIODASD_MAJOR, VIOD_GENHD_NAME);
return -EIO; goto early_fail;
} }
/* Actually open the path to the hosting partition */ /* Actually open the path to the hosting partition */
if (viopath_open(viopath_hostLp, viomajorsubtype_blockio, rc = viopath_open(viopath_hostLp, viomajorsubtype_blockio,
VIOMAXREQ + 2)) { VIOMAXREQ + 2);
if (rc) {
printk(VIOD_KERN_WARNING printk(VIOD_KERN_WARNING
"error opening path to host partition %d\n", "error opening path to host partition %d\n",
viopath_hostLp); viopath_hostLp);
unregister_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME); goto unregister_blk;
return -EIO;
} }
/* Initialize our request handler */ /* Initialize our request handler */
vio_setHandler(viomajorsubtype_blockio, handle_block_event); vio_setHandler(viomajorsubtype_blockio, handle_block_event);
rc = vio_register_driver(&viodasd_driver); rc = vio_register_driver(&viodasd_driver);
if (rc == 0) if (rc) {
driver_create_file(&viodasd_driver.driver, &driver_attr_probe); printk(VIOD_KERN_WARNING "vio_register_driver failed\n");
goto unset_handler;
}
/*
* If this call fails, it just means that we cannot dynamically
* add virtual disks, but the driver will still work fine for
* all existing disk, so ignore the failure.
*/
if (!driver_create_file(&viodasd_driver.driver, &driver_attr_probe))
need_delete_probe = 1;
return 0;
unset_handler:
vio_clearHandler(viomajorsubtype_blockio);
viopath_close(viopath_hostLp, viomajorsubtype_blockio, VIOMAXREQ + 2);
unregister_blk:
unregister_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME);
early_fail:
return rc; return rc;
} }
module_init(viodasd_init); module_init(viodasd_init);
void viodasd_exit(void) void __exit viodasd_exit(void)
{ {
driver_remove_file(&viodasd_driver.driver, &driver_attr_probe); if (need_delete_probe)
driver_remove_file(&viodasd_driver.driver, &driver_attr_probe);
vio_unregister_driver(&viodasd_driver); vio_unregister_driver(&viodasd_driver);
vio_clearHandler(viomajorsubtype_blockio); vio_clearHandler(viomajorsubtype_blockio);
unregister_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME);
viopath_close(viopath_hostLp, viomajorsubtype_blockio, VIOMAXREQ + 2); viopath_close(viopath_hostLp, viomajorsubtype_blockio, VIOMAXREQ + 2);
unregister_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME);
} }
module_exit(viodasd_exit); module_exit(viodasd_exit);