mwifiex: use USB core's soft_unbind option
authorAmitkumar Karwar <akarwar@marvell.com>
Mon, 14 Apr 2014 22:32:54 +0000 (15:32 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 22 Apr 2014 19:06:30 +0000 (15:06 -0400)
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>
drivers/net/wireless/mwifiex/usb.c

index edbe4af..db6377f 100644 (file)
@@ -22,9 +22,9 @@
 
 #define USB_VERSION    "1.0"
 
+static u8 user_rmmod;
 static struct mwifiex_if_ops usb_ops;
 static struct semaphore add_remove_card_sem;
-static struct usb_card_rec *usb_card;
 
 static struct usb_device_id mwifiex_usb_table[] = {
        /* 8797 */
@@ -532,28 +532,43 @@ static int mwifiex_usb_resume(struct usb_interface *intf)
 static void mwifiex_usb_disconnect(struct usb_interface *intf)
 {
        struct usb_card_rec *card = usb_get_intfdata(intf);
+       struct mwifiex_adapter *adapter;
 
-       if (!card) {
-               pr_err("%s: card is NULL\n", __func__);
+       if (!card || !card->adapter) {
+               pr_err("%s: card or card->adapter is NULL\n", __func__);
                return;
        }
 
-       mwifiex_usb_free(card);
+       adapter = card->adapter;
+       if (!adapter->priv_num)
+               return;
 
-       if (card->adapter) {
-               struct mwifiex_adapter *adapter = card->adapter;
+       /* In case driver is removed when asynchronous FW downloading is
+        * in progress
+        */
+       wait_for_completion(&adapter->fw_load);
 
-               if (!adapter->priv_num)
-                       return;
+       if (user_rmmod) {
+#ifdef CONFIG_PM
+               if (adapter->is_suspended)
+                       mwifiex_usb_resume(intf);
+#endif
+
+               mwifiex_deauthenticate_all(adapter);
 
-               dev_dbg(adapter->dev, "%s: removing card\n", __func__);
-               mwifiex_remove_card(adapter, &add_remove_card_sem);
+               mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
+                                                         MWIFIEX_BSS_ROLE_ANY),
+                                        MWIFIEX_FUNC_SHUTDOWN);
        }
 
+       mwifiex_usb_free(card);
+
+       dev_dbg(adapter->dev, "%s: removing card\n", __func__);
+       mwifiex_remove_card(adapter, &add_remove_card_sem);
+
        usb_set_intfdata(intf, NULL);
        usb_put_dev(interface_to_usbdev(intf));
        kfree(card);
-       usb_card = NULL;
 
        return;
 }
@@ -565,6 +580,7 @@ static struct usb_driver mwifiex_usb_driver = {
        .id_table = mwifiex_usb_table,
        .suspend = mwifiex_usb_suspend,
        .resume = mwifiex_usb_resume,
+       .soft_unbind = 1,
 };
 
 static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter)
@@ -762,7 +778,6 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
 
        card->adapter = adapter;
        adapter->dev = &card->udev->dev;
-       usb_card = card;
 
        switch (le16_to_cpu(card->udev->descriptor.idProduct)) {
        case USB8897_PID_1:
@@ -1025,25 +1040,8 @@ static void mwifiex_usb_cleanup_module(void)
        if (!down_interruptible(&add_remove_card_sem))
                up(&add_remove_card_sem);
 
-       if (usb_card && usb_card->adapter) {
-               struct mwifiex_adapter *adapter = usb_card->adapter;
-
-               /* In case driver is removed when asynchronous FW downloading is
-                * in progress
-                */
-               wait_for_completion(&adapter->fw_load);
-
-#ifdef CONFIG_PM
-               if (adapter->is_suspended)
-                       mwifiex_usb_resume(usb_card->intf);
-#endif
-
-               mwifiex_deauthenticate_all(adapter);
-
-               mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
-                                                         MWIFIEX_BSS_ROLE_ANY),
-                                        MWIFIEX_FUNC_SHUTDOWN);
-       }
+       /* set the flag as user is removing this module */
+       user_rmmod = 1;
 
        usb_deregister(&mwifiex_usb_driver);
 }