aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex/usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mwifiex/usb.c')
-rw-r--r--drivers/net/wireless/mwifiex/usb.c55
1 files changed, 24 insertions, 31 deletions
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index edbe4aff00d8..a8ce8130cfae 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -22,9 +22,9 @@
22 22
23#define USB_VERSION "1.0" 23#define USB_VERSION "1.0"
24 24
25static u8 user_rmmod;
25static struct mwifiex_if_ops usb_ops; 26static struct mwifiex_if_ops usb_ops;
26static struct semaphore add_remove_card_sem; 27static struct semaphore add_remove_card_sem;
27static struct usb_card_rec *usb_card;
28 28
29static struct usb_device_id mwifiex_usb_table[] = { 29static struct usb_device_id mwifiex_usb_table[] = {
30 /* 8797 */ 30 /* 8797 */
@@ -532,28 +532,38 @@ static int mwifiex_usb_resume(struct usb_interface *intf)
532static void mwifiex_usb_disconnect(struct usb_interface *intf) 532static void mwifiex_usb_disconnect(struct usb_interface *intf)
533{ 533{
534 struct usb_card_rec *card = usb_get_intfdata(intf); 534 struct usb_card_rec *card = usb_get_intfdata(intf);
535 struct mwifiex_adapter *adapter;
535 536
536 if (!card) { 537 if (!card || !card->adapter) {
537 pr_err("%s: card is NULL\n", __func__); 538 pr_err("%s: card or card->adapter is NULL\n", __func__);
538 return; 539 return;
539 } 540 }
540 541
541 mwifiex_usb_free(card); 542 adapter = card->adapter;
543 if (!adapter->priv_num)
544 return;
542 545
543 if (card->adapter) { 546 if (user_rmmod) {
544 struct mwifiex_adapter *adapter = card->adapter; 547#ifdef CONFIG_PM
548 if (adapter->is_suspended)
549 mwifiex_usb_resume(intf);
550#endif
545 551
546 if (!adapter->priv_num) 552 mwifiex_deauthenticate_all(adapter);
547 return;
548 553
549 dev_dbg(adapter->dev, "%s: removing card\n", __func__); 554 mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
550 mwifiex_remove_card(adapter, &add_remove_card_sem); 555 MWIFIEX_BSS_ROLE_ANY),
556 MWIFIEX_FUNC_SHUTDOWN);
551 } 557 }
552 558
559 mwifiex_usb_free(card);
560
561 dev_dbg(adapter->dev, "%s: removing card\n", __func__);
562 mwifiex_remove_card(adapter, &add_remove_card_sem);
563
553 usb_set_intfdata(intf, NULL); 564 usb_set_intfdata(intf, NULL);
554 usb_put_dev(interface_to_usbdev(intf)); 565 usb_put_dev(interface_to_usbdev(intf));
555 kfree(card); 566 kfree(card);
556 usb_card = NULL;
557 567
558 return; 568 return;
559} 569}
@@ -565,6 +575,7 @@ static struct usb_driver mwifiex_usb_driver = {
565 .id_table = mwifiex_usb_table, 575 .id_table = mwifiex_usb_table,
566 .suspend = mwifiex_usb_suspend, 576 .suspend = mwifiex_usb_suspend,
567 .resume = mwifiex_usb_resume, 577 .resume = mwifiex_usb_resume,
578 .soft_unbind = 1,
568}; 579};
569 580
570static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter) 581static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter)
@@ -762,7 +773,6 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
762 773
763 card->adapter = adapter; 774 card->adapter = adapter;
764 adapter->dev = &card->udev->dev; 775 adapter->dev = &card->udev->dev;
765 usb_card = card;
766 776
767 switch (le16_to_cpu(card->udev->descriptor.idProduct)) { 777 switch (le16_to_cpu(card->udev->descriptor.idProduct)) {
768 case USB8897_PID_1: 778 case USB8897_PID_1:
@@ -1025,25 +1035,8 @@ static void mwifiex_usb_cleanup_module(void)
1025 if (!down_interruptible(&add_remove_card_sem)) 1035 if (!down_interruptible(&add_remove_card_sem))
1026 up(&add_remove_card_sem); 1036 up(&add_remove_card_sem);
1027 1037
1028 if (usb_card && usb_card->adapter) { 1038 /* set the flag as user is removing this module */
1029 struct mwifiex_adapter *adapter = usb_card->adapter; 1039 user_rmmod = 1;
1030
1031 /* In case driver is removed when asynchronous FW downloading is
1032 * in progress
1033 */
1034 wait_for_completion(&adapter->fw_load);
1035
1036#ifdef CONFIG_PM
1037 if (adapter->is_suspended)
1038 mwifiex_usb_resume(usb_card->intf);
1039#endif
1040
1041 mwifiex_deauthenticate_all(adapter);
1042
1043 mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
1044 MWIFIEX_BSS_ROLE_ANY),
1045 MWIFIEX_FUNC_SHUTDOWN);
1046 }
1047 1040
1048 usb_deregister(&mwifiex_usb_driver); 1041 usb_deregister(&mwifiex_usb_driver);
1049} 1042}