Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e3f37d16 authored by Nilesh Javali's avatar Nilesh Javali Committed by James Bottomley
Browse files

[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: default avatarNilesh Javali <nilesh.javali@qlogic.com>
Signed-off-by: default avatarVikas Chaudhary <vikas.chaudhary@qlogic.com>
Reviewed-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent ce505f9d
Loading
Loading
Loading
Loading
+11 −8
Original line number Diff line number Diff line
@@ -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);

	while (1) {
	qla4_8xxx_idc_lock(ha);
	while (1) {

		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;
}