usb/117598: [patch] Not possible to record with Plantronics DSP-400 USB headset

Henrik Gulbrandsen henrik at gulbra.net
Sun Oct 28 04:10:01 PDT 2007


>Number:         117598
>Category:       usb
>Synopsis:       [patch] Not possible to record with Plantronics DSP-400 USB headset
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-usb
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Oct 28 11:10:01 UTC 2007
>Closed-Date:
>Last-Modified:
>Originator:     Henrik Gulbrandsen
>Release:        FreeBSD 7.0-BETA1.5 i386
>Organization:
>Environment:
FreeBSD Test 7.0-BETA1.5 FreeBSD 7.0-BETA1.5 #2 Sat Oct 27 12:53:33 CEST 2007
tester at Test:/usr/src/sys/i386/compile/GENERIC  i386

(uname -a after patching)
>Description:
The Plantronics DSP-400 USB headset works fine for playback, but recording
fails. A look at /dev/sndstat indicated that there were no recording channels
available, and the relevant lines from /var/log/messages are as follows:

Oct 25 17:37:43  root: Unknown USB device: vendor 0x047f product 0x0ca1 bus uhub2
Oct 25 17:37:43  kernel: uaudio0: <Plantronics Plantronics Headset, class 0/0, rev 1.10/0.04, addr 2> on uhub2
Oct 25 17:37:43  kernel: uaudio0: ignored input endpoint of type adaptive
Oct 25 17:37:43  last message repeated 2 times
Oct 25 17:37:43  kernel: uaudio0: audio rev 1.00
Oct 25 17:37:43  kernel: pcm0: <USB Audio> on uaudio0

Apparently, the headset reports using an adaptive audio source endpoint for
data from the microphone. According to the USB specs, such endpoints need an
explicit synch pipe to specify the wanted sample rate [See USB Spec rev 2.0,
sec. 5.12.4.2 "Feedback" and the USB Device Class Definition for Audio Devices,
sec. 3.7.2.2 "Isochronous Synch Endpoint"]. Unfortunately, FreeBSD currently
doesn't support these synch endpoints. Fortunately, neither does the DSP-400 :-)

The rest of the story follows in the fix description...

>How-To-Repeat:
Plug in your Plantronics DSP-400 headset and make sure that the snd_uaudio
kernel module is loaded. Verify that playback works and recording fails.

>Fix:
Recompiling sys/dev/sound/usb/uaudio.c with defined UAUDIO_MULTIPLE_ENDPOINTS
revealed that that the required synch endpoint didn't exist. There is already a
USB quirk flag UQ_AU_INP_ASYNC, which specifies that a claimed adaptive input is
in fact not adaptive at all, but better handled as asynchronous. After setting
the flag for the DSP-400 headset, recording seems to work without obvious flaws.

I'm attaching a patch that adds this to the set of known quirks. Since this has
happened at least twice, I'm also adding some optional code that assumes that
all cases with a mysteriously missing sync endpoint should be handled similarly.
This may help to save some debugging time for other problem devices out there...


Patch attached with submission follows:

--- dev/sound/usb/uaudio.c.orig	2007-06-20 07:11:37.000000000 +0200
+++ dev/sound/usb/uaudio.c	2007-10-27 21:50:10.000000000 +0200
@@ -116,7 +116,11 @@
 #else
 /* #define USB_DEBUG */
 #endif
+
+/* A few knobs to enable/disable features... */
 /* #define UAUDIO_MULTIPLE_ENDPOINTS */
+#define UAUDIO_ASSUME_ASYNC
+
 #ifdef USB_DEBUG
 #define DPRINTF(x)	do { if (uaudiodebug) printf x; } while (0)
 #define DPRINTFN(n,x)	do { if (uaudiodebug>(n)) printf x; } while (0)
@@ -2018,6 +2022,12 @@
 	    dir == UE_DIR_IN && type == UE_ISO_ADAPT)
 		type = UE_ISO_ASYNC;
 
+#ifdef UAUDIO_ASSUME_ASYNC
+	/* Dammit! The spec doesn't allow this, so why not assume a quirk? */
+	if (dir == UE_DIR_IN && type == UE_ISO_ADAPT && id->bNumEndpoints == 1)
+		type = UE_ISO_ASYNC;
+#endif
+
 	/* We can't handle endpoints that need a sync pipe yet. */
 	sync = FALSE;
 	if (dir == UE_DIR_IN && type == UE_ISO_ADAPT) {
@@ -2050,9 +2060,18 @@
 	if (sync && id->bNumEndpoints <= 1) {
 		printf("%s: a sync-pipe endpoint but no other endpoint\n",
 		       device_get_nameunit(sc->sc_dev));
+#ifndef UAUDIO_ASSUME_ASYNC
+		if (dir != UE_DIR_IN)
+			return USBD_INVAL;
+		printf("This device may need a UQ_AU_INP_ASYNC quirk flag.\n");
+		printf("Consider adding it in sys/dev/usb/usb_quirks.c !!!\n");
+		printf("vendor: 0x%04x; product: 0x%04x; release: 0x%04x\n",
+			sc->sc_vendor, sc->sc_product, sc->sc_release);
+#endif /* UAUDIO_ASSUME_ASYNC */
 		return USBD_INVAL;
 	}
-#endif
+#endif /* UAUDIO_MULTIPLE_ENDPOINTS */
+
 	if (!sync && id->bNumEndpoints > 1) {
 		printf("%s: non sync-pipe endpoint but multiple endpoints\n",
 		       device_get_nameunit(sc->sc_dev));
--- dev/usb/usb_quirks.c.orig	2007-07-22 17:59:45.000000000 +0200
+++ dev/usb/usb_quirks.c	2007-10-27 12:53:02.000000000 +0200
@@ -74,6 +74,8 @@
  { USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1,	    0x009, { UQ_AU_NO_FRAC }},
  { USB_VENDOR_SILICONPORTALS, USB_PRODUCT_SILICONPORTALS_YAPPHONE,
    						    0x100, { UQ_AU_INP_ASYNC }},
+ { USB_VENDOR_PLANTRONICS, USB_PRODUCT_PLANTRONICS_DSP400,
+						    0x004, { UQ_AU_INP_ASYNC }},
  { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_UN53B, ANY, { UQ_NO_STRINGS }},
  /* XXX These should have a revision number, but I don't know what they are. */
  { USB_VENDOR_HP, USB_PRODUCT_HP_895C,		    ANY,   { UQ_BROKEN_BIDIR }},
--- dev/usb/usbdevs.orig	2007-10-05 09:26:39.000000000 +0200
+++ dev/usb/usbdevs	2007-10-27 12:53:06.000000000 +0200
@@ -1851,6 +1851,9 @@
 product PLANEX3 GU1000T		0xab11	GU-1000T
 product PLANEX3 GWUS54MINI	0xab13	GW-US54Mini
 
+/* Plantronics products */
+product PLANTRONICS DSP400	0x0ca1	DSP-400 Foldable PC Headset
+
 /* Plextor Corp. */
 product PLEXTOR 40_12_40U	0x0011	PlexWriter 40/12/40U
 


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-usb mailing list