diff options
author | Shyam Sundar <shyam.sundar@qlogic.com> | 2010-09-07 20:55:32 -0700 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-09-16 22:54:10 -0400 |
commit | e6a4202aa920a25db76f0e02dabe133179293ec0 (patch) | |
tree | 732a248684a0dd2b4e7eb239c0a4120ffa190798 /drivers/scsi/qla2xxx | |
parent | 6de76cfc7db8844bc26ab9a60b20f50ad7851833 (diff) | |
download | op-kernel-dev-e6a4202aa920a25db76f0e02dabe133179293ec0.zip op-kernel-dev-e6a4202aa920a25db76f0e02dabe133179293ec0.tar.gz |
[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.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 614d745..8d8e40b 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) } } +void qla82xx_rom_lock_recovery(struct qla_hw_data *ha) +{ + if (qla82xx_rom_lock(ha)) + /* Someone else is holding the lock. */ + qla_printk(KERN_INFO, ha, "Resetting rom_lock\n"); + + /* + * Either we got the lock, or someone + * else died while holding it. + * In either case, unlock. + */ + qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK)); +} + /* * qla82xx_device_bootstrap * Initialize device, set DEV_READY, start fw @@ -3166,12 +3180,13 @@ qla82xx_start_iocbs(srb_t *sp) static int qla82xx_device_bootstrap(scsi_qla_host_t *vha) { - int rval, i, timeout; + int rval = QLA_SUCCESS; + int i, timeout; uint32_t old_count, count; struct qla_hw_data *ha = vha->hw; + int need_reset = 0, peg_stuck = 1; - if (qla82xx_need_reset(ha)) - goto dev_initialize; + need_reset = qla82xx_need_reset(ha); old_count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); @@ -3185,9 +3200,27 @@ qla82xx_device_bootstrap(scsi_qla_host_t *vha) count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); if (count != old_count) + peg_stuck = 0; + } + + if (need_reset) { + /* We are trying to perform a recovery here. */ + if (peg_stuck) + qla82xx_rom_lock_recovery(ha); + goto dev_initialize; + } else { + /* Start of day for this ha context. */ + if (peg_stuck) { + /* Either we are the first or recovery in progress. */ + qla82xx_rom_lock_recovery(ha); + goto dev_initialize; + } else + /* Firmware already running. */ goto dev_ready; } + return rval; + dev_initialize: /* set to DEV_INITIALIZING */ qla_printk(KERN_INFO, ha, "HW State: INITIALIZING\n"); |