From 9ec1f5aae7a2bc48667dd5e1b962625f4f791e2e Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 21 Jun 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-06-21 --- port/devlance.c | 254 +++++++++++++++--------------------------------- power/devrtc.c | 43 ++++---- power/trap.c | 2 +- 3 files changed, 105 insertions(+), 194 deletions(-) diff --git a/port/devlance.c b/port/devlance.c index b43c5efdf7337b2d10527dbd111ee357fff1f233..b9d7947127c3faed3a5b4bf906cc3427f94c99f9 100644 --- a/port/devlance.c +++ b/port/devlance.c @@ -8,9 +8,8 @@ #include "devtab.h" enum { - Ntypes= 8, /* max number of ethernet packet types */ - Ndir= Ntypes+2, /* entries in top level directory */ - Ndpkt= 200, /* number of debug packets */ + Ntypes= 9, /* max number of ethernet packet types */ + Ndir= Ntypes+1, /* entries in top level directory */ Maxrb= 128, /* max buffers in a ring */ }; #define RSUCC(x) (((x)+1)%l.nrrb) @@ -18,8 +17,6 @@ enum { #define NOW (MACHP(0)->ticks*MS2HZ) -int plance; - /* * Communication with the lance is via a transmit and receive ring of * message descriptors. The Initblock contains pointers to and sizes of @@ -81,29 +78,10 @@ struct Lancemem typedef struct { QLock; int type; /* ethernet type */ + int prom; /* promiscuous mode */ Queue *q; } Ethertype; -/* - * circular debug queue (first 44 bytes of the last Ndpkt packets) - */ -typedef struct { - uchar d[6]; - uchar s[6]; - uchar type[2]; - uchar data[60]; -} Dpkt; -typedef struct { - ulong ticks; - char tag; - int len; - Dpkt p; -} Trace; -typedef struct { - Lock; - int next; - Trace t[Ndpkt]; -} Debqueue; /* * lance state @@ -112,11 +90,13 @@ typedef struct { QLock; Lance; /* host dependent lance params */ + int prom; /* number of promiscuous channels */ int inited; uchar *lmp; /* location of parity test */ Rendez rr; /* rendezvous for an input buffer */ + QLock rlock; /* semaphore on tc */ ushort rl; /* first rcv Message belonging to Lance */ ushort rc; /* first rcv Message belonging to CPU */ @@ -128,7 +108,6 @@ typedef struct { Ethertype e[Ntypes]; int debug; int kstarted; - Debqueue dq; /* sadistics */ @@ -203,58 +182,8 @@ static SoftLance l; /* * predeclared */ -void lancekproc(void *); - -/* - * mode used by restart - */ -int lancemode; - -/* - * print a packet preceded by a message - */ -int -sprintpacket(char *buf, Trace *t) -{ - Dpkt *p = &t->p; - int i, n; - - n = sprint(buf, "%c: %.8ud %.4d d(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)s(%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux)t(%.2ux %.2ux)d(", - 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]); - for(i=0; idata); i++) - n += sprint(buf+n, "%.2ux", p->data[i]); - n += sprint(buf+n, ")\n"); - return n; -} - -/* - * save a message in a circular queue for later debugging - */ -void -lancedebq(char tag, Etherpkt *p, int len) -{ - Trace *t; - - lock(&l.dq); - t = &l.dq.t[l.dq.next]; - t->ticks = NOW; - t->tag = tag; - t->len = len; - memmove(&(t->p), p, sizeof(Dpkt)); - l.dq.next = (l.dq.next+1) % Ndpkt; - unlock(&l.dq); - if(plance){ - char buf[1024]; - if(p->d[0] != 0xff){ - sprintpacket(buf, t); - print("%s\n", buf); - } - } /**/ -} - +static void lancekproc(void *); +static void lancestart(int); /* * lance stream module definition */ @@ -295,9 +224,17 @@ lancestclose(Queue *q) Ethertype *et; et = (Ethertype *)(q->ptr); + if(et->prom){ + qlock(&l); + l.prom--; + if(l.prom == 0) + lancestart(0); + qunlock(&l); + } qlock(et); et->type = 0; et->q = 0; + et->prom = 0; qunlock(et); } @@ -321,9 +258,16 @@ lanceoput(Queue *q, Block *bp ) Msg *m; if(bp->type == M_CTL){ + e = q->ptr; if(streamparse("connect", bp)){ - n = strtoul((char *)bp->rptr, 0, 0); - ((Ethertype *)q->ptr)->type = n; + e->type = strtol((char *)bp->rptr, 0, 0); + } else if(streamparse("promiscuous", bp)) { + e->prom = 1; + qlock(&l); + l.prom++; + if(l.prom == 1) + lancestart(PROM); + qunlock(&l); } freeb(bp); return; @@ -378,8 +322,6 @@ lanceoput(Queue *q, Block *bp ) len = 60; } - lancedebq('o', p, len);/**/ - /* * set up the ring descriptor and hand to lance */ @@ -400,8 +342,7 @@ lanceoput(Queue *q, Block *bp ) */ enum { Lchanqid = 1, - Ltraceqid = 2, - Lstatsqid = 3, + Lstatsqid = 2, }; Dirtab lancedir[Ndir]; @@ -436,19 +377,30 @@ lancereset(void) * It may be used to restart a dead lance. */ static void -lancestart(void) +lancestart(int mode) { int i; Etherpkt *p; Lancemem *lm = LANCEMEM; Msg *m; + /* + * wait till both receiver and transmitter are + * quiescent + */ + qlock(&l.tlock); + qlock(&l.rlock); + lancereset(); + l.rl = 0; + l.rc = 0; + l.tl = 0; + l.tc = 0; /* * create the initialization block */ - MPus(lm->mode) = lancemode; + MPus(lm->mode) = mode; /* * set ether addr from the value in the id prom. @@ -527,8 +479,7 @@ lancestart(void) } /* - * set up the free list and lance directory. - * start the lance. + * set up lance directory. */ void lanceinit(void) @@ -545,14 +496,10 @@ lanceinit(void) lancedir[i].length = 0; lancedir[i].perm = 0600; } - strcpy(lancedir[Ntypes].name, "trace"); - lancedir[Ntypes].qid.path = Ltraceqid; + strcpy(lancedir[Ntypes].name, "stats"); + lancedir[Ntypes].qid.path = Lstatsqid; lancedir[Ntypes].length = 0; lancedir[Ntypes].perm = 0600; - strcpy(lancedir[Ntypes+1].name, "stats"); - lancedir[Ntypes+1].qid.path = Lstatsqid; - lancedir[Ntypes+1].length = 0; - lancedir[Ntypes+1].perm = 0600; } @@ -562,7 +509,7 @@ lanceattach(char *spec) if(l.kstarted == 0){ kproc("lancekproc", lancekproc, 0);/**/ l.kstarted = 1; - lancestart(); + lancestart(0); } return devattach('l', spec); } @@ -589,7 +536,7 @@ lancewalk(Chan *c, char *name) void lancestat(Chan *c, char *dp) { - if(c->qid.path==CHDIR || c->qid.path==Ltraceqid || c->qid.path==Lstatsqid) + if(c->qid.path==CHDIR || c->qid.path==Lstatsqid) devstat(c, dp, lancedir, Ndir, devgen); else devstat(c, dp, 0, 0, streamgen); @@ -603,7 +550,6 @@ lanceopen(Chan *c, int omode) { switch(c->qid.path){ case CHDIR: - case Ltraceqid: case Lstatsqid: if(omode != OREAD) error(Eperm); @@ -631,38 +577,6 @@ lanceclose(Chan *c) streamclose(c); } -static long -lancetraceread(Chan *c, void *a, long n, ulong offset) -{ - char buf[1024]; - long rv; - int i; - char *ca = a; - int off; - Trace *t; - int plen; - - rv = 0; - plen = sprintpacket(buf, l.dq.t); - off = offset % plen; - for(t = &l.dq.t[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 - off; - if(i > n) - i = n; - memmove(ca, buf + off, i); - n -= i; - ca += i; - rv += i; - off = 0; - } - return rv; -} - long lanceread(Chan *c, void *a, long n, ulong offset) { @@ -677,8 +591,6 @@ lanceread(Chan *c, void *a, long n, ulong offset) l.overflows, l.frames, l.buffs, l.oerrs, l.ea[0], l.ea[1], l.ea[2], l.ea[3], l.ea[4], l.ea[5]); return stringread(c, a, n, buf, offset); - case Ltraceqid: - return lancetraceread(c, a, n, offset); default: return streamread(c, a, n); } @@ -729,8 +641,9 @@ lanceintr(void) } if(csr & IDON){ - print("lance inited\n"); l.inited = 1; + qunlock(&l.rlock); + qunlock(&l.tlock); } /* @@ -752,6 +665,31 @@ lanceintr(void) } } +/* + * send a packet upstream + */ +void +lanceup(Ethertype *e, Etherpkt *p, int len) +{ + Block *bp; + + /* + * only a trace channel gets packets destined for other machines + */ + if(e->type != -1){ + if(!(p->d[0]&0x80) && memcmp(p->d, l.ea, sizeof(p->d))!=0) + return; + } + if(e->q && e->q->next->len<=Streamhi && !waserror()){ + bp = allocb(len); + memmove(bp->rptr, (uchar *)p, len); + bp->wptr += len; + bp->flags |= S_DELIM; + PUTNEXT(e->q, bp); + poperror(); + } +} + /* * input process, awakened on each interrupt with rcv buffers filled */ @@ -761,19 +699,18 @@ isinput(void *arg) Lancemem *lm = LANCEMEM; return l.rl!=l.rc && (MPus(lm->rmr[l.rl].flags) & OWN)==0; } -void +static void lancekproc(void *arg) { - Block *bp; Etherpkt *p; Ethertype *e; - int t; int len; - int i, last; + int t; Lancemem *lm = LANCEMEM; Msg *m; for(;;){ + qlock(&l.rlock); for(; l.rl!=l.rc && (MPus(lm->rmr[l.rl].flags) & OWN)==0 ; l.rl=RSUCC(l.rl)){ l.inpackets++; m = &(lm->rmr[l.rl]); @@ -791,47 +728,19 @@ lancekproc(void *arg) } /* - * See if a queue exists for this packet type. + * stuff packet up each queue that wants it */ p = &l.rp[l.rl]; t = (p->type[0]<<8) | p->type[1]; len = MPus(m->cntflags) - 4; - lancedebq('i', p, len);/**/ for(e = &l.e[0]; e < &l.e[Ntypes]; e++){ - if(e->q==0 || t!=e->type || !canqlock(e)) - continue; - if(e->q && t == e->type) - break; - qunlock(e); - } - /* - * If no match, see if any stream has type -1. - * It matches all packets. - */ - if(e == &l.e[Ntypes]){ - for(e = &l.e[0]; e < &l.e[Ntypes]; e++){ - if(e->q==0 || e->type!=-1 || !canqlock(e)) - continue; - if(e->q && e->type == -1) - break; + if(e->q!=0 && (t==e->type||e->type==-1) && canqlock(e)){ + if(t==e->type||e->type==-1) + lanceup(e, p, len); qunlock(e); } } - /* - * The lock on e makes sure the queue is still there. - */ - if(e!=&l.e[Ntypes]){ - if(e->q->next->len<=Streamhi && !waserror()){ - bp = allocb(len); - memmove(bp->rptr, (uchar *)p, len); - bp->wptr += len; - bp->flags |= S_DELIM; - PUTNEXT(e->q, bp); - poperror(); - } - qunlock(e); - } - + stage: /* * stage the next input buffer @@ -844,12 +753,7 @@ stage: l.rc = RSUCC(l.rc); wbflush(); } + qunlock(&l.rlock); sleep(&l.rr, isinput, 0); } } - -void -lancetoggle(void) -{ - plance ^= 1; -} diff --git a/power/devrtc.c b/power/devrtc.c index c1709ed6279a78da7dfcf6f68316bd173cf751ab..a1107ec7e6711c578d93c91e4e7791aa5e3dad79 100644 --- a/power/devrtc.c +++ b/power/devrtc.c @@ -26,6 +26,7 @@ struct Rtc QLock rtclock; /* mutex on clock operations */ +#define NRTC 1 static Dirtab rtcdir[]={ "rtc", {1, 0}, 0, 0600, }; @@ -95,19 +96,13 @@ rtcclone(Chan *c, Chan *nc) int rtcwalk(Chan *c, char *name) { - if(c->qid.path != CHDIR) - return 0; - if(strcmp(name, "rtc") == 0){ - c->qid.path = 1; - return 1; - } - return 0; + return devwalk(c, name, rtcdir, NRTC, devgen); } void rtcstat(Chan *c, char *dp) { - devstat(c, dp, rtcdir, 1, devgen); + devstat(c, dp, rtcdir, NRTC, devgen); } Chan* @@ -117,10 +112,7 @@ rtcopen(Chan *c, int omode) if(strcmp(u->p->pgrp->user, "bootes")) /* BUG */ error(Eperm); } - c->mode = openmode(omode); - c->flag |= COPEN; - c->offset = 0; - return c; + return devopen(c, omode, rtcdir, NRTC, devgen); } void @@ -137,7 +129,7 @@ rtcclose(Chan *c) #define GETBCD(o) ((bcdclock[o]&0xf) + 10*(bcdclock[o]>>4)) long -rtcread(Chan *c, void *buf, long n, ulong offset) +rtctime(void) { int i,j; uchar ch; @@ -146,15 +138,11 @@ rtcread(Chan *c, void *buf, long n, ulong offset) char atime[64]; Rtc rtc; - if(c->qid.path & CHDIR) - return devdirread(c, buf, n, rtcdir, 1, devgen); - nv = RTC; /* * set up the pattern for the clock */ - qlock(&rtclock); rtcpattern(); /* @@ -191,8 +179,27 @@ rtcread(Chan *c, void *buf, long n, ulong offset) rtc.year += 2000; else rtc.year += 1900; + return rtc2sec(&rtc); +} + +long +rtcread(Chan *c, void *buf, long n, ulong offset) +{ + ulong t, ot; + + if(c->qid.path & CHDIR) + return devdirread(c, buf, n, rtcdir, NRTC, devgen); + + qlock(&rtclock); + t = rtctime(); + do{ + ot = t; + t = rtctime(); /* make sure there's no skew */ + }while(t != ot); + qunlock(&rtclock); + n = readnum(offset, buf, n, t, 12); + return n; - return readnum(offset, buf, n, rtc2sec(&rtc), 12); } #define PUTBCD(n,o) bcdclock[o] = (n % 10) | (((n / 10) % 10)<<4) diff --git a/power/trap.c b/power/trap.c index aee9ce0b8799a843817ed1ec6d81abcc32cc63af..dc3113d488d8812516aac6138d47a450d1a3ea83 100644 --- a/power/trap.c +++ b/power/trap.c @@ -443,7 +443,7 @@ Syscall sysdup, syserrstr, sysexec, sysexits, sysfork, sysforkpgrp; Syscall sysfstat, sysfwstat, sysgetpid, sysmount, sysnoted; Syscall sysnotify, sysopen, syspipe, sysr1, sysread, sysremove, sysseek; Syscall syssleep, sysstat, syswait, syswrite, syswstat, sysalarm, syslkbrk_; - +#define LKBRK_ 12 Syscall *systab[]={ [SYSR1] sysr1, [ERRSTR] syserrstr,