aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
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
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')
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c80
-rw-r--r--drivers/isdn/gigaset/common.c105
-rw-r--r--drivers/isdn/gigaset/gigaset.h8
-rw-r--r--drivers/isdn/gigaset/interface.c4
-rw-r--r--drivers/isdn/gigaset/usb-gigaset.c30
5 files changed, 85 insertions, 142 deletions
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 7c905305406b..5255b5e20e13 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -134,7 +134,6 @@ struct bas_cardstate {
134 134
135 135
136static struct gigaset_driver *driver = NULL; 136static struct gigaset_driver *driver = NULL;
137static struct cardstate *cardstate = NULL;
138 137
139/* usb specific object needed to register this driver with the usb subsystem */ 138/* usb specific object needed to register this driver with the usb subsystem */
140static struct usb_driver gigaset_usb_driver = { 139static struct usb_driver gigaset_usb_driver = {
@@ -2247,11 +2246,11 @@ static int gigaset_probe(struct usb_interface *interface,
2247 __func__, le16_to_cpu(udev->descriptor.idVendor), 2246 __func__, le16_to_cpu(udev->descriptor.idVendor),
2248 le16_to_cpu(udev->descriptor.idProduct)); 2247 le16_to_cpu(udev->descriptor.idProduct));
2249 2248
2250 cs = gigaset_getunassignedcs(driver); 2249 /* allocate memory for our device state and intialize it */
2251 if (!cs) { 2250 cs = gigaset_initcs(driver, BAS_CHANNELS, 0, 0, cidmode,
2252 dev_err(&udev->dev, "no free cardstate\n"); 2251 GIGASET_MODULENAME);
2252 if (!cs)
2253 return -ENODEV; 2253 return -ENODEV;
2254 }
2255 ucs = cs->hw.bas; 2254 ucs = cs->hw.bas;
2256 2255
2257 /* save off device structure ptrs for later use */ 2256 /* save off device structure ptrs for later use */
@@ -2320,7 +2319,7 @@ allocerr:
2320error: 2319error:
2321 freeurbs(cs); 2320 freeurbs(cs);
2322 usb_set_intfdata(interface, NULL); 2321 usb_set_intfdata(interface, NULL);
2323 gigaset_unassign(cs); 2322 gigaset_freecs(cs);
2324 return -ENODEV; 2323 return -ENODEV;
2325} 2324}
2326 2325
@@ -2362,7 +2361,7 @@ static void gigaset_disconnect(struct usb_interface *interface)
2362 ucs->interface = NULL; 2361 ucs->interface = NULL;
2363 ucs->udev = NULL; 2362 ucs->udev = NULL;
2364 cs->dev = NULL; 2363 cs->dev = NULL;
2365 gigaset_unassign(cs); 2364 gigaset_freecs(cs);
2366} 2365}
2367 2366
2368/* gigaset_suspend 2367/* gigaset_suspend
@@ -2501,12 +2500,6 @@ static int __init bas_gigaset_init(void)
2501 &gigops, THIS_MODULE)) == NULL) 2500 &gigops, THIS_MODULE)) == NULL)
2502 goto error; 2501 goto error;
2503 2502
2504 /* allocate memory for our device state and intialize it */
2505 cardstate = gigaset_initcs(driver, BAS_CHANNELS, 0, 0, cidmode,
2506 GIGASET_MODULENAME);
2507 if (!cardstate)
2508 goto error;
2509
2510 /* register this driver with the USB subsystem */ 2503 /* register this driver with the USB subsystem */
2511 result = usb_register(&gigaset_usb_driver); 2504 result = usb_register(&gigaset_usb_driver);
2512 if (result < 0) { 2505 if (result < 0) {
@@ -2518,9 +2511,7 @@ static int __init bas_gigaset_init(void)
2518 info(DRIVER_DESC); 2511 info(DRIVER_DESC);
2519 return 0; 2512 return 0;
2520 2513
2521error: if (cardstate) 2514error:
2522 gigaset_freecs(cardstate);
2523 cardstate = NULL;
2524 if (driver) 2515 if (driver)
2525 gigaset_freedriver(driver); 2516 gigaset_freedriver(driver);
2526 driver = NULL; 2517 driver = NULL;
@@ -2532,43 +2523,50 @@ error: if (cardstate)
2532 */ 2523 */
2533static void __exit bas_gigaset_exit(void) 2524static void __exit bas_gigaset_exit(void)
2534{ 2525{
2535 struct bas_cardstate *ucs = cardstate->hw.bas; 2526 struct bas_cardstate *ucs;
2527 int i;
2536 2528
2537 gigaset_blockdriver(driver); /* => probe will fail 2529 gigaset_blockdriver(driver); /* => probe will fail
2538 * => no gigaset_start any more 2530 * => no gigaset_start any more
2539 */ 2531 */
2540 2532
2541 gigaset_shutdown(cardstate); 2533 /* stop all connected devices */
2542 /* from now on, no isdn callback should be possible */ 2534 for (i = 0; i < driver->minors; i++) {
2543 2535 if (gigaset_shutdown(driver->cs + i) < 0)
2544 /* close all still open channels */ 2536 continue; /* no device */
2545 if (ucs->basstate & BS_B1OPEN) { 2537 /* from now on, no isdn callback should be possible */
2546 gig_dbg(DEBUG_INIT, "closing B1 channel"); 2538
2547 usb_control_msg(ucs->udev, usb_sndctrlpipe(ucs->udev, 0), 2539 /* close all still open channels */
2548 HD_CLOSE_B1CHANNEL, OUT_VENDOR_REQ, 0, 0, 2540 ucs = driver->cs[i].hw.bas;
2549 NULL, 0, BAS_TIMEOUT); 2541 if (ucs->basstate & BS_B1OPEN) {
2550 } 2542 gig_dbg(DEBUG_INIT, "closing B1 channel");
2551 if (ucs->basstate & BS_B2OPEN) { 2543 usb_control_msg(ucs->udev,
2552 gig_dbg(DEBUG_INIT, "closing B2 channel"); 2544 usb_sndctrlpipe(ucs->udev, 0),
2553 usb_control_msg(ucs->udev, usb_sndctrlpipe(ucs->udev, 0), 2545 HD_CLOSE_B1CHANNEL, OUT_VENDOR_REQ,
2554 HD_CLOSE_B2CHANNEL, OUT_VENDOR_REQ, 0, 0, 2546 0, 0, NULL, 0, BAS_TIMEOUT);
2555 NULL, 0, BAS_TIMEOUT); 2547 }
2556 } 2548 if (ucs->basstate & BS_B2OPEN) {
2557 if (ucs->basstate & BS_ATOPEN) { 2549 gig_dbg(DEBUG_INIT, "closing B2 channel");
2558 gig_dbg(DEBUG_INIT, "closing AT channel"); 2550 usb_control_msg(ucs->udev,
2559 usb_control_msg(ucs->udev, usb_sndctrlpipe(ucs->udev, 0), 2551 usb_sndctrlpipe(ucs->udev, 0),
2560 HD_CLOSE_ATCHANNEL, OUT_VENDOR_REQ, 0, 0, 2552 HD_CLOSE_B2CHANNEL, OUT_VENDOR_REQ,
2561 NULL, 0, BAS_TIMEOUT); 2553 0, 0, NULL, 0, BAS_TIMEOUT);
2554 }
2555 if (ucs->basstate & BS_ATOPEN) {
2556 gig_dbg(DEBUG_INIT, "closing AT channel");
2557 usb_control_msg(ucs->udev,
2558 usb_sndctrlpipe(ucs->udev, 0),
2559 HD_CLOSE_ATCHANNEL, OUT_VENDOR_REQ,
2560 0, 0, NULL, 0, BAS_TIMEOUT);
2561 }
2562 ucs->basstate = 0;
2562 } 2563 }
2563 ucs->basstate = 0;
2564 2564
2565 /* deregister this driver with the USB subsystem */ 2565 /* deregister this driver with the USB subsystem */
2566 usb_deregister(&gigaset_usb_driver); 2566 usb_deregister(&gigaset_usb_driver);
2567 /* this will call the disconnect-callback */ 2567 /* this will call the disconnect-callback */
2568 /* from now on, no disconnect/probe callback should be running */ 2568 /* from now on, no disconnect/probe callback should be running */
2569 2569
2570 gigaset_freecs(cardstate);
2571 cardstate = NULL;
2572 gigaset_freedriver(driver); 2570 gigaset_freedriver(driver);
2573 driver = NULL; 2571 driver = NULL;
2574} 2572}
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index f8f7d7e553bf..aacedec4986f 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -31,7 +31,6 @@ MODULE_PARM_DESC(debug, "debug level");
31/* driver state flags */ 31/* driver state flags */
32#define VALID_MINOR 0x01 32#define VALID_MINOR 0x01
33#define VALID_ID 0x02 33#define VALID_ID 0x02
34#define ASSIGNED 0x04
35 34
36void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, 35void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,
37 size_t len, const unsigned char *buf) 36 size_t len, const unsigned char *buf)
@@ -178,7 +177,7 @@ int gigaset_get_channel(struct bc_state *bcs)
178 unsigned long flags; 177 unsigned long flags;
179 178
180 spin_lock_irqsave(&bcs->cs->lock, flags); 179 spin_lock_irqsave(&bcs->cs->lock, flags);
181 if (bcs->use_count) { 180 if (bcs->use_count || !try_module_get(bcs->cs->driver->owner)) {
182 gig_dbg(DEBUG_ANY, "could not allocate channel %d", 181 gig_dbg(DEBUG_ANY, "could not allocate channel %d",
183 bcs->channel); 182 bcs->channel);
184 spin_unlock_irqrestore(&bcs->cs->lock, flags); 183 spin_unlock_irqrestore(&bcs->cs->lock, flags);
@@ -203,6 +202,7 @@ void gigaset_free_channel(struct bc_state *bcs)
203 } 202 }
204 --bcs->use_count; 203 --bcs->use_count;
205 bcs->busy = 0; 204 bcs->busy = 0;
205 module_put(bcs->cs->driver->owner);
206 gig_dbg(DEBUG_ANY, "freed channel %d", bcs->channel); 206 gig_dbg(DEBUG_ANY, "freed channel %d", bcs->channel);
207 spin_unlock_irqrestore(&bcs->cs->lock, flags); 207 spin_unlock_irqrestore(&bcs->cs->lock, flags);
208} 208}
@@ -356,31 +356,28 @@ static struct cardstate *alloc_cs(struct gigaset_driver *drv)
356{ 356{
357 unsigned long flags; 357 unsigned long flags;
358 unsigned i; 358 unsigned i;
359 struct cardstate *cs;
359 struct cardstate *ret = NULL; 360 struct cardstate *ret = NULL;
360 361
361 spin_lock_irqsave(&drv->lock, flags); 362 spin_lock_irqsave(&drv->lock, flags);
363 if (drv->blocked)
364 goto exit;
362 for (i = 0; i < drv->minors; ++i) { 365 for (i = 0; i < drv->minors; ++i) {
363 if (!(drv->flags[i] & VALID_MINOR)) { 366 cs = drv->cs + i;
364 if (try_module_get(drv->owner)) { 367 if (!(cs->flags & VALID_MINOR)) {
365 drv->flags[i] = VALID_MINOR; 368 cs->flags = VALID_MINOR;
366 ret = drv->cs + i; 369 ret = cs;
367 }
368 break; 370 break;
369 } 371 }
370 } 372 }
373exit:
371 spin_unlock_irqrestore(&drv->lock, flags); 374 spin_unlock_irqrestore(&drv->lock, flags);
372 return ret; 375 return ret;
373} 376}
374 377
375static void free_cs(struct cardstate *cs) 378static void free_cs(struct cardstate *cs)
376{ 379{
377 unsigned long flags; 380 cs->flags = 0;
378 struct gigaset_driver *drv = cs->driver;
379 spin_lock_irqsave(&drv->lock, flags);
380 if (drv->flags[cs->minor_index] & VALID_MINOR)
381 module_put(drv->owner);
382 drv->flags[cs->minor_index] = 0;
383 spin_unlock_irqrestore(&drv->lock, flags);
384} 381}
385 382
386static void make_valid(struct cardstate *cs, unsigned mask) 383static void make_valid(struct cardstate *cs, unsigned mask)
@@ -388,7 +385,7 @@ static void make_valid(struct cardstate *cs, unsigned mask)
388 unsigned long flags; 385 unsigned long flags;
389 struct gigaset_driver *drv = cs->driver; 386 struct gigaset_driver *drv = cs->driver;
390 spin_lock_irqsave(&drv->lock, flags); 387 spin_lock_irqsave(&drv->lock, flags);
391 drv->flags[cs->minor_index] |= mask; 388 cs->flags |= mask;
392 spin_unlock_irqrestore(&drv->lock, flags); 389 spin_unlock_irqrestore(&drv->lock, flags);
393} 390}
394 391
@@ -397,7 +394,7 @@ static void make_invalid(struct cardstate *cs, unsigned mask)
397 unsigned long flags; 394 unsigned long flags;
398 struct gigaset_driver *drv = cs->driver; 395 struct gigaset_driver *drv = cs->driver;
399 spin_lock_irqsave(&drv->lock, flags); 396 spin_lock_irqsave(&drv->lock, flags);
400 drv->flags[cs->minor_index] &= ~mask; 397 cs->flags &= ~mask;
401 spin_unlock_irqrestore(&drv->lock, flags); 398 spin_unlock_irqrestore(&drv->lock, flags);
402} 399}
403 400
@@ -893,10 +890,17 @@ error:
893} 890}
894EXPORT_SYMBOL_GPL(gigaset_start); 891EXPORT_SYMBOL_GPL(gigaset_start);
895 892
896void gigaset_shutdown(struct cardstate *cs) 893/* gigaset_shutdown
894 * check if a device is associated to the cardstate structure and stop it
895 * return value: 0 if ok, -1 if no device was associated
896 */
897int gigaset_shutdown(struct cardstate *cs)
897{ 898{
898 mutex_lock(&cs->mutex); 899 mutex_lock(&cs->mutex);
899 900
901 if (!(cs->flags & VALID_MINOR))
902 return -1;
903
900 cs->waiting = 1; 904 cs->waiting = 1;
901 905
902 if (!gigaset_add_event(cs, &cs->at_state, EV_SHUTDOWN, NULL, 0, NULL)) { 906 if (!gigaset_add_event(cs, &cs->at_state, EV_SHUTDOWN, NULL, 0, NULL)) {
@@ -913,6 +917,7 @@ void gigaset_shutdown(struct cardstate *cs)
913 917
914exit: 918exit:
915 mutex_unlock(&cs->mutex); 919 mutex_unlock(&cs->mutex);
920 return 0;
916} 921}
917EXPORT_SYMBOL_GPL(gigaset_shutdown); 922EXPORT_SYMBOL_GPL(gigaset_shutdown);
918 923
@@ -954,13 +959,11 @@ struct cardstate *gigaset_get_cs_by_id(int id)
954 list_for_each_entry(drv, &drivers, list) { 959 list_for_each_entry(drv, &drivers, list) {
955 spin_lock(&drv->lock); 960 spin_lock(&drv->lock);
956 for (i = 0; i < drv->minors; ++i) { 961 for (i = 0; i < drv->minors; ++i) {
957 if (drv->flags[i] & VALID_ID) { 962 cs = drv->cs + i;
958 cs = drv->cs + i; 963 if ((cs->flags & VALID_ID) && cs->myid == id) {
959 if (cs->myid == id) 964 ret = cs;
960 ret = cs;
961 }
962 if (ret)
963 break; 965 break;
966 }
964 } 967 }
965 spin_unlock(&drv->lock); 968 spin_unlock(&drv->lock);
966 if (ret) 969 if (ret)
@@ -983,10 +986,9 @@ void gigaset_debugdrivers(void)
983 spin_lock(&drv->lock); 986 spin_lock(&drv->lock);
984 for (i = 0; i < drv->minors; ++i) { 987 for (i = 0; i < drv->minors; ++i) {
985 gig_dbg(DEBUG_DRIVER, " index %u", i); 988 gig_dbg(DEBUG_DRIVER, " index %u", i);
986 gig_dbg(DEBUG_DRIVER, " flags 0x%02x",
987 drv->flags[i]);
988 cs = drv->cs + i; 989 cs = drv->cs + i;
989 gig_dbg(DEBUG_DRIVER, " cardstate %p", cs); 990 gig_dbg(DEBUG_DRIVER, " cardstate %p", cs);
991 gig_dbg(DEBUG_DRIVER, " flags 0x%02x", cs->flags);
990 gig_dbg(DEBUG_DRIVER, " minor_index %u", 992 gig_dbg(DEBUG_DRIVER, " minor_index %u",
991 cs->minor_index); 993 cs->minor_index);
992 gig_dbg(DEBUG_DRIVER, " driver %p", cs->driver); 994 gig_dbg(DEBUG_DRIVER, " driver %p", cs->driver);
@@ -1010,7 +1012,7 @@ static struct cardstate *gigaset_get_cs_by_minor(unsigned minor)
1010 continue; 1012 continue;
1011 index = minor - drv->minor; 1013 index = minor - drv->minor;
1012 spin_lock(&drv->lock); 1014 spin_lock(&drv->lock);
1013 if (drv->flags[index] & VALID_MINOR) 1015 if (drv->cs[index].flags & VALID_MINOR)
1014 ret = drv->cs + index; 1016 ret = drv->cs + index;
1015 spin_unlock(&drv->lock); 1017 spin_unlock(&drv->lock);
1016 if (ret) 1018 if (ret)
@@ -1038,7 +1040,6 @@ void gigaset_freedriver(struct gigaset_driver *drv)
1038 gigaset_if_freedriver(drv); 1040 gigaset_if_freedriver(drv);
1039 1041
1040 kfree(drv->cs); 1042 kfree(drv->cs);
1041 kfree(drv->flags);
1042 kfree(drv); 1043 kfree(drv);
1043} 1044}
1044EXPORT_SYMBOL_GPL(gigaset_freedriver); 1045EXPORT_SYMBOL_GPL(gigaset_freedriver);
@@ -1080,12 +1081,8 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors,
1080 if (!drv->cs) 1081 if (!drv->cs)
1081 goto error; 1082 goto error;
1082 1083
1083 drv->flags = kmalloc(minors * sizeof *drv->flags, GFP_KERNEL);
1084 if (!drv->flags)
1085 goto error;
1086
1087 for (i = 0; i < minors; ++i) { 1084 for (i = 0; i < minors; ++i) {
1088 drv->flags[i] = 0; 1085 drv->cs[i].flags = 0;
1089 drv->cs[i].driver = drv; 1086 drv->cs[i].driver = drv;
1090 drv->cs[i].ops = drv->ops; 1087 drv->cs[i].ops = drv->ops;
1091 drv->cs[i].minor_index = i; 1088 drv->cs[i].minor_index = i;
@@ -1106,53 +1103,9 @@ error:
1106} 1103}
1107EXPORT_SYMBOL_GPL(gigaset_initdriver); 1104EXPORT_SYMBOL_GPL(gigaset_initdriver);
1108 1105
1109/* For drivers without fixed assignment device<->cardstate (usb) */
1110struct cardstate *gigaset_getunassignedcs(struct gigaset_driver *drv)
1111{
1112 unsigned long flags;
1113 struct cardstate *cs = NULL;
1114 unsigned i;
1115
1116 spin_lock_irqsave(&drv->lock, flags);
1117 if (drv->blocked)
1118 goto exit;
1119 for (i = 0; i < drv->minors; ++i) {
1120 if ((drv->flags[i] & VALID_MINOR) &&
1121 !(drv->flags[i] & ASSIGNED)) {
1122 drv->flags[i] |= ASSIGNED;
1123 cs = drv->cs + i;
1124 break;
1125 }
1126 }
1127exit:
1128 spin_unlock_irqrestore(&drv->lock, flags);
1129 return cs;
1130}
1131EXPORT_SYMBOL_GPL(gigaset_getunassignedcs);
1132
1133void gigaset_unassign(struct cardstate *cs)
1134{
1135 unsigned long flags;
1136 unsigned *minor_flags;
1137 struct gigaset_driver *drv;
1138
1139 if (!cs)
1140 return;
1141 drv = cs->driver;
1142 spin_lock_irqsave(&drv->lock, flags);
1143 minor_flags = drv->flags + cs->minor_index;
1144 if (*minor_flags & VALID_MINOR)
1145 *minor_flags &= ~ASSIGNED;
1146 spin_unlock_irqrestore(&drv->lock, flags);
1147}
1148EXPORT_SYMBOL_GPL(gigaset_unassign);
1149
1150void gigaset_blockdriver(struct gigaset_driver *drv) 1106void gigaset_blockdriver(struct gigaset_driver *drv)
1151{ 1107{
1152 unsigned long flags;
1153 spin_lock_irqsave(&drv->lock, flags);
1154 drv->blocked = 1; 1108 drv->blocked = 1;
1155 spin_unlock_irqrestore(&drv->lock, flags);
1156} 1109}
1157EXPORT_SYMBOL_GPL(gigaset_blockdriver); 1110EXPORT_SYMBOL_GPL(gigaset_blockdriver);
1158 1111
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h
index 92986a5d4055..f365993161fc 100644
--- a/drivers/isdn/gigaset/gigaset.h
+++ b/drivers/isdn/gigaset/gigaset.h
@@ -435,6 +435,7 @@ struct cardstate {
435 unsigned minor_index; 435 unsigned minor_index;
436 struct device *dev; 436 struct device *dev;
437 struct device *tty_dev; 437 struct device *tty_dev;
438 unsigned flags;
438 439
439 const struct gigaset_ops *ops; 440 const struct gigaset_ops *ops;
440 441
@@ -539,7 +540,6 @@ struct gigaset_driver {
539 unsigned minor; 540 unsigned minor;
540 unsigned minors; 541 unsigned minors;
541 struct cardstate *cs; 542 struct cardstate *cs;
542 unsigned *flags;
543 int blocked; 543 int blocked;
544 544
545 const struct gigaset_ops *ops; 545 const struct gigaset_ops *ops;
@@ -767,10 +767,6 @@ void gigaset_freedriver(struct gigaset_driver *drv);
767void gigaset_debugdrivers(void); 767void gigaset_debugdrivers(void);
768struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty); 768struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty);
769struct cardstate *gigaset_get_cs_by_id(int id); 769struct cardstate *gigaset_get_cs_by_id(int id);
770
771/* For drivers without fixed assignment device<->cardstate (usb) */
772struct cardstate *gigaset_getunassignedcs(struct gigaset_driver *drv);
773void gigaset_unassign(struct cardstate *cs);
774void gigaset_blockdriver(struct gigaset_driver *drv); 770void gigaset_blockdriver(struct gigaset_driver *drv);
775 771
776/* Allocate and initialize card state. Calls hardware dependent 772/* Allocate and initialize card state. Calls hardware dependent
@@ -789,7 +785,7 @@ int gigaset_start(struct cardstate *cs);
789void gigaset_stop(struct cardstate *cs); 785void gigaset_stop(struct cardstate *cs);
790 786
791/* Tell common.c that the driver is being unloaded. */ 787/* Tell common.c that the driver is being unloaded. */
792void gigaset_shutdown(struct cardstate *cs); 788int gigaset_shutdown(struct cardstate *cs);
793 789
794/* Tell common.c that an skb has been sent. */ 790/* Tell common.c that an skb has been sent. */
795void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb); 791void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb);
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index f4731c9984f6..af195b07c191 100644
--- a/drivers/isdn/gigaset/interface.c
+++ b/drivers/isdn/gigaset/interface.c
@@ -161,7 +161,7 @@ static int if_open(struct tty_struct *tty, struct file *filp)
161 tty->driver_data = NULL; 161 tty->driver_data = NULL;
162 162
163 cs = gigaset_get_cs_by_tty(tty); 163 cs = gigaset_get_cs_by_tty(tty);
164 if (!cs) 164 if (!cs || !try_module_get(cs->driver->owner))
165 return -ENODEV; 165 return -ENODEV;
166 166
167 if (mutex_lock_interruptible(&cs->mutex)) 167 if (mutex_lock_interruptible(&cs->mutex))
@@ -207,6 +207,8 @@ static void if_close(struct tty_struct *tty, struct file *filp)
207 } 207 }
208 208
209 mutex_unlock(&cs->mutex); 209 mutex_unlock(&cs->mutex);
210
211 module_put(cs->driver->owner);
210} 212}
211 213
212static int if_ioctl(struct tty_struct *tty, struct file *file, 214static int if_ioctl(struct tty_struct *tty, struct file *file,
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}