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/pc/usbohci.c | |
parent | 89ab1f286e7c9c5f21109eaf351e5e3c195fb337 (diff) |
usb: added buffer delay control
Diffstat (limited to 'sys/src/9/pc/usbohci.c')
-rw-r--r-- | sys/src/9/pc/usbohci.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/sys/src/9/pc/usbohci.c b/sys/src/9/pc/usbohci.c index c0a790ff9..003a5e7ee 100644 --- a/sys/src/9/pc/usbohci.c +++ b/sys/src/9/pc/usbohci.c @@ -220,6 +220,7 @@ struct Isoio ulong frno; /* next frame number avail for I/O */ ulong left; /* remainder after rounding Hz to samples/ms */ int nerrs; /* consecutive errors on iso I/O */ + int delay; /* maximum number of frames to buffer */ }; /* @@ -1101,6 +1102,17 @@ isocanwrite(void *a) iso->navail > iso->nframes / 2; } +static int +isodelay(void *a) +{ + Isoio *iso; + + iso = a; + if(iso->state == Qclose || iso->err != nil || iso->delay == 0) + return 1; + return (iso->nframes - iso->navail) <= iso->delay; +} + /* * Service a completed/failed Td from the done queue. * It may be of any transfer type. @@ -1780,6 +1792,7 @@ episowrite(Ep *ep, void *a, long count) ctlr = ep->hp->aux; iso = ep->aux; + iso->delay = (ep->sampledelay*ep->samplesz + ep->maxpkt-1) / ep->maxpkt; iso->debug = ep->debug; qlock(iso); @@ -1821,6 +1834,11 @@ episowrite(Ep *ep, void *a, long count) nw = putsamples(ctlr, ep, 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); |