aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
authorShyam Sundar <shyam.sundar@qlogic.com>2010-09-07 23:55:32 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-09-16 22:54:10 -0400
commite6a4202aa920a25db76f0e02dabe133179293ec0 (patch)
tree732a248684a0dd2b4e7eb239c0a4120ffa190798 /drivers/scsi/qla2xxx
parent6de76cfc7db8844bc26ab9a60b20f50ad7851833 (diff)
[SCSI] qla2xxx: ROM lock recovery if fw hangs while holding the lock.
Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index 614d745d7e11..8d8e40b829e4 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -3152,6 +3152,20 @@ qla82xx_start_iocbs(srb_t *sp)
3152 } 3152 }
3153} 3153}
3154 3154
3155void qla82xx_rom_lock_recovery(struct qla_hw_data *ha)
3156{
3157 if (qla82xx_rom_lock(ha))
3158 /* Someone else is holding the lock. */
3159 qla_printk(KERN_INFO, ha, "Resetting rom_lock\n");
3160
3161 /*
3162 * Either we got the lock, or someone
3163 * else died while holding it.
3164 * In either case, unlock.
3165 */
3166 qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK));
3167}
3168
3155/* 3169/*
3156 * qla82xx_device_bootstrap 3170 * qla82xx_device_bootstrap
3157 * Initialize device, set DEV_READY, start fw 3171 * Initialize device, set DEV_READY, start fw
@@ -3166,12 +3180,13 @@ qla82xx_start_iocbs(srb_t *sp)
3166static int 3180static int
3167qla82xx_device_bootstrap(scsi_qla_host_t *vha) 3181qla82xx_device_bootstrap(scsi_qla_host_t *vha)
3168{ 3182{
3169 int rval, i, timeout; 3183 int rval = QLA_SUCCESS;
3184 int i, timeout;
3170 uint32_t old_count, count; 3185 uint32_t old_count, count;
3171 struct qla_hw_data *ha = vha->hw; 3186 struct qla_hw_data *ha = vha->hw;
3187 int need_reset = 0, peg_stuck = 1;
3172 3188
3173 if (qla82xx_need_reset(ha)) 3189 need_reset = qla82xx_need_reset(ha);
3174 goto dev_initialize;
3175 3190
3176 old_count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); 3191 old_count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
3177 3192
@@ -3185,9 +3200,27 @@ qla82xx_device_bootstrap(scsi_qla_host_t *vha)
3185 3200
3186 count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); 3201 count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
3187 if (count != old_count) 3202 if (count != old_count)
3203 peg_stuck = 0;
3204 }
3205
3206 if (need_reset) {
3207 /* We are trying to perform a recovery here. */
3208 if (peg_stuck)
3209 qla82xx_rom_lock_recovery(ha);
3210 goto dev_initialize;
3211 } else {
3212 /* Start of day for this ha context. */
3213 if (peg_stuck) {
3214 /* Either we are the first or recovery in progress. */
3215 qla82xx_rom_lock_recovery(ha);
3216 goto dev_initialize;
3217 } else
3218 /* Firmware already running. */
3188 goto dev_ready; 3219 goto dev_ready;
3189 } 3220 }
3190 3221
3222 return rval;
3223
3191dev_initialize: 3224dev_initialize:
3192 /* set to DEV_INITIALIZING */ 3225 /* set to DEV_INITIALIZING */
3193 qla_printk(KERN_INFO, ha, "HW State: INITIALIZING\n"); 3226 qla_printk(KERN_INFO, ha, "HW State: INITIALIZING\n");