Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 17 Dec 2007 01:10:07 GMT
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 131054 for review
Message-ID:  <200712170110.lBH1A7tg094301@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=131054

Change 131054 by peter@peter_overcee on 2007/12/17 01:09:34

	Disable the async FCLOSE command processing - wait for it to
	complete.  There is a race somewhere without this.  I don't even
	know if it is a race with the firmware or a race in the driver.
	It just doesn't quite work right after the last great tty reorg
	and is quite likely to hang if you close() and then open() it
	immediately.
	Tweak debugging printfs.  Handle async FCLOSE posting.

Affected files ...

.. //depot/projects/hammer/sys/dev/si/si.c#26 edit
.. //depot/projects/hammer/sys/dev/si/si.h#7 edit

Differences ...

==== //depot/projects/hammer/sys/dev/si/si.c#26 (text+ko) ====

@@ -195,6 +195,34 @@
 	"SXISA",
 };
 
+#ifdef SI_DEBUG
+static char *
+si_cmdname(int cmd)
+{
+	static char buf[32];
+
+	switch (cmd) {
+	case IDLE_OPEN:		return("IDLE_OPEN");
+	case LOPEN:		return("LOPEN");
+	case MOPEN:		return("MOPEN");
+	case MPEND:		return("MPEND");
+	case CONFIG:		return("CONFIG");
+	case CLOSE:		return("CLOSE");
+	case SBREAK:		return("SBREAK");
+	case EBREAK:		return("EBREAK");
+	case IDLE_CLOSE:	return("IDLE_CLOSE");
+	case IDLE_BREAK:	return("IDLE_BREAK");
+	case FCLOSE:		return("FCLOSE");
+	case RESUME:		return("RESUME");
+	case WFLUSH:		return("WFLUSH");
+	case RFLUSH:		return("RFLUSH");
+	default:
+		sprintf(buf, "?cmd:0x%x?", cmd);
+		return (buf);
+	}
+}
+#endif
+
 /*
  * We have to make an 8 bit version of bcopy, since some cards can't
  * deal with 32 bit I/O
@@ -615,7 +643,7 @@
 
 	mtx_assert(&Giant, MA_OWNED);
 	pp = tp->t_sc;
-	(void) si_command(pp, FCLOSE, SI_NOWAIT);
+	(void) si_command(pp, FCLOSE, SI_WAIT);
 }
 
 static void
@@ -1167,22 +1195,23 @@
 			 */
 			if (ccbp->hi_stat != pp->sp_pend) {
 				DPRINT((pp, DBG_INTR,
-					"si_intr hi_stat = 0x%x, pend = %d\n",
-					ccbp->hi_stat, pp->sp_pend));
+					"si_intr hi_stat = %s, pend = %s\n",
+					si_cmdname(ccbp->hi_stat),
+					si_cmdname(pp->sp_pend)));
 				switch(pp->sp_pend) {
 				case LOPEN:
 				case MPEND:
 				case MOPEN:
+				case FCLOSE:
 				case CONFIG:
 				case SBREAK:
 				case EBREAK:
-					pp->sp_pend = ccbp->hi_stat;
-						/* sleeping in si_command */
+					/* sleeping in si_command */
+					DPRINT((pp, DBG_INTR, "do wakeup\n"));
 					wakeup(&pp->sp_state);
 					break;
-				default:
-					pp->sp_pend = ccbp->hi_stat;
 				}
+				pp->sp_pend = ccbp->hi_stat;
 			}
 
 			/*
@@ -1264,7 +1293,6 @@
 			 */
 			if (n <= SI_BUFFERSIZE - op) {
 
-				DPRINT((pp, DBG_INTR, "\tsingle copy\n"));
 				z = ccbp->hi_rxbuf + op;
 				si_vbcopy(z, si_rxbuf, n);
 
@@ -1272,12 +1300,9 @@
 			} else {
 				x = SI_BUFFERSIZE - op;
 
-				DPRINT((pp, DBG_INTR, "\tdouble part 1 %d\n", x));
 				z = ccbp->hi_rxbuf + op;
 				si_vbcopy(z, si_rxbuf, x);
 
-				DPRINT((pp, DBG_INTR, "\tdouble part 2 %d\n",
-					n - x));
 				z = ccbp->hi_rxbuf;
 				si_vbcopy(z, si_rxbuf + x, n - x);
 
@@ -1533,8 +1558,9 @@
 	volatile struct si_channel *ccbp = pp->sp_ccb;
 	int x;
 
-	DPRINT((pp, DBG_ENTRY|DBG_PARAM, "si_command(%x,%x,%d): hi_stat 0x%x\n",
-		pp, cmd, waitflag, ccbp->hi_stat));
+	DPRINT((pp, DBG_ENTRY|DBG_PARAM, "si_command(%x,%s,%d): hi_stat %s, sp_pend: %s\n",
+		pp, si_cmdname(cmd), waitflag, si_cmdname(ccbp->hi_stat),
+		si_cmdname(pp->sp_pend)));
 
 	oldspl = spltty();		/* Keep others out */
 	mtx_assert(&Giant, MA_OWNED);
@@ -1548,6 +1574,8 @@
 			x != cmd) {
 		if (ttysleep(pp->sp_tty, (caddr_t)&pp->sp_state, TTIPRI|PCATCH,
 				"sicmd1", hz/4)) {
+			DPRINT((pp, DBG_PARAM, "sicmd1 timeout: hi_stat (%s)\n",
+				si_cmdname(ccbp->hi_stat)));
 			/* This is very very bad.  The card has crashed. */
 			/* XXX the driver breaks at this point */
 			splx(oldspl);
@@ -1561,9 +1589,11 @@
 	case LOPEN:
 	case MPEND:
 	case MOPEN:
+	case FCLOSE:
 	case CONFIG:
 	case SBREAK:
 	case EBREAK:
+		DPRINT((pp, DBG_PARAM, "si_command: sp_pend %s\n", si_cmdname(pp->sp_pend)));
 		wakeup(&pp->sp_state);
 		break;
 	default:
@@ -1574,8 +1604,9 @@
 	ccbp->hi_stat = cmd;		/* Post it */
 
 	if (waitflag) {
-		while(ccbp->hi_stat != IDLE_OPEN &&
-			     ccbp->hi_stat != IDLE_BREAK) {
+		while((x = ccbp->hi_stat) != IDLE_OPEN &&
+			     x != IDLE_CLOSE &&
+			     x != IDLE_BREAK) {
 			if (ttysleep(pp->sp_tty, (caddr_t)&pp->sp_state, TTIPRI|PCATCH,
 			    "sicmd2", 0))
 				break;

==== //depot/projects/hammer/sys/dev/si/si.h#7 (text+ko) ====

@@ -286,10 +286,8 @@
 	int		sp_state;
 	int		sp_delta_overflows;
 	struct callout_handle lstart_ch;/* For canceling our timeout */
-#ifdef	SI_DEBUG
 	int		sp_debug;	/* debug mask */
 	char		sp_name[5];
-#endif
 };
 
 /* sp_state */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200712170110.lBH1A7tg094301>