pr_debug("info: %s: free adapter\n", __func__);
 }
 
+/*
+ * This function cancels all works in the queue and destroys
+ * the main workqueue.
+ */
+static void mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
+{
+       flush_workqueue(adapter->workqueue);
+       destroy_workqueue(adapter->workqueue);
+       adapter->workqueue = NULL;
+}
+
 /*
  * This function gets firmware and initializes it.
  *
  */
 static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
 {
-       int ret;
+       int ret, i;
        char fmt[64];
        struct mwifiex_private *priv;
        struct mwifiex_adapter *adapter = context;
        if (!firmware) {
                dev_err(adapter->dev,
                        "Failed to get firmware %s\n", adapter->fw_name);
-               goto done;
+               goto err_dnld_fw;
        }
 
        memset(&fw, 0, sizeof(struct mwifiex_fw_image));
        else
                ret = mwifiex_dnld_fw(adapter, &fw);
        if (ret == -1)
-               goto done;
+               goto err_dnld_fw;
 
        dev_notice(adapter->dev, "WLAN FW is active\n");
 
        }
 
        /* enable host interrupt after fw dnld is successful */
-       if (adapter->if_ops.enable_int)
-               adapter->if_ops.enable_int(adapter);
+       if (adapter->if_ops.enable_int) {
+               if (adapter->if_ops.enable_int(adapter))
+                       goto err_dnld_fw;
+       }
 
        adapter->init_wait_q_woken = false;
        ret = mwifiex_init_fw(adapter);
        if (ret == -1) {
-               goto done;
+               goto err_init_fw;
        } else if (!ret) {
                adapter->hw_status = MWIFIEX_HW_STATUS_READY;
                goto done;
        wait_event_interruptible(adapter->init_wait_q,
                                 adapter->init_wait_q_woken);
        if (adapter->hw_status != MWIFIEX_HW_STATUS_READY)
-               goto done;
+               goto err_init_fw;
 
        priv = adapter->priv[MWIFIEX_BSS_ROLE_STA];
        if (mwifiex_register_cfg80211(adapter)) {
                dev_err(adapter->dev, "cannot register with cfg80211\n");
-               goto err_init_fw;
+               goto err_register_cfg80211;
        }
 
        rtnl_lock();
        goto done;
 
 err_add_intf:
-       mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev);
+       for (i = 0; i < adapter->priv_num; i++) {
+               priv = adapter->priv[i];
+
+               if (!priv)
+                       continue;
+
+               if (priv->wdev && priv->netdev)
+                       mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev);
+       }
        rtnl_unlock();
+err_register_cfg80211:
+       wiphy_unregister(adapter->wiphy);
+       wiphy_free(adapter->wiphy);
 err_init_fw:
        if (adapter->if_ops.disable_int)
                adapter->if_ops.disable_int(adapter);
+err_dnld_fw:
        pr_debug("info: %s: unregister device\n", __func__);
-       adapter->if_ops.unregister_dev(adapter);
+       if (adapter->if_ops.unregister_dev)
+               adapter->if_ops.unregister_dev(adapter);
+
+       if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) ||
+           (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) {
+               pr_debug("info: %s: shutdown mwifiex\n", __func__);
+               adapter->init_wait_q_woken = false;
+
+               if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
+                       wait_event_interruptible(adapter->init_wait_q,
+                                                adapter->init_wait_q_woken);
+       }
+       adapter->surprise_removed = true;
+       mwifiex_terminate_workqueue(adapter);
+       mwifiex_free_adapter(adapter);
 done:
        if (adapter->cal_data) {
                release_firmware(adapter->cal_data);
        }
        release_firmware(adapter->firmware);
        complete(&adapter->fw_load);
+       up(adapter->card_sem);
        return;
 }
 
        mwifiex_main_process(adapter);
 }
 
-/*
- * This function cancels all works in the queue and destroys
- * the main workqueue.
- */
-static void
-mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
-{
-       flush_workqueue(adapter->workqueue);
-       destroy_workqueue(adapter->workqueue);
-       adapter->workqueue = NULL;
-}
-
 /*
  * This function adds the card.
  *
        }
 
        adapter->iface_type = iface_type;
+       adapter->card_sem = sem;
 
        adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
        adapter->surprise_removed = false;
                goto err_init_fw;
        }
 
-       up(sem);
        return 0;
 
 err_init_fw:
        pr_debug("info: %s: unregister device\n", __func__);
        if (adapter->if_ops.unregister_dev)
                adapter->if_ops.unregister_dev(adapter);
-err_registerdev:
-       adapter->surprise_removed = true;
-       mwifiex_terminate_workqueue(adapter);
-err_kmalloc:
        if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) ||
            (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) {
                pr_debug("info: %s: shutdown mwifiex\n", __func__);
                        wait_event_interruptible(adapter->init_wait_q,
                                                 adapter->init_wait_q_woken);
        }
-
+err_registerdev:
+       adapter->surprise_removed = true;
+       mwifiex_terminate_workqueue(adapter);
+err_kmalloc:
        mwifiex_free_adapter(adapter);
 
 err_init_sw: