diff options
author | Amitkumar Karwar <akarwar@marvell.com> | 2014-04-14 18:32:54 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-04-22 15:06:30 -0400 |
commit | 3fffd7c17cca31b8538a313e02f9f4a6e63d360a (patch) | |
tree | 6937bf22b22feca090de5145d1b69470c407f330 | |
parent | 5af3fae3356c21faa97de496863a197660a6e1b0 (diff) |
mwifiex: use USB core's soft_unbind option
This option allows driver to finish pending operations in
disconnect handler by not killing URBs after usb_deregister
call.
We will get rid of global pointer 'usb_card' by moving code
from cleanup_module() to disconnect(). This will help to match
with our handling for SDIO and PCIe interfaces.
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/mwifiex/usb.c | 60 |
1 files changed, 29 insertions, 31 deletions
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c index edbe4aff00d8..db6377f7dcb8 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,43 @@ 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 | /* In case driver is removed when asynchronous FW downloading is |
544 | struct mwifiex_adapter *adapter = card->adapter; | 547 | * in progress |
548 | */ | ||
549 | wait_for_completion(&adapter->fw_load); | ||
545 | 550 | ||
546 | if (!adapter->priv_num) | 551 | if (user_rmmod) { |
547 | return; | 552 | #ifdef CONFIG_PM |
553 | if (adapter->is_suspended) | ||
554 | mwifiex_usb_resume(intf); | ||
555 | #endif | ||
556 | |||
557 | mwifiex_deauthenticate_all(adapter); | ||
548 | 558 | ||
549 | dev_dbg(adapter->dev, "%s: removing card\n", __func__); | 559 | mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, |
550 | mwifiex_remove_card(adapter, &add_remove_card_sem); | 560 | MWIFIEX_BSS_ROLE_ANY), |
561 | MWIFIEX_FUNC_SHUTDOWN); | ||
551 | } | 562 | } |
552 | 563 | ||
564 | mwifiex_usb_free(card); | ||
565 | |||
566 | dev_dbg(adapter->dev, "%s: removing card\n", __func__); | ||
567 | mwifiex_remove_card(adapter, &add_remove_card_sem); | ||
568 | |||
553 | usb_set_intfdata(intf, NULL); | 569 | usb_set_intfdata(intf, NULL); |
554 | usb_put_dev(interface_to_usbdev(intf)); | 570 | usb_put_dev(interface_to_usbdev(intf)); |
555 | kfree(card); | 571 | kfree(card); |
556 | usb_card = NULL; | ||
557 | 572 | ||
558 | return; | 573 | return; |
559 | } | 574 | } |
@@ -565,6 +580,7 @@ static struct usb_driver mwifiex_usb_driver = { | |||
565 | .id_table = mwifiex_usb_table, | 580 | .id_table = mwifiex_usb_table, |
566 | .suspend = mwifiex_usb_suspend, | 581 | .suspend = mwifiex_usb_suspend, |
567 | .resume = mwifiex_usb_resume, | 582 | .resume = mwifiex_usb_resume, |
583 | .soft_unbind = 1, | ||
568 | }; | 584 | }; |
569 | 585 | ||
570 | static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter) | 586 | static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter) |
@@ -762,7 +778,6 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) | |||
762 | 778 | ||
763 | card->adapter = adapter; | 779 | card->adapter = adapter; |
764 | adapter->dev = &card->udev->dev; | 780 | adapter->dev = &card->udev->dev; |
765 | usb_card = card; | ||
766 | 781 | ||
767 | switch (le16_to_cpu(card->udev->descriptor.idProduct)) { | 782 | switch (le16_to_cpu(card->udev->descriptor.idProduct)) { |
768 | case USB8897_PID_1: | 783 | case USB8897_PID_1: |
@@ -1025,25 +1040,8 @@ static void mwifiex_usb_cleanup_module(void) | |||
1025 | if (!down_interruptible(&add_remove_card_sem)) | 1040 | if (!down_interruptible(&add_remove_card_sem)) |
1026 | up(&add_remove_card_sem); | 1041 | up(&add_remove_card_sem); |
1027 | 1042 | ||
1028 | if (usb_card && usb_card->adapter) { | 1043 | /* set the flag as user is removing this module */ |
1029 | struct mwifiex_adapter *adapter = usb_card->adapter; | 1044 | 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 | 1045 | ||
1048 | usb_deregister(&mwifiex_usb_driver); | 1046 | usb_deregister(&mwifiex_usb_driver); |
1049 | } | 1047 | } |