aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmitkumar Karwar <akarwar@marvell.com>2014-04-14 18:32:54 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-04-22 15:06:30 -0400
commit3fffd7c17cca31b8538a313e02f9f4a6e63d360a (patch)
tree6937bf22b22feca090de5145d1b69470c407f330
parent5af3fae3356c21faa97de496863a197660a6e1b0 (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.c60
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
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,43 @@ 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 /* 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
570static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter) 586static 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}