|
@@ -31,10 +31,27 @@
|
|
|
|
|
|
#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);
|
|
|
}
|
|
|
|