Commit 3fffd7c1 authored by Amitkumar Karwar's avatar Amitkumar Karwar Committed by John W. Linville

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: default avatarAmitkumar Karwar <akarwar@marvell.com>
Signed-off-by: default avatarBing Zhao <bzhao@marvell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 5af3fae3
...@@ -22,9 +22,9 @@ ...@@ -22,9 +22,9 @@
#define USB_VERSION "1.0" #define USB_VERSION "1.0"
static u8 user_rmmod;
static struct mwifiex_if_ops usb_ops; static struct mwifiex_if_ops usb_ops;
static struct semaphore add_remove_card_sem; static struct semaphore add_remove_card_sem;
static struct usb_card_rec *usb_card;
static struct usb_device_id mwifiex_usb_table[] = { static struct usb_device_id mwifiex_usb_table[] = {
/* 8797 */ /* 8797 */
...@@ -532,28 +532,43 @@ static int mwifiex_usb_resume(struct usb_interface *intf) ...@@ -532,28 +532,43 @@ static int mwifiex_usb_resume(struct usb_interface *intf)
static void mwifiex_usb_disconnect(struct usb_interface *intf) static void mwifiex_usb_disconnect(struct usb_interface *intf)
{ {
struct usb_card_rec *card = usb_get_intfdata(intf); struct usb_card_rec *card = usb_get_intfdata(intf);
struct mwifiex_adapter *adapter;
if (!card) { if (!card || !card->adapter) {
pr_err("%s: card is NULL\n", __func__); pr_err("%s: card or card->adapter is NULL\n", __func__);
return; return;
} }
mwifiex_usb_free(card); adapter = card->adapter;
if (!adapter->priv_num)
return;
if (card->adapter) { /* In case driver is removed when asynchronous FW downloading is
struct mwifiex_adapter *adapter = card->adapter; * in progress
*/
wait_for_completion(&adapter->fw_load);
if (!adapter->priv_num) if (user_rmmod) {
return; #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_init_shutdown_fw(mwifiex_get_priv(adapter,
mwifiex_remove_card(adapter, &add_remove_card_sem); 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_set_intfdata(intf, NULL);
usb_put_dev(interface_to_usbdev(intf)); usb_put_dev(interface_to_usbdev(intf));
kfree(card); kfree(card);
usb_card = NULL;
return; return;
} }
...@@ -565,6 +580,7 @@ static struct usb_driver mwifiex_usb_driver = { ...@@ -565,6 +580,7 @@ static struct usb_driver mwifiex_usb_driver = {
.id_table = mwifiex_usb_table, .id_table = mwifiex_usb_table,
.suspend = mwifiex_usb_suspend, .suspend = mwifiex_usb_suspend,
.resume = mwifiex_usb_resume, .resume = mwifiex_usb_resume,
.soft_unbind = 1,
}; };
static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter) static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter)
...@@ -762,7 +778,6 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) ...@@ -762,7 +778,6 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
card->adapter = adapter; card->adapter = adapter;
adapter->dev = &card->udev->dev; adapter->dev = &card->udev->dev;
usb_card = card;
switch (le16_to_cpu(card->udev->descriptor.idProduct)) { switch (le16_to_cpu(card->udev->descriptor.idProduct)) {
case USB8897_PID_1: case USB8897_PID_1:
...@@ -1025,25 +1040,8 @@ static void mwifiex_usb_cleanup_module(void) ...@@ -1025,25 +1040,8 @@ static void mwifiex_usb_cleanup_module(void)
if (!down_interruptible(&add_remove_card_sem)) if (!down_interruptible(&add_remove_card_sem))
up(&add_remove_card_sem); up(&add_remove_card_sem);
if (usb_card && usb_card->adapter) { /* set the flag as user is removing this module */
struct mwifiex_adapter *adapter = usb_card->adapter; user_rmmod = 1;
/* 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);
}
usb_deregister(&mwifiex_usb_driver); usb_deregister(&mwifiex_usb_driver);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment