return ret;
 }
 
-static void
-qla2x00_stop_dpc_thread(scsi_qla_host_t *vha)
-{
-       struct qla_hw_data *ha = vha->hw;
-       struct task_struct *t = ha->dpc_thread;
-
-       if (ha->dpc_thread == NULL)
-               return;
-       /*
-        * qla2xxx_wake_dpc checks for ->dpc_thread
-        * so we need to zero it out.
-        */
-       ha->dpc_thread = NULL;
-       kthread_stop(t);
-}
-
 static void
 qla2x00_shutdown(struct pci_dev *pdev)
 {
        qla2x00_free_fw_dump(ha);
 }
 
+/* Deletes all the virtual ports for a given ha */
 static void
-qla2x00_remove_one(struct pci_dev *pdev)
+qla2x00_delete_all_vps(struct qla_hw_data *ha, scsi_qla_host_t *base_vha)
 {
-       scsi_qla_host_t *base_vha, *vha;
-       struct qla_hw_data  *ha;
+       struct Scsi_Host *scsi_host;
+       scsi_qla_host_t *vha;
        unsigned long flags;
 
-       /*
-        * If the PCI device is disabled that means that probe failed and any
-        * resources should be have cleaned up on probe exit.
-        */
-       if (!atomic_read(&pdev->enable_cnt))
-               return;
-
-       base_vha = pci_get_drvdata(pdev);
-       ha = base_vha->hw;
-
-       ha->flags.host_shutting_down = 1;
-
-       set_bit(UNLOADING, &base_vha->dpc_flags);
-       if (IS_QLAFX00(ha))
-               qlafx00_driver_shutdown(base_vha, 20);
-
        mutex_lock(&ha->vport_lock);
        while (ha->cur_vport_count) {
                spin_lock_irqsave(&ha->vport_slock, flags);
                BUG_ON(base_vha->list.next == &ha->vp_list);
                /* This assumes first entry in ha->vp_list is always base vha */
                vha = list_first_entry(&base_vha->list, scsi_qla_host_t, list);
-               scsi_host_get(vha->host);
+               scsi_host = scsi_host_get(vha->host);
 
                spin_unlock_irqrestore(&ha->vport_slock, flags);
                mutex_unlock(&ha->vport_lock);
                mutex_lock(&ha->vport_lock);
        }
        mutex_unlock(&ha->vport_lock);
+}
 
-       if (IS_QLA8031(ha)) {
-               ql_dbg(ql_dbg_p3p, base_vha, 0xb07e,
-                   "Clearing fcoe driver presence.\n");
-               if (qla83xx_clear_drv_presence(base_vha) != QLA_SUCCESS)
-                       ql_dbg(ql_dbg_p3p, base_vha, 0xb079,
-                           "Error while clearing DRV-Presence.\n");
-       }
-
-       qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
-
-       qla2x00_dfs_remove(base_vha);
-
-       qla84xx_put_chip(base_vha);
-
-       /* Disable timer */
-       if (base_vha->timer_active)
-               qla2x00_stop_timer(base_vha);
-
-       base_vha->flags.online = 0;
-
+/* Stops all deferred work threads */
+static void
+qla2x00_destroy_deferred_work(struct qla_hw_data *ha)
+{
        /* Flush the work queue and remove it */
        if (ha->wq) {
                flush_workqueue(ha->wq);
                ha->dpc_thread = NULL;
                kthread_stop(t);
        }
-       qlt_remove_target(ha, base_vha);
-
-       qla2x00_free_sysfs_attr(base_vha);
-
-       fc_remove_host(base_vha->host);
-
-       scsi_remove_host(base_vha->host);
-
-       qla2x00_free_device(base_vha);
-
-       scsi_host_put(base_vha->host);
+}
 
-       if (IS_QLA8044(ha)) {
-               qla8044_idc_lock(ha);
-               qla8044_clear_drv_active(base_vha);
-               qla8044_idc_unlock(ha);
-       }
+static void
+qla2x00_unmap_iobases(struct qla_hw_data *ha)
+{
        if (IS_QLA82XX(ha)) {
-               qla82xx_idc_lock(ha);
-               qla82xx_clear_drv_active(ha);
-               qla82xx_idc_unlock(ha);
 
                iounmap((device_reg_t __iomem *)ha->nx_pcibase);
                if (!ql2xdbwr)
                if (IS_QLA83XX(ha) && ha->msixbase)
                        iounmap(ha->msixbase);
        }
+}
+
+static void
+qla2x00_clear_drv_active(scsi_qla_host_t *vha)
+{
+       struct qla_hw_data *ha = vha->hw;
+
+       if (IS_QLA8044(ha)) {
+               qla8044_idc_lock(ha);
+               qla8044_clear_drv_active(vha);
+               qla8044_idc_unlock(ha);
+       } else if (IS_QLA82XX(ha)) {
+               qla82xx_idc_lock(ha);
+               qla82xx_clear_drv_active(ha);
+               qla82xx_idc_unlock(ha);
+       }
+}
+
+static void
+qla2x00_remove_one(struct pci_dev *pdev)
+{
+       scsi_qla_host_t *base_vha;
+       struct qla_hw_data  *ha;
+
+       /*
+        * If the PCI device is disabled that means that probe failed and any
+        * resources should be have cleaned up on probe exit.
+        */
+       if (!atomic_read(&pdev->enable_cnt))
+               return;
+
+       base_vha = pci_get_drvdata(pdev);
+       ha = base_vha->hw;
+
+       set_bit(UNLOADING, &base_vha->dpc_flags);
+
+       if (IS_QLAFX00(ha))
+               qlafx00_driver_shutdown(base_vha, 20);
+
+       qla2x00_delete_all_vps(ha, base_vha);
+
+       if (IS_QLA8031(ha)) {
+               ql_dbg(ql_dbg_p3p, base_vha, 0xb07e,
+                   "Clearing fcoe driver presence.\n");
+               if (qla83xx_clear_drv_presence(base_vha) != QLA_SUCCESS)
+                       ql_dbg(ql_dbg_p3p, base_vha, 0xb079,
+                           "Error while clearing DRV-Presence.\n");
+       }
+
+       qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
+
+       qla2x00_dfs_remove(base_vha);
+
+       qla84xx_put_chip(base_vha);
+
+       /* Disable timer */
+       if (base_vha->timer_active)
+               qla2x00_stop_timer(base_vha);
+
+       base_vha->flags.online = 0;
+
+       qla2x00_destroy_deferred_work(ha);
+
+       qlt_remove_target(ha, base_vha);
+
+       qla2x00_free_sysfs_attr(base_vha, true);
+
+       fc_remove_host(base_vha->host);
+
+       scsi_remove_host(base_vha->host);
+
+       qla2x00_free_device(base_vha);
+
+       scsi_host_put(base_vha->host);
+
+       qla2x00_clear_drv_active(base_vha);
+
+       qla2x00_unmap_iobases(ha);
 
        pci_release_selected_regions(ha->pdev, ha->bars);
        kfree(ha);
        if (vha->timer_active)
                qla2x00_stop_timer(vha);
 
-       qla2x00_stop_dpc_thread(vha);
-
        qla25xx_delete_queues(vha);
+
        if (ha->flags.fce_enabled)
                qla2x00_disable_fce_trace(vha, NULL, NULL);