diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2006-11-12 22:43:17 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-12-04 04:39:10 -0500 |
commit | f9df68ec7bf49e37b46aa0a5d9e7938c060dba52 (patch) | |
tree | d3a8918428d17e9a650459a19d3df882b0bc035d /drivers | |
parent | 6ad4e70cafc43155d3a7e6e796e8b6b6967fc9e2 (diff) |
[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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/viodasd.c | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index ec5a1b90a0a2..e19ba4ebcd4e 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c | |||
@@ -759,6 +759,8 @@ static struct vio_driver viodasd_driver = { | |||
759 | } | 759 | } |
760 | }; | 760 | }; |
761 | 761 | ||
762 | static int need_delete_probe; | ||
763 | |||
762 | /* | 764 | /* |
763 | * Initialize the whole device driver. Handle module and non-module | 765 | * Initialize the whole device driver. Handle module and non-module |
764 | * versions | 766 | * versions |
@@ -773,46 +775,67 @@ static int __init viodasd_init(void) | |||
773 | 775 | ||
774 | if (viopath_hostLp == HvLpIndexInvalid) { | 776 | if (viopath_hostLp == HvLpIndexInvalid) { |
775 | printk(VIOD_KERN_WARNING "invalid hosting partition\n"); | 777 | printk(VIOD_KERN_WARNING "invalid hosting partition\n"); |
776 | return -EIO; | 778 | rc = -EIO; |
779 | goto early_fail; | ||
777 | } | 780 | } |
778 | 781 | ||
779 | printk(VIOD_KERN_INFO "vers " VIOD_VERS ", hosting partition %d\n", | 782 | printk(VIOD_KERN_INFO "vers " VIOD_VERS ", hosting partition %d\n", |
780 | viopath_hostLp); | 783 | viopath_hostLp); |
781 | 784 | ||
782 | /* register the block device */ | 785 | /* register the block device */ |
783 | if (register_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME)) { | 786 | rc = register_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME); |
787 | if (rc) { | ||
784 | printk(VIOD_KERN_WARNING | 788 | printk(VIOD_KERN_WARNING |
785 | "Unable to get major number %d for %s\n", | 789 | "Unable to get major number %d for %s\n", |
786 | VIODASD_MAJOR, VIOD_GENHD_NAME); | 790 | VIODASD_MAJOR, VIOD_GENHD_NAME); |
787 | return -EIO; | 791 | goto early_fail; |
788 | } | 792 | } |
789 | /* Actually open the path to the hosting partition */ | 793 | /* Actually open the path to the hosting partition */ |
790 | if (viopath_open(viopath_hostLp, viomajorsubtype_blockio, | 794 | rc = viopath_open(viopath_hostLp, viomajorsubtype_blockio, |
791 | VIOMAXREQ + 2)) { | 795 | VIOMAXREQ + 2); |
796 | if (rc) { | ||
792 | printk(VIOD_KERN_WARNING | 797 | printk(VIOD_KERN_WARNING |
793 | "error opening path to host partition %d\n", | 798 | "error opening path to host partition %d\n", |
794 | viopath_hostLp); | 799 | viopath_hostLp); |
795 | unregister_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME); | 800 | goto unregister_blk; |
796 | return -EIO; | ||
797 | } | 801 | } |
798 | 802 | ||
799 | /* Initialize our request handler */ | 803 | /* Initialize our request handler */ |
800 | vio_setHandler(viomajorsubtype_blockio, handle_block_event); | 804 | vio_setHandler(viomajorsubtype_blockio, handle_block_event); |
801 | 805 | ||
802 | rc = vio_register_driver(&viodasd_driver); | 806 | rc = vio_register_driver(&viodasd_driver); |
803 | if (rc == 0) | 807 | if (rc) { |
804 | driver_create_file(&viodasd_driver.driver, &driver_attr_probe); | 808 | printk(VIOD_KERN_WARNING "vio_register_driver failed\n"); |
809 | goto unset_handler; | ||
810 | } | ||
811 | |||
812 | /* | ||
813 | * If this call fails, it just means that we cannot dynamically | ||
814 | * add virtual disks, but the driver will still work fine for | ||
815 | * all existing disk, so ignore the failure. | ||
816 | */ | ||
817 | if (!driver_create_file(&viodasd_driver.driver, &driver_attr_probe)) | ||
818 | need_delete_probe = 1; | ||
819 | |||
820 | return 0; | ||
821 | |||
822 | unset_handler: | ||
823 | vio_clearHandler(viomajorsubtype_blockio); | ||
824 | viopath_close(viopath_hostLp, viomajorsubtype_blockio, VIOMAXREQ + 2); | ||
825 | unregister_blk: | ||
826 | unregister_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME); | ||
827 | early_fail: | ||
805 | return rc; | 828 | return rc; |
806 | } | 829 | } |
807 | module_init(viodasd_init); | 830 | module_init(viodasd_init); |
808 | 831 | ||
809 | void viodasd_exit(void) | 832 | void __exit viodasd_exit(void) |
810 | { | 833 | { |
811 | driver_remove_file(&viodasd_driver.driver, &driver_attr_probe); | 834 | if (need_delete_probe) |
835 | driver_remove_file(&viodasd_driver.driver, &driver_attr_probe); | ||
812 | vio_unregister_driver(&viodasd_driver); | 836 | vio_unregister_driver(&viodasd_driver); |
813 | vio_clearHandler(viomajorsubtype_blockio); | 837 | vio_clearHandler(viomajorsubtype_blockio); |
814 | unregister_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME); | ||
815 | viopath_close(viopath_hostLp, viomajorsubtype_blockio, VIOMAXREQ + 2); | 838 | viopath_close(viopath_hostLp, viomajorsubtype_blockio, VIOMAXREQ + 2); |
839 | unregister_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME); | ||
816 | } | 840 | } |
817 | |||
818 | module_exit(viodasd_exit); | 841 | module_exit(viodasd_exit); |