From: Nilesh Javali Date: Fri, 2 Dec 2011 06:42:11 +0000 (-0800) Subject: [SCSI] qla4xxx: Fix the IDC locking mechanism X-Git-Tag: next-20111216~64^2~12 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=e3f37d1636b7142527704ff62bf6f695a2887501;p=karo-tx-linux.git [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 Signed-off-by: Vikas Chaudhary Reviewed-by: Mike Christie Signed-off-by: James Bottomley --- diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index 7fc29c6ff57e..8d6bc1b2ff17 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; }