## diffname bitsy/devuart.c 2000/0904 ## diff -e /dev/null /n/emeliedump/2000/0904/sys/src/9/bitsy/devuart.c 0a #include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "io.h" #include "../port/error.h" #include "../port/netif.h" enum { Nuart = 1, Stagesize= 1024, }; /* hardware registers */ typedef struct Uartregs Uartregs; struct Uartregs { ulong ctl0; ulong ctl1; ulong ctl2; ulong ctl3; uchar dummyd[4]; ulong data; uchar dummyf[4]; ulong status0; ulong status1; }; #define UART3REGS IOA(Uartregs, 0x50000) /* ctl0 bits */ enum { XmitNotFull = (1 << 2), }; /* software representation */ typedef struct Uart Uart; struct Uart { QLock; int opens; int enabled; Uart *elist; /* next enabled interface */ char name[NAMELEN]; uchar sticky[8]; /* sticky write register values */ uchar osticky[8]; /* kernel saved sticky write register values */ ulong port; /* io ports */ ulong freq; /* clock frequency */ uchar mask; /* bits/char */ int dev; int baud; /* baud rate */ uchar istat; /* last istat read */ int frame; /* framing errors */ int overrun; /* rcvr overruns */ /* buffers */ int (*putc)(Queue*, int); Queue *iq; Queue *oq; Lock flock; /* fifo */ uchar fifoon; /* fifo's enabled */ uchar type; /* chip version */ Lock rlock; /* receive */ uchar istage[Stagesize]; uchar *ip; uchar *ie; int haveinput; Lock tlock; /* transmit */ uchar ostage[Stagesize]; uchar *op; uchar *oe; int modem; /* hardware flow control on */ int xonoff; /* software flow control on */ int blocked; int cts, dsr, dcd, dcdts; /* keep track of modem status */ int ctsbackoff; int hup_dsr, hup_dcd; /* send hangup upstream? */ int dohup; int kinuse; /* device in use by kernel */ Rendez r; }; static Uart* uart[Nuart]; static int nuart; static Dirtab *uartdir; static int uartndir; /* * means the kernel is using this for debugging output */ static char Ekinuse[] = "device in use by kernel"; /* * default is 9600 baud, 1 stop bit, 8 bit chars, no interrupts, * transmit and receive enabled, interrupts disabled. */ static void uartsetup0(Uart *p) { memset(p->sticky, 0, sizeof(p->sticky)); /* * set rate to 9600 baud. * 8 bits/character. * 1 stop bit. * interrupts enabled. */ // p->sticky[Format] = Bits8; // uartwrreg(p, Format, 0); // p->sticky[Mctl] |= Inton; // uartwrreg(p, Mctl, 0x0); // uartsetbaud(p, 9600); // p->iq = qopen(4*1024, 0, uartflow, p); // p->oq = qopen(4*1024, 0, uartkick, p); if(p->iq == nil || p->oq == nil) panic("uartsetup0"); p->ip = p->istage; p->ie = &p->istage[Stagesize]; p->op = p->ostage; p->oe = p->ostage; } /* * called by main() to create a new duart */ void uartsetup(ulong port, ulong freq, char *name, int type) { Uart *p; if(nuart >= Nuart) return; p = xalloc(sizeof(Uart)); uart[nuart] = p; strcpy(p->name, name); p->dev = nuart; nuart++; p->port = port; p->freq = freq; p->type = type; uartsetup0(p); } static void uartenable(Uart *p) { USED(p); } static void uartdisable(Uart *p) { USED(p); } static long uartstatus(Chan*, Uart *p, void *buf, long n, long offset) { USED(p); // "b%d c%d d%d e%d l%d m%d p%c r%d s%d i%d\n" // "dev(%d) type(%d) framing(%d) overruns(%d)%s%s%s%s\n", return readstr(offset, buf, n, ""); } static void setlength(int i) { Uart *p; if(i > 0){ p = uart[i]; if(p && p->opens && p->iq) uartdir[3*i].length = qlen(p->iq); } else for(i = 0; i < nuart; i++){ p = uart[i]; if(p && p->opens && p->iq) uartdir[3*i].length = qlen(p->iq); } } static void uartreset(void) { int i; Dirtab *dp; nuart = Nuart; uartndir = 3*nuart; uartdir = xalloc(uartndir * sizeof(Dirtab)); dp = uartdir; for(i = 0; i < nuart; i++){ /* 3 directory entries per port */ sprint(dp->name, "eia%d", i); dp->qid.path = NETQID(i, Ndataqid); dp->perm = 0660; dp++; sprint(dp->name, "eia%dctl", i); dp->qid.path = NETQID(i, Nctlqid); dp->perm = 0660; dp++; sprint(dp->name, "eia%dstat", i); dp->qid.path = NETQID(i, Nstatqid); dp->perm = 0444; dp++; } } static Chan* uartattach(char *spec) { return devattach('t', spec); } static int uartwalk(Chan *c, char *name) { return devwalk(c, name, uartdir, uartndir, devgen); } static void uartstat(Chan *c, char *dp) { if(NETTYPE(c->qid.path) == Ndataqid) setlength(NETID(c->qid.path)); devstat(c, dp, uartdir, uartndir, devgen); } static Chan* uartopen(Chan *c, int omode) { Uart *p; c = devopen(c, omode, uartdir, uartndir, devgen); switch(NETTYPE(c->qid.path)){ case Nctlqid: case Ndataqid: p = uart[NETID(c->qid.path)]; if(p->kinuse) error(Ekinuse); qlock(p); if(p->opens++ == 0){ uartenable(p); qreopen(p->iq); qreopen(p->oq); } qunlock(p); break; } return c; } static void uartclose(Chan *c) { Uart *p; if(c->qid.path & CHDIR) return; if((c->flag & COPEN) == 0) return; switch(NETTYPE(c->qid.path)){ case Ndataqid: case Nctlqid: p = uart[NETID(c->qid.path)]; if(p->kinuse) error(Ekinuse); qlock(p); if(--(p->opens) == 0){ uartdisable(p); qclose(p->iq); qclose(p->oq); p->ip = p->istage; p->dcd = p->dsr = p->dohup = 0; } qunlock(p); break; } } static long uartread(Chan *c, void *buf, long n, vlong off) { Uart *p; ulong offset = off; if(c->qid.path & CHDIR){ setlength(-1); return devdirread(c, buf, n, uartdir, uartndir, devgen); } p = uart[NETID(c->qid.path)]; if(p->kinuse) error(Ekinuse); switch(NETTYPE(c->qid.path)){ case Ndataqid: return qread(p->iq, buf, n); case Nctlqid: return readnum(offset, buf, n, NETID(c->qid.path), NUMSIZE); case Nstatqid: return uartstatus(c, p, buf, n, offset); } return 0; } static void uartctl(Uart *p, char *cmd) { int i, n; char *f[32]; int nf; /* let output drain for a while */ for(i = 0; i < 16 && qlen(p->oq); i++) tsleep(&p->r, (int(*)(void*))qlen, p->oq, 125); nf = getfields(cmd, f, nelem(f), 1, " \t\n"); for(i = 0; i < nf; i++){ if(strncmp(f[i], "break", 5) == 0){ // uartbreak(p, 0); continue; } n = atoi(f[i]+1); switch(*f[i]){ case 'B': case 'b': // uartsetbaud(p, n); break; case 'C': case 'c': // uartdcdhup(p, n); break; case 'D': case 'd': // uartdtr(p, n); break; case 'E': case 'e': // uartdsrhup(p, n); break; case 'f': case 'F': qflush(p->oq); break; case 'H': case 'h': qhangup(p->iq, 0); qhangup(p->oq, 0); break; case 'i': case 'I': // lock(&p->flock); // uartfifo(p, n); // unlock(&p->flock); break; case 'L': case 'l': // uartbits(p, n); break; case 'm': case 'M': // uartmflow(p, n); break; case 'n': case 'N': qnoblock(p->oq, n); break; case 'P': case 'p': // uartparity(p, *(cmd+1)); break; case 'K': case 'k': // uartbreak(p, n); break; case 'R': case 'r': // uartrts(p, n); break; case 'Q': case 'q': qsetlimit(p->iq, n); qsetlimit(p->oq, n); break; case 'T': case 't': // uartdcdts(p, n); break; case 'W': case 'w': /* obsolete */ break; case 'X': case 'x': ilock(&p->tlock); p->xonoff = n; iunlock(&p->tlock); break; } } } static long uartwrite(Chan *c, void *buf, long n, vlong) { Uart *p; char cmd[32]; if(c->qid.path & CHDIR) error(Eperm); p = uart[NETID(c->qid.path)]; if(p->kinuse) error(Ekinuse); switch(NETTYPE(c->qid.path)){ case Ndataqid: return qwrite(p->oq, buf, n); case Nctlqid: if(n >= sizeof(cmd)) n = sizeof(cmd)-1; memmove(cmd, buf, n); cmd[n] = 0; uartctl(p, cmd); return n; } } static void uartwstat(Chan *c, char *dp) { Dir d; Dirtab *dt; if(!iseve()) error(Eperm); if(CHDIR & c->qid.path) error(Eperm); if(NETTYPE(c->qid.path) == Nstatqid) error(Eperm); dt = &uartdir[3 * NETID(c->qid.path)]; convM2D(dp, &d); d.mode &= 0666; dt[0].perm = dt[1].perm = d.mode; } Dev uartdevtab = { 't', "uart", uartreset, devinit, uartattach, devclone, uartwalk, uartstat, uartopen, devcreate, uartclose, uartread, devbread, uartwrite, devbwrite, devremove, uartwstat, }; void putuartstr(char *str) { Uartregs *ur; ur = UART3REGS; while(*str){ /* wait for output ready */ while(ur->status1 & XmitNotFull) ; ur->data = *str++; } } . ## diffname bitsy/devuart.c 2000/0905 ## diff -e /n/emeliedump/2000/0904/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/0905/sys/src/9/bitsy/devuart.c 504d 501c while((ur->status1 & XmitNotFull) == 0) . 499c while(n-- > 0){ . 494c serialputs(char *str, int n) . 35a /* status register 1 bits */ XmitBusy = (1 << 0), . 27c ulong dummyb; . 25c ulong dummya; . ## diffname bitsy/devuart.c 2000/0906 ## diff -e /n/emeliedump/2000/0905/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/0906/sys/src/9/bitsy/devuart.c 500c ur = uart3regs; . 32a static Uartregs *uart3regs = UART3REGS; . 31d ## diffname bitsy/devuart.c 2000/0907 ## diff -e /n/emeliedump/2000/0906/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/0907/sys/src/9/bitsy/devuart.c 32c Uartregs *uart3regs = UART3REGS; . 18d ## diffname bitsy/devuart.c 2000/0928 ## diff -e /n/emeliedump/2000/0907/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/0928/sys/src/9/bitsy/devuart.c 506a while((ur->status1 & XmitBusy)) ; . ## diffname bitsy/devuart.c 2000/0930 ## diff -e /n/emeliedump/2000/0928/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/0930/sys/src/9/bitsy/devuart.c 507c while((ur->status1 & Tbusy)) . 503c while((ur->status1 & Tnotfull) == 0) . 494a static void uartsetbaud(Uart *p, int rate) { ulong brconst; if(rate <= 0) return; brconst = (p->freq+8*rate-1)/(16*rate) - 1; p->regs->ctl[1] = (brconst>>8) & 0xf; p->regs->ctl[2] = brconst; p->baud = rate; } . 205c uartsetup(uart3regs, ; . 198a /* * setup the '#t' directory */ . 171c p->sticky[3] &= ~(Rintena|Tintena); p->regs->ctl[3] = p->sticky[3]; . 167a /* * disable interrupts. clear DTR, and RTS */ . 165c p->sticky[3] |= Rintena|Tintena; p->regs->ctl[3] = p->sticky[3]; . 143,161d 141c * enable a port's interrupts. set DTR and RTS . 132c panic("uartsetup"); . 127,130c p->iq = qopen(4*1024, 0, uartflow, p); p->oq = qopen(4*1024, 0, uartkick, p); . 122,125c p->sticky[0] = Bits8; p->regs->ctl[0] = p->sticky[0]; p->sticky[3] = Rena|Tena; p->regs->ctl[3] = p->sticky[3]; uartsetbaud(p, 115200); . 120c * interrupts disabled. . 117c * set rate to 115200 baud. . 115a . 114a Uart *p; if(nuart >= Nuart) return; p = xalloc(sizeof(Uart)); uart[nuart] = p; strcpy(p->name, name); p->dev = nuart++; p->port = port; p->freq = freq; p->regs = regs; . 113c uartsetup(Uartregs *regs, ulong freq, char *name) . 109,110c * define a Uart. . 107a static void uartsetbaud(Uart *p, int rate); . 104c * means the kernel is using this as a console . 69,72d 60c int parity; /* parity errors */ . 57d 52,54c uchar sticky[4]; /* sticky write register values */ . 46a Uartregs *regs; . 45a int dev; . 40a Uartregs *uart3regs = UART3REGS; . 36,38c /* ctl[0] bits */ Parity= 1<<0, Even= 1<<1, Stop1= 0<<2, Stop2= 1<<2, Bits7= 0<<3, Bits8= 1<<3, SCE= 1<<4, /* synchronous clock enable */ RCE= 1<<5, /* rx on falling edge of clock */ TCE= 1<<6, /* tx on falling edge of clock */ /* ctl[3] bits */ Rena= 1<<0, /* receiver enable */ Tena= 1<<1, /* transmitter enable */ Break= 1<<2, /* force TXD3 low */ Rintena= 1<<3, /* enable receive interrupt */ Tintena= 1<<4, /* enable transmitter interrupt */ Loopback= 1<<5, /* loop back data */ /* data bits */ DEparity= 1<<8, /* parity error */ DEframe= 1<<9, /* framing error */ DEoverrun= 1<<10, /* overrun error */ /* status0 bits */ Tint= 1<<0, /* transmit fifo half full interrupt */ Rint0= 1<<1, /* receiver fifo 1/3-2/3 full */ Rint1= 1<<2, /* receiver fifo not empty and receiver idle */ Breakstart= 1<<3, Breakend= 1<<4, Fifoerror= 1<<5, /* fifo error */ /* status1 bits */ Tbusy= 1<<0, /* transmitting */ Rnotempty= 1<<1, /* receive fifo not empty */ Tnotfull= 1<<2, /* transmit fifo not full */ ParityError= 1<<3, FrameError= 1<<4, Overrun= 1<<5, . 31,33d 20,23c ulong ctl[4]; . ## diffname bitsy/devuart.c 2000/1002 ## diff -e /n/emeliedump/2000/0930/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/1002/sys/src/9/bitsy/devuart.c 537a } /* * turn on/off rts */ static void uartrts(Uart *p, int on) { } /* * restart input if it's off */ static void uartflow(void *v) { Uart *p; p = v; if(p->modem){ uartrts(p, 1); ilock(&p->rlock); p->haveinput = 1; iunlock(&p->rlock); } } /* * restart output if not blocked and OK to send */ static void uartkick0(void *v) { int i; Uart *p; p = v; if(p->cts == 0 || p->blocked) return; /* * 128 here is an arbitrary limit to make sure * we don't stay in this loop too long. If the * chips output queue is longer than 128, too * bad -- presotto */ for(i = 0; i < 128; i++){ // if(!(uartrdreg(p, Lstat) & Outready)) // break; // if(p->op >= p->oe && stageoutput(p) == 0) // break; // outb(p->port + Data, *(p->op++)); } } static void uartkick(void *v) { Uart *p; p = v; ilock(&p->tlock); uartkick0(p); iunlock(&p->tlock); . 524a /* * set the buad rate */ . 235,236d 152d 135a static void uartflow(void *v); static void uartkick0(void *v); static void uartkick(void *v); static void uartrts(Uart *p, int on); . ## diffname bitsy/devuart.c 2000/1006 ## diff -e /n/emeliedump/2000/1002/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/1006/sys/src/9/bitsy/devuart.c 605a } static void uartintr(Ureg*, void *x) { Uart *p; p = x; . 548c uartrts(Uart*, int) . 256d 191a intrenable(IRQuart3, uartintr, p, p->name); . 184a * setup all uarts (called early by main() to allow debugging output to * a serial port) */ void uartsetup(void) { uart3regs = mapspecial(UART3REGS, 64); uartsetup0(uart3regs, 36864000, "serialport3"); } /* . 145c uartsetup0(Uartregs *regs, ulong freq, char *name) . 139a static void uartintr(Ureg*, void*); . ## diffname bitsy/devuart.c 2000/1007 ## diff -e /n/emeliedump/2000/1006/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/1007/sys/src/9/bitsy/devuart.c 590,641c n = qconsume(p->oq, p->ostage, Stagesize); if(n <= 0) return 0; p->op = p->ostage; p->oe = p->ostage + n; return n; . 587,588c int n; . 584,585c int uartstageoutput(Uart *p) . 582c * put some bytes into the local queue to avoid calling * qconsume for every character . 570,578c p->dcdts = n; . 568c uartdcdts(Uart *p, int n) . 565c * save dcd timestamps for gps clock . 561a p->hup_dcd = n; . 560c uartdcdhup(Uart *p, int n) . 556,558d 544,553c p->hup_dsr = n; . 542c uartdsrhup(Uart *p, int n) . 539c * decide if we should hangup when dsr or dcd drops. . 456c uartdcdts(p, n); . 447c (*p->phys->rts)(p, n); . 443c (*p->phys->dobreak)(p, n); . 439c (*p->phys->parity)(p, *(cmd+1)); . 431c (*p->phys->modemctl)(p, n); . 427c (*p->phys->bits)(p, n); . 421,423d 408c uartdsrhup(p, n); . 404c (*p->phys->dtr)(p, n); . 400c uartdcdhup(p, n); . 396c (*p->phys->baud)(p, n); . 388c (*p->phys->dobreak)(p, 0); . 366c return (*p->phys->status)(p, buf, n, offset); . 335c (*p->phys->disable)(p); . 307c (*p->phys->enable)(p, 1); . 200,226d 185,198d 182a return p; . 174,175c p->iq = qopen(4*1024, 0, p->phys->flow, p); p->oq = qopen(4*1024, 0, p->phys->kick, p); . 168,172c (*p->phys->bits)(p, 8); (*p->phys->stop)(p, 1); (*p->phys->baud)(p, 115200); (*p->phys->enable)(p, 0); . 166c * enabled with interrupts disabled. . 160,161d 158a p->phys = phys; . 151c return nil; . 145,146c Uart* uartsetup(PhysUart *phys, void *regs, ulong freq, char *name) . 143c * define a Uart . 135,140c static void uartdcdhup(Uart*, int); static void uartdcdts(Uart*, int); static void uartdsrhup(Uart*, int); . 17,123d 11,15d ## diffname bitsy/devuart.c 2000/1015 ## diff -e /n/emeliedump/2000/1007/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/1015/sys/src/9/bitsy/devuart.c 416a } /* * restart output */ void uartkick(void *v) { Uart *p = v; ilock(&p->tlock); (*p->phys->kick)(p); iunlock(&p->tlock); } /* * streceiveage a character at interrupt time */ void uartrecv(Uart *p, char ch) { /* software flow control */ if(p->xonoff){ if(ch == CTLS){ p->blocked = 1; }else if (ch == CTLQ){ p->blocked = 0; p->ctsbackoff = 2; /* clock gets output going again */ } } /* receive the character */ if(p->putc) p->putc(p->iq, ch); else { ilock(&p->rlock); if(p->ip < p->ie) *p->ip++ = ch; p->haveinput = 1; iunlock(&p->rlock); } } /* * we save up input characters till clock time to reduce * per character interrupt overhead. * * There's also a bit of code to get a stalled print going. * It shouldn't happen, but it does. Obviously I don't * understand something. Since it was there, I bundled a * restart after flow control with it to give some hysteresis * to the hardware flow control. This makes compressing * modems happier but will probably bother something else. * -- presotto */ static void uartclock(void) { int n; Uart *p; for(p = uartalloc.elist; p; p = p->elist){ /* this amortizes cost of qproduce to many chars */ if(p->haveinput){ ilock(&p->rlock); if(p->haveinput){ n = p->ip - p->istage; if(n > 0 && p->iq){ if(n > Stagesize) panic("uartclock"); if(qproduce(p->iq, p->istage, n) < 0) (*p->phys->rts)(p, 0); else p->ip = p->istage; } p->haveinput = 0; } iunlock(&p->rlock); } if(p->dohup){ ilock(&p->rlock); if(p->dohup){ qhangup(p->iq, 0); qhangup(p->oq, 0); } p->dohup = 0; iunlock(&p->rlock); } /* this adds hysteresis to hardware/software flow control */ if(p->ctsbackoff){ ilock(&p->tlock); if(p->ctsbackoff){ if(--(p->ctsbackoff) == 0) (*p->phys->kick)(p); } iunlock(&p->tlock); } } } /* * configure a uart port as a console or a mouse */ void uartspecial(Uart *p, int baud, Queue **in, Queue **out, int (*putc)(Queue*, int)) { uartenable(p); if(baud) (*p->phys->baud)(p, baud); p->putc = putc; if(in) *in = p->iq; if(out) *out = p->oq; p->opens++; . 402a * restart input if it's off */ static void uartflow(void *v) { Uart *p; p = v; if(p->modem){ (*p->phys->rts)(p, 1); ilock(&p->rlock); p->haveinput = 1; iunlock(&p->rlock); } } /* . 178c uartdisable(p); . 150c uartenable(p); . 111a addclock0link(uartclock); . 69a uartenable(Uart *p) { Uart **l; p->hup_dsr = p->hup_dcd = 0; p->dsr = p->dcd = 0; /* assume we can send */ p->cts = 1; (*p->phys->enable)(p, 1); lock(&uartalloc); for(l = &uartalloc.elist; *l; l = &(*l)->elist){ if(*l == p) break; } if(*l == 0){ p->elist = uartalloc.elist; uartalloc.elist = p; } p->enabled = 1; unlock(&uartalloc); } static void uartdisable(Uart *p) { Uart **l; (*p->phys->disable)(p); lock(&uartalloc); for(l = &uartalloc.elist; *l; l = &(*l)->elist){ if(*l == p){ *l = p->elist; break; } } p->enabled = 0; unlock(&uartalloc); } static void . 68a /* * enable/diable uart and add/remove to list of enabled uarts */ . 57,58c p->iq = qopen(4*1024, 0, uartflow, p); p->oq = qopen(4*1024, 0, uartkick, p); . 25a static void uartenable(Uart*); static void uartdisable(Uart*); static void uartclock(void); static void uartflow(void*); . 22a struct Uartalloc { Lock; Uart *elist; /* list of enabled interfaces */ } uartalloc; . ## diffname bitsy/devuart.c 2000/1019 ## diff -e /n/emeliedump/2000/1015/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/1019/sys/src/9/bitsy/devuart.c 578d 572,576c qhangup(p->iq, 0); qhangup(p->oq, 0); . 570a /* hang up if requested */ . 569d 567c } else { if(qproduce(p->iq, p->ir, iw-p->ir) < 0) (*p->phys->rts)(p, 0); p->ir = iw; . 564,565c p->ir = iw; . 555,562c if(p->iw != p->ir){ iw = p->iw; if(iw < p->ir){ if(qproduce(p->iq, p->ir, p->ie-p->ir) < 0){ (*p->phys->rts)(p, 0); p->ir = p->istage; } else { if(qproduce(p->iq, p->istage, iw-p->istage) < 0) . 550a uchar *iw; . 549d 537,544d 526,530c next = p->iw + 1; if(next == p->ie) next = p->istage; if(next != p->ir){ *p->iw = ch; p->iw = next; } . 511a uchar *next; . 470,473d 468c if(p->modem) . 238c p->ir = p->iw = p->istage; . 71c p->ir = p->istage; p->iw = p->istage; . 47a memset(p, 0, sizeof(*p)); . ## diffname bitsy/devuart.c 2000/1020 ## diff -e /n/emeliedump/2000/1019/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/1020/sys/src/9/bitsy/devuart.c 564a if(qproduce(p->iq, p->ir, iw-p->ir) < 0) (*p->phys->rts)(p, 0); p->ir = iw; . 554,563c p->ir = p->istage; . 552c if(qproduce(p->iq, p->ir, p->ie-p->ir) < 0) . ## diffname bitsy/devuart.c 2000/1121 ## diff -e /n/emeliedump/2000/1020/sys/src/9/bitsy/devuart.c /n/emeliedump/2000/1121/sys/src/9/bitsy/devuart.c 10a enum { Nuart = 4, /* soft flow control chars */ CTLS= 023, CTLQ= 021, }; . ## diffname bitsy/devuart.c 2001/0529 # deleted ## diff -e /n/emeliedump/2000/1121/sys/src/9/bitsy/devuart.c /n/emeliedump/2001/0529/sys/src/9/bitsy/devuart.c 1,603d