## diffname gnot/devincon.c 1990/0312 ## diff -e /dev/null /n/bootesdump/1990/0312/sys/src/9/68020/devincon.c 0a #include "u.h" #include "lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "errno.h" #include "devtab.h" #include "io.h" typedef struct Incon Incon; typedef struct Device Device; #define NOW (MACHP(0)->ticks*MS2HZ) #define DPRINT if(0) enum { Minstation= 2, /* lowest station # to poll */ Maxstation= 15, /* highest station # to poll */ Nincon= 1, /* number of incons */ Nraw= 1024, /* size of raw input buffer */ }; /* * incon datakit board */ struct Device { uchar cdata; #define cpolln cdata uchar u0; uchar cstatus; uchar u1; uchar creset; uchar u2; uchar csend; uchar u3; ushort data_cntl; /* data is high byte, cntl is low byte */ uchar status; #define cmd status uchar u5; uchar reset; uchar u6; uchar send; uchar u7; }; #define INCON ((Device *)0x40700000) struct Incon { QLock; QLock xmit; /* transmit lock */ QLock reslock; /* reset lock */ Device *dev; int station; /* station number */ int state; /* chip state */ Rendez r; /* output process */ Rendez kr; /* input kernel process */ ushort chan; /* current input channel */ Queue *rq; /* read queue */ uchar buf[1024]; /* bytes being collected */ uchar *wptr; /* pointer into buf */ int kstarted; /* true if kernel process started */ ushort raw[Nraw]; ushort *rp; ushort *wp; /* statistics */ ulong overflow; /* overflow errors */ ulong pack0; /* channel 0 */ ulong crc; /* crc errors */ ulong in; /* bytes in */ ulong out; /* bytes out */ }; Incon incon[Nincon]; /* * chip state */ enum { Selecting, Selected, Dead, }; /* * internal chip registers */ #define sel_polln 0 #define sel_station 1 #define sel_poll0 2 #define sel_rcv_cnt 3 #define sel_rcv_tim 4 #define sel_tx_cnt 5 /* * CSR bits */ #define INCON_RUN 0x80 #define INCON_STOP 0x00 #define ENABLE_IRQ 0x40 #define ENABLE_TX_IRQ 0x20 #define INCON_ALIVE 0x80 #define TX_FULL 0x10 #define TX_EMPTY 0x08 #define RCV_EMPTY 0x04 #define OVERFLOW 0x02 #define CRC_ERROR 0x01 /* * polling constants */ #define HT_GNOT 0x30 #define ST_UNIX 0x04 #define NCHAN 16 static void inconkproc(void*); /* * incon stream module definition */ static void inconoput(Queue*, Block*); static void inconstopen(Queue*, Stream*); static void inconstclose(Queue*); Qinfo inconinfo = { nullput, inconoput, inconstopen, inconstclose, "incon" }; /* * set the incon parameters */ void inconset(Incon *ip, int cnt, int delay) { Device *dev; if (cnt<1 || cnt>14 || delay<1 || delay>15) error(0, Ebadarg); dev = ip->dev; dev->cmd = sel_rcv_cnt | INCON_RUN; *(uchar *)&dev->data_cntl = cnt; dev->cmd = sel_rcv_tim | INCON_RUN; *(uchar *)&dev->data_cntl = delay; dev->cmd = INCON_RUN | ENABLE_IRQ; } static void nop(void) { } /* * poll for a station number */ void inconpoll(Incon *ip, int station) { ulong timer; Device *dev; dev = ip->dev; /* * get us to a known state */ ip->state = Dead; dev->cmd = INCON_STOP; /* * try a station number */ dev->cmd = sel_station; *(uchar *)&dev->data_cntl = station; dev->cmd = sel_poll0; *(uchar *)&dev->data_cntl = HT_GNOT; dev->cmd = sel_rcv_cnt; *(uchar *)&dev->data_cntl = 3; dev->cmd = sel_rcv_tim; *(uchar *)&dev->data_cntl = 15; dev->cmd = sel_tx_cnt; *(uchar *)&dev->data_cntl = 1; dev->cmd = sel_polln; *(uchar *)&dev->data_cntl = 0x00; *(uchar *)&dev->data_cntl = ST_UNIX; *(uchar *)&dev->data_cntl = NCHAN; *(uchar *)&dev->data_cntl = 'g'; *(uchar *)&dev->data_cntl = 'n'; *(uchar *)&dev->data_cntl = 'o'; *(uchar *)&dev->data_cntl = 't'; dev->cpolln = 0; /* * poll and wait for ready (or 1/4 second) */ ip->state = Selecting; dev->cmd = INCON_RUN | ENABLE_IRQ; timer = NOW + 250; while (NOW < timer) { nop(); if(dev->status & INCON_ALIVE){ ip->station = station; ip->state = Selected; break; } } } /* * reset the chip and find a new staion number */ void inconrestart(Incon *ip) { Device *dev; int i; if(!canqlock(&ip->reslock)) return; /* * poll for incon station numbers */ for(i = Minstation; i <= Maxstation; i++){ inconpoll(ip, i); if(ip->state == Selected) break; } switch(ip->state) { case Selecting: print("incon[%d] not polled\n", ip-incon); break; case Selected: print("incon[%d] station %d\n", ip-incon, ip->station); inconset(ip, 8, 9); break; default: print("incon[%d] bollixed\n", ip-incon); break; } qunlock(&ip->reslock); } /* * reset all incon chips. */ void inconreset(void) { int i; Incon *ip; incon[0].dev = INCON; incon[0].state = Selected; incon[0].rp = incon[0].wp = incon[0].raw; for(i=1; icmd = INCON_STOP; incon[i].rp = incon[i].wp = incon[i].raw; } } void inconinit(void) { } /* * enable the device for interrupts, spec is the device number */ Chan* inconattach(char *spec) { Incon *ip; int i; Chan *c; i = strtoul(spec, 0, 0); if(i >= Nincon) error(0, Ebadarg); ip = &incon[i]; if(ip->state != Selected) inconrestart(ip); c = devattach('i', spec); c->dev = i; c->qid = CHDIR; return c; } Chan* inconclone(Chan *c, Chan *nc) { return devclone(c, nc); } int inconwalk(Chan *c, char *name) { return devwalk(c, name, 0, 0, streamgen); } void inconstat(Chan *c, char *dp) { devstat(c, dp, 0, 0, streamgen); } Chan* inconopen(Chan *c, int omode) { if(c->qid == CHDIR){ if(omode != OREAD) error(0, Eperm); }else streamopen(c, &inconinfo); c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; return c; } void inconcreate(Chan *c, char *name, int omode, ulong perm) { error(0, Eperm); } void inconclose(Chan *c) { if(c->qid != CHDIR) streamclose(c); } long inconread(Chan *c, void *buf, long n) { return streamread(c, buf, n); } long inconwrite(Chan *c, void *buf, long n) { return streamwrite(c, buf, n, 0); } void inconremove(Chan *c) { error(0, Eperm); } void inconwstat(Chan *c, char *dp) { error(0, Eperm); } void inconuserstr(Error *e, char *buf) { consuserstr(e, buf); } void inconerrstr(Error *e, char *buf) { rooterrstr(e, buf); } /* * the stream routines */ /* * create the kernel process for input */ static void inconstopen(Queue *q, Stream *s) { Incon *ip; char name[32]; ip = &incon[s->dev]; sprint(name, "**incon%d**", s->dev); q->ptr = q->other->ptr = ip; ip->rq = q; kproc(name, inconkproc, ip); } /* * kill off the kernel process */ static int kDead(void *arg) { Incon *ip; ip = (Incon *)arg; return ip->kstarted == 0; } static void inconstclose(Queue * q) { Incon *ip; ip = (Incon *)q->ptr; qlock(ip); ip->rq = 0; qunlock(ip); wakeup(&ip->kr); sleep(&ip->r, kDead, ip); } /* * 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); } } /* * 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 inconoput(Queue *q, Block *bp) { Device *dev; Incon *ip; ulong end; int chan; int ctl; int n, size; 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 */ ip = (Incon *)q->ptr; qlock(&ip->xmit); dev = ip->dev; /* * parse message */ bp = getq(q); if(bp->wptr - bp->rptr < 3){ freemsg(q, bp); qunlock(&ip->xmit); return; } chan = bp->rptr[0] | (bp->rptr[1]<<8); ctl = bp->rptr[2]; bp->rptr += 3; /* * make sure there's an incon out there */ if(!(dev->status&INCON_ALIVE) || ip->state==Dead){ inconrestart(ip); freemsg(q, bp); qunlock(&ip->xmit); return; } /* * send the 8 bit data */ for(;;){ /* * spin till there is room */ for(end = NOW+1000; dev->status & TX_FULL;){ nop(); /* make sure we don't optimize too much */ if(NOW > end){ print("incon output stuck\n"); freemsg(q, bp); qunlock(&ip->xmit); return; } } /* * put in next packet */ n = bp->wptr - bp->rptr; if(n > 16) n = 16; size = n; dev->cdata = chan; DPRINT("CH|%uo->\n", chan); while(n--){ DPRINT("->%uo\n", *bp->rptr); *(uchar *)&dev->data_cntl = *bp->rptr++; } /* * get next block */ if(bp->rptr >= bp->wptr){ if(bp->flags & S_DELIM){ freeb(bp); break; } freeb(bp); bp = getq(q); if(bp==0) break; } /* * end packet */ dev->cdata = 0; } /* * send the control byte if there is one */ if(ctl){ if(size >= 16){ dev->cdata = 0; DPRINT("CH|%uo->\n", chan); dev->cdata = chan; } DPRINT("CTL|%uo->\n", ctl); dev->cdata = ctl; } dev->cdata = 0; qunlock(&ip->xmit); return; } /* * return true if the raw fifo is non-empty */ static int notempty(void *arg) { Incon *ip; ip = (Incon *)arg; return ip->wp!=ip->rp; } /* * fill a block with what is currently buffered and send it upstream */ static void upstream(Incon *ip, unsigned int ctl) { int n; Block *bp; n = ip->wptr - ip->buf; bp = allocb(3 + n); bp->wptr[0] = ip->chan; bp->wptr[1] = ip->chan>>8; bp->wptr[2] = ctl; if(n) memcpy(&bp->wptr[3], ip->buf, n); bp->wptr += 3 + n; bp->flags |= S_DELIM; PUTNEXT(ip->rq, bp); ip->wptr = ip->buf; } /* * Read bytes from the raw input circular buffer. */ static void inconkproc(void *arg) { Incon *ip; unsigned int c; uchar *lim; ushort *p, *e; ip = (Incon *)arg; ip->kstarted = 1; ip->wptr = ip->buf; e = &ip->raw[Nraw]; for(;;){ /* * die if the device is closed */ qlock(ip); if(ip->rq == 0){ qunlock(ip); ip->kstarted = 0; wakeup(&ip->r); return; } /* * sleep if input fifo empty */ while(!notempty(ip)) sleep(&ip->kr, notempty, ip); p = ip->rp; /* * get channel number */ c = (*p++)>>8; if(p == e) p = ip->raw; DPRINT("<-CH|%uo\n", c); if(ip->chan != c){ if(ip->wptr - ip->buf != 0) upstream(ip, 0); ip->chan = c; } /* * null byte marks end of packet */ for(lim = &ip->buf[sizeof ip->buf];;){ if((c=*p++)&1) { /* * data byte, put in local buffer */ c = *ip->wptr++ = c>>8; DPRINT("<-%uo\n", c); if(ip->wptr >= lim) upstream(ip, 0); } else if (c>>=8) { /* * control byte ends block */ DPRINT("<-CTL|%uo\n", c); upstream(ip, c); } else { /* end of packet */ break; } if(p == e) p = ip->raw; } ip->rp = p; qunlock(ip); } } /* * read the packets from the device into the raw input buffer. * we have to do this at interrupt tevel to turn off the interrupts. */ static rdpackets(Incon *ip) { Device *dev; unsigned int c; ushort *p, *e; int n; dev = ip->dev; while(!(dev->status & RCV_EMPTY)){ n = ip->rp - ip->wp; if(n <= 0) n += Nraw; if(n < 19){ /* * no room in the raw queue, throw it away */ c = (dev->data_cntl)>>8; for(c=0;c<18;c++){ if(dev->data_cntl == 0) break; } } else { /* * put packet in the raw queue */ p = ip->wp; e = &ip->raw[Nraw]; *p++ = dev->data_cntl; if(p == e) p = ip->raw; do { *p++ = c = dev->data_cntl; if(p == e) p = ip->raw; } while(c); ip->wp = p; } } wakeup(&ip->kr); } /* * Receive an incon interrupt. One entry point * for all types of interrupt. Until we figure out * how to use more than one incon, this routine only * is for incon[0]. */ inconintr(Ureg *ur) { uchar status; Incon *ip; ip = &incon[0]; status = ip->dev->status; if(!(status & RCV_EMPTY)) rdpackets(ip); /* check for exceptional conditions */ if(status&(OVERFLOW|CRC_ERROR)){ if(status&OVERFLOW){ print("incon overflow\n"); ip->overflow++; } if(status&CRC_ERROR){ print("incon crc error\n"); ip->crc++; } } /* see if it died underneath us */ if(!(status&INCON_ALIVE)){ switch(ip->state){ case Selected: ip->dev->cmd = INCON_STOP; print("Incon died\n"); break; case Selecting: print("rejected\n"); break; default: ip->dev->cmd = INCON_STOP; break; } ip->state = Dead; } } . ## diffname gnot/devincon.c 1990/0315 ## diff -e /n/bootesdump/1990/0312/sys/src/9/68020/devincon.c /n/bootesdump/1990/0315/sys/src/9/68020/devincon.c 665,713d 660c bp = nextin(ip, c); if(bp == 0) continue; . 653,654c if(bp->wptr >= bp->lim){ bp = nextin(ip, 0); if(bp == 0) continue; } . 651c c = *bp->wptr++ = c>>8; . 646,647c for(;;){ if((c=dev->data_cntl)&1) { . 638,639c if(bp->wptr - bp->rptr > 3){ bp = nextin(ip, 0); if(bp == 0) continue; } . 633,635c c = (dev->data_cntl)>>8; . 629a /* * drop an input packet on the floor */ static void droppacket(Device *dev) { int i; int c; for(i = 0; i < 17; i++){ c = dev->data_cntl; if(c==0) break; } } /* * advance the queue. if we've run out of staged input blocks, * drop the packet and return 0. otherwise return the next input * block to fill. */ static Block * nextin(Incon *ip, unsigned int c) { Block *bp = ip->inb[ip->wi]; bp->base[0] = ip->chan; bp->base[1] = ip->chan>>8; bp->base[2] = c; ip->wi = (ip->wi + 1) % Nin; if(((ip->wi+1)%Nin) == ip->ri){ droppacket(ip->dev); return 0; } return ip->inb[ip->wi]; } /* * read the packets from the device into the staged input blocks. * we have to do this at interrupt tevel to turn off the interrupts. */ static void rdpackets(Incon *ip) { Block *bp; unsigned int c; Device *dev; dev = ip->dev; while(!(dev->status & RCV_EMPTY)){ bp = ip->inb[ip->wi]; if(((ip->wi+1)%Nin) == ip->ri || bp==0){ c = dev->data_cntl; droppacket(dev); continue; } . 626,628c while(ip->ri != ip->wi){ PUTNEXT(ip->rq, ip->inb[ip->ri]); bp = ip->inb[ip->ri] = allocb(128); bp->wptr += 3; ip->ri = (ip->ri+1)%Nin; } qunlock(ip); } } . 624c * send blocks upstream and stage new blocks . 612a * sleep if input fifo empty */ sleep(&ip->kr, notempty, ip); /* . 610c /* * create a number of blocks for input */ for(i = 0; i < Nin; i++){ bp = ip->inb[i] = allocb(128); bp->wptr += 3; } . 608d 602,604c Block *bp; int i; . 574,595d 570c return ip->ri!=ip->wi; . 553a MICROSECOND; . 261c incon[i].ri = incon[i].wi = 0; . 256c incon[0].ri = incon[0].wi = 0; inconset(&incon[0], 8, 9); . 145c MICROSECOND; *(uchar *)&dev->data_cntl = del; MICROSECOND; . 143a MICROSECOND; . 142a MICROSECOND; . 138c if (cnt<1 || cnt>14 || del<1 || del>15) . 134c inconset(Incon *ip, int cnt, int del) . 68a Block *inb[Nin]; ushort wi; ushort ri; . 65,67c /* input blocks */ . 61,62d 22c Nin= 32, /* size of raw input buffer */ . 15a static int SpEcIaL; #define MICROSECOND SpEcIaL = 0 . ## diffname gnot/devincon.c 1990/0320 ## diff -e /n/bootesdump/1990/0315/sys/src/9/68020/devincon.c /n/bootesdump/1990/0320/sys/src/9/68020/devincon.c 761c screenputc('+'); . 757c screenputc('^'); . 733,734c /* * pass a block on if it doesn't have room for one more * packet. this way we don't have to check per byte. */ if(p + 16 > bp->lim){ bp->wptr = p; bp = nextin(ip, 0); if(bp == 0) goto done; p = bp->wptr; } } bp->wptr = p; done: if(first != ip->wi)/**/ wakeup(&ip->kr); . 727c goto done; p = bp->wptr; . 724c bp->wptr = p; . 713,719c *p++ = c>>8; . 700c goto done; p = bp->wptr; . 697c if(p - bp->rptr > 3){ bp->wptr = p; . 695d 684,690d 682a bp = ip->inb[ip->wi]; if(bp==0){ droppacket(ip->dev); goto done; } p = bp->wptr; . 680a uchar *p; int first = ip->wi; . 664,667d 662c ip->wi = next; . 658a next = (ip->wi+1)%Nin; if(next == ip->ri){ bp->wptr = bp->base+3; droppacket(ip->dev); return 0; } . 657a int next; . 642,645c screenputc('!'); while(!(dev->status & RCV_EMPTY)){ for(i = 0; i < 17; i++){ c = dev->data_cntl; if(c==0) break; } . 625c bp = ip->inb[ip->ri] = allocb(Bsize); . 599c bp = ip->inb[i] = allocb(Bsize); . 563a MICROSECOND; . 562d 560d 558a MICROSECOND; . 557c MICROSECOND; . 527d 525d 25c Nin= 16, /* Blocks in the input ring */ Bsize= 128, /* size of an input ring block */ . 9a #include "ureg.h" . ## diffname gnot/devincon.c 1990/0321 ## diff -e /n/bootesdump/1990/0320/sys/src/9/68020/devincon.c /n/bootesdump/1990/0321/sys/src/9/68020/devincon.c 751d 744,745d 728,729d 706,707d 701a if(c == 0){ droppacket(dev); continue; } . 693,694c flushfifo(ip->dev); return; . 673a next = (ip->wi+3)%Nin; if(next == ip->ri){ bp->wptr = bp->base+3; return bp; } ip->wi = (ip->wi+1)%Nin; . 672d 663,668c bp = ip->inb[ip->wi]; . 660c Block *bp; . 652a * flush the input fifo */ static void flushfifo(Device *dev) { while(!(dev->status & RCV_EMPTY)) droppacket(dev); } /* . 642,648c for(i = 0; i < 17; i++){ c = dev->data_cntl; if(c==0) break; . 634c * drop a single packet . 27a Mfifo= 0xff /* a mask, must be 2^n-1, must be > Nin */ . 26c Nin= 64, /* Blocks in the input ring */ . ## diffname gnot/devincon.c 1990/0322 ## diff -e /n/bootesdump/1990/0321/sys/src/9/68020/devincon.c /n/bootesdump/1990/0322/sys/src/9/68020/devincon.c 625c bp = ip->inb[ip->ri]; n = BLEN(bp); if(n <= 64){ nbp = allocb(n); memcpy(nbp->wptr, bp->rptr, n); nbp->wptr += n; freeb(bp); PUTNEXT(ip->rq, nbp); } else { PUTNEXT(ip->rq, bp); } . 622c * send blocks upstream and stage new blocks. if the block is small * (< 64 bytes) copy into a smaller buffer. . 590,591c Block *bp, *nbp; int i, n; . 26c Nin= 32, /* Blocks in the input ring */ . ## diffname gnot/devincon.c 1990/0330 ## diff -e /n/bootesdump/1990/0322/sys/src/9/68020/devincon.c /n/bootesdump/1990/0330/sys/src/9/68020/devincon.c 267c /* inconset(&incon[0], 8, 9); /**/ . ## diffname gnot/devincon.c 1990/0331 ## diff -e /n/bootesdump/1990/0330/sys/src/9/68020/devincon.c /n/bootesdump/1990/0331/sys/src/9/68020/devincon.c 628,636c PUTNEXT(ip->rq, bp); . 267c /* inconset(&incon[0], 3, 15); /**/ . 246c inconset(ip, 3, 15); . ## diffname gnot/devincon.c 1990/05312 ## diff -e /n/bootesdump/1990/0331/sys/src/9/68020/devincon.c /n/bootesdump/1990/05312/sys/src/9/68020/devincon.c 759a if(bp->wptr != bp->base+3) nextin(ip, 0); . ## diffname gnot/devincon.c 1990/0619 ## diff -e /n/bootesdump/1990/05312/sys/src/9/68020/devincon.c /n/bootesdump/1990/0619/sys/src/9/68020/devincon.c 793d 789,791c if(status&CRC_ERROR) . 786,787c if(status&OVERFLOW) . ## diffname gnot/devincon.c 1990/0623 ## diff -e /n/bootesdump/1990/0619/sys/src/9/68020/devincon.c /n/bootesdump/1990/0623/sys/src/9/68020/devincon.c 231a print("inconrestart\n"); . ## diffname gnot/devincon.c 1990/0629 ## diff -e /n/bootesdump/1990/0623/sys/src/9/68020/devincon.c /n/bootesdump/1990/0629/sys/src/9/68020/devincon.c 809a } incontoggle() { incondebug ^= 1; . 679a if(incondebug) print("<-(%d)%uo %d\n", ip->chan, c, bp->wptr-bp->rptr)-3; . 494a if(incondebug) print("->(%d)%uo %d\n", chan, ctl, bp->wptr - bp->rptr); . 135a int incondebug; . ## diffname gnot/devincon.c 1990/0725 ## diff -e /n/bootesdump/1990/0629/sys/src/9/68020/devincon.c /n/bootesdump/1990/0725/sys/src/9/68020/devincon.c 815c ip->state = Notliving; . 503c if(!(dev->status&INCON_ALIVE) || ip->state==Notliving){ . 430c sleep(&ip->r, kNotliving, ip); . 413c kNotliving(void *arg) . 403c sprint(name, "incon%d", s->dev); . 274c incon[i].state = Notliving; . 180c ip->state = Notliving; . 92c Notliving, . ## diffname gnot/devincon.c 1990/0731 ## diff -e /n/bootesdump/1990/0725/sys/src/9/68020/devincon.c /n/bootesdump/1990/0731/sys/src/9/68020/devincon.c 693c ip->wi = next; . 688c next = (ip->wi+1)%Nin; . 686c print("<-(%d)%uo %d\n", ip->chan, c, bp->wptr-bp->rptr); . ## diffname gnot/devincon.c 1990/0802 ## diff -e /n/bootesdump/1990/0731/sys/src/9/68020/devincon.c /n/bootesdump/1990/0802/sys/src/9/68020/devincon.c 495a if(chan<=0) print("bad channel %d\n", chan); . ## diffname gnot/devincon.c 1990/1024 ## diff -e /n/bootesdump/1990/0802/sys/src/9/68020/devincon.c /n/bootesdump/1990/1024/sys/src/9/68020/devincon.c 612a /* * ignore errors */ if(waserror()) ; . ## diffname gnot/devincon.c 1990/1101 ## diff -e /n/bootesdump/1990/1024/sys/src/9/68020/devincon.c /n/bootesdump/1990/1101/sys/src/9/68020/devincon.c 648a locked = 0; . 627a locked = 1; . 613,617c locked = 0; if(waserror()){ if(locked) qunlock(ip); ip->kstarted = 0; wakeup(&ip->r); return; } . 600a int locked; . 480d 467c if(streamparse("inconset", bp)) inconsetctl(ip, bp); else freeb(bp); . 465a ip = (Incon *)q->ptr; . 160a /* * parse a set request */ void inconsetctl(Incon *ip, Block *bp) { char *field[3]; int n; int del; int cnt; del = 15; n = getfields((char *)bp->rptr, field, 3, ' '); switch(n){ default: freeb(bp); error(0, Ebadarg); case 2: del = strtol(field[1], 0, 0); if(del<0 || del>15){ freeb(bp); error(0, Ebadarg); } /* fall through */ case 1: cnt = strtol(field[0], 0, 0); if(cnt<0 || cnt>15){ freeb(bp); error(0, Ebadarg); } } inconset(ip, cnt, del); freeb(bp); } . ## diffname gnot/devincon.c 1990/11151 ## diff -e /n/bootesdump/1990/1101/sys/src/9/68020/devincon.c /n/bootesdump/1990/11151/sys/src/9/68020/devincon.c 134c Qinfo inconinfo = { nullput, inconoput, inconstopen, inconstclose, "incon" }; . ## diffname gnot/devincon.c 1990/11211 ## diff -e /n/bootesdump/1990/11151/sys/src/9/68020/devincon.c /n/bootesdump/1990/11211/sys/src/9/68020/devincon.c 416,428c error(Eperm); . 410c error(Eperm); . 391c if(c->qid.path != CHDIR) . 385c error(Eperm); . 373c error(Eperm); . 371c if(c->qid.path == CHDIR){ . 346c c->qid.path = CHDIR; c->qid.vers = 0; . 339c error(Ebadarg); . 196c error(Ebadarg); . 189c error(Ebadarg); . 184c error(Ebadarg); . 154c error(Ebadarg); . ## diffname gnot/devincon.c 1990/1212 ## diff -e /n/bootesdump/1990/11211/sys/src/9/68020/devincon.c /n/bootesdump/1990/1212/sys/src/9/68020/devincon.c 605a if(dev->status & TX_FULL) print("inconfull\n"); . 602a for(end = NOW+1000; dev->status & TX_FULL;){ nop(); /* make sure we don't optimize too much */ if(NOW > end){ print("incon output stuck\n"); freemsg(q, bp); qunlock(&ip->xmit); return; } } . ## diffname gnot/devincon.c 1990/1214 ## diff -e /n/bootesdump/1990/1212/sys/src/9/68020/devincon.c /n/bootesdump/1990/1214/sys/src/9/68020/devincon.c 698a USED(locked); . 693d 683a poperror(); . 679a locked = 1; . 678c USED(locked); . 646c int i; . 17,18c #define MICROSECOND USED(NOW) . ## diffname gnot/devincon.c 1991/0115 ## diff -e /n/bootesdump/1990/1214/sys/src/9/68020/devincon.c /n/bootesdump/1991/0115/sys/src/9/68020/devincon.c 880c void incontoggle(void) . ## diffname gnot/devincon.c 1991/0411 ## diff -e /n/bootesdump/1991/0201/sys/src/9/68020/devincon.c /n/bootesdump/1991/0411/sys/src/9/gnot/devincon.c 402c inconwrite(Chan *c, void *buf, long n, ulong offset) . 396c inconread(Chan *c, void *buf, long n, ulong offset) . ## diffname gnot/devincon.c 1991/0419 ## diff -e /n/bootesdump/1991/0411/sys/src/9/gnot/devincon.c /n/bootesdump/1991/0419/sys/src/9/gnot/devincon.c 361a Chan* inconclwalk(Chan *c, char *name) { return devclwalk(c, name); } . ## diffname gnot/devincon.c 1991/0427 ## diff -e /n/bootesdump/1991/0419/sys/src/9/gnot/devincon.c /n/bootesdump/1991/0427/sys/src/9/gnot/devincon.c 362,367d ## diffname gnot/devincon.c 1991/0906 ## diff -e /n/bootesdump/1991/0427/sys/src/9/gnot/devincon.c /n/bootesdump/1991/0906/sys/src/9/gnot/devincon.c 275,276d ## diffname gnot/devincon.c 1991/1122 ## diff -e /n/bootesdump/1991/0906/sys/src/9/gnot/devincon.c /n/bootesdump/1991/1122/sys/src/9/gnot/devincon.c 691a ip->in += BLEN(bp); . 568a ip->out += n; . 559a ip->wait = (n + ip->wait)>>1; . 551c start = NOW; for(n = 0, end = start+1000; dev->status & TX_FULL; n++){ . 489c ulong start, end; . 396c char b[256]; Incon *i; if(c->qid.path == CHDIR) return devdirread(c, buf, n, incondir, 1, streamgen); else if(c->qid.path == Qstats){ i = &incon[c->dev]; sprint(b, "in: %d\nout: %d\noverflow: %d\ncrc: %d\nwait: %d\n", i->in, i->out, i->overflow, i->crc, i->wait); return stringread(buf, n, b, offset); } else return streamread(c, buf, n); . 369c if(c->qid.path == CHDIR || c->qid.path == Qstats){ . 363c devstat(c, dp, incondir, 1, streamgen); . 357c return devwalk(c, name, incondir, 1, streamgen); . 143a Dirtab incondir[]={ "stats", {Qstats}, 0, 0444, }; . 80a ulong wait; /* wait time in milliseconds */ . 27c Mfifo= 0xff, /* a mask, must be 2^n-1, must be > Nin */ Qstats= 1, /* qid of the statistics file */ . ## diffname gnot/devincon.c 1991/1209 ## diff -e /n/bootesdump/1991/1122/sys/src/9/gnot/devincon.c /n/bootesdump/1991/1209/sys/src/9/gnot/devincon.c 831a if(bp==0){ flushfifo(ip->dev); return; } . 811a if(bp==0){ flushfifo(ip->dev); return; } . ## diffname gnot/devincon.c 1991/1219 ## diff -e /n/bootesdump/1991/1209/sys/src/9/gnot/devincon.c /n/bootesdump/1991/1219/sys/src/9/gnot/devincon.c 458,465d 450a wakeup(&ip->kr); sleep(&ip->r, kNotliving, ip); . 440a * first wait for any old ones to die . 439a * for sleeping while kproc dies */ static int kNotliving(void *arg) { Incon *ip; ip = (Incon *)arg; return ip->kstarted == 0; } /* . ## diffname gnot/devincon.c 1992/0111 ## diff -e /n/bootesdump/1991/1219/sys/src/9/gnot/devincon.c /n/bootesdump/1992/0111/sys/src/9/gnot/devincon.c 6c #include "../port/error.h" . ## diffname gnot/devincon.c 1992/0321 ## diff -e /n/bootesdump/1992/0111/sys/src/9/gnot/devincon.c /n/bootesdump/1992/0321/sys/src/9/gnot/devincon.c 2c #include "../port/lib.h" . ## diffname gnot/devincon.c 1992/0611 ## diff -e /n/bootesdump/1992/0321/sys/src/9/gnot/devincon.c /n/bootesdump/1992/0611/sys/src/9/gnot/devincon.c 877a void . ## diffname gnot/devincon.c 1992/0623 ## diff -e /n/bootesdump/1992/0611/sys/src/9/gnot/devincon.c /n/bootesdump/1992/0623/sys/src/9/gnot/devincon.c 865c if(bp->wptr != bp->rptr+3) . 778c bp->wptr = bp->rptr+3; . 770,772c bp->rptr[0] = ip->chan; bp->rptr[1] = ip->chan>>8; bp->rptr[2] = c; . 545,549d 527a if(BLEN(bp) < 3){ bp = pullup(bp, 3); if(bp == 0){ print("inconoput pullup failed\n"); return; } } . 412c return readstr(offset, buf, n, b); . ## diffname gnot/devincon.c 1992/0711 ## diff -e /n/bootesdump/1992/0623/sys/src/9/gnot/devincon.c /n/bootesdump/1992/0711/sys/src/9/gnot/devincon.c 885a USED(ur); . 672c Block *bp; . 431a USED(c, dp); . 425a USED(c); . 419a USED(offset); . 389a USED(c, name, omode, perm); . 312d 276d ## diffname gnot/devincon.c 1993/0501 # deleted ## diff -e /n/bootesdump/1992/0711/sys/src/9/gnot/devincon.c /n/fornaxdump/1993/0501/sys/src/brazil/gnot/devincon.c 1,925d