Skip to contentSkip to conversation

fusion reset

PATCH Superseded Bernd Schubert 2 participants 5 messages Jan 7, 2009 – Jan 9, 2009

Subsystems (2)

v1 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

cover fusion reset

Hello,

here are two patches for the mpt fusion reset handling. Still missing from the series is a patch to prevent DV deadlocks, since my present approach still sometimes leaves the deadlock.

Signature · 2 lines
Bernd Schubert
Q-Leap Networks GmbH
#1 lore raw

PATCH 1/2 introduce soft reset handler

On dual port 53C1030 based HBAs such as the LSI22320R, the hard reset handler will cause DID_SOFT_ERROR for innocent devices on the second port. Introduce a mpt_SoftResetHandler() which doesn't cause this issue and slightly improve mpt_HardResetHandler().
This is mostly a backport of the fusion-4.x driver available from LSI.

 drivers/message/fusion/mptbase.c  |  211 ++++++++++++++++++++++++----
 drivers/message/fusion/mptbase.h  |   11 +
 drivers/message/fusion/mptctl.c   |    7
 drivers/message/fusion/mptsas.c   |    4
 drivers/message/fusion/mptscsih.c |   35 ++--
 5 files changed, 218 insertions(+), 50 deletions(-)
drivers/message/fusion/mptbase.c +131 -2
Index: linux-2.6/drivers/message/fusion/mptbase.c
===================================================================
@@ -5945,7 +5945,7 @@ mpt_timer_expired(unsigned long data)
 	dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name));
 
 	/* Perform a FW reload */
-	if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
+	if (mpt_SoftHardResetHandler(ioc, NO_SLEEP) < 0)
 		printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
 
 	/* No more processing.
@@ -6319,6 +6319,134 @@ mpt_print_ioc_summary(MPT_ADAPTER *ioc, 
 /*
  *	Reset Handling
  */
+
+/**
+ *	mpt_SoftResetHandler - Issues a less expensive reset
+ *	@ioc: Pointer to MPT_ADAPTER structure
+ *	@sleepFlag: Indicates if sleep or schedule must be called.
+
+ *
+ *	Returns 0 for SUCCESS or -1 if FAILED.
+ *
+ *	Message Unit Reset - instructs the IOC to reset the Reply Post and
+ *	Free FIFO's. All the Message Frames on Reply Free FIFO are discarded.
+ *	All posted buffers are freed, and event notification is turned off.
+ *	IOC doesnt reply to any outstanding request. This will transfer IOC
+ *	to READY state.
+ **/
+static int
+mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
+{
+	int		 rc;
+	int		 ii;
+	u8		 cb_idx;
+	unsigned long	 flags;
+	u32		 ioc_state;
+	unsigned long	 time_count;
+
+	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SoftResetHandler Entered!\n",
+			      ioc->name));
+
+	ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
+	if (ioc_state == MPI_IOC_STATE_FAULT ||
+	    ioc_state == MPI_IOC_STATE_RESET) {
+		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
+		    "skipping, either in FAULT or RESET state!\n", ioc->name));
+		return -1;
+	}
+
+	spin_lock_irqsave(&ioc->diagLock, flags);
+	if (ioc->ioc_reset_in_progress) {
+		spin_unlock_irqrestore(&ioc->diagLock, flags);
+		return -1;
+	}
+	ioc->ioc_reset_in_progress = 1;
+	spin_unlock_irqrestore(&ioc->diagLock, flags);
+
+	rc = -1;
+
+	for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
+		if (MptResetHandlers[cb_idx])
+			mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
+	}
+
+	/* Disable reply interrupts (also blocks FreeQ) */
+	CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
+	ioc->active = 0;
+	time_count = jiffies;
+	rc = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
+	if (rc != 0)
+		goto out;
+
+	/* MPT_IOC_PRE_RESET clears pending requests, but MUR
+	 * (MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET) tries to find a DMA request and
+	 * will fault the fw if no request is found. So we need to do
+	 * MPT_IOC_PRE_RESET after MUR */
+	for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
+		if (MptResetHandlers[cb_idx])
+			mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
+	}
+
+	ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
+	if (ioc_state != MPI_IOC_STATE_READY)
+		goto out;
+
+	for (ii = 0; ii < 5; ii++) {
+		/* Get IOC facts! Allow 5 retries */
+		rc = GetIocFacts(ioc, sleepFlag, MPT_HOSTEVENT_IOC_RECOVER);
+		if (rc == 0)
+			break;
+		if (sleepFlag == CAN_SLEEP)
+			msleep(100);
+		else
+			mdelay(100);
+	}
+	if (ii == 5)
+		goto out;
+
+	rc = PrimeIocFifos(ioc);
+	if (rc != 0)
+		goto out;
+
+	rc = SendIocInit(ioc, sleepFlag);
+	if (rc != 0)
+		goto out;
+
+	rc = SendEventNotification(ioc, 1);
+	if (rc != 0)
+		goto out;
+
+	if (ioc->hard_resets < -1)
+		ioc->hard_resets++;
+
+	/*
+	 * At this point, we know soft reset succeeded.
+	 */
+
+	ioc->active = 1;
+	CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
+
+ out:
+	spin_lock_irqsave(&ioc->diagLock, flags);
+	ioc->ioc_reset_in_progress = 0;
+	ioc->taskmgmt_quiesce_io = 0;
+	ioc->taskmgmt_in_progress = 0;
+	spin_unlock_irqrestore(&ioc->diagLock, flags);
+
+	if (ioc->active) {	/* otherwise, hard reset coming */
+		for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
+			if (MptResetHandlers[cb_idx])
+				mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
+		}
+	}
+
+	printk(MYIOC_s_INFO_FMT "SoftResetHandler: completed (%d seconds): %s\n",
+	    ioc->name, jiffies_to_msecs(jiffies - time_count)/1000,
+	    ((rc == 0) ? "SUCCESS" : "FAILED"));
+
+	return rc;
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *	mpt_HardResetHandler - Generic reset handler
@@ -6340,9 +6468,10 @@ int
 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
 {
 	int		 rc;
+	u8		 cb_idx;
 	unsigned long	 flags;
+	unsigned long	 time_count;
 
-	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", 

ioc->name));
#ifdef MFCNT
printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name); printk("MF count 0x%x !\n", ioc->mfcnt);
@@ -6352,12 +6481,15 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, i
* mpt_do_ioc_recovery at any instant in time.
*/
spin_lock_irqsave(&ioc->diagLock, flags);
- if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
+ if (ioc->ioc_reset_in_progress) {
spin_unlock_irqrestore(&ioc->diagLock, flags); return 0;
} else {
ioc->diagPending = 1;
}
+ ioc->ioc_reset_in_progress = 1;
+ if (ioc->alt_ioc)
+ ioc->alt_ioc->ioc_reset_in_progress = 1;
spin_unlock_irqrestore(&ioc->diagLock, flags);

/* FIXME: If do_ioc_recovery fails, repeat....
@@ -6368,42 +6500,70 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, i
* Prevents timeouts occurring during a diagnostic reset...very bad.
* For all other protocol drivers, this is a no-op.
*/
- {
- u8 cb_idx;
- int r = 0;
-
- for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
- if (MptResetHandlers[cb_idx]) {
- dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler
#%d\n",
- ioc->name, cb_idx));
- r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
- if (ioc->alt_ioc) {
- dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset
handler #%d\n",
- ioc->name, ioc->alt_ioc->name, cb_idx));
- r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
- }
- }
+ for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
+ if (MptResetHandlers[cb_idx]) {
+ mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
+ if (ioc->alt_ioc)
+ mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
}
}

- if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) !=
0) {
- printk(MYIOC_s_WARN_FMT "Cannot recover rc = %d!\n", ioc->name, rc);
+ time_count = jiffies;
+ rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag);
+ if (rc != 0) {
+ printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
+ rc, ioc->name);
+ } else {
+ if (ioc->hard_resets < -1)
+ ioc->hard_resets++;
}
- ioc->reload_fw = 0;
- if (ioc->alt_ioc)
- ioc->alt_ioc->reload_fw = 0;

spin_lock_irqsave(&ioc->diagLock, flags);
- ioc->diagPending = 0;
- if (ioc->alt_ioc)
- ioc->alt_ioc->diagPending = 0;
+ ioc->ioc_reset_in_progress = 0;
+ ioc->taskmgmt_quiesce_io = 0;
+ ioc->taskmgmt_in_progress = 0;
+ if (ioc->alt_ioc) {
+ ioc->alt_ioc->ioc_reset_in_progress = 0;
+ ioc->alt_ioc->taskmgmt_quiesce_io = 0;
+ ioc->alt_ioc->taskmgmt_in_progress = 0;
+ }
spin_unlock_irqrestore(&ioc->diagLock, flags);

- dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n",
ioc->name, rc));
+ for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
+ if (MptResetHandlers[cb_idx]) {
+ mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
+ if (ioc->alt_ioc)
+ mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET);
+ }
+ }
+
+ dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler: completed (%d
seconds): %s\n",
+ ioc->name, jiffies_to_msecs(jiffies - time_count)/1000,
+ ((rc == 0) ? "SUCCESS" : "FAILED")));
+ return rc;
+}
+
+/**
+ * mpt_SoftHardResetHandler - Generic reset handler
+ * @ioc: Pointer to MPT_ADAPTER structure
+ * @sleepFlag: Indicates if sleep or schedule must be called.
+ *
+ * First try to do a soft reset and if this fails, call the
+ * hard-reset-handler
+ */
+int
+mpt_SoftHardResetHandler(MPT_ADAPTER *ioc, int sleepFlag) +{
+ int rc;
+
+ rc = mpt_SoftResetHandler(ioc, sleepFlag);
+ if (rc)
+ rc = mpt_HardResetHandler(ioc, sleepFlag);

return rc;
}

+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ static void
EventDescriptionStr(u8 event, u32 evData0, char *evStr)
@@ -7561,6 +7721,7 @@ EXPORT_SYMBOL(mpt_verify_adapter);
EXPORT_SYMBOL(mpt_GetIocState); EXPORT_SYMBOL(mpt_print_ioc_summary); EXPORT_SYMBOL(mpt_HardResetHandler);
+EXPORT_SYMBOL(mpt_SoftHardResetHandler);
EXPORT_SYMBOL(mpt_config);
EXPORT_SYMBOL(mpt_findImVolumes); EXPORT_SYMBOL(mpt_alloc_fw_memory);

drivers/message/fusion/mptbase.h +8 -2
Index: linux-2.6/drivers/message/fusion/mptbase.h
===================================================================
@@ -701,6 +701,9 @@ typedef struct _MPT_ADAPTER
 	MPT_SAS_MGMT		 sas_mgmt;
 	struct work_struct	 sas_persist_task;
 
+	int			 taskmgmt_in_progress;
+	u8			 taskmgmt_quiesce_io;
+
 	struct work_struct	 fc_setup_reset_work;
 	struct list_head	 fc_rports;
 	struct work_struct	 fc_lsc_work;
@@ -709,6 +712,11 @@ typedef struct _MPT_ADAPTER
 	struct work_struct	 fc_rescan_work;
 	char			 fc_rescan_work_q_name[20];
 	struct workqueue_struct *fc_rescan_work_q;
+
+	unsigned long		 hard_resets;	/* driver forced bus resets count */
+	unsigned long		 soft_resets;	/* fw/external bus resets count */
+	u8			 ioc_reset_in_progress;
+
 	struct scsi_cmnd	**ScsiLookup;
 	spinlock_t		  scsi_lookup_lock;
 
@@ -844,8 +852,6 @@ typedef struct _MPT_SCSI_HOST {
 	MPT_FRAME_HDR		 *cmdPtr;		/* Ptr to nonOS request */
 	struct scsi_cmnd	 *abortSCpnt;
 	MPT_LOCAL_REPLY		  localReply;		/* internal cmd reply struct */
-	unsigned long		  hard_resets;		/* driver forced bus resets count */
-	unsigned long		  soft_resets;		/* fw/external bus resets count */
 	unsigned long		  timeouts;		/* cmd timeouts */
 	ushort			  sel_timeout[MPT_MAX_FC_DEVICES];
 	char 			  *info_kbuf;
@@ -916,6 +922,7 @@ extern int	 mpt_verify_adapter(int iocid
 extern u32	 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
 extern void	 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, 

int len, int showlan);
extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
+extern int mpt_SoftHardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
extern int mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);

drivers/message/fusion/mptscsih.c +21 -18
Index: linux-2.6/drivers/message/fusion/mptscsih.c
===================================================================
@@ -1605,7 +1605,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8
 			"TM Handler for type=%x: IOC Not operational (0x%x)!\n",
 			ioc->name, type, ioc_raw_state);
 		printk(MYIOC_s_WARN_FMT " Issuing HardReset!!\n", ioc->name);
-		if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
+		if (mpt_SoftHardResetHandler(ioc, CAN_SLEEP) < 0)
 			printk(MYIOC_s_WARN_FMT "TMHandler: HardReset "
 			    "FAILED!!\n", ioc->name);
 		return FAILED;
@@ -1621,8 +1621,8 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8
 
 	/* Isse the Task Mgmt request.
 	 */
-	if (hd->hard_resets < -1)
-		hd->hard_resets++;
+	if (ioc->hard_resets < -1)
+		ioc->hard_resets++;
 
 	rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun,
 	    ctx2abort, timeout);
@@ -1724,7 +1724,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd
 			ioc, mf));
 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling HardReset! \n",
 			 ioc->name));
-		retval = mpt_HardResetHandler(ioc, CAN_SLEEP);
+		retval = mpt_SoftHardResetHandler(ioc, CAN_SLEEP);
 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rc=%d \n",
 			 ioc->name, retval));
 		goto fail_out;
@@ -1998,11 +1998,12 @@ int
 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
 {
 	MPT_SCSI_HOST *  hd;
-	int              retval;
+	int		 retval, status;
 	MPT_ADAPTER	*ioc;
 
 	/*  If we can't locate the host to reset, then we failed. */
-	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
+	hd = shost_priv(SCpnt->device->host);
+	if (hd == NULL) {
 		printk(KERN_ERR MYNAM ": host reset: "
 		    "Can't locate host! (sc=%p)\n", SCpnt);
 		return FAILED;
@@ -2015,21 +2016,23 @@ mptscsih_host_reset(struct scsi_cmnd *SC
 	/*  If our attempts to reset the host failed, then return a failed
 	 *  status.  The host will be taken off line by the SCSI mid-layer.
 	 */
-	if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0) {
-		retval = FAILED;
-	} else {
+	retval = mpt_SoftHardResetHandler(ioc, CAN_SLEEP);
+
+	if (retval < 0)
+		status = FAILED;
+	else {
 		/*  Make sure TM pending is cleared and TM state is set to
 		 *  NONE.
 		 */
-		retval = 0;
+		status = SUCCESS;
 		hd->tmPending = 0;
 		hd->tmState = TM_STATE_NONE;
 	}
 
 	printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
-	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
+	    ioc->name, ((status == SUCCESS) ? "SUCCESS" : "FAILED"), SCpnt);
 
-	return retval;
+	return status;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2218,7 +2221,7 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *
 		 */
 		if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED ||
 		    hd->cmdPtr)
-			if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
+			if (mpt_SoftHardResetHandler(ioc, NO_SLEEP) < 0)
 				printk(MYIOC_s_WARN_FMT " Firmware Reload FAILED!!\n", ioc->name);
 		break;
 
@@ -2740,8 +2743,8 @@ mptscsih_event_process(MPT_ADAPTER *ioc,
 		break;
 	case MPI_EVENT_IOC_BUS_RESET:			/* 04 */
 	case MPI_EVENT_EXT_BUS_RESET:			/* 05 */
-		if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
-			hd->soft_resets++;
+		if (hd && (ioc->bus_type == SPI) && (ioc->soft_resets < -1))
+			ioc->soft_resets++;
 		break;
 	case MPI_EVENT_LOGOUT:				/* 09 */
 		/* FIXME! */
@@ -2979,9 +2982,9 @@ mptscsih_timer_expired(unsigned long dat
 			 */
 		} else {
 			/* Perform a FW reload */
-			if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
-				printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
-			}
+			if (mpt_SoftHardResetHandler(ioc, NO_SLEEP) < 0)
+				printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n",
+				       ioc->name);
 		}
 	} else {
 		/* This should NEVER happen */
drivers/message/fusion/mptctl.c +5 -3
Index: linux-2.6/drivers/message/fusion/mptctl.c
===================================================================
@@ -323,7 +323,7 @@ static void mptctl_timeout_expired (MPT_
 		 */
 		dctlprintk(ioctl->ioc, printk(MYIOC_s_DEBUG_FMT "Calling HardReset! \n",
 			 ioctl->ioc->name));
-		mpt_HardResetHandler(ioctl->ioc, CAN_SLEEP);
+		mpt_SoftHardResetHandler(ioctl->ioc, CAN_SLEEP);
 	}
 	return;
 
@@ -678,6 +678,8 @@ static int mptctl_do_reset(unsigned long
 	dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "mptctl_do_reset called.\n",
 	    iocp->name));
 
+	/* We can't use the soft reset handler here, since only the hard
+	 * reset handler can clear possible fw faults */
 	if (mpt_HardResetHandler(iocp, CAN_SLEEP) != 0) {
 		printk (MYIOC_s_ERR_FMT "%s@%d::mptctl_do_reset - reset failed.\n",
 			iocp->name, __FILE__, __LINE__);
@@ -2465,8 +2467,8 @@ mptctl_hp_hostinfo(unsigned long arg, un
 		MPT_SCSI_HOST *hd =  shost_priv(ioc->sh);
 
 		if (hd && (cim_rev == 1)) {
-			karg.hard_resets = hd->hard_resets;
-			karg.soft_resets = hd->soft_resets;
+			karg.hard_resets = ioc->hard_resets;
+			karg.soft_resets = ioc->soft_resets;
 			karg.timeouts = hd->timeouts;
 		}
 	}
drivers/message/fusion/mptsas.c +2 -2
Index: linux-2.6/drivers/message/fusion/mptsas.c
===================================================================
@@ -1167,7 +1167,7 @@ static int mptsas_phy_reset(struct sas_p
 	if (!timeleft) {
 		/* On timeout reset the board */
 		mpt_free_msg_frame(ioc, mf);
-		mpt_HardResetHandler(ioc, CAN_SLEEP);
+		mpt_SoftHardResetHandler(ioc, CAN_SLEEP);
 		error = -ETIMEDOUT;
 		goto out_unlock;
 	}
@@ -1345,7 +1345,7 @@ static int mptsas_smp_handler(struct Scs
 	if (!timeleft) {
 		printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __func__);
 		/* On timeout reset the board */
-		mpt_HardResetHandler(ioc, CAN_SLEEP);
+		mpt_SoftHardResetHandler(ioc, CAN_SLEEP);
 		ret = -ETIMEDOUT;
 		goto unmap;
 	}
#2 lore raw

RE: [PATCH 1/2 (resend) ] introduce soft reset handler

I have some concern regarding the usage of both ioc_reset_in_progress and diagPending. Could you please remove the usage of DiagPending completely and use ioc_reset_in_progress.

-----Original Message-----
From: Bernd Schubert [mailto:[email protected]]
Sent: Wednesday, January 07, 2009 11:34 PM
To: [email protected]
Cc: Prakash, Sathya; Moore, Eric; James Bottomley; DL-MPT Fusion Linux
Subject: [PATCH 1/2 (resend) ] introduce soft reset handler

On dual port 53C1030 based HBAs such as the LSI22320R, the hard reset handler will cause DID_SOFT_ERROR for innocent devices on the second port. Introduce a mpt_SoftResetHandler() which doesn't cause this issue and slightly improve mpt_HardResetHandler().
This is mostly a backport of the fusion-4.x driver available from LSI.

 drivers/message/fusion/mptbase.c  |  211 ++++++++++++++++++++++++----
 drivers/message/fusion/mptbase.h  |   11 +
 drivers/message/fusion/mptctl.c   |    7
 drivers/message/fusion/mptsas.c   |    4
 drivers/message/fusion/mptscsih.c |   35 ++--
 5 files changed, 218 insertions(+), 50 deletions(-)
drivers/message/fusion/mptbase.c +130 -2
Index: linux-2.6/drivers/message/fusion/mptbase.c
===================================================================
@@ -5945,7 +5945,7 @@ mpt_timer_expired(unsigned long data)
        dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name));
 
        /* Perform a FW reload */
-       if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
+       if (mpt_SoftHardResetHandler(ioc, NO_SLEEP) < 0)
                printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
 
        /* No more processing.
@@ -6319,6 +6319,134 @@ mpt_print_ioc_summary(MPT_ADAPTER *ioc,
 /*
  *     Reset Handling
  */
+
+/**
+ *     mpt_SoftResetHandler - Issues a less expensive reset
+ *     @ioc: Pointer to MPT_ADAPTER structure
+ *     @sleepFlag: Indicates if sleep or schedule must be called.
+
+ *
+ *     Returns 0 for SUCCESS or -1 if FAILED.
+ *
+ *     Message Unit Reset - instructs the IOC to reset the Reply Post and
+ *     Free FIFO's. All the Message Frames on Reply Free FIFO are discarded.
+ *     All posted buffers are freed, and event notification is turned off.
+ *     IOC doesnt reply to any outstanding request. This will transfer IOC
+ *     to READY state.
+ **/
+static int
+mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag) {
+       int              rc;
+       int              ii;
+       u8               cb_idx;
+       unsigned long    flags;
+       u32              ioc_state;
+       unsigned long    time_count;
+
+       dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SoftResetHandler Entered!\n",
+                             ioc->name));
+
+       ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
+       if (ioc_state == MPI_IOC_STATE_FAULT ||
+           ioc_state == MPI_IOC_STATE_RESET) {
+               dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
+                   "skipping, either in FAULT or RESET state!\n", ioc->name));
+               return -1;
+       }
+
+       spin_lock_irqsave(&ioc->diagLock, flags);
+       if (ioc->ioc_reset_in_progress) {
+               spin_unlock_irqrestore(&ioc->diagLock, flags);
+               return -1;
+       }
+       ioc->ioc_reset_in_progress = 1;
+       spin_unlock_irqrestore(&ioc->diagLock, flags);
+
+       rc = -1;
+
+       for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
+               if (MptResetHandlers[cb_idx])
+                       mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
+       }
+
+       /* Disable reply interrupts (also blocks FreeQ) */
+       CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
+       ioc->active = 0;
+       time_count = jiffies;
+       rc = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
+       if (rc != 0)
+               goto out;
+
+       /* MPT_IOC_PRE_RESET clears pending requests, but MUR
+        * (MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET) tries to find a DMA request and
+        * will fault the fw if no request is found. So we need to do
+        * MPT_IOC_PRE_RESET after MUR */
+       for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
+               if (MptResetHandlers[cb_idx])
+                       mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
+       }
+
+       ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
+       if (ioc_state != MPI_IOC_STATE_READY)
+               goto out;
+
+       for (ii = 0; ii < 5; ii++) {
+               /* Get IOC facts! Allow 5 retries */
+               rc = GetIocFacts(ioc, sleepFlag, MPT_HOSTEVENT_IOC_RECOVER);
+               if (rc == 0)
+                       break;
+               if (sleepFlag == CAN_SLEEP)
+                       msleep(100);
+               else
+                       mdelay(100);
+       }
+       if (ii == 5)
+               goto out;
+
+       rc = PrimeIocFifos(ioc);
+       if (rc != 0)
+               goto out;
+
+       rc = SendIocInit(ioc, sleepFlag);
+       if (rc != 0)
+               goto out;
+
+       rc = SendEventNotification(ioc, 1);
+       if (rc != 0)
+               goto out;
+
+       if (ioc->hard_resets < -1)
+               ioc->hard_resets++;
+
+       /*
+        * At this point, we know soft reset succeeded.
+        */
+
+       ioc->active = 1;
+       CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
+
+ out:
+       spin_lock_irqsave(&ioc->diagLock, flags);
+       ioc->ioc_reset_in_progress = 0;
+       ioc->taskmgmt_quiesce_io = 0;
+       ioc->taskmgmt_in_progress = 0;
+       spin_unlock_irqrestore(&ioc->diagLock, flags);
+
+       if (ioc->active) {      /* otherwise, hard reset coming */
+               for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
+                       if (MptResetHandlers[cb_idx])
+                               mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
+               }
+       }
+
+       printk(MYIOC_s_INFO_FMT "SoftResetHandler: completed (%d seconds): %s\n",
+           ioc->name, jiffies_to_msecs(jiffies - time_count)/1000,
+           ((rc == 0) ? "SUCCESS" : "FAILED"));
+
+       return rc;
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *     mpt_HardResetHandler - Generic reset handler
@@ -6340,9 +6468,10 @@ int
 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)  {
        int              rc;
+       u8               cb_idx;
        unsigned long    flags;
+       unsigned long    time_count;
 
-       dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n",

ioc->name));

 #ifdef MFCNT
        printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
        printk("MF count 0x%x !\n", ioc->mfcnt); @@ -6352,12 +6481,15 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, i
         * mpt_do_ioc_recovery at any instant in time.
         */
        spin_lock_irqsave(&ioc->diagLock, flags);
-       if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
+       if (ioc->ioc_reset_in_progress) {
                spin_unlock_irqrestore(&ioc->diagLock, flags);
                return 0;
        } else {
                ioc->diagPending = 1;
        }
+       ioc->ioc_reset_in_progress = 1;
+       if (ioc->alt_ioc)
+               ioc->alt_ioc->ioc_reset_in_progress = 1;
        spin_unlock_irqrestore(&ioc->diagLock, flags);

        /* FIXME: If do_ioc_recovery fails, repeat....

@@ -6368,42 +6500,70 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, i
* Prevents timeouts occurring during a diagnostic reset...very bad.
* For all other protocol drivers, this is a no-op.
*/
- {

-               u8       cb_idx;
-               int      r = 0;

-
- for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
- if (MptResetHandlers[cb_idx]) {
- dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler
#%d\n",
- ioc->name, cb_idx));
- r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
- if (ioc->alt_ioc) {
- dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset
handler #%d\n",
- ioc->name, ioc->alt_ioc->name, cb_idx));
- r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
- }
- }
+ for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
+ if (MptResetHandlers[cb_idx]) {
+ mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
+ if (ioc->alt_ioc)
+ mpt_signal_reset(cb_idx, ioc->alt_ioc,

+ MPT_IOC_SETUP_RESET);
                }
        }

- if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) !=
0) {
- printk(MYIOC_s_WARN_FMT "Cannot recover rc = %d!\n", ioc->name, rc);

+       time_count = jiffies;
+       rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag);
+       if (rc != 0) {

+ printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
+ rc, ioc->name);
+ } else {
+ if (ioc->hard_resets < -1)

+                       ioc->hard_resets++;
        }

- ioc->reload_fw = 0;
- if (ioc->alt_ioc)
- ioc->alt_ioc->reload_fw = 0;

        spin_lock_irqsave(&ioc->diagLock, flags);
-       ioc->diagPending = 0;
-       if (ioc->alt_ioc)
-               ioc->alt_ioc->diagPending = 0;
+       ioc->ioc_reset_in_progress = 0;
+       ioc->taskmgmt_quiesce_io = 0;
+       ioc->taskmgmt_in_progress = 0;
+       if (ioc->alt_ioc) {
+               ioc->alt_ioc->ioc_reset_in_progress = 0;
+               ioc->alt_ioc->taskmgmt_quiesce_io   = 0;
+               ioc->alt_ioc->taskmgmt_in_progress  = 0;
+       }
        spin_unlock_irqrestore(&ioc->diagLock, flags);

- dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n",
ioc->name, rc));
+ for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
+ if (MptResetHandlers[cb_idx]) {
+ mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
+ if (ioc->alt_ioc)
+ mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET);
+ }
+ }
+
+ dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler:
+ completed (%d
seconds): %s\n",
+ ioc->name, jiffies_to_msecs(jiffies - time_count)/1000,
+ ((rc == 0) ? "SUCCESS" : "FAILED")));
+ return rc;
+}
+
+/**

+ *     mpt_SoftHardResetHandler - Generic reset handler
+ *     @ioc: Pointer to MPT_ADAPTER structure
+ *     @sleepFlag: Indicates if sleep or schedule must be called.

+ *
+ * First try to do a soft reset and if this fails, call the
+ * hard-reset-handler
+ */
+int
+mpt_SoftHardResetHandler(MPT_ADAPTER *ioc, int sleepFlag) {
+ int rc;
+
+ rc = mpt_SoftResetHandler(ioc, sleepFlag);
+ if (rc)
+ rc = mpt_HardResetHandler(ioc, sleepFlag);

        return rc;

}

+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static void
EventDescriptionStr(u8 event, u32 evData0, char *evStr) @@ -7561,6 +7721,7 @@ EXPORT_SYMBOL(mpt_verify_adapter); EXPORT_SYMBOL(mpt_GetIocState);
EXPORT_SYMBOL(mpt_print_ioc_summary);
EXPORT_SYMBOL(mpt_HardResetHandler);
+EXPORT_SYMBOL(mpt_SoftHardResetHandler);
EXPORT_SYMBOL(mpt_config);
EXPORT_SYMBOL(mpt_findImVolumes);
EXPORT_SYMBOL(mpt_alloc_fw_memory);

drivers/message/fusion/mptbase.h +8 -2
Index: linux-2.6/drivers/message/fusion/mptbase.h
===================================================================
@@ -701,6 +701,9 @@ typedef struct _MPT_ADAPTER
        MPT_SAS_MGMT             sas_mgmt;
        struct work_struct       sas_persist_task;
 
+       int                      taskmgmt_in_progress;
+       u8                       taskmgmt_quiesce_io;
+
        struct work_struct       fc_setup_reset_work;
        struct list_head         fc_rports;
        struct work_struct       fc_lsc_work;
@@ -709,6 +712,11 @@ typedef struct _MPT_ADAPTER
        struct work_struct       fc_rescan_work;
        char                     fc_rescan_work_q_name[20];
        struct workqueue_struct *fc_rescan_work_q;
+
+       unsigned long            hard_resets;   /* driver forced bus resets count */
+       unsigned long            soft_resets;   /* fw/external bus resets count */
+       u8                       ioc_reset_in_progress;
+
        struct scsi_cmnd        **ScsiLookup;
        spinlock_t                scsi_lookup_lock;
 
@@ -844,8 +852,6 @@ typedef struct _MPT_SCSI_HOST {
        MPT_FRAME_HDR            *cmdPtr;               /* Ptr to nonOS request */
        struct scsi_cmnd         *abortSCpnt;
        MPT_LOCAL_REPLY           localReply;           /* internal cmd reply struct */
-       unsigned long             hard_resets;          /* driver forced bus resets count */
-       unsigned long             soft_resets;          /* fw/external bus resets count */
        unsigned long             timeouts;             /* cmd timeouts */
        ushort                    sel_timeout[MPT_MAX_FC_DEVICES];
        char                      *info_kbuf;
@@ -916,6 +922,7 @@ extern int   mpt_verify_adapter(int iocid
 extern u32      mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
 extern void     mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size,

int len, int showlan);

 extern int      mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
+extern int      mpt_SoftHardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
 extern int      mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
 extern int      mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
 extern void     mpt_free_fw_memory(MPT_ADAPTER *ioc);
drivers/message/fusion/mptscsih.c +16 -12
Index: linux-2.6/drivers/message/fusion/mptscsih.c
===================================================================
@@ -1605,7 +1605,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8
                        "TM Handler for type=%x: IOC Not operational (0x%x)!\n",
                        ioc->name, type, ioc_raw_state);
                printk(MYIOC_s_WARN_FMT " Issuing HardReset!!\n", ioc->name);
-               if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
+               if (mpt_SoftHardResetHandler(ioc, CAN_SLEEP) < 0)
                        printk(MYIOC_s_WARN_FMT "TMHandler: HardReset "
                            "FAILED!!\n", ioc->name);
                return FAILED;
@@ -1621,8 +1621,8 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8
 
        /* Isse the Task Mgmt request.
         */
-       if (hd->hard_resets < -1)
-               hd->hard_resets++;
+       if (ioc->hard_resets < -1)
+               ioc->hard_resets++;
 
        rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun,
            ctx2abort, timeout);
@@ -1724,7 +1724,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd
                        ioc, mf));
                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling HardReset! \n",
                         ioc->name));
-               retval = mpt_HardResetHandler(ioc, CAN_SLEEP);
+               retval = mpt_SoftHardResetHandler(ioc, CAN_SLEEP);
                dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rc=%d \n",
                         ioc->name, retval));
                goto fail_out;
@@ -1998,11 +1998,12 @@ int
 mptscsih_host_reset(struct scsi_cmnd *SCpnt)  {
        MPT_SCSI_HOST *  hd;
-       int              retval;
+       int              retval, status;
        MPT_ADAPTER     *ioc;
 
        /*  If we can't locate the host to reset, then we failed. */
-       if ((hd = shost_priv(SCpnt->device->host)) == NULL){
+       hd = shost_priv(SCpnt->device->host);
+       if (hd == NULL) {
                printk(KERN_ERR MYNAM ": host reset: "
                    "Can't locate host! (sc=%p)\n", SCpnt);
                return FAILED;
@@ -2015,21 +2016,23 @@ mptscsih_host_reset(struct scsi_cmnd *SC
        /*  If our attempts to reset the host failed, then return a failed
         *  status.  The host will be taken off line by the SCSI mid-layer.
         */
-       if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0) {
-               retval = FAILED;
-       } else {
+       retval = mpt_SoftHardResetHandler(ioc, CAN_SLEEP);
+
+       if (retval < 0)
+               status = FAILED;
+       else {
                /*  Make sure TM pending is cleared and TM state is set to
                 *  NONE.
                 */
-               retval = 0;
+               status = SUCCESS;
                hd->tmPending = 0;
                hd->tmState = TM_STATE_NONE;
        }
 
        printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
-           ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
+           ioc->name, ((status == SUCCESS) ? "SUCCESS" : "FAILED"),
+ SCpnt);
 
-       return retval;
+       return status;
 }
 

/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2218,7 +2221,7 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *

                 */
                if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED ||
                    hd->cmdPtr)
-                       if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
+                       if (mpt_SoftHardResetHandler(ioc, NO_SLEEP) < 0)
                                printk(MYIOC_s_WARN_FMT " Firmware Reload FAILED!!\n", ioc->name);
                break;

@@ -2740,8 +2743,8 @@ mptscsih_event_process(MPT_ADAPTER *ioc,
break;
case MPI_EVENT_IOC_BUS_RESET: /* 04 */
case MPI_EVENT_EXT_BUS_RESET: /* 05 */
- if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
- hd->soft_resets++;
+ if (hd && (ioc->bus_type == SPI) && (ioc->soft_resets < -1))

+                       ioc->soft_resets++;
                break;
        case MPI_EVENT_LOGOUT:                          /* 09 */
                /* FIXME! */
@@ -2979,9 +2982,9 @@ mptscsih_timer_expired(unsigned long dat
                         */
                } else {
                        /* Perform a FW reload */

- if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
- printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
- }
+ if (mpt_SoftHardResetHandler(ioc, NO_SLEEP) < 0)
+ printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n",

+                                      ioc->name);
                }
        } else {
                /* This should NEVER happen */
drivers/message/fusion/mptctl.c +3 -1
Index: linux-2.6/drivers/message/fusion/mptctl.c
===================================================================
@@ -323,7 +323,7 @@ static void mptctl_timeout_expired (MPT_
                 */
                dctlprintk(ioctl->ioc, printk(MYIOC_s_DEBUG_FMT "Calling HardReset! \n",
                         ioctl->ioc->name));
-               mpt_HardResetHandler(ioctl->ioc, CAN_SLEEP);
+               mpt_SoftHardResetHandler(ioctl->ioc, CAN_SLEEP);
        }
        return;
 
@@ -678,6 +678,8 @@ static int mptctl_do_reset(unsigned long
        dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "mptctl_do_reset called.\n",
            iocp->name));
 
+       /* We can't use the soft reset handler here, since only the hard
+        * reset handler can clear possible fw faults */
        if (mpt_HardResetHandler(iocp, CAN_SLEEP) != 0) {
                printk (MYIOC_s_ERR_FMT "%s@%d::mptctl_do_reset - reset failed.\n",
                        iocp->name, __FILE__, __LINE__); @@ -2465,8 +2467,8 @@ mptctl_hp_hostinfo(unsigned long arg, un
                MPT_SCSI_HOST *hd =  shost_priv(ioc->sh);

                if (hd && (cim_rev == 1)) {
-                       karg.hard_resets = hd->hard_resets;
-                       karg.soft_resets = hd->soft_resets;
+                       karg.hard_resets = ioc->hard_resets;
+                       karg.soft_resets = ioc->soft_resets;
                        karg.timeouts = hd->timeouts;
                }
        }
drivers/message/fusion/mptsas.c +2 -2
Index: linux-2.6/drivers/message/fusion/mptsas.c
===================================================================
@@ -1167,7 +1167,7 @@ static int mptsas_phy_reset(struct sas_p
        if (!timeleft) {
                /* On timeout reset the board */
                mpt_free_msg_frame(ioc, mf);
-               mpt_HardResetHandler(ioc, CAN_SLEEP);
+               mpt_SoftHardResetHandler(ioc, CAN_SLEEP);
                error = -ETIMEDOUT;
                goto out_unlock;
        }
@@ -1345,7 +1345,7 @@ static int mptsas_smp_handler(struct Scs
        if (!timeleft) {
                printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __func__);
                /* On timeout reset the board */
-               mpt_HardResetHandler(ioc, CAN_SLEEP);
+               mpt_SoftHardResetHandler(ioc, CAN_SLEEP);
                ret = -ETIMEDOUT;
                goto unmap;
        }
#3 lore raw

PATCH 2/2 reset flag documentation

In reply to Bernd Schubert

Add documentation of a fusion MPT reset flag.

drivers/message/fusion/mptbase.h +0 -0
Index: linux-2.6/drivers/message/fusion/mptbase.h
===================================================================
@@ -735,8 +735,9 @@ typedef struct _MPT_ADAPTER
 typedef int (*MPT_CALLBACK)(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, 

MPT_FRAME_HDR *reply);
typedef int (*MPT_EVHANDLER)(MPT_ADAPTER *ioc, EventNotificationReply_t
*evReply);
typedef int (*MPT_RESETHANDLER)(MPT_ADAPTER *ioc, int reset_phase);
-/* reset_phase defs */
-#define MPT_IOC_PRE_RESET 0
+
+/* reset_phase defs, see e.g. mptscsih_ioc_reset() about flag usage */
+#define MPT_IOC_PRE_RESET 0 /* clear pending requests */
#define MPT_IOC_POST_RESET 1
#define MPT_IOC_SETUP_RESET 2

Signature · 2 lines
Bernd Schubert
Q-Leap Networks GmbH
#4 lore raw

RE: [PATCH 2/2 (resend) ] reset flag documentation

ACK

-----Original Message-----
From: Bernd Schubert [mailto:[email protected]]
Sent: Wednesday, January 07, 2009 11:36 PM
To: [email protected]
Cc: Prakash, Sathya; Moore, Eric; James Bottomley; DL-MPT Fusion Linux
Subject: [PATCH 2/2 (resend) ] reset flag documentation

Add documentation of a fusion MPT reset flag.

drivers/message/fusion/mptbase.h +3 -2
Index: linux-2.6/drivers/message/fusion/mptbase.h
===================================================================
@@ -735,8 +735,9 @@ typedef struct _MPT_ADAPTER  typedef int (*MPT_CALLBACK)(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);  typedef int (*MPT_EVHANDLER)(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply);  typedef int (*MPT_RESETHANDLER)(MPT_ADAPTER *ioc, int reset_phase);
-/* reset_phase defs */
-#define MPT_IOC_PRE_RESET              0
+
+/* reset_phase defs, see e.g. mptscsih_ioc_reset() about flag usage */
+#define MPT_IOC_PRE_RESET              0       /* clear pending requests */
 #define MPT_IOC_POST_RESET             1
 #define MPT_IOC_SETUP_RESET            2
 
 
 
 

--
Bernd Schubert
Q-Leap Networks GmbH