## diffname port/stasync.c 1990/1009 ## diff -e /dev/null /n/bootesdump/1990/1009/sys/src/9/mips/stasync.c 0a #include "u.h" #include "lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "errno.h" #define DPRINT if(asyncdebug)kprint /* * configuration */ enum { MAXFRAME= 256, /* also known to tsm8 code */ }; /* input states */ enum { Hunt=0, Framing, Framed, Data, Escape }; typedef struct Async { QLock; int inuse; Queue *wq; /* output state */ QLock xmit; /* transmit lock */ int chan; /* current urp channel */ Block *bp; /* current output buffer */ int count; ushort crc; /* input state */ int state; /* input state */ uchar buf[MAXFRAME]; /* current input buffer */ int icount; ushort icrc; /* statistics */ ulong chan0; ulong toolong; ulong tooshort; ulong badcrc; ulong badescape; ulong in; /* bytes in */ ulong out; /* bytes out */ } Async; Async *async; /* * async stream module definition */ static void asynciput(Queue*, Block*); static void asyncoput(Queue*, Block*); static void asyncopen(Queue*, Stream*); static void asyncclose(Queue*); static void asyncreset(void); Qinfo asyncinfo = { asynciput, asyncoput, asyncopen, asyncclose, "async", asyncreset }; int asyncdebug = 0; int asyncerror; static ushort crc_table[256] = { #include "crc_16.h" }; #define BOT 0050 /* begin trailer */ #define BOTM 0051 /* begin trailer, more data follows */ #define BOTS 0052 /* seq update alg. on this trailer */ #define FRAME 0x7e #define STUF 0x9d #define CRCSTART (crc_table[0xff]) #define CRCFUNC(crc,x) (crc_table[((crc)^(x))&0xff]^((crc)>>8)) /* * create the async structures */ static void asyncreset(void) { async = (Async *)ialloc(conf.nasync*sizeof(Async), 0); } /* * allocate an async structure */ static void asyncopen(Queue *q, Stream *s) { Async *ap; DPRINT("asyncopen %d\n", s->dev); for(ap = async; ap < &async[conf.nasync]; ap++){ qlock(ap); if(ap->inuse == 0) break; qunlock(ap); } if(ap == &async[conf.nasync]) error(0, Enoasync); q->ptr = q->other->ptr = ap; ap->inuse = 1; ap->bp = 0; ap->chan = -1; ap->count = 0; ap->toolong = 0; ap->tooshort = 0; ap->badcrc = 0; ap->badescape = 0; ap->chan0 = 0; ap->in = 0; ap->out = 0; ap->wq = WR(q); ap->state = Hunt; qunlock(ap); } static void asyncclose(Queue * q) { Async *ap = (Async *)q->ptr; DPRINT("asyncstclose %d\n", ap-async); qlock(ap); ap->inuse = 0; qunlock(ap); } /* * free all blocks of a message in `q', `bp' is the first block * of the message */ static void freemsg(Queue *q, Block *bp) { for(; bp; bp = getq(q)){ if(bp->flags & S_DELIM){ freeb(bp); return; } freeb(bp); } } static void showframe(char *t, Async *ap, uchar *buf, int n) { kprint("a%d %s [", ap-async, t); while (--n >= 0) kprint(" %2.2ux", *buf++); kprint(" ]\n"); } void aswrite(Async *ap) { if(ap->bp->rptr == ap->bp->wptr) return; FLOWCTL(ap->wq); PUTNEXT(ap->wq, ap->bp); ap->bp = 0; } void asputf(Async *ap, int frame) { uchar *p; int c; p = ap->bp->wptr; if(ap->count > 0) { if(asyncerror) ap->crc^=1, asyncerror=0; *p++ = c = ap->crc&0xff; if(c == FRAME) *p++ = 0x00; *p++ = c = (ap->crc>>8)&0xff; if(c == FRAME) *p++ = 0x00; ap->count = 0; } if(frame) { *p++ = FRAME; *p++ = FRAME; } ap->bp->wptr = p; if(asyncdebug > 2) showframe("out", ap, ap->bp->rptr, BLEN(ap->bp)); aswrite(ap); } void asputc(Async *ap, int c) { int d; uchar *p; if(ap->bp == 0) ap->bp = allocb(MAXFRAME+4); p = ap->bp->wptr; if(ap->count <= 0) { *p++ = FRAME; *p++ = FRAME; *p++ = d = 0x80|((ap->chan>>5)&0x7e); ap->crc = CRCFUNC(CRCSTART, d); *p++ = d = 0x80|((ap->chan<<1)&0x7e); ap->crc = CRCFUNC(ap->crc, d); } *p++ = c; if(c == FRAME) *p++ = 0x00; ap->crc = CRCFUNC(ap->crc, c); ap->bp->wptr = p; if(++ap->count >= MAXFRAME-4) asputf(ap, 0); else if(ap->bp->lim - p < 8) aswrite(ap); } /* * output a block * * the first 2 bytes of every message are the channel number, * low order byte first. the third is a possible trailing control * character. */ void asyncoput(Queue *q, Block *bp) { Async *ap = (Async *)q->ptr; int c, chan, ctl; if(bp->type != M_DATA){ freeb(bp); return; } /* * get a whole message before handing bytes to the device */ if(!putq(q, bp)) return; /* * one transmitter at a time */ qlock(&ap->xmit); /* * parse message */ bp = getq(q); if(bp->wptr - bp->rptr < 3){ freemsg(q, bp); qunlock(&ap->xmit); return; } chan = bp->rptr[0] | (bp->rptr[1]<<8); ctl = bp->rptr[2]; bp->rptr += 3; /* * new frame if the channel number has changed */ if(chan != ap->chan && ap->count > 0) asputf(ap, 0); ap->chan = chan; /* * send the 8 bit data */ for(;;){ /* * put in next packet */ while (bp->rptr < bp->wptr) { asputc(ap, c = *bp->rptr++); if(c == STUF) asputc(ap, 0); } /* * get next block */ if(bp->flags & S_DELIM){ freeb(bp); break; } freeb(bp); bp = getq(q); if(bp==0) break; } /* * send the control byte if there is one */ if(ctl){ asputc(ap, STUF); asputc(ap, ctl); switch (ctl) { case BOT: case BOTM: case BOTS: break; default: asputf(ap, 1); } } qunlock(&ap->xmit); return; } /* * Read bytes from the raw input. */ void asdeliver(Queue *q, Async *ap) { int chan, c; Block *bp = 0; uchar *p = ap->buf; int n = ap->icount; chan = *p++ & 0x7e; chan = (chan<<5)|((*p++ & 0x7e)>>1); if(chan==0) { DPRINT("a%d deliver chan 0\n", ap-async); ap->chan0++; return; } for (n-=4; n>0; n--) { if(!bp) { bp = allocb(n+2); bp->flags |= S_DELIM; bp->wptr[0] = chan; bp->wptr[1] = chan>>8; bp->wptr[2] = 0; bp->wptr += 3; } if((c = *p++) == STUF) { --n; if((c = *p++) != 0) { bp->rptr[2] = c; if(asyncdebug > 1) kprint("a%d<-(%d)%3.3uo %d\n", ap-async, chan, bp->rptr[2], bp->wptr - bp->rptr - 3); PUTNEXT(q, bp); bp = 0; continue; } else c = STUF; } *bp->wptr++ = c; } if(bp) { if(asyncdebug > 1) kprint("a%d<-(%d)%3.3uo %d\n", ap-async, chan, bp->rptr[2], bp->wptr - bp->rptr - 3); PUTNEXT(q, bp); } } static void asynciput(Queue *q, Block *bp) { int c; Async *ap = q->ptr; int state = ap->state; while(bp->wptr > bp->rptr){ c = *bp->rptr++; switch(state) { case Hunt: /* wait for framing byte */ if(c == FRAME) state = Framing; break; case Framing: /* saw 1 framing byte after Hunt */ if(c == FRAME) state = Framed; else state = Hunt; break; case Framed: /* saw 2 or more framing bytes */ if(c == FRAME) break; state = Data; ap->icrc = CRCSTART; ap->icount = 0; goto Datachar; case Data: /* mid-frame */ if(c == FRAME) { state = Escape; break; } Datachar: if(ap->icount >= MAXFRAME) { DPRINT("a%d pkt too long\n", ap-async); ap->toolong++; state = Hunt; break; } ap->icrc = CRCFUNC(ap->icrc, c); ap->buf[ap->icount++] = c; break; case Escape: /* saw framing byte in Data */ switch (c) { case FRAME: if(asyncdebug > 2) showframe("in", ap, ap->buf, ap->icount); if(ap->icount < 5) { DPRINT("a%d pkt too short\n", ap-async); ap->tooshort++; } else if(ap->icrc != 0) { DPRINT("a%d bad crc\n", ap-async); ap->badcrc++; } else { asdeliver(q, ap); } state = Framed; break; case 0: c = FRAME; state = Data; goto Datachar; default: DPRINT("a%d bad escape\n", ap-async); ap->badescape++; state = Hunt; break; } break; } } ap->state = state; freeb(bp); } . ## diffname port/stasync.c 1990/11151 ## diff -e /n/bootesdump/1990/1009/sys/src/9/mips/stasync.c /n/bootesdump/1990/11151/sys/src/9/mips/stasync.c 62c Qinfo asyncinfo = { asynciput, asyncoput, asyncopen, asyncclose, "async", asyncreset }; . ## diffname port/stasync.c 1990/11211 ## diff -e /n/bootesdump/1990/11151/sys/src/9/mips/stasync.c /n/bootesdump/1990/11211/sys/src/9/mips/stasync.c 115c error(Enoasync); . ## diffname port/stasync.c 1991/0217 ## diff -e /n/bootesdump/1990/1210/sys/src/9/mips/stasync.c /n/bootesdump/1991/0217/sys/src/9/port/stasync.c 249a if(streamparse("debug", bp)) asyncdebug = 3; . 72c int asyncdebug = 3; . ## diffname port/stasync.c 1991/0223 ## diff -e /n/bootesdump/1991/0217/sys/src/9/port/stasync.c /n/bootesdump/1991/0223/sys/src/9/port/stasync.c 325c asputf(ap); . 284c asputf(ap); . 231c asputf(ap); . 218,219d 198,201c *p++ = FRAME; *p++ = FRAME; . 181c asputf(Async *ap) . ## diffname port/stasync.c 1991/0423 ## diff -e /n/bootesdump/1991/0223/sys/src/9/port/stasync.c /n/bootesdump/1991/0423/sys/src/9/port/stasync.c 437a if(asyncdebug && asyncdebug<=2) showframe("badin", ap, ap->buf, ap->icount); . 434a if(asyncdebug && asyncdebug<=2) showframe("shortin", ap, ap->buf, ap->icount); . 323a if(debugcount > 0 && --debugcount == 0) asyncdebug = 1; . 282a if(asyncdebug > 1) kprint("a%d->(%d)%3.3uo %d\n", ap-async, chan, ctl, bp->wptr-bp->rptr); . 71a static int debugcount = 6; . ## diffname port/stasync.c 1991/0428 ## diff -e /n/bootesdump/1991/0423/sys/src/9/port/stasync.c /n/bootesdump/1991/0428/sys/src/9/port/stasync.c 77c #include "../port/crc_16.h" . ## diffname port/stasync.c 1991/0926 ## diff -e /n/bootesdump/1991/0428/sys/src/9/port/stasync.c /n/bootesdump/1991/0926/sys/src/9/port/stasync.c 332a poperror(); . 331a freeb(msg); . 300,311d 291,294c for(bp = msg; bp; bp = bp->next){ . 273,275d 271c freeb(msg); nexterror(); . 263,269c if(waserror()){ . 259,261d 257a } chan = msg->rptr[0] | (msg->rptr[1]<<8); ctl = msg->rptr[2]; msg->rptr += 3; . 256c msg = pullup(bp, 3); if(BLEN(msg) < 3){ print("asyncoput msglen < 3\n"); freeb(bp); . 254c * each datakit message has a 2 byte channel number followed by * one control byte . 244a Block *msg; . ## diffname port/stasync.c 1992/0111 ## diff -e /n/bootesdump/1991/0926/sys/src/9/port/stasync.c /n/bootesdump/1992/0111/sys/src/9/port/stasync.c 6c #include "../port/error.h" . ## diffname port/stasync.c 1992/0114 ## diff -e /n/bootesdump/1992/0111/sys/src/9/port/stasync.c /n/bootesdump/1992/0114/sys/src/9/port/stasync.c 116c exhausted("async stream modules"); . ## diffname port/stasync.c 1992/0305 ## diff -e /n/bootesdump/1992/0114/sys/src/9/port/stasync.c /n/bootesdump/1992/0305/sys/src/9/port/stasync.c 176,177c FLOWCTL(ap->wq, ap->bp); . ## diffname port/stasync.c 1992/0321 ## diff -e /n/bootesdump/1992/0305/sys/src/9/port/stasync.c /n/bootesdump/1992/0321/sys/src/9/port/stasync.c 2c #include "../port/lib.h" . ## diffname port/stasync.c 1992/0622 ## diff -e /n/bootesdump/1992/0321/sys/src/9/port/stasync.c /n/bootesdump/1992/0622/sys/src/9/port/stasync.c 96c async = (Async *)xalloc(conf.nasync*sizeof(Async)); . 42d 35d 27d 18c enum { Hunt, Framing, Framed, Data, Escape }; . ## diffname port/stasync.c 1992/0623 ## diff -e /n/bootesdump/1992/0622/sys/src/9/port/stasync.c /n/bootesdump/1992/0623/sys/src/9/port/stasync.c 448c DPRINT("a%d bad escape\n", ap->id); . 434c DPRINT("a%d bad crc\n", ap->id); . 429c DPRINT("a%d pkt too short\n", ap->id); . 414c DPRINT("a%d pkt too long\n", ap->id); . 371c ap->id, chan, bp->rptr[2], . 358c ap->id, chan, bp->rptr[2], . 339c DPRINT("a%d deliver chan 0\n", ap->id); . 287c ap->id, chan, ctl, bp->wptr-bp->rptr); . 169c kprint("a%d %s [", ap->id, t); . 144c DPRINT("asyncstclose %d\n", ap->id); . 119,120c if(ap == 0){ ap = smalloc(sizeof(Async)); qlock(ap); lock(&asyncalloc); ap->list = asyncalloc.async; asyncalloc.async = ap; ap->id = nasync++; unlock(&asyncalloc); } . 113c for(ap = asyncalloc.async; ap; ap = ap->list){ . 100d 57a /* list of allocated async structures (never freed) */ struct { Lock; Async *async; } asyncalloc; . 56c int nasync; . 54c }; . 28a Async *list; int id; . 27c typedef struct Async Async; struct Async { . ## diffname port/stasync.c 1992/0725 ## diff -e /n/bootesdump/1992/0623/sys/src/9/port/stasync.c /n/bootesdump/1992/0725/sys/src/9/port/stasync.c 88c int asyncdebug; . ## diffname port/stasync.c 1992/0917 ## diff -e /n/bootesdump/1992/0725/sys/src/9/port/stasync.c /n/bootesdump/1992/0917/sys/src/9/port/stasync.c 270c freeb(bp); } else { PUTNEXT(q, bp); } . 268c if(streamparse("debug", bp)){ . ## diffname port/stasync.c 1992/1219 ## diff -e /n/bootesdump/1992/0917/sys/src/9/port/stasync.c /n/bootesdump/1992/1219/sys/src/9/port/stasync.c 284d 282c if(msg == 0){ . ## diffname port/stasync.c 1993/0418 ## diff -e /n/bootesdump/1992/1219/sys/src/9/port/stasync.c /n/bootesdump/1993/0418/sys/src/9/port/stasync.c 198a ap->count = 0; . ## diffname port/stasync.c 1993/0501 ## diff -e /n/bootesdump/1993/0418/sys/src/9/port/stasync.c /n/fornaxdump/1993/0501/sys/src/brazil/port/stasync.c 199d ## diffname port/stasync.c 1993/0804 # deleted ## diff -e /n/fornaxdump/1993/0501/sys/src/brazil/port/stasync.c /n/fornaxdump/1993/0804/sys/src/brazil/port/stasync.c 1,477d