shithub: riscv

Download patch

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,