NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/55919: Creative HP-BTW3 (BT-W3) USB audio device has another descriptor layout



>Number:         55919
>Category:       kern
>Synopsis:       Creative HP-BTW3 (BT-W3) USB audio device has another descriptor layout
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Jan 10 19:05:00 +0000 2021
>Originator:     Ryo ONODERA
>Release:        NetBSD 9.99.77
>Organization:
Ryo ONODERA // ryo%tetera.org@localhost
PGP fingerprint = 82A2 DC91 76E0 A10A 8ABB  FD1B F404 27FA C7D1 15F3
>Environment:
System: NetBSD brownie 9.99.77 NetBSD 9.99.77 (DTRACE7) #44: Mon Jan 11 02:23:28 JST 2021 ryoon@brownie:/usr/world/9.99/amd64/obj/sys/arch/amd64/compile/DTRACE7 amd64
Architecture: x86_64
Machine: amd64
>Description:
Creative HP-BTW# (BT-W3) USB audio device has usb_audio_streaming_endpoint_descriptor is placed before usb_endpoint_descriptor_audio_t.
And I get "no usable endpoint found" error from uaudio(4).
>How-To-Repeat:
Connect BT-W3.
>Fix:
My idea is as follows.

Index: sys/dev/usb/uaudio.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/uaudio.c,v
retrieving revision 1.168
diff -u -r1.168 uaudio.c
--- sys/dev/usb/uaudio.c	10 Jan 2021 15:50:16 -0000	1.168
+++ sys/dev/usb/uaudio.c	10 Jan 2021 18:57:45 -0000
@@ -1536,6 +1536,7 @@
 	const struct usb_audio_streaming_type1_descriptor *asf1d;
 	const usb_endpoint_descriptor_audio_t *ed;
 	const usb_endpoint_descriptor_audio_t *epdesc1;
+	const usb_config_descriptor_t *desc;
 	const struct usb_audio_streaming_endpoint_descriptor *sed;
 	int format, chan __unused, prec, enc;
 	int dir, type, sync;
@@ -1566,7 +1567,21 @@
 		return USBD_NORMAL_COMPLETION;
 	}
 
-	ed = (const void *)(tbuf + offs);
+	desc = (const void *)(tbuf + offs);
+	if (desc->bDescriptorType == UDESC_ENDPOINT) {
+		ed = (const void *)desc;
+		offs += ed->bLength;
+		sed = (const void *)(tbuf + offs);
+		offs += sed->bLength;
+	} else if (desc->bDescriptorType == UDESC_CS_ENDPOINT) {
+		sed = (const void *)desc;
+		offs += sed->bLength;
+		ed = (const void *)(tbuf + offs);
+		offs += ed->bLength;
+	} else {
+		return USBD_INVAL;
+	}
+
 	if (ed->bDescriptorType != UDESC_ENDPOINT)
 		return USBD_INVAL;
 	DPRINTF("endpoint[0] bLength=%d bDescriptorType=%d "
@@ -1575,7 +1590,6 @@
 		 ed->bLength, ed->bDescriptorType, ed->bEndpointAddress,
 		 ed->bmAttributes, UGETW(ed->wMaxPacketSize),
 		 ed->bInterval, ed->bRefresh, ed->bSynchAddress);
-	offs += ed->bLength;
 	if (offs > size)
 		return USBD_INVAL;
 	if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS)
@@ -1606,12 +1620,10 @@
 #endif
 	}
 
-	sed = (const void *)(tbuf + offs);
 	if (sed->bDescriptorType != UDESC_CS_ENDPOINT ||
 	    sed->bDescriptorSubtype != AS_GENERAL)
 		return USBD_INVAL;
 	DPRINTF(" streadming_endpoint: offset=%d bLength=%d\n", offs, sed->bLength);
-	offs += sed->bLength;
 	if (offs > size)
 		return USBD_INVAL;
 



Home | Main Index | Thread Index | Old Index