diff options
author | cinap_lenrek <cinap_lenrek@localhost> | 2011-08-01 19:02:50 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@localhost> | 2011-08-01 19:02:50 +0200 |
commit | 676a876df607eda5488d7635592a99228066d0f9 (patch) | |
tree | 624a13da9b0f0fc5dc107fe2e69fda149f5220ae /sys/src/9/port/usbehci.c | |
parent | 89ab1f286e7c9c5f21109eaf351e5e3c195fb337 (diff) |
usb: added buffer delay control
Diffstat (limited to 'sys/src/9/port/usbehci.c')
-rw-r--r-- | sys/src/9/port/usbehci.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/sys/src/9/port/usbehci.c b/sys/src/9/port/usbehci.c index e6ff879e3..56aae9371 100644 --- a/sys/src/9/port/usbehci.c +++ b/sys/src/9/port/usbehci.c @@ -215,6 +215,7 @@ struct Isoio ulong maxsize; /* ntds * ep->maxpkt */ long nleft; /* number of bytes left from last write */ int debug; /* debug flag from the endpoint */ + int delay; /* max number of bytes to buffer */ int hs; /* is high speed? */ Isoio* next; /* in list of active Isoios */ ulong td0frno; /* first frame used in ctlr */ @@ -1291,6 +1292,43 @@ itdactive(Itd *td) } static int +isodelay(void *a) +{ + Isoio *iso; + int delay; + + iso = a; + if(iso->state == Qclose || iso->err || iso->delay == 0) + return 1; + + delay = 0; + if(iso->hs){ + Itd *i; + + for(i = iso->tdi; i->next != iso->tdu; i = i->next){ + if(!itdactive(i)) + continue; + delay += i->mdata; + if(delay > iso->delay) + break; + } + } else { + Sitd *i; + + for(i = iso->stdi; i->next != iso->stdu; i = i->next){ + if((i->csw & Stdactive) == 0) + continue; + delay += i->mdata; + if(delay > iso->delay) + break; + } + } + + return delay <= iso->delay; +} + + +static int isohsinterrupt(Ctlr *ctlr, Isoio *iso) { int err, i, nframes, t; @@ -1996,6 +2034,7 @@ episowrite(Ep *ep, Isoio *iso, void *a, long count) int tot, nw; char *err; + iso->delay = ep->sampledelay * ep->samplesz; iso->debug = ep->debug; diprint("ehci: episowrite: %#p ep%d.%d\n", iso, ep->dev->nb, ep->nb); @@ -2039,6 +2078,11 @@ episowrite(Ep *ep, Isoio *iso, void *a, long count) nw = putsamples(iso, b+tot, count-tot); ilock(ctlr); } + while(isodelay(iso) == 0){ + iunlock(ctlr); + sleep(iso, isodelay, iso); + ilock(ctlr); + } if(iso->state != Qclose) iso->state = Qdone; iunlock(ctlr); |