All of lore.kernel.org
 help / color / mirror / Atom feed
* [ PATCH 0/3 ] mpt fusion enhancements
@ 2009-02-06 13:08 Bernd Schubert
  2009-02-06 13:18 ` [ PATCH 1/3 ] rename diagPending to ioc_reset_in_progress Bernd Schubert
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Bernd Schubert @ 2009-02-06 13:08 UTC (permalink / raw)
  To: Prakash, Sathya
  Cc: linux-scsi, Desai, Kashyap, Moore, Eric, James.Bottomley,
	DL-MPT Fusion Linux, Andrew Morton

Here are 3 patches for the mpt fusion driver.


-- 
Bernd Schubert
Q-Leap Networks GmbH

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ PATCH 1/3 ] rename diagPending to ioc_reset_in_progress.
  2009-02-06 13:08 [ PATCH 0/3 ] mpt fusion enhancements Bernd Schubert
@ 2009-02-06 13:18 ` Bernd Schubert
  2009-02-06 13:20 ` [ PATCH 2/3 v4 ] introduce soft reset handler Bernd Schubert
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Bernd Schubert @ 2009-02-06 13:18 UTC (permalink / raw)
  To: Prakash, Sathya
  Cc: linux-scsi, Desai, Kashyap, Moore, Eric, James.Bottomley,
	DL-MPT Fusion Linux, Andrew Morton

Replace diagPending by ioc_reset_in_progress. Similarily to the fusion-4.17 
driver.

Signed-off-by: Bernd Schubert <bs@q-leap.de>

---
 drivers/message/fusion/mptbase.c  |   16 +++++++++-------
 drivers/message/fusion/mptbase.h  |    2 +-
 drivers/message/fusion/mptscsih.c |    3 ++-
 3 files changed, 12 insertions(+), 9 deletions(-)

Index: linus-git/drivers/message/fusion/mptbase.c
===================================================================
--- linus-git.orig/drivers/message/fusion/mptbase.c
+++ linus-git/drivers/message/fusion/mptbase.c
@@ -290,7 +290,7 @@ mpt_fault_reset_work(struct work_struct 
 	int		 rc;
 	unsigned long	 flags;
 
-	if (ioc->diagPending || !ioc->active)
+	if (ioc->ioc_reset_in_progress || !ioc->active)
 		goto out;
 
 	ioc_raw_state = mpt_GetIocState(ioc, 0);
@@ -1655,7 +1655,7 @@ mpt_attach(struct pci_dev *pdev, const s
 	ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
 
 	ioc->pcidev = pdev;
-	ioc->diagPending = 0;
+	ioc->ioc_reset_in_progress = 0;
 	spin_lock_init(&ioc->diagLock);
 	spin_lock_init(&ioc->initializing_hba_lock);
 
@@ -6411,12 +6411,14 @@ 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)
+	|| (ioc->alt_ioc && ioc->alt_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....
@@ -6453,9 +6455,9 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, i
 		ioc->alt_ioc->reload_fw = 0;
 
 	spin_lock_irqsave(&ioc->diagLock, flags);
-	ioc->diagPending = 0;
+	ioc->ioc_reset_in_progress = 0;
 	if (ioc->alt_ioc)
-		ioc->alt_ioc->diagPending = 0;
+		ioc->alt_ioc->ioc_reset_in_progress = 0;
 	spin_unlock_irqrestore(&ioc->diagLock, flags);
 
 	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
Index: linus-git/drivers/message/fusion/mptbase.h
===================================================================
--- linus-git.orig/drivers/message/fusion/mptbase.h
+++ linus-git/drivers/message/fusion/mptbase.h
@@ -644,7 +644,7 @@ typedef struct _MPT_ADAPTER
 	struct proc_dir_entry	*ioc_dentry;
 	struct _MPT_ADAPTER	*alt_ioc;	/* ptr to 929 bound adapter port */
 	spinlock_t		 diagLock;	/* diagnostic reset lock */
-	int			 diagPending;
+	u8			 ioc_reset_in_progress;
 	u32			 biosVersion;	/* BIOS version from IO Unit Page 2 */
 	int			 eventTypes;	/* Event logging parameters */
 	int			 eventContext;	/* Next event context */
Index: linus-git/drivers/message/fusion/mptscsih.c
===================================================================
--- linus-git.orig/drivers/message/fusion/mptscsih.c
+++ linus-git/drivers/message/fusion/mptscsih.c
@@ -1561,7 +1561,8 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8
 	// SJR - CHECKME - Can we avoid this here?
 	// (mpt_HardResetHandler has this check...)
 	spin_lock_irqsave(&ioc->diagLock, flags);
-	if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
+	if ((ioc->ioc_reset_in_progress)
+	|| (ioc->alt_ioc && ioc->alt_ioc->ioc_reset_in_progress)) {
 		spin_unlock_irqrestore(&ioc->diagLock, flags);
 		return FAILED;
 	}



-- 
Bernd Schubert
Q-Leap Networks GmbH

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ PATCH 2/3 v4 ] introduce soft reset handler
  2009-02-06 13:08 [ PATCH 0/3 ] mpt fusion enhancements Bernd Schubert
  2009-02-06 13:18 ` [ PATCH 1/3 ] rename diagPending to ioc_reset_in_progress Bernd Schubert
@ 2009-02-06 13:20 ` Bernd Schubert
  2009-02-06 13:23 ` [ PATCH 3/3 ] tests in mpt_config() Bernd Schubert
  2012-06-21 21:20 ` [ PATCH 0/3 ] mpt fusion enhancements Ron Eisler
  3 siblings, 0 replies; 6+ messages in thread
From: Bernd Schubert @ 2009-02-06 13:20 UTC (permalink / raw)
  To: Prakash, Sathya
  Cc: linux-scsi, Desai, Kashyap, Moore, Eric, James.Bottomley,
	DL-MPT Fusion Linux, Andrew Morton

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.

Signed-off-by: Bernd Schubert <bs@q-leap.de>

 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/mptbase.c  |  209 +++++++++++++++++++++++++++++++++-----
 drivers/message/fusion/mptbase.h  |   10 +
 drivers/message/fusion/mptctl.c   |    8 -
 drivers/message/fusion/mptsas.c   |    4 
 drivers/message/fusion/mptscsih.c |   39 +++----
 5 files changed, 219 insertions(+), 51 deletions(-)

Index: linus-git/drivers/message/fusion/mptbase.c
===================================================================
--- linus-git.orig/drivers/message/fusion/mptbase.c
+++ linus-git/drivers/message/fusion/mptbase.c
@@ -5975,7 +5975,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.
@@ -6376,6 +6376,134 @@ EXPORT_SYMBOL(mpt_halt_firmware);
 /*
  *	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
@@ -6397,9 +6525,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);
@@ -6429,38 +6558,65 @@ 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);
-	}
-	ioc->reload_fw = 0;
-	if (ioc->alt_ioc)
-		ioc->alt_ioc->reload_fw = 0;
+	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++;
+ 	}
 
 	spin_lock_irqsave(&ioc->diagLock, flags);
 	ioc->ioc_reset_in_progress = 0;
-	if (ioc->alt_ioc)
+	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;
 }
@@ -7621,6 +7777,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);
Index: linus-git/drivers/message/fusion/mptbase.h
===================================================================
--- linus-git.orig/drivers/message/fusion/mptbase.h
+++ linus-git/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,10 @@ 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 */
+
 	struct scsi_cmnd	**ScsiLookup;
 	spinlock_t		  scsi_lookup_lock;
 
@@ -844,8 +851,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 +921,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);
Index: linus-git/drivers/message/fusion/mptscsih.c
===================================================================
--- linus-git.orig/drivers/message/fusion/mptscsih.c
+++ linus-git/drivers/message/fusion/mptscsih.c
@@ -1606,7 +1606,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;
@@ -1622,8 +1622,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);
@@ -1725,7 +1725,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;
@@ -2002,11 +2002,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;
@@ -2022,21 +2023,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;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2225,7 +2228,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;
 
@@ -2747,8 +2750,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! */
@@ -2986,9 +2989,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 */
Index: linus-git/drivers/message/fusion/mptctl.c
===================================================================
--- linus-git.orig/drivers/message/fusion/mptctl.c
+++ linus-git/drivers/message/fusion/mptctl.c
@@ -324,7 +324,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;
 
@@ -679,6 +679,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__);
@@ -2466,8 +2468,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;
 		}
 	}
Index: linus-git/drivers/message/fusion/mptsas.c
===================================================================
--- linus-git.orig/drivers/message/fusion/mptsas.c
+++ linus-git/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;
 	}


-- 
Bernd Schubert
Q-Leap Networks GmbH

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [ PATCH 3/3 ] tests in mpt_config().
  2009-02-06 13:08 [ PATCH 0/3 ] mpt fusion enhancements Bernd Schubert
  2009-02-06 13:18 ` [ PATCH 1/3 ] rename diagPending to ioc_reset_in_progress Bernd Schubert
  2009-02-06 13:20 ` [ PATCH 2/3 v4 ] introduce soft reset handler Bernd Schubert
@ 2009-02-06 13:23 ` Bernd Schubert
  2012-06-21 21:20 ` [ PATCH 0/3 ] mpt fusion enhancements Ron Eisler
  3 siblings, 0 replies; 6+ messages in thread
From: Bernd Schubert @ 2009-02-06 13:23 UTC (permalink / raw)
  To: Prakash, Sathya
  Cc: linux-scsi, Desai, Kashyap, Moore, Eric, James.Bottomley,
	DL-MPT Fusion Linux, Andrew Morton

Add basic checks to mpt_config(). This is a backport from the mpt fusion 4.17 driver.

Signed-off-by: Bernd Schubert <bs@q-leap.de>

---
 drivers/message/fusion/mptbase.c |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

Index: linus-git/drivers/message/fusion/mptbase.c
===================================================================
--- linus-git.orig/drivers/message/fusion/mptbase.c
+++ linus-git/drivers/message/fusion/mptbase.c
@@ -5868,6 +5868,26 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS
 		return -EPERM;
 	}
 
+	/* don't send a config page during diag reset */
+	spin_lock_irqsave(&ioc->diagLock, flags);
+	if (ioc->ioc_reset_in_progress) {
+		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
+			    "%s: busy with host reset\n", ioc->name, __func__));
+		spin_unlock_irqrestore(&ioc->diagLock, flags);
+		return -EBUSY;
+	}
+	spin_unlock_irqrestore(&ioc->diagLock, flags);
+
+	/* don't send if no chance of success */
+	if (!ioc->active
+	||  mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_OPERATIONAL) {
+		dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
+			    "%s: ioc not operational, %d, %xh\n",
+		ioc->name, __func__, ioc->active,
+		mpt_GetIocState(ioc, 0)));
+		return -EFAULT;
+	}
+
 	/* Get and Populate a free Frame
 	 */
 	if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {


-- 
Bernd Schubert
Q-Leap Networks GmbH

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [ PATCH 0/3 ] mpt fusion enhancements
  2009-02-06 13:08 [ PATCH 0/3 ] mpt fusion enhancements Bernd Schubert
                   ` (2 preceding siblings ...)
  2009-02-06 13:23 ` [ PATCH 3/3 ] tests in mpt_config() Bernd Schubert
@ 2012-06-21 21:20 ` Ron Eisler
  2012-06-22  9:30   ` Bernd Schubert
  3 siblings, 1 reply; 6+ messages in thread
From: Ron Eisler @ 2012-06-21 21:20 UTC (permalink / raw)
  To: linux-scsi

Bernd Schubert <bs <at> q-leap.de> writes:

> 
> Here are 3 patches for the mpt fusion driver.
> 

Hello Bernd,

I am looking mpt fusion backport fixes for the LSI 53C1030 that will run with
Linux kernel 2.6.27.62. Current version is 3.04.07. Our problem is that running
on VMWare VSphere, with the SAN heavily loaded, we get SCSI timeouts.

Ex. mptscsih: ioc0: attempting task abort! (sc-ffff...)
    sd 0:0:0:0: [sda] CDB: Read (10): 28 00 ...
    mptscsih: ioc0: task abort: Success (sc=ffff...)

The system hangs for 30 seconds on each one.

I see comments/patches here: http://comments.gmane.org/gmane.linux.scsi/48215

Do you have source that would work for 2.6.27.62?

Thank you
Ron Eisler




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [ PATCH 0/3 ] mpt fusion enhancements
  2012-06-21 21:20 ` [ PATCH 0/3 ] mpt fusion enhancements Ron Eisler
@ 2012-06-22  9:30   ` Bernd Schubert
  0 siblings, 0 replies; 6+ messages in thread
From: Bernd Schubert @ 2012-06-22  9:30 UTC (permalink / raw)
  To: Ron Eisler; +Cc: linux-scsi

Hello Ron,

On 06/21/2012 11:20 PM, Ron Eisler wrote:
> Bernd Schubert <bs <at> q-leap.de> writes:
>
>>
>> Here are 3 patches for the mpt fusion driver.
>>
>
> Hello Bernd,
>
> I am looking mpt fusion backport fixes for the LSI 53C1030 that will run with
> Linux kernel 2.6.27.62. Current version is 3.04.07. Our problem is that running
> on VMWare VSphere, with the SAN heavily loaded, we get SCSI timeouts.
>
> Ex. mptscsih: ioc0: attempting task abort! (sc-ffff...)
>      sd 0:0:0:0: [sda] CDB: Read (10): 28 00 ...
>      mptscsih: ioc0: task abort: Success (sc=ffff...)
>
> The system hangs for 30 seconds on each one.
>
> I see comments/patches here: http://comments.gmane.org/gmane.linux.scsi/48215
>
> Do you have source that would work for 2.6.27.62?
>

is there a chance you could use the the mpt-4.x driver? The other simple 
way would be to use the driver from the SLES10 kernel (SLES10 without 
any service pack, so 2.6.27).
I think you could simply replace the drivers/message/funsion directory.

I definitely cannot recommend to use a more recent kernel, as I know 
from Q-Leap that recent kernels run into DV (domain validation) races, 
which they 'solved' by introducing simple sleeps into the code.
I'm still in contact with Q-Leap, but decided to take another job some 
time ago....


Cheers,
Bernd

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2012-06-22  9:30 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-02-06 13:08 [ PATCH 0/3 ] mpt fusion enhancements Bernd Schubert
2009-02-06 13:18 ` [ PATCH 1/3 ] rename diagPending to ioc_reset_in_progress Bernd Schubert
2009-02-06 13:20 ` [ PATCH 2/3 v4 ] introduce soft reset handler Bernd Schubert
2009-02-06 13:23 ` [ PATCH 3/3 ] tests in mpt_config() Bernd Schubert
2012-06-21 21:20 ` [ PATCH 0/3 ] mpt fusion enhancements Ron Eisler
2012-06-22  9:30   ` Bernd Schubert

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.