[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:
Родитель
6ad4e70caf
Коммит
f9df68ec7b
|
@ -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);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче