[SCSI] zfcp: Implement module unloading
authorChristof Schmitt <christof.schmitt@de.ibm.com>
Tue, 24 Nov 2009 15:54:04 +0000 (16:54 +0100)
committerJames Bottomley <James.Bottomley@suse.de>
Fri, 4 Dec 2009 18:02:06 +0000 (12:02 -0600)
With the reference counting for zfcp data structures, it is now
possible to implement module unloading again. Module unloading
requires to free all data structures in the module exit function. This
is done by unregistering zfcp from s390 cio and the SCSI midlayer
first in the module exit function.

Reviewed-by: Swen Schillig <swen@vnet.ibm.com>
Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
drivers/s390/scsi/zfcp_aux.c
drivers/s390/scsi/zfcp_ccw.c
drivers/s390/scsi/zfcp_ext.h

index baef2ec7482f04274926fbf98a95d4108a142a32..12de1ce9a92dc75d5dbcd7d157e919a2b6487bdd 100644 (file)
@@ -189,7 +189,7 @@ static int __init zfcp_module_init(void)
                goto out_misc;
        }
 
-       retval = zfcp_ccw_register();
+       retval = ccw_driver_register(&zfcp_ccw_driver);
        if (retval) {
                pr_err("The zfcp device driver could not register with "
                       "the common I/O layer\n");
@@ -218,6 +218,19 @@ out:
 
 module_init(zfcp_module_init);
 
+static void __exit zfcp_module_exit(void)
+{
+       ccw_driver_unregister(&zfcp_ccw_driver);
+       misc_deregister(&zfcp_cfdc_misc);
+       fc_release_transport(zfcp_data.scsi_transport_template);
+       kmem_cache_destroy(zfcp_data.gid_pn_cache);
+       kmem_cache_destroy(zfcp_data.sr_buffer_cache);
+       kmem_cache_destroy(zfcp_data.qtcb_cache);
+       kmem_cache_destroy(zfcp_data.gpn_ft_cache);
+}
+
+module_exit(zfcp_module_exit);
+
 /**
  * zfcp_get_unit_by_lun - find unit in unit list of port by FCP LUN
  * @port: pointer to port to search for unit
index ca8dffcd1e02c22644a6380b31f24cafa78f1937..4d35902a0cc58dd68571142e0d2e9d1a5b986b66 100644 (file)
@@ -279,14 +279,3 @@ struct ccw_driver zfcp_ccw_driver = {
        .thaw        = zfcp_ccw_activate,
        .restore     = zfcp_ccw_activate,
 };
-
-/**
- * zfcp_ccw_register - ccw register function
- *
- * Registers the driver at the common i/o layer. This function will be called
- * at module load time/system start.
- */
-int __init zfcp_ccw_register(void)
-{
-       return ccw_driver_register(&zfcp_ccw_driver);
-}
index 1e3ec708505bddf2f77a5017fb75d86550ae4eb3..5f205f85e6f96ceee2b006ac6ba603ec4bfe90bb 100644 (file)
@@ -27,7 +27,6 @@ extern void zfcp_adapter_release(struct kref *);
 extern void zfcp_adapter_unregister(struct zfcp_adapter *);
 
 /* zfcp_ccw.c */
-extern int zfcp_ccw_register(void);
 extern int zfcp_ccw_priv_sch(struct zfcp_adapter *);
 extern struct ccw_driver zfcp_ccw_driver;
 extern struct zfcp_adapter *zfcp_ccw_adapter_by_cdev(struct ccw_device *);