From 7bff2baeaead80a5453d822a00b3c98c954b0d69 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Mon, 17 Sep 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-09-17 --- pc/devusb.c | 128 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 99 insertions(+), 29 deletions(-) diff --git a/pc/devusb.c b/pc/devusb.c index 2cd2492f061bb2608805e900b8571a2b9421857c..d9201ee36751e51d7fe993f7612df2d8a3a6507f 100644 --- a/pc/devusb.c +++ b/pc/devusb.c @@ -714,6 +714,44 @@ isoxmit(Endpt *e, Block *b, int pid) return ob; } +static Block* +isorecv(Endpt *e, Block *b, int pid) +{ + TD *td; + int n, id; + Block *ob; + static int ioc; + + td = e->etd; + if (td == nil) + panic("usb: isoxmit"); + while(td->status & Active){ + XPRINT("isorecv: sleep %lux\n", &e->wr); + sleep(&e->wr, tdisready, e->etd); + XPRINT("isorecv: awake\n"); + } + if (td->status & AnyError) + iprint("usbisoerror 0x%lux\n", td->status); + ob = td->bp; + if (ob == nil) + panic("isorecv: null block"); + n = (td->status + 1) & 0x7FF; + if(n > ob->lim - b->wp) + n = 0; + ob->wp = ob->rp + n; + td->buffer = PADDR(b->rp); + td->bp = b; + n = BLEN(b); + id = (e->x<<7)|(e->dev->x&0x7F); + td->dev = ((n-1)<<21) | ((id&0x7FF)<<8) | pid; + if ((ioc++ & 0xff) == 0) + td->status = ErrLimit3 | Active | IsoSelect | IOC; + else + td->status = ErrLimit3 | Active | IsoSelect; + e->etd = td->next; + return ob; +} + static QH* qxmit(Endpt *e, Block *b, int pid) { @@ -835,14 +873,14 @@ schedendpt(Endpt *e) TD *td, **prev, *first; int i, j; - e->curblock = allocb(e->maxpkt); - if (e->curblock == nil) - panic("schedept: allocb"); - e->curbytes = 0; if(!e->iso || e->sched >= 0) return 0; ub = &ubus; + e->curblock = allocb(e->maxpkt); + if (e->curblock == nil) + panic("schedept: allocb"); + e->curbytes = 0; ilock(ub); e->sched = usbsched(ub, e->pollms, e->maxpkt); if(e->sched < 0) @@ -1602,32 +1640,65 @@ readusb(Endpt *e, void *a, long n) } 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); + if (e->iso){ + if (e->curbytes == 0){ + /* calculate size of next receive buffer */ + e->psize = (e->hz + e->remain)*e->pollms/1000; + e->remain = (e->hz + e->remain)*e->pollms%1000; + e->psize *= e->samplesz; + if (e->psize > e->maxpkt) + panic("packet size > maximum"); + e->curblock->wp = e->curblock->rp + e->psize; + /* put empty buffer on receive queue and get next full one */ + b = isorecv(e, e->curblock, TokIN); + /* bytes to consume in b: */ + e->curbytes = BLEN(b); + b->wp = b->rp; + e->nbytes += e->curbytes; + e->nblocks++; + }else{ + b = e->curblock; + } + if (b == nil) + panic("readusb: block"); + if((i = n) >= e->curbytes) + i = e->curbytes; + memmove(p, b->wp, i); + b->wp += i; p += i; + n -= i; + e->curbytes -= i; + e->curblock = b; + }else{ + 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(); + freeb(b); + n -= i; + if (l != e->maxpkt) + break; } - poperror(); - freeb(b); - n -= i; - } while (l == e->maxpkt && n > 0); + } while (n > 0); poperror(); qunlock(&e->rlock); return p-(uchar*)a; @@ -1727,7 +1798,6 @@ writeusb(Endpt *e, void *a, long n, int tok) nexterror(); } do { - if(e->err) error(e->err); if (e->iso){