From 4b784ab08ca76e708266478ceeb90957cd5de71b Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 8 Jun 1996 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1996-06-08 --- pc/ether79c970.c | 10 +-- pc/ether82557.c | 2 - pc/etherelnk3.c | 2 - pc/u.h | 3 +- port/devns16552.c | 185 +++++++++++++++++++++------------------------- 5 files changed, 92 insertions(+), 110 deletions(-) diff --git a/pc/ether79c970.c b/pc/ether79c970.c index c89bd00e9973221608878ad78a2bedb835f2a60e..b50b9f51ff196b5afe6cd8aaa7618323ff51e9b4 100644 --- a/pc/ether79c970.c +++ b/pc/ether79c970.c @@ -185,8 +185,8 @@ promiscuous(void* arg, int on) ctlr = ether->ctlr; /* - * Put the chip into promiscuous mode. First we must wait until - * anyone transmitting is done, then we can stop the chip and put + * Put the chip into promiscuous mode. First must wait until + * anyone transmitting is done, then stop the chip and put * it in promiscuous mode. Restarting is made harder by the chip * reloading the transmit and receive descriptor pointers with their * base addresses when Strt is set (unlike the older Lance chip), @@ -284,7 +284,7 @@ interrupt(Ureg*, void* arg) /* * Receiver interrupt: run round the descriptor ring logging * errors and passing valid receive data up to the higher levels - * until we encounter a descriptor still owned by the chip. + * until a descriptor is encountered still owned by the chip. */ if(csr0 & Rint){ rdre = &ctlr->rdr[ctlr->rdrx]; @@ -371,8 +371,8 @@ reset(Ether* ether) /* * Any adapter matches if no ether->port is supplied, otherwise the - * ports must match. First see if we've already found an adapter that fits - * the bill. If not then scan for another. + * ports must match. First see if an adapter that fits the bill has + * already been found. If not then scan for another. */ port = 0; for(app = &adapter, ap = *app; ap; app = &ap->next, ap = ap->next){ diff --git a/pc/ether82557.c b/pc/ether82557.c index 170efb7161d421f0927e441437e3bcc2493f18e1..90eddf20693242c95413ed134494b1b6e0cc09c8 100644 --- a/pc/ether82557.c +++ b/pc/ether82557.c @@ -434,7 +434,6 @@ interrupt(Ureg*, void* arg) etherrloop(ether, rfd, rfd->count & 0x3FFF); ether->inpackets++; } -else print("%s#%d: rfd->field %uX\n", ctlr->type, ctlr->ctlrno, rfd->field); /* * Reinitialise the frame for reception and bump @@ -463,7 +462,6 @@ else print("%s#%d: rfd->field %uX\n", ctlr->type, ctlr->ctlrno, rfd->field); while(csr8r(ctlr, Command)) ; csr8w(ctlr, Command, RUresume); -print("%s#%d: status %uX\n", ctlr->type, ctlr->ctlrno, status); status &= ~StatRNR; } diff --git a/pc/etherelnk3.c b/pc/etherelnk3.c index 7f3047604a69dccea91b7a2c444848ba7b3632b1..9ed4da6bc458acb2070dbe4330339e33b036f327 100644 --- a/pc/etherelnk3.c +++ b/pc/etherelnk3.c @@ -564,7 +564,6 @@ receive(Ether* ether) */ if(rxstatus & rxError){ if(ctlr->rxstatus9){ -iprint("R%uX|", rxstatus); switch(rxstatus & rxError9){ case rxOverrun9: @@ -588,7 +587,6 @@ iprint("R%uX|", rxstatus); } else{ rxerror = inb(port+RxError); -iprint("R%uX|", rxerror); if(rxerror & rxOverrun) ether->overflows++; if(rxerror & (oversizedFrame|runtFrame)) diff --git a/pc/u.h b/pc/u.h index 23cad5731ddea777dcb1b99cd7cb94dbecf7b36b..cc6fc082ffe947a284614e360d1430fdeb2019eb 100644 --- a/pc/u.h +++ b/pc/u.h @@ -1,8 +1,9 @@ #define nil ((void*)0) typedef unsigned short ushort; typedef unsigned char uchar; -typedef signed char schar; +typedef unsigned int uint; typedef unsigned long ulong; +typedef signed char schar; typedef long vlong; typedef union Length Length; typedef ushort Rune; diff --git a/port/devns16552.c b/port/devns16552.c index 1e97b3b25ce4ffa109f45d40601d4bd1f4d0ed60..8d0a23f97d1546526c1087fefada74c8122badb3 100644 --- a/port/devns16552.c +++ b/port/devns16552.c @@ -72,54 +72,56 @@ typedef struct Uart Uart; struct Uart { QLock; + int opens; - Uart *elist; /* next enabled interface */ + int enabled; + Uart *elist; /* next enabled interface */ char name[NAMELEN]; - uchar sticky[8]; /* sticky write register values */ + uchar sticky[8]; /* sticky write register values */ ulong port; - Lock plock; /* for printing variable */ - ulong freq; /* clock frequency */ - int opens; - uchar mask; /* bits/char */ - uchar istat; /* last istat read */ - uchar fifoon; /* fifo's enabled */ - uchar nofifo; /* earlier chip version with nofifo */ - int enabled; + ulong freq; /* clock frequency */ + uchar mask; /* bits/char */ int dev; + int baud; /* baud rate */ - int frame; /* framing errors */ - int overrun; /* rcvr overruns */ - int baud; /* baud rate */ - - /* flow control */ - int xonoff; /* software flow control on */ - int blocked; - int modem; /* hardware flow control on */ - int cts; /* ... cts state */ - int ctsbackoff; - int rts; /* ... rts state */ - Rendez r; + uchar istat; /* last istat read */ + int frame; /* framing errors */ + int overrun; /* rcvr overruns */ /* buffers */ int (*putc)(Queue*, int); Queue *iq; Queue *oq; - /* staging areas to avoid some of the per character costs */ + Lock flock; /* fifo */ + uchar fifoon; /* fifo's enabled */ + uchar nofifo; /* earlier chip version with nofifo */ + + 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; + int ctsbackoff; + + Rendez r; }; static Uart *uart[Nuart]; static int nuart; -static int haveinput; struct Uartalloc { Lock; Uart *elist; /* list of enabled interfaces */ @@ -209,27 +211,18 @@ ns16552dtr(Uart *p, int n) void ns16552rts(Uart *p, int n) { - int x; - - x = splhi(); - lock(&p->plock); - if(n) p->sticky[Mctl] |= Rts; else p->sticky[Mctl] &= ~Rts; uartwrreg(p, Mctl, 0); - p->rts = n; - - unlock(&p->plock); - splx(x); } /* * send break */ -void +static void ns16552break(Uart *p, int ms) { if(ms == 0) @@ -240,7 +233,7 @@ ns16552break(Uart *p, int ms) uartwrreg(p, Format, 0); } -void +static void ns16552fifoon(Uart *p) { ulong i, x; @@ -276,33 +269,40 @@ ns16552fifoon(Uart *p) /* * modem flow control on/off (rts/cts) */ -void +static void ns16552mflow(Uart *p, int n) { + ilock(&p->tlock); if(n){ p->sticky[Iena] |= Imstat; uartwrreg(p, Iena, 0); p->modem = 1; p->cts = uartrdreg(p, Mstat) & Cts; - - /* turn on fifo's */ - ns16552fifoon(p); } else { p->sticky[Iena] &= ~Imstat; uartwrreg(p, Iena, 0); p->modem = 0; p->cts = 1; + iunlock(&p->tlock); + } + iunlock(&p->tlock); + ilock(&p->flock); + if(n) + /* turn on fifo's */ + ns16552fifoon(p); + else { /* turn off fifo's */ p->fifoon = 0; uartwrreg(p, Fifoctl, 0); } + iunlock(&p->flock); } /* * turn on a port's interrupts. set DTR and RTS */ -void +static void ns16552enable(Uart *p) { Uart **l; @@ -327,8 +327,10 @@ ns16552enable(Uart *p) /* * assume we can send */ + ilock(&p->tlock); p->cts = 1; p->blocked = 0; + iunlock(&p->tlock); /* * set baud rate to the last used @@ -351,7 +353,7 @@ ns16552enable(Uart *p) /* * turn off a port's interrupts. reset DTR and RTS */ -void +static void ns16552disable(Uart *p) { Uart **l; @@ -374,7 +376,10 @@ ns16552disable(Uart *p) ns16552dtr(p, 0); ns16552rts(p, 0); ns16552mflow(p, 0); - p->xonoff = p->blocked = 0; + ilock(&p->tlock); + p->blocked = 0; + iunlock(&p->tlock); + p->xonoff = 0; uartpower(p->dev, 0); @@ -410,30 +415,23 @@ stageoutput(Uart *p) * (re)start output */ static void -ns16552kick(Uart *p) +ns16552kick0(Uart *p) { - int x, n; - - x = splhi(); - lock(&p->plock); - if((uartrdreg(p, Lstat) & Outready)) - if(p->cts && p->blocked == 0) - if(p->op < p->oe || stageoutput(p)){ - n = 0; - while((uartrdreg(p, Lstat) & Outready) == 0){ - if(++n > 100000){ - print("stuck serial line\n"); - break; - } - } - do{ - outb(p->port + Data, *(p->op++)); - if(p->op >= p->oe && stageoutput(p) == 0) - break; - }while(uartrdreg(p, Lstat) & Outready); + if(p->cts == 0 || p->blocked) + return; + while(uartrdreg(p, Lstat) & Outready){ + if(p->op >= p->oe && stageoutput(p) == 0) + break; + outb(p->port + Data, *(p->op++)); } - unlock(&p->plock); - splx(x); +} + +static void +ns16552kick(Uart *p) +{ + ilock(&p->tlock); + ns16552kick0(p); + iunlock(&p->tlock); } /* @@ -444,7 +442,9 @@ ns16552flow(Uart *p) { if(p->modem){ ns16552rts(p, 1); - haveinput = 1; + ilock(&p->rlock); + p->haveinput = 1; + iunlock(&p->rlock); } } @@ -518,22 +518,6 @@ ns16552special(int port, int baud, Queue **in, Queue **out, int (*putc)(Queue*, p->opens++; } -/* - * reset the interface - */ -void -ns16552shake(Uart *p) -{ - int xonoff, modem; - - xonoff = p->xonoff; - modem = p->modem; - ns16552disable(p); - ns16552enable(p); - p->xonoff = xonoff; - ns16552mflow(p, modem); -} - /* * handle an interrupt to a single uart */ @@ -564,6 +548,7 @@ ns16552intr(int dev) case 4: /* received data available */ case 12: ch = uartrdreg(p, Data) & 0xff; + lock(&p->tlock); if(p->xonoff){ if(ch == CTLS){ p->blocked = 1; @@ -572,37 +557,31 @@ ns16552intr(int dev) /* clock gets output going again */ } } + unlock(&p->tlock); if(p->putc) (*p->putc)(p->iq, ch); else { + lock(&p->rlock); if(p->ip < p->ie) *p->ip++ = ch; - haveinput = 1; + p->haveinput = 1; + unlock(&p->rlock); } break; case 2: /* transmitter not full */ - lock(&p->plock); - l = uartrdreg(p, Lstat) & Outready; - if(l && p->cts && p->blocked == 0) - if(p->op < p->oe || stageoutput(p)){ - do{ - outb(p->port + Data, *(p->op++)); - if(p->op >= p->oe && stageoutput(p) == 0) - break; - l = uartrdreg(p, Lstat) & Outready; - }while(l); - } - unlock(&p->plock); + ns16552kick(p); break; case 0: /* modem status */ ch = uartrdreg(p, Mstat); if(ch & Ctsc){ + lock(&p->tlock); l = p->cts; p->cts = ch & Cts; if(l == 0 && p->cts) p->ctsbackoff = 2; /* clock gets output going again */ + unlock(&p->tlock); } break; @@ -633,8 +612,10 @@ uartclock(void) Uart *p; for(p = uartalloc.elist; p; p = p->elist){ + /* this amortizes cost of qproduce to many chars */ - if(haveinput){ + lock(&p->rlock); + if(p->haveinput){ n = p->ip - p->istage; if(n > 0 && p->iq){ if(n > Stagesize) @@ -644,15 +625,18 @@ uartclock(void) else p->ip = p->istage; } + p->haveinput = 0; } + unlock(&p->rlock); /* this adds hysteresis to hardware flow control */ + lock(&p->tlock); if(p->ctsbackoff){ if(--(p->ctsbackoff) == 0) - ns16552kick(p); + ns16552kick0(p); } + unlock(&p->tlock); } - haveinput = 0; } Dirtab *ns16552dir; @@ -672,7 +656,6 @@ setlength(int i) if(p && p->opens && p->iq) ns16552dir[3*i].length = qlen(p->iq); } - } /* @@ -792,7 +775,7 @@ ns16552close(Chan *c) } } -static long +long uartstatus(Chan*, Uart *p, void *buf, long n, long offset) { uchar mstat; @@ -855,7 +838,7 @@ ns16552bread(Chan *c, long n, ulong offset) return devbread(c, n, offset); } -static void +void ns16552ctl(Uart *p, char *cmd) { int i, n; @@ -944,8 +927,10 @@ ns16552write(Chan *c, void *buf, long n, ulong) * The fifo's turn themselves off sometimes. * It must be something I don't understand. -- presotto */ + lock(&p->flock); if((p->istat & Fenabd) == 0 && p->fifoon && p->nofifo == 0) ns16552fifoon(p); + unlock(&p->flock); switch(NETTYPE(c->qid.path)){ case Ndataqid: