diff options
Diffstat (limited to 'drivers/net/wireless/mwifiex/usb.c')
-rw-r--r-- | drivers/net/wireless/mwifiex/usb.c | 55 |
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 | ||
25 | static u8 user_rmmod; | ||
25 | static struct mwifiex_if_ops usb_ops; | 26 | static struct mwifiex_if_ops usb_ops; |
26 | static struct semaphore add_remove_card_sem; | 27 | static struct semaphore add_remove_card_sem; |
27 | static struct usb_card_rec *usb_card; | ||
28 | 28 | ||
29 | static struct usb_device_id mwifiex_usb_table[] = { | 29 | static struct usb_device_id mwifiex_usb_table[] = { |
30 | /* 8797 */ | 30 | /* 8797 */ |
@@ -532,28 +532,38 @@ static int mwifiex_usb_resume(struct usb_interface *intf) | |||
532 | static void mwifiex_usb_disconnect(struct usb_interface *intf) | 532 | static 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 | ||
570 | static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter) | 581 | static 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 | } |