const char driver_version[] = "mwifiex " VERSION " (%s) ";
 
-struct mwifiex_adapter *g_adapter;
-EXPORT_SYMBOL_GPL(g_adapter);
-
 static struct mwifiex_bss_attr mwifiex_bss_sta[] = {
        {MWIFIEX_BSS_TYPE_STA, MWIFIEX_DATA_FRAME_TYPE_ETH_II, true, 0, 0},
 };
  * proper cleanup before exiting.
  */
 static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
-                           struct mwifiex_drv_mode *drv_mode_ptr)
+                           struct mwifiex_drv_mode *drv_mode_ptr,
+                           void **padapter)
 {
        struct mwifiex_adapter *adapter;
        int i;
        if (!adapter)
                return -ENOMEM;
 
-       g_adapter = adapter;
+       *padapter = adapter;
        adapter->card = card;
 
        /* Save interface specific operations in adapter */
  * and initializing the private structures.
  */
 static int
-mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops)
+mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops, void **padapter)
 {
        int i;
        struct mwifiex_drv_mode *drv_mode_ptr;
                return -1;
        }
 
-       if (mwifiex_register(card, if_ops, drv_mode_ptr))
+       if (mwifiex_register(card, if_ops, drv_mode_ptr, padapter))
                return -1;
 
        return 0;
        if (down_interruptible(sem))
                goto exit_sem_err;
 
-       if (mwifiex_init_sw(card, if_ops)) {
+       if (mwifiex_init_sw(card, if_ops, (void **)&adapter)) {
                pr_err("%s: software init failed\n", __func__);
                goto err_init_sw;
        }
 
-       adapter = g_adapter;
-
        adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
        adapter->surprise_removed = false;
        init_waitqueue_head(&adapter->init_wait_q);
 
 
 #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.
  *
 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);
 }
 
 /*
 {
        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);
 }
 
 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);
 }