summaryrefslogtreecommitdiff
path: root/sys/src/9/pc/usbohci.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@localhost>2011-08-01 19:02:50 +0200
committercinap_lenrek <cinap_lenrek@localhost>2011-08-01 19:02:50 +0200
commit676a876df607eda5488d7635592a99228066d0f9 (patch)
tree624a13da9b0f0fc5dc107fe2e69fda149f5220ae /sys/src/9/pc/usbohci.c
parent89ab1f286e7c9c5f21109eaf351e5e3c195fb337 (diff)
usb: added buffer delay control
Diffstat (limited to 'sys/src/9/pc/usbohci.c')
-rw-r--r--sys/src/9/pc/usbohci.c18
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);