xref: /freebsd/sys/dev/sound/usb/uaudio.c (revision a346b0961c0939e5df18cda6627d380b57459743)
1 /*	$NetBSD: uaudio.c,v 1.91 2004/11/05 17:46:14 kent Exp $	*/
2 /*	$FreeBSD$ */
3 
4 /*-
5  * Copyright (c) 1999 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Lennart Augustsson (lennart@augustsson.net) at
10  * Carlstedt Research & Technology.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgement:
22  *        This product includes software developed by the NetBSD
23  *        Foundation, Inc. and its contributors.
24  * 4. Neither the name of The NetBSD Foundation nor the names of its
25  *    contributors may be used to endorse or promote products derived
26  *    from this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 /*
42  * USB audio specs: http://www.usb.org/developers/devclass_docs/audio10.pdf
43  *                  http://www.usb.org/developers/devclass_docs/frmts10.pdf
44  *                  http://www.usb.org/developers/devclass_docs/termt10.pdf
45  */
46 
47 #include <sys/cdefs.h>
48 #if defined(__NetBSD__) || defined(__OpenBSD__)
49 __KERNEL_RCSID(0, "$NetBSD: uaudio.c,v 1.91 2004/11/05 17:46:14 kent Exp $");
50 #endif
51 
52 /*
53  * Also merged:
54  *  $NetBSD: uaudio.c,v 1.94 2005/01/15 15:19:53 kent Exp $
55  *  $NetBSD: uaudio.c,v 1.95 2005/01/16 06:02:19 dsainty Exp $
56  *  $NetBSD: uaudio.c,v 1.96 2005/01/16 12:46:00 kent Exp $
57  *  $NetBSD: uaudio.c,v 1.97 2005/02/24 08:19:38 martin Exp $
58  *  $NetBSD: uaudio.c,v 1.102 2006/04/14 17:00:55 christos Exp $
59  *  $NetBSD: uaudio.c,v 1.103 2006/05/11 19:09:25 mrg Exp $
60  *  $NetBSD: uaudio.c,v 1.105 2006/10/04 16:00:15 christos Exp $
61  */
62 
63 #include <sys/param.h>
64 #include <sys/systm.h>
65 #include <sys/kernel.h>
66 #include <sys/malloc.h>
67 #if defined(__NetBSD__) || defined(__OpenBSD__)
68 #include <sys/device.h>
69 #include <sys/ioctl.h>
70 #endif
71 #include <sys/tty.h>
72 #include <sys/file.h>
73 #include <sys/reboot.h>		/* for bootverbose */
74 #include <sys/select.h>
75 #include <sys/proc.h>
76 #if defined(__NetBSD__) || defined(__OpenBSD__)
77 #include <sys/device.h>
78 #elif defined(__FreeBSD__)
79 #include <sys/module.h>
80 #include <sys/bus.h>
81 #include <sys/conf.h>
82 #endif
83 #include <sys/poll.h>
84 #if defined(__FreeBSD__)
85 #include <sys/sysctl.h>
86 #include <sys/sbuf.h>
87 #endif
88 
89 #if defined(__NetBSD__) || defined(__OpenBSD__)
90 #include <sys/audioio.h>
91 #include <dev/audio_if.h>
92 #include <dev/audiovar.h>
93 #include <dev/mulaw.h>
94 #include <dev/auconv.h>
95 #elif defined(__FreeBSD__)
96 #include <dev/sound/pcm/sound.h>	/* XXXXX */
97 #include <dev/sound/chip.h>
98 #include "feeder_if.h"
99 #endif
100 
101 #include <dev/usb/usb.h>
102 #include <dev/usb/usbdi.h>
103 #include <dev/usb/usbdi_util.h>
104 #include <dev/usb/usb_quirks.h>
105 
106 #if defined(__NetBSD__) || defined(__OpenBSD__)
107 #include <dev/usb/uaudioreg.h>
108 #elif defined(__FreeBSD__)
109 #include <dev/sound/usb/uaudioreg.h>
110 #include <dev/sound/usb/uaudio.h>
111 #endif
112 
113 #if defined(__NetBSD__) || defined(__OpenBSD__)
114 /* #define UAUDIO_DEBUG */
115 #else
116 /* #define USB_DEBUG */
117 #endif
118 /* #define UAUDIO_MULTIPLE_ENDPOINTS */
119 #ifdef USB_DEBUG
120 #define DPRINTF(x)	do { if (uaudiodebug) logprintf x; } while (0)
121 #define DPRINTFN(n,x)	do { if (uaudiodebug>(n)) logprintf x; } while (0)
122 int	uaudiodebug = 0;
123 #if defined(__FreeBSD__)
124 SYSCTL_NODE(_hw_usb, OID_AUTO, uaudio, CTLFLAG_RW, 0, "USB uaudio");
125 SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, debug, CTLFLAG_RW,
126 	   &uaudiodebug, 0, "uaudio debug level");
127 #endif
128 #else
129 #define DPRINTF(x)
130 #define DPRINTFN(n,x)
131 #endif
132 
133 #define UAUDIO_NCHANBUFS 6	/* number of outstanding request */
134 #if defined(__NetBSD__) || defined(__OpenBSD__)
135 #define UAUDIO_NFRAMES   10	/* ms of sound in each request */
136 #elif defined(__FreeBSD__)
137 #define UAUDIO_NFRAMES   20	/* ms of sound in each request */
138 #endif
139 
140 
141 #define MIX_MAX_CHAN 8
142 struct mixerctl {
143 	uint16_t	wValue[MIX_MAX_CHAN]; /* using nchan */
144 	uint16_t	wIndex;
145 	uint8_t		nchan;
146 	uint8_t		type;
147 #define MIX_ON_OFF	1
148 #define MIX_SIGNED_16	2
149 #define MIX_UNSIGNED_16	3
150 #define MIX_SIGNED_8	4
151 #define MIX_SELECTOR	5
152 #define MIX_SIZE(n) ((n) == MIX_SIGNED_16 || (n) == MIX_UNSIGNED_16 ? 2 : 1)
153 #define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16)
154 	int		minval, maxval;
155 	u_int		delta;
156 	u_int		mul;
157 #if defined(__FreeBSD__) /* XXXXX */
158 	unsigned	ctl;
159 #define MAX_SELECTOR_INPUT_PIN 256
160 	uint8_t		slctrtype[MAX_SELECTOR_INPUT_PIN];
161 #endif
162 	uint8_t		class;
163 #if !defined(__FreeBSD__)
164 	char		ctlname[MAX_AUDIO_DEV_LEN];
165 	char		*ctlunit;
166 #endif
167 };
168 #define MAKE(h,l) (((h) << 8) | (l))
169 
170 struct as_info {
171 	uint8_t		alt;
172 	uint8_t		encoding;
173 	uint8_t		attributes; /* Copy of bmAttributes of
174 				     * usb_audio_streaming_endpoint_descriptor
175 				     */
176 	usbd_interface_handle	ifaceh;
177 	const usb_interface_descriptor_t *idesc;
178 	const usb_endpoint_descriptor_audio_t *edesc;
179 	const usb_endpoint_descriptor_audio_t *edesc1;
180 	const struct usb_audio_streaming_type1_descriptor *asf1desc;
181 	int		sc_busy;	/* currently used */
182 };
183 
184 struct chan {
185 #if defined(__NetBSD__) || defined(__OpenBSD__)
186 	void	(*intr)(void *);	/* DMA completion intr handler */
187 	void	*arg;		/* arg for intr() */
188 #else
189 	struct pcm_channel *pcm_ch;
190 #endif
191 	usbd_pipe_handle pipe;
192 	usbd_pipe_handle sync_pipe;
193 
194 	u_int	sample_size;
195 	u_int	sample_rate;
196 	u_int	bytes_per_frame;
197 	u_int	fraction;	/* fraction/1000 is the extra samples/frame */
198 	u_int	residue;	/* accumulates the fractional samples */
199 
200 	u_char	*start;		/* upper layer buffer start */
201 	u_char	*end;		/* upper layer buffer end */
202 	u_char	*cur;		/* current position in upper layer buffer */
203 	int	blksize;	/* chunk size to report up */
204 	int	transferred;	/* transferred bytes not reported up */
205 
206 	int	altidx;		/* currently used altidx */
207 
208 	int	curchanbuf;
209 	struct chanbuf {
210 		struct chan	*chan;
211 		usbd_xfer_handle xfer;
212 		u_char		*buffer;
213 		u_int16_t	sizes[UAUDIO_NFRAMES];
214 		u_int16_t	offsets[UAUDIO_NFRAMES];
215 		u_int16_t	size;
216 	} chanbufs[UAUDIO_NCHANBUFS];
217 
218 	struct uaudio_softc *sc; /* our softc */
219 #if defined(__FreeBSD__)
220 	u_int32_t format;
221 	int	precision;
222 	int	channels;
223 #endif
224 };
225 
226 struct uaudio_softc {
227 	device_t	sc_dev;		/* base device */
228 	usbd_device_handle sc_udev;	/* USB device */
229 	int		sc_ac_iface;	/* Audio Control interface */
230 	usbd_interface_handle	sc_ac_ifaceh;
231 	struct chan	sc_playchan;	/* play channel */
232 	struct chan	sc_recchan;	/* record channel */
233 	int		sc_nullalt;
234 	int		sc_audio_rev;
235 	struct as_info	*sc_alts;	/* alternate settings */
236 	int		sc_nalts;	/* # of alternate settings */
237 	int		sc_altflags;
238 #define HAS_8		0x01
239 #define HAS_16		0x02
240 #define HAS_8U		0x04
241 #define HAS_ALAW	0x08
242 #define HAS_MULAW	0x10
243 #define UA_NOFRAC	0x20		/* don't do sample rate adjustment */
244 #define HAS_24		0x40
245 #define HAS_32		0x80
246 	int		sc_mode;	/* play/record capability */
247 	struct mixerctl *sc_ctls;	/* mixer controls */
248 	int		sc_nctls;	/* # of mixer controls */
249 	device_t	sc_audiodev;
250 	char		sc_dying;
251 #if defined(__FreeBSD__)
252 	struct sbuf	uaudio_sndstat;
253 	int		uaudio_sndstat_flag;
254 #endif
255 };
256 
257 struct terminal_list {
258 	int size;
259 	uint16_t terminals[1];
260 };
261 #define TERMINAL_LIST_SIZE(N)	(offsetof(struct terminal_list, terminals) \
262 				+ sizeof(uint16_t) * (N))
263 
264 struct io_terminal {
265 	union {
266 		const usb_descriptor_t *desc;
267 		const struct usb_audio_input_terminal *it;
268 		const struct usb_audio_output_terminal *ot;
269 		const struct usb_audio_mixer_unit *mu;
270 		const struct usb_audio_selector_unit *su;
271 		const struct usb_audio_feature_unit *fu;
272 		const struct usb_audio_processing_unit *pu;
273 		const struct usb_audio_extension_unit *eu;
274 	} d;
275 	int inputs_size;
276 	struct terminal_list **inputs; /* list of source input terminals */
277 	struct terminal_list *output; /* list of destination output terminals */
278 	int direct;		/* directly connected to an output terminal */
279 };
280 
281 #define UAC_OUTPUT	0
282 #define UAC_INPUT	1
283 #define UAC_EQUAL	2
284 #define UAC_RECORD	3
285 #define UAC_NCLASSES	4
286 #ifdef USB_DEBUG
287 #if defined(__FreeBSD__)
288 #define AudioCinputs	"inputs"
289 #define AudioCoutputs	"outputs"
290 #define AudioCrecord	"record"
291 #define AudioCequalization	"equalization"
292 #endif
293 static const char *uac_names[] = {
294 	AudioCoutputs, AudioCinputs, AudioCequalization, AudioCrecord,
295 };
296 #endif
297 
298 static usbd_status uaudio_identify_ac
299 	(struct uaudio_softc *, const usb_config_descriptor_t *);
300 static usbd_status uaudio_identify_as
301 	(struct uaudio_softc *, const usb_config_descriptor_t *);
302 static usbd_status uaudio_process_as
303 	(struct uaudio_softc *, const char *, int *, int,
304 	 const usb_interface_descriptor_t *);
305 
306 static void	uaudio_add_alt(struct uaudio_softc *, const struct as_info *);
307 
308 static const usb_interface_descriptor_t *uaudio_find_iface
309 	(const char *, int, int *, int);
310 
311 static void	uaudio_mixer_add_ctl(struct uaudio_softc *, struct mixerctl *);
312 
313 #if defined(__NetBSD__) || defined(__OpenBSD__)
314 static char	*uaudio_id_name
315 	(struct uaudio_softc *, const struct io_terminal *, int);
316 #endif
317 
318 #ifdef USB_DEBUG
319 static void	uaudio_dump_cluster(const struct usb_audio_cluster *);
320 #endif
321 static struct usb_audio_cluster uaudio_get_cluster
322 	(int, const struct io_terminal *);
323 static void	uaudio_add_input
324 	(struct uaudio_softc *, const struct io_terminal *, int);
325 static void	uaudio_add_output
326 	(struct uaudio_softc *, const struct io_terminal *, int);
327 static void	uaudio_add_mixer
328 	(struct uaudio_softc *, const struct io_terminal *, int);
329 static void	uaudio_add_selector
330 	(struct uaudio_softc *, const struct io_terminal *, int);
331 #ifdef USB_DEBUG
332 static const char *uaudio_get_terminal_name(int);
333 #endif
334 static int	uaudio_determine_class
335 	(const struct io_terminal *, struct mixerctl *);
336 #if defined(__FreeBSD__)
337 static const int uaudio_feature_name(const struct io_terminal *,
338 		    struct mixerctl *);
339 #else
340 static const char *uaudio_feature_name
341 	(const struct io_terminal *, struct mixerctl *);
342 #endif
343 static void	uaudio_add_feature
344 	(struct uaudio_softc *, const struct io_terminal *, int);
345 static void	uaudio_add_processing_updown
346 	(struct uaudio_softc *, const struct io_terminal *, int);
347 static void	uaudio_add_processing
348 	(struct uaudio_softc *, const struct io_terminal *, int);
349 static void	uaudio_add_extension
350 	(struct uaudio_softc *, const struct io_terminal *, int);
351 static struct terminal_list *uaudio_merge_terminal_list
352 	(const struct io_terminal *);
353 static struct terminal_list *uaudio_io_terminaltype
354 	(int, struct io_terminal *, int);
355 static usbd_status uaudio_identify
356 	(struct uaudio_softc *, const usb_config_descriptor_t *);
357 
358 static int	uaudio_signext(int, int);
359 #if defined(__NetBSD__) || defined(__OpenBSD__)
360 static int	uaudio_value2bsd(struct mixerctl *, int);
361 #endif
362 static int	uaudio_bsd2value(struct mixerctl *, int);
363 static int	uaudio_get(struct uaudio_softc *, int, int, int, int, int);
364 #if defined(__NetBSD__) || defined(__OpenBSD__)
365 static int	uaudio_ctl_get
366 	(struct uaudio_softc *, int, struct mixerctl *, int);
367 #endif
368 static void	uaudio_set
369 	(struct uaudio_softc *, int, int, int, int, int, int);
370 static void	uaudio_ctl_set
371 	(struct uaudio_softc *, int, struct mixerctl *, int, int);
372 
373 static usbd_status uaudio_set_speed(struct uaudio_softc *, int, u_int);
374 
375 static usbd_status uaudio_chan_open(struct uaudio_softc *, struct chan *);
376 static void	uaudio_chan_close(struct uaudio_softc *, struct chan *);
377 static usbd_status uaudio_chan_alloc_buffers
378 	(struct uaudio_softc *, struct chan *);
379 static void	uaudio_chan_free_buffers(struct uaudio_softc *, struct chan *);
380 
381 #if defined(__NetBSD__) || defined(__OpenBSD__)
382 static void	uaudio_chan_init
383 	(struct chan *, int, const struct audio_params *, int);
384 static void	uaudio_chan_set_param(struct chan *, u_char *, u_char *, int);
385 #endif
386 
387 static void	uaudio_chan_ptransfer(struct chan *);
388 static void	uaudio_chan_pintr
389 	(usbd_xfer_handle, usbd_private_handle, usbd_status);
390 
391 static void	uaudio_chan_rtransfer(struct chan *);
392 static void	uaudio_chan_rintr
393 	(usbd_xfer_handle, usbd_private_handle, usbd_status);
394 
395 #if defined(__NetBSD__) || defined(__OpenBSD__)
396 static int	uaudio_open(void *, int);
397 static void	uaudio_close(void *);
398 static int	uaudio_drain(void *);
399 static int	uaudio_query_encoding(void *, struct audio_encoding *);
400 static void	uaudio_get_minmax_rates
401 	(int, const struct as_info *, const struct audio_params *,
402 	 int, u_long *, u_long *);
403 static int	uaudio_match_alt_sub
404 	(int, const struct as_info *, const struct audio_params *, int, u_long);
405 static int	uaudio_match_alt_chan
406 	(int, const struct as_info *, struct audio_params *, int);
407 static int	uaudio_match_alt
408 	(int, const struct as_info *, struct audio_params *, int);
409 static int	uaudio_set_params
410 	(void *, int, int, struct audio_params *, struct audio_params *);
411 static int	uaudio_round_blocksize(void *, int);
412 static int	uaudio_trigger_output
413 	(void *, void *, void *, int, void (*)(void *), void *,
414 	 struct audio_params *);
415 static int	uaudio_trigger_input
416 	(void *, void *, void *, int, void (*)(void *), void *,
417 	 struct audio_params *);
418 static int	uaudio_halt_in_dma(void *);
419 static int	uaudio_halt_out_dma(void *);
420 static int	uaudio_getdev(void *, struct audio_device *);
421 static int	uaudio_mixer_set_port(void *, mixer_ctrl_t *);
422 static int	uaudio_mixer_get_port(void *, mixer_ctrl_t *);
423 static int	uaudio_query_devinfo(void *, mixer_devinfo_t *);
424 static int	uaudio_get_props(void *);
425 
426 static const struct audio_hw_if uaudio_hw_if = {
427 	uaudio_open,
428 	uaudio_close,
429 	uaudio_drain,
430 	uaudio_query_encoding,
431 	uaudio_set_params,
432 	uaudio_round_blocksize,
433 	NULL,
434 	NULL,
435 	NULL,
436 	NULL,
437 	NULL,
438 	uaudio_halt_out_dma,
439 	uaudio_halt_in_dma,
440 	NULL,
441 	uaudio_getdev,
442 	NULL,
443 	uaudio_mixer_set_port,
444 	uaudio_mixer_get_port,
445 	uaudio_query_devinfo,
446 	NULL,
447 	NULL,
448 	NULL,
449 	NULL,
450 	uaudio_get_props,
451 	uaudio_trigger_output,
452 	uaudio_trigger_input,
453 	NULL,
454 };
455 
456 static struct audio_device uaudio_device = {
457 	"USB audio",
458 	"",
459 	"uaudio"
460 };
461 
462 #elif defined(__FreeBSD__)
463 static int	audio_attach_mi(device_t);
464 static int	uaudio_init_params(struct uaudio_softc * sc, struct chan *ch, int mode);
465 static int 	uaudio_sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose);
466 
467 /* for NetBSD compatibirity */
468 #define	AUMODE_PLAY	0x01
469 #define	AUMODE_RECORD	0x02
470 
471 #define	AUDIO_PROP_FULLDUPLEX	0x01
472 
473 #define	AUDIO_ENCODING_ULAW		1
474 #define	AUDIO_ENCODING_ALAW		2
475 #define	AUDIO_ENCODING_SLINEAR_LE	6
476 #define	AUDIO_ENCODING_SLINEAR_BE	7
477 #define	AUDIO_ENCODING_ULINEAR_LE	8
478 #define	AUDIO_ENCODING_ULINEAR_BE	9
479 
480 #endif	/* FreeBSD */
481 
482 
483 #if defined(__NetBSD__) || defined(__OpenBSD__)
484 
485 USB_DECLARE_DRIVER(uaudio);
486 
487 #elif defined(__FreeBSD__)
488 
489 USB_DECLARE_DRIVER_INIT(uaudio,
490 		DEVMETHOD(device_suspend, bus_generic_suspend),
491 		DEVMETHOD(device_resume, bus_generic_resume),
492 		DEVMETHOD(device_shutdown, bus_generic_shutdown),
493 		DEVMETHOD(bus_print_child, bus_generic_print_child)
494 		);
495 #endif
496 
497 
498 USB_MATCH(uaudio)
499 {
500 	USB_MATCH_START(uaudio, uaa);
501 	usb_interface_descriptor_t *id;
502 
503 	if (uaa->iface == NULL)
504 		return UMATCH_NONE;
505 
506 	id = usbd_get_interface_descriptor(uaa->iface);
507 	/* Trigger on the control interface. */
508 	if (id == NULL ||
509 	    id->bInterfaceClass != UICLASS_AUDIO ||
510 	    id->bInterfaceSubClass != UISUBCLASS_AUDIOCONTROL ||
511 	    (usbd_get_quirks(uaa->device)->uq_flags & UQ_BAD_AUDIO))
512 		return UMATCH_NONE;
513 
514 	return UMATCH_IFACECLASS_IFACESUBCLASS;
515 }
516 
517 USB_ATTACH(uaudio)
518 {
519 	USB_ATTACH_START(uaudio, sc, uaa);
520 	usb_interface_descriptor_t *id;
521 	usb_config_descriptor_t *cdesc;
522 	char devinfo[1024];
523 	usbd_status err;
524 	int i, j, found;
525 
526 #if defined(__FreeBSD__)
527 	usbd_devinfo(uaa->device, 0, devinfo);
528 	USB_ATTACH_SETUP;
529 #else
530 	usbd_devinfo(uaa->device, 0, devinfo, sizeof(devinfo));
531 	printf(": %s\n", devinfo);
532 #endif
533 
534 	sc->sc_udev = uaa->device;
535 
536 	cdesc = usbd_get_config_descriptor(sc->sc_udev);
537 	if (cdesc == NULL) {
538 		printf("%s: failed to get configuration descriptor\n",
539 		       device_get_nameunit(sc->sc_dev));
540 		USB_ATTACH_ERROR_RETURN;
541 	}
542 
543 	err = uaudio_identify(sc, cdesc);
544 	if (err) {
545 		printf("%s: audio descriptors make no sense, error=%d\n",
546 		       device_get_nameunit(sc->sc_dev), err);
547 		USB_ATTACH_ERROR_RETURN;
548 	}
549 
550 	sc->sc_ac_ifaceh = uaa->iface;
551 	/* Pick up the AS interface. */
552 	for (i = 0; i < uaa->nifaces; i++) {
553 		if (uaa->ifaces[i] == NULL)
554 			continue;
555 		id = usbd_get_interface_descriptor(uaa->ifaces[i]);
556 		if (id == NULL)
557 			continue;
558 		found = 0;
559 		for (j = 0; j < sc->sc_nalts; j++) {
560 			if (id->bInterfaceNumber ==
561 			    sc->sc_alts[j].idesc->bInterfaceNumber) {
562 				sc->sc_alts[j].ifaceh = uaa->ifaces[i];
563 				found = 1;
564 			}
565 		}
566 		if (found)
567 			uaa->ifaces[i] = NULL;
568 	}
569 
570 	for (j = 0; j < sc->sc_nalts; j++) {
571 		if (sc->sc_alts[j].ifaceh == NULL) {
572 			printf("%s: alt %d missing AS interface(s)\n",
573 			    device_get_nameunit(sc->sc_dev), j);
574 			USB_ATTACH_ERROR_RETURN;
575 		}
576 	}
577 
578 	printf("%s: audio rev %d.%02x\n", device_get_nameunit(sc->sc_dev),
579 	       sc->sc_audio_rev >> 8, sc->sc_audio_rev & 0xff);
580 
581 	sc->sc_playchan.sc = sc->sc_recchan.sc = sc;
582 	sc->sc_playchan.altidx = -1;
583 	sc->sc_recchan.altidx = -1;
584 
585 	if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_FRAC)
586 		sc->sc_altflags |= UA_NOFRAC;
587 
588 #ifndef USB_DEBUG
589 	if (bootverbose)
590 #endif
591 		printf("%s: %d mixer controls\n", device_get_nameunit(sc->sc_dev),
592 		    sc->sc_nctls);
593 
594 #if !defined(__FreeBSD__)
595 	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
596 			   USBDEV(sc->sc_dev));
597 #endif
598 
599 	DPRINTF(("uaudio_attach: doing audio_attach_mi\n"));
600 #if defined(__OpenBSD__)
601 	audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev);
602 #elif defined(__NetBSD__)
603 	sc->sc_audiodev = audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev);
604 #elif defined(__FreeBSD__)
605 	sc->sc_dying = 0;
606 	if (audio_attach_mi(sc->sc_dev)) {
607 		printf("audio_attach_mi failed\n");
608 		USB_ATTACH_ERROR_RETURN;
609 	}
610 #endif
611 
612 	USB_ATTACH_SUCCESS_RETURN;
613 }
614 
615 #if defined(__NetBSD__) || defined(__OpenBSD__)
616 int
617 uaudio_activate(device_t self, enum devact act)
618 {
619 	struct uaudio_softc *sc;
620 	int rv;
621 
622 	sc = (struct uaudio_softc *)self;
623 	rv = 0;
624 	switch (act) {
625 	case DVACT_ACTIVATE:
626 		return EOPNOTSUPP;
627 
628 	case DVACT_DEACTIVATE:
629 		if (sc->sc_audiodev != NULL)
630 			rv = config_deactivate(sc->sc_audiodev);
631 		sc->sc_dying = 1;
632 		break;
633 	}
634 	return rv;
635 }
636 #endif
637 
638 #if defined(__NetBSD__) || defined(__OpenBSD__)
639 int
640 uaudio_detach(device_t self, int flags)
641 {
642 	struct uaudio_softc *sc;
643 	int rv;
644 
645 	sc = (struct uaudio_softc *)self;
646 	rv = 0;
647 	/* Wait for outstanding requests to complete. */
648 	usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
649 
650 	if (sc->sc_audiodev != NULL)
651 		rv = config_detach(sc->sc_audiodev, flags);
652 
653 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
654 			   USBDEV(sc->sc_dev));
655 
656 	return rv;
657 }
658 #elif defined(__FreeBSD__)
659 
660 USB_DETACH(uaudio)
661 {
662 	USB_DETACH_START(uaudio, sc);
663 
664 	sbuf_delete(&(sc->uaudio_sndstat));
665 	sc->uaudio_sndstat_flag = 0;
666 
667 	sc->sc_dying = 1;
668 
669 #if 0 /* XXX */
670 	/* Wait for outstanding requests to complete. */
671 	usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
672 #endif
673 
674 	/* do nothing ? */
675 	return bus_generic_detach(sc->sc_dev);
676 }
677 #endif
678 
679 #if defined(__NetBSD__) || defined(__OpenBSD__)
680 static int
681 uaudio_query_encoding(void *addr, struct audio_encoding *fp)
682 {
683 	struct uaudio_softc *sc;
684 	int flags;
685 	int idx;
686 
687 	sc = addr;
688 	flags = sc->sc_altflags;
689 	if (sc->sc_dying)
690 		return EIO;
691 
692 	if (sc->sc_nalts == 0 || flags == 0)
693 		return ENXIO;
694 
695 	idx = fp->index;
696 	switch (idx) {
697 	case 0:
698 		strlcpy(fp->name, AudioEulinear, sizeof(fp->name));
699 		fp->encoding = AUDIO_ENCODING_ULINEAR;
700 		fp->precision = 8;
701 		fp->flags = flags&HAS_8U ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
702 		return (0);
703 	case 1:
704 		strlcpy(fp->name, AudioEmulaw, sizeof(fp->name));
705 		fp->encoding = AUDIO_ENCODING_ULAW;
706 		fp->precision = 8;
707 		fp->flags = flags&HAS_MULAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
708 		return (0);
709 	case 2:
710 		strlcpy(fp->name, AudioEalaw, sizeof(fp->name));
711 		fp->encoding = AUDIO_ENCODING_ALAW;
712 		fp->precision = 8;
713 		fp->flags = flags&HAS_ALAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
714 		return (0);
715 	case 3:
716 		strlcpy(fp->name, AudioEslinear, sizeof(fp->name));
717 		fp->encoding = AUDIO_ENCODING_SLINEAR;
718 		fp->precision = 8;
719 		fp->flags = flags&HAS_8 ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
720 		return (0);
721 	case 4:
722 		strlcpy(fp->name, AudioEslinear_le, sizeof(fp->name));
723 		fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
724 		fp->precision = 16;
725 		fp->flags = 0;
726 		return (0);
727 	case 5:
728 		strlcpy(fp->name, AudioEulinear_le, sizeof(fp->name));
729 		fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
730 		fp->precision = 16;
731 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
732 		return (0);
733 	case 6:
734 		strlcpy(fp->name, AudioEslinear_be, sizeof(fp->name));
735 		fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
736 		fp->precision = 16;
737 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
738 		return (0);
739 	case 7:
740 		strlcpy(fp->name, AudioEulinear_be, sizeof(fp->name));
741 		fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
742 		fp->precision = 16;
743 		fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
744 		return (0);
745 	default:
746 		return (EINVAL);
747 	}
748 }
749 #endif
750 
751 static const usb_interface_descriptor_t *
752 uaudio_find_iface(const char *buf, int size, int *offsp, int subtype)
753 {
754 	const usb_interface_descriptor_t *d;
755 
756 	while (*offsp < size) {
757 		d = (const void *)(buf + *offsp);
758 		*offsp += d->bLength;
759 		if (d->bDescriptorType == UDESC_INTERFACE &&
760 		    d->bInterfaceClass == UICLASS_AUDIO &&
761 		    d->bInterfaceSubClass == subtype)
762 			return d;
763 	}
764 	return NULL;
765 }
766 
767 static void
768 uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct mixerctl *mc)
769 {
770 	int res;
771 	size_t len;
772 	struct mixerctl *nmc;
773 
774 #if defined(__FreeBSD__)
775 	if (mc->class < UAC_NCLASSES) {
776 		DPRINTF(("%s: adding %s.%d\n",
777 			 __func__, uac_names[mc->class], mc->ctl));
778 	} else {
779 		DPRINTF(("%s: adding %d\n", __func__, mc->ctl));
780 	}
781 #else
782 	if (mc->class < UAC_NCLASSES) {
783 		DPRINTF(("%s: adding %s.%s\n",
784 			 __func__, uac_names[mc->class], mc->ctlname));
785 	} else {
786 		DPRINTF(("%s: adding %s\n", __func__, mc->ctlname));
787 	}
788 #endif
789 	len = sizeof(*mc) * (sc->sc_nctls + 1);
790 	nmc = malloc(len, M_USBDEV, M_NOWAIT);
791 	if (nmc == NULL) {
792 		printf("uaudio_mixer_add_ctl: no memory\n");
793 		return;
794 	}
795 	/* Copy old data, if there was any */
796 	if (sc->sc_nctls != 0) {
797 		memcpy(nmc, sc->sc_ctls, sizeof(*mc) * (sc->sc_nctls));
798 		free(sc->sc_ctls, M_USBDEV);
799 	}
800 	sc->sc_ctls = nmc;
801 
802 	mc->delta = 0;
803 	if (mc->type == MIX_ON_OFF) {
804 		mc->minval = 0;
805 		mc->maxval = 1;
806 	} else if (mc->type == MIX_SELECTOR) {
807 		;
808 	} else {
809 		/* Determine min and max values. */
810 		mc->minval = uaudio_signext(mc->type,
811 			uaudio_get(sc, GET_MIN, UT_READ_CLASS_INTERFACE,
812 				   mc->wValue[0], mc->wIndex,
813 				   MIX_SIZE(mc->type)));
814 		mc->maxval = 1 + uaudio_signext(mc->type,
815 			uaudio_get(sc, GET_MAX, UT_READ_CLASS_INTERFACE,
816 				   mc->wValue[0], mc->wIndex,
817 				   MIX_SIZE(mc->type)));
818 		mc->mul = mc->maxval - mc->minval;
819 		if (mc->mul == 0)
820 			mc->mul = 1;
821 		res = uaudio_get(sc, GET_RES, UT_READ_CLASS_INTERFACE,
822 				 mc->wValue[0], mc->wIndex,
823 				 MIX_SIZE(mc->type));
824 		if (res > 0)
825 			mc->delta = (res * 255 + mc->mul/2) / mc->mul;
826 	}
827 
828 	sc->sc_ctls[sc->sc_nctls++] = *mc;
829 
830 #ifdef USB_DEBUG
831 	if (uaudiodebug > 2) {
832 		int i;
833 		DPRINTF(("uaudio_mixer_add_ctl: wValue=%04x",mc->wValue[0]));
834 		for (i = 1; i < mc->nchan; i++)
835 			DPRINTF((",%04x", mc->wValue[i]));
836 #if defined(__FreeBSD__)
837 		DPRINTF((" wIndex=%04x type=%d ctl='%d' "
838 			 "min=%d max=%d\n",
839 			 mc->wIndex, mc->type, mc->ctl,
840 			 mc->minval, mc->maxval));
841 #else
842 		DPRINTF((" wIndex=%04x type=%d name='%s' unit='%s' "
843 			 "min=%d max=%d\n",
844 			 mc->wIndex, mc->type, mc->ctlname, mc->ctlunit,
845 			 mc->minval, mc->maxval));
846 #endif
847 	}
848 #endif
849 }
850 
851 #if defined(__NetBSD__) || defined(__OpenBSD__)
852 static char *
853 uaudio_id_name(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
854 {
855 	static char buf[32];
856 
857 	snprintf(buf, sizeof(buf), "i%d", id);
858 	return buf;
859 }
860 #endif
861 
862 #ifdef USB_DEBUG
863 static void
864 uaudio_dump_cluster(const struct usb_audio_cluster *cl)
865 {
866 	static const char *channel_names[16] = {
867 		"LEFT", "RIGHT", "CENTER", "LFE",
868 		"LEFT_SURROUND", "RIGHT_SURROUND", "LEFT_CENTER", "RIGHT_CENTER",
869 		"SURROUND", "LEFT_SIDE", "RIGHT_SIDE", "TOP",
870 		"RESERVED12", "RESERVED13", "RESERVED14", "RESERVED15",
871 	};
872 	int cc, i, first;
873 
874 	cc = UGETW(cl->wChannelConfig);
875 	logprintf("cluster: bNrChannels=%u wChannelConfig=0x%.4x",
876 		  cl->bNrChannels, cc);
877 	first = TRUE;
878 	for (i = 0; cc != 0; i++) {
879 		if (cc & 1) {
880 			logprintf("%c%s", first ? '<' : ',', channel_names[i]);
881 			first = FALSE;
882 		}
883 		cc = cc >> 1;
884 	}
885 	logprintf("> iChannelNames=%u", cl->iChannelNames);
886 }
887 #endif
888 
889 static struct usb_audio_cluster
890 uaudio_get_cluster(int id, const struct io_terminal *iot)
891 {
892 	struct usb_audio_cluster r;
893 	const usb_descriptor_t *dp;
894 	int i;
895 
896 	for (i = 0; i < 25; i++) { /* avoid infinite loops */
897 		dp = iot[id].d.desc;
898 		if (dp == 0)
899 			goto bad;
900 		switch (dp->bDescriptorSubtype) {
901 		case UDESCSUB_AC_INPUT:
902 			r.bNrChannels = iot[id].d.it->bNrChannels;
903 			USETW(r.wChannelConfig, UGETW(iot[id].d.it->wChannelConfig));
904 			r.iChannelNames = iot[id].d.it->iChannelNames;
905 			return r;
906 		case UDESCSUB_AC_OUTPUT:
907 			id = iot[id].d.ot->bSourceId;
908 			break;
909 		case UDESCSUB_AC_MIXER:
910 			r = *(const struct usb_audio_cluster *)
911 				&iot[id].d.mu->baSourceId[iot[id].d.mu->bNrInPins];
912 			return r;
913 		case UDESCSUB_AC_SELECTOR:
914 			/* XXX This is not really right */
915 			id = iot[id].d.su->baSourceId[0];
916 			break;
917 		case UDESCSUB_AC_FEATURE:
918 			id = iot[id].d.fu->bSourceId;
919 			break;
920 		case UDESCSUB_AC_PROCESSING:
921 			r = *(const struct usb_audio_cluster *)
922 				&iot[id].d.pu->baSourceId[iot[id].d.pu->bNrInPins];
923 			return r;
924 		case UDESCSUB_AC_EXTENSION:
925 			r = *(const struct usb_audio_cluster *)
926 				&iot[id].d.eu->baSourceId[iot[id].d.eu->bNrInPins];
927 			return r;
928 		default:
929 			goto bad;
930 		}
931 	}
932  bad:
933 	printf("uaudio_get_cluster: bad data\n");
934 	memset(&r, 0, sizeof r);
935 	return r;
936 
937 }
938 
939 static void
940 uaudio_add_input(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
941 {
942 #ifdef USB_DEBUG
943 	const struct usb_audio_input_terminal *d = iot[id].d.it;
944 
945 	DPRINTFN(2,("uaudio_add_input: bTerminalId=%d wTerminalType=0x%04x "
946 		    "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d "
947 		    "iChannelNames=%d iTerminal=%d\n",
948 		    d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
949 		    d->bNrChannels, UGETW(d->wChannelConfig),
950 		    d->iChannelNames, d->iTerminal));
951 #endif
952 }
953 
954 static void
955 uaudio_add_output(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
956 {
957 #ifdef USB_DEBUG
958 	const struct usb_audio_output_terminal *d;
959 
960 	d = iot[id].d.ot;
961 	DPRINTFN(2,("uaudio_add_output: bTerminalId=%d wTerminalType=0x%04x "
962 		    "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n",
963 		    d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
964 		    d->bSourceId, d->iTerminal));
965 #endif
966 }
967 
968 static void
969 uaudio_add_mixer(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
970 {
971 	const struct usb_audio_mixer_unit *d = iot[id].d.mu;
972 	const struct usb_audio_mixer_unit_1 *d1;
973 	int c, chs, ichs, ochs, i, o, bno, p, mo, mc, k;
974 	const uByte *bm;
975 	struct mixerctl mix;
976 
977 	DPRINTFN(2,("uaudio_add_mixer: bUnitId=%d bNrInPins=%d\n",
978 		    d->bUnitId, d->bNrInPins));
979 
980 	/* Compute the number of input channels */
981 	ichs = 0;
982 	for (i = 0; i < d->bNrInPins; i++)
983 		ichs += uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels;
984 
985 	/* and the number of output channels */
986 	d1 = (const struct usb_audio_mixer_unit_1 *)&d->baSourceId[d->bNrInPins];
987 	ochs = d1->bNrChannels;
988 	DPRINTFN(2,("uaudio_add_mixer: ichs=%d ochs=%d\n", ichs, ochs));
989 
990 	bm = d1->bmControls;
991 	mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
992 	uaudio_determine_class(&iot[id], &mix);
993 	mix.type = MIX_SIGNED_16;
994 #if !defined(__FreeBSD__)	/* XXXXX */
995 	mix.ctlunit = AudioNvolume;
996 #endif
997 
998 #define BIT(bno) ((bm[bno / 8] >> (7 - bno % 8)) & 1)
999 	for (p = i = 0; i < d->bNrInPins; i++) {
1000 		chs = uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels;
1001 		mc = 0;
1002 		for (c = 0; c < chs; c++) {
1003 			mo = 0;
1004 			for (o = 0; o < ochs; o++) {
1005 				bno = (p + c) * ochs + o;
1006 				if (BIT(bno))
1007 					mo++;
1008 			}
1009 			if (mo == 1)
1010 				mc++;
1011 		}
1012 		if (mc == chs && chs <= MIX_MAX_CHAN) {
1013 			k = 0;
1014 			for (c = 0; c < chs; c++)
1015 				for (o = 0; o < ochs; o++) {
1016 					bno = (p + c) * ochs + o;
1017 					if (BIT(bno))
1018 						mix.wValue[k++] =
1019 							MAKE(p+c+1, o+1);
1020 				}
1021 #if !defined(__FreeBSD__)
1022 			snprintf(mix.ctlname, sizeof(mix.ctlname), "mix%d-%s",
1023 			    d->bUnitId, uaudio_id_name(sc, iot,
1024 			    d->baSourceId[i]));
1025 #endif
1026 			mix.nchan = chs;
1027 			uaudio_mixer_add_ctl(sc, &mix);
1028 		} else {
1029 			/* XXX */
1030 		}
1031 #undef BIT
1032 		p += chs;
1033 	}
1034 
1035 }
1036 
1037 static void
1038 uaudio_add_selector(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
1039 {
1040 	const struct usb_audio_selector_unit *d;
1041 	struct mixerctl mix;
1042 #if !defined(__FreeBSD__)
1043 	int i, wp;
1044 #else
1045 	int i;
1046 	struct mixerctl dummy;
1047 #endif
1048 
1049 	d = iot[id].d.su;
1050 	DPRINTFN(2,("uaudio_add_selector: bUnitId=%d bNrInPins=%d\n",
1051 		    d->bUnitId, d->bNrInPins));
1052 	mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1053 	mix.wValue[0] = MAKE(0, 0);
1054 	uaudio_determine_class(&iot[id], &mix);
1055 	mix.nchan = 1;
1056 	mix.type = MIX_SELECTOR;
1057 #if defined(__FreeBSD__)
1058 	mix.ctl = SOUND_MIXER_NRDEVICES;	/* XXXXX */
1059 	mix.minval = 1;
1060 	mix.maxval = d->bNrInPins;
1061 	mix.mul = mix.maxval - mix.minval;
1062 	for (i = 0; i < MAX_SELECTOR_INPUT_PIN; i++) {
1063 		mix.slctrtype[i] = SOUND_MIXER_NRDEVICES;
1064 	}
1065 	for (i = mix.minval; i <= mix.maxval; i++) {
1066 		mix.slctrtype[i - 1] = uaudio_feature_name(&iot[d->baSourceId[i - 1]], &dummy);
1067 	}
1068 #else
1069 	mix.ctlunit = "";
1070 	mix.minval = 1;
1071 	mix.maxval = d->bNrInPins;
1072 	mix.mul = mix.maxval - mix.minval;
1073 	wp = snprintf(mix.ctlname, MAX_AUDIO_DEV_LEN, "sel%d-", d->bUnitId);
1074 	for (i = 1; i <= d->bNrInPins; i++) {
1075 		wp += snprintf(mix.ctlname + wp, MAX_AUDIO_DEV_LEN - wp,
1076 			       "i%d", d->baSourceId[i - 1]);
1077 		if (wp > MAX_AUDIO_DEV_LEN - 1)
1078 			break;
1079 	}
1080 #endif
1081 	uaudio_mixer_add_ctl(sc, &mix);
1082 }
1083 
1084 #ifdef USB_DEBUG
1085 static const char *
1086 uaudio_get_terminal_name(int terminal_type)
1087 {
1088 	static char buf[100];
1089 
1090 	switch (terminal_type) {
1091 	/* USB terminal types */
1092 	case UAT_UNDEFINED:	return "UAT_UNDEFINED";
1093 	case UAT_STREAM:	return "UAT_STREAM";
1094 	case UAT_VENDOR:	return "UAT_VENDOR";
1095 	/* input terminal types */
1096 	case UATI_UNDEFINED:	return "UATI_UNDEFINED";
1097 	case UATI_MICROPHONE:	return "UATI_MICROPHONE";
1098 	case UATI_DESKMICROPHONE:	return "UATI_DESKMICROPHONE";
1099 	case UATI_PERSONALMICROPHONE:	return "UATI_PERSONALMICROPHONE";
1100 	case UATI_OMNIMICROPHONE:	return "UATI_OMNIMICROPHONE";
1101 	case UATI_MICROPHONEARRAY:	return "UATI_MICROPHONEARRAY";
1102 	case UATI_PROCMICROPHONEARR:	return "UATI_PROCMICROPHONEARR";
1103 	/* output terminal types */
1104 	case UATO_UNDEFINED:	return "UATO_UNDEFINED";
1105 	case UATO_SPEAKER:	return "UATO_SPEAKER";
1106 	case UATO_HEADPHONES:	return "UATO_HEADPHONES";
1107 	case UATO_DISPLAYAUDIO:	return "UATO_DISPLAYAUDIO";
1108 	case UATO_DESKTOPSPEAKER:	return "UATO_DESKTOPSPEAKER";
1109 	case UATO_ROOMSPEAKER:	return "UATO_ROOMSPEAKER";
1110 	case UATO_COMMSPEAKER:	return "UATO_COMMSPEAKER";
1111 	case UATO_SUBWOOFER:	return "UATO_SUBWOOFER";
1112 	/* bidir terminal types */
1113 	case UATB_UNDEFINED:	return "UATB_UNDEFINED";
1114 	case UATB_HANDSET:	return "UATB_HANDSET";
1115 	case UATB_HEADSET:	return "UATB_HEADSET";
1116 	case UATB_SPEAKERPHONE:	return "UATB_SPEAKERPHONE";
1117 	case UATB_SPEAKERPHONEESUP:	return "UATB_SPEAKERPHONEESUP";
1118 	case UATB_SPEAKERPHONEECANC:	return "UATB_SPEAKERPHONEECANC";
1119 	/* telephony terminal types */
1120 	case UATT_UNDEFINED:	return "UATT_UNDEFINED";
1121 	case UATT_PHONELINE:	return "UATT_PHONELINE";
1122 	case UATT_TELEPHONE:	return "UATT_TELEPHONE";
1123 	case UATT_DOWNLINEPHONE:	return "UATT_DOWNLINEPHONE";
1124 	/* external terminal types */
1125 	case UATE_UNDEFINED:	return "UATE_UNDEFINED";
1126 	case UATE_ANALOGCONN:	return "UATE_ANALOGCONN";
1127 	case UATE_LINECONN:	return "UATE_LINECONN";
1128 	case UATE_LEGACYCONN:	return "UATE_LEGACYCONN";
1129 	case UATE_DIGITALAUIFC:	return "UATE_DIGITALAUIFC";
1130 	case UATE_SPDIF:	return "UATE_SPDIF";
1131 	case UATE_1394DA:	return "UATE_1394DA";
1132 	case UATE_1394DV:	return "UATE_1394DV";
1133 	/* embedded function terminal types */
1134 	case UATF_UNDEFINED:	return "UATF_UNDEFINED";
1135 	case UATF_CALIBNOISE:	return "UATF_CALIBNOISE";
1136 	case UATF_EQUNOISE:	return "UATF_EQUNOISE";
1137 	case UATF_CDPLAYER:	return "UATF_CDPLAYER";
1138 	case UATF_DAT:	return "UATF_DAT";
1139 	case UATF_DCC:	return "UATF_DCC";
1140 	case UATF_MINIDISK:	return "UATF_MINIDISK";
1141 	case UATF_ANALOGTAPE:	return "UATF_ANALOGTAPE";
1142 	case UATF_PHONOGRAPH:	return "UATF_PHONOGRAPH";
1143 	case UATF_VCRAUDIO:	return "UATF_VCRAUDIO";
1144 	case UATF_VIDEODISCAUDIO:	return "UATF_VIDEODISCAUDIO";
1145 	case UATF_DVDAUDIO:	return "UATF_DVDAUDIO";
1146 	case UATF_TVTUNERAUDIO:	return "UATF_TVTUNERAUDIO";
1147 	case UATF_SATELLITE:	return "UATF_SATELLITE";
1148 	case UATF_CABLETUNER:	return "UATF_CABLETUNER";
1149 	case UATF_DSS:	return "UATF_DSS";
1150 	case UATF_RADIORECV:	return "UATF_RADIORECV";
1151 	case UATF_RADIOXMIT:	return "UATF_RADIOXMIT";
1152 	case UATF_MULTITRACK:	return "UATF_MULTITRACK";
1153 	case UATF_SYNTHESIZER:	return "UATF_SYNTHESIZER";
1154 	default:
1155 		snprintf(buf, sizeof(buf), "unknown type (0x%.4x)", terminal_type);
1156 		return buf;
1157 	}
1158 }
1159 #endif
1160 
1161 static int
1162 uaudio_determine_class(const struct io_terminal *iot, struct mixerctl *mix)
1163 {
1164 	int terminal_type;
1165 
1166 	if (iot == NULL || iot->output == NULL) {
1167 		mix->class = UAC_OUTPUT;
1168 		return 0;
1169 	}
1170 	terminal_type = 0;
1171 	if (iot->output->size == 1)
1172 		terminal_type = iot->output->terminals[0];
1173 	/*
1174 	 * If the only output terminal is USB,
1175 	 * the class is UAC_RECORD.
1176 	 */
1177 	if ((terminal_type & 0xff00) == (UAT_UNDEFINED & 0xff00)) {
1178 		mix->class = UAC_RECORD;
1179 		if (iot->inputs_size == 1
1180 		    && iot->inputs[0] != NULL
1181 		    && iot->inputs[0]->size == 1)
1182 			return iot->inputs[0]->terminals[0];
1183 		else
1184 			return 0;
1185 	}
1186 	/*
1187 	 * If the ultimate destination of the unit is just one output
1188 	 * terminal and the unit is connected to the output terminal
1189 	 * directly, the class is UAC_OUTPUT.
1190 	 */
1191 	if (terminal_type != 0 && iot->direct) {
1192 		mix->class = UAC_OUTPUT;
1193 		return terminal_type;
1194 	}
1195 	/*
1196 	 * If the unit is connected to just one input terminal,
1197 	 * the class is UAC_INPUT.
1198 	 */
1199 	if (iot->inputs_size == 1 && iot->inputs[0] != NULL
1200 	    && iot->inputs[0]->size == 1) {
1201 		mix->class = UAC_INPUT;
1202 		return iot->inputs[0]->terminals[0];
1203 	}
1204 	/*
1205 	 * Otherwise, the class is UAC_OUTPUT.
1206 	 */
1207 	mix->class = UAC_OUTPUT;
1208 	return terminal_type;
1209 }
1210 
1211 #if defined(__FreeBSD__)
1212 const int
1213 uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix)
1214 {
1215 	int terminal_type;
1216 
1217 	terminal_type = uaudio_determine_class(iot, mix);
1218 	if (mix->class == UAC_RECORD && terminal_type == 0)
1219 		return SOUND_MIXER_IMIX;
1220 	DPRINTF(("%s: terminal_type=%s\n", __func__,
1221 		 uaudio_get_terminal_name(terminal_type)));
1222 	switch (terminal_type) {
1223 	case UAT_STREAM:
1224 		return SOUND_MIXER_PCM;
1225 
1226 	case UATI_MICROPHONE:
1227 	case UATI_DESKMICROPHONE:
1228 	case UATI_PERSONALMICROPHONE:
1229 	case UATI_OMNIMICROPHONE:
1230 	case UATI_MICROPHONEARRAY:
1231 	case UATI_PROCMICROPHONEARR:
1232 		return SOUND_MIXER_MIC;
1233 
1234 	case UATO_SPEAKER:
1235 	case UATO_DESKTOPSPEAKER:
1236 	case UATO_ROOMSPEAKER:
1237 	case UATO_COMMSPEAKER:
1238 		return SOUND_MIXER_SPEAKER;
1239 
1240 	case UATE_ANALOGCONN:
1241 	case UATE_LINECONN:
1242 	case UATE_LEGACYCONN:
1243 		return SOUND_MIXER_LINE;
1244 
1245 	case UATE_DIGITALAUIFC:
1246 	case UATE_SPDIF:
1247 	case UATE_1394DA:
1248 	case UATE_1394DV:
1249 		return SOUND_MIXER_ALTPCM;
1250 
1251 	case UATF_CDPLAYER:
1252 		return SOUND_MIXER_CD;
1253 
1254 	case UATF_SYNTHESIZER:
1255 		return SOUND_MIXER_SYNTH;
1256 
1257 	case UATF_VIDEODISCAUDIO:
1258 	case UATF_DVDAUDIO:
1259 	case UATF_TVTUNERAUDIO:
1260 		return SOUND_MIXER_VIDEO;
1261 
1262 /* telephony terminal types */
1263 	case UATT_UNDEFINED:
1264 	case UATT_PHONELINE:
1265 	case UATT_TELEPHONE:
1266 	case UATT_DOWNLINEPHONE:
1267 		return SOUND_MIXER_PHONEIN;
1268 /*		return SOUND_MIXER_PHONEOUT;*/
1269 
1270 	case UATF_RADIORECV:
1271 	case UATF_RADIOXMIT:
1272 		return SOUND_MIXER_RADIO;
1273 
1274 	case UAT_UNDEFINED:
1275 	case UAT_VENDOR:
1276 	case UATI_UNDEFINED:
1277 /* output terminal types */
1278 	case UATO_UNDEFINED:
1279 	case UATO_DISPLAYAUDIO:
1280 	case UATO_SUBWOOFER:
1281 	case UATO_HEADPHONES:
1282 /* bidir terminal types */
1283 	case UATB_UNDEFINED:
1284 	case UATB_HANDSET:
1285 	case UATB_HEADSET:
1286 	case UATB_SPEAKERPHONE:
1287 	case UATB_SPEAKERPHONEESUP:
1288 	case UATB_SPEAKERPHONEECANC:
1289 /* external terminal types */
1290 	case UATE_UNDEFINED:
1291 /* embedded function terminal types */
1292 	case UATF_UNDEFINED:
1293 	case UATF_CALIBNOISE:
1294 	case UATF_EQUNOISE:
1295 	case UATF_DAT:
1296 	case UATF_DCC:
1297 	case UATF_MINIDISK:
1298 	case UATF_ANALOGTAPE:
1299 	case UATF_PHONOGRAPH:
1300 	case UATF_VCRAUDIO:
1301 	case UATF_SATELLITE:
1302 	case UATF_CABLETUNER:
1303 	case UATF_DSS:
1304 	case UATF_MULTITRACK:
1305 	case 0xffff:
1306 	default:
1307 		DPRINTF(("%s: 'master' for 0x%.4x\n", __func__, terminal_type));
1308 		return SOUND_MIXER_VOLUME;
1309 	}
1310 	return SOUND_MIXER_VOLUME;
1311 }
1312 #else
1313 static const char *
1314 uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix)
1315 {
1316 	int terminal_type;
1317 
1318 	terminal_type = uaudio_determine_class(iot, mix);
1319 	if (mix->class == UAC_RECORD && terminal_type == 0)
1320 		return AudioNmixerout;
1321 	DPRINTF(("%s: terminal_type=%s\n", __func__,
1322 		 uaudio_get_terminal_name(terminal_type)));
1323 	switch (terminal_type) {
1324 	case UAT_STREAM:
1325 		return AudioNdac;
1326 
1327 	case UATI_MICROPHONE:
1328 	case UATI_DESKMICROPHONE:
1329 	case UATI_PERSONALMICROPHONE:
1330 	case UATI_OMNIMICROPHONE:
1331 	case UATI_MICROPHONEARRAY:
1332 	case UATI_PROCMICROPHONEARR:
1333 		return AudioNmicrophone;
1334 
1335 	case UATO_SPEAKER:
1336 	case UATO_DESKTOPSPEAKER:
1337 	case UATO_ROOMSPEAKER:
1338 	case UATO_COMMSPEAKER:
1339 		return AudioNspeaker;
1340 
1341 	case UATO_HEADPHONES:
1342 		return AudioNheadphone;
1343 
1344 	case UATO_SUBWOOFER:
1345 		return AudioNlfe;
1346 
1347 	/* telephony terminal types */
1348 	case UATT_UNDEFINED:
1349 	case UATT_PHONELINE:
1350 	case UATT_TELEPHONE:
1351 	case UATT_DOWNLINEPHONE:
1352 		return "phone";
1353 
1354 	case UATE_ANALOGCONN:
1355 	case UATE_LINECONN:
1356 	case UATE_LEGACYCONN:
1357 		return AudioNline;
1358 
1359 	case UATE_DIGITALAUIFC:
1360 	case UATE_SPDIF:
1361 	case UATE_1394DA:
1362 	case UATE_1394DV:
1363 		return AudioNaux;
1364 
1365 	case UATF_CDPLAYER:
1366 		return AudioNcd;
1367 
1368 	case UATF_SYNTHESIZER:
1369 		return AudioNfmsynth;
1370 
1371 	case UATF_VIDEODISCAUDIO:
1372 	case UATF_DVDAUDIO:
1373 	case UATF_TVTUNERAUDIO:
1374 		return AudioNvideo;
1375 
1376 	case UAT_UNDEFINED:
1377 	case UAT_VENDOR:
1378 	case UATI_UNDEFINED:
1379 /* output terminal types */
1380 	case UATO_UNDEFINED:
1381 	case UATO_DISPLAYAUDIO:
1382 /* bidir terminal types */
1383 	case UATB_UNDEFINED:
1384 	case UATB_HANDSET:
1385 	case UATB_HEADSET:
1386 	case UATB_SPEAKERPHONE:
1387 	case UATB_SPEAKERPHONEESUP:
1388 	case UATB_SPEAKERPHONEECANC:
1389 /* external terminal types */
1390 	case UATE_UNDEFINED:
1391 /* embedded function terminal types */
1392 	case UATF_UNDEFINED:
1393 	case UATF_CALIBNOISE:
1394 	case UATF_EQUNOISE:
1395 	case UATF_DAT:
1396 	case UATF_DCC:
1397 	case UATF_MINIDISK:
1398 	case UATF_ANALOGTAPE:
1399 	case UATF_PHONOGRAPH:
1400 	case UATF_VCRAUDIO:
1401 	case UATF_SATELLITE:
1402 	case UATF_CABLETUNER:
1403 	case UATF_DSS:
1404 	case UATF_RADIORECV:
1405 	case UATF_RADIOXMIT:
1406 	case UATF_MULTITRACK:
1407 	case 0xffff:
1408 	default:
1409 		DPRINTF(("%s: 'master' for 0x%.4x\n", __func__, terminal_type));
1410 		return AudioNmaster;
1411 	}
1412 	return AudioNmaster;
1413 }
1414 #endif
1415 
1416 static void
1417 uaudio_add_feature(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
1418 {
1419 	const struct usb_audio_feature_unit *d;
1420 	const uByte *ctls;
1421 	int ctlsize;
1422 	int nchan;
1423 	u_int fumask, mmask, cmask;
1424 	struct mixerctl mix;
1425 	int chan, ctl, i, unit;
1426 #if defined(__FreeBSD__)
1427 	int mixernumber;
1428 #else
1429 	const char *mixername;
1430 #endif
1431 
1432 #define GET(i) (ctls[(i)*ctlsize] | \
1433 		(ctlsize > 1 ? ctls[(i)*ctlsize+1] << 8 : 0))
1434 	d = iot[id].d.fu;
1435 	ctls = d->bmaControls;
1436 	ctlsize = d->bControlSize;
1437 	nchan = (d->bLength - 7) / ctlsize;
1438 	mmask = GET(0);
1439 	/* Figure out what we can control */
1440 	for (cmask = 0, chan = 1; chan < nchan; chan++) {
1441 		DPRINTFN(9,("uaudio_add_feature: chan=%d mask=%x\n",
1442 			    chan, GET(chan)));
1443 		cmask |= GET(chan);
1444 	}
1445 
1446 #if !defined(__FreeBSD__)
1447 	DPRINTFN(1,("uaudio_add_feature: bUnitId=%d, "
1448 		    "%d channels, mmask=0x%04x, cmask=0x%04x\n",
1449 		    d->bUnitId, nchan, mmask, cmask));
1450 #endif
1451 
1452 	if (nchan > MIX_MAX_CHAN)
1453 		nchan = MIX_MAX_CHAN;
1454 	unit = d->bUnitId;
1455 	mix.wIndex = MAKE(unit, sc->sc_ac_iface);
1456 	for (ctl = MUTE_CONTROL; ctl < LOUDNESS_CONTROL; ctl++) {
1457 		fumask = FU_MASK(ctl);
1458 		DPRINTFN(4,("uaudio_add_feature: ctl=%d fumask=0x%04x\n",
1459 			    ctl, fumask));
1460 		if (mmask & fumask) {
1461 			mix.nchan = 1;
1462 			mix.wValue[0] = MAKE(ctl, 0);
1463 		} else if (cmask & fumask) {
1464 			mix.nchan = nchan - 1;
1465 			for (i = 1; i < nchan; i++) {
1466 				if (GET(i) & fumask)
1467 					mix.wValue[i-1] = MAKE(ctl, i);
1468 				else
1469 					mix.wValue[i-1] = -1;
1470 			}
1471 		} else {
1472 			continue;
1473 		}
1474 #undef GET
1475 
1476 #if defined(__FreeBSD__)
1477 		mixernumber = uaudio_feature_name(&iot[id], &mix);
1478 #else
1479 		mixername = uaudio_feature_name(&iot[id], &mix);
1480 #endif
1481 		switch (ctl) {
1482 		case MUTE_CONTROL:
1483 			mix.type = MIX_ON_OFF;
1484 #if defined(__FreeBSD__)
1485 			mix.ctl = SOUND_MIXER_NRDEVICES;
1486 #else
1487 			mix.ctlunit = "";
1488 			snprintf(mix.ctlname, sizeof(mix.ctlname),
1489 				 "%s.%s", mixername, AudioNmute);
1490 #endif
1491 			break;
1492 		case VOLUME_CONTROL:
1493 			mix.type = MIX_SIGNED_16;
1494 #if defined(__FreeBSD__)
1495 			mix.ctl = mixernumber;
1496 #else
1497 			mix.ctlunit = AudioNvolume;
1498 			strlcpy(mix.ctlname, mixername, sizeof(mix.ctlname));
1499 #endif
1500 			break;
1501 		case BASS_CONTROL:
1502 			mix.type = MIX_SIGNED_8;
1503 #if defined(__FreeBSD__)
1504 			mix.ctl = SOUND_MIXER_BASS;
1505 #else
1506 			mix.ctlunit = AudioNbass;
1507 			snprintf(mix.ctlname, sizeof(mix.ctlname),
1508 				 "%s.%s", mixername, AudioNbass);
1509 #endif
1510 			break;
1511 		case MID_CONTROL:
1512 			mix.type = MIX_SIGNED_8;
1513 #if defined(__FreeBSD__)
1514 			mix.ctl = SOUND_MIXER_NRDEVICES;	/* XXXXX */
1515 #else
1516 			mix.ctlunit = AudioNmid;
1517 			snprintf(mix.ctlname, sizeof(mix.ctlname),
1518 				 "%s.%s", mixername, AudioNmid);
1519 #endif
1520 			break;
1521 		case TREBLE_CONTROL:
1522 			mix.type = MIX_SIGNED_8;
1523 #if defined(__FreeBSD__)
1524 			mix.ctl = SOUND_MIXER_TREBLE;
1525 #else
1526 			mix.ctlunit = AudioNtreble;
1527 			snprintf(mix.ctlname, sizeof(mix.ctlname),
1528 				 "%s.%s", mixername, AudioNtreble);
1529 #endif
1530 			break;
1531 		case GRAPHIC_EQUALIZER_CONTROL:
1532 			continue; /* XXX don't add anything */
1533 			break;
1534 		case AGC_CONTROL:
1535 			mix.type = MIX_ON_OFF;
1536 #if defined(__FreeBSD__)
1537 			mix.ctl = SOUND_MIXER_NRDEVICES;	/* XXXXX */
1538 #else
1539 			mix.ctlunit = "";
1540 			snprintf(mix.ctlname, sizeof(mix.ctlname), "%s.%s",
1541 				 mixername, AudioNagc);
1542 #endif
1543 			break;
1544 		case DELAY_CONTROL:
1545 			mix.type = MIX_UNSIGNED_16;
1546 #if defined(__FreeBSD__)
1547 			mix.ctl = SOUND_MIXER_NRDEVICES;	/* XXXXX */
1548 #else
1549 			mix.ctlunit = "4 ms";
1550 			snprintf(mix.ctlname, sizeof(mix.ctlname),
1551 				 "%s.%s", mixername, AudioNdelay);
1552 #endif
1553 			break;
1554 		case BASS_BOOST_CONTROL:
1555 			mix.type = MIX_ON_OFF;
1556 #if defined(__FreeBSD__)
1557 			mix.ctl = SOUND_MIXER_NRDEVICES;	/* XXXXX */
1558 #else
1559 			mix.ctlunit = "";
1560 			snprintf(mix.ctlname, sizeof(mix.ctlname),
1561 				 "%s.%s", mixername, AudioNbassboost);
1562 #endif
1563 			break;
1564 		case LOUDNESS_CONTROL:
1565 			mix.type = MIX_ON_OFF;
1566 #if defined(__FreeBSD__)
1567 			mix.ctl = SOUND_MIXER_LOUD;	/* Is this correct ? */
1568 #else
1569 			mix.ctlunit = "";
1570 			snprintf(mix.ctlname, sizeof(mix.ctlname),
1571 				 "%s.%s", mixername, AudioNloudness);
1572 #endif
1573 			break;
1574 		}
1575 		uaudio_mixer_add_ctl(sc, &mix);
1576 	}
1577 }
1578 
1579 static void
1580 uaudio_add_processing_updown(struct uaudio_softc *sc,
1581 			     const struct io_terminal *iot, int id)
1582 {
1583 	const struct usb_audio_processing_unit *d;
1584 	const struct usb_audio_processing_unit_1 *d1;
1585 	const struct usb_audio_processing_unit_updown *ud;
1586 	struct mixerctl mix;
1587 	int i;
1588 
1589 	d = iot[id].d.pu;
1590 	d1 = (const struct usb_audio_processing_unit_1 *)
1591 		&d->baSourceId[d->bNrInPins];
1592 	ud = (const struct usb_audio_processing_unit_updown *)
1593 		&d1->bmControls[d1->bControlSize];
1594 	DPRINTFN(2,("uaudio_add_processing_updown: bUnitId=%d bNrModes=%d\n",
1595 		    d->bUnitId, ud->bNrModes));
1596 
1597 	if (!(d1->bmControls[0] & UA_PROC_MASK(UD_MODE_SELECT_CONTROL))) {
1598 		DPRINTF(("uaudio_add_processing_updown: no mode select\n"));
1599 		return;
1600 	}
1601 
1602 	mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1603 	mix.nchan = 1;
1604 	mix.wValue[0] = MAKE(UD_MODE_SELECT_CONTROL, 0);
1605 	uaudio_determine_class(&iot[id], &mix);
1606 	mix.type = MIX_ON_OFF;	/* XXX */
1607 #if !defined(__FreeBSD__)
1608 	mix.ctlunit = "";
1609 	snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d-mode", d->bUnitId);
1610 #endif
1611 
1612 	for (i = 0; i < ud->bNrModes; i++) {
1613 		DPRINTFN(2,("uaudio_add_processing_updown: i=%d bm=0x%x\n",
1614 			    i, UGETW(ud->waModes[i])));
1615 		/* XXX */
1616 	}
1617 	uaudio_mixer_add_ctl(sc, &mix);
1618 }
1619 
1620 static void
1621 uaudio_add_processing(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
1622 {
1623 	const struct usb_audio_processing_unit *d;
1624 	const struct usb_audio_processing_unit_1 *d1;
1625 	int ptype;
1626 	struct mixerctl mix;
1627 
1628 	d = iot[id].d.pu;
1629 	d1 = (const struct usb_audio_processing_unit_1 *)
1630 		&d->baSourceId[d->bNrInPins];
1631 	ptype = UGETW(d->wProcessType);
1632 	DPRINTFN(2,("uaudio_add_processing: wProcessType=%d bUnitId=%d "
1633 		    "bNrInPins=%d\n", ptype, d->bUnitId, d->bNrInPins));
1634 
1635 	if (d1->bmControls[0] & UA_PROC_ENABLE_MASK) {
1636 		mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1637 		mix.nchan = 1;
1638 		mix.wValue[0] = MAKE(XX_ENABLE_CONTROL, 0);
1639 		uaudio_determine_class(&iot[id], &mix);
1640 		mix.type = MIX_ON_OFF;
1641 #if !defined(__FreeBSD__)
1642 		mix.ctlunit = "";
1643 		snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d.%d-enable",
1644 		    d->bUnitId, ptype);
1645 #endif
1646 		uaudio_mixer_add_ctl(sc, &mix);
1647 	}
1648 
1649 	switch(ptype) {
1650 	case UPDOWNMIX_PROCESS:
1651 		uaudio_add_processing_updown(sc, iot, id);
1652 		break;
1653 	case DOLBY_PROLOGIC_PROCESS:
1654 	case P3D_STEREO_EXTENDER_PROCESS:
1655 	case REVERBATION_PROCESS:
1656 	case CHORUS_PROCESS:
1657 	case DYN_RANGE_COMP_PROCESS:
1658 	default:
1659 #ifdef USB_DEBUG
1660 		printf("uaudio_add_processing: unit %d, type=%d not impl.\n",
1661 		       d->bUnitId, ptype);
1662 #endif
1663 		break;
1664 	}
1665 }
1666 
1667 static void
1668 uaudio_add_extension(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
1669 {
1670 	const struct usb_audio_extension_unit *d;
1671 	const struct usb_audio_extension_unit_1 *d1;
1672 	struct mixerctl mix;
1673 
1674 	d = iot[id].d.eu;
1675 	d1 = (const struct usb_audio_extension_unit_1 *)
1676 		&d->baSourceId[d->bNrInPins];
1677 	DPRINTFN(2,("uaudio_add_extension: bUnitId=%d bNrInPins=%d\n",
1678 		    d->bUnitId, d->bNrInPins));
1679 
1680 	if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_XU)
1681 		return;
1682 
1683 	if (d1->bmControls[0] & UA_EXT_ENABLE_MASK) {
1684 		mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
1685 		mix.nchan = 1;
1686 		mix.wValue[0] = MAKE(UA_EXT_ENABLE, 0);
1687 		uaudio_determine_class(&iot[id], &mix);
1688 		mix.type = MIX_ON_OFF;
1689 #if !defined(__FreeBSD__)
1690 		mix.ctlunit = "";
1691 		snprintf(mix.ctlname, sizeof(mix.ctlname), "ext%d-enable",
1692 		    d->bUnitId);
1693 #endif
1694 		uaudio_mixer_add_ctl(sc, &mix);
1695 	}
1696 }
1697 
1698 static struct terminal_list*
1699 uaudio_merge_terminal_list(const struct io_terminal *iot)
1700 {
1701 	struct terminal_list *tml;
1702 	uint16_t *ptm;
1703 	int i, len;
1704 
1705 	len = 0;
1706 	if (iot->inputs == NULL)
1707 		return NULL;
1708 	for (i = 0; i < iot->inputs_size; i++) {
1709 		if (iot->inputs[i] != NULL)
1710 			len += iot->inputs[i]->size;
1711 	}
1712 	tml = malloc(TERMINAL_LIST_SIZE(len), M_TEMP, M_NOWAIT);
1713 	if (tml == NULL) {
1714 		printf("uaudio_merge_terminal_list: no memory\n");
1715 		return NULL;
1716 	}
1717 	tml->size = 0;
1718 	ptm = tml->terminals;
1719 	for (i = 0; i < iot->inputs_size; i++) {
1720 		if (iot->inputs[i] == NULL)
1721 			continue;
1722 		if (iot->inputs[i]->size > len)
1723 			break;
1724 		memcpy(ptm, iot->inputs[i]->terminals,
1725 		       iot->inputs[i]->size * sizeof(uint16_t));
1726 		tml->size += iot->inputs[i]->size;
1727 		ptm += iot->inputs[i]->size;
1728 		len -= iot->inputs[i]->size;
1729 	}
1730 	return tml;
1731 }
1732 
1733 static struct terminal_list *
1734 uaudio_io_terminaltype(int outtype, struct io_terminal *iot, int id)
1735 {
1736 	struct terminal_list *tml;
1737 	struct io_terminal *it;
1738 	int src_id, i;
1739 
1740 	it = &iot[id];
1741 	if (it->output != NULL) {
1742 		/* already has outtype? */
1743 		for (i = 0; i < it->output->size; i++)
1744 			if (it->output->terminals[i] == outtype)
1745 				return uaudio_merge_terminal_list(it);
1746 		tml = malloc(TERMINAL_LIST_SIZE(it->output->size + 1),
1747 			     M_TEMP, M_NOWAIT);
1748 		if (tml == NULL) {
1749 			printf("uaudio_io_terminaltype: no memory\n");
1750 			return uaudio_merge_terminal_list(it);
1751 		}
1752 		memcpy(tml, it->output, TERMINAL_LIST_SIZE(it->output->size));
1753 		tml->terminals[it->output->size] = outtype;
1754 		tml->size++;
1755 		free(it->output, M_TEMP);
1756 		it->output = tml;
1757 		if (it->inputs != NULL) {
1758 			for (i = 0; i < it->inputs_size; i++)
1759 				if (it->inputs[i] != NULL)
1760 					free(it->inputs[i], M_TEMP);
1761 			free(it->inputs, M_TEMP);
1762 		}
1763 		it->inputs_size = 0;
1764 		it->inputs = NULL;
1765 	} else {		/* end `iot[id] != NULL' */
1766 		it->inputs_size = 0;
1767 		it->inputs = NULL;
1768 		it->output = malloc(TERMINAL_LIST_SIZE(1), M_TEMP, M_NOWAIT);
1769 		if (it->output == NULL) {
1770 			printf("uaudio_io_terminaltype: no memory\n");
1771 			return NULL;
1772 		}
1773 		it->output->terminals[0] = outtype;
1774 		it->output->size = 1;
1775 		it->direct = FALSE;
1776 	}
1777 
1778 	switch (it->d.desc->bDescriptorSubtype) {
1779 	case UDESCSUB_AC_INPUT:
1780 		it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT);
1781 		if (it->inputs == NULL) {
1782 			printf("uaudio_io_terminaltype: no memory\n");
1783 			return NULL;
1784 		}
1785 		tml = malloc(TERMINAL_LIST_SIZE(1), M_TEMP, M_NOWAIT);
1786 		if (tml == NULL) {
1787 			printf("uaudio_io_terminaltype: no memory\n");
1788 			free(it->inputs, M_TEMP);
1789 			it->inputs = NULL;
1790 			return NULL;
1791 		}
1792 		it->inputs[0] = tml;
1793 		tml->terminals[0] = UGETW(it->d.it->wTerminalType);
1794 		tml->size = 1;
1795 		it->inputs_size = 1;
1796 		return uaudio_merge_terminal_list(it);
1797 	case UDESCSUB_AC_FEATURE:
1798 		src_id = it->d.fu->bSourceId;
1799 		it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT);
1800 		if (it->inputs == NULL) {
1801 			printf("uaudio_io_terminaltype: no memory\n");
1802 			return uaudio_io_terminaltype(outtype, iot, src_id);
1803 		}
1804 		it->inputs[0] = uaudio_io_terminaltype(outtype, iot, src_id);
1805 		it->inputs_size = 1;
1806 		return uaudio_merge_terminal_list(it);
1807 	case UDESCSUB_AC_OUTPUT:
1808 		it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT);
1809 		if (it->inputs == NULL) {
1810 			printf("uaudio_io_terminaltype: no memory\n");
1811 			return NULL;
1812 		}
1813 		src_id = it->d.ot->bSourceId;
1814 		it->inputs[0] = uaudio_io_terminaltype(outtype, iot, src_id);
1815 		it->inputs_size = 1;
1816 		iot[src_id].direct = TRUE;
1817 		return NULL;
1818 	case UDESCSUB_AC_MIXER:
1819 		it->inputs_size = 0;
1820 		it->inputs = malloc(sizeof(struct terminal_list *)
1821 				    * it->d.mu->bNrInPins, M_TEMP, M_NOWAIT);
1822 		if (it->inputs == NULL) {
1823 			printf("uaudio_io_terminaltype: no memory\n");
1824 			return NULL;
1825 		}
1826 		for (i = 0; i < it->d.mu->bNrInPins; i++) {
1827 			src_id = it->d.mu->baSourceId[i];
1828 			it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
1829 							       src_id);
1830 			it->inputs_size++;
1831 		}
1832 		return uaudio_merge_terminal_list(it);
1833 	case UDESCSUB_AC_SELECTOR:
1834 		it->inputs_size = 0;
1835 		it->inputs = malloc(sizeof(struct terminal_list *)
1836 				    * it->d.su->bNrInPins, M_TEMP, M_NOWAIT);
1837 		if (it->inputs == NULL) {
1838 			printf("uaudio_io_terminaltype: no memory\n");
1839 			return NULL;
1840 		}
1841 		for (i = 0; i < it->d.su->bNrInPins; i++) {
1842 			src_id = it->d.su->baSourceId[i];
1843 			it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
1844 							       src_id);
1845 			it->inputs_size++;
1846 		}
1847 		return uaudio_merge_terminal_list(it);
1848 	case UDESCSUB_AC_PROCESSING:
1849 		it->inputs_size = 0;
1850 		it->inputs = malloc(sizeof(struct terminal_list *)
1851 				    * it->d.pu->bNrInPins, M_TEMP, M_NOWAIT);
1852 		if (it->inputs == NULL) {
1853 			printf("uaudio_io_terminaltype: no memory\n");
1854 			return NULL;
1855 		}
1856 		for (i = 0; i < it->d.pu->bNrInPins; i++) {
1857 			src_id = it->d.pu->baSourceId[i];
1858 			it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
1859 							       src_id);
1860 			it->inputs_size++;
1861 		}
1862 		return uaudio_merge_terminal_list(it);
1863 	case UDESCSUB_AC_EXTENSION:
1864 		it->inputs_size = 0;
1865 		it->inputs = malloc(sizeof(struct terminal_list *)
1866 				    * it->d.eu->bNrInPins, M_TEMP, M_NOWAIT);
1867 		if (it->inputs == NULL) {
1868 			printf("uaudio_io_terminaltype: no memory\n");
1869 			return NULL;
1870 		}
1871 		for (i = 0; i < it->d.eu->bNrInPins; i++) {
1872 			src_id = it->d.eu->baSourceId[i];
1873 			it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
1874 							       src_id);
1875 			it->inputs_size++;
1876 		}
1877 		return uaudio_merge_terminal_list(it);
1878 	case UDESCSUB_AC_HEADER:
1879 	default:
1880 		return NULL;
1881 	}
1882 }
1883 
1884 static usbd_status
1885 uaudio_identify(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc)
1886 {
1887 	usbd_status err;
1888 
1889 	err = uaudio_identify_ac(sc, cdesc);
1890 	if (err)
1891 		return err;
1892 	return uaudio_identify_as(sc, cdesc);
1893 }
1894 
1895 static void
1896 uaudio_add_alt(struct uaudio_softc *sc, const struct as_info *ai)
1897 {
1898 	size_t len;
1899 	struct as_info *nai;
1900 
1901 	len = sizeof(*ai) * (sc->sc_nalts + 1);
1902 	nai = malloc(len, M_USBDEV, M_NOWAIT);
1903 	if (nai == NULL) {
1904 		printf("uaudio_add_alt: no memory\n");
1905 		return;
1906 	}
1907 	/* Copy old data, if there was any */
1908 	if (sc->sc_nalts != 0) {
1909 		memcpy(nai, sc->sc_alts, sizeof(*ai) * (sc->sc_nalts));
1910 		free(sc->sc_alts, M_USBDEV);
1911 	}
1912 	sc->sc_alts = nai;
1913 	DPRINTFN(2,("uaudio_add_alt: adding alt=%d, enc=%d\n",
1914 		    ai->alt, ai->encoding));
1915 	sc->sc_alts[sc->sc_nalts++] = *ai;
1916 }
1917 
1918 static usbd_status
1919 uaudio_process_as(struct uaudio_softc *sc, const char *buf, int *offsp,
1920 		  int size, const usb_interface_descriptor_t *id)
1921 #define offs (*offsp)
1922 {
1923 	const struct usb_audio_streaming_interface_descriptor *asid;
1924 	const struct usb_audio_streaming_type1_descriptor *asf1d;
1925 	const usb_endpoint_descriptor_audio_t *ed;
1926 	const usb_endpoint_descriptor_audio_t *epdesc1;
1927 	const struct usb_audio_streaming_endpoint_descriptor *sed;
1928 	int format, chan, prec, enc;
1929 	int dir, type, sync;
1930 	struct as_info ai;
1931 	const char *format_str;
1932 
1933 	asid = (const void *)(buf + offs);
1934 
1935 	if (asid->bDescriptorType != UDESC_CS_INTERFACE ||
1936 	    asid->bDescriptorSubtype != AS_GENERAL)
1937 		return USBD_INVAL;
1938 	DPRINTF(("uaudio_process_as: asid: bTerminakLink=%d wFormatTag=%d\n",
1939 		 asid->bTerminalLink, UGETW(asid->wFormatTag)));
1940 	offs += asid->bLength;
1941 	if (offs > size)
1942 		return USBD_INVAL;
1943 
1944 	asf1d = (const void *)(buf + offs);
1945 	if (asf1d->bDescriptorType != UDESC_CS_INTERFACE ||
1946 	    asf1d->bDescriptorSubtype != FORMAT_TYPE)
1947 		return USBD_INVAL;
1948 	offs += asf1d->bLength;
1949 	if (offs > size)
1950 		return USBD_INVAL;
1951 
1952 	if (asf1d->bFormatType != FORMAT_TYPE_I) {
1953 		printf("%s: ignored setting with type %d format\n",
1954 		       device_get_nameunit(sc->sc_dev), UGETW(asid->wFormatTag));
1955 		return USBD_NORMAL_COMPLETION;
1956 	}
1957 
1958 	ed = (const void *)(buf + offs);
1959 	if (ed->bDescriptorType != UDESC_ENDPOINT)
1960 		return USBD_INVAL;
1961 	DPRINTF(("uaudio_process_as: endpoint[0] bLength=%d bDescriptorType=%d "
1962 		 "bEndpointAddress=%d bmAttributes=0x%x wMaxPacketSize=%d "
1963 		 "bInterval=%d bRefresh=%d bSynchAddress=%d\n",
1964 		 ed->bLength, ed->bDescriptorType, ed->bEndpointAddress,
1965 		 ed->bmAttributes, UGETW(ed->wMaxPacketSize),
1966 		 ed->bInterval, ed->bRefresh, ed->bSynchAddress));
1967 	offs += ed->bLength;
1968 	if (offs > size)
1969 		return USBD_INVAL;
1970 	if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS)
1971 		return USBD_INVAL;
1972 
1973 	dir = UE_GET_DIR(ed->bEndpointAddress);
1974 	type = UE_GET_ISO_TYPE(ed->bmAttributes);
1975 	if ((usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_INP_ASYNC) &&
1976 	    dir == UE_DIR_IN && type == UE_ISO_ADAPT)
1977 		type = UE_ISO_ASYNC;
1978 
1979 	/* We can't handle endpoints that need a sync pipe yet. */
1980 	sync = FALSE;
1981 	if (dir == UE_DIR_IN && type == UE_ISO_ADAPT) {
1982 		sync = TRUE;
1983 #ifndef UAUDIO_MULTIPLE_ENDPOINTS
1984 		printf("%s: ignored input endpoint of type adaptive\n",
1985 		       device_get_nameunit(sc->sc_dev));
1986 		return USBD_NORMAL_COMPLETION;
1987 #endif
1988 	}
1989 	if (dir != UE_DIR_IN && type == UE_ISO_ASYNC) {
1990 		sync = TRUE;
1991 #ifndef UAUDIO_MULTIPLE_ENDPOINTS
1992 		printf("%s: ignored output endpoint of type async\n",
1993 		       device_get_nameunit(sc->sc_dev));
1994 		return USBD_NORMAL_COMPLETION;
1995 #endif
1996 	}
1997 
1998 	sed = (const void *)(buf + offs);
1999 	if (sed->bDescriptorType != UDESC_CS_ENDPOINT ||
2000 	    sed->bDescriptorSubtype != AS_GENERAL)
2001 		return USBD_INVAL;
2002 	DPRINTF((" streadming_endpoint: offset=%d bLength=%d\n", offs, sed->bLength));
2003 	offs += sed->bLength;
2004 	if (offs > size)
2005 		return USBD_INVAL;
2006 
2007 #ifdef UAUDIO_MULTIPLE_ENDPOINTS
2008 	if (sync && id->bNumEndpoints <= 1) {
2009 		printf("%s: a sync-pipe endpoint but no other endpoint\n",
2010 		       device_get_nameunit(sc->sc_dev));
2011 		return USBD_INVAL;
2012 	}
2013 #endif
2014 	if (!sync && id->bNumEndpoints > 1) {
2015 		printf("%s: non sync-pipe endpoint but multiple endpoints\n",
2016 		       device_get_nameunit(sc->sc_dev));
2017 		return USBD_INVAL;
2018 	}
2019 	epdesc1 = NULL;
2020 	if (id->bNumEndpoints > 1) {
2021 		epdesc1 = (const void*)(buf + offs);
2022 		if (epdesc1->bDescriptorType != UDESC_ENDPOINT)
2023 			return USBD_INVAL;
2024 		DPRINTF(("uaudio_process_as: endpoint[1] bLength=%d "
2025 			 "bDescriptorType=%d bEndpointAddress=%d "
2026 			 "bmAttributes=0x%x wMaxPacketSize=%d bInterval=%d "
2027 			 "bRefresh=%d bSynchAddress=%d\n",
2028 			 epdesc1->bLength, epdesc1->bDescriptorType,
2029 			 epdesc1->bEndpointAddress, epdesc1->bmAttributes,
2030 			 UGETW(epdesc1->wMaxPacketSize), epdesc1->bInterval,
2031 			 epdesc1->bRefresh, epdesc1->bSynchAddress));
2032 		offs += epdesc1->bLength;
2033 		if (offs > size)
2034 			return USBD_INVAL;
2035 		if (epdesc1->bSynchAddress != 0) {
2036 			printf("%s: invalid endpoint: bSynchAddress=0\n",
2037 			       device_get_nameunit(sc->sc_dev));
2038 			return USBD_INVAL;
2039 		}
2040 		if (UE_GET_XFERTYPE(epdesc1->bmAttributes) != UE_ISOCHRONOUS) {
2041 			printf("%s: invalid endpoint: bmAttributes=0x%x\n",
2042 			       device_get_nameunit(sc->sc_dev), epdesc1->bmAttributes);
2043 			return USBD_INVAL;
2044 		}
2045 		if (epdesc1->bEndpointAddress != ed->bSynchAddress) {
2046 			printf("%s: invalid endpoint addresses: "
2047 			       "ep[0]->bSynchAddress=0x%x "
2048 			       "ep[1]->bEndpointAddress=0x%x\n",
2049 			       device_get_nameunit(sc->sc_dev), ed->bSynchAddress,
2050 			       epdesc1->bEndpointAddress);
2051 			return USBD_INVAL;
2052 		}
2053 		/* UE_GET_ADDR(epdesc1->bEndpointAddress), and epdesc1->bRefresh */
2054 	}
2055 
2056 	format = UGETW(asid->wFormatTag);
2057 	chan = asf1d->bNrChannels;
2058 	prec = asf1d->bBitResolution;
2059 	if (prec != 8 && prec != 16 && prec != 24 && prec != 32) {
2060 		printf("%s: ignored setting with precision %d\n",
2061 		       device_get_nameunit(sc->sc_dev), prec);
2062 		return USBD_NORMAL_COMPLETION;
2063 	}
2064 	switch (format) {
2065 	case UA_FMT_PCM:
2066 		if (prec == 8) {
2067 			sc->sc_altflags |= HAS_8;
2068 		} else if (prec == 16) {
2069 			sc->sc_altflags |= HAS_16;
2070 		} else if (prec == 24) {
2071 			sc->sc_altflags |= HAS_24;
2072 		} else if (prec == 32) {
2073 			sc->sc_altflags |= HAS_32;
2074 		}
2075 		enc = AUDIO_ENCODING_SLINEAR_LE;
2076 		format_str = "pcm";
2077 		break;
2078 	case UA_FMT_PCM8:
2079 		enc = AUDIO_ENCODING_ULINEAR_LE;
2080 		sc->sc_altflags |= HAS_8U;
2081 		format_str = "pcm8";
2082 		break;
2083 	case UA_FMT_ALAW:
2084 		enc = AUDIO_ENCODING_ALAW;
2085 		sc->sc_altflags |= HAS_ALAW;
2086 		format_str = "alaw";
2087 		break;
2088 	case UA_FMT_MULAW:
2089 		enc = AUDIO_ENCODING_ULAW;
2090 		sc->sc_altflags |= HAS_MULAW;
2091 		format_str = "mulaw";
2092 		break;
2093 	case UA_FMT_IEEE_FLOAT:
2094 	default:
2095 		printf("%s: ignored setting with format %d\n",
2096 		       device_get_nameunit(sc->sc_dev), format);
2097 		return USBD_NORMAL_COMPLETION;
2098 	}
2099 #ifdef USB_DEBUG
2100 	printf("%s: %s: %dch, %d/%dbit, %s,", device_get_nameunit(sc->sc_dev),
2101 	       dir == UE_DIR_IN ? "recording" : "playback",
2102 	       chan, prec, asf1d->bSubFrameSize * 8, format_str);
2103 	if (asf1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
2104 		printf(" %d-%dHz\n", UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d));
2105 	} else {
2106 		int r;
2107 		printf(" %d", UA_GETSAMP(asf1d, 0));
2108 		for (r = 1; r < asf1d->bSamFreqType; r++)
2109 			printf(",%d", UA_GETSAMP(asf1d, r));
2110 		printf("Hz\n");
2111 	}
2112 #endif
2113 #if defined(__FreeBSD__)
2114 	if (sc->uaudio_sndstat_flag != 0) {
2115 		sbuf_printf(&(sc->uaudio_sndstat), "\n\t");
2116 		sbuf_printf(&(sc->uaudio_sndstat),
2117 		    "mode %d:(%s) %dch, %d/%dbit, %s,",
2118 		    id->bAlternateSetting,
2119 		    dir == UE_DIR_IN ? "input" : "output",
2120 		    chan, prec, asf1d->bSubFrameSize * 8, format_str);
2121 		if (asf1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
2122 			sbuf_printf(&(sc->uaudio_sndstat), " %d-%dHz",
2123 			    UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d));
2124 		} else {
2125 			int r;
2126 			sbuf_printf(&(sc->uaudio_sndstat),
2127 			    " %d", UA_GETSAMP(asf1d, 0));
2128 			for (r = 1; r < asf1d->bSamFreqType; r++)
2129 				sbuf_printf(&(sc->uaudio_sndstat),
2130 				    ",%d", UA_GETSAMP(asf1d, r));
2131 			sbuf_printf(&(sc->uaudio_sndstat), "Hz");
2132 		}
2133 	}
2134 #endif
2135 	ai.alt = id->bAlternateSetting;
2136 	ai.encoding = enc;
2137 	ai.attributes = sed->bmAttributes;
2138 	ai.idesc = id;
2139 	ai.edesc = ed;
2140 	ai.edesc1 = epdesc1;
2141 	ai.asf1desc = asf1d;
2142 	ai.sc_busy = 0;
2143 	ai.ifaceh = NULL;
2144 	uaudio_add_alt(sc, &ai);
2145 #ifdef USB_DEBUG
2146 	if (ai.attributes & UA_SED_FREQ_CONTROL)
2147 		DPRINTFN(1, ("uaudio_process_as:  FREQ_CONTROL\n"));
2148 	if (ai.attributes & UA_SED_PITCH_CONTROL)
2149 		DPRINTFN(1, ("uaudio_process_as:  PITCH_CONTROL\n"));
2150 #endif
2151 	sc->sc_mode |= (dir == UE_DIR_OUT) ? AUMODE_PLAY : AUMODE_RECORD;
2152 
2153 	return USBD_NORMAL_COMPLETION;
2154 }
2155 #undef offs
2156 
2157 static usbd_status
2158 uaudio_identify_as(struct uaudio_softc *sc,
2159 		   const usb_config_descriptor_t *cdesc)
2160 {
2161 	const usb_interface_descriptor_t *id;
2162 	const char *buf;
2163 	int size, offs;
2164 
2165 	size = UGETW(cdesc->wTotalLength);
2166 	buf = (const char *)cdesc;
2167 
2168 	/* Locate the AudioStreaming interface descriptor. */
2169 	offs = 0;
2170 	id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOSTREAM);
2171 	if (id == NULL)
2172 		return USBD_INVAL;
2173 
2174 #if defined(__FreeBSD__)
2175 	sc->uaudio_sndstat_flag = 0;
2176 	if (sbuf_new(&(sc->uaudio_sndstat), NULL, 4096, SBUF_AUTOEXTEND) != NULL)
2177 		sc->uaudio_sndstat_flag = 1;
2178 #endif
2179 	/* Loop through all the alternate settings. */
2180 	while (offs <= size) {
2181 		DPRINTFN(2, ("uaudio_identify: interface=%d offset=%d\n",
2182 		    id->bInterfaceNumber, offs));
2183 		switch (id->bNumEndpoints) {
2184 		case 0:
2185 			DPRINTFN(2, ("uaudio_identify: AS null alt=%d\n",
2186 				     id->bAlternateSetting));
2187 			sc->sc_nullalt = id->bAlternateSetting;
2188 			break;
2189 		case 1:
2190 #ifdef UAUDIO_MULTIPLE_ENDPOINTS
2191 		case 2:
2192 #endif
2193 			uaudio_process_as(sc, buf, &offs, size, id);
2194 			break;
2195 		default:
2196 			printf("%s: ignored audio interface with %d "
2197 			       "endpoints\n",
2198 			       device_get_nameunit(sc->sc_dev), id->bNumEndpoints);
2199 			break;
2200 		}
2201 		id = uaudio_find_iface(buf, size, &offs,UISUBCLASS_AUDIOSTREAM);
2202 		if (id == NULL)
2203 			break;
2204 	}
2205 #if defined(__FreeBSD__)
2206 	sbuf_finish(&(sc->uaudio_sndstat));
2207 #endif
2208 	if (offs > size)
2209 		return USBD_INVAL;
2210 	DPRINTF(("uaudio_identify_as: %d alts available\n", sc->sc_nalts));
2211 
2212 	if (sc->sc_mode == 0) {
2213 		printf("%s: no usable endpoint found\n",
2214 		       device_get_nameunit(sc->sc_dev));
2215 		return USBD_INVAL;
2216 	}
2217 
2218 	return USBD_NORMAL_COMPLETION;
2219 }
2220 
2221 static usbd_status
2222 uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc)
2223 {
2224 	struct io_terminal* iot;
2225 	const usb_interface_descriptor_t *id;
2226 	const struct usb_audio_control_descriptor *acdp;
2227 	const usb_descriptor_t *dp;
2228 	const struct usb_audio_output_terminal *pot;
2229 	struct terminal_list *tml;
2230 	const char *buf, *ibuf, *ibufend;
2231 	int size, offs, aclen, ndps, i, j;
2232 
2233 	size = UGETW(cdesc->wTotalLength);
2234 	buf = (const char *)cdesc;
2235 
2236 	/* Locate the AudioControl interface descriptor. */
2237 	offs = 0;
2238 	id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOCONTROL);
2239 	if (id == NULL)
2240 		return USBD_INVAL;
2241 	if (offs + sizeof *acdp > size)
2242 		return USBD_INVAL;
2243 	sc->sc_ac_iface = id->bInterfaceNumber;
2244 	DPRINTFN(2,("uaudio_identify_ac: AC interface is %d\n", sc->sc_ac_iface));
2245 
2246 	/* A class-specific AC interface header should follow. */
2247 	ibuf = buf + offs;
2248 	acdp = (const struct usb_audio_control_descriptor *)ibuf;
2249 	if (acdp->bDescriptorType != UDESC_CS_INTERFACE ||
2250 	    acdp->bDescriptorSubtype != UDESCSUB_AC_HEADER)
2251 		return USBD_INVAL;
2252 	aclen = UGETW(acdp->wTotalLength);
2253 	if (offs + aclen > size)
2254 		return USBD_INVAL;
2255 
2256 	if (!(usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_BAD_ADC) &&
2257 	     UGETW(acdp->bcdADC) != UAUDIO_VERSION)
2258 		return USBD_INVAL;
2259 
2260 	sc->sc_audio_rev = UGETW(acdp->bcdADC);
2261 	DPRINTFN(2,("uaudio_identify_ac: found AC header, vers=%03x, len=%d\n",
2262 		 sc->sc_audio_rev, aclen));
2263 
2264 	sc->sc_nullalt = -1;
2265 
2266 	/* Scan through all the AC specific descriptors */
2267 	ibufend = ibuf + aclen;
2268 	dp = (const usb_descriptor_t *)ibuf;
2269 	ndps = 0;
2270 	iot = malloc(sizeof(struct io_terminal) * 256, M_TEMP, M_NOWAIT | M_ZERO);
2271 	if (iot == NULL) {
2272 		printf("%s: no memory\n", __func__);
2273 		return USBD_NOMEM;
2274 	}
2275 	for (;;) {
2276 		ibuf += dp->bLength;
2277 		if (ibuf >= ibufend)
2278 			break;
2279 		dp = (const usb_descriptor_t *)ibuf;
2280 		if (ibuf + dp->bLength > ibufend) {
2281 			free(iot, M_TEMP);
2282 			return USBD_INVAL;
2283 		}
2284 		if (dp->bDescriptorType != UDESC_CS_INTERFACE) {
2285 			printf("uaudio_identify_ac: skip desc type=0x%02x\n",
2286 			       dp->bDescriptorType);
2287 			continue;
2288 		}
2289 		i = ((const struct usb_audio_input_terminal *)dp)->bTerminalId;
2290 		iot[i].d.desc = dp;
2291 		if (i > ndps)
2292 			ndps = i;
2293 	}
2294 	ndps++;
2295 
2296 	/* construct io_terminal */
2297 	for (i = 0; i < ndps; i++) {
2298 		dp = iot[i].d.desc;
2299 		if (dp == NULL)
2300 			continue;
2301 		if (dp->bDescriptorSubtype != UDESCSUB_AC_OUTPUT)
2302 			continue;
2303 		pot = iot[i].d.ot;
2304 		tml = uaudio_io_terminaltype(UGETW(pot->wTerminalType), iot, i);
2305 		if (tml != NULL)
2306 			free(tml, M_TEMP);
2307 	}
2308 
2309 #ifdef USB_DEBUG
2310 	for (i = 0; i < 256; i++) {
2311 		struct usb_audio_cluster cluster;
2312 
2313 		if (iot[i].d.desc == NULL)
2314 			continue;
2315 		logprintf("id %d:\t", i);
2316 		switch (iot[i].d.desc->bDescriptorSubtype) {
2317 		case UDESCSUB_AC_INPUT:
2318 			logprintf("AC_INPUT type=%s\n", uaudio_get_terminal_name
2319 				  (UGETW(iot[i].d.it->wTerminalType)));
2320 			logprintf("\t");
2321 			cluster = uaudio_get_cluster(i, iot);
2322 			uaudio_dump_cluster(&cluster);
2323 			logprintf("\n");
2324 			break;
2325 		case UDESCSUB_AC_OUTPUT:
2326 			logprintf("AC_OUTPUT type=%s ", uaudio_get_terminal_name
2327 				  (UGETW(iot[i].d.ot->wTerminalType)));
2328 			logprintf("src=%d\n", iot[i].d.ot->bSourceId);
2329 			break;
2330 		case UDESCSUB_AC_MIXER:
2331 			logprintf("AC_MIXER src=");
2332 			for (j = 0; j < iot[i].d.mu->bNrInPins; j++)
2333 				logprintf("%d ", iot[i].d.mu->baSourceId[j]);
2334 			logprintf("\n\t");
2335 			cluster = uaudio_get_cluster(i, iot);
2336 			uaudio_dump_cluster(&cluster);
2337 			logprintf("\n");
2338 			break;
2339 		case UDESCSUB_AC_SELECTOR:
2340 			logprintf("AC_SELECTOR src=");
2341 			for (j = 0; j < iot[i].d.su->bNrInPins; j++)
2342 				logprintf("%d ", iot[i].d.su->baSourceId[j]);
2343 			logprintf("\n");
2344 			break;
2345 		case UDESCSUB_AC_FEATURE:
2346 			logprintf("AC_FEATURE src=%d\n", iot[i].d.fu->bSourceId);
2347 			break;
2348 		case UDESCSUB_AC_PROCESSING:
2349 			logprintf("AC_PROCESSING src=");
2350 			for (j = 0; j < iot[i].d.pu->bNrInPins; j++)
2351 				logprintf("%d ", iot[i].d.pu->baSourceId[j]);
2352 			logprintf("\n\t");
2353 			cluster = uaudio_get_cluster(i, iot);
2354 			uaudio_dump_cluster(&cluster);
2355 			logprintf("\n");
2356 			break;
2357 		case UDESCSUB_AC_EXTENSION:
2358 			logprintf("AC_EXTENSION src=");
2359 			for (j = 0; j < iot[i].d.eu->bNrInPins; j++)
2360 				logprintf("%d ", iot[i].d.eu->baSourceId[j]);
2361 			logprintf("\n\t");
2362 			cluster = uaudio_get_cluster(i, iot);
2363 			uaudio_dump_cluster(&cluster);
2364 			logprintf("\n");
2365 			break;
2366 		default:
2367 			logprintf("unknown audio control (subtype=%d)\n",
2368 				  iot[i].d.desc->bDescriptorSubtype);
2369 		}
2370 		for (j = 0; j < iot[i].inputs_size; j++) {
2371 			int k;
2372 			logprintf("\tinput%d: ", j);
2373 			tml = iot[i].inputs[j];
2374 			if (tml == NULL) {
2375 				logprintf("NULL\n");
2376 				continue;
2377 			}
2378 			for (k = 0; k < tml->size; k++)
2379 				logprintf("%s ", uaudio_get_terminal_name
2380 					  (tml->terminals[k]));
2381 			logprintf("\n");
2382 		}
2383 		logprintf("\toutput: ");
2384 		tml = iot[i].output;
2385 		for (j = 0; j < tml->size; j++)
2386 			logprintf("%s ", uaudio_get_terminal_name(tml->terminals[j]));
2387 		logprintf("\n");
2388 	}
2389 #endif
2390 
2391 	for (i = 0; i < ndps; i++) {
2392 		dp = iot[i].d.desc;
2393 		if (dp == NULL)
2394 			continue;
2395 		DPRINTF(("uaudio_identify_ac: id=%d subtype=%d\n",
2396 			 i, dp->bDescriptorSubtype));
2397 		switch (dp->bDescriptorSubtype) {
2398 		case UDESCSUB_AC_HEADER:
2399 			printf("uaudio_identify_ac: unexpected AC header\n");
2400 			break;
2401 		case UDESCSUB_AC_INPUT:
2402 			uaudio_add_input(sc, iot, i);
2403 			break;
2404 		case UDESCSUB_AC_OUTPUT:
2405 			uaudio_add_output(sc, iot, i);
2406 			break;
2407 		case UDESCSUB_AC_MIXER:
2408 			uaudio_add_mixer(sc, iot, i);
2409 			break;
2410 		case UDESCSUB_AC_SELECTOR:
2411 			uaudio_add_selector(sc, iot, i);
2412 			break;
2413 		case UDESCSUB_AC_FEATURE:
2414 			uaudio_add_feature(sc, iot, i);
2415 			break;
2416 		case UDESCSUB_AC_PROCESSING:
2417 			uaudio_add_processing(sc, iot, i);
2418 			break;
2419 		case UDESCSUB_AC_EXTENSION:
2420 			uaudio_add_extension(sc, iot, i);
2421 			break;
2422 		default:
2423 			printf("uaudio_identify_ac: bad AC desc subtype=0x%02x\n",
2424 			       dp->bDescriptorSubtype);
2425 			break;
2426 		}
2427 	}
2428 
2429 	/* delete io_terminal */
2430 	for (i = 0; i < 256; i++) {
2431 		if (iot[i].d.desc == NULL)
2432 			continue;
2433 		if (iot[i].inputs != NULL) {
2434 			for (j = 0; j < iot[i].inputs_size; j++) {
2435 				if (iot[i].inputs[j] != NULL)
2436 					free(iot[i].inputs[j], M_TEMP);
2437 			}
2438 			free(iot[i].inputs, M_TEMP);
2439 		}
2440 		if (iot[i].output != NULL)
2441 			free(iot[i].output, M_TEMP);
2442 		iot[i].d.desc = NULL;
2443 	}
2444 	free(iot, M_TEMP);
2445 
2446 	return USBD_NORMAL_COMPLETION;
2447 }
2448 
2449 #if defined(__NetBSD__) || defined(__OpenBSD__)
2450 static int
2451 uaudio_query_devinfo(void *addr, mixer_devinfo_t *mi)
2452 {
2453 	struct uaudio_softc *sc;
2454 	struct mixerctl *mc;
2455 	int n, nctls, i;
2456 
2457 	sc = addr;
2458 	DPRINTFN(2,("uaudio_query_devinfo: index=%d\n", mi->index));
2459 	if (sc->sc_dying)
2460 		return EIO;
2461 
2462 	n = mi->index;
2463 	nctls = sc->sc_nctls;
2464 
2465 	switch (n) {
2466 	case UAC_OUTPUT:
2467 		mi->type = AUDIO_MIXER_CLASS;
2468 		mi->mixer_class = UAC_OUTPUT;
2469 		mi->next = mi->prev = AUDIO_MIXER_LAST;
2470 		strlcpy(mi->label.name, AudioCoutputs, sizeof(mi->label.name));
2471 		return 0;
2472 	case UAC_INPUT:
2473 		mi->type = AUDIO_MIXER_CLASS;
2474 		mi->mixer_class = UAC_INPUT;
2475 		mi->next = mi->prev = AUDIO_MIXER_LAST;
2476 		strlcpy(mi->label.name, AudioCinputs, sizeof(mi->label.name));
2477 		return 0;
2478 	case UAC_EQUAL:
2479 		mi->type = AUDIO_MIXER_CLASS;
2480 		mi->mixer_class = UAC_EQUAL;
2481 		mi->next = mi->prev = AUDIO_MIXER_LAST;
2482 		strlcpy(mi->label.name, AudioCequalization,
2483 		    sizeof(mi->label.name));
2484 		return 0;
2485 	case UAC_RECORD:
2486 		mi->type = AUDIO_MIXER_CLASS;
2487 		mi->mixer_class = UAC_RECORD;
2488 		mi->next = mi->prev = AUDIO_MIXER_LAST;
2489 		strlcpy(mi->label.name, AudioCrecord, sizeof(mi->label.name));
2490 		return 0;
2491 	default:
2492 		break;
2493 	}
2494 
2495 	n -= UAC_NCLASSES;
2496 	if (n < 0 || n >= nctls)
2497 		return ENXIO;
2498 
2499 	mc = &sc->sc_ctls[n];
2500 	strlcpy(mi->label.name, mc->ctlname, sizeof(mi->label.name));
2501 	mi->mixer_class = mc->class;
2502 	mi->next = mi->prev = AUDIO_MIXER_LAST;	/* XXX */
2503 	switch (mc->type) {
2504 	case MIX_ON_OFF:
2505 		mi->type = AUDIO_MIXER_ENUM;
2506 		mi->un.e.num_mem = 2;
2507 		strlcpy(mi->un.e.member[0].label.name, AudioNoff,
2508 		    sizeof(mi->un.e.member[0].label.name));
2509 		mi->un.e.member[0].ord = 0;
2510 		strlcpy(mi->un.e.member[1].label.name, AudioNon,
2511 		    sizeof(mi->un.e.member[1].label.name));
2512 		mi->un.e.member[1].ord = 1;
2513 		break;
2514 	case MIX_SELECTOR:
2515 		mi->type = AUDIO_MIXER_ENUM;
2516 		mi->un.e.num_mem = mc->maxval - mc->minval + 1;
2517 		for (i = 0; i <= mc->maxval - mc->minval; i++) {
2518 			snprintf(mi->un.e.member[i].label.name,
2519 				 sizeof(mi->un.e.member[i].label.name),
2520 				 "%d", i + mc->minval);
2521 			mi->un.e.member[i].ord = i + mc->minval;
2522 		}
2523 		break;
2524 	default:
2525 		mi->type = AUDIO_MIXER_VALUE;
2526 		strlcpy(mi->un.v.units.name, mc->ctlunit, MAX_AUDIO_DEV_LEN);
2527 		mi->un.v.num_channels = mc->nchan;
2528 		mi->un.v.delta = mc->delta;
2529 		break;
2530 	}
2531 	return 0;
2532 }
2533 
2534 static int
2535 uaudio_open(void *addr, int flags)
2536 {
2537 	struct uaudio_softc *sc;
2538 
2539 	sc = addr;
2540 	DPRINTF(("uaudio_open: sc=%p\n", sc));
2541 	if (sc->sc_dying)
2542 		return EIO;
2543 
2544 	if ((flags & FWRITE) && !(sc->sc_mode & AUMODE_PLAY))
2545 		return EACCES;
2546 	if ((flags & FREAD) && !(sc->sc_mode & AUMODE_RECORD))
2547 		return EACCES;
2548 
2549 	return 0;
2550 }
2551 
2552 /*
2553  * Close function is called at splaudio().
2554  */
2555 static void
2556 uaudio_close(void *addr)
2557 {
2558 }
2559 
2560 static int
2561 uaudio_drain(void *addr)
2562 {
2563 	struct uaudio_softc *sc;
2564 
2565 	sc = addr;
2566 	usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
2567 
2568 	return 0;
2569 }
2570 
2571 static int
2572 uaudio_halt_out_dma(void *addr)
2573 {
2574 	struct uaudio_softc *sc;
2575 
2576 	sc = addr;
2577 	if (sc->sc_dying)
2578 		return EIO;
2579 
2580 	DPRINTF(("uaudio_halt_out_dma: enter\n"));
2581 	if (sc->sc_playchan.pipe != NULL) {
2582 		uaudio_chan_close(sc, &sc->sc_playchan);
2583 		sc->sc_playchan.pipe = NULL;
2584 		uaudio_chan_free_buffers(sc, &sc->sc_playchan);
2585 		sc->sc_playchan.intr = NULL;
2586 	}
2587 	return 0;
2588 }
2589 
2590 static int
2591 uaudio_halt_in_dma(void *addr)
2592 {
2593 	struct uaudio_softc *sc;
2594 
2595 	DPRINTF(("uaudio_halt_in_dma: enter\n"));
2596 	sc = addr;
2597 	if (sc->sc_recchan.pipe != NULL) {
2598 		uaudio_chan_close(sc, &sc->sc_recchan);
2599 		sc->sc_recchan.pipe = NULL;
2600 		uaudio_chan_free_buffers(sc, &sc->sc_recchan);
2601 		sc->sc_recchan.intr = NULL;
2602 	}
2603 	return 0;
2604 }
2605 
2606 static int
2607 uaudio_getdev(void *addr, struct audio_device *retp)
2608 {
2609 	struct uaudio_softc *sc;
2610 
2611 	DPRINTF(("uaudio_mixer_getdev:\n"));
2612 	sc = addr;
2613 	if (sc->sc_dying)
2614 		return EIO;
2615 
2616 	*retp = uaudio_device;
2617 	return 0;
2618 }
2619 
2620 /*
2621  * Make sure the block size is large enough to hold all outstanding transfers.
2622  */
2623 static int
2624 uaudio_round_blocksize(void *addr, int blk)
2625 {
2626 	struct uaudio_softc *sc;
2627 	int b;
2628 
2629 	sc = addr;
2630 	DPRINTF(("uaudio_round_blocksize: blk=%d mode=%s\n", blk,
2631 		mode == AUMODE_PLAY ? "AUMODE_PLAY" : "AUMODE_RECORD"));
2632 
2633 	/* chan.bytes_per_frame can be 0. */
2634 	if (mode == AUMODE_PLAY || sc->sc_recchan.bytes_per_frame <= 0) {
2635 		b = param->sample_rate * UAUDIO_NFRAMES * UAUDIO_NCHANBUFS;
2636 
2637 		/*
2638 		 * This does not make accurate value in the case
2639 		 * of b % USB_FRAMES_PER_SECOND != 0
2640 		 */
2641 		b /= USB_FRAMES_PER_SECOND;
2642 
2643 		b *= param->precision / 8 * param->channels;
2644 	} else {
2645 		/*
2646 		 * use wMaxPacketSize in bytes_per_frame.
2647 		 * See uaudio_set_params() and uaudio_chan_init()
2648 		 */
2649 		b = sc->sc_recchan.bytes_per_frame
2650 			* UAUDIO_NFRAMES * UAUDIO_NCHANBUFS;
2651 	}
2652 
2653 	if (b <= 0)
2654 		b = 1;
2655 	blk = blk <= b ? b : blk / b * b;
2656 
2657 #ifdef DIAGNOSTIC
2658 	if (blk <= 0) {
2659 		printf("uaudio_round_blocksize: blk=%d\n", blk);
2660 		blk = 512;
2661 	}
2662 #endif
2663 
2664 	DPRINTF(("uaudio_round_blocksize: resultant blk=%d\n", blk));
2665 	return blk;
2666 }
2667 
2668 static int
2669 uaudio_get_props(void *addr)
2670 {
2671 	return AUDIO_PROP_FULLDUPLEX | AUDIO_PROP_INDEPENDENT;
2672 
2673 }
2674 #endif	/* NetBSD or OpenBSD */
2675 
2676 static int
2677 uaudio_get(struct uaudio_softc *sc, int which, int type, int wValue,
2678 	   int wIndex, int len)
2679 {
2680 	usb_device_request_t req;
2681 	uint8_t data[4];
2682 	usbd_status err;
2683 	int val;
2684 
2685 #if defined(__FreeBSD__)
2686 	if (sc->sc_dying)
2687 		return EIO;
2688 #endif
2689 
2690 	if (wValue == -1)
2691 		return 0;
2692 
2693 	req.bmRequestType = type;
2694 	req.bRequest = which;
2695 	USETW(req.wValue, wValue);
2696 	USETW(req.wIndex, wIndex);
2697 	USETW(req.wLength, len);
2698 	DPRINTFN(2,("uaudio_get: type=0x%02x req=0x%02x wValue=0x%04x "
2699 		    "wIndex=0x%04x len=%d\n",
2700 		    type, which, wValue, wIndex, len));
2701 	err = usbd_do_request(sc->sc_udev, &req, data);
2702 	if (err) {
2703 		DPRINTF(("uaudio_get: err=%s\n", usbd_errstr(err)));
2704 		return -1;
2705 	}
2706 	switch (len) {
2707 	case 1:
2708 		val = data[0];
2709 		break;
2710 	case 2:
2711 		val = data[0] | (data[1] << 8);
2712 		break;
2713 	default:
2714 		DPRINTF(("uaudio_get: bad length=%d\n", len));
2715 		return -1;
2716 	}
2717 	DPRINTFN(2,("uaudio_get: val=%d\n", val));
2718 	return val;
2719 }
2720 
2721 static void
2722 uaudio_set(struct uaudio_softc *sc, int which, int type, int wValue,
2723 	   int wIndex, int len, int val)
2724 {
2725 	usb_device_request_t req;
2726 	uint8_t data[4];
2727 	usbd_status err;
2728 
2729 #if defined(__FreeBSD__)
2730 	if (sc->sc_dying)
2731 		return;
2732 #endif
2733 
2734 	if (wValue == -1)
2735 		return;
2736 
2737 	req.bmRequestType = type;
2738 	req.bRequest = which;
2739 	USETW(req.wValue, wValue);
2740 	USETW(req.wIndex, wIndex);
2741 	USETW(req.wLength, len);
2742 	switch (len) {
2743 	case 1:
2744 		data[0] = val;
2745 		break;
2746 	case 2:
2747 		data[0] = val;
2748 		data[1] = val >> 8;
2749 		break;
2750 	default:
2751 		return;
2752 	}
2753 	DPRINTFN(2,("uaudio_set: type=0x%02x req=0x%02x wValue=0x%04x "
2754 		    "wIndex=0x%04x len=%d, val=%d\n",
2755 		    type, which, wValue, wIndex, len, val & 0xffff));
2756 	err = usbd_do_request(sc->sc_udev, &req, data);
2757 #ifdef USB_DEBUG
2758 	if (err)
2759 		DPRINTF(("uaudio_set: err=%d\n", err));
2760 #endif
2761 }
2762 
2763 static int
2764 uaudio_signext(int type, int val)
2765 {
2766 	if (!MIX_UNSIGNED(type)) {
2767 		if (MIX_SIZE(type) == 2)
2768 			val = (int16_t)val;
2769 		else
2770 			val = (int8_t)val;
2771 	}
2772 	return val;
2773 }
2774 
2775 #if defined(__NetBSD__) || defined(__OpenBSD__)
2776 static int
2777 uaudio_value2bsd(struct mixerctl *mc, int val)
2778 {
2779 	DPRINTFN(5, ("uaudio_value2bsd: type=%03x val=%d min=%d max=%d ",
2780 		     mc->type, val, mc->minval, mc->maxval));
2781 	if (mc->type == MIX_ON_OFF) {
2782 		val = (val != 0);
2783 	} else if (mc->type == MIX_SELECTOR) {
2784 		if (val < mc->minval || val > mc->maxval)
2785 			val = mc->minval;
2786 	} else
2787 		val = ((uaudio_signext(mc->type, val) - mc->minval) * 255
2788 			+ mc->mul/2) / mc->mul;
2789 	DPRINTFN(5, ("val'=%d\n", val));
2790 	return val;
2791 }
2792 #endif
2793 
2794 int
2795 uaudio_bsd2value(struct mixerctl *mc, int val)
2796 {
2797 	DPRINTFN(5,("uaudio_bsd2value: type=%03x val=%d min=%d max=%d ",
2798 		    mc->type, val, mc->minval, mc->maxval));
2799 	if (mc->type == MIX_ON_OFF) {
2800 		val = (val != 0);
2801 	} else if (mc->type == MIX_SELECTOR) {
2802 		if (val < mc->minval || val > mc->maxval)
2803 			val = mc->minval;
2804 	} else
2805 		val = (val + mc->delta/2) * mc->mul / 255 + mc->minval;
2806 	DPRINTFN(5, ("val'=%d\n", val));
2807 	return val;
2808 }
2809 
2810 #if defined(__NetBSD__) || defined(__OpenBSD__)
2811 static int
2812 uaudio_ctl_get(struct uaudio_softc *sc, int which, struct mixerctl *mc,
2813 	       int chan)
2814 {
2815 	int val;
2816 
2817 	DPRINTFN(5,("uaudio_ctl_get: which=%d chan=%d\n", which, chan));
2818 	val = uaudio_get(sc, which, UT_READ_CLASS_INTERFACE, mc->wValue[chan],
2819 			 mc->wIndex, MIX_SIZE(mc->type));
2820 	return uaudio_value2bsd(mc, val);
2821 }
2822 #endif
2823 
2824 static void
2825 uaudio_ctl_set(struct uaudio_softc *sc, int which, struct mixerctl *mc,
2826 	       int chan, int val)
2827 {
2828 	val = uaudio_bsd2value(mc, val);
2829 	uaudio_set(sc, which, UT_WRITE_CLASS_INTERFACE, mc->wValue[chan],
2830 		   mc->wIndex, MIX_SIZE(mc->type), val);
2831 }
2832 
2833 #if defined(__NetBSD__) || defined(__OpenBSD__)
2834 static int
2835 uaudio_mixer_get_port(void *addr, mixer_ctrl_t *cp)
2836 {
2837 	struct uaudio_softc *sc;
2838 	struct mixerctl *mc;
2839 	int i, n, vals[MIX_MAX_CHAN], val;
2840 
2841 	DPRINTFN(2,("uaudio_mixer_get_port: index=%d\n", cp->dev));
2842 	sc = addr;
2843 	if (sc->sc_dying)
2844 		return EIO;
2845 
2846 	n = cp->dev - UAC_NCLASSES;
2847 	if (n < 0 || n >= sc->sc_nctls)
2848 		return ENXIO;
2849 	mc = &sc->sc_ctls[n];
2850 
2851 	if (mc->type == MIX_ON_OFF) {
2852 		if (cp->type != AUDIO_MIXER_ENUM)
2853 			return EINVAL;
2854 		cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0);
2855 	} else if (mc->type == MIX_SELECTOR) {
2856 		if (cp->type != AUDIO_MIXER_ENUM)
2857 			return EINVAL;
2858 		cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0);
2859 	} else {
2860 		if (cp->type != AUDIO_MIXER_VALUE)
2861 			return (EINVAL);
2862 		if (cp->un.value.num_channels != 1 &&
2863 		    cp->un.value.num_channels != mc->nchan)
2864 			return EINVAL;
2865 		for (i = 0; i < mc->nchan; i++)
2866 			vals[i] = uaudio_ctl_get(sc, GET_CUR, mc, i);
2867 		if (cp->un.value.num_channels == 1 && mc->nchan != 1) {
2868 			for (val = 0, i = 0; i < mc->nchan; i++)
2869 				val += vals[i];
2870 			vals[0] = val / mc->nchan;
2871 		}
2872 		for (i = 0; i < cp->un.value.num_channels; i++)
2873 			cp->un.value.level[i] = vals[i];
2874 	}
2875 
2876 	return 0;
2877 }
2878 
2879 static int
2880 uaudio_mixer_set_port(void *addr, mixer_ctrl_t *cp)
2881 {
2882 	struct uaudio_softc *sc;
2883 	struct mixerctl *mc;
2884 	int i, n, vals[MIX_MAX_CHAN];
2885 
2886 	DPRINTFN(2,("uaudio_mixer_set_port: index = %d\n", cp->dev));
2887 	sc = addr;
2888 	if (sc->sc_dying)
2889 		return EIO;
2890 
2891 	n = cp->dev - UAC_NCLASSES;
2892 	if (n < 0 || n >= sc->sc_nctls)
2893 		return ENXIO;
2894 	mc = &sc->sc_ctls[n];
2895 
2896 	if (mc->type == MIX_ON_OFF) {
2897 		if (cp->type != AUDIO_MIXER_ENUM)
2898 			return EINVAL;
2899 		uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord);
2900 	} else if (mc->type == MIX_SELECTOR) {
2901 		if (cp->type != AUDIO_MIXER_ENUM)
2902 			return EINVAL;
2903 		uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord);
2904 	} else {
2905 		if (cp->type != AUDIO_MIXER_VALUE)
2906 			return EINVAL;
2907 		if (cp->un.value.num_channels == 1)
2908 			for (i = 0; i < mc->nchan; i++)
2909 				vals[i] = cp->un.value.level[0];
2910 		else if (cp->un.value.num_channels == mc->nchan)
2911 			for (i = 0; i < mc->nchan; i++)
2912 				vals[i] = cp->un.value.level[i];
2913 		else
2914 			return EINVAL;
2915 		for (i = 0; i < mc->nchan; i++)
2916 			uaudio_ctl_set(sc, SET_CUR, mc, i, vals[i]);
2917 	}
2918 	return 0;
2919 }
2920 
2921 static int
2922 uaudio_trigger_input(void *addr, void *start, void *end, int blksize,
2923 		     void (*intr)(void *), void *arg,
2924 		     struct audio_params *param)
2925 {
2926 	struct uaudio_softc *sc;
2927 	struct chan *ch;
2928 	usbd_status err;
2929 	int i, s;
2930 
2931 	sc = addr;
2932 	if (sc->sc_dying)
2933 		return EIO;
2934 
2935 	DPRINTFN(3,("uaudio_trigger_input: sc=%p start=%p end=%p "
2936 		    "blksize=%d\n", sc, start, end, blksize));
2937 	ch = &sc->sc_recchan;
2938 	uaudio_chan_set_param(ch, start, end, blksize);
2939 	DPRINTFN(3,("uaudio_trigger_input: sample_size=%d bytes/frame=%d "
2940 		    "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
2941 		    ch->fraction));
2942 
2943 	err = uaudio_chan_alloc_buffers(sc, ch);
2944 	if (err)
2945 		return EIO;
2946 
2947 	err = uaudio_chan_open(sc, ch);
2948 	if (err) {
2949 		uaudio_chan_free_buffers(sc, ch);
2950 		return EIO;
2951 	}
2952 
2953 	ch->intr = intr;
2954 	ch->arg = arg;
2955 
2956 	s = splusb();
2957 	for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */
2958 		uaudio_chan_rtransfer(ch);
2959 	splx(s);
2960 
2961 	return 0;
2962 }
2963 
2964 static int
2965 uaudio_trigger_output(void *addr, void *start, void *end, int blksize,
2966 		      void (*intr)(void *), void *arg,
2967 		      struct audio_params *param)
2968 {
2969 	struct uaudio_softc *sc;
2970 	struct chan *ch;
2971 	usbd_status err;
2972 	int i, s;
2973 
2974 	sc = addr;
2975 	if (sc->sc_dying)
2976 		return EIO;
2977 
2978 	DPRINTFN(3,("uaudio_trigger_output: sc=%p start=%p end=%p "
2979 		    "blksize=%d\n", sc, start, end, blksize));
2980 	ch = &sc->sc_playchan;
2981 	uaudio_chan_set_param(ch, start, end, blksize);
2982 	DPRINTFN(3,("uaudio_trigger_output: sample_size=%d bytes/frame=%d "
2983 		    "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
2984 		    ch->fraction));
2985 
2986 	err = uaudio_chan_alloc_buffers(sc, ch);
2987 	if (err)
2988 		return EIO;
2989 
2990 	err = uaudio_chan_open(sc, ch);
2991 	if (err) {
2992 		uaudio_chan_free_buffers(sc, ch);
2993 		return EIO;
2994 	}
2995 
2996 	ch->intr = intr;
2997 	ch->arg = arg;
2998 
2999 	s = splusb();
3000 	for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */
3001 		uaudio_chan_ptransfer(ch);
3002 	splx(s);
3003 
3004 	return 0;
3005 }
3006 #endif	/* NetBSD or OpenBSD */
3007 
3008 /* Set up a pipe for a channel. */
3009 static usbd_status
3010 uaudio_chan_open(struct uaudio_softc *sc, struct chan *ch)
3011 {
3012 	struct as_info *as;
3013 	int endpt;
3014 	usbd_status err;
3015 
3016 #if defined(__FreeBSD__)
3017 	if (sc->sc_dying)
3018 		return EIO;
3019 #endif
3020 
3021 	as = &sc->sc_alts[ch->altidx];
3022 	endpt = as->edesc->bEndpointAddress;
3023 	DPRINTF(("uaudio_chan_open: endpt=0x%02x, speed=%d, alt=%d\n",
3024 		 endpt, ch->sample_rate, as->alt));
3025 
3026 	/* Set alternate interface corresponding to the mode. */
3027 	err = usbd_set_interface(as->ifaceh, as->alt);
3028 	if (err)
3029 		return err;
3030 
3031 	/*
3032 	 * If just one sampling rate is supported,
3033 	 * no need to call uaudio_set_speed().
3034 	 * Roland SD-90 freezes by a SAMPLING_FREQ_CONTROL request.
3035 	 */
3036 	if (as->asf1desc->bSamFreqType != 1) {
3037 		err = uaudio_set_speed(sc, endpt, ch->sample_rate);
3038 		if (err) {
3039 			DPRINTF(("uaudio_chan_open: set_speed failed err=%s\n",
3040 				 usbd_errstr(err)));
3041 		}
3042 	}
3043 
3044 	ch->pipe = 0;
3045 	ch->sync_pipe = 0;
3046 	DPRINTF(("uaudio_chan_open: create pipe to 0x%02x\n", endpt));
3047 	err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->pipe);
3048 	if (err)
3049 		return err;
3050 	if (as->edesc1 != NULL) {
3051 		endpt = as->edesc1->bEndpointAddress;
3052 		DPRINTF(("uaudio_chan_open: create sync-pipe to 0x%02x\n", endpt));
3053 		err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->sync_pipe);
3054 	}
3055 	return err;
3056 }
3057 
3058 static void
3059 uaudio_chan_close(struct uaudio_softc *sc, struct chan *ch)
3060 {
3061 	struct as_info *as;
3062 
3063 #if defined(__FreeBSD__)
3064 	if (sc->sc_dying)
3065 		return ;
3066 #endif
3067 
3068 	as = &sc->sc_alts[ch->altidx];
3069 	as->sc_busy = 0;
3070 	if (sc->sc_nullalt >= 0) {
3071 		DPRINTF(("uaudio_chan_close: set null alt=%d\n",
3072 			 sc->sc_nullalt));
3073 		usbd_set_interface(as->ifaceh, sc->sc_nullalt);
3074 	}
3075 	if (ch->pipe) {
3076 		usbd_abort_pipe(ch->pipe);
3077 		usbd_close_pipe(ch->pipe);
3078 	}
3079 	if (ch->sync_pipe) {
3080 		usbd_abort_pipe(ch->sync_pipe);
3081 		usbd_close_pipe(ch->sync_pipe);
3082 	}
3083 }
3084 
3085 static usbd_status
3086 uaudio_chan_alloc_buffers(struct uaudio_softc *sc, struct chan *ch)
3087 {
3088 	usbd_xfer_handle xfer;
3089 	void *buf;
3090 	int i, size;
3091 
3092 	size = (ch->bytes_per_frame + ch->sample_size) * UAUDIO_NFRAMES;
3093 	for (i = 0; i < UAUDIO_NCHANBUFS; i++) {
3094 		xfer = usbd_alloc_xfer(sc->sc_udev);
3095 		if (xfer == 0)
3096 			goto bad;
3097 		ch->chanbufs[i].xfer = xfer;
3098 		buf = usbd_alloc_buffer(xfer, size);
3099 		if (buf == 0) {
3100 			i++;
3101 			goto bad;
3102 		}
3103 		ch->chanbufs[i].buffer = buf;
3104 		ch->chanbufs[i].chan = ch;
3105 	}
3106 
3107 	return USBD_NORMAL_COMPLETION;
3108 
3109 bad:
3110 	while (--i >= 0)
3111 		/* implicit buffer free */
3112 		usbd_free_xfer(ch->chanbufs[i].xfer);
3113 	return USBD_NOMEM;
3114 }
3115 
3116 static void
3117 uaudio_chan_free_buffers(struct uaudio_softc *sc, struct chan *ch)
3118 {
3119 	int i;
3120 
3121 	for (i = 0; i < UAUDIO_NCHANBUFS; i++)
3122 		usbd_free_xfer(ch->chanbufs[i].xfer);
3123 }
3124 
3125 /* Called at splusb() */
3126 static void
3127 uaudio_chan_ptransfer(struct chan *ch)
3128 {
3129 	struct chanbuf *cb;
3130 	int i, n, size, residue, total;
3131 
3132 	if (ch->sc->sc_dying)
3133 		return;
3134 
3135 	/* Pick the next channel buffer. */
3136 	cb = &ch->chanbufs[ch->curchanbuf];
3137 	if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
3138 		ch->curchanbuf = 0;
3139 
3140 	/* Compute the size of each frame in the next transfer. */
3141 	residue = ch->residue;
3142 	total = 0;
3143 	for (i = 0; i < UAUDIO_NFRAMES; i++) {
3144 		size = ch->bytes_per_frame;
3145 		residue += ch->fraction;
3146 		if (residue >= USB_FRAMES_PER_SECOND) {
3147 			if ((ch->sc->sc_altflags & UA_NOFRAC) == 0)
3148 				size += ch->sample_size;
3149 			residue -= USB_FRAMES_PER_SECOND;
3150 		}
3151 		cb->sizes[i] = size;
3152 		total += size;
3153 	}
3154 	ch->residue = residue;
3155 	cb->size = total;
3156 
3157 	/*
3158 	 * Transfer data from upper layer buffer to channel buffer, taking
3159 	 * care of wrapping the upper layer buffer.
3160 	 */
3161 	n = min(total, ch->end - ch->cur);
3162 	memcpy(cb->buffer, ch->cur, n);
3163 	ch->cur += n;
3164 	if (ch->cur >= ch->end)
3165 		ch->cur = ch->start;
3166 	if (total > n) {
3167 		total -= n;
3168 		memcpy(cb->buffer + n, ch->cur, total);
3169 		ch->cur += total;
3170 	}
3171 
3172 #ifdef USB_DEBUG
3173 	if (uaudiodebug > 8) {
3174 		DPRINTF(("uaudio_chan_ptransfer: buffer=%p, residue=0.%03d\n",
3175 			 cb->buffer, ch->residue));
3176 		for (i = 0; i < UAUDIO_NFRAMES; i++) {
3177 			DPRINTF(("   [%d] length %d\n", i, cb->sizes[i]));
3178 		}
3179 	}
3180 #endif
3181 
3182 	DPRINTFN(5,("uaudio_chan_transfer: ptransfer xfer=%p\n", cb->xfer));
3183 	/* Fill the request */
3184 	usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes,
3185 			     UAUDIO_NFRAMES, USBD_NO_COPY,
3186 			     uaudio_chan_pintr);
3187 
3188 	(void)usbd_transfer(cb->xfer);
3189 }
3190 
3191 static void
3192 uaudio_chan_pintr(usbd_xfer_handle xfer, usbd_private_handle priv,
3193 		  usbd_status status)
3194 {
3195 	struct chanbuf *cb;
3196 	struct chan *ch;
3197 	u_int32_t count;
3198 	int s;
3199 
3200 	cb = priv;
3201 	ch = cb->chan;
3202 	/* Return if we are aborting. */
3203 	if (status == USBD_CANCELLED)
3204 		return;
3205 
3206 	usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
3207 	DPRINTFN(5,("uaudio_chan_pintr: count=%d, transferred=%d\n",
3208 		    count, ch->transferred));
3209 #ifdef DIAGNOSTIC
3210 	if (count != cb->size) {
3211 		printf("uaudio_chan_pintr: count(%d) != size(%d)\n",
3212 		       count, cb->size);
3213 	}
3214 #endif
3215 
3216 	ch->transferred += cb->size;
3217 #if defined(__FreeBSD__)
3218 	/* s = spltty(); */
3219 	s = splhigh();
3220 	chn_intr(ch->pcm_ch);
3221 	splx(s);
3222 #else
3223 	s = splaudio();
3224 	/* Call back to upper layer */
3225 	while (ch->transferred >= ch->blksize) {
3226 		ch->transferred -= ch->blksize;
3227 		DPRINTFN(5,("uaudio_chan_pintr: call %p(%p)\n",
3228 			    ch->intr, ch->arg));
3229 		ch->intr(ch->arg);
3230 	}
3231 	splx(s);
3232 #endif
3233 
3234 	/* start next transfer */
3235 	uaudio_chan_ptransfer(ch);
3236 }
3237 
3238 /* Called at splusb() */
3239 static void
3240 uaudio_chan_rtransfer(struct chan *ch)
3241 {
3242 	struct chanbuf *cb;
3243 	int i, size, residue, total;
3244 
3245 	if (ch->sc->sc_dying)
3246 		return;
3247 
3248 	/* Pick the next channel buffer. */
3249 	cb = &ch->chanbufs[ch->curchanbuf];
3250 	if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
3251 		ch->curchanbuf = 0;
3252 
3253 	/* Compute the size of each frame in the next transfer. */
3254 	residue = ch->residue;
3255 	total = 0;
3256 	for (i = 0; i < UAUDIO_NFRAMES; i++) {
3257 		size = ch->bytes_per_frame;
3258 		cb->sizes[i] = size;
3259 		cb->offsets[i] = total;
3260 		total += size;
3261 	}
3262 	ch->residue = residue;
3263 	cb->size = total;
3264 
3265 #ifdef USB_DEBUG
3266 	if (uaudiodebug > 8) {
3267 		DPRINTF(("uaudio_chan_rtransfer: buffer=%p, residue=0.%03d\n",
3268 			 cb->buffer, ch->residue));
3269 		for (i = 0; i < UAUDIO_NFRAMES; i++) {
3270 			DPRINTF(("   [%d] length %d\n", i, cb->sizes[i]));
3271 		}
3272 	}
3273 #endif
3274 
3275 	DPRINTFN(5,("uaudio_chan_rtransfer: transfer xfer=%p\n", cb->xfer));
3276 	/* Fill the request */
3277 	usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes,
3278 			     UAUDIO_NFRAMES, USBD_NO_COPY,
3279 			     uaudio_chan_rintr);
3280 
3281 	(void)usbd_transfer(cb->xfer);
3282 }
3283 
3284 static void
3285 uaudio_chan_rintr(usbd_xfer_handle xfer, usbd_private_handle priv,
3286 		  usbd_status status)
3287 {
3288 	struct chanbuf *cb = priv;
3289 	struct chan *ch = cb->chan;
3290 	u_int32_t count;
3291 	int s, i, n, frsize;
3292 
3293 	/* Return if we are aborting. */
3294 	if (status == USBD_CANCELLED)
3295 		return;
3296 
3297 	usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
3298 	DPRINTFN(5,("uaudio_chan_rintr: count=%d, transferred=%d\n",
3299 		    count, ch->transferred));
3300 
3301 	/* count < cb->size is normal for asynchronous source */
3302 #ifdef DIAGNOSTIC
3303 	if (count > cb->size) {
3304 		printf("uaudio_chan_rintr: count(%d) > size(%d)\n",
3305 		       count, cb->size);
3306 	}
3307 #endif
3308 
3309 	/*
3310 	 * Transfer data from channel buffer to upper layer buffer, taking
3311 	 * care of wrapping the upper layer buffer.
3312 	 */
3313 	for(i = 0; i < UAUDIO_NFRAMES; i++) {
3314 		frsize = cb->sizes[i];
3315 		n = min(frsize, ch->end - ch->cur);
3316 		memcpy(ch->cur, cb->buffer + cb->offsets[i], n);
3317 		ch->cur += n;
3318 		if (ch->cur >= ch->end)
3319 			ch->cur = ch->start;
3320 		if (frsize > n) {
3321 			memcpy(ch->cur, cb->buffer + cb->offsets[i] + n,
3322 			    frsize - n);
3323 			ch->cur += frsize - n;
3324 		}
3325 	}
3326 
3327 	/* Call back to upper layer */
3328 	ch->transferred += count;
3329 #if defined(__FreeBSD__)
3330 	s = spltty();
3331 	chn_intr(ch->pcm_ch);
3332 	splx(s);
3333 #else
3334 	s = splaudio();
3335 	while (ch->transferred >= ch->blksize) {
3336 		ch->transferred -= ch->blksize;
3337 		DPRINTFN(5,("uaudio_chan_rintr: call %p(%p)\n",
3338 			    ch->intr, ch->arg));
3339 		ch->intr(ch->arg);
3340 	}
3341 	splx(s);
3342 #endif
3343 
3344 	/* start next transfer */
3345 	uaudio_chan_rtransfer(ch);
3346 }
3347 
3348 #if defined(__NetBSD__) || defined(__OpenBSD__)
3349 static void
3350 uaudio_chan_init(struct chan *ch, int altidx, const struct audio_params *param,
3351     int maxpktsize)
3352 {
3353 	int samples_per_frame, sample_size;
3354 
3355 	ch->altidx = altidx;
3356 	sample_size = param->precision * param->factor * param->hw_channels / 8;
3357 	samples_per_frame = param->hw_sample_rate / USB_FRAMES_PER_SECOND;
3358 	ch->sample_size = sample_size;
3359 	ch->sample_rate = param->hw_sample_rate;
3360 	if (maxpktsize == 0) {
3361 		ch->fraction = param->hw_sample_rate % USB_FRAMES_PER_SECOND;
3362 		ch->bytes_per_frame = samples_per_frame * sample_size;
3363 	} else {
3364 		ch->fraction = 0;
3365 		ch->bytes_per_frame = maxpktsize;
3366 	}
3367 	ch->residue = 0;
3368 }
3369 
3370 static void
3371 uaudio_chan_set_param(struct chan *ch, u_char *start, u_char *end, int blksize)
3372 {
3373 	ch->start = start;
3374 	ch->end = end;
3375 	ch->cur = start;
3376 	ch->blksize = blksize;
3377 	ch->transferred = 0;
3378 	ch->curchanbuf = 0;
3379 }
3380 
3381 static void
3382 uaudio_get_minmax_rates(int nalts, const struct as_info *alts,
3383 			const struct audio_params *p, int mode,
3384 			u_long *min, u_long *max)
3385 {
3386 	const struct usb_audio_streaming_type1_descriptor *a1d;
3387 	int i, j;
3388 
3389 	*min = ULONG_MAX;
3390 	*max = 0;
3391 	for (i = 0; i < nalts; i++) {
3392 		a1d = alts[i].asf1desc;
3393 		if (alts[i].sc_busy)
3394 			continue;
3395 		if (p->hw_channels != a1d->bNrChannels)
3396 			continue;
3397 		if (p->hw_precision != a1d->bBitResolution)
3398 			continue;
3399 		if (p->hw_encoding != alts[i].encoding)
3400 			continue;
3401 		if (mode != UE_GET_DIR(alts[i].edesc->bEndpointAddress))
3402 			continue;
3403 		if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
3404 			DPRINTFN(2,("uaudio_get_minmax_rates: cont %d-%d\n",
3405 				    UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
3406 			if (UA_SAMP_LO(a1d) < *min)
3407 				*min = UA_SAMP_LO(a1d);
3408 			if (UA_SAMP_HI(a1d) > *max)
3409 				*max = UA_SAMP_HI(a1d);
3410 		} else {
3411 			for (j = 0; j < a1d->bSamFreqType; j++) {
3412 				DPRINTFN(2,("uaudio_get_minmax_rates: disc #%d: %d\n",
3413 					    j, UA_GETSAMP(a1d, j)));
3414 				if (UA_GETSAMP(a1d, j) < *min)
3415 					*min = UA_GETSAMP(a1d, j);
3416 				if (UA_GETSAMP(a1d, j) > *max)
3417 					*max = UA_GETSAMP(a1d, j);
3418 			}
3419 		}
3420 	}
3421 }
3422 
3423 static int
3424 uaudio_match_alt_sub(int nalts, const struct as_info *alts,
3425 		     const struct audio_params *p, int mode, u_long rate)
3426 {
3427 	const struct usb_audio_streaming_type1_descriptor *a1d;
3428 	int i, j;
3429 
3430 	DPRINTF(("uaudio_match_alt_sub: search for %luHz %dch\n",
3431 		 rate, p->hw_channels));
3432 	for (i = 0; i < nalts; i++) {
3433 		a1d = alts[i].asf1desc;
3434 		if (alts[i].sc_busy)
3435 			continue;
3436 		if (p->hw_channels != a1d->bNrChannels)
3437 			continue;
3438 		if (p->hw_precision != a1d->bBitResolution)
3439 			continue;
3440 		if (p->hw_encoding != alts[i].encoding)
3441 			continue;
3442 		if (mode != UE_GET_DIR(alts[i].edesc->bEndpointAddress))
3443 			continue;
3444 		if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
3445 			DPRINTFN(3,("uaudio_match_alt_sub: cont %d-%d\n",
3446 				    UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
3447 			if (UA_SAMP_LO(a1d) <= rate && rate <= UA_SAMP_HI(a1d))
3448 				return i;
3449 		} else {
3450 			for (j = 0; j < a1d->bSamFreqType; j++) {
3451 				DPRINTFN(3,("uaudio_match_alt_sub: disc #%d: %d\n",
3452 					    j, UA_GETSAMP(a1d, j)));
3453 				/* XXX allow for some slack */
3454 				if (UA_GETSAMP(a1d, j) == rate)
3455 					return i;
3456 			}
3457 		}
3458 	}
3459 	return -1;
3460 }
3461 
3462 static int
3463 uaudio_match_alt_chan(int nalts, const struct as_info *alts,
3464 		      struct audio_params *p, int mode)
3465 {
3466 	int i, n;
3467 	u_long min, max;
3468 	u_long rate;
3469 
3470 	/* Exact match */
3471 	DPRINTF(("uaudio_match_alt_chan: examine %ldHz %dch %dbit.\n",
3472 		 p->sample_rate, p->hw_channels, p->hw_precision));
3473 	i = uaudio_match_alt_sub(nalts, alts, p, mode, p->sample_rate);
3474 	if (i >= 0)
3475 		return i;
3476 
3477 	uaudio_get_minmax_rates(nalts, alts, p, mode, &min, &max);
3478 	DPRINTF(("uaudio_match_alt_chan: min=%lu max=%lu\n", min, max));
3479 	if (max <= 0)
3480 		return -1;
3481 	/* Search for biggers */
3482 	n = 2;
3483 	while ((rate = p->sample_rate * n++) <= max) {
3484 		i = uaudio_match_alt_sub(nalts, alts, p, mode, rate);
3485 		if (i >= 0) {
3486 			p->hw_sample_rate = rate;
3487 			return i;
3488 		}
3489 	}
3490 	if (p->sample_rate >= min) {
3491 		i = uaudio_match_alt_sub(nalts, alts, p, mode, max);
3492 		if (i >= 0) {
3493 			p->hw_sample_rate = max;
3494 			return i;
3495 		}
3496 	} else {
3497 		i = uaudio_match_alt_sub(nalts, alts, p, mode, min);
3498 		if (i >= 0) {
3499 			p->hw_sample_rate = min;
3500 			return i;
3501 		}
3502 	}
3503 	return -1;
3504 }
3505 
3506 static int
3507 uaudio_match_alt(int nalts, const struct as_info *alts,
3508 		 struct audio_params *p, int mode)
3509 {
3510 	int i, n;
3511 
3512 	mode = mode == AUMODE_PLAY ? UE_DIR_OUT : UE_DIR_IN;
3513 	i = uaudio_match_alt_chan(nalts, alts, p, mode);
3514 	if (i >= 0)
3515 		return i;
3516 
3517 	for (n = p->channels + 1; n <= AUDIO_MAX_CHANNELS; n++) {
3518 		p->hw_channels = n;
3519 		i = uaudio_match_alt_chan(nalts, alts, p, mode);
3520 		if (i >= 0)
3521 			return i;
3522 	}
3523 
3524 	if (p->channels != 2)
3525 		return -1;
3526 	p->hw_channels = 1;
3527 	return uaudio_match_alt_chan(nalts, alts, p, mode);
3528 }
3529 
3530 static int
3531 uaudio_set_params(void *addr, int setmode, int usemode,
3532 		  struct audio_params *play, struct audio_params *rec)
3533 {
3534 	struct uaudio_softc *sc;
3535 	int flags;
3536 	int factor;
3537 	int enc, i;
3538 	int paltidx, raltidx;
3539 	void (*swcode)(void *, u_char *buf, int cnt);
3540 	struct audio_params *p;
3541 	int mode;
3542 
3543 	sc = addr;
3544 	flags = sc->sc_altflags;
3545 	paltidx = -1;
3546 	raltidx = -1;
3547 	if (sc->sc_dying)
3548 		return EIO;
3549 
3550 	if (((usemode & AUMODE_PLAY) && sc->sc_playchan.pipe != NULL) ||
3551 	    ((usemode & AUMODE_RECORD) && sc->sc_recchan.pipe != NULL))
3552 		return EBUSY;
3553 
3554 	if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1)
3555 		sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 0;
3556 	if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1)
3557 		sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 0;
3558 
3559 	/* Some uaudio devices are unidirectional.  Don't try to find a
3560 	   matching mode for the unsupported direction. */
3561 	setmode &= sc->sc_mode;
3562 
3563 	for (mode = AUMODE_RECORD; mode != -1;
3564 	     mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
3565 		if ((setmode & mode) == 0)
3566 			continue;
3567 
3568 		p = (mode == AUMODE_PLAY) ? play : rec;
3569 
3570 		factor = 1;
3571 		swcode = 0;
3572 		enc = p->encoding;
3573 		switch (enc) {
3574 		case AUDIO_ENCODING_SLINEAR_BE:
3575 			/* FALLTHROUGH */
3576 		case AUDIO_ENCODING_SLINEAR_LE:
3577 			if (enc == AUDIO_ENCODING_SLINEAR_BE
3578 			    && p->precision == 16 && (flags & HAS_16)) {
3579 				swcode = swap_bytes;
3580 				enc = AUDIO_ENCODING_SLINEAR_LE;
3581 			} else if (p->precision == 8) {
3582 				if (flags & HAS_8) {
3583 					/* No conversion */
3584 				} else if (flags & HAS_8U) {
3585 					swcode = change_sign8;
3586 					enc = AUDIO_ENCODING_ULINEAR_LE;
3587 				} else if (flags & HAS_16) {
3588 					factor = 2;
3589 					p->hw_precision = 16;
3590 					if (mode == AUMODE_PLAY)
3591 						swcode = linear8_to_linear16_le;
3592 					else
3593 						swcode = linear16_to_linear8_le;
3594 				}
3595 			}
3596 			break;
3597 		case AUDIO_ENCODING_ULINEAR_BE:
3598 			/* FALLTHROUGH */
3599 		case AUDIO_ENCODING_ULINEAR_LE:
3600 			if (p->precision == 16) {
3601 				if (enc == AUDIO_ENCODING_ULINEAR_LE)
3602 					swcode = change_sign16_le;
3603 				else if (mode == AUMODE_PLAY)
3604 					swcode = swap_bytes_change_sign16_le;
3605 				else
3606 					swcode = change_sign16_swap_bytes_le;
3607 				enc = AUDIO_ENCODING_SLINEAR_LE;
3608 			} else if (p->precision == 8) {
3609 				if (flags & HAS_8U) {
3610 					/* No conversion */
3611 				} else if (flags & HAS_8) {
3612 					swcode = change_sign8;
3613 					enc = AUDIO_ENCODING_SLINEAR_LE;
3614 				} else if (flags & HAS_16) {
3615 					factor = 2;
3616 					p->hw_precision = 16;
3617 					enc = AUDIO_ENCODING_SLINEAR_LE;
3618 					if (mode == AUMODE_PLAY)
3619 						swcode = ulinear8_to_slinear16_le;
3620 					else
3621 						swcode = slinear16_to_ulinear8_le;
3622 				}
3623 			}
3624 			break;
3625 		case AUDIO_ENCODING_ULAW:
3626 			if (flags & HAS_MULAW)
3627 				break;
3628 			if (flags & HAS_16) {
3629 				if (mode == AUMODE_PLAY)
3630 					swcode = mulaw_to_slinear16_le;
3631 				else
3632 					swcode = slinear16_to_mulaw_le;
3633 				factor = 2;
3634 				enc = AUDIO_ENCODING_SLINEAR_LE;
3635 				p->hw_precision = 16;
3636 			} else if (flags & HAS_8U) {
3637 				if (mode == AUMODE_PLAY)
3638 					swcode = mulaw_to_ulinear8;
3639 				else
3640 					swcode = ulinear8_to_mulaw;
3641 				enc = AUDIO_ENCODING_ULINEAR_LE;
3642 			} else if (flags & HAS_8) {
3643 				if (mode == AUMODE_PLAY)
3644 					swcode = mulaw_to_slinear8;
3645 				else
3646 					swcode = slinear8_to_mulaw;
3647 				enc = AUDIO_ENCODING_SLINEAR_LE;
3648 			} else
3649 				return (EINVAL);
3650 			break;
3651 		case AUDIO_ENCODING_ALAW:
3652 			if (flags & HAS_ALAW)
3653 				break;
3654 			if (mode == AUMODE_PLAY && (flags & HAS_16)) {
3655 				swcode = alaw_to_slinear16_le;
3656 				factor = 2;
3657 				enc = AUDIO_ENCODING_SLINEAR_LE;
3658 				p->hw_precision = 16;
3659 			} else if (flags & HAS_8U) {
3660 				if (mode == AUMODE_PLAY)
3661 					swcode = alaw_to_ulinear8;
3662 				else
3663 					swcode = ulinear8_to_alaw;
3664 				enc = AUDIO_ENCODING_ULINEAR_LE;
3665 			} else if (flags & HAS_8) {
3666 				if (mode == AUMODE_PLAY)
3667 					swcode = alaw_to_slinear8;
3668 				else
3669 					swcode = slinear8_to_alaw;
3670 				enc = AUDIO_ENCODING_SLINEAR_LE;
3671 			} else
3672 				return (EINVAL);
3673 			break;
3674 		default:
3675 			return (EINVAL);
3676 		}
3677 		/* XXX do some other conversions... */
3678 
3679 		DPRINTF(("uaudio_set_params: chan=%d prec=%d enc=%d rate=%ld\n",
3680 			 p->channels, p->hw_precision, enc, p->sample_rate));
3681 
3682 		p->hw_encoding = enc;
3683 		i = uaudio_match_alt(sc->sc_nalts, sc->sc_alts, p, mode);
3684 		if (i < 0)
3685 			return (EINVAL);
3686 
3687 		p->sw_code = swcode;
3688 		p->factor  = factor;
3689 
3690 		if (mode == AUMODE_PLAY)
3691 			paltidx = i;
3692 		else
3693 			raltidx = i;
3694 	}
3695 
3696 	if ((setmode & AUMODE_PLAY)) {
3697 		/* XXX abort transfer if currently happening? */
3698 		uaudio_chan_init(&sc->sc_playchan, paltidx, play, 0);
3699 	}
3700 	if ((setmode & AUMODE_RECORD)) {
3701 		/* XXX abort transfer if currently happening? */
3702 		uaudio_chan_init(&sc->sc_recchan, raltidx, rec,
3703 		    UGETW(sc->sc_alts[raltidx].edesc->wMaxPacketSize));
3704 	}
3705 
3706 	if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1)
3707 		sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 1;
3708 	if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1)
3709 		sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 1;
3710 
3711 	DPRINTF(("uaudio_set_params: use altidx=p%d/r%d, altno=p%d/r%d\n",
3712 		 sc->sc_playchan.altidx, sc->sc_recchan.altidx,
3713 		 (sc->sc_playchan.altidx >= 0)
3714 		   ?sc->sc_alts[sc->sc_playchan.altidx].idesc->bAlternateSetting
3715 		   : -1,
3716 		 (sc->sc_recchan.altidx >= 0)
3717 		   ? sc->sc_alts[sc->sc_recchan.altidx].idesc->bAlternateSetting
3718 		   : -1));
3719 
3720 	return 0;
3721 }
3722 #endif /* NetBSD or OpenBSD */
3723 
3724 static usbd_status
3725 uaudio_set_speed(struct uaudio_softc *sc, int endpt, u_int speed)
3726 {
3727 	usb_device_request_t req;
3728 	uint8_t data[3];
3729 
3730 	DPRINTFN(5,("uaudio_set_speed: endpt=%d speed=%u\n", endpt, speed));
3731 	req.bmRequestType = UT_WRITE_CLASS_ENDPOINT;
3732 	req.bRequest = SET_CUR;
3733 	USETW2(req.wValue, SAMPLING_FREQ_CONTROL, 0);
3734 	USETW(req.wIndex, endpt);
3735 	USETW(req.wLength, 3);
3736 	data[0] = speed;
3737 	data[1] = speed >> 8;
3738 	data[2] = speed >> 16;
3739 
3740 	return usbd_do_request(sc->sc_udev, &req, data);
3741 }
3742 
3743 
3744 #if defined(__FreeBSD__)
3745 /************************************************************/
3746 int
3747 uaudio_init_params(struct uaudio_softc *sc, struct chan *ch, int mode)
3748 {
3749 	int i, j, enc;
3750 	int samples_per_frame, sample_size;
3751 
3752 	if ((sc->sc_playchan.pipe != NULL) || (sc->sc_recchan.pipe != NULL))
3753 		return (-1);
3754 
3755 	switch(ch->format & 0x000FFFFF) {
3756 	case AFMT_U8:
3757 		enc = AUDIO_ENCODING_ULINEAR_LE;
3758 		ch->precision = 8;
3759 		break;
3760 	case AFMT_S8:
3761 		enc = AUDIO_ENCODING_SLINEAR_LE;
3762 		ch->precision = 8;
3763 		break;
3764 	case AFMT_A_LAW:	/* ? */
3765 		enc = AUDIO_ENCODING_ALAW;
3766 		ch->precision = 8;
3767 		break;
3768 	case AFMT_MU_LAW:	/* ? */
3769 		enc = AUDIO_ENCODING_ULAW;
3770 		ch->precision = 8;
3771 		break;
3772 	case AFMT_S16_LE:
3773 		enc = AUDIO_ENCODING_SLINEAR_LE;
3774 		ch->precision = 16;
3775 		break;
3776 	case AFMT_S16_BE:
3777 		enc = AUDIO_ENCODING_SLINEAR_BE;
3778 		ch->precision = 16;
3779 		break;
3780 	case AFMT_U16_LE:
3781 		enc = AUDIO_ENCODING_ULINEAR_LE;
3782 		ch->precision = 16;
3783 		break;
3784 	case AFMT_U16_BE:
3785 		enc = AUDIO_ENCODING_ULINEAR_BE;
3786 		ch->precision = 16;
3787 		break;
3788 	case AFMT_S24_LE:
3789 		enc = AUDIO_ENCODING_SLINEAR_LE;
3790 		ch->precision = 24;
3791 		break;
3792 	case AFMT_S24_BE:
3793 		enc = AUDIO_ENCODING_SLINEAR_BE;
3794 		ch->precision = 24;
3795 		break;
3796 	case AFMT_U24_LE:
3797 		enc = AUDIO_ENCODING_ULINEAR_LE;
3798 		ch->precision = 24;
3799 		break;
3800 	case AFMT_U24_BE:
3801 		enc = AUDIO_ENCODING_ULINEAR_BE;
3802 		ch->precision = 24;
3803 		break;
3804 	case AFMT_S32_LE:
3805 		enc = AUDIO_ENCODING_SLINEAR_LE;
3806 		ch->precision = 32;
3807 		break;
3808 	case AFMT_S32_BE:
3809 		enc = AUDIO_ENCODING_SLINEAR_BE;
3810 		ch->precision = 32;
3811 		break;
3812 	case AFMT_U32_LE:
3813 		enc = AUDIO_ENCODING_ULINEAR_LE;
3814 		ch->precision = 32;
3815 		break;
3816 	case AFMT_U32_BE:
3817 		enc = AUDIO_ENCODING_ULINEAR_BE;
3818 		ch->precision = 32;
3819 		break;
3820 	default:
3821 		enc = 0;
3822 		ch->precision = 16;
3823 		printf("Unknown format %x\n", ch->format);
3824 	}
3825 
3826 	if (ch->format & AFMT_STEREO) {
3827 		ch->channels = 2;
3828 	} else {
3829 		ch->channels = 1;
3830 	}
3831 
3832 /*	for (mode =  ......	 */
3833 		for (i = 0; i < sc->sc_nalts; i++) {
3834 			const struct usb_audio_streaming_type1_descriptor *a1d =
3835 				sc->sc_alts[i].asf1desc;
3836 			if (ch->channels == a1d->bNrChannels &&
3837 			    ch->precision == a1d->bBitResolution &&
3838 #if 0
3839 			    enc == sc->sc_alts[i].encoding) {
3840 #else
3841 			    enc == sc->sc_alts[i].encoding &&
3842 			    (mode == AUMODE_PLAY ? UE_DIR_OUT : UE_DIR_IN) ==
3843 			    UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress)) {
3844 #endif
3845 				if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
3846 					DPRINTFN(2,("uaudio_set_params: cont %d-%d\n",
3847 					    UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
3848 					if (UA_SAMP_LO(a1d) <= ch->sample_rate &&
3849 					    ch->sample_rate <= UA_SAMP_HI(a1d)) {
3850 						if (mode == AUMODE_PLAY)
3851 							sc->sc_playchan.altidx = i;
3852 						else
3853 							sc->sc_recchan.altidx = i;
3854 						goto found;
3855 					}
3856 				} else {
3857 					for (j = 0; j < a1d->bSamFreqType; j++) {
3858 						DPRINTFN(2,("uaudio_set_params: disc #"
3859 						    "%d: %d\n", j, UA_GETSAMP(a1d, j)));
3860 						/* XXX allow for some slack */
3861 						if (UA_GETSAMP(a1d, j) ==
3862 						    ch->sample_rate) {
3863 							if (mode == AUMODE_PLAY)
3864 								sc->sc_playchan.altidx = i;
3865 							else
3866 								sc->sc_recchan.altidx = i;
3867 							goto found;
3868 						}
3869 					}
3870 				}
3871 			}
3872 		}
3873 		/* return (EINVAL); */
3874 		if (mode == AUMODE_PLAY)
3875 			printf("uaudio: This device can't play in rate=%d.\n", ch->sample_rate);
3876 		else
3877 			printf("uaudio: This device can't record in rate=%d.\n", ch->sample_rate);
3878 		return (-1);
3879 
3880 	found:
3881 #if 0 /* XXX */
3882 		p->sw_code = swcode;
3883 		p->factor  = factor;
3884 		if (usemode == mode)
3885 			sc->sc_curaltidx = i;
3886 #endif
3887 /*	} */
3888 
3889 	sample_size = ch->precision * ch->channels / 8;
3890 	samples_per_frame = ch->sample_rate / USB_FRAMES_PER_SECOND;
3891 	ch->fraction = ch->sample_rate % USB_FRAMES_PER_SECOND;
3892 	ch->sample_size = sample_size;
3893 	ch->bytes_per_frame = samples_per_frame * sample_size;
3894 	ch->residue = 0;
3895 
3896 	ch->cur = ch->start;
3897 	ch->transferred = 0;
3898 	ch->curchanbuf = 0;
3899 	return (0);
3900 }
3901 
3902 struct uaudio_conversion {
3903 	uint8_t uaudio_fmt;
3904 	uint8_t uaudio_prec;
3905 	uint32_t freebsd_fmt;
3906 };
3907 
3908 const struct uaudio_conversion const accepted_conversion[] = {
3909 	{AUDIO_ENCODING_ULINEAR_LE, 8, AFMT_U8},
3910 	{AUDIO_ENCODING_ULINEAR_LE, 16, AFMT_U16_LE},
3911 	{AUDIO_ENCODING_ULINEAR_LE, 24, AFMT_U24_LE},
3912 	{AUDIO_ENCODING_ULINEAR_LE, 32, AFMT_U32_LE},
3913 	{AUDIO_ENCODING_ULINEAR_BE, 16, AFMT_U16_BE},
3914 	{AUDIO_ENCODING_ULINEAR_BE, 24, AFMT_U24_BE},
3915 	{AUDIO_ENCODING_ULINEAR_BE, 32, AFMT_U32_BE},
3916 	{AUDIO_ENCODING_SLINEAR_LE, 8, AFMT_S8},
3917 	{AUDIO_ENCODING_SLINEAR_LE, 16, AFMT_S16_LE},
3918 	{AUDIO_ENCODING_SLINEAR_LE, 24, AFMT_S24_LE},
3919 	{AUDIO_ENCODING_SLINEAR_LE, 32, AFMT_S32_LE},
3920 	{AUDIO_ENCODING_SLINEAR_BE, 16, AFMT_S16_BE},
3921 	{AUDIO_ENCODING_SLINEAR_BE, 24, AFMT_S24_BE},
3922 	{AUDIO_ENCODING_SLINEAR_BE, 32, AFMT_S32_BE},
3923 	{AUDIO_ENCODING_ALAW, 8, AFMT_A_LAW},
3924 	{AUDIO_ENCODING_ULAW, 8, AFMT_MU_LAW},
3925 	{0,0,0}
3926 };
3927 
3928 unsigned
3929 uaudio_query_formats(device_t dev, int reqdir, unsigned maxfmt, struct pcmchan_caps *cap)
3930 {
3931 	struct uaudio_softc *sc;
3932 	const struct usb_audio_streaming_type1_descriptor *asf1d;
3933 	const struct uaudio_conversion *iterator;
3934 	unsigned fmtcount, foundcount;
3935 	u_int32_t fmt;
3936 	uint8_t format, numchan, subframesize, prec, dir, iscontinuous;
3937 	int freq, freq_min, freq_max;
3938 	char *numchannel_descr;
3939 	char freq_descr[64];
3940 	int i,r;
3941 
3942 	sc = device_get_softc(dev);
3943 	if (sc == NULL)
3944 		return 0;
3945 
3946 	cap->minspeed = cap->maxspeed = 0;
3947 	foundcount = fmtcount = 0;
3948 
3949 	for (i = 0; i < sc->sc_nalts; i++) {
3950 		dir = UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress);
3951 
3952 		if ((dir == UE_DIR_OUT) != (reqdir == PCMDIR_PLAY))
3953 			continue;
3954 
3955 		asf1d = sc->sc_alts[i].asf1desc;
3956 		format = sc->sc_alts[i].encoding;
3957 
3958 		numchan = asf1d->bNrChannels;
3959 		subframesize = asf1d->bSubFrameSize;
3960 		prec = asf1d->bBitResolution;	/* precision */
3961 		iscontinuous = asf1d->bSamFreqType == UA_SAMP_CONTNUOUS;
3962 
3963 		if (iscontinuous)
3964 			snprintf(freq_descr, sizeof(freq_descr), "continous min %d max %d", UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d));
3965 		else
3966 			snprintf(freq_descr, sizeof(freq_descr), "fixed frequency (%d listed formats)", asf1d->bSamFreqType);
3967 
3968 		if (numchan == 1)
3969 			numchannel_descr = " (mono)";
3970 		else if (numchan == 2)
3971 			numchannel_descr = " (stereo)";
3972 		else
3973 			numchannel_descr = "";
3974 
3975 		if (bootverbose) {
3976 			device_printf(dev, "uaudio_query_formats: found a native %s channel%s %s %dbit %dbytes/subframe X %d channels = %d bytes per sample\n",
3977 					(dir==UE_DIR_OUT)?"playback":"record",
3978 					numchannel_descr, freq_descr,
3979 					prec, subframesize, numchan, subframesize*numchan);
3980 		}
3981 		/*
3982 		 * Now start rejecting the ones that don't map to FreeBSD
3983 		 */
3984 
3985 		if (numchan != 1 && numchan != 2)
3986 			continue;
3987 
3988 		for (iterator = accepted_conversion ; iterator->uaudio_fmt != 0 ; iterator++)
3989 			if (iterator->uaudio_fmt == format && iterator->uaudio_prec == prec)
3990 				break;
3991 
3992 		if (iterator->uaudio_fmt == 0)
3993 			continue;
3994 
3995 		fmt = iterator->freebsd_fmt;
3996 
3997 		if (numchan == 2)
3998 			fmt |= AFMT_STEREO;
3999 
4000 		foundcount++;
4001 
4002 		if (fmtcount >= maxfmt)
4003 			continue;
4004 
4005 		cap->fmtlist[fmtcount++] = fmt;
4006 
4007 		if (iscontinuous) {
4008 			freq_min = UA_SAMP_LO(asf1d);
4009 			freq_max = UA_SAMP_HI(asf1d);
4010 
4011 			if (cap->minspeed == 0 || freq_min < cap->minspeed)
4012 				cap->minspeed = freq_min;
4013 			if (cap->maxspeed == 0)
4014 				cap->maxspeed = cap->minspeed;
4015 			if (freq_max > cap->maxspeed)
4016 				cap->maxspeed = freq_max;
4017 		} else {
4018 			for (r = 0; r < asf1d->bSamFreqType; r++) {
4019 				freq = UA_GETSAMP(asf1d, r);
4020 				if (cap->minspeed == 0 || freq < cap->minspeed)
4021 					cap->minspeed = freq;
4022 				if (cap->maxspeed == 0)
4023 					cap->maxspeed = cap->minspeed;
4024 				if (freq > cap->maxspeed)
4025 					cap->maxspeed = freq;
4026 			}
4027 		}
4028 	}
4029 	cap->fmtlist[fmtcount] = 0;
4030 	return foundcount;
4031 }
4032 
4033 void
4034 uaudio_chan_set_param_pcm_dma_buff(device_t dev, u_char *start, u_char *end,
4035 		struct pcm_channel *pc, int dir)
4036 {
4037 	struct uaudio_softc *sc;
4038 	struct chan *ch;
4039 
4040 	sc = device_get_softc(dev);
4041 #ifndef NO_RECORDING
4042 	if (dir == PCMDIR_PLAY)
4043 		ch = &sc->sc_playchan;
4044 	else
4045 		ch = &sc->sc_recchan;
4046 #else
4047 	ch = &sc->sc_playchan;
4048 #endif
4049 
4050 	ch->start = start;
4051 	ch->end = end;
4052 
4053 	ch->pcm_ch = pc;
4054 
4055 	return;
4056 }
4057 
4058 void
4059 uaudio_chan_set_param_blocksize(device_t dev, u_int32_t blocksize, int dir)
4060 {
4061 	struct uaudio_softc *sc;
4062 	struct chan *ch;
4063 
4064 	sc = device_get_softc(dev);
4065 #ifndef NO_RECORDING
4066 	if (dir == PCMDIR_PLAY)
4067 		ch = &sc->sc_playchan;
4068 	else
4069 		ch = &sc->sc_recchan;
4070 #else
4071 	ch = &sc->sc_playchan;
4072 #endif
4073 
4074 	ch->blksize = blocksize;
4075 
4076 	return;
4077 }
4078 
4079 int
4080 uaudio_chan_set_param_speed(device_t dev, u_int32_t speed, int reqdir)
4081 {
4082 	const struct uaudio_conversion *iterator;
4083 	struct uaudio_softc *sc;
4084 	struct chan *ch;
4085 	int i, r, score, hiscore, bestspeed;
4086 
4087 	sc = device_get_softc(dev);
4088 #ifndef NO_RECORDING
4089 	if (reqdir == PCMDIR_PLAY)
4090 		ch = &sc->sc_playchan;
4091 	else
4092 		ch = &sc->sc_recchan;
4093 #else
4094 	ch = &sc->sc_playchan;
4095 #endif
4096 	/*
4097 	 * We are successful if we find an endpoint that matches our selected format and it
4098 	 * supports the requested speed.
4099 	 */
4100 	hiscore = 0;
4101 	bestspeed = 1;
4102 	for (i = 0; i < sc->sc_nalts; i++) {
4103 		int dir = UE_GET_DIR(sc->sc_alts[i].edesc->bEndpointAddress);
4104 		int format = sc->sc_alts[i].encoding;
4105 		const struct usb_audio_streaming_type1_descriptor *asf1d = sc->sc_alts[i].asf1desc;
4106 		int iscontinuous = asf1d->bSamFreqType == UA_SAMP_CONTNUOUS;
4107 
4108 		if ((dir == UE_DIR_OUT) != (reqdir == PCMDIR_PLAY))
4109 			continue;
4110 
4111 		for (iterator = accepted_conversion ; iterator->uaudio_fmt != 0 ; iterator++)
4112 			if (iterator->uaudio_fmt != format || iterator->freebsd_fmt != (ch->format&0xfffffff))
4113 				continue;
4114 			if (iscontinuous) {
4115 				if (speed >= UA_SAMP_LO(asf1d) && speed <= UA_SAMP_HI(asf1d)) {
4116 					ch->sample_rate = speed;
4117 					return speed;
4118 				} else if (speed < UA_SAMP_LO(asf1d)) {
4119 					score = 0xfff * speed / UA_SAMP_LO(asf1d);
4120 					if (score > hiscore) {
4121 						bestspeed = UA_SAMP_LO(asf1d);
4122 						hiscore = score;
4123 					}
4124 				} else if (speed > UA_SAMP_HI(asf1d)) {
4125 					score = 0xfff * UA_SAMP_HI(asf1d) / speed;
4126 					if (score > hiscore) {
4127 						bestspeed = UA_SAMP_HI(asf1d);
4128 						hiscore = score;
4129 					}
4130 				}
4131 				continue;
4132 			}
4133 			for (r = 0; r < asf1d->bSamFreqType; r++) {
4134 				if (speed == UA_GETSAMP(asf1d, r)) {
4135 					ch->sample_rate = speed;
4136 					return speed;
4137 				}
4138 				if (speed > UA_GETSAMP(asf1d, r))
4139 					score = 0xfff * UA_GETSAMP(asf1d, r) / speed;
4140 				else
4141 					score = 0xfff * speed / UA_GETSAMP(asf1d, r);
4142 				if (score > hiscore) {
4143 					bestspeed = UA_GETSAMP(asf1d, r);
4144 					hiscore = score;
4145 				}
4146 			}
4147 	}
4148 	if (bestspeed != 1) {
4149 		ch->sample_rate = bestspeed;
4150 		return bestspeed;
4151 	}
4152 
4153 	return 0;
4154 }
4155 
4156 int
4157 uaudio_chan_getptr(device_t dev, int dir)
4158 {
4159 	struct uaudio_softc *sc;
4160 	struct chan *ch;
4161 	int ptr;
4162 
4163 	sc = device_get_softc(dev);
4164 #ifndef NO_RECORDING
4165 	if (dir == PCMDIR_PLAY)
4166 		ch = &sc->sc_playchan;
4167 	else
4168 		ch = &sc->sc_recchan;
4169 #else
4170 	ch = &sc->sc_playchan;
4171 #endif
4172 
4173 	ptr = ch->cur - ch->start;
4174 
4175 	return ptr;
4176 }
4177 
4178 void
4179 uaudio_chan_set_param_format(device_t dev, u_int32_t format, int dir)
4180 {
4181 	struct uaudio_softc *sc;
4182 	struct chan *ch;
4183 
4184 	sc = device_get_softc(dev);
4185 #ifndef NO_RECORDING
4186 	if (dir == PCMDIR_PLAY)
4187 		ch = &sc->sc_playchan;
4188 	else
4189 		ch = &sc->sc_recchan;
4190 #else
4191 	ch = &sc->sc_playchan;
4192 #endif
4193 
4194 	ch->format = format;
4195 
4196 	return;
4197 }
4198 
4199 int
4200 uaudio_halt_out_dma(device_t dev)
4201 {
4202 	struct uaudio_softc *sc;
4203 
4204 	sc = device_get_softc(dev);
4205 
4206 	DPRINTF(("uaudio_halt_out_dma: enter\n"));
4207 	if (sc->sc_playchan.pipe != NULL) {
4208 		uaudio_chan_close(sc, &sc->sc_playchan);
4209 		sc->sc_playchan.pipe = 0;
4210 		uaudio_chan_free_buffers(sc, &sc->sc_playchan);
4211 	}
4212         return (0);
4213 }
4214 
4215 int
4216 uaudio_halt_in_dma(device_t dev)
4217 {
4218 	struct uaudio_softc *sc;
4219 
4220 	sc = device_get_softc(dev);
4221 
4222 	if (sc->sc_dying)
4223 		return (EIO);
4224 
4225 	DPRINTF(("uaudio_halt_in_dma: enter\n"));
4226 	if (sc->sc_recchan.pipe != NULL) {
4227 		uaudio_chan_close(sc, &sc->sc_recchan);
4228 		sc->sc_recchan.pipe = NULL;
4229 		uaudio_chan_free_buffers(sc, &sc->sc_recchan);
4230 /*		sc->sc_recchan.intr = NULL; */
4231 	}
4232 	return (0);
4233 }
4234 
4235 int
4236 uaudio_trigger_input(device_t dev)
4237 {
4238 	struct uaudio_softc *sc;
4239 	struct chan *ch;
4240 	usbd_status err;
4241 	int i, s;
4242 
4243 	sc = device_get_softc(dev);
4244 	ch = &sc->sc_recchan;
4245 
4246 	if (sc->sc_dying)
4247 		return (EIO);
4248 
4249 /*	uaudio_chan_set_param(ch, start, end, blksize) */
4250 	if (uaudio_init_params(sc, ch, AUMODE_RECORD))
4251 		return (EIO);
4252 
4253 	err = uaudio_chan_alloc_buffers(sc, ch);
4254 	if (err)
4255 		return (EIO);
4256 
4257 	err = uaudio_chan_open(sc, ch);
4258 	if (err) {
4259 		uaudio_chan_free_buffers(sc, ch);
4260 		return (EIO);
4261 	}
4262 
4263 /*	ch->intr = intr;
4264 	ch->arg = arg; */
4265 
4266 	s = splusb();
4267 	for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */
4268 		uaudio_chan_rtransfer(ch);
4269 	splx(s);
4270 
4271 	return (0);
4272 }
4273 
4274 int
4275 uaudio_trigger_output(device_t dev)
4276 {
4277 	struct uaudio_softc *sc;
4278 	struct chan *ch;
4279 	usbd_status err;
4280 	int i, s;
4281 
4282 	sc = device_get_softc(dev);
4283 	ch = &sc->sc_playchan;
4284 
4285 	if (sc->sc_dying)
4286 		return (EIO);
4287 
4288 	if (uaudio_init_params(sc, ch, AUMODE_PLAY))
4289 		return (EIO);
4290 
4291 	err = uaudio_chan_alloc_buffers(sc, ch);
4292 	if (err)
4293 		return (EIO);
4294 
4295 	err = uaudio_chan_open(sc, ch);
4296 	if (err) {
4297 		uaudio_chan_free_buffers(sc, ch);
4298 		return (EIO);
4299 	}
4300 
4301 	s = splusb();
4302 	for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */
4303 		uaudio_chan_ptransfer(ch);
4304 	splx(s);
4305 
4306         return (0);
4307 }
4308 
4309 u_int32_t
4310 uaudio_query_mix_info(device_t dev)
4311 {
4312 	int i;
4313 	u_int32_t mask = 0;
4314 	struct uaudio_softc *sc;
4315 	struct mixerctl *mc;
4316 
4317 	sc = device_get_softc(dev);
4318 	for (i=0; i < sc->sc_nctls; i++) {
4319 		mc = &sc->sc_ctls[i];
4320 		if (mc->ctl != SOUND_MIXER_NRDEVICES) {
4321 			/* Set device mask bits.
4322 			   See /usr/include/machine/soundcard.h */
4323 			mask |= (1 << mc->ctl);
4324 		}
4325 	}
4326 	return mask;
4327 }
4328 
4329 u_int32_t
4330 uaudio_query_recsrc_info(device_t dev)
4331 {
4332 	int i, rec_selector_id;
4333 	u_int32_t mask = 0;
4334 	struct uaudio_softc *sc;
4335 	struct mixerctl *mc;
4336 
4337 	sc = device_get_softc(dev);
4338 	rec_selector_id = -1;
4339 	for (i=0; i < sc->sc_nctls; i++) {
4340 		mc = &sc->sc_ctls[i];
4341 		if (mc->ctl == SOUND_MIXER_NRDEVICES &&
4342 		    mc->type == MIX_SELECTOR && mc->class == UAC_RECORD) {
4343 			if (rec_selector_id == -1) {
4344 				rec_selector_id = i;
4345 			} else {
4346 				printf("There are many selectors.  Can't recognize which selector is a record source selector.\n");
4347 				return mask;
4348 			}
4349 		}
4350 	}
4351 	if (rec_selector_id == -1)
4352 		return mask;
4353 	mc = &sc->sc_ctls[rec_selector_id];
4354 	for (i = mc->minval; i <= mc->maxval; i++) {
4355 		if (mc->slctrtype[i - 1] == SOUND_MIXER_NRDEVICES)
4356 			continue;
4357 		mask |= 1 << mc->slctrtype[i - 1];
4358 	}
4359 	return mask;
4360 }
4361 
4362 void
4363 uaudio_mixer_set(device_t dev, unsigned type, unsigned left, unsigned right)
4364 {
4365 	int i;
4366 	struct uaudio_softc *sc;
4367 	struct mixerctl *mc;
4368 
4369 	sc = device_get_softc(dev);
4370 	for (i=0; i < sc->sc_nctls; i++) {
4371 		mc = &sc->sc_ctls[i];
4372 		if (mc->ctl == type) {
4373 			if (mc->nchan == 2) {
4374 				/* set Right */
4375 				uaudio_ctl_set(sc, SET_CUR, mc, 1, (int)(right*255)/100);
4376 			}
4377 			/* set Left or Mono */
4378 			uaudio_ctl_set(sc, SET_CUR, mc, 0, (int)(left*255)/100);
4379 		}
4380 	}
4381 	return;
4382 }
4383 
4384 u_int32_t
4385 uaudio_mixer_setrecsrc(device_t dev, u_int32_t src)
4386 {
4387 	int i, rec_selector_id;
4388 	struct uaudio_softc *sc;
4389 	struct mixerctl *mc;
4390 
4391 	sc = device_get_softc(dev);
4392 	rec_selector_id = -1;
4393 	for (i=0; i < sc->sc_nctls; i++) {
4394 		mc = &sc->sc_ctls[i];
4395 		if (mc->ctl == SOUND_MIXER_NRDEVICES &&
4396 		    mc->type == MIX_SELECTOR && mc->class == UAC_RECORD) {
4397 			if (rec_selector_id == -1) {
4398 				rec_selector_id = i;
4399 			} else {
4400 				return src; /* Can't recognize which selector is record source selector */
4401 			}
4402 		}
4403 	}
4404 	if (rec_selector_id == -1)
4405 		return src;
4406 	mc = &sc->sc_ctls[rec_selector_id];
4407 	for (i = mc->minval; i <= mc->maxval; i++) {
4408 		if (src != (1 << mc->slctrtype[i - 1]))
4409 			continue;
4410 		uaudio_ctl_set(sc, SET_CUR, mc, 0, i);
4411 		return (1 << mc->slctrtype[i - 1]);
4412 	}
4413 	uaudio_ctl_set(sc, SET_CUR, mc, 0, mc->minval);
4414 	return (1 << mc->slctrtype[mc->minval - 1]);
4415 }
4416 
4417 static int
4418 uaudio_sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose)
4419 {
4420     	struct snddev_info *d;
4421     	struct snddev_channel *sce;
4422 	struct pcm_channel *c;
4423 	struct pcm_feeder *f;
4424     	int pc, rc, vc;
4425 	device_t pa_dev = device_get_parent(dev);
4426 	struct uaudio_softc *sc = device_get_softc(pa_dev);
4427 
4428 	if (verbose < 1)
4429 		return 0;
4430 
4431 	d = device_get_softc(dev);
4432 	if (!d)
4433 		return ENXIO;
4434 
4435 	snd_mtxlock(d->lock);
4436 	if (SLIST_EMPTY(&d->channels)) {
4437 		sbuf_printf(s, " (mixer only)");
4438 		snd_mtxunlock(d->lock);
4439 		return 0;
4440 	}
4441 	pc = rc = vc = 0;
4442 	SLIST_FOREACH(sce, &d->channels, link) {
4443 		c = sce->channel;
4444 		if (c->direction == PCMDIR_PLAY) {
4445 			if (c->flags & CHN_F_VIRTUAL)
4446 				vc++;
4447 			else
4448 				pc++;
4449 		} else
4450 			rc++;
4451 	}
4452 	sbuf_printf(s, " (%dp/%dr/%dv channels%s%s)",
4453 			d->playcount, d->reccount, d->vchancount,
4454 			(d->flags & SD_F_SIMPLEX)? "" : " duplex",
4455 #ifdef USING_DEVFS
4456 			(device_get_unit(dev) == snd_unit)? " default" : ""
4457 #else
4458 			""
4459 #endif
4460 			);
4461 
4462 	if (sc->uaudio_sndstat_flag != 0) {
4463 		sbuf_cat(s, sbuf_data(&(sc->uaudio_sndstat)));
4464 	}
4465 
4466 	if (verbose <= 1) {
4467 		snd_mtxunlock(d->lock);
4468 		return 0;
4469 	}
4470 
4471 	SLIST_FOREACH(sce, &d->channels, link) {
4472 		c = sce->channel;
4473 		sbuf_printf(s, "\n\t");
4474 
4475 		KASSERT(c->bufhard != NULL && c->bufsoft != NULL,
4476 			("hosed pcm channel setup"));
4477 
4478 		/* it would be better to indent child channels */
4479 		sbuf_printf(s, "%s[%s]: ", c->parentchannel? c->parentchannel->name : "", c->name);
4480 		sbuf_printf(s, "spd %d", c->speed);
4481 		if (c->speed != sndbuf_getspd(c->bufhard))
4482 			sbuf_printf(s, "/%d", sndbuf_getspd(c->bufhard));
4483 		sbuf_printf(s, ", fmt 0x%08x", c->format);
4484 		if (c->format != sndbuf_getfmt(c->bufhard))
4485 			sbuf_printf(s, "/0x%08x", sndbuf_getfmt(c->bufhard));
4486 		sbuf_printf(s, ", flags 0x%08x, 0x%08x", c->flags, c->feederflags);
4487 		if (c->pid != -1)
4488 			sbuf_printf(s, ", pid %d", c->pid);
4489 		sbuf_printf(s, "\n\t");
4490 
4491 		sbuf_printf(s, "interrupts %d, ", c->interrupts);
4492 		if (c->direction == PCMDIR_REC)
4493 			sbuf_printf(s, "overruns %d, hfree %d, sfree %d",
4494 				c->xruns, sndbuf_getfree(c->bufhard), sndbuf_getfree(c->bufsoft));
4495 		else
4496 			sbuf_printf(s, "underruns %d, ready %d",
4497 				c->xruns, sndbuf_getready(c->bufsoft));
4498 		sbuf_printf(s, "\n\t");
4499 
4500 		sbuf_printf(s, "{%s}", (c->direction == PCMDIR_REC)? "hardware" : "userland");
4501 		sbuf_printf(s, " -> ");
4502 		f = c->feeder;
4503 		while (f->source != NULL)
4504 			f = f->source;
4505 		while (f != NULL) {
4506 			sbuf_printf(s, "%s", f->class->name);
4507 			if (f->desc->type == FEEDER_FMT)
4508 				sbuf_printf(s, "(0x%08x -> 0x%08x)", f->desc->in, f->desc->out);
4509 			if (f->desc->type == FEEDER_RATE)
4510 				sbuf_printf(s, "(%d -> %d)", FEEDER_GET(f, FEEDRATE_SRC), FEEDER_GET(f, FEEDRATE_DST));
4511 			if (f->desc->type == FEEDER_ROOT || f->desc->type == FEEDER_MIXER)
4512 				sbuf_printf(s, "(0x%08x)", f->desc->out);
4513 			sbuf_printf(s, " -> ");
4514 			f = f->parent;
4515 		}
4516 		sbuf_printf(s, "{%s}", (c->direction == PCMDIR_REC)? "userland" : "hardware");
4517 	}
4518 	snd_mtxunlock(d->lock);
4519 
4520 	return 0;
4521 }
4522 
4523 void
4524 uaudio_sndstat_register(device_t dev)
4525 {
4526 	struct snddev_info *d = device_get_softc(dev);
4527 	sndstat_register(dev, d->status, uaudio_sndstat_prepare_pcm);
4528 }
4529 
4530 static int
4531 audio_attach_mi(device_t dev)
4532 {
4533 	device_t child;
4534 	struct sndcard_func *func;
4535 
4536 	/* Attach the children. */
4537 	/* PCM Audio */
4538 	func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT);
4539 	if (func == NULL)
4540 		return (ENOMEM);
4541 	bzero(func, sizeof(*func));
4542 	func->func = SCF_PCM;
4543 	child = device_add_child(dev, "pcm", -1);
4544 	device_set_ivars(child, func);
4545 
4546 	bus_generic_attach(dev);
4547 
4548 	return 0; /* XXXXX */
4549 }
4550 
4551 DRIVER_MODULE(uaudio, uhub, uaudio_driver, uaudio_devclass, usbd_driver_load, 0);
4552 MODULE_VERSION(uaudio, 1);
4553 
4554 #endif
4555