From 3afa7e7b0372d3635892d107eb969e31e68ef616 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 6 Mar 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-03-06 --- port/devcons.c | 4 -- port/devenv.c | 1 + port/devlance.c | 153 ++++++++++++++++++++++++++++++------------------ port/devmnt.c | 13 +++- power/dat.h | 13 ++++ power/devbit.c | 71 ++++++++++------------ 6 files changed, 151 insertions(+), 104 deletions(-) diff --git a/port/devcons.c b/port/devcons.c index 8bb8264991a72aca398e73dc2e1c56279cee32b4..2e7f51d4766b3536a12cf8d9cca29b58bc152384 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -238,10 +238,6 @@ echo(int c) */ if(c == 0x14) DEBUG(); - else if(c == 0x0c) - LANCEDEBUG(); - else if(c == 0x02) - LANCEPRDEBQ(); if(c == 0x15) putstrn("^U\n", 3); else{ diff --git a/port/devenv.c b/port/devenv.c index ad30d487f5712f88eff2b912e27affb7c6a3eaf4..1d6d78ba85e288b6b28d075847a734f383d5d22d 100644 --- a/port/devenv.c +++ b/port/devenv.c @@ -299,6 +299,7 @@ envopen(Chan *c, int omode) if(waserror()){ unlock(e); unlock(&envalloc); + unlock(pg); nexterror(); } if(e->pgref == 0) diff --git a/port/devlance.c b/port/devlance.c index 0c8abf3d2b05650bcb0f0f5c2222890209512cc8..3538a79108c7b49d01921e73751ccfca0cc283e1 100644 --- a/port/devlance.c +++ b/port/devlance.c @@ -11,15 +11,18 @@ */ enum { Ntypes= 8, /* max number of ethernet packet types */ + Ndir= Ntypes+1, /* entries in top level directory */ LogNrrb= 7, /* log of number of receive buffers */ Nrrb= (1<ticks) + /* * Communication with the lance is via a transmit and receive ring of * message descriptors. The Initblock contains pointers to and sizes of @@ -101,12 +104,16 @@ typedef struct { uchar type[2]; uchar data[40]; } Dpkt; +typedef struct { + ulong ticks; + char tag; + int len; + Dpkt p; +} Trace; typedef struct { Lock; int next; - char *tag[Ndpkt]; - int len[Ndpkt]; - Dpkt p[Ndpkt]; + Trace t[Ndpkt]; } Debqueue; /* @@ -136,7 +143,6 @@ typedef struct { Ethertype e[Ntypes]; int debug; - int prdebug; int kstarted; Debqueue dq; } Lance; @@ -215,26 +221,32 @@ void lancekproc(void *); /* * print a packet preceded by a message */ -printpacket(char *tag, Pkt *p, int len) +sprintpacket(char *buf, Trace *t) { - print("%s: %d d(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)s(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)t(%ux %ux)d(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)\n", - tag, len, - p->d[0], p->d[1], p->d[2], p->d[3], p->d[4], p->d[5], - p->s[0], p->s[1], p->s[2], p->s[3], p->s[4], p->s[5], p->type[0], p->type[1], - p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5], - p->data[6], p->data[7], p->data[8], p->data[9], p->data[10], p->data[11]); + Dpkt *p = &t->p; + + sprint(buf, "%c: %.8ud %.4d d(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)s(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)t(%.2ux %.2ux)d(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)\n", + t->tag, t->ticks, t->len, + p->d[0], p->d[1], p->d[2], p->d[3], p->d[4], p->d[5], + p->s[0], p->s[1], p->s[2], p->s[3], p->s[4], p->s[5], p->type[0],p->type[1], + p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5], + p->data[6], p->data[7], p->data[8], p->data[9], p->data[10], p->data[11]); } /* * save a message in a circular queue for later debugging */ void -lancedebq(char *tag, Pkt *p, int len) +lancedebq(char tag, Pkt *p, int len) { + Trace *t; + lock(&l.dq); - l.dq.tag[l.dq.next] = tag; - l.dq.len[l.dq.next] = len; - memcpy(&l.dq.p[l.dq.next], p, sizeof(Dpkt)); + t = &l.dq.t[l.dq.next]; + t->ticks = NOW; + t->tag = tag; + t->len = len; + memcpy(&(t->p), p, sizeof(Dpkt)); l.dq.next = (l.dq.next+1) % Ndpkt; unlock(&l.dq); } @@ -351,7 +363,7 @@ lanceoput(Queue *q, Block *bp ) len = 0; while(bp = getq(q)){ if(sizeof(Pkt) - len >= (n = bp->wptr - bp->rptr)){ - slowcpy(((uchar *)p)+len, bp->rptr, n); + memcpy(((uchar *)p)+len, bp->rptr, n); len += n; } else print("no room damn it\n"); @@ -373,7 +385,7 @@ lanceoput(Queue *q, Block *bp ) if(len < 60) len = 60; - lancedebq("out", p, len); + lancedebq('o', p, len); /* * set up the ring descriptor and hand to lance @@ -392,9 +404,10 @@ lanceoput(Queue *q, Block *bp ) * lance directory */ enum { - Lchanqid = 1 + Lchanqid = 1, + Ltraceqid = 2, }; -Dirtab lancedir[Ntypes]; +Dirtab lancedir[Ndir]; /* @@ -549,6 +562,10 @@ lanceinit(void) lancedir[i].length = 0; lancedir[i].perm = 0600; } + strcpy(lancedir[Ntypes].name, "trace"); + lancedir[Ntypes].qid = Ltraceqid; + lancedir[Ntypes].length = 0; + lancedir[Ntypes].perm = 0600; } Chan* @@ -580,7 +597,7 @@ int lancewalk(Chan *c, char *name) { if(c->qid == CHDIR) - return devwalk(c, name, lancedir, Ntypes, devgen); + return devwalk(c, name, lancedir, Ndir, devgen); else return devwalk(c, name, 0, 0, streamgen); } @@ -589,7 +606,7 @@ void lancestat(Chan *c, char *dp) { if(c->qid == CHDIR) - devstat(c, dp, lancedir, Ntypes, devgen); + devstat(c, dp, lancedir, Ndir, devgen); else devstat(c, dp, 0, 0, streamgen); } @@ -602,11 +619,16 @@ lanceopen(Chan *c, int omode) { extern Qinfo nonetinfo; - if(c->qid == CHDIR){ + switch(c->qid){ + case CHDIR: + case Ltraceqid: if(omode != OREAD) error(0, Eperm); - }else + break; + default: streamopen(c, &lanceinfo); + break; + } c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; @@ -623,17 +645,60 @@ void lanceclose(Chan *c) { /* real closing happens in lancestclose */ - if(c->qid != CHDIR) + switch(c->qid){ + case CHDIR: + case Ltraceqid: + break; + default: streamclose(c); + break; + } +} + +static long +lancetraceread(Chan *c, void *a, long n) +{ + char buf[512]; + long rv; + int i; + char *ca = a; + int offset; + Trace *t; + int plen; + + rv = 0; + sprintpacket(buf, l.dq.t); + plen = strlen(buf); + offset = c->offset % plen; + for(t = &l.dq.t[c->offset/plen]; n && t < &l.dq.t[Ndpkt]; t++){ + if(t->tag == 0) + break; + lock(&l.dq); + sprintpacket(buf, t); + unlock(&l.dq); + i = plen - offset; + if(i > n) + i = n; + memcpy(ca, buf + offset, i); + n -= i; + ca += i; + rv += i; + offset = 0; + } + return rv; } long lanceread(Chan *c, void *a, long n) { - if(c->qid == CHDIR) - return devdirread(c, a, n, lancedir, Ntypes, devgen); - else + switch(c->qid){ + case CHDIR: + return devdirread(c, a, n, lancedir, Ndir, devgen); + case Ltraceqid: + return lancetraceread(c, a, n); + default: return streamread(c, a, n); + } } long @@ -752,7 +817,7 @@ lancekproc(void *arg) p = l.rp[l.rl]; t = (p->type[0]<<8) | p->type[1]; len = m->cntflags - 4; - lancedebq("in", p, len); + lancedebq('i', p, len); for(e = &l.e[0]; e < &l.e[Ntypes]; e++){ if(!canqlock(e)) continue; @@ -779,7 +844,7 @@ lancekproc(void *arg) * The lock on e makes sure the queue is still there. */ bp = allocb(len); - slowcpy(bp->rptr, (uchar *)p, len); + memcpy(bp->rptr, (uchar *)p, len); bp->wptr += len; bp->flags |= S_DELIM; PUTNEXT(e->q, bp); @@ -797,18 +862,6 @@ stage: m->flags = OWN|HADDR(l.rp[l.rc]); l.rc = RSUCC(l.rc); } - if(l.prdebug){ - lock(&l.dq); - i = l.dq.next; - do { - if(l.dq.tag[i]) - printpacket(l.dq.tag[i], (Pkt *)&l.dq.p[i], - l.dq.len[i]); - i = (i+1) % Ndpkt; - } while(i != l.dq.next); - unlock(&l.dq); - l.prdebug = 0; - } sleep(&l.rr, isinput, 0); } } @@ -820,19 +873,3 @@ lanceparity(void) MODEREG->promenet &= ~4; MODEREG->promenet |= 4; } - -void -LANCEDEBUG() -{ - l.debug ^= 1; -} - -/* - * print the debug queue - */ -void -LANCEPRDEBQ() -{ - l.prdebug = 1; - wakeup(&l.rr); -} diff --git a/port/devmnt.c b/port/devmnt.c index 0d7b689eeb24ede701181af7f5489e48282085bb..a899d915a57bdbb92993755dd46d69424e1d5c43 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -554,6 +554,7 @@ mntxmit(Mnt *m, Mnthdr *mh) ulong n; Mntbuf *mbr, *mbw; Chan *mntpt; + int isbit; mbr = mballoc(); mbw = mballoc(); @@ -568,10 +569,15 @@ mntxmit(Mnt *m, Mnthdr *mh) qunlock(m); error(0, Eshutdown); } - qlock(m->msg); + isbit = 0; + if(devchar[m->msg->type] == 'b') + isbit = 1; + if(!isbit) + qlock(m->msg); if(waserror()){ qunlock(m); - qunlock(m->msg); + if(!isbit) + qunlock(m->msg); nexterror(); } if((*devtab[m->msg->type].write)(m->msg, mbw->buf, n) != n){ @@ -584,7 +590,8 @@ mntxmit(Mnt *m, Mnthdr *mh) */ n = (*devtab[m->msg->type].read)(m->msg, mbr->buf, BUFSIZE); qunlock(m); - qunlock(m->msg); + if(!isbit) + qunlock(m->msg); poperror(); if(convM2S(mbr->buf, &mh->rhdr, n) == 0){ diff --git a/power/dat.h b/power/dat.h index 821a2e724d9d919e6e33f8695b4c2b7a68d22e9b..f169942a147b4d6592bff575dfd12ce9f07bb76c 100644 --- a/power/dat.h +++ b/power/dat.h @@ -1,4 +1,5 @@ typedef struct Alarm Alarm; +typedef struct Bitmsg Bitmsg; typedef struct Blist Blist; typedef struct Block Block; typedef struct Chan Chan; @@ -75,6 +76,13 @@ struct Alarm void *arg; }; +struct Bitmsg +{ + ulong cmd; + ulong addr; + ulong count; +}; + #define CHDIR 0x80000000L #define QPATH 0x0000FFFFL struct Chan @@ -327,6 +335,11 @@ struct User Chan *dot; Chan *fd[NFD]; int maxfd; /* highest fd in use */ + /* + * I/O point for bit interface. This is the easiest way to allocate + * them, but not the prettiest or most general. + */ + Bitmsg bit; /* * Rest of structure controlled by devproc.c and friends. * lock(&p->debug) to modify. diff --git a/power/devbit.c b/power/devbit.c index 7a0de965987a4db882818ff5ea30d41e04996041..a3c16b1079d4ccb8da4ab158d66081a60362dbed 100644 --- a/power/devbit.c +++ b/power/devbit.c @@ -8,20 +8,10 @@ #include "io.h" -typedef struct Bitmsg Bitmsg; -struct Bitmsg -{ - ulong cmd; - ulong addr; - ulong count; - ulong result; -}; - static struct { QLock; int open; - Bitmsg msg; char buf[10*1024]; }bit; @@ -36,23 +26,17 @@ enum }; void -bitsend(ulong cmd, void *addr, ulong count) +bitsend(Bitmsg *bp, ulong cmd, void *addr, ulong count) { - bit.msg.cmd = cmd; - bit.msg.addr = (ulong)addr; - bit.msg.count = count; + bp->cmd = cmd; + bp->addr = (ulong)addr; + bp->count = count; if(*BITADDR) panic("bitsend"); - *BITADDR = &bit.msg; + *BITADDR = bp; wbflush(); *BITINTR = 0x20; -} - -void -bitsync(void) -{ - while(*BITADDR) - ; + do; while(*BITADDR); } void @@ -102,6 +86,9 @@ bitstat(Chan *c, char *dp) Chan* bitopen(Chan *c, int omode) { + Bitmsg *bp; + + bp = &((User*)(u->p->upage->pa|KZERO))->bit; if(c->qid!=1 || omode!=ORDWR) error(0, Eperm); qlock(&bit); @@ -110,9 +97,7 @@ bitopen(Chan *c, int omode) print("multiple bit open\n"); error(0, Einuse); } - bitsync(); - bitsend(RESET, 0, 0); - bitsync(); + bitsend(bp, RESET, 0, 0); bit.open = 1; qunlock(&bit); c->mode = openmode(omode); @@ -146,21 +131,28 @@ bitclose(Chan *c) long bitread(Chan *c, void *buf, long n) { + Bitmsg *bp; + int docpy; + + bp = &((User*)(u->p->upage->pa|KZERO))->bit; switch(c->qid){ case 1: if(n > sizeof bit.buf) error(0, Egreg); + docpy = 0; qlock(&bit); - if((((ulong)buf)&(KSEGM|3)) == KSEG0){ - bitsend(READ, buf, n); - bitsync(); - }else{ - bitsend(READ, bit.buf, n); - bitsync(); - memcpy(buf, bit.buf, n); + if((((ulong)buf)&(KSEGM|3)) == KSEG0) + bitsend(bp, READ, buf, n); + else{ + bitsend(bp, READ, bit.buf, n); + docpy = 1; } - n = bit.msg.result; qunlock(&bit); + do + n = bp->count; + while(n == 0); + if(docpy) + memcpy(buf, bit.buf, n); return n; } error(0, Egreg); @@ -170,18 +162,19 @@ bitread(Chan *c, void *buf, long n) long bitwrite(Chan *c, void *buf, long n) { + Bitmsg *bp; + + bp = &((User*)(u->p->upage->pa|KZERO))->bit; switch(c->qid){ case 1: if(n > sizeof bit.buf) error(0, Egreg); qlock(&bit); - if((((ulong)buf)&(KSEGM|3)) == KSEG0){ - bitsend(WRITE, buf, n); - bitsync(); - }else{ + if((((ulong)buf)&(KSEGM|3)) == KSEG0) + bitsend(bp, WRITE, buf, n); + else{ memcpy(bit.buf, buf, n); - bitsend(WRITE, bit.buf, n); - bitsync(); + bitsend(bp, WRITE, bit.buf, n); } qunlock(&bit); return n;