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>