diff options
author | Nilesh Javali <nilesh.javali@qlogic.com> | 2011-12-02 06:42:11 (GMT) |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-12-15 06:57:42 (GMT) |
commit | e3f37d1636b7142527704ff62bf6f695a2887501 (patch) | |
tree | 7d4b91ff1c2a89cdf8e924d97e7fc879d0fa1231 /drivers/scsi/qla4xxx/ql4_nx.c | |
parent | ce505f9d1d9701f02b124ba1ee6caec21c2100e2 (diff) | |
download | linux-e3f37d1636b7142527704ff62bf6f695a2887501.tar.xz |
[SCSI] qla4xxx: Fix the IDC locking mechanism
This ensures the transition of dev_state from COLD to
INITIALIZING is within lock and atomic.
Signed-off-by: Nilesh Javali <nilesh.javali@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla4xxx/ql4_nx.c')
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_nx.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index 7fc29c6..8d6bc1b 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c @@ -1792,8 +1792,11 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha) int rval = QLA_SUCCESS; unsigned long dev_init_timeout; - if (!test_bit(AF_INIT_DONE, &ha->flags)) + if (!test_bit(AF_INIT_DONE, &ha->flags)) { + qla4_8xxx_idc_lock(ha); qla4_8xxx_set_drv_active(ha); + qla4_8xxx_idc_unlock(ha); + } dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE); ql4_printk(KERN_INFO, ha, "1:Device state is 0x%x = %s\n", dev_state, @@ -1802,8 +1805,8 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha) /* wait for 30 seconds for device to go ready */ dev_init_timeout = jiffies + (ha->nx_dev_init_timeout * HZ); + qla4_8xxx_idc_lock(ha); while (1) { - qla4_8xxx_idc_lock(ha); if (time_after_eq(jiffies, dev_init_timeout)) { ql4_printk(KERN_WARNING, ha, "Device init failed!\n"); @@ -1819,15 +1822,14 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha) /* NOTE: Make sure idc unlocked upon exit of switch statement */ switch (dev_state) { case QLA82XX_DEV_READY: - qla4_8xxx_idc_unlock(ha); goto exit; case QLA82XX_DEV_COLD: rval = qla4_8xxx_device_bootstrap(ha); - qla4_8xxx_idc_unlock(ha); goto exit; case QLA82XX_DEV_INITIALIZING: qla4_8xxx_idc_unlock(ha); msleep(1000); + qla4_8xxx_idc_lock(ha); break; case QLA82XX_DEV_NEED_RESET: if (!ql4xdontresethba) { @@ -1841,31 +1843,32 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha) msleep(1000); qla4_8xxx_idc_lock(ha); } - qla4_8xxx_idc_unlock(ha); break; case QLA82XX_DEV_NEED_QUIESCENT: - qla4_8xxx_idc_unlock(ha); /* idc locked/unlocked in handler */ qla4_8xxx_need_qsnt_handler(ha); - qla4_8xxx_idc_lock(ha); - /* fall thru needs idc_locked */ + break; case QLA82XX_DEV_QUIESCENT: qla4_8xxx_idc_unlock(ha); msleep(1000); + qla4_8xxx_idc_lock(ha); break; case QLA82XX_DEV_FAILED: qla4_8xxx_idc_unlock(ha); qla4xxx_dead_adapter_cleanup(ha); rval = QLA_ERROR; + qla4_8xxx_idc_lock(ha); goto exit; default: qla4_8xxx_idc_unlock(ha); qla4xxx_dead_adapter_cleanup(ha); rval = QLA_ERROR; + qla4_8xxx_idc_lock(ha); goto exit; } } exit: + qla4_8xxx_idc_unlock(ha); return rval; } |