aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/gigaset/usb-gigaset.c
diff options
context:
space:
mode:
authorTilman Schmidt <tilman@imap.cc>2008-02-06 04:38:29 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-06 13:41:12 -0500
commite468c04894f36045cf93d1384183a461014b6840 (patch)
treeb734bbc4ee65f8282de5299dc200f47ea466067a /drivers/isdn/gigaset/usb-gigaset.c
parent9d4bee2b9de9e30057a860d2d6794f874caffc5e (diff)
Gigaset: permit module unload
Fix the initialization and reference counting of the Gigaset driver modules so that they can be unloaded when they are not actually in use. Signed-off-by: Tilman Schmidt <tilman@imap.cc> Cc: Hansjoerg Lipp <hjlipp@web.de> Cc: Greg KH <gregkh@suse.de> Cc: Karsten Keil <kkeil@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/isdn/gigaset/usb-gigaset.c')
-rw-r--r--drivers/isdn/gigaset/usb-gigaset.c30
1 files changed, 12 insertions, 18 deletions
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c
index c58ddee68dea..77d20ab0cd4d 100644
--- a/drivers/isdn/gigaset/usb-gigaset.c
+++ b/drivers/isdn/gigaset/usb-gigaset.c
@@ -115,7 +115,6 @@ static int gigaset_resume(struct usb_interface *intf);
115static int gigaset_pre_reset(struct usb_interface *intf); 115static int gigaset_pre_reset(struct usb_interface *intf);
116 116
117static struct gigaset_driver *driver = NULL; 117static struct gigaset_driver *driver = NULL;
118static struct cardstate *cardstate = NULL;
119 118
120/* usb specific object needed to register this driver with the usb subsystem */ 119/* usb specific object needed to register this driver with the usb subsystem */
121static struct usb_driver gigaset_usb_driver = { 120static struct usb_driver gigaset_usb_driver = {
@@ -727,11 +726,10 @@ static int gigaset_probe(struct usb_interface *interface,
727 726
728 dev_info(&udev->dev, "%s: Device matched ... !\n", __func__); 727 dev_info(&udev->dev, "%s: Device matched ... !\n", __func__);
729 728
730 cs = gigaset_getunassignedcs(driver); 729 /* allocate memory for our device state and intialize it */
731 if (!cs) { 730 cs = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME);
732 dev_warn(&udev->dev, "no free cardstate\n"); 731 if (!cs)
733 return -ENODEV; 732 return -ENODEV;
734 }
735 ucs = cs->hw.usb; 733 ucs = cs->hw.usb;
736 734
737 /* save off device structure ptrs for later use */ 735 /* save off device structure ptrs for later use */
@@ -818,7 +816,7 @@ error:
818 usb_put_dev(ucs->udev); 816 usb_put_dev(ucs->udev);
819 ucs->udev = NULL; 817 ucs->udev = NULL;
820 ucs->interface = NULL; 818 ucs->interface = NULL;
821 gigaset_unassign(cs); 819 gigaset_freecs(cs);
822 return retval; 820 return retval;
823} 821}
824 822
@@ -852,7 +850,7 @@ static void gigaset_disconnect(struct usb_interface *interface)
852 ucs->interface = NULL; 850 ucs->interface = NULL;
853 ucs->udev = NULL; 851 ucs->udev = NULL;
854 cs->dev = NULL; 852 cs->dev = NULL;
855 gigaset_unassign(cs); 853 gigaset_freecs(cs);
856} 854}
857 855
858/* gigaset_suspend 856/* gigaset_suspend
@@ -934,11 +932,6 @@ static int __init usb_gigaset_init(void)
934 &ops, THIS_MODULE)) == NULL) 932 &ops, THIS_MODULE)) == NULL)
935 goto error; 933 goto error;
936 934
937 /* allocate memory for our device state and intialize it */
938 cardstate = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME);
939 if (!cardstate)
940 goto error;
941
942 /* register this driver with the USB subsystem */ 935 /* register this driver with the USB subsystem */
943 result = usb_register(&gigaset_usb_driver); 936 result = usb_register(&gigaset_usb_driver);
944 if (result < 0) { 937 if (result < 0) {
@@ -951,9 +944,7 @@ static int __init usb_gigaset_init(void)
951 info(DRIVER_DESC); 944 info(DRIVER_DESC);
952 return 0; 945 return 0;
953 946
954error: if (cardstate) 947error:
955 gigaset_freecs(cardstate);
956 cardstate = NULL;
957 if (driver) 948 if (driver)
958 gigaset_freedriver(driver); 949 gigaset_freedriver(driver);
959 driver = NULL; 950 driver = NULL;
@@ -967,11 +958,16 @@ error: if (cardstate)
967 */ 958 */
968static void __exit usb_gigaset_exit(void) 959static void __exit usb_gigaset_exit(void)
969{ 960{
961 int i;
962
970 gigaset_blockdriver(driver); /* => probe will fail 963 gigaset_blockdriver(driver); /* => probe will fail
971 * => no gigaset_start any more 964 * => no gigaset_start any more
972 */ 965 */
973 966
974 gigaset_shutdown(cardstate); 967 /* stop all connected devices */
968 for (i = 0; i < driver->minors; i++)
969 gigaset_shutdown(driver->cs + i);
970
975 /* from now on, no isdn callback should be possible */ 971 /* from now on, no isdn callback should be possible */
976 972
977 /* deregister this driver with the USB subsystem */ 973 /* deregister this driver with the USB subsystem */
@@ -979,8 +975,6 @@ static void __exit usb_gigaset_exit(void)
979 /* this will call the disconnect-callback */ 975 /* this will call the disconnect-callback */
980 /* from now on, no disconnect/probe callback should be running */ 976 /* from now on, no disconnect/probe callback should be running */
981 977
982 gigaset_freecs(cardstate);
983 cardstate = NULL;
984 gigaset_freedriver(driver); 978 gigaset_freedriver(driver);
985 driver = NULL; 979 driver = NULL;
986} 980}