ref: 229d14ae06ab148aa7185ed7cb21f410f49a93a9
parent: d263e43424c90198f5ed8b84a381bf86f3dccbe5
author: Michael Forney <mforney@mforney.org>
date: Fri Nov 18 04:11:50 EST 2022
nusb/audio: only consider data endpoints when setting up An async iso endpoint has a data endpoint and feedback endpoint, and both get mapped to the same slot in d->usb->ep. However, when setting up audio streams, we are only interested in the data endpoints. If the feedback endpoint appears first in the list, we end up trying to use feedback endpoints for audio data and ignore the data endpoints.
--- a/sys/src/cmd/nusb/audio/audio.c
+++ b/sys/src/cmd/nusb/audio/audio.c
@@ -231,30 +231,36 @@
parsedescr(d->usb->ddesc[i]);
for(i = 0; i < nelem(d->usb->ep); i++){
e = d->usb->ep[i];
- if(e != nil && e->type == Eiso && e->iface->csp == CSP(Claudio, 2, 0)){
- switch(e->dir){
- case Ein:
- if(audioepin != nil)
- continue;
- audioepin = e;
+ if(e == nil || e->type != Eiso || e->iface->csp != CSP(Claudio, 2, 0))
+ continue;
+ for(; e != nil; e = e->next){
+ if((e->attrib>>4 & 3) == Edata)
break;
- case Eout:
- if(audioepout != nil)
- continue;
- audioepout = e;
- break;
- }
- if((ed = setupep(audiodev, e, audiofreq)) == nil){
- fprint(2, "setupep: %r\n");
-
- if(e == audioepin)
- audioepin = nil;
- if(e == audioepout)
- audioepout = nil;
+ }
+ if(e == nil)
+ continue;
+ switch(e->dir){
+ case Ein:
+ if(audioepin != nil)
continue;
- }
- closedev(ed);
+ audioepin = e;
+ break;
+ case Eout:
+ if(audioepout != nil)
+ continue;
+ audioepout = e;
+ break;
}
+ if((ed = setupep(audiodev, e, audiofreq)) == nil){
+ fprint(2, "setupep: %r\n");
+
+ if(e == audioepin)
+ audioepin = nil;
+ if(e == audioepout)
+ audioepout = nil;
+ continue;
+ }
+ closedev(ed);
}
if(audioepout == nil)
sysfatal("no endpoints found");
--- a/sys/src/cmd/nusb/lib/usb.h
+++ b/sys/src/cmd/nusb/lib/usb.h
@@ -100,6 +100,11 @@
Ebulk = 2,
Eintr = 3,
+ /* endpoint isousage */
+ Edata = 0,
+ Efeedback = 1,
+ Eimplicit = 2,
+
/* config attrib */
Cbuspowered = 1<<7,
Cselfpowered = 1<<6,