diff options
| -rw-r--r-- | drivers/message/fusion/mptbase.c | 29 | ||||
| -rw-r--r-- | drivers/message/fusion/mptbase.h | 2 | ||||
| -rw-r--r-- | drivers/message/fusion/mptsas.c | 9 | ||||
| -rw-r--r-- | drivers/message/fusion/mptscsih.c | 12 | 
4 files changed, 47 insertions, 5 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 517621fa8bc..e9c6a6047a0 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -6474,8 +6474,19 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)  			pReq->Action, ioc->mptbase_cmds.status, timeleft));  		if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)  			goto out; -		if (!timeleft) +		if (!timeleft) { +			spin_lock_irqsave(&ioc->taskmgmt_lock, flags); +			if (ioc->ioc_reset_in_progress) { +				spin_unlock_irqrestore(&ioc->taskmgmt_lock, +					flags); +				printk(MYIOC_s_INFO_FMT "%s: host reset in" +					" progress mpt_config timed out.!!\n", +					__func__, ioc->name); +				return -EFAULT; +			} +			spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);  			issue_hard_reset = 1; +		}  		goto out;  	} @@ -7189,7 +7200,18 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)  	spin_lock_irqsave(&ioc->taskmgmt_lock, flags);  	if (ioc->ioc_reset_in_progress) {  		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); -		return 0; +		ioc->wait_on_reset_completion = 1; +		do { +			ssleep(1); +		} while (ioc->ioc_reset_in_progress == 1); +		ioc->wait_on_reset_completion = 0; +		return ioc->reset_status; +	} +	if (ioc->wait_on_reset_completion) { +		spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); +		rc = 0; +		time_count = jiffies; +		goto exit;  	}  	ioc->ioc_reset_in_progress = 1;  	if (ioc->alt_ioc) @@ -7226,6 +7248,7 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)  	ioc->ioc_reset_in_progress = 0;  	ioc->taskmgmt_quiesce_io = 0;  	ioc->taskmgmt_in_progress = 0; +	ioc->reset_status = rc;  	if (ioc->alt_ioc) {  		ioc->alt_ioc->ioc_reset_in_progress = 0;  		ioc->alt_ioc->taskmgmt_quiesce_io = 0; @@ -7241,7 +7264,7 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)  					ioc->alt_ioc, MPT_IOC_POST_RESET);  		}  	} - +exit:  	dtmprintk(ioc,  	    printk(MYIOC_s_DEBUG_FMT  		"HardResetHandler: completed (%d seconds): %s\n", ioc->name, diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index a4048ea45c9..b4d24dc081a 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -753,6 +753,8 @@ typedef struct _MPT_ADAPTER  	int			 taskmgmt_in_progress;  	u8			 taskmgmt_quiesce_io;  	u8			 ioc_reset_in_progress; +	u8			 reset_status; +	u8			 wait_on_reset_completion;  	MPT_SCHEDULE_TARGET_RESET schedule_target_reset;  	MPT_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds;  	struct work_struct	 sas_persist_task; diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 074e52254fc..9d950429854 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -1950,6 +1950,15 @@ static enum blk_eh_timer_return mptsas_eh_timed_out(struct scsi_cmnd *sc)  		goto done;  	} +	/* In case if IOC is in reset from internal context. +	*  Do not execute EEH for the same IOC. SML should to reset timer. +	*/ +	if (ioc->ioc_reset_in_progress) { +		dtmprintk(ioc, printk(MYIOC_s_WARN_FMT ": %s: ioc is in reset," +		    "SML need to reset the timer (sc=%p)\n", +		    ioc->name, __func__, sc)); +		rc = BLK_EH_RESET_TIMER; +	}  	vdevice = sc->device->hostdata;  	if (vdevice && vdevice->vtarget && (vdevice->vtarget->inDMD  		|| vdevice->vtarget->deleted)) { diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index de8cf92d861..ced6e4dc084 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -1630,7 +1630,13 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun,  		return 0;  	} -	if (ioc_raw_state & MPI_DOORBELL_ACTIVE) { +	/* DOORBELL ACTIVE check is not required if +	*  MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q is supported. +	*/ + +	if (!((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) +		 && (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) && +		(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {  		printk(MYIOC_s_WARN_FMT  			"TaskMgmt type=%x: ioc_state: "  			"DOORBELL_ACTIVE (0x%x)!\n", @@ -1729,7 +1735,9 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun,  		printk(MYIOC_s_WARN_FMT  		       "Issuing Reset from %s!! doorbell=0x%08x\n",  		       ioc->name, __func__, mpt_GetIocState(ioc, 0)); -		retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); +		retval = (ioc->bus_type == SAS) ? +			mpt_HardResetHandler(ioc, CAN_SLEEP) : +			mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);  		mpt_free_msg_frame(ioc, mf);  	}  |