From 114881b1db2b7dae09130580780eefc631f2daaa Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 10 Oct 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-10-10 --- pc/devusb.c | 320 ++++++++++++++++++++++++++-------------------- pc/etherwavelan.c | 25 +++- pc/uarti8250.c | 2 +- 3 files changed, 203 insertions(+), 144 deletions(-) diff --git a/pc/devusb.c b/pc/devusb.c index 66be594651520674d46a148cf28db97c983e4fcc..553b1fde0f9d17e41f92b0fcc6f2468057d2c429 100644 --- a/pc/devusb.c +++ b/pc/devusb.c @@ -46,8 +46,6 @@ enum { Rother = 3, }; -typedef uchar byte; - typedef struct Ctlr Ctlr; typedef struct Endpt Endpt; typedef struct Udev Udev; @@ -71,7 +69,10 @@ struct TD { /* software */ ulong flags; - Block* bp; + union{ + Block* bp; /* non-iso */ + ulong offset; /* iso */ + }; Endpt* ep; TD* next; }; @@ -162,7 +163,7 @@ struct Udev { int busy; int state; int id; - byte port; /* port number on connecting hub */ + uchar port; /* port number on connecting hub */ ulong csp; int ls; int npt; @@ -203,18 +204,18 @@ struct Endpt { int id; /* hardware endpoint address */ int maxpkt; /* maximum packet size (from endpoint descriptor) */ int data01; /* 0=DATA0, 1=DATA1 */ - byte eof; + uchar eof; ulong csp; - byte isopen; /* ep operations forbidden on open endpoints */ - byte mode; /* OREAD, OWRITE, ORDWR */ - byte nbuf; /* number of buffers allowed */ - volatile byte iso; - byte debug; - byte active; /* listed for examination by interrupts */ + uchar isopen; /* ep operations forbidden on open endpoints */ + uchar mode; /* OREAD, OWRITE, ORDWR */ + uchar nbuf; /* number of buffers allowed */ + uchar iso; + uchar debug; + uchar active; /* listed for examination by interrupts */ int setin; /* ISO related: */ - byte * tdalloc; - byte * bpalloc; + uchar* tdalloc; + uchar* bpalloc; int hz; int remain; /* for packet size calculations */ int samplesz; @@ -223,11 +224,12 @@ struct Endpt { int psize; /* (remaining) size of this packet */ int off; /* offset into packet */ int isolock; /* reader/writer interlock with interrupt */ - TD* td0; /* first td in array */ - TD* etd; /* pointer into circular list of TDs for isochronous ept */ - TD* xtd; /* next td to be cleaned */ + uchar* bp0; /* first block in array */ + TD * td0; /* first td in array */ + TD * etd; /* pointer into circular list of TDs for isochronous ept */ + TD * xtd; /* next td to be cleaned */ /* end ISO stuff */ - QH* epq; /* queue of TDs for this endpoint */ + QH * epq; /* queue of TDs for this endpoint */ QLock rlock; Rendez rr; Queue* rq; @@ -244,6 +246,7 @@ struct Endpt { ulong nbytes; ulong nblocks; + vlong time; }; struct Ctlr { @@ -816,16 +819,17 @@ schedendpt(Endpt *e) e->tdalloc = mallocz(0x10 + NFRAME*sizeof(TD), 1); e->bpalloc = mallocz(0x10 + e->maxpkt*NFRAME/e->pollms, 1); e->td0 = (TD*)(((ulong)e->tdalloc + 0xf) & ~0xf); - bp = (byte *)(((ulong)e->bpalloc + 0xf) & ~0xf); + e->bp0 = (uchar *)(((ulong)e->bpalloc + 0xf) & ~0xf); frnum = (IN(Frnum) + 1) & 0x3ff; frnum = (frnum & ~(e->pollms - 1)) + e->sched; e->xtd = &e->td0[(frnum+8)&0x3ff]; /* Next td to finish */ e->etd = nil; e->remain = 0; + e->nbytes = 0; td = e->td0; for(i = e->sched; i < NFRAME; i += e->pollms){ - td->bp = (Block *)(bp + e->maxpkt*i/e->pollms); - td->buffer = PADDR(td->bp); + bp = e->bp0 + e->maxpkt*i/e->pollms; + td->buffer = PADDR(bp); td->ep = e; td->next = &td[1]; ub->frameld[i] += e->maxpkt; @@ -1066,15 +1070,19 @@ static void cleaniso(Endpt *e, int frnum) { TD *td; - int id, n; + int id, n, i; + uchar *bp; td = e->xtd; if (td->status & Active) return; id = (e->x<<7)|(e->dev->x&0x7F); - do{ + do { if (td->status & AnyError) iprint("usbisoerror 0x%lux\n", td->status); + e->nbytes += (td->status + 1) & 0x3ff; + if ((td->flags & IsoClean) == 0) + e->nblocks++; if (e->mode == OREAD){ td->dev = ((e->maxpkt -1)<<21) | ((id&0x7FF)<<8) | TokIN; }else{ @@ -1089,23 +1097,26 @@ cleaniso(Endpt *e, int frnum) break; } } while ((td->status & Active) == 0); + e->time = todget(nil); e->xtd = td; if (e->isolock) return; for (n = 2; n < 6; n++){ - td = e->td0 + ((frnum + n)&0x3ff); + i = ((frnum + n)&0x3ff); + td = e->td0 + i; + bp = e->bp0 + e->maxpkt*i/e->pollms; if (td->status & Active) continue; if (td == e->etd) { XPRINT("*"); - memset((byte*)td->bp+e->off, 0, e->maxpkt-e->off); + memset(bp+e->off, 0, e->maxpkt-e->off); if (e->off == 0) td->flags |= IsoClean; e->etd = nil; }else if ((td->flags & IsoClean) == 0){ XPRINT("-"); - memset((byte*)td->bp, 0, e->maxpkt); + memset(bp, 0, e->maxpkt); td->flags |= IsoClean; } td->status = ErrLimit1 | Active | IsoSelect | IOC; @@ -1113,6 +1124,15 @@ cleaniso(Endpt *e, int frnum) wakeup(&e->wr); } +static int sapecount1; +static int sapecount2; +static int sapecmd; +static int sapestatus; +static int sapeintenb; +static int sapeframe; +static int sapeport1; +static int sapeport2; + static void interrupt(Ureg*, void *a) { @@ -1121,27 +1141,27 @@ interrupt(Ureg*, void *a) int s, frnum; QH *q; +sapecount1++; ub = a; s = IN(Status); +sapestatus = s; +sapeintenb = IN(Usbintr); +sapeframe = IN(Frnum); +sapeport1 = IN(Portsc0); +sapeport2 = IN(Portsc1); +sapecmd = IN(Cmd); + OUT(Status, s); if ((s & 0x1f) == 0) return; +sapecount2++; frnum = IN(Frnum) & 0x3ff; - XPRINT("usbint: #%x f%d\n", s, frnum); +// iprint("usbint: #%x f%d\n", s, frnum); if (s & 0x1a) { XPRINT("cmd #%x sofmod #%x\n", IN(Cmd), inb(ub->io+SOFMod)); XPRINT("sc0 #%x sc1 #%x\n", IN(Portsc0), IN(Portsc1)); } - XPRINT("cleanq(ub->ctlq, 0, 0)\n"); - cleanq(ub->ctlq, 0, 0); - XPRINT("cleanq(ub->bulkq, 0, Vf)\n"); - cleanq(ub->bulkq, 0, Vf); - XPRINT("clean recvq\n"); - for (q = ub->recvq->next; q; q = q->hlink) { - XPRINT("cleanq(q, 0, Vf)\n"); - cleanq(q, 0, Vf); - } ilock(&activends); for(e = activends.f; e != nil; e = e->activef){ if(!e->iso && e->epq != nil) { @@ -1154,6 +1174,15 @@ interrupt(Ureg*, void *a) } } iunlock(&activends); + XPRINT("cleanq(ub->ctlq, 0, 0)\n"); + cleanq(ub->ctlq, 0, 0); + XPRINT("cleanq(ub->bulkq, 0, Vf)\n"); + cleanq(ub->bulkq, 0, Vf); + XPRINT("clean recvq\n"); + for (q = ub->recvq->next; q; q = q->hlink) { + XPRINT("cleanq(q, 0, Vf)\n"); + cleanq(q, 0, Vf); + } } enum @@ -1267,26 +1296,36 @@ usbreset(void) return; } ub = &ubus; - memset(&cfg, 0, sizeof(cfg)); - cfg = pcimatch(0, 0x8086, 0x7112); /* Intel chipset PIIX 4*/ - if(cfg == nil) { - cfg = pcimatch(0, 0x1106, 0x0586); /* Via chipset */ - if(cfg == nil) { - DPRINT("No USB device found\n"); - return; + cfg = nil; + while(cfg = pcimatch(cfg, 0, 0)){ + /* + * Look for devices with the correct class and + * sub-class code and known device and vendor ID. + */ + if(cfg->ccrb != 0x0C || cfg->ccru != 0x03) + continue; + switch(cfg->vid | cfg->did<<16){ + default: + continue; + case 0x8086 | 0x7112<<16: /* 82371[AE]B (PIIX4[E]) */ + case 0x8086 | 0x719A<<16: /* 82443MX */ + case 0x0586 | 0x1106<<16: /* VIA 82C586 */ + break; } + if((cfg->mem[4].bar & ~0x0F) != 0) + break; } - port = cfg->mem[4].bar & ~0x0F; - if (port == 0) { - print("usb: failed to map registers\n"); + if(cfg == nil) { + DPRINT("No USB device found\n"); return; } + port = cfg->mem[4].bar & ~0x0F; DPRINT("USB: %x/%x port 0x%lux size 0x%x irq %d\n", cfg->vid, cfg->did, port, cfg->mem[4].size, cfg->intl); i = inb(port+SOFMod); - if(1){ +if(0){ OUT(Cmd, 4); /* global reset */ delay(15); OUT(Cmd, 0); /* end reset */ @@ -1327,11 +1366,14 @@ usbreset(void) ub->recvq = allocqh(ub); t = alloctd(ub); /* inactive TD, looped */ t->link = PADDR(t); - ub->bwsop->entries = PADDR(t); - ub->ctlq->head = PADDR(ub->bwsop) | IsQH; - ub->bwsop->head = PADDR(ub->bulkq) | IsQH; + + ub->ctlq->head = PADDR(ub->bulkq) | IsQH; ub->bulkq->head = PADDR(ub->recvq) | IsQH; - ub->recvq->head = PADDR(ub->bwsop) | IsQH; /* loop back */ + ub->recvq->head = PADDR(ub->bwsop) | IsQH; + ub->bwsop->head = Terminate; /* loop back */ +// ub->bwsop->head = PADDR(ub->bwsop) | IsQH; /* loop back */ + ub->bwsop->entries = PADDR(t); + XPRINT("usbcmd\t0x%.4x\nusbsts\t0x%.4x\nusbintr\t0x%.4x\nfrnum\t0x%.2x\n", IN(Cmd), IN(Status), IN(Usbintr), inb(port+Frnum)); XPRINT("frbaseadd\t0x%.4x\nsofmod\t0x%x\nportsc1\t0x%.4x\nportsc2\t0x%.4x\n", @@ -1525,8 +1567,12 @@ usbopen(Chan *c, int omode) XPRINT("usbopen failed (endpoint)\n"); error(Enodev); } - if(schedendpt(e) < 0) - error("can't schedule USB endpoint"); + if(schedendpt(e) < 0){ + if (e->isopen) + error("can't schedule USB endpoint, isopen"); + else + error("can't schedule USB endpoint"); + } e->isopen++; eptactivate(e); } @@ -1615,18 +1661,21 @@ isoready(void *arg) } static long -isoio(Endpt *e, void *a, long n, int w) +isoio(Endpt *e, void *a, long n, vlong offset, int w) { int i, frnum; - uchar *p, *q; + uchar *p, *q, *bp; Ctlr *ub; TD *td; - p = a; + qlock(&e->rlock); if(waserror()){ e->isolock = 0; + qunlock(&e->rlock); + eptcancel(e); nexterror(); } + p = a; e->isolock = 1; do { td = e->etd; @@ -1657,11 +1706,10 @@ isoio(Endpt *e, void *a, long n, int w) e->psize = (e->etd->status + 1) & 0x7ff; if (e->psize > e->maxpkt) panic("packet size > maximum"); - e->nbytes += e->psize; - e->nblocks++; } td->flags &= ~IsoClean; - q = (uchar*)td->bp + e->off; + bp = e->bp0 + (td - e->td0) * e->maxpkt / e->pollms; + q = bp + e->off; if((i = n) >= e->psize) i = e->psize; if (w) @@ -1683,6 +1731,7 @@ isoio(Endpt *e, void *a, long n, int w) } while(n > 0); e->isolock = 0; poperror(); + qunlock(&e->rlock); return p-(uchar*)a; } @@ -1701,49 +1750,42 @@ readusb(Endpt *e, void *a, long n) eptcancel(e); nexterror(); } - if (e->iso){ - n = isoio(e, a, n, 0); - poperror(); - qunlock(&e->rlock); - return n; - }else{ - p = a; - do { - if(e->eof) { - XPRINT("e->eof\n"); - break; - } - if(e->err) - error(e->err); - qrcv(e); - if(!e->iso) - e->data01 ^= 1; - sleep(&e->rr, eptinput, e); - if(e->err) - error(e->err); - b = qget(e->rq); /* TO DO */ - if(b == nil) { - XPRINT("b == nil\n"); - break; - } - if(waserror()){ - freeb(b); - nexterror(); - } - l = BLEN(b); - if((i = l) > n) - i = n; - if(i > 0){ - memmove(p, b->rp, i); - p += i; - } - poperror(); + p = a; + do { + if(e->eof) { + XPRINT("e->eof\n"); + break; + } + if(e->err) + error(e->err); + qrcv(e); + if(!e->iso) + e->data01 ^= 1; + sleep(&e->rr, eptinput, e); + if(e->err) + error(e->err); + b = qget(e->rq); /* TO DO */ + if(b == nil) { + XPRINT("b == nil\n"); + break; + } + if(waserror()){ freeb(b); - n -= i; - if (l != e->maxpkt) - break; - } while (n > 0); - } + nexterror(); + } + l = BLEN(b); + if((i = l) > n) + i = n; + if(i > 0){ + memmove(p, b->rp, i); + p += i; + } + poperror(); + freeb(b); + n -= i; + if (l != e->maxpkt) + break; + } while (n > 0); poperror(); qunlock(&e->rlock); return p-(uchar*)a; @@ -1820,7 +1862,10 @@ usbread(Chan *c, void *a, long n, vlong offset) error(Eio); if((e = d->ep[t]) == nil || e->mode == OWRITE) error(Eio); /* can't happen */ - n=readusb(e, a, n); + if (e->iso) + n=isoio(e, a, n, offset, 0); + else + n=readusb(e, a, n); break; } return n; @@ -1846,51 +1891,43 @@ writeusb(Endpt *e, void *a, long n, int tok) eptcancel(e); nexterror(); } - if (e->iso){ - n = isoio(e, a, n, 1); + p = a; + do { + int j; + + if(e->err) + error(e->err); + if((i = n) >= e->maxpkt) + i = e->maxpkt; + b = allocb(i); + if(waserror()){ + freeb(b); + nexterror(); + } + XPRINT("out [%d]", i); + for (j = 0; j < i; j++) XPRINT(" %.2x", p[j]); + XPRINT("\n"); + memmove(b->wp, p, i); + b->wp += i; + p += i; + n -= i; poperror(); - qunlock(&e->wlock); - return n; - }else{ - p = a; - do { - int j; - - if(e->err) - error(e->err); - if((i = n) >= e->maxpkt) - i = e->maxpkt; - b = allocb(i); - if(waserror()){ - freeb(b); - nexterror(); - } - XPRINT("out [%d]", i); - for (j = 0; j < i; j++) XPRINT(" %.2x", p[j]); - XPRINT("\n"); - memmove(b->wp, p, i); - b->wp += i; - p += i; - n -= i; - poperror(); - qh = qxmit(e, b, tok); - tok = TokOUT; - if(!e->iso) - e->data01 ^= 1; - if(e->ntd >= e->nbuf) { - XPRINT("writeusb: sleep %lux\n", &e->wr); - sleep(&e->wr, qisempty, qh); - XPRINT("writeusb: awake\n"); - } - } while(n > 0); - } + qh = qxmit(e, b, tok); + tok = TokOUT; + e->data01 ^= 1; + if(e->ntd >= e->nbuf) { + XPRINT("writeusb: sleep %lux\n", &e->wr); + sleep(&e->wr, qisempty, qh); + XPRINT("writeusb: awake\n"); + } + } while(n > 0); poperror(); qunlock(&e->wlock); return p-(uchar*)a; } long -usbwrite(Chan *c, void *a, long n, vlong) +usbwrite(Chan *c, void *a, long n, vlong offset) { Udev *d; Endpt *e; @@ -2084,7 +2121,10 @@ usbwrite(Chan *c, void *a, long n, vlong) if((e = d->ep[t]) == nil || e->mode == OREAD) { error(Eio); /* can't happen */ } - n = writeusb(e, a, n, TokOUT); + if (e->iso) + n = isoio(e, a, n, offset, 1); + else + n = writeusb(e, a, n, TokOUT); break; } return n; diff --git a/pc/etherwavelan.c b/pc/etherwavelan.c index 548588c6b56ff4214963084e4d9eec16112e9f18..139b2e6be97d4f4a0c9281c497447be9ba274e28 100644 --- a/pc/etherwavelan.c +++ b/pc/etherwavelan.c @@ -1187,13 +1187,19 @@ interrupt(Ureg* ,void* arg) iunlock(&ctlr->Lock); } +static char* wavenames[] = { + "WaveLAN/IEEE", + "TrueMobile 1150", + nil, +}; + static int reset(Ether* ether) { int i; Wltv ltv; Ctlr* ctlr; - char *p; + char *name, *p; if((ctlr = malloc(sizeof(Ctlr))) == nil) return -1; @@ -1212,12 +1218,25 @@ reset(Ether* ether) goto abort1; } - if ((ctlr->slot = pcmspecial("WaveLAN/IEEE", ether))<0){ - if ((ctlr->slot = pcmspecial("TrueMobile 1150", ether))<0){ + for (i=0; wavenames[i]; i++) + if ((ctlr->slot = pcmspecial(wavenames[i], ether))>=0) + break; + name = wavenames[i]; + + if (name == nil){ + for (i=0; inopt; i++){ + if (cistrncmp(ether->opt[i], "id=", 3) == 0){ + name = ðer->opt[i][3]; + if ((ctlr->slot = pcmspecial(name, ether)) < 0) + name = nil; + } + } + if (name == nil){ DEBUG("no wavelan found\n"); goto abort; } } + // DEBUG("#l%d: port=0x%lx irq=%ld\n", // ether->ctlrno, ether->port, ether->irq); diff --git a/pc/uarti8250.c b/pc/uarti8250.c index 3e3f013aceab3cf4c0eaafcafb1ae51bc6fef699..b68e3e0dd4c9aefc1754dce1755297ecb8f084fb 100644 --- a/pc/uarti8250.c +++ b/pc/uarti8250.c @@ -657,7 +657,7 @@ i8250console(void) } uartctl(uart, "b9600 l8 pn s1"); - if(*cmd != nil) + if(*cmd != '\0') uartctl(uart, cmd); (*uart->phys->enable)(uart, 0);