/* * This function cleans up the SDIO driver. * * The following major steps are followed for cleanup - * - Resume the device if its suspended * - Disconnect the device if connected * - Shutdown the firmware * - Unregister the device from SDIO bus. */ 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); exit: up(&add_remove_card_sem); exit_sem_err: sdio_unregister_driver(&mwifiex_sdio); }
/* * SDIO remove. * * This function removes the interface and frees up the card structure. */ static void mwifiex_sdio_remove(struct sdio_func *func) { struct sdio_mmc_card *card; struct mwifiex_adapter *adapter; struct mwifiex_private *priv; int i; pr_debug("info: SDIO func num=%d\n", func->num); card = sdio_get_drvdata(func); if (!card) return; adapter = card->adapter; if (!adapter || !adapter->priv_num) return; /* In case driver is removed when asynchronous FW load is in progress */ wait_for_completion(&adapter->fw_load); if (user_rmmod) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) if (adapter->is_suspended) mwifiex_sdio_resume(adapter->dev); #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) */ 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); priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); mwifiex_disable_auto_ds(priv); mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN); } mwifiex_remove_card(card->adapter, &add_remove_card_sem); kfree(card); }
static void mwifiex_sdio_remove(struct sdio_func *func) { struct sdio_mmc_card *card; struct mwifiex_adapter *adapter; struct mwifiex_private *priv; int i; pr_debug("info: SDIO func num=%d\n", func->num); 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); priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); mwifiex_disable_auto_ds(priv); mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN); } mwifiex_remove_card(card->adapter, &add_remove_card_sem); kfree(card); }