From 1e4aa83fb98ece7178ca0ae87cd154a2736c273e Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Mon, 5 Jun 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-06-05 --- ip/rudp.c | 33 ++++--- pc/devi82365.c | 251 ++++++++++++++++++++++++++++++------------------- pc/ether589.c | 42 +++++++-- pc/etherec2t.c | 8 +- pc/fns.h | 1 + 5 files changed, 211 insertions(+), 124 deletions(-) diff --git a/ip/rudp.c b/ip/rudp.c index a4fad890cdf344b2a61661010f2670514843277d..3dda3da3cdefccee7cf7975aeae3bf43f0d03880 100644 --- a/ip/rudp.c +++ b/ip/rudp.c @@ -181,15 +181,16 @@ struct Rudpcb /* * local functions */ -void relsendack(Conv *, Reliable *, int); -int reliput(Conv *, Block *, uchar *, ushort); -Reliable *relstate(Rudpcb *, uchar *, ushort, char *from); -void relput(Reliable *); -void relforget(Conv *, uchar *, int, int); +void relsendack(Conv*, Reliable*, int); +int reliput(Conv*, Block*, uchar*, ushort); +Reliable *relstate(Rudpcb*, uchar*, ushort, char*); +void relput(Reliable*); +void relforget(Conv *, uchar*, int, int); void relackproc(void *); -void relackq(Reliable *, Block *); -void relhangup(Conv *, Reliable *); -void relrexmit(Conv *, Reliable *); +void relackq(Reliable *, Block*); +void relhangup(Conv *, Reliable*); +void relrexmit(Conv *, Reliable*); +void relput(Reliable*); static void rudpstartackproc(Proto *rudp) @@ -295,7 +296,6 @@ rudpclose(Conv *c) ucb->r = 0; qunlock(ucb); - qunlock(c); } @@ -445,6 +445,12 @@ rudpkick(Conv *c, int) doipoput(c, f, bp, 0, c->ttl, c->tos); + if(waserror()) { + relput(r); + qunlock(&r->lock); + nexterror(); + } + /* flow control of sorts */ qlock(&r->lock); if(UNACKED(r) > Maxunacked){ @@ -452,9 +458,10 @@ rudpkick(Conv *c, int) sleep(&r->vous, flow, r); r->blocked = 0; } - qunlock(&r->lock); + qunlock(&r->lock); relput(r); + poperror(); } void @@ -554,7 +561,7 @@ rudpiput(Proto *rudp, uchar *ia, Block *bp) len -= (UDP_RHDRSIZE-UDP_PHDRSIZE); bp = trimblock(bp, UDP_IPHDR+UDP_RHDRSIZE, len); - if(bp == nil){ + if(bp == nil) { netlog(f, Logrudp, "rudp: len err %I.%d -> %I.%d\n", raddr, rport, laddr, lport); DPRINT("rudp: len err %I.%d -> %I.%d\n", @@ -607,7 +614,7 @@ rudpiput(Proto *rudp, uchar *ia, Block *bp) if(bp->next) bp = concatblock(bp); - if(qfull(c->rq)){ + if(qfull(c->rq)) { netlog(f, Logrudp, "rudp: qfull %I.%d -> %I.%d\n", raddr, rport, laddr, lport); freeblist(bp); @@ -810,6 +817,7 @@ relstate(Rudpcb *ucb, uchar *addr, ushort port, char *from) if(r == nil){ while(generation == 0) generation = rand(); + DPRINT("from %s new state %lud for %I!%ud\n", from, generation, addr, port); @@ -832,6 +840,7 @@ relstate(Rudpcb *ucb, uchar *addr, ushort port, char *from) *l = r; } + incref(r); return r; } diff --git a/pc/devi82365.c b/pc/devi82365.c index c13384fcff9e6875149ce262ff8aeeccbee58c56..58c89a41b2c22c7695ad7496dd5c50b6d61446c8 100644 --- a/pc/devi82365.c +++ b/pc/devi82365.c @@ -104,6 +104,7 @@ enum typedef struct I82365 I82365; typedef struct Slot Slot; typedef struct Conftab Conftab; +typedef struct Cisdat Cisdat; /* a controller */ enum @@ -144,6 +145,15 @@ struct Conftab ulong otherwait; }; +/* cis memory walking */ +struct Cisdat +{ + uchar *cisbase; + int cispos; + int cisskip; + int cislen; +}; + /* a card slot */ struct Slot { @@ -175,8 +185,7 @@ struct Slot Conftab *def; /* default conftab */ /* for walking through cis */ - int cispos; /* current position scanning cis */ - uchar *cisbase; + Cisdat; /* memory maps */ Lock mlock; /* lock down the maps */ @@ -1046,67 +1055,111 @@ pcmio(int slotno, ISAConf *isa) * read and crack the card information structure enough to set * important parameters like power */ -static void tcfig(Slot*, int); -static void tentry(Slot*, int); -static void tvers1(Slot*, int); - -static void (*parse[256])(Slot*, int) = -{ -[0x15] tvers1, -[0x1A] tcfig, -[0x1B] tentry, +static void tcfig(Slot*, Cisdat*, int); +static void tentry(Slot*, Cisdat*, int); +static void tvers1(Slot*, Cisdat*, int); + +struct { + int n; + void (*parse)(Slot*, Cisdat*, int); +} cistab[] = { + 0x15, tvers1, + 0x1A, tcfig, + 0x1B, tentry, }; static int -readc(Slot *pp, uchar *x) +readc(Cisdat *pp, uchar *x) { - if(pp->cispos >= Mchunk) + if(pp->cispos >= pp->cislen) return 0; - *x = pp->cisbase[2*pp->cispos]; + *x = pp->cisbase[pp->cisskip*pp->cispos]; pp->cispos++; return 1; } -static void -cisread(Slot *pp) +static int +xcistuple(int slotno, int tuple, void *v, int nv, int attr) { - uchar link; - uchar type; - int this, i; PCMmap *m; + Cisdat cis; + int i, l; + uchar *p; + uchar type, link; + int this; - memset(pp->ctab, 0, sizeof(pp->ctab)); - pp->caddr = 0; - pp->cpresent = 0; - pp->configed = 0; - pp->nctab = 0; - - m = pcmmap(pp->slotno, 0, 0, 1); + m = pcmmap(slotno, 0, 0, attr); if(m == 0) - return; - pp->cisbase = KADDR(m->isa); - pp->cispos = 0; + return -1; + + cis.cisbase = KADDR(m->isa); + cis.cispos = 0; + cis.cisskip = attr ? 2 : 1; + cis.cislen = Mchunk; /* loop through all the tuples */ for(i = 0; i < 1000; i++){ - this = pp->cispos; - if(readc(pp, &type) != 1) + this = cis.cispos; + if(readc(&cis, &type) != 1) break; if(type == 0xFF) break; - if(readc(pp, &link) != 1) + if(readc(&cis, &link) != 1) break; - if(parse[type]) - (*parse[type])(pp, type); - if(link == 0xff) + if(link == 0xFF) break; - pp->cispos = this + (2+link); + if(type == tuple) { + p = v; + for(l=0; l= 0) + return n; + return xcistuple(slotno, tuple, v, nv, 0); +} + +static void +cisread(Slot *pp) +{ + uchar v[256]; + int i, nv; + Cisdat cis; + + memset(pp->ctab, 0, sizeof(pp->ctab)); + pp->caddr = 0; + pp->cpresent = 0; + pp->configed = 0; + pp->nctab = 0; + + for(i = 0; i < nelem(cistab); i++) { + if((nv = pcmcistuple(pp->slotno, cistab[i].n, v, sizeof(v))) >= 0) { + cis.cisbase = v; + cis.cispos = 0; + cis.cisskip = 1; + cis.cislen = nv; + + (*cistab[i].parse)(pp, &cis, cistab[i].n); + } } - pcmunmap(pp->slotno, m); } static ulong -getlong(Slot *pp, int size) +getlong(Cisdat *cis, int size) { uchar c; int i; @@ -1114,7 +1167,7 @@ getlong(Slot *pp, int size) x = 0; for(i = 0; i < size; i++){ - if(readc(pp, &c) != 1) + if(readc(cis, &c) != 1) break; x |= c<<(i*8); } @@ -1122,19 +1175,19 @@ getlong(Slot *pp, int size) } static void -tcfig(Slot *pp, int ) +tcfig(Slot *pp, Cisdat *cis, int ) { uchar size, rasize, rmsize; uchar last; - if(readc(pp, &size) != 1) + if(readc(cis, &size) != 1) return; rasize = (size&0x3) + 1; rmsize = ((size>>2)&0xf) + 1; - if(readc(pp, &last) != 1) + if(readc(cis, &last) != 1) return; - pp->caddr = getlong(pp, rasize); - pp->cpresent = getlong(pp, rmsize); + pp->caddr = getlong(cis, rasize); + pp->cpresent = getlong(cis, rmsize); } static ulong vexp[8] = @@ -1147,18 +1200,18 @@ static ulong vmant[16] = }; static ulong -microvolt(Slot *pp) +microvolt(Cisdat *cis) { uchar c; ulong microvolts; ulong exp; - if(readc(pp, &c) != 1) + if(readc(cis, &c) != 1) return 0; exp = vexp[c&0x7]; microvolts = vmant[(c>>3)&0xf]*exp; while(c & 0x80){ - if(readc(pp, &c) != 1) + if(readc(cis, &c) != 1) return 0; switch(c){ case 0x7d: @@ -1176,16 +1229,16 @@ microvolt(Slot *pp) } static ulong -nanoamps(Slot *pp) +nanoamps(Cisdat *cis) { uchar c; ulong nanoamps; - if(readc(pp, &c) != 1) + if(readc(cis, &c) != 1) return 0; nanoamps = vexp[c&0x7]*vmant[(c>>3)&0xf]; while(c & 0x80){ - if(readc(pp, &c) != 1) + if(readc(cis, &c) != 1) return 0; if(c == 0x7d || c == 0x7e || c == 0x7f) nanoamps = 0; @@ -1197,28 +1250,28 @@ nanoamps(Slot *pp) * only nominal voltage is important for config */ static ulong -power(Slot *pp) +power(Cisdat *cis) { uchar feature; ulong mv; mv = 0; - if(readc(pp, &feature) != 1) + if(readc(cis, &feature) != 1) return 0; if(feature & 1) - mv = microvolt(pp); + mv = microvolt(cis); if(feature & 2) - microvolt(pp); + microvolt(cis); if(feature & 4) - microvolt(pp); + microvolt(cis); if(feature & 8) - nanoamps(pp); + nanoamps(cis); if(feature & 0x10) - nanoamps(pp); + nanoamps(cis); if(feature & 0x20) - nanoamps(pp); + nanoamps(cis); if(feature & 0x40) - nanoamps(pp); + nanoamps(cis); return mv/1000000; } @@ -1229,12 +1282,12 @@ static ulong exponent[8] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, }; static ulong -ttiming(Slot *pp, int scale) +ttiming(Cisdat *cis, int scale) { uchar unscaled; ulong nanosecs; - if(readc(pp, &unscaled) != 1) + if(readc(cis, &unscaled) != 1) return 0; nanosecs = (mantissa[(unscaled>>3)&0xf]*exponent[unscaled&7])/10; nanosecs = nanosecs * vexp[scale]; @@ -1242,31 +1295,31 @@ ttiming(Slot *pp, int scale) } static void -timing(Slot *pp, Conftab *ct) +timing(Cisdat *cis, Conftab *ct) { uchar c, i; - if(readc(pp, &c) != 1) + if(readc(cis, &c) != 1) return; i = c&0x3; if(i != 3) - ct->maxwait = ttiming(pp, i); /* max wait */ + ct->maxwait = ttiming(cis, i); /* max wait */ i = (c>>2)&0x7; if(i != 7) - ct->readywait = ttiming(pp, i); /* max ready/busy wait */ + ct->readywait = ttiming(cis, i); /* max ready/busy wait */ i = (c>>5)&0x7; if(i != 7) - ct->otherwait = ttiming(pp, i); /* reserved wait */ + ct->otherwait = ttiming(cis, i); /* reserved wait */ } static void -iospaces(Slot *pp, Conftab *ct) +iospaces(Cisdat *cis, Conftab *ct) { uchar c; int i, nio; ct->nio = 0; - if(readc(pp, &c) != 1) + if(readc(cis, &c) != 1) return; ct->bit16 = ((c>>5)&3) >= 2; @@ -1277,55 +1330,55 @@ iospaces(Slot *pp, Conftab *ct) return; } - if(readc(pp, &c) != 1) + if(readc(cis, &c) != 1) return; nio = (c&0xf)+1; for(i = 0; i < nio; i++){ - ct->io[i].start = getlong(pp, (c>>4)&0x3); - ct->io[0].len = getlong(pp, (c>>6)&0x3); + ct->io[i].start = getlong(cis, (c>>4)&0x3); + ct->io[0].len = getlong(cis, (c>>6)&0x3); } ct->nio = nio; } static void -irq(Slot *pp, Conftab *ct) +irq(Cisdat *cis, Conftab *ct) { uchar c; - if(readc(pp, &c) != 1) + if(readc(cis, &c) != 1) return; ct->irqtype = c & 0xe0; if(c & 0x10) - ct->irqs = getlong(pp, 2); + ct->irqs = getlong(cis, 2); else ct->irqs = 1<<(c&0xf); ct->irqs &= 0xDEB8; /* levels available to card */ } static void -memspace(Slot *pp, int asize, int lsize, int host) +memspace(Cisdat *cis, int asize, int lsize, int host) { ulong haddress, address, len; - len = getlong(pp, lsize)*256; - address = getlong(pp, asize)*256; + len = getlong(cis, lsize)*256; + address = getlong(cis, asize)*256; USED(len, address); if(host){ - haddress = getlong(pp, asize)*256; + haddress = getlong(cis, asize)*256; USED(haddress); } } static void -tentry(Slot *pp, int ) +tentry(Slot *pp, Cisdat *cis, int ) { uchar c, i, feature; Conftab *ct; if(pp->nctab >= Maxctab) return; - if(readc(pp, &c) != 1) + if(readc(cis, &c) != 1) return; ct = &pp->ctab[pp->nctab++]; @@ -1341,65 +1394,65 @@ tentry(Slot *pp, int ) /* memory wait specified? */ if(c & 0x80){ - if(readc(pp, &i) != 1) + if(readc(cis, &i) != 1) return; if(i&0x80) ct->memwait = 1; } - if(readc(pp, &feature) != 1) + if(readc(cis, &feature) != 1) return; switch(feature&0x3){ case 1: - ct->vpp1 = ct->vpp2 = power(pp); + ct->vpp1 = ct->vpp2 = power(cis); break; case 2: - power(pp); - ct->vpp1 = ct->vpp2 = power(pp); + power(cis); + ct->vpp1 = ct->vpp2 = power(cis); break; case 3: - power(pp); - ct->vpp1 = power(pp); - ct->vpp2 = power(pp); + power(cis); + ct->vpp1 = power(cis); + ct->vpp2 = power(cis); break; default: break; } if(feature&0x4) - timing(pp, ct); + timing(cis, ct); if(feature&0x8) - iospaces(pp, ct); + iospaces(cis, ct); if(feature&0x10) - irq(pp, ct); + irq(cis, ct); switch((feature>>5)&0x3){ case 1: - memspace(pp, 0, 2, 0); + memspace(cis, 0, 2, 0); break; case 2: - memspace(pp, 2, 2, 0); + memspace(cis, 2, 2, 0); break; case 3: - if(readc(pp, &c) != 1) + if(readc(cis, &c) != 1) return; for(i = 0; i <= (c&0x7); i++) - memspace(pp, (c>>5)&0x3, (c>>3)&0x3, c&0x80); + memspace(cis, (c>>5)&0x3, (c>>3)&0x3, c&0x80); break; } pp->configed++; } static void -tvers1(Slot *pp, int ) +tvers1(Slot *pp, Cisdat *cis, int ) { uchar c, major, minor; int i; - if(readc(pp, &major) != 1) + if(readc(cis, &major) != 1) return; - if(readc(pp, &minor) != 1) + if(readc(cis, &minor) != 1) return; for(i = 0; i < sizeof(pp->verstr)-1; i++){ - if(readc(pp, &c) != 1) + if(readc(cis, &c) != 1) return; if(c == 0) c = '\n'; diff --git a/pc/ether589.c b/pc/ether589.c index fb90a0df3247b4d7661ca594fcd6ced5b9295d87..f45483efd34b4baa00e7a79e64173912f8c91a8a 100644 --- a/pc/ether589.c +++ b/pc/ether589.c @@ -2,8 +2,6 @@ * 3C589 and 3C562. * To do: * check xcvr10Base2 still works (is GlobalReset necessary?). - * pull the station address out of the card space for the 3C562, - * it has no EEPROM. */ #include "u.h" #include "../port/lib.h" @@ -82,6 +80,13 @@ enum { /* Window 4 - diagnostic */ extern int etherelnk3reset(Ether*); +static char *tcmpcmcia[] = { + "3C589", /* 3COM 589[ABCD] */ + "3C562", /* 3COM 562 */ + "589E", /* 3COM Megahertz 589E */ + nil, +}; + static int configASIC(Ether* ether, int port, int xcvr) { @@ -111,10 +116,12 @@ configASIC(Ether* ether, int port, int xcvr) static int reset(Ether* ether) { - int i, slot; + int i, t, slot; + char *type; int port; enum { WantAny, Want10BT, Want10B2 }; int want; + uchar ea[6]; char *p; if(ether->irq == 0) @@ -126,11 +133,34 @@ reset(Ether* ether) if(ioalloc(port, 0x10, 0, "3C589") < 0) return -1; - if((slot = pcmspecial(ether->type, ether)) < 0){ + type = nil; + slot = -1; + for(i = 0; tcmpcmcia[i] != nil; i++){ + type = tcmpcmcia[i]; + if((slot = pcmspecial(type, ether)) >= 0) + break; + } + if(slot < 0){ iofree(port); return -1; } + /* + * Read Ethernet address from card memory + * on 3C562, but only if the user has not + * overridden it. + */ + memset(ea, 0, sizeof ea); + if(memcmp(ea, ether->ea, 6) == 0 && strcmp(type, "3C562") == 0) { + if(pcmcistuple(slot, 0x88, ea, 6) == 6) { + for(i = 0; i < 6; i += 2){ + t = ea[i]; + ea[i] = ea[i+1]; + ea[i+1] = t; + } + memmove(ether->ea, ea, 6); + } + } /* * Allow user to specify desired media in plan9.ini */ @@ -156,7 +186,7 @@ reset(Ether* ether) COMMAND(port, SelectRegisterWindow, Wdiagnostic); if((ins(port+MediaStatus)&linkBeatDetect) || want==Want10BT){ COMMAND(port, SelectRegisterWindow, Wop); - print("#l%d: xcvr10BaseT %s\n", ether->ctlrno, ether->type); + print("#l%d: xcvr10BaseT %s\n", ether->ctlrno, type); return 0; } } @@ -169,7 +199,7 @@ reset(Ether* ether) iofree(port); return -1; } - print("#l%d: xcvr10Base2 %s\n", ether->ctlrno, ether->type); + print("#l%d: xcvr10Base2 %s\n", ether->ctlrno, type); return 0; } return -1; /* not reached */ diff --git a/pc/etherec2t.c b/pc/etherec2t.c index 72a5ba3a729d562d340b9ffa85740c01f7805885..cd6ed105701b9a50a97d2889297a161f4f8ccc1a 100644 --- a/pc/etherec2t.c +++ b/pc/etherec2t.c @@ -79,13 +79,7 @@ reset(Ether* ether) ctlr->pstart = ctlr->tstart + HOWMANY(sizeof(Etherpkt), Dp8390BufSz); ctlr->pstop = ctlr->tstart + HOWMANY(ether->size, Dp8390BufSz); - ctlr->dummyrr = 1; - for(i = 0; i < ether->nopt; i++){ - if(strcmp(ether->opt[i], "nodummyrr")) - continue; - ctlr->dummyrr = 0; - break; - } + ctlr->dummyrr = 0; /* * Reset the board. This is done by doing a read diff --git a/pc/fns.h b/pc/fns.h index 1cb32c56e666a9af16346e243c161e923d8dfefb..4fa350c26c11f6b1bac7107c14b7850b23dfe281 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -89,6 +89,7 @@ Pcidev* pcimatch(Pcidev*, int, int); Pcidev* pcimatchtbdf(int); void pcireset(void); void pcisetbme(Pcidev*); +int pcmcistuple(int, int, void*, int); PCMmap* pcmmap(int, ulong, int, int); int pcmspecial(char*, ISAConf*); void pcmspecialclose(int);