diff options
author | Saurav Kashyap <saurav.kashyap@qlogic.com> | 2010-12-21 19:00:14 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-12-23 16:40:55 -0500 |
commit | 579d12b58abb4bd1161728f0a4a2524258ecf0a3 (patch) | |
tree | 53f9ff32d3112b3c850aa51de9f1bbef08fbf996 /drivers/scsi/qla2xxx/qla_init.c | |
parent | 5f7bb3a439ce51ae8b92ca1dc93b91712224b69a (diff) |
[SCSI] qla2xxx: Added support for quiescence mode for ISP82xx.
Support is added for quiescence mode. This feature is for P3P
adapters. Any of the functions can put the firmware into quiescence
state. All the others have to ack that request. During quiescence mode
current commands are processed and all the new incoming I/Os are
blocked. Loop resync is performed after firmware comes out of
quiescence state.
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
Signed-off-by: Madhuranath Iyengar <Madhu.Iyengar@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
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 259f51137493..6f7cf3970383 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) | |||
3844 | return (rval); | 3844 | return (rval); |
3845 | } | 3845 | } |
3846 | 3846 | ||
3847 | /* | ||
3848 | * qla2x00_perform_loop_resync | ||
3849 | * Description: This function will set the appropriate flags and call | ||
3850 | * qla2x00_loop_resync. If successful loop will be resynced | ||
3851 | * Arguments : scsi_qla_host_t pointer | ||
3852 | * returm : Success or Failure | ||
3853 | */ | ||
3854 | |||
3855 | int qla2x00_perform_loop_resync(scsi_qla_host_t *ha) | ||
3856 | { | ||
3857 | int32_t rval = 0; | ||
3858 | |||
3859 | if (!test_and_set_bit(LOOP_RESYNC_ACTIVE, &ha->dpc_flags)) { | ||
3860 | /*Configure the flags so that resync happens properly*/ | ||
3861 | atomic_set(&ha->loop_down_timer, 0); | ||
3862 | if (!(ha->device_flags & DFLG_NO_CABLE)) { | ||
3863 | atomic_set(&ha->loop_state, LOOP_UP); | ||
3864 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); | ||
3865 | set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); | ||
3866 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | ||
3867 | |||
3868 | rval = qla2x00_loop_resync(ha); | ||
3869 | } else | ||
3870 | atomic_set(&ha->loop_state, LOOP_DEAD); | ||
3871 | |||
3872 | clear_bit(LOOP_RESYNC_ACTIVE, &ha->dpc_flags); | ||
3873 | } | ||
3874 | |||
3875 | return rval; | ||
3876 | } | ||
3877 | |||
3847 | void | 3878 | void |
3848 | qla2x00_update_fcports(scsi_qla_host_t *base_vha) | 3879 | qla2x00_update_fcports(scsi_qla_host_t *base_vha) |
3849 | { | 3880 | { |
@@ -3871,11 +3902,43 @@ qla2x00_update_fcports(scsi_qla_host_t *base_vha) | |||
3871 | spin_unlock_irqrestore(&ha->vport_slock, flags); | 3902 | spin_unlock_irqrestore(&ha->vport_slock, flags); |
3872 | } | 3903 | } |
3873 | 3904 | ||
3905 | /* | ||
3906 | * qla82xx_quiescent_state_cleanup | ||
3907 | * Description: This function will block the new I/Os | ||
3908 | * Its not aborting any I/Os as context | ||
3909 | * is not destroyed during quiescence | ||
3910 | * Arguments: scsi_qla_host_t | ||
3911 | * return : void | ||
3912 | */ | ||
3913 | void | ||
3914 | qla82xx_quiescent_state_cleanup(scsi_qla_host_t *vha) | ||
3915 | { | ||
3916 | struct qla_hw_data *ha = vha->hw; | ||
3917 | struct scsi_qla_host *vp; | ||
3918 | |||
3919 | qla_printk(KERN_INFO, ha, | ||
3920 | "Performing ISP error recovery - ha= %p.\n", ha); | ||
3921 | |||
3922 | atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); | ||
3923 | if (atomic_read(&vha->loop_state) != LOOP_DOWN) { | ||
3924 | atomic_set(&vha->loop_state, LOOP_DOWN); | ||
3925 | qla2x00_mark_all_devices_lost(vha, 0); | ||
3926 | list_for_each_entry(vp, &ha->vp_list, list) | ||
3927 | qla2x00_mark_all_devices_lost(vha, 0); | ||
3928 | } else { | ||
3929 | if (!atomic_read(&vha->loop_down_timer)) | ||
3930 | atomic_set(&vha->loop_down_timer, | ||
3931 | LOOP_DOWN_TIME); | ||
3932 | } | ||
3933 | /* Wait for pending cmds to complete */ | ||
3934 | qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST); | ||
3935 | } | ||
3936 | |||
3874 | void | 3937 | void |
3875 | qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) | 3938 | qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) |
3876 | { | 3939 | { |
3877 | struct qla_hw_data *ha = vha->hw; | 3940 | struct qla_hw_data *ha = vha->hw; |
3878 | struct scsi_qla_host *vp, *base_vha = pci_get_drvdata(ha->pdev); | 3941 | struct scsi_qla_host *vp; |
3879 | unsigned long flags; | 3942 | unsigned long flags; |
3880 | 3943 | ||
3881 | vha->flags.online = 0; | 3944 | vha->flags.online = 0; |
@@ -3896,7 +3959,7 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) | |||
3896 | qla2x00_mark_all_devices_lost(vha, 0); | 3959 | qla2x00_mark_all_devices_lost(vha, 0); |
3897 | 3960 | ||
3898 | spin_lock_irqsave(&ha->vport_slock, flags); | 3961 | spin_lock_irqsave(&ha->vport_slock, flags); |
3899 | list_for_each_entry(vp, &base_vha->hw->vp_list, list) { | 3962 | list_for_each_entry(vp, &ha->vp_list, list) { |
3900 | atomic_inc(&vp->vref_count); | 3963 | atomic_inc(&vp->vref_count); |
3901 | spin_unlock_irqrestore(&ha->vport_slock, flags); | 3964 | spin_unlock_irqrestore(&ha->vport_slock, flags); |
3902 | 3965 | ||