NetBSD Problem Report #55919

From ryo@tetera.org  Sun Jan 10 19:01:17 2021
Return-Path: <ryo@tetera.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 63B2A1A9217
	for <gnats-bugs@gnats.NetBSD.org>; Sun, 10 Jan 2021 19:01:17 +0000 (UTC)
Message-Id: <5ffb4efa.1c69fb81.1347c.5085@mx.google.com>
Date: Mon, 11 Jan 2021 04:00:50 +0900
From: ryo@tetera.org
Reply-To: ryo@tetera.org
To: gnats-bugs@NetBSD.org
Subject: Creative HP-BTW3 (BT-W3) USB audio device has another descriptor layout
X-Send-Pr-Version: 3.95

>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
>Last-Modified:  Tue Feb 23 14:25:01 +0000 2021
>Originator:     Ryo ONODERA
>Release:        NetBSD 9.99.77
>Organization:
Ryo ONODERA // ryo@tetera.org
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;


>Audit-Trail:
From: Ryo ONODERA <ryo@tetera.org>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/55919: Creative HP-BTW3 (BT-W3) USB audio device has
 another descriptor layout
Date: Sat, 30 Jan 2021 04:51:16 +0900

 Hi,

 I have rewrite my patch.
 As far as I understand correctly, the order of descriptors is not
 specified in spec, 
 https://usb.org/sites/default/files/audio10.pdf .

 My patch is here:
 http://www.ryoon.net/~ryoon/sys-dev-uaudio.c-2.diff

 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	29 Jan 2021 19:36:18 -0000
 @@ -1532,52 +1532,63 @@
  		  int size, const usb_interface_descriptor_t *id)
  #define offs (*offsp)
  {
 -	const struct usb_audio_streaming_interface_descriptor *asid;
 -	const struct usb_audio_streaming_type1_descriptor *asf1d;
 -	const usb_endpoint_descriptor_audio_t *ed;
 -	const usb_endpoint_descriptor_audio_t *epdesc1;
 -	const struct usb_audio_streaming_endpoint_descriptor *sed;
 +	const struct usb_audio_streaming_interface_descriptor *asid = NULL;
 +	const struct usb_audio_streaming_type1_descriptor *asf1d = NULL;
 +	const usb_endpoint_descriptor_audio_t *ed = NULL;
 +	const usb_endpoint_descriptor_audio_t *epdesc1 = NULL;
 +	const struct usb_audio_streaming_endpoint_descriptor *sed = NULL;
 +	const usb_descriptor_t *desc = NULL;
  	int format, chan __unused, prec, enc;
  	int dir, type, sync;
  	struct as_info ai;
  	const char *format_str __unused;

 -	asid = (const void *)(tbuf + offs);
 -	if (asid->bDescriptorType != UDESC_CS_INTERFACE ||
 -	    asid->bDescriptorSubtype != AS_GENERAL)
 +	while (offs < size) {
 +		desc = (const void *)(tbuf + offs);
 +
 +		if (desc->bDescriptorType == UDESC_CS_INTERFACE &&
 +		    desc->bDescriptorSubtype == AS_GENERAL) {
 +			asid = (const void *)desc;
 +			offs += asid->bLength;
 +		} else if (desc->bDescriptorType == UDESC_CS_INTERFACE &&
 +			   desc->bDescriptorSubtype == FORMAT_TYPE) {
 +			asf1d = (const void *)desc;
 +			offs += asf1d->bLength;
 +		} else if (desc->bDescriptorType == UDESC_ENDPOINT) {
 +			ed = (const void *)desc;
 +			offs += ed->bLength;
 +		} else if (desc->bDescriptorType == UDESC_CS_ENDPOINT &&
 +	    		   desc->bDescriptorSubtype == AS_GENERAL) {
 +			sed = (const void *)desc;
 +			offs += sed->bLength;
 +		} else if (ed != NULL && id->bNumEndpoints > 1 &&
 +			   desc->bDescriptorType == UDESC_ENDPOINT) {
 +			epdesc1 = (const void*)desc;
 +			offs += epdesc1->bLength;
 +		} else
 +			break;
 +	}
 +
 +	if (asid == NULL || asf1d == NULL || ed == NULL || sed == NULL ||
 +	    (id->bNumEndpoints > 1 && epdesc1 == NULL))
  		return USBD_INVAL;
 +
 +	format = UGETW(asid->wFormatTag);
  	DPRINTF("asid: bTerminalLink=%d wFormatTag=%d\n",
  		 asid->bTerminalLink, UGETW(asid->wFormatTag));
 -	offs += asid->bLength;
 -	if (offs > size)
 -		return USBD_INVAL;
 -
 -	asf1d = (const void *)(tbuf + offs);
 -	if (asf1d->bDescriptorType != UDESC_CS_INTERFACE ||
 -	    asf1d->bDescriptorSubtype != FORMAT_TYPE)
 -		return USBD_INVAL;
 -	offs += asf1d->bLength;
 -	if (offs > size)
 -		return USBD_INVAL;

  	if (asf1d->bFormatType != FORMAT_TYPE_I) {
  		aprint_normal_dev(sc->sc_dev,
 -		    "ignored setting with type %d format\n", UGETW(asid->wFormatTag));
 +		    "ignored setting with type %d format\n", format);
  		return USBD_NORMAL_COMPLETION;
  	}

 -	ed = (const void *)(tbuf + offs);
 -	if (ed->bDescriptorType != UDESC_ENDPOINT)
 -		return USBD_INVAL;
  	DPRINTF("endpoint[0] bLength=%d bDescriptorType=%d "
  		 "bEndpointAddress=%d bmAttributes=%#x wMaxPacketSize=%d "
  		 "bInterval=%d bRefresh=%d bSynchAddress=%d\n",
  		 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)
  		return USBD_INVAL;

 @@ -1606,14 +1617,7 @@
  #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;

  #ifdef UAUDIO_MULTIPLE_ENDPOINTS
  	if (sync && id->bNumEndpoints <= 1) {
 @@ -1627,11 +1631,7 @@
  		    "non sync-pipe endpoint but multiple endpoints\n");
  		return USBD_INVAL;
  	}
 -	epdesc1 = NULL;
  	if (id->bNumEndpoints > 1) {
 -		epdesc1 = (const void*)(tbuf + offs);
 -		if (epdesc1->bDescriptorType != UDESC_ENDPOINT)
 -			return USBD_INVAL;
  		DPRINTF("endpoint[1] bLength=%d "
  			 "bDescriptorType=%d bEndpointAddress=%d "
  			 "bmAttributes=%#x wMaxPacketSize=%d bInterval=%d "
 @@ -1640,9 +1640,6 @@
  			 epdesc1->bEndpointAddress, epdesc1->bmAttributes,
  			 UGETW(epdesc1->wMaxPacketSize), epdesc1->bInterval,
  			 epdesc1->bRefresh, epdesc1->bSynchAddress);
 -		offs += epdesc1->bLength;
 -		if (offs > size)
 -			return USBD_INVAL;
  		if (epdesc1->bSynchAddress != 0) {
  			aprint_error_dev(sc->sc_dev,
  			    "invalid endpoint: bSynchAddress=0\n");
 @@ -1665,7 +1662,6 @@
  		/* UE_GET_ADDR(epdesc1->bEndpointAddress), and epdesc1->bRefresh */
  	}

 -	format = UGETW(asid->wFormatTag);
  	chan = asf1d->bNrChannels;
  	prec = asf1d->bBitResolution;
  	if (prec != 8 && prec != 16 && prec != 24) {

 -- 
 Ryo ONODERA // ryo@tetera.org
 PGP fingerprint = 82A2 DC91 76E0 A10A 8ABB  FD1B F404 27FA C7D1 15F3

From: Ryo ONODERA <ryo@tetera.org>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/55919: Creative HP-BTW3 (BT-W3) USB audio device has
 another descriptor layout
Date: Wed, 10 Feb 2021 23:32:13 +0900

 Hi,

 Could anyone review my second patch and give me comments?
 See: http://www.ryoon.net/~ryoon/sys-dev-uaudio.c-2.diff

 Thank you.

 -- 
 Ryo ONODERA // ryo@tetera.org
 PGP fingerprint = 82A2 DC91 76E0 A10A 8ABB  FD1B F404 27FA C7D1 15F3

From: matthew green <mrg@eterna.com.au>
To: gnats-bugs@netbsd.org
Cc: kern-bug-people@netbsd.org, gnats-admin@netbsd.org,
    netbsd-bugs@netbsd.org, ryo@tetera.org
Subject: re: kern/55919: Creative HP-BTW3 (BT-W3) USB audio device has another descriptor layout
Date: Mon, 15 Feb 2021 18:34:52 +1100

 +       while (offs < size) {
 +               desc = (const void *)(tbuf + offs);

 should this be "offs <= size - sizeof(*desc)"?  so that we
 don't attempt to read beyond the buffer for this part, and
 these should probably check the larger structure size before
 deciding it's valid:

 +                       asid = (const void *)desc;
 +                       offs += asid->bLength;

 +                       asf1d = (const void *)desc;
 +                       offs += asf1d->bLength;

 etc..

 rest LGTM.  would be nice to have tested on many usb audio
 devices :)


 .mrg.

From: Ryo ONODERA <ryo@tetera.org>
To: matthew green <mrg@eterna.com.au>, gnats-bugs@netbsd.org
Cc: kern-bug-people@netbsd.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Subject: re: kern/55919: Creative HP-BTW3 (BT-W3) USB audio device has
 another descriptor layout
Date: Mon, 15 Feb 2021 22:30:46 +0900

 Hi,

 matthew green <mrg@eterna.com.au> writes:

 > +       while (offs < size) {
 > +               desc = (const void *)(tbuf + offs);
 >
 > should this be "offs <= size - sizeof(*desc)"?  so that we
 > don't attempt to read beyond the buffer for this part, and
 > these should probably check the larger structure size before
 > deciding it's valid:
 >
 > +                       asid = (const void *)desc;
 > +                       offs += asid->bLength;
 >
 > +                       asf1d = (const void *)desc;
 > +                       offs += asf1d->bLength;
 >
 > etc..
 >
 > rest LGTM.  would be nice to have tested on many usb audio
 > devices :)

 Thanks for your comment.
 I have tried to fixed two issues.

 How about this?

 http://www.ryoon.net/~ryoon/sys-dev-usb-uaudio-3.diff

 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	15 Feb 2021 13:28:02 -0000
 @@ -1532,52 +1532,73 @@
  		  int size, const usb_interface_descriptor_t *id)
  #define offs (*offsp)
  {
 -	const struct usb_audio_streaming_interface_descriptor *asid;
 -	const struct usb_audio_streaming_type1_descriptor *asf1d;
 -	const usb_endpoint_descriptor_audio_t *ed;
 -	const usb_endpoint_descriptor_audio_t *epdesc1;
 -	const struct usb_audio_streaming_endpoint_descriptor *sed;
 +	const struct usb_audio_streaming_interface_descriptor *asid = NULL;
 +	const struct usb_audio_streaming_type1_descriptor *asf1d = NULL;
 +	const usb_endpoint_descriptor_audio_t *ed = NULL;
 +	const usb_endpoint_descriptor_audio_t *epdesc1 = NULL;
 +	const struct usb_audio_streaming_endpoint_descriptor *sed = NULL;
 +	const usb_descriptor_t *desc = NULL;
  	int format, chan __unused, prec, enc;
  	int dir, type, sync;
  	struct as_info ai;
  	const char *format_str __unused;

 -	asid = (const void *)(tbuf + offs);
 -	if (asid->bDescriptorType != UDESC_CS_INTERFACE ||
 -	    asid->bDescriptorSubtype != AS_GENERAL)
 -		return USBD_INVAL;
 -	DPRINTF("asid: bTerminalLink=%d wFormatTag=%d\n",
 -		 asid->bTerminalLink, UGETW(asid->wFormatTag));
 -	offs += asid->bLength;
 -	if (offs > size)
 -		return USBD_INVAL;
 +	while (offs <= size - sizeof(*desc)) {
 +		desc = (const void *)(tbuf + offs);

 -	asf1d = (const void *)(tbuf + offs);
 -	if (asf1d->bDescriptorType != UDESC_CS_INTERFACE ||
 -	    asf1d->bDescriptorSubtype != FORMAT_TYPE)
 -		return USBD_INVAL;
 -	offs += asf1d->bLength;
 -	if (offs > size)
 +		if (desc->bDescriptorType == UDESC_CS_INTERFACE &&
 +		    desc->bDescriptorSubtype == AS_GENERAL) {
 +			offs += desc->bLength;
 +			if (offs > size)
 +				return USBD_INVAL;
 +			asid = (const void *)desc;
 +		} else if (desc->bDescriptorType == UDESC_CS_INTERFACE &&
 +			   desc->bDescriptorSubtype == FORMAT_TYPE) {
 +			offs += desc->bLength;
 +			if (offs > size)
 +				return USBD_INVAL;
 +			asf1d = (const void *)desc;
 +		} else if (desc->bDescriptorType == UDESC_ENDPOINT) {
 +			offs += desc->bLength;
 +			if (offs > size)
 +				return USBD_INVAL;
 +			ed = (const void *)desc;
 +		} else if (desc->bDescriptorType == UDESC_CS_ENDPOINT &&
 +	    		   desc->bDescriptorSubtype == AS_GENERAL) {
 +			offs += desc->bLength;
 +			if (offs > size)
 +				return USBD_INVAL;
 +			sed = (const void *)desc;
 +		} else if (ed != NULL && id->bNumEndpoints > 1 &&
 +			   desc->bDescriptorType == UDESC_ENDPOINT) {
 +			offs += desc->bLength;
 +			if (offs > size)
 +				return USBD_INVAL;
 +			epdesc1 = (const void*)desc;
 +		} else
 +			break;
 +	}
 +
 +	if (asid == NULL || asf1d == NULL || ed == NULL || sed == NULL ||
 +	    (id->bNumEndpoints > 1 && epdesc1 == NULL))
  		return USBD_INVAL;

 +	format = UGETW(asid->wFormatTag);
 +	DPRINTF("asid: bTerminalLink=%d wFormatTag=%d\n",
 +		 asid->bTerminalLink, format);
 +
  	if (asf1d->bFormatType != FORMAT_TYPE_I) {
  		aprint_normal_dev(sc->sc_dev,
 -		    "ignored setting with type %d format\n", UGETW(asid->wFormatTag));
 +		    "ignored setting with type %d format\n", format);
  		return USBD_NORMAL_COMPLETION;
  	}

 -	ed = (const void *)(tbuf + offs);
 -	if (ed->bDescriptorType != UDESC_ENDPOINT)
 -		return USBD_INVAL;
  	DPRINTF("endpoint[0] bLength=%d bDescriptorType=%d "
  		 "bEndpointAddress=%d bmAttributes=%#x wMaxPacketSize=%d "
  		 "bInterval=%d bRefresh=%d bSynchAddress=%d\n",
  		 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)
  		return USBD_INVAL;

 @@ -1606,14 +1627,7 @@
  #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;

  #ifdef UAUDIO_MULTIPLE_ENDPOINTS
  	if (sync && id->bNumEndpoints <= 1) {
 @@ -1627,11 +1641,7 @@
  		    "non sync-pipe endpoint but multiple endpoints\n");
  		return USBD_INVAL;
  	}
 -	epdesc1 = NULL;
  	if (id->bNumEndpoints > 1) {
 -		epdesc1 = (const void*)(tbuf + offs);
 -		if (epdesc1->bDescriptorType != UDESC_ENDPOINT)
 -			return USBD_INVAL;
  		DPRINTF("endpoint[1] bLength=%d "
  			 "bDescriptorType=%d bEndpointAddress=%d "
  			 "bmAttributes=%#x wMaxPacketSize=%d bInterval=%d "
 @@ -1640,9 +1650,6 @@
  			 epdesc1->bEndpointAddress, epdesc1->bmAttributes,
  			 UGETW(epdesc1->wMaxPacketSize), epdesc1->bInterval,
  			 epdesc1->bRefresh, epdesc1->bSynchAddress);
 -		offs += epdesc1->bLength;
 -		if (offs > size)
 -			return USBD_INVAL;
  		if (epdesc1->bSynchAddress != 0) {
  			aprint_error_dev(sc->sc_dev,
  			    "invalid endpoint: bSynchAddress=0\n");
 @@ -1665,7 +1672,6 @@
  		/* UE_GET_ADDR(epdesc1->bEndpointAddress), and epdesc1->bRefresh */
  	}

 -	format = UGETW(asid->wFormatTag);
  	chan = asf1d->bNrChannels;
  	prec = asf1d->bBitResolution;
  	if (prec != 8 && prec != 16 && prec != 24) {


 > .mrg.

 -- 
 Ryo ONODERA // ryo@tetera.org
 PGP fingerprint = 82A2 DC91 76E0 A10A 8ABB  FD1B F404 27FA C7D1 15F3

From: Ryo ONODERA <ryo@tetera.org>
To: matthew green <mrg@eterna.com.au>, gnats-bugs@netbsd.org
Cc: 
Subject: re: kern/55919: Creative HP-BTW3 (BT-W3) USB audio device has
 another descriptor layout
Date: Mon, 15 Feb 2021 22:35:49 +0900

 Hi,

 I have tested with the following devices.

 * Sennheiser PC 8 USB headset
   This device has conventional descriptor layout.
 * Creative BT-W3 Bluetooth audio to USB converter

 I have only these two USB devices.
 These devices works fine.

 Thank you.

 -- 
 Ryo ONODERA // ryo@tetera.org
 PGP fingerprint = 82A2 DC91 76E0 A10A 8ABB  FD1B F404 27FA C7D1 15F3

From: matthew green <mrg@eterna.com.au>
To: Ryo ONODERA <ryo@tetera.org>
Cc: kern-bug-people@netbsd.org, gnats-admin@netbsd.org,
    netbsd-bugs@netbsd.org, gnats-bugs@netbsd.org
Subject: re: kern/55919: Creative HP-BTW3 (BT-W3) USB audio device has another descriptor layout
Date: Tue, 16 Feb 2021 19:40:13 +1100

 > http://www.ryoon.net/~ryoon/sys-dev-usb-uaudio-3.diff

 looks good.

 i'll try to find time to test on a couple of devices i have
 somewhere around here that used to work... and even try the
 one that crashed the one time i tried.

From: coypu@sdf.org
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/55919: Creative HP-BTW3 (BT-W3) USB audio device has
 another descriptor layout
Date: Tue, 23 Feb 2021 14:23:16 +0000

 I have the same hardware (Creative BT-W3).
 it works but after some time:

 System panicked: kernel diagnostic assertion "xfer == SIMPLEQ_FIRST(&pipe->up_queue)" failed: file "/bracket/repo/src/sys/dev/usb/usbdi.c", line 1035 xfer 0xffff9459c4a33188 is not start of queue (0xffff9459c4a33048 is at start)
 Backtrace from time of crash is available.
 crash> bt
 _KERNEL_OPT_GENFB_GLYPHCACHE() at 0
 _KERNEL_OPT_GENFB_GLYPHCACHE() at 0
 sys_reboot() at sys_reboot
 vpanic() at vpanic+0x160
 __x86_indirect_thunk_rax() at __x86_indirect_thunk_rax
 usb_transfer_complete() at usb_transfer_complete+0x448
 xhci_softintr() at xhci_softintr+0x597
 usb_soft_intr() at usb_soft_intr+0x25
 softint_dispatch() at softint_dispatch+0xf5
 DDB lost frame for Xsoftintr+0x4f, trying 0xffffa4013df190f0
 Xsoftintr() at Xsoftintr+0x4f
 --- interrupt ---
 754a0230390a0234:

 With line numbers:

 #4  0xffffffff8045de43 in usb_transfer_complete (xfer=0xffff9459c4a33188)
     at /bracket/repo/src/sys/dev/usb/usbdi.c:1035
 #5  0xffffffff80683615 in xhci_event_transfer (trb=<optimized out>, sc=0xffff945933d98000)
     at /bracket/repo/src/sys/dev/usb/xhci.c:2122
 #6  xhci_handle_event (trb=<optimized out>, sc=0xffff945933d98000) at /bracket/repo/src/sys/dev/usb/xhci.c:2198
 #7  xhci_softintr (v=<optimized out>) at /bracket/repo/src/sys/dev/usb/xhci.c:2238
 #8  0xffffffff80459f3e in usb_soft_intr (arg=0xffff945933d98050) at /bracket/repo/src/sys/dev/usb/usb.c:1316
 #9  0xffffffff80cb7190 in softint_execute (s=5, l=0xffff945c319664c0)
     at /bracket/repo/src/sys/kern/kern_softint.c:565
 #10 softint_dispatch (pinned=<optimized out>, s=5) at /bracket/repo/src/sys/kern/kern_softint.c:814

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.46 2020/01/03 16:35:01 leot Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2020 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.