mwifiex: fix issues in driver unload path for USB chipsets
authorUjjal Roy <royujjal@gmail.com>
Fri, 15 Nov 2013 03:10:42 +0000 (19:10 -0800)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 15 Nov 2013 19:29:32 +0000 (14:29 -0500)
1) After driver load failure, clear 'card->adapter' instead of
card pointer so that card specific cleanup is performed later
when user unloads the driver.

2) Clear usb_card pointer in disconnect handler to avoid invalid
memory access when user unloads the driver after removing the
card.

Signed-off-by: Ujjal Roy <royujjal@gmail.com>
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 1c70b8d092270ba3a456664aaf6ec3e9da4b3b59..edf5b7a24900ec1edf8d1fbb1e426b5268d2d3e2 100644 (file)
@@ -350,7 +350,6 @@ static int mwifiex_usb_probe(struct usb_interface *intf,
 
        card->udev = udev;
        card->intf = intf;
-       usb_card = card;
 
        pr_debug("info: bcdUSB=%#x Device Class=%#x SubClass=%#x Protocol=%#x\n",
                 udev->descriptor.bcdUSB, udev->descriptor.bDeviceClass,
@@ -525,25 +524,28 @@ 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 || !card->adapter) {
-               pr_err("%s: card or card->adapter is NULL\n", __func__);
+       if (!card) {
+               pr_err("%s: card is NULL\n", __func__);
                return;
        }
 
-       adapter = card->adapter;
-       if (!adapter->priv_num)
-               return;
-
        mwifiex_usb_free(card);
 
-       dev_dbg(adapter->dev, "%s: removing card\n", __func__);
-       mwifiex_remove_card(adapter, &add_remove_card_sem);
+       if (card->adapter) {
+               struct mwifiex_adapter *adapter = card->adapter;
+
+               if (!adapter->priv_num)
+                       return;
+
+               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;
 }
@@ -754,6 +756,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
        card->adapter = adapter;
        adapter->dev = &card->udev->dev;
        strcpy(adapter->fw_name, USB8797_DEFAULT_FW_NAME);
+       usb_card = card;
 
        return 0;
 }
@@ -762,7 +765,7 @@ static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
 {
        struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;
 
-       usb_set_intfdata(card->intf, NULL);
+       card->adapter = NULL;
 }
 
 static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
@@ -1004,7 +1007,7 @@ static void mwifiex_usb_cleanup_module(void)
        if (!down_interruptible(&add_remove_card_sem))
                up(&add_remove_card_sem);
 
-       if (usb_card) {
+       if (usb_card && usb_card->adapter) {
                struct mwifiex_adapter *adapter = usb_card->adapter;
                int i;