svn commit: r316407 - stable/10/sys/dev/isp

Alexander Motin mav at FreeBSD.org
Sun Apr 2 10:57:51 UTC 2017


Author: mav
Date: Sun Apr  2 10:57:49 2017
New Revision: 316407
URL: https://svnweb.freebsd.org/changeset/base/316407

Log:
  MFC r315681: Improve command timeout handling.
  
  Let firmware do its best first, and if it can't, try software recovery.
  I would remove software timeout handler completely, but found bunch of
  complains on command timeout on sparc64 mailing list few years ago, so
  better be safe in case of interrupt loss.

Modified:
  stable/10/sys/dev/isp/isp.c
  stable/10/sys/dev/isp/isp_freebsd.c
  stable/10/sys/dev/isp/isp_freebsd.h
  stable/10/sys/dev/isp/ispvar.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/isp/isp.c
==============================================================================
--- stable/10/sys/dev/isp/isp.c	Sun Apr  2 10:57:19 2017	(r316406)
+++ stable/10/sys/dev/isp/isp.c	Sun Apr  2 10:57:49 2017	(r316407)
@@ -4500,13 +4500,9 @@ isp_start(XS_T *xs)
 			cdbp = t2->req_cdb;
 		}
 	}
+	*tptr = XS_TIME(xs);
 	ISP_MEMCPY(cdbp, XS_CDBP(xs), cdblen);
 
-	*tptr = (XS_TIME(xs) + 999) / 1000;
-	if (IS_24XX(isp) && *tptr > 0x1999) {
-		*tptr = 0x1999;
-	}
-
 	/* Whew. Thankfully the same for type 7 requests */
 	reqp->req_handle = isp_allocate_handle(isp, xs, ISP_HANDLE_INITIATOR);
 	if (reqp->req_handle == 0) {

Modified: stable/10/sys/dev/isp/isp_freebsd.c
==============================================================================
--- stable/10/sys/dev/isp/isp_freebsd.c	Sun Apr  2 10:57:19 2017	(r316406)
+++ stable/10/sys/dev/isp/isp_freebsd.c	Sun Apr  2 10:57:49 2017	(r316407)
@@ -1241,7 +1241,7 @@ isp_target_start_ctio(ispsoftc_t *isp, u
 			cto->ct_iid_hi = atp->sid >> 16;
 			cto->ct_oxid = atp->oxid;
 			cto->ct_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(ccb));
-			cto->ct_timeout = (XS_TIME(ccb) + 999) / 1000;
+			cto->ct_timeout = XS_TIME(ccb);
 			cto->ct_flags = atp->tattr << CT7_TASK_ATTR_SHIFT;
 
 			/*
@@ -1390,7 +1390,7 @@ isp_target_start_ctio(ispsoftc_t *isp, u
 					cto->ct_lun = ccb->ccb_h.target_lun;
 				}
 			}
-			cto->ct_timeout = (XS_TIME(ccb) + 999) / 1000;
+			cto->ct_timeout = XS_TIME(ccb);
 			cto->ct_rxid = cso->tag_id;
 
 			/*
@@ -2958,9 +2958,10 @@ isp_abort_inot(ispsoftc_t *isp, union cc
 static void
 isp_action(struct cam_sim *sim, union ccb *ccb)
 {
-	int bus, tgt, ts, error;
+	int bus, tgt, error;
 	ispsoftc_t *isp;
 	struct ccb_trans_settings *cts;
+	sbintime_t ts;
 
 	CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n"));
 
@@ -3010,15 +3011,12 @@ isp_action(struct cam_sim *sim, union cc
 		switch (error) {
 		case CMD_QUEUED:
 			ccb->ccb_h.status |= CAM_SIM_QUEUED;
-			if (ccb->ccb_h.timeout == CAM_TIME_INFINITY) {
+			if (ccb->ccb_h.timeout == CAM_TIME_INFINITY)
 				break;
-			}
-			ts = ccb->ccb_h.timeout;
-			if (ts == CAM_TIME_DEFAULT) {
-				ts = 60*1000;
-			}
-			ts = isp_mstohz(ts);
-			callout_reset(&PISP_PCMD(ccb)->wdog, ts, isp_watchdog, ccb);
+			/* Give firmware extra 10s to handle timeout. */
+			ts = SBT_1MS * ccb->ccb_h.timeout + 10 * SBT_1S;
+			callout_reset_sbt(&PISP_PCMD(ccb)->wdog, ts, 0,
+			    isp_watchdog, ccb, 0);
 			break;
 		case CMD_RQLATER:
 			isp_prt(isp, ISP_LOGDEBUG0, "%d.%jx retry later",
@@ -4096,23 +4094,6 @@ isp_fc_scratch_acquire(ispsoftc_t *isp, 
 	return (ret);
 }
 
-int
-isp_mstohz(int ms)
-{
-	int hz;
-	struct timeval t;
-	t.tv_sec = ms / 1000;
-	t.tv_usec = (ms % 1000) * 1000;
-	hz = tvtohz(&t);
-	if (hz < 0) {
-		hz = 0x7fffffff;
-	}
-	if (hz == 0) {
-		hz = 1;
-	}
-	return (hz);
-}
-
 void
 isp_platform_intr(void *arg)
 {

Modified: stable/10/sys/dev/isp/isp_freebsd.h
==============================================================================
--- stable/10/sys/dev/isp/isp_freebsd.h	Sun Apr  2 10:57:19 2017	(r316406)
+++ stable/10/sys/dev/isp/isp_freebsd.h	Sun Apr  2 10:57:49 2017	(r316407)
@@ -520,7 +520,9 @@ default:							\
 
 #define	XS_CDBLEN(ccb)		(ccb)->cdb_len
 #define	XS_XFRLEN(ccb)		(ccb)->dxfer_len
-#define	XS_TIME(ccb)		(ccb)->ccb_h.timeout
+#define	XS_TIME(ccb)	\
+	(((ccb)->ccb_h.timeout > 0xffff * 1000 - 999) ? 0 : \
+	  (((ccb)->ccb_h.timeout + 999) / 1000))
 #define	XS_GET_RESID(ccb)	(ccb)->resid
 #define	XS_SET_RESID(ccb, r)	(ccb)->resid = r
 #define	XS_STSP(ccb)		(&(ccb)->scsi_status)
@@ -711,7 +713,6 @@ void isp_mbox_wait_complete(ispsoftc_t *
 void isp_mbox_notify_done(ispsoftc_t *);
 void isp_mbox_release(ispsoftc_t *);
 int isp_fc_scratch_acquire(ispsoftc_t *, int);
-int isp_mstohz(int);
 void isp_platform_intr(void *);
 void isp_platform_intr_resp(void *);
 void isp_platform_intr_atio(void *);

Modified: stable/10/sys/dev/isp/ispvar.h
==============================================================================
--- stable/10/sys/dev/isp/ispvar.h	Sun Apr  2 10:57:19 2017	(r316406)
+++ stable/10/sys/dev/isp/ispvar.h	Sun Apr  2 10:57:49 2017	(r316407)
@@ -1011,7 +1011,7 @@ void isp_prt_endcmd(ispsoftc_t *, XS_T *
  *	XS_CDBP(xs)		gets a pointer to the scsi CDB ""
  *	XS_CDBLEN(xs)		gets the CDB's length ""
  *	XS_XFRLEN(xs)		gets the associated data transfer length ""
- *	XS_TIME(xs)		gets the time (in milliseconds) for this command
+ *	XS_TIME(xs)		gets the time (in seconds) for this command
  *	XS_GET_RESID(xs)	gets the current residual count
  *	XS_GET_RESID(xs, resid)	sets the current residual count
  *	XS_STSP(xs)		gets a pointer to the SCSI status byte ""


More information about the svn-src-all mailing list