## diffname gnot/devcons.c 1990/03091 ## diff -e /dev/null /n/bootesdump/1990/03091/sys/src/9/68020/devcons.c 0a #include "u.h" #include "lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "io.h" #include "errno.h" #include "devtab.h" static struct { Lock; int printing; int c; }printq; typedef struct IOQ IOQ; #define NQ 4096 struct IOQ{ union{ Lock; QLock; }; uchar buf[NQ]; uchar *in; uchar *out; int state; Rendez r; }; IOQ kbdq; /* qlock to getc; interrupt putc's */ IOQ lineq; /* lock to getc; interrupt putc's */ void printinit(void) { lock(&printq); /* allocate lock */ unlock(&printq); kbdq.in = kbdq.buf; kbdq.out = kbdq.buf; lineq.in = lineq.buf; lineq.out = lineq.buf; qlock(&kbdq); /* allocate qlock */ qunlock(&kbdq); lock(&lineq); /* allocate lock */ unlock(&lineq); screeninit(); } /* * Print a string on the console. */ void putstrn(char *str, long n) { int s; s = splhi(); lock(&printq); printq.printing = 1; while(--n >= 0) screenputc(*str++); printq.printing = 0; unlock(&printq); splx(s); } int cangetc(IOQ *q) { return q->in != q->out; } int isbrkc(IOQ *q) { uchar *p; for(p=q->out; p!=q->in; ){ if(*p==0x04 || *p=='\n') return 1; p++; if(p >= q->buf+sizeof(q->buf)) p = q->buf; } return 0; } int getc(IOQ *q) { int c; if(q->in == q->out) return -1; c = *q->out++; if(q->out == q->buf+sizeof(q->buf)) q->out = q->buf; return c; } int sprint(char *s, char *fmt, ...) { return donprint(s, s+PRINTSIZE, fmt, (&fmt+1)) - s; } int print(char *fmt, ...) { char buf[PRINTSIZE]; int n; n = donprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf; putstrn(buf, n); return n; } void panic(char *fmt, ...) { char buf[PRINTSIZE]; int n; strcpy(buf, "panic: "); n = donprint(buf+7, buf+sizeof(buf), fmt, (&fmt+1)) - buf; buf[n] = '\n'; putstrn(buf, n+1); exit(); } int pprint(char *fmt, ...) { char buf[2*PRINTSIZE]; Chan *c; int n; c = u->fd[2]; if(c==0 || (c->mode!=OWRITE && c->mode!=ORDWR)) return; n = sprint(buf, "%s %d: ", u->p->text, u->p->pid); n = donprint(buf+n, buf+sizeof(buf), fmt, (&fmt+1)) - buf; qlock(c); if(waserror()){ qunlock(c); return; } (*devtab[c->type].write)(c, buf, n); c->offset += n; qunlock(c); return n; } void prflush(void) { while(printq.printing) delay(100); } void echo(int c) { char ch; /* * ^t hack BUG */ if(c == 0x14) DEBUG(); if(c == 0x15) putstrn("^U\n", 3); else{ ch = c; putstrn(&ch, 1); } } /* * Put character into read queue at interrupt time. * Always called splhi from proc 0. */ void kbdchar(int c) { if(c == '\r') c = '\n'; echo(c); *kbdq.in++ = c; if(kbdq.in == kbdq.buf+sizeof(kbdq.buf)) kbdq.in = kbdq.buf; if(c=='\n' || c==0x04) wakeup(&kbdq.r); } int consactive(void) { return printq.printing; } /* * I/O interface */ enum{ Qdir, Qcons, Qcputime, Qnull, Qpgrpid, Qpid, Qppid, Qtime, Quser, }; Dirtab consdir[]={ "cons", Qcons, 0, 0600, "cputime", Qcputime, 72, 0600, "null", Qnull, 0, 0600, "pgrpid", Qpgrpid, 12, 0600, "pid", Qpid, 12, 0600, "ppid", Qppid, 12, 0600, "time", Qtime, 12, 0600, "user", Quser, 0, 0600, }; #define NCONS (sizeof consdir/sizeof(Dirtab)) ulong boottime; /* seconds since epoch at boot */ long seconds(void) { return boottime + MACHP(0)->ticks*MS2HZ/1000; } int readnum(ulong off, char *buf, ulong n, ulong val, int size) { char tmp[64]; Op op = (Op){ tmp, tmp+sizeof(tmp), &val, size-1, 0, FUNSIGN|FLONG }; numbconv(&op, 10); tmp[size-1] = ' '; off %= size; if(off+n > size) n = size-off; memcpy(buf, tmp+off, n); return n; } int readstr(ulong off, char *buf, ulong n, char *str) { int size; size = strlen(str); off %= size; if(off+n > size) n = size-off; memcpy(buf, str+off, n); return n; } void consreset(void) { } void consinit(void) { } Chan* consattach(char *spec) { return devattach('c', spec); } Chan* consclone(Chan *c, Chan *nc) { return devclone(c, nc); } int conswalk(Chan *c, char *name) { return devwalk(c, name, consdir, NCONS, devgen); } void consstat(Chan *c, char *dp) { devstat(c, dp, consdir, NCONS, devgen); } Chan* consopen(Chan *c, int omode) { if(c->qid==Quser && omode==(OWRITE|OTRUNC)){ /* truncate? */ if(strcmp(u->p->pgrp->user, "bootes") == 0) /* BUG */ u->p->pgrp->user[0] = 0; else error(0, Eperm); } return devopen(c, omode, consdir, NCONS, devgen); } void conscreate(Chan *c, char *name, int omode, ulong perm) { error(0, Eperm); } void consclose(Chan *c) { } long consread(Chan *c, void *buf, long n) { int ch, i, j, k; ulong l; uchar *out; char *cbuf = buf; char *user; int userlen; char tmp[6*NUMSIZE]; if(n <= 0) return n; switch(c->qid&~CHDIR){ case Qdir: return devdirread(c, buf, n, consdir, NCONS, devgen); case Qcons: qlock(&kbdq); while(!cangetc(&lineq)){ sleep(&kbdq.r, (int(*)(void*))isbrkc, &kbdq); do{ ch = getc(&kbdq); switch(ch){ case '\b': if(lineq.in != lineq.out){ if(lineq.in == lineq.buf) lineq.in = lineq.buf+sizeof(lineq.buf); lineq.in--; } break; case 0x15: lineq.in = lineq.out; break; default: *lineq.in++ = ch; if(lineq.in == lineq.buf+sizeof(lineq.buf)) lineq.in = lineq.buf; } }while(ch!='\n' && ch!=0x04); } i = 0; while(n>0){ ch = getc(&lineq); if(ch == 0x04 || ch == -1) break; i++; *cbuf++ = ch; --n; } qunlock(&kbdq); return i; case Qcputime: k = c->offset % sizeof tmp; if(k+n > sizeof tmp) n = sizeof tmp - k; /* easiest to format in a separate buffer and copy out */ for(i=0; i<6 && NUMSIZE*ip->time[i]; if(i == TReal) l = MACHP(0)->ticks - l; l *= MS2HZ; readnum(0, tmp+NUMSIZE*i, NUMSIZE, l, NUMSIZE); } memcpy(buf, tmp+k, n); return n; case Qpgrpid: return readnum(c->offset, buf, n, u->p->pgrp->pgrpid, NUMSIZE); case Qpid: return readnum(c->offset, buf, n, u->p->pid, NUMSIZE); case Qppid: return readnum(c->offset, buf, n, u->p->parentpid, NUMSIZE); case Qtime: return readnum(c->offset, buf, n, boottime+MACHP(0)->ticks/(1000/MS2HZ), 12); case Quser: return readstr(c->offset, buf, n, u->p->pgrp->user); case Qnull: return 0; default: panic("consread %lux\n", c->qid); return 0; } } long conswrite(Chan *c, void *va, long n) { char cbuf[64]; char buf[256]; long l, m; char *a = va; switch(c->qid){ case Qcons: /* * Damn. Can't page fault in putstrn, so copy the data locally. */ l = n; while(l > 0){ m = l; if(m > sizeof buf) m = sizeof buf; memcpy(buf, a, m); putstrn(a, m); a += m; l -= m; } break; case Qtime: if(n<=0 || boottime!=0) /* only one write please */ return 0; if(n >= sizeof cbuf) n = sizeof cbuf - 1; memcpy(cbuf, a, n); cbuf[n-1] = 0; boottime = strtoul(a, 0, 0); break; case Quser: if(u->p->pgrp->user[0]) /* trying to overwrite /dev/user */ error(0, Eperm); if(c->offset >= NAMELEN-1) return 0; if(c->offset+n >= NAMELEN-1) n = NAMELEN-1 - c->offset; memcpy(u->p->pgrp->user+c->offset, a, n); u->p->pgrp->user[c->offset+n] = 0; break; case Qcputime: case Qpgrpid: case Qpid: case Qppid: error(0, Eperm); case Qnull: break; default: error(0, Egreg); } return n; } void consremove(Chan *c) { error(0, Eperm); } void conswstat(Chan *c, char *dp) { error(0, Eperm); } void conserrstr(Error *e, char *buf) { rooterrstr(e, buf); } void consuserstr(Error *e, char *buf) { strcpy(buf, u->p->pgrp->user); } typedef struct Incon{ unsigned char cdata; unsigned char u0; unsigned char cstatus; unsigned char u1; unsigned char creset; unsigned char u2; unsigned char csend; unsigned char u3; unsigned short data_cntl; /* data is high byte, cntl is low byte */ unsigned char status; unsigned char u5; unsigned char reset; unsigned char u6; unsigned char send; unsigned char u7; }Incon; inconintr(Ureg *ur) { int x; x = ((Incon*)0x40700000)->status; } . ## diffname gnot/devcons.c 1990/0312 ## diff -e /n/bootesdump/1990/03091/sys/src/9/68020/devcons.c /n/bootesdump/1990/0312/sys/src/9/68020/devcons.c 520a */ . 515a /* . 383c k = c->offset; if(k >= sizeof tmp) return 0; . 264c if(off >= size) return 0; . 251c if(off >= size) return 0; . ## diffname gnot/devcons.c 1990/0321 ## diff -e /n/bootesdump/1990/0312/sys/src/9/68020/devcons.c /n/bootesdump/1990/0321/sys/src/9/68020/devcons.c 198a } void kbdrepeat(int rep) { if(rep) kbdq.repeat = 1; else kbdq.repeat = 0; } void kbdclock(void) { if(kbdq.repeat==2 && (++kbdq.count&1)) kbdchar(kbdq.c); . 190a if(kbdq.repeat == 1){ kbdq.c = c; kbdq.count = 0; kbdq.repeat = 2; } . 187a . 155a poperror(); . 151c return 0; . 145c return 0; . 35a struct{ IOQ; /* qlock to getc; interrupt putc's */ int c; int repeat; int count; }kbdq; . 33d ## diffname gnot/devcons.c 1990/0515 ## diff -e /n/bootesdump/1990/0321/sys/src/9/68020/devcons.c /n/bootesdump/1990/0515/sys/src/9/68020/devcons.c 463a case Qrcons: . 404c if(ch==-1 || (raw.ref==0 && ch==0x04)) . 402c while(n > 0){ . 399c unlock(&lineq); }while(raw.ref==0 && ch!='\n' && ch!=0x04); . 397c lineq.in = lineq.buf; . 393a Default: . 382a if(raw.ref){ unlock(&lineq); goto Default; } . 381a lock(&lineq); . 376a case Qrcons: . 357a if(c->qid == Qrcons) decref(&raw); . 345a if(c->qid == Qrcons) if(incref(&raw) == 0){ lock(&lineq); while((ch=getc(&kbdq)) != -1){ *lineq.in++ = ch; if(lineq.in == lineq.buf+sizeof(lineq.buf)) lineq.in = lineq.buf; } unlock(&lineq); } . 338a int ch; . 257a "rcons", Qrcons, 0, 0600, . 246a Qrcons, . 210c if(raw.ref || c=='\n' || c==0x04) . 182a if(raw.ref) return; . 90a if(raw.ref) return 1; . 41a Ref raw; /* whether kbd i/o is raw (rcons is open) */ . 33c IOQ lineq; . ## diffname gnot/devcons.c 1990/06111 ## diff -e /n/bootesdump/1990/0515/sys/src/9/68020/devcons.c /n/bootesdump/1990/06111/sys/src/9/68020/devcons.c 470c return readnum(c->offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), 12); . 454c l = TK2MS(l); . 277c return boottime + TK2SEC(MACHP(0)->ticks); . 157c n = doprint(buf+n, buf+sizeof(buf), fmt, (&fmt+1)) - buf; . 141c n = doprint(buf+7, buf+sizeof(buf), fmt, (&fmt+1)) - buf; . 129c n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf; . 120c return doprint(s, s+PRINTSIZE, fmt, (&fmt+1)) - s; . ## diffname gnot/devcons.c 1990/0617 ## diff -e /n/bootesdump/1990/06111/sys/src/9/68020/devcons.c /n/bootesdump/1990/0617/sys/src/9/68020/devcons.c 401a if(waserror()){ qunlock(&kbdq); nexterror(); } . 190a if(c == 0x16) dumpqueues(); . ## diffname gnot/devcons.c 1990/0619 ## diff -e /n/bootesdump/1990/0617/sys/src/9/68020/devcons.c /n/bootesdump/1990/0619/sys/src/9/68020/devcons.c 380c if(c->qid==Qrcons && (c->flag&COPEN)) . ## diffname gnot/devcons.c 1990/0629 ## diff -e /n/bootesdump/1990/0619/sys/src/9/68020/devcons.c /n/bootesdump/1990/0629/sys/src/9/68020/devcons.c 574,592d 515a case Qrs232: qlock(&rs232oq); l = n; while(--l >= 0) putc(&rs232oq, *a++); splhi(); if(rs232oq.state == 0){ rs232oq.state = 1; duartstartrs232o(); } spllo(); qunlock(&rs232oq); break; . 448a case Qrs232: qlock(&rs232iq); if(waserror()){ qunlock(&rs232iq); nexterror(); } while(!cangetc(&rs232iq)) sleep(&rs232iq.r, (int(*)(void*))cangetc, &rs232iq); for(i=0; iin++ = c; if(q->in == q->buf+sizeof(q->buf)) q->in = q->buf; } . 58a lock(&rs232iq); /* allocate lock */ unlock(&rs232iq); lock(&rs232oq); /* allocate lock */ unlock(&rs232oq); . 52a rs232iq.in = rs232iq.buf; rs232iq.out = rs232iq.buf; rs232oq.in = rs232oq.buf; rs232oq.out = rs232oq.buf; . 33a IOQ rs232iq; IOQ rs232oq; . 20c #define NQ 1024 . ## diffname gnot/devcons.c 1990/0702 ## diff -e /n/bootesdump/1990/0629/sys/src/9/68020/devcons.c /n/bootesdump/1990/0702/sys/src/9/68020/devcons.c 206,207d ## diffname gnot/devcons.c 1990/0707 ## diff -e /n/bootesdump/1990/0702/sys/src/9/68020/devcons.c /n/bootesdump/1990/0707/sys/src/9/68020/devcons.c 583d 576,581c while(--l >= 0) { while (putc(&rs232oq, *a) < 0) sleep(&rs232oq.r, (int(*)(void*))canputc, &rs232oq); a++; if(rs232oq.state == 0){ splhi(); if(rs232oq.state == 0){ rs232oq.state = 1; duartstartrs232o(); } spllo(); } . 540a case Qklog: qlock(&klogq); if(waserror()){ qunlock(&klogq); nexterror(); } while(!cangetc(&klogq)) sleep(&klogq.r, (int(*)(void*))cangetc, &klogq); for(i=0; i=ntab) return -1; tab += i; devdir(c, tab->qid, tab->name, tab->length, tab->perm, dp); switch(dp->qid){ case Qrs232: dp->length = cangetc(&rs232iq); break; } return 1; } . 310a "klog", Qklog, 0, 0400, . 297a Qklog, . 273a wakeup(&rs232oq.r); . 260,262c putc(&rs232iq, c); . 207c if(c == 0x18) mntdump(); . 205c if(c == 0x16) . 151a int kprint(char *fmt, ...) { char buf[PRINTSIZE]; int n; n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf; putstrk(buf, n); return n; } . 134a void putstrk(char *str, long n) { int s; s = splhi(); lock(&klogq.put); while(--n >= 0){ *klogq.in++ = *str++; if(klogq.in == klogq.buf+sizeof(klogq.buf)) klogq.in = klogq.buf; } unlock(&klogq.put); splx(s); wakeup(&klogq.r); } . 130,132c uchar *nextin; if(q->in >= &q->buf[sizeof(q->buf)-1]) nextin = q->buf; else nextin = q->in+1; if(nextin == q->out) return -1; *q->in = c; q->in = nextin; return 0; . 127c int . 97a canputc(IOQ *q) { return sizeof(q->buf)-cangetc(q)-1; } int . 94c int n = q->in - q->out; if (n < 0) n += sizeof(q->buf); return n; . 68a lock(&klogq); /* allocate lock */ unlock(&klogq); lock(&klogq.put); /* allocate lock */ unlock(&klogq.put); . 58a klogq.in = klogq.buf; klogq.out = klogq.buf; . 37a IOQ; Lock put; }klogq; struct{ . ## diffname gnot/devcons.c 1990/0808 ## diff -e /n/bootesdump/1990/0707/sys/src/9/68020/devcons.c /n/bootesdump/1990/0808/sys/src/9/68020/devcons.c 675a qunlock(&rs232oq); break; case Qrs232ctl: qlock(&rs232oq); if(waserror()){ qunlock(&rs232oq); nexterror(); } if(n>2 && noffset, buf, n, TK2MS(MACHP(0)->ticks), NUMSIZE); case Qclock: k = c->offset; if(k >= 2*NUMSIZE) return 0; if(k+n > 2*NUMSIZE) n = 2*NUMSIZE - k; readnum(0, tmp, NUMSIZE, MACHP(0)->ticks, NUMSIZE); readnum(0, tmp+NUMSIZE, NUMSIZE, HZ, NUMSIZE); memcpy(buf, tmp+k, n); return n; . 609c return readnum(c->offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), NUMSIZE); . 575a poperror(); . 570c sleep(&rs232iq.r, cangetc, &rs232iq); . 523c sleep(&kbdq.r, isbrkc, &kbdq); . 358,369c "cons", Qcons, 0, 0600, "cputime", Qcputime, 6*NUMSIZE, 0600, "null", Qnull, 0, 0600, "pgrpid", Qpgrpid, NUMSIZE, 0600, "pid", Qpid, NUMSIZE, 0600, "ppid", Qppid, NUMSIZE, 0600, "rcons", Qrcons, 0, 0600, "rs232", Qrs232, 0, 0600, "rs232ctl", Qrs232ctl, 0, 0600, "time", Qtime, NUMSIZE, 0600, "user", Quser, 0, 0600, "klog", Qklog, 0, 0400, "msec", Qmsec, NUMSIZE, 0400, "clock", Qclock, 2*NUMSIZE, 0400, . 354a Qmsec, Qclock, . 119a IOQ *q = (IOQ *)arg; . 118c isbrkc(void *arg) . 113a IOQ *q = (IOQ *)arg; . 112c canputc(void *arg) . 104a IOQ *q = (IOQ *)arg; . 103c cangetc(void *arg) . 20c #define NQ 2048 . ## diffname gnot/devcons.c 1990/0825 ## diff -e /n/bootesdump/1990/08101/sys/src/9/68020/devcons.c /n/bootesdump/1990/0825/sys/src/9/68020/devcons.c 290,291d ## diffname gnot/devcons.c 1990/0830 ## diff -e /n/bootesdump/1990/0825/sys/src/9/68020/devcons.c /n/bootesdump/1990/0830/sys/src/9/68020/devcons.c 720a strncpy(buf, a, n); buf[n] = 0; l = strtoul(buf+1, 0, 0); switch(buf[0]){ case 'B': duartbaud(l); break; case 'D': duartdtr(l); break; case 'K': duartbreak(l); break; default: error(0, Ebadarg); } . 715,719c if(n<=2 || n>=sizeof buf) . 586c if(c->offset) return 0; *(char *)buf = duartinputport(); return 1; . ## diffname gnot/devcons.c 1990/0831 ## diff -e /n/bootesdump/1990/0830/sys/src/9/68020/devcons.c /n/bootesdump/1990/0831/sys/src/9/68020/devcons.c 792a } /* * rs232 stream routines */ static void rs232output(Rs232 *r) { int next; Queue *q; Block *bp; qlock(&r->outlock); q = r->wq; /* * free emptied blocks */ for(; r->out.f != r->out.r; r->out.f = NEXT(r->out.f)){ freeb(r->out.bp[r->out.f]); r->out.bp[r->out.f] = 0; } /* * stage new blocks */ bp = getq(q); for(next = NEXT(r->out.w); bp && next!=r->out.r; next = NEXT(next)){ r->out.bp[r->out.w] = bp; bp = getq(q); r->out.w = next; } /* * start output */ if(r->txenabled == 0){ r->txenabled = 1; duartstartrs232o(); } qunlock(&r->outlock); } static void rs232input(Rs232 *r) { Queue *q; char c; Block *bp; q = RD(r->wq); bp = 0; while((c = getc(&r->in)) >= 0){ if(bp == 0){ bp->flags |= S_DELIM; bp = allocb(64); } *bp->wptr++ = c; if(bp->wptr == bp->lim){ if(QFULL(q->next)) freeb(bp); else PUTNEXT(q, bp); bp = 0; } } if(bp){ if(QFULL(q->next)) freeb(bp); else PUTNEXT(q, bp); } } static int rs232stuff(void *arg) { Rs232 *r; r = arg; return (r->in.in != r->in.out) || (r->out.r != r->out.w) || (r->out.f != r->out.r); } static void rs232kproc(void *a) { Rs232 *r; r = a; for(;;){ qlock(r); if(r->wq != 0){ rs232output(r); rs232input(r); } qunlock(r); sleep(&r->r, rs232stuff, r); } } static void rs232open(Queue *q, Stream *c) { Rs232 *r; r = &rs232; RD(q)->ptr = r; WR(q)->ptr = r; r->wq = WR(q); if(r->kstarted == 0){ r->in.in = r->in.out = r->in.buf; kproc("rs232", rs232kproc, r); r->kstarted = 1; } } static void rs232close(Queue *q) { Rs232 *r; r = q->ptr; qlock(r); r->wq = 0; qunlock(r); } static void rs232oput(Queue *q, Block *bp) { if(bp->rptr == bp->wptr) freeb(bp); else putq(q, bp); rs232output(q->ptr); } static void rs232timer(Alarm *a) { Rs232 *r; r = a->arg; cancel(a); r->a = 0; wakeup(&r->r); } void rs232ichar(int c) { Rs232 *r; r = &rs232; putc(&r->in, c); if(r->a == 0) alarm(125, rs232timer, r); } int getrs232o(void) { int c; Rs232 *r; Block *bp; r = &rs232; if(r->out.r == r->out.w){ r->txenabled = 0; return -1; } bp = r->out.bp[r->out.r]; c = *bp->rptr++; if(bp->rptr >= bp->wptr){ r->out.r = NEXT(r->out.r); if(r->out.r==r->out.w || NEXT(r->out.r)==r->out.w) wakeup(&r->r); } return c; . 733c qunlock(&rs232); . 715c qunlock(&rs232); . 713c qlock(&rs232); . 689,709c n = streamwrite(c, va, n, 1); . 569,583c return streamread(c, buf, n); . 500a if(c->qid == Qrs232) streamclose(c); . 486a if(c->qid == Qrs232) streamopen(c, &rs232info); . 462c switch(c->qid){ case Qrs232: streamstat(c, dp, "rs232"); break; default: devstat(c, dp, consdir, NCONS, consgen); break; } . 386,389d 357a Qrs232 = STREAMQID(1, Sdataqid), . 351d 322,333d 314,320d 72,75d 60,63d 50a /* * rs232 stream module */ typedef struct Rs232 Rs232; typedef struct IOBQ IOBQ; #define NBQ 4 struct IOBQ{ Block *bp[NBQ]; int w; int r; int f; }; #define NEXT(x) ((x+1)%NBQ) struct Rs232{ QLock; QLock outlock; IOQ in; IOBQ out; int kstarted; /* true if kproc started */ Queue *wq; Alarm *a; /* alarm for waking the rs232 kernel process */ int txenabled; Rendez r; }; Rs232 rs232; static void rs232output(Rs232*); static void rs232input(Rs232*); static void rs232timer(Alarm*); static void rs232kproc(void*); static void rs232open(Queue*, Stream*); static void rs232close(Queue*); static void rs232oput(Queue*, Block*); Qinfo rs232info = { nullput, rs232oput, rs232open, rs232close, "rs232" }; . 34,35d 18,19d 10a typedef struct IOQ IOQ; . ## diffname gnot/devcons.c 1990/0901 ## diff -e /n/bootesdump/1990/0831/sys/src/9/68020/devcons.c /n/bootesdump/1990/0901/sys/src/9/68020/devcons.c 946c r->started = 0; . 940c uchar c; . 936a /* * called by output interrupt. runs splhi */ . 932,934c if(putc(&r->in, c) < 0) screenputc('^'); /* * pass upstream within 1/16 second */ if(r->a==0) r->a = alarm(64, rs232timer, r); . 925a /* * called by input interrupt. runs splhi */ . 830a bp->flags |= S_DELIM; . 829d 822c int c; . 814a spllo(); . 811,812c splhi(); if(r->started == 0){ r->started = 1; . 809c * start output, the spl's sync with interrupt level * this wouldn't work on a multi-processor . 804a if(bp == 0) break; r->out.bp[r->out.w] = bp; . 801,803c for(next = NEXT(r->out.w); next!=r->out.r; next = NEXT(next)){ . 72c int started; . 55c #define NBQ 6 . ## diffname gnot/devcons.c 1990/0905 ## diff -e /n/bootesdump/1990/0901/sys/src/9/68020/devcons.c /n/bootesdump/1990/0905/sys/src/9/68020/devcons.c 804a if(bp->type == M_CTL){ while(!rs232empty(r)) sleep(&r->r, rs232empty, r); l = strtoul((char *)(bp->rptr+1), 0, 0); switch(*bp->rptr){ case 'B': duartbaud(l); break; case 'D': duartdtr(l); break; case 'K': duartbreak(l); break; } freeb(bp); break; } . 801c for(next = NEXT(r->out.w); next != r->out.r; next = NEXT(next)){ . 799a * * if we run into a control block, wait till the queue * is empty before doing the control. . 791,798d 785a long l; . 779a static int rs232empty(void *a) { Rs232 *r; r = a; return r->out.w == r->out.r; } . 778a * * A kernel process, rs232kproc, stages blocks to be output and * packages input bytes into stream blocks to send upstream. * The process is awakened whenever the interrupt side is almost * out of bytes to xmit or 1/16 second has elapsed since a byte * was input. . 694,717d 690a case Qrs232ctl: . 500a break; } . 499c break; case Qrs232: case Qrs232ctl: . 482,489c switch(c->qid){ case Quser: if(omode==(OWRITE|OTRUNC)){ /* truncate? */ if(strcmp(u->p->pgrp->user, "bootes") == 0) /* BUG */ u->p->pgrp->user[0] = 0; else error(0, Eperm); } break; case Qrcons: . 365a Qrs232ctl = STREAMQID(1, Sctlqid), . 360d ## diffname gnot/devcons.c 1990/0911 ## diff -e /n/bootesdump/1990/0905/sys/src/9/68020/devcons.c /n/bootesdump/1990/0911/sys/src/9/68020/devcons.c 955,956c if(r->a==0){ if(r->delay == 0) wakeup(&r->r); else r->a = alarm(r->delay, rs232timer, r); } . 922c if(bp->rptr >= bp->wptr) . 810c case 'k': duartbreak(l); break; case 'W': case 'w': if(l>=0 && l<1000) r->delay = l; break; . 808c case 'd': duartdtr(l); break; . 806c case 'b': duartbaud(l); break; . 796c for(next = NEXT(r->out.w); next != r->out.f; next = NEXT(next)){ . 790a * free old blocks */ for(next = r->out.f; next != r->out.r; next = NEXT(next)){ freeb(r->out.bp[next]); r->out.bp[next] = 0; } r->out.f = next; /* . 293c if(c == 0x1A) . 72a int delay; /* time between character input and waking kproc */ . ## diffname gnot/devcons.c 1990/0914 ## diff -e /n/bootesdump/1990/0911/sys/src/9/68020/devcons.c /n/bootesdump/1990/0914/sys/src/9/68020/devcons.c 107c lock(&klogq.put); /* allocate lock */ . 100a rs232.in.in = rs232.in.buf; rs232.in.out = rs232.in.buf; . ## diffname gnot/devcons.c 1990/0918 ## diff -e /n/bootesdump/1990/0914/sys/src/9/68020/devcons.c /n/bootesdump/1990/0918/sys/src/9/68020/devcons.c 292,297c if(ctrlt == 2){ ctrlt = 0; switch(c){ case 0x14: break; /* pass it on */ case 'p': DEBUG(); return; case 'q': dumpqueues(); return; case 'm': mntdump(); return; } }else if(c == 0x14){ ctrlt++; return; } ctrlt = 0; . 287a static int ctrlt; . ## diffname gnot/devcons.c 1990/1024 ## diff -e /n/bootesdump/1990/0918/sys/src/9/68020/devcons.c /n/bootesdump/1990/1024/sys/src/9/68020/devcons.c 540c if(c->stream) . ## diffname gnot/devcons.c 1990/11151 ## diff -e /n/bootesdump/1990/1024/sys/src/9/68020/devcons.c /n/bootesdump/1990/11151/sys/src/9/68020/devcons.c 86c Qinfo rs232info = { nullput, rs232oput, rs232open, rs232close, "rs232" }; . ## diffname gnot/devcons.c 1990/11211 ## diff -e /n/bootesdump/1990/11151/sys/src/9/68020/devcons.c /n/bootesdump/1990/11211/sys/src/9/68020/devcons.c 771,783c error(Eperm); . 765c error(Eperm); . 757c error(Egreg); . 752c error(Eperm); . 739c error(Eperm); . 704c switch(c->qid.path){ . 564c switch(c->qid.path&~CHDIR){ . 545c if(c->qid.path==Qrcons && (c->flag&COPEN)) . 539c error(Eperm); . 514c error(Eperm); . 507c switch(c->qid.path){ . 492c switch(c->qid.path){ . 395,408c "cons", {Qcons}, 0, 0600, "cputime", {Qcputime}, 6*NUMSIZE, 0600, "null", {Qnull}, 0, 0600, "pgrpid", {Qpgrpid}, NUMSIZE, 0600, "pid", {Qpid}, NUMSIZE, 0600, "ppid", {Qppid}, NUMSIZE, 0600, "rcons", {Qrcons}, 0, 0600, "rs232", {Qrs232}, 0, 0600, "rs232ctl", {Qrs232ctl}, 0, 0600, "time", {Qtime}, NUMSIZE, 0600, "user", {Quser}, 0, 0600, "klog", {Qklog}, 0, 0400, "msec", {Qmsec}, NUMSIZE, 0400, "clock", {Qclock}, 2*NUMSIZE, 0400, . ## diffname gnot/devcons.c 1990/1212 ## diff -e /n/bootesdump/1990/11211/sys/src/9/68020/devcons.c /n/bootesdump/1990/1212/sys/src/9/68020/devcons.c 313a case 'i': incontoggle(); return; . ## diffname gnot/devcons.c 1990/1219 ## diff -e /n/bootesdump/1990/1212/sys/src/9/68020/devcons.c /n/bootesdump/1990/1219/sys/src/9/68020/devcons.c 337d ## diffname gnot/devcons.c 1991/0112 ## diff -e /n/bootesdump/1990/1219/sys/src/9/68020/devcons.c /n/bootesdump/1991/0112/sys/src/9/68020/devcons.c 310a case 'r': panic("you asked for it"); break; . ## diffname gnot/devcons.c 1991/0221 ## diff -e /n/bootesdump/1991/0201/sys/src/9/68020/devcons.c /n/bootesdump/1991/0221/sys/src/9/gnot/devcons.c 257a dumpstack(); . ## diffname gnot/devcons.c 1991/0311 ## diff -e /n/bootesdump/1991/0221/sys/src/9/gnot/devcons.c /n/bootesdump/1991/0311/sys/src/9/gnot/devcons.c 118,119d 97a screeninit(); . ## diffname gnot/devcons.c 1991/0318 ## diff -e /n/bootesdump/1991/0311/sys/src/9/gnot/devcons.c /n/bootesdump/1991/0318/sys/src/9/gnot/devcons.c 749c memmove(u->p->pgrp->user+c->offset, a, n); . 737c memmove(cbuf, a, n); . 720c memmove(buf, a, m); . 669c memmove(buf, tmp+k, n); . 644c memmove(buf, tmp+k, n); . 462c memmove(buf, str+off, n); . 448c memmove(buf, tmp+off, n); . ## diffname gnot/devcons.c 1991/0411 ## diff -e /n/bootesdump/1991/0318/sys/src/9/gnot/devcons.c /n/bootesdump/1991/0411/sys/src/9/gnot/devcons.c 747,750c if(offset+n >= NAMELEN-1) n = NAMELEN-1 - offset; memmove(u->p->pgrp->user+offset, a, n); u->p->pgrp->user[offset+n] = 0; . 745c if(offset >= NAMELEN-1) . 702c conswrite(Chan *c, void *va, long n, ulong offset) . 673c return readstr(offset, buf, n, u->p->pgrp->user); . 662c k = offset; . 660c return readnum(offset, buf, n, TK2MS(MACHP(0)->ticks), NUMSIZE); . 657c return readnum(offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), NUMSIZE); . 654c return readnum(offset, buf, n, u->p->parentpid, NUMSIZE); . 651c return readnum(offset, buf, n, u->p->pid, NUMSIZE); . 648c return readnum(offset, buf, n, u->p->pgrp->pgrpid, NUMSIZE); . 631c k = offset; . 625c if(offset) . 557c consread(Chan *c, void *buf, long n, ulong offset) . 279c qunlock(&c->wrl); . 277c (*devtab[c->type].write)(c, buf, n, c->offset); . 274c qunlock(&c->wrl); . 272c qlock(&c->wrl); . ## diffname gnot/devcons.c 1991/0419 ## diff -e /n/bootesdump/1991/0411/sys/src/9/gnot/devcons.c /n/bootesdump/1991/0419/sys/src/9/gnot/devcons.c 493a Chan* consclwalk(Chan *c, char *name) { return devclwalk(c, name); } . ## diffname gnot/devcons.c 1991/0423 ## diff -e /n/bootesdump/1991/0419/sys/src/9/gnot/devcons.c /n/bootesdump/1991/0423/sys/src/9/gnot/devcons.c 1028a r->started = 1; . 1018a wakeup(&r->rempty); . 1008c * called by output interrupt. runs spl5 . 997c * pass upstream within r->delay milliseconds . 957a qlock(&r->outlock); while(!rs232empty(r)) sleep(&r->rempty, rs232empty, r); qunlock(&r->outlock); kprint("rs232close: emptied\n"); rs232output(r); /* reclaim blocks written */ . 956a kprint("rs232close: q=0x%ux\n", q); . 949c }else wakeup(&r->r); /* pick up any input characters */ . 944a kprint("rs232open: q=0x%ux, inuse=%d, type=%d, dev=%d, id=%d\n", q, c->inuse, c->type, c->dev, c->id); . 871,872d 867,869c if(r->started == 0) . 855a poperror(); . 835c sleep(&r->rempty, rs232empty, r); . 833a if(waserror()){ freeb(bp); qunlock(&r->outlock); nexterror(); } . 822a if(q==0){ kprint("rs232output: null q\n"); qunlock(&r->outlock); return; } . 702c panic("consread %lux\n", c->qid.path); . 339a . 295a extern void DEBUG(void), dumpqueues(void), mntdump(void); . 110a rs232.delay = 64; /* msec */ . 74a Rendez rempty; . 72c int started; /* true if output interrupt pending */ . ## diffname gnot/devcons.c 1991/0427 ## diff -e /n/bootesdump/1991/0423/sys/src/9/gnot/devcons.c /n/bootesdump/1991/0427/sys/src/9/gnot/devcons.c 498,503d ## diffname gnot/devcons.c 1991/0514 ## diff -e /n/bootesdump/1991/0427/sys/src/9/gnot/devcons.c /n/bootesdump/1991/0514/sys/src/9/gnot/devcons.c 1010c /*screenputc('^')*/; . 73c int delay; /* between character input and waking kproc */ . ## diffname gnot/devcons.c 1991/0605 ## diff -e /n/bootesdump/1991/0514/sys/src/9/gnot/devcons.c /n/bootesdump/1991/0605/sys/src/9/gnot/devcons.c 781,1047d 764a case Qnoise: consnoise(a, n); break; case Qlights: conslights(a, n); break; case Qsysstat: for(id = 0; id < 32; id++) { if(active.machs & (1<cs = 0; mp->intr = 0; mp->syscall = 0; mp->pfault = 0; mp->tlbfault = 0; mp->tlbpurge = 0; mp->spinlock = 0; } } break; . 731,735d 715a case Qcons: . 714d 711a Mach *mp; int id; . 704a void conslights(char *a, int n) { int l; char line[128]; char *lp; int c; lp = line; while(n--){ *lp++ = c = *a++; if(c=='\n' || n==0 || lp==&line[sizeof(line)-1]) break; } *lp = 0; lights(strtoul(line, 0, 0)); } void consnoise(char *a, int n) { int freq; int duration; char line[128]; char *lp; int c; lp = line; while(n--){ *lp++ = c = *a++; if(c=='\n' || n==0 || lp==&line[sizeof(line)-1]){ *lp = 0; freq = strtoul(line, &lp, 0); while(*lp==' ' || *lp=='\t') lp++; duration = strtoul(lp, &lp, 0); buzz(freq, duration); lp = line; } } } . 700c panic("consread %lux\n", c->qid); . 698a case Qmsec: return readnum(offset, buf, n, TK2MS(MACHP(0)->ticks), NUMSIZE); case Qsysstat: j = 0; for(id = 0; id < 32; id++) { if(active.machs & (1<cs, mp->intr, mp->syscall, mp->pfault, mp->tlbfault, mp->tlbpurge, m->spinlock); } } return readstr(offset, buf, n, xbuf); . 663,664d 661c return readnum(offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), 12); . 625,633d 608a else lineq.in++; . 606,607c *lineq.in = ch; if(lineq.in >= lineq.buf+sizeof(lineq.buf)-1) . 575c return devdirread(c, buf, n, consdir, NCONS, devgen); . 573c switch(c->qid.path & ~CHDIR){ . 569c char tmp[6*NUMSIZE], xbuf[1024]; Mach *mp; . 563c int ch, i, j, k, id; . 559a . 556,557d 542c return devopen(c, omode, consdir, NCONS, devgen); . 537,540d 501,508c devstat(c, dp, consdir, NCONS, devgen); . 495c return devwalk(c, name, consdir, NCONS, devgen); . 422,431d 417a "sysstat", {Qsysstat}, 0, 0600, . 411,412d 405a "lights", {Qlights}, 0, 0600, "noise", {Qnoise}, 0, 0600, . 399,400c Qsysstat, . 388a Qlights, Qnoise, . 379c return printq.in != printq.out; . 372,373c if(kbdq.repeat == 0) return; if(kbdq.repeat==1 && ++kbdq.count>HZ){ kbdq.repeat = 2; kbdq.count = 0; return; } if(++kbdq.count&1) kbdputc(&kbdq, kbdq.c); . 363,366c kbdq.repeat = rep; kbdq.count = 0; . 357a return 0; . 356c if(raw.ref || ch=='\n' || ch==0x04) . 347,353c echo(ch); kbdq.c = ch; *kbdq.in++ = ch; . 343,345c int kbdputc(IOQ *q, int ch) . 317,322d 315c firmware(); . 307a case 'm': mntdump(); return; . 298d 289,290c while(printq.in != printq.out) ; . 261a . 260c for(;;); . 245c klogputs(buf, n); . 177,221d 144,161d 142c isbrkc(KIOQ *q) . 138a wakeup(&klogq.r); . 132,137c lock(&klogq); while(n){ m = &klogq.buf[NQ] - klogq.in; if(m > n) m = n; memmove(klogq.in, str, m); n -= m; str += m; nextin = klogq.in + m; if(nextin >= &klogq.buf[NQ]) klogq.in = klogq.buf; else klogq.in = nextin; } unlock(&klogq); . 129c int s, m; uchar *nextin; . 127c klogputs(char *str, long n) . 124c * Print a string in the kernel log. Ignore overflow. . 101,120c while(n > 0){ if(printq.puts && *str=='\n') (*printq.puts)(&printq, "\r", 1); m = n; t = memchr(str+1, '\n', m-1); if(t) if(t-str < m) m = t - str; if(printq.puts) (*printq.puts)(&printq, str, m); screenputs(str, m); n -= m; str += m; } . 99c int s, c, m; char *t; . 97c putstrn(char *str, int n) . 95a /* * Print a string on the console. Convert \n to \r\n */ . 89,94c initq(&printq); initq(&lineq); initq(&kbdq); initq(&klogq); initq(&mouseq); mouseq.putc = mouseputc; } . 52,87c void printinit(void) . 50c * init the queues and set the output routine . 20,46d 13,18c IOQ lineq; /* lock to getc; interrupt putc's */ IOQ printq; IOQ mouseq; KIOQ kbdq; . 11c struct { IOQ; /* lock to klogputs */ QLock; /* qlock to getc */ } klogq; . ## diffname gnot/devcons.c 1991/0608 # deleted ## diff -e /n/bootesdump/1991/0605/sys/src/9/gnot/devcons.c /n/bootesdump/1991/0608/sys/src/9/gnot/devcons.c 1,715d