qla2x00_update_fcports(scsi_qla_host_t *base_vha)
 {
        fc_port_t *fcport;
-       struct scsi_qla_host *vha;
+       struct scsi_qla_host *vha, *tvp;
        struct qla_hw_data *ha = base_vha->hw;
        unsigned long flags;
 
        spin_lock_irqsave(&ha->vport_slock, flags);
        /* Go with deferred removal of rport references. */
-       list_for_each_entry(vha, &base_vha->hw->vp_list, list) {
+       list_for_each_entry_safe(vha, tvp, &base_vha->hw->vp_list, list) {
                atomic_inc(&vha->vref_count);
                list_for_each_entry(fcport, &vha->vp_fcports, list) {
                        if (fcport->drport &&
 qla2x00_quiesce_io(scsi_qla_host_t *vha)
 {
        struct qla_hw_data *ha = vha->hw;
-       struct scsi_qla_host *vp;
+       struct scsi_qla_host *vp, *tvp;
+       unsigned long flags;
 
        ql_dbg(ql_dbg_dpc, vha, 0x401d,
            "Quiescing I/O - ha=%p.\n", ha);
        if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
                atomic_set(&vha->loop_state, LOOP_DOWN);
                qla2x00_mark_all_devices_lost(vha);
-               list_for_each_entry(vp, &ha->vp_list, list)
+
+               spin_lock_irqsave(&ha->vport_slock, flags);
+               list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
+                       atomic_inc(&vp->vref_count);
+                       spin_unlock_irqrestore(&ha->vport_slock, flags);
+
                        qla2x00_mark_all_devices_lost(vp);
+
+                       spin_lock_irqsave(&ha->vport_slock, flags);
+                       atomic_dec(&vp->vref_count);
+               }
+               spin_unlock_irqrestore(&ha->vport_slock, flags);
        } else {
                if (!atomic_read(&vha->loop_down_timer))
                        atomic_set(&vha->loop_down_timer,
 qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
 {
        struct qla_hw_data *ha = vha->hw;
-       struct scsi_qla_host *vp;
+       struct scsi_qla_host *vp, *tvp;
        unsigned long flags;
        fc_port_t *fcport;
        u16 i;
                qla2x00_mark_all_devices_lost(vha);
 
                spin_lock_irqsave(&ha->vport_slock, flags);
-               list_for_each_entry(vp, &ha->vp_list, list) {
+               list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
                        atomic_inc(&vp->vref_count);
                        spin_unlock_irqrestore(&ha->vport_slock, flags);
 
                fcport->scan_state = 0;
        }
        spin_lock_irqsave(&ha->vport_slock, flags);
-       list_for_each_entry(vp, &ha->vp_list, list) {
+       list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
                atomic_inc(&vp->vref_count);
                spin_unlock_irqrestore(&ha->vport_slock, flags);
 
        int rval;
        uint8_t        status = 0;
        struct qla_hw_data *ha = vha->hw;
-       struct scsi_qla_host *vp;
+       struct scsi_qla_host *vp, *tvp;
        struct req_que *req = ha->req_q_map[0];
        unsigned long flags;
 
                ql_dbg(ql_dbg_taskm, vha, 0x8022, "%s succeeded.\n", __func__);
                qla2x00_configure_hba(vha);
                spin_lock_irqsave(&ha->vport_slock, flags);
-               list_for_each_entry(vp, &ha->vp_list, list) {
+               list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
                        if (vp->vp_idx) {
                                atomic_inc(&vp->vref_count);
                                spin_unlock_irqrestore(&ha->vport_slock, flags);
 {
        int status, rval;
        struct qla_hw_data *ha = vha->hw;
-       struct scsi_qla_host *vp;
+       struct scsi_qla_host *vp, *tvp;
        unsigned long flags;
 
        status = qla2x00_init_rings(vha);
                    "qla82xx_restart_isp succeeded.\n");
 
                spin_lock_irqsave(&ha->vport_slock, flags);
-               list_for_each_entry(vp, &ha->vp_list, list) {
+               list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
                        if (vp->vp_idx) {
                                atomic_inc(&vp->vref_count);
                                spin_unlock_irqrestore(&ha->vport_slock, flags);
 
        uint16_t vp_id;
        struct qla_hw_data *ha = vha->hw;
        unsigned long flags = 0;
-       u8 i;
+       u32 i, bailout;
 
        mutex_lock(&ha->vport_lock);
        /*
         * ensures no active vp_list traversal while the vport is removed
         * from the queue)
         */
-       for (i = 0; i < 10; i++) {
-               if (wait_event_timeout(vha->vref_waitq,
-                   !atomic_read(&vha->vref_count), HZ) > 0)
+       bailout = 0;
+       for (i = 0; i < 500; i++) {
+               spin_lock_irqsave(&ha->vport_slock, flags);
+               if (atomic_read(&vha->vref_count) == 0) {
+                       list_del(&vha->list);
+                       qlt_update_vp_map(vha, RESET_VP_IDX);
+                       bailout = 1;
+               }
+               spin_unlock_irqrestore(&ha->vport_slock, flags);
+
+               if (bailout)
                        break;
+               else
+                       msleep(20);
        }
-
-       spin_lock_irqsave(&ha->vport_slock, flags);
-       if (atomic_read(&vha->vref_count)) {
-               ql_dbg(ql_dbg_vport, vha, 0xfffa,
-                   "vha->vref_count=%u timeout\n", vha->vref_count.counter);
-               vha->vref_count = (atomic_t)ATOMIC_INIT(0);
+       if (!bailout) {
+               ql_log(ql_log_info, vha, 0xfffa,
+                       "vha->vref_count=%u timeout\n", vha->vref_count.counter);
+               spin_lock_irqsave(&ha->vport_slock, flags);
+               list_del(&vha->list);
+               qlt_update_vp_map(vha, RESET_VP_IDX);
+               spin_unlock_irqrestore(&ha->vport_slock, flags);
        }
-       list_del(&vha->list);
-       qlt_update_vp_map(vha, RESET_VP_IDX);
-       spin_unlock_irqrestore(&ha->vport_slock, flags);
 
        vp_id = vha->vp_idx;
        ha->num_vhosts--;
 void
 qla2x00_alert_all_vps(struct rsp_que *rsp, uint16_t *mb)
 {
-       scsi_qla_host_t *vha;
+       scsi_qla_host_t *vha, *tvp;
        struct qla_hw_data *ha = rsp->hw;
        int i = 0;
        unsigned long flags;
 
        spin_lock_irqsave(&ha->vport_slock, flags);
-       list_for_each_entry(vha, &ha->vp_list, list) {
+       list_for_each_entry_safe(vha, tvp, &ha->vp_list, list) {
                if (vha->vp_idx) {
                        if (test_bit(VPORT_DELETE, &vha->dpc_flags))
                                continue;
 qla2x00_do_dpc_all_vps(scsi_qla_host_t *vha)
 {
        struct qla_hw_data *ha = vha->hw;
-       scsi_qla_host_t *vp;
+       scsi_qla_host_t *vp, *tvp;
        unsigned long flags = 0;
 
        if (vha->vp_idx)
                return;
 
        spin_lock_irqsave(&ha->vport_slock, flags);
-       list_for_each_entry(vp, &ha->vp_list, list) {
+       list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
                if (vp->vp_idx) {
                        atomic_inc(&vp->vref_count);
                        spin_unlock_irqrestore(&ha->vport_slock, flags);
 
        struct qla_hw_data *ha = vha->hw;
        scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
        struct qla_qpair *qpair = NULL;
-       struct scsi_qla_host *vp;
+       struct scsi_qla_host *vp, *tvp;
        fc_port_t *fcport;
        int i;
        unsigned long flags;
        qla2x00_mark_all_devices_lost(vha);
 
        spin_lock_irqsave(&ha->vport_slock, flags);
-       list_for_each_entry(vp, &ha->vp_list, list) {
+       list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
                atomic_inc(&vp->vref_count);
                spin_unlock_irqrestore(&ha->vport_slock, flags);
                qla2x00_mark_all_devices_lost(vp);
                fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT);
 
        spin_lock_irqsave(&ha->vport_slock, flags);
-       list_for_each_entry(vp, &ha->vp_list, list) {
+       list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
                atomic_inc(&vp->vref_count);
                spin_unlock_irqrestore(&ha->vport_slock, flags);
                list_for_each_entry(fcport, &vp->vp_fcports, list)