diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 67 |
1 files changed, 65 insertions, 2 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 259f5113749..6f7cf397038 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -3844,6 +3844,37 @@ qla2x00_loop_resync(scsi_qla_host_t *vha) return (rval); } +/* +* qla2x00_perform_loop_resync +* Description: This function will set the appropriate flags and call +* qla2x00_loop_resync. If successful loop will be resynced +* Arguments : scsi_qla_host_t pointer +* returm : Success or Failure +*/ + +int qla2x00_perform_loop_resync(scsi_qla_host_t *ha) +{ + int32_t rval = 0; + + if (!test_and_set_bit(LOOP_RESYNC_ACTIVE, &ha->dpc_flags)) { + /*Configure the flags so that resync happens properly*/ + atomic_set(&ha->loop_down_timer, 0); + if (!(ha->device_flags & DFLG_NO_CABLE)) { + atomic_set(&ha->loop_state, LOOP_UP); + set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); + set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); + set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); + + rval = qla2x00_loop_resync(ha); + } else + atomic_set(&ha->loop_state, LOOP_DEAD); + + clear_bit(LOOP_RESYNC_ACTIVE, &ha->dpc_flags); + } + + return rval; +} + void qla2x00_update_fcports(scsi_qla_host_t *base_vha) { @@ -3871,11 +3902,43 @@ qla2x00_update_fcports(scsi_qla_host_t *base_vha) spin_unlock_irqrestore(&ha->vport_slock, flags); } +/* +* qla82xx_quiescent_state_cleanup +* Description: This function will block the new I/Os +* Its not aborting any I/Os as context +* is not destroyed during quiescence +* Arguments: scsi_qla_host_t +* return : void +*/ +void +qla82xx_quiescent_state_cleanup(scsi_qla_host_t *vha) +{ + struct qla_hw_data *ha = vha->hw; + struct scsi_qla_host *vp; + + qla_printk(KERN_INFO, ha, + "Performing ISP error recovery - ha= %p.\n", ha); + + atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); + if (atomic_read(&vha->loop_state) != LOOP_DOWN) { + atomic_set(&vha->loop_state, LOOP_DOWN); + qla2x00_mark_all_devices_lost(vha, 0); + list_for_each_entry(vp, &ha->vp_list, list) + qla2x00_mark_all_devices_lost(vha, 0); + } else { + if (!atomic_read(&vha->loop_down_timer)) + atomic_set(&vha->loop_down_timer, + LOOP_DOWN_TIME); + } + /* Wait for pending cmds to complete */ + qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST); +} + void qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) { struct qla_hw_data *ha = vha->hw; - struct scsi_qla_host *vp, *base_vha = pci_get_drvdata(ha->pdev); + struct scsi_qla_host *vp; unsigned long flags; vha->flags.online = 0; @@ -3896,7 +3959,7 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) qla2x00_mark_all_devices_lost(vha, 0); spin_lock_irqsave(&ha->vport_slock, flags); - list_for_each_entry(vp, &base_vha->hw->vp_list, list) { + list_for_each_entry(vp, &ha->vp_list, list) { atomic_inc(&vp->vref_count); spin_unlock_irqrestore(&ha->vport_slock, flags); |