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>
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c
index c58ddee..77d20ab 100644
--- a/drivers/isdn/gigaset/usb-gigaset.c
+++ b/drivers/isdn/gigaset/usb-gigaset.c
@@ -115,7 +115,6 @@
 static int gigaset_pre_reset(struct usb_interface *intf);
 
 static struct gigaset_driver *driver = NULL;
-static struct cardstate *cardstate = NULL;
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver gigaset_usb_driver = {
@@ -727,11 +726,10 @@
 
 	dev_info(&udev->dev, "%s: Device matched ... !\n", __func__);
 
-	cs = gigaset_getunassignedcs(driver);
-	if (!cs) {
-		dev_warn(&udev->dev, "no free cardstate\n");
+	/* allocate memory for our device state and intialize it */
+	cs = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME);
+	if (!cs)
 		return -ENODEV;
-	}
 	ucs = cs->hw.usb;
 
 	/* save off device structure ptrs for later use */
@@ -818,7 +816,7 @@
 	usb_put_dev(ucs->udev);
 	ucs->udev = NULL;
 	ucs->interface = NULL;
-	gigaset_unassign(cs);
+	gigaset_freecs(cs);
 	return retval;
 }
 
@@ -852,7 +850,7 @@
 	ucs->interface = NULL;
 	ucs->udev = NULL;
 	cs->dev = NULL;
-	gigaset_unassign(cs);
+	gigaset_freecs(cs);
 }
 
 /* gigaset_suspend
@@ -934,11 +932,6 @@
 				       &ops, THIS_MODULE)) == NULL)
 		goto error;
 
-	/* allocate memory for our device state and intialize it */
-	cardstate = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME);
-	if (!cardstate)
-		goto error;
-
 	/* register this driver with the USB subsystem */
 	result = usb_register(&gigaset_usb_driver);
 	if (result < 0) {
@@ -951,9 +944,7 @@
 	info(DRIVER_DESC);
 	return 0;
 
-error:	if (cardstate)
-		gigaset_freecs(cardstate);
-	cardstate = NULL;
+error:
 	if (driver)
 		gigaset_freedriver(driver);
 	driver = NULL;
@@ -967,11 +958,16 @@
  */
 static void __exit usb_gigaset_exit(void)
 {
+	int i;
+
 	gigaset_blockdriver(driver); /* => probe will fail
 				      * => no gigaset_start any more
 				      */
 
-	gigaset_shutdown(cardstate);
+	/* stop all connected devices */
+	for (i = 0; i < driver->minors; i++)
+		gigaset_shutdown(driver->cs + i);
+
 	/* from now on, no isdn callback should be possible */
 
 	/* deregister this driver with the USB subsystem */
@@ -979,8 +975,6 @@
 	/* this will call the disconnect-callback */
 	/* from now on, no disconnect/probe callback should be running */
 
-	gigaset_freecs(cardstate);
-	cardstate = NULL;
 	gigaset_freedriver(driver);
 	driver = NULL;
 }