mwifiex: get rid of global adapter pointer
[deliverable/linux.git] / drivers / net / wireless / mwifiex / sdio.c
index 4327b6d099c891b39ac4633a98a2a9f19a3febe0..711fa689a95c3575a2cc433ae711fedfe29d3b9e 100644 (file)
 
 #define SDIO_VERSION   "1.0"
 
+/* The mwifiex_sdio_remove() callback function is called when
+ * user removes this module from kernel space or ejects
+ * the card from the slot. The driver handles these 2 cases
+ * differently.
+ * If the user is removing the module, the few commands (FUNC_SHUTDOWN,
+ * HS_CANCEL etc.) are sent to the firmware.
+ * If the card is removed, there is no need to send these command.
+ *
+ * The variable 'user_rmmod' is used to distinguish these two
+ * scenarios. This flag is initialized as FALSE in case the card
+ * is removed, and will be set to TRUE for module removal when
+ * module_exit function is called.
+ */
+static u8 user_rmmod;
+
 static struct mwifiex_if_ops sdio_ops;
 
 static struct semaphore add_remove_card_sem;
 
+static int mwifiex_sdio_resume(struct device *dev);
+
 /*
  * SDIO probe.
  *
@@ -93,17 +110,36 @@ static void
 mwifiex_sdio_remove(struct sdio_func *func)
 {
        struct sdio_mmc_card *card;
+       struct mwifiex_adapter *adapter;
+       int i;
 
        pr_debug("info: SDIO func num=%d\n", func->num);
 
-       if (func) {
-               card = sdio_get_drvdata(func);
-               if (card) {
-                       mwifiex_remove_card(card->adapter,
-                                       &add_remove_card_sem);
-                       kfree(card);
-               }
+       card = sdio_get_drvdata(func);
+       if (!card)
+               return;
+
+       adapter = card->adapter;
+       if (!adapter || !adapter->priv_num)
+               return;
+
+       if (user_rmmod) {
+               if (adapter->is_suspended)
+                       mwifiex_sdio_resume(adapter->dev);
+
+               for (i = 0; i < adapter->priv_num; i++)
+                       if ((GET_BSS_ROLE(adapter->priv[i]) ==
+                                               MWIFIEX_BSS_ROLE_STA) &&
+                                       adapter->priv[i]->media_connected)
+                               mwifiex_deauthenticate(adapter->priv[i], NULL);
+
+               mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
+                                               MWIFIEX_BSS_ROLE_ANY),
+                                        MWIFIEX_FUNC_SHUTDOWN);
        }
+
+       mwifiex_remove_card(card->adapter, &add_remove_card_sem);
+       kfree(card);
 }
 
 /*
@@ -1696,6 +1732,9 @@ mwifiex_sdio_init_module(void)
 {
        sema_init(&add_remove_card_sem, 1);
 
+       /* Clear the flag in case user removes the card. */
+       user_rmmod = 0;
+
        return sdio_register_driver(&mwifiex_sdio);
 }
 
@@ -1711,32 +1750,12 @@ mwifiex_sdio_init_module(void)
 static void
 mwifiex_sdio_cleanup_module(void)
 {
-       struct mwifiex_adapter *adapter = g_adapter;
-       int i;
-
-       if (down_interruptible(&add_remove_card_sem))
-               goto exit_sem_err;
-
-       if (!adapter || !adapter->priv_num)
-               goto exit;
-
-       if (adapter->is_suspended)
-               mwifiex_sdio_resume(adapter->dev);
-
-       for (i = 0; i < adapter->priv_num; i++)
-               if ((GET_BSS_ROLE(adapter->priv[i]) == MWIFIEX_BSS_ROLE_STA) &&
-                   adapter->priv[i]->media_connected)
-                       mwifiex_deauthenticate(adapter->priv[i], NULL);
-
-       if (!adapter->surprise_removed)
-               mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
-                                                         MWIFIEX_BSS_ROLE_ANY),
-                                        MWIFIEX_FUNC_SHUTDOWN);
+       if (!down_interruptible(&add_remove_card_sem))
+               up(&add_remove_card_sem);
 
-exit:
-       up(&add_remove_card_sem);
+       /* Set the flag as user is removing this module. */
+       user_rmmod = 1;
 
-exit_sem_err:
        sdio_unregister_driver(&mwifiex_sdio);
 }
 
This page took 0.042234 seconds and 5 git commands to generate.