root/dev/usb/uaudio.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. uaudio_match
  2. uaudio_attach
  3. uaudio_activate
  4. uaudio_detach
  5. uaudio_query_encoding
  6. uaudio_find_iface
  7. uaudio_mixer_add_ctl
  8. uaudio_id_name
  9. uaudio_get_cluster
  10. uaudio_add_input
  11. uaudio_add_output
  12. uaudio_add_mixer
  13. uaudio_add_selector
  14. uaudio_get_terminal_name
  15. uaudio_determine_class
  16. uaudio_feature_name
  17. uaudio_add_feature
  18. uaudio_add_processing_updown
  19. uaudio_add_processing
  20. uaudio_add_extension
  21. uaudio_merge_terminal_list
  22. uaudio_io_terminaltype
  23. uaudio_identify
  24. uaudio_add_alt
  25. uaudio_process_as
  26. uaudio_identify_as
  27. uaudio_identify_ac
  28. uaudio_query_devinfo
  29. uaudio_open
  30. uaudio_close
  31. uaudio_drain
  32. uaudio_halt_out_dma
  33. uaudio_halt_in_dma
  34. uaudio_getdev
  35. uaudio_round_blocksize
  36. uaudio_get_props
  37. uaudio_get
  38. uaudio_set
  39. uaudio_signext
  40. uaudio_value2bsd
  41. uaudio_bsd2value
  42. uaudio_ctl_get
  43. uaudio_ctl_set
  44. uaudio_mixer_get_port
  45. uaudio_mixer_set_port
  46. uaudio_trigger_input
  47. uaudio_trigger_output
  48. uaudio_chan_open
  49. uaudio_chan_close
  50. uaudio_chan_alloc_buffers
  51. uaudio_chan_free_buffers
  52. uaudio_chan_ptransfer
  53. uaudio_chan_pintr
  54. uaudio_chan_rtransfer
  55. uaudio_chan_rintr
  56. uaudio_chan_init
  57. uaudio_chan_set_param
  58. uaudio_get_minmax_rates
  59. uaudio_match_alt_sub
  60. uaudio_match_alt_chan
  61. uaudio_match_alt
  62. uaudio_set_params
  63. uaudio_set_speed

    1 /*      $OpenBSD: uaudio.c,v 1.48 2007/06/14 10:11:15 mbalmer Exp $ */
    2 /*      $NetBSD: uaudio.c,v 1.90 2004/10/29 17:12:53 kent Exp $ */
    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/param.h>
   48 #include <sys/systm.h>
   49 #include <sys/kernel.h>
   50 #include <sys/malloc.h>
   51 #include <sys/device.h>
   52 #include <sys/ioctl.h>
   53 #include <sys/tty.h>
   54 #include <sys/file.h>
   55 #include <sys/reboot.h>                 /* for bootverbose */
   56 #include <sys/selinfo.h>
   57 #include <sys/proc.h>
   58 #include <sys/vnode.h>
   59 #include <sys/device.h>
   60 #include <sys/poll.h>
   61 
   62 #include <sys/audioio.h>
   63 #include <dev/audio_if.h>
   64 #include <dev/mulaw.h>
   65 #include <dev/auconv.h>
   66 
   67 #include <dev/usb/usb.h>
   68 #include <dev/usb/usbdi.h>
   69 #include <dev/usb/usbdi_util.h>
   70 #include <dev/usb/usb_quirks.h>
   71 
   72 #include <dev/usb/uaudioreg.h>
   73 
   74 /* #define UAUDIO_DEBUG */
   75 /* #define UAUDIO_MULTIPLE_ENDPOINTS */
   76 #ifdef UAUDIO_DEBUG
   77 #define DPRINTF(x)      do { if (uaudiodebug) printf x; } while (0)
   78 #define DPRINTFN(n,x)   do { if (uaudiodebug>(n)) printf x; } while (0)
   79 int     uaudiodebug = 0;
   80 #else
   81 #define DPRINTF(x)
   82 #define DPRINTFN(n,x)
   83 #endif
   84 
   85 #define UAUDIO_NCHANBUFS 6      /* number of outstanding request */
   86 #define UAUDIO_NFRAMES   10     /* ms of sound in each request */
   87 
   88 
   89 #define MIX_MAX_CHAN 8
   90 struct mixerctl {
   91         u_int16_t       wValue[MIX_MAX_CHAN]; /* using nchan */
   92         u_int16_t       wIndex;
   93         u_int8_t        nchan;
   94         u_int8_t        type;
   95 #define MIX_ON_OFF      1
   96 #define MIX_SIGNED_16   2
   97 #define MIX_UNSIGNED_16 3
   98 #define MIX_SIGNED_8    4
   99 #define MIX_SELECTOR    5
  100 #define MIX_SIZE(n) ((n) == MIX_SIGNED_16 || (n) == MIX_UNSIGNED_16 ? 2 : 1)
  101 #define MIX_UNSIGNED(n) ((n) == MIX_UNSIGNED_16)
  102         int             minval, maxval;
  103         u_int           delta;
  104         u_int           mul;
  105         u_int8_t        class;
  106         char            ctlname[MAX_AUDIO_DEV_LEN];
  107         char            *ctlunit;
  108 };
  109 #define MAKE(h,l) (((h) << 8) | (l))
  110 
  111 struct as_info {
  112         u_int8_t        alt;
  113         u_int8_t        encoding;
  114         u_int8_t        attributes; /* Copy of bmAttributes of
  115                                      * usb_audio_streaming_endpoint_descriptor
  116                                      */
  117         usbd_interface_handle   ifaceh;
  118         const usb_interface_descriptor_t *idesc;
  119         const usb_endpoint_descriptor_audio_t *edesc;
  120         const usb_endpoint_descriptor_audio_t *edesc1;
  121         const struct usb_audio_streaming_type1_descriptor *asf1desc;
  122         int             sc_busy;        /* currently used */
  123 };
  124 
  125 struct chan {
  126         void    (*intr)(void *);        /* DMA completion intr handler */
  127         void    *arg;           /* arg for intr() */
  128         usbd_pipe_handle pipe;
  129         usbd_pipe_handle sync_pipe;
  130 
  131         u_int   sample_size;
  132         u_int   sample_rate;
  133         u_int   bytes_per_frame;
  134         u_int   fraction;       /* fraction/1000 is the extra samples/frame */
  135         u_int   residue;        /* accumulates the fractional samples */
  136 
  137         u_char  *start;         /* upper layer buffer start */
  138         u_char  *end;           /* upper layer buffer end */
  139         u_char  *cur;           /* current position in upper layer buffer */
  140         int     blksize;        /* chunk size to report up */
  141         int     transferred;    /* transferred bytes not reported up */
  142 
  143         int     altidx;         /* currently used altidx */
  144 
  145         int     curchanbuf;
  146         struct chanbuf {
  147                 struct chan     *chan;
  148                 usbd_xfer_handle xfer;
  149                 u_char          *buffer;
  150                 u_int16_t       sizes[UAUDIO_NFRAMES];
  151                 u_int16_t       offsets[UAUDIO_NFRAMES];
  152                 u_int16_t       size;
  153         } chanbufs[UAUDIO_NCHANBUFS];
  154 
  155         struct uaudio_softc *sc; /* our softc */
  156 };
  157 
  158 struct uaudio_softc {
  159         struct device    sc_dev;        /* base device */
  160         usbd_device_handle sc_udev;     /* USB device */
  161         int              sc_ac_iface;   /* Audio Control interface */
  162         usbd_interface_handle   sc_ac_ifaceh;
  163         struct chan      sc_playchan;   /* play channel */
  164         struct chan      sc_recchan;    /* record channel */
  165         int              sc_nullalt;
  166         int              sc_audio_rev;
  167         struct as_info  *sc_alts;       /* alternate settings */
  168         int              sc_nalts;      /* # of alternate settings */
  169         int              sc_altflags;
  170 #define HAS_8            0x01
  171 #define HAS_16           0x02
  172 #define HAS_8U           0x04
  173 #define HAS_ALAW         0x08
  174 #define HAS_MULAW        0x10
  175 #define UA_NOFRAC        0x20           /* don't do sample rate adjustment */
  176 #define HAS_24           0x40
  177         int              sc_mode;       /* play/record capability */
  178         struct mixerctl *sc_ctls;       /* mixer controls */
  179         int              sc_nctls;      /* # of mixer controls */
  180         struct device   *sc_audiodev;
  181         char             sc_dying;
  182 };
  183 
  184 struct terminal_list {
  185         int size;
  186         uint16_t terminals[1];
  187 };
  188 #define TERMINAL_LIST_SIZE(N)   (offsetof(struct terminal_list, terminals) \
  189                                 + sizeof(uint16_t) * (N))
  190 
  191 struct io_terminal {
  192         union {
  193                 const usb_descriptor_t *desc;
  194                 const struct usb_audio_input_terminal *it;
  195                 const struct usb_audio_output_terminal *ot;
  196                 const struct usb_audio_mixer_unit *mu;
  197                 const struct usb_audio_selector_unit *su;
  198                 const struct usb_audio_feature_unit *fu;
  199                 const struct usb_audio_processing_unit *pu;
  200                 const struct usb_audio_extension_unit *eu;
  201         } d;
  202         int inputs_size;
  203         struct terminal_list **inputs; /* list of source input terminals */
  204         struct terminal_list *output; /* list of destination output terminals */
  205         int direct;             /* directly connected to an output terminal */
  206 };
  207 
  208 #define UAC_OUTPUT      0
  209 #define UAC_INPUT       1
  210 #define UAC_EQUAL       2
  211 #define UAC_RECORD      3
  212 #define UAC_NCLASSES    4
  213 #ifdef UAUDIO_DEBUG
  214 const char *uac_names[] = {
  215         AudioCoutputs, AudioCinputs, AudioCequalization, AudioCrecord,
  216 };
  217 #endif
  218 
  219 usbd_status uaudio_identify_ac
  220         (struct uaudio_softc *, const usb_config_descriptor_t *);
  221 usbd_status uaudio_identify_as
  222         (struct uaudio_softc *, const usb_config_descriptor_t *);
  223 usbd_status uaudio_process_as
  224         (struct uaudio_softc *, const char *, int *, int,
  225          const usb_interface_descriptor_t *);
  226 
  227 void    uaudio_add_alt(struct uaudio_softc *, const struct as_info *);
  228 
  229 const usb_interface_descriptor_t *uaudio_find_iface
  230         (const char *, int, int *, int);
  231 
  232 void    uaudio_mixer_add_ctl(struct uaudio_softc *, struct mixerctl *);
  233 char    *uaudio_id_name
  234         (struct uaudio_softc *, const struct io_terminal *, int);
  235 struct usb_audio_cluster uaudio_get_cluster
  236         (int, const struct io_terminal *);
  237 void    uaudio_add_input
  238         (struct uaudio_softc *, const struct io_terminal *, int);
  239 void    uaudio_add_output
  240         (struct uaudio_softc *, const struct io_terminal *, int);
  241 void    uaudio_add_mixer
  242         (struct uaudio_softc *, const struct io_terminal *, int);
  243 void    uaudio_add_selector
  244         (struct uaudio_softc *, const struct io_terminal *, int);
  245 #ifdef UAUDIO_DEBUG
  246 const char *uaudio_get_terminal_name(int);
  247 #endif
  248 int     uaudio_determine_class
  249         (const struct io_terminal *, struct mixerctl *);
  250 const char *uaudio_feature_name
  251         (const struct io_terminal *, struct mixerctl *);
  252 void    uaudio_add_feature
  253         (struct uaudio_softc *, const struct io_terminal *, int);
  254 void    uaudio_add_processing_updown
  255         (struct uaudio_softc *, const struct io_terminal *, int);
  256 void    uaudio_add_processing
  257         (struct uaudio_softc *, const struct io_terminal *, int);
  258 void    uaudio_add_extension
  259         (struct uaudio_softc *, const struct io_terminal *, int);
  260 struct terminal_list *uaudio_merge_terminal_list
  261         (const struct io_terminal *);
  262 struct terminal_list *uaudio_io_terminaltype
  263         (int, struct io_terminal *, int);
  264 usbd_status uaudio_identify
  265         (struct uaudio_softc *, const usb_config_descriptor_t *);
  266 
  267 int     uaudio_signext(int, int);
  268 int     uaudio_value2bsd(struct mixerctl *, int);
  269 int     uaudio_bsd2value(struct mixerctl *, int);
  270 int     uaudio_get(struct uaudio_softc *, int, int, int, int, int);
  271 int     uaudio_ctl_get
  272         (struct uaudio_softc *, int, struct mixerctl *, int);
  273 void    uaudio_set
  274         (struct uaudio_softc *, int, int, int, int, int, int);
  275 void    uaudio_ctl_set
  276         (struct uaudio_softc *, int, struct mixerctl *, int, int);
  277 
  278 usbd_status uaudio_set_speed(struct uaudio_softc *, int, u_int);
  279 
  280 usbd_status uaudio_chan_open(struct uaudio_softc *, struct chan *);
  281 void    uaudio_chan_close(struct uaudio_softc *, struct chan *);
  282 usbd_status uaudio_chan_alloc_buffers
  283         (struct uaudio_softc *, struct chan *);
  284 void    uaudio_chan_free_buffers(struct uaudio_softc *, struct chan *);
  285 void    uaudio_chan_init
  286         (struct chan *, int, const struct audio_params *, int);
  287 void    uaudio_chan_set_param(struct chan *, u_char *, u_char *, int);
  288 void    uaudio_chan_ptransfer(struct chan *);
  289 void    uaudio_chan_pintr
  290         (usbd_xfer_handle, usbd_private_handle, usbd_status);
  291 
  292 void    uaudio_chan_rtransfer(struct chan *);
  293 void    uaudio_chan_rintr
  294         (usbd_xfer_handle, usbd_private_handle, usbd_status);
  295 
  296 int     uaudio_open(void *, int);
  297 void    uaudio_close(void *);
  298 int     uaudio_drain(void *);
  299 int     uaudio_query_encoding(void *, struct audio_encoding *);
  300 void    uaudio_get_minmax_rates
  301         (int, const struct as_info *, const struct audio_params *,
  302          int, u_long *, u_long *);
  303 int     uaudio_match_alt_sub
  304         (int, const struct as_info *, const struct audio_params *, int, u_long);
  305 int     uaudio_match_alt_chan
  306         (int, const struct as_info *, struct audio_params *, int);
  307 int     uaudio_match_alt
  308         (int, const struct as_info *, struct audio_params *, int);
  309 int     uaudio_set_params
  310         (void *, int, int, struct audio_params *, struct audio_params *);
  311 int     uaudio_round_blocksize(void *, int);
  312 int     uaudio_trigger_output
  313         (void *, void *, void *, int, void (*)(void *), void *,
  314          struct audio_params *);
  315 int     uaudio_trigger_input
  316         (void *, void *, void *, int, void (*)(void *), void *,
  317          struct audio_params *);
  318 int     uaudio_halt_in_dma(void *);
  319 int     uaudio_halt_out_dma(void *);
  320 int     uaudio_getdev(void *, struct audio_device *);
  321 int     uaudio_mixer_set_port(void *, mixer_ctrl_t *);
  322 int     uaudio_mixer_get_port(void *, mixer_ctrl_t *);
  323 int     uaudio_query_devinfo(void *, mixer_devinfo_t *);
  324 int     uaudio_get_props(void *);
  325 
  326 struct audio_hw_if uaudio_hw_if = {
  327         uaudio_open,
  328         uaudio_close,
  329         uaudio_drain,
  330         uaudio_query_encoding,
  331         uaudio_set_params,
  332         uaudio_round_blocksize,
  333         NULL,
  334         NULL,
  335         NULL,
  336         NULL,
  337         NULL,
  338         uaudio_halt_out_dma,
  339         uaudio_halt_in_dma,
  340         NULL,
  341         uaudio_getdev,
  342         NULL,
  343         uaudio_mixer_set_port,
  344         uaudio_mixer_get_port,
  345         uaudio_query_devinfo,
  346         NULL,
  347         NULL,
  348         NULL,
  349         NULL,
  350         uaudio_get_props,
  351         uaudio_trigger_output,
  352         uaudio_trigger_input,
  353 };
  354 
  355 struct audio_device uaudio_device = {
  356         "USB audio",
  357         "",
  358         "uaudio"
  359 };
  360 
  361 int uaudio_match(struct device *, void *, void *); 
  362 void uaudio_attach(struct device *, struct device *, void *); 
  363 int uaudio_detach(struct device *, int); 
  364 int uaudio_activate(struct device *, enum devact); 
  365 
  366 struct cfdriver uaudio_cd = { 
  367         NULL, "uaudio", DV_DULL 
  368 }; 
  369 
  370 const struct cfattach uaudio_ca = { 
  371         sizeof(struct uaudio_softc), 
  372         uaudio_match, 
  373         uaudio_attach, 
  374         uaudio_detach, 
  375         uaudio_activate, 
  376 };
  377 
  378 int
  379 uaudio_match(struct device *parent, void *match, void *aux)
  380 {
  381         struct usb_attach_arg *uaa = aux;
  382         usb_interface_descriptor_t *id;
  383 
  384         if (uaa->iface == NULL)
  385                 return (UMATCH_NONE);
  386 
  387         id = usbd_get_interface_descriptor(uaa->iface);
  388         /* Trigger on the control interface. */
  389         if (id == NULL ||
  390             id->bInterfaceClass != UICLASS_AUDIO ||
  391             id->bInterfaceSubClass != UISUBCLASS_AUDIOCONTROL ||
  392             (usbd_get_quirks(uaa->device)->uq_flags & UQ_BAD_AUDIO))
  393                 return (UMATCH_NONE);
  394 
  395         return (UMATCH_IFACECLASS_IFACESUBCLASS);
  396 }
  397 
  398 void
  399 uaudio_attach(struct device *parent, struct device *self, void *aux)
  400 {
  401         struct uaudio_softc *sc = (struct uaudio_softc *)self;
  402         struct usb_attach_arg *uaa = aux;
  403         usb_interface_descriptor_t *id;
  404         usb_config_descriptor_t *cdesc;
  405         char *devinfop;
  406         usbd_status err;
  407         int i, j, found;
  408 
  409         devinfop = usbd_devinfo_alloc(uaa->device, 0);
  410         printf(": %s\n", devinfop);
  411         usbd_devinfo_free(devinfop);
  412 
  413         sc->sc_udev = uaa->device;
  414 
  415         cdesc = usbd_get_config_descriptor(sc->sc_udev);
  416         if (cdesc == NULL) {
  417                 printf("%s: failed to get configuration descriptor\n",
  418                        sc->sc_dev.dv_xname);
  419                 return;
  420         }
  421 
  422         err = uaudio_identify(sc, cdesc);
  423         if (err) {
  424                 printf("%s: audio descriptors make no sense, error=%d\n",
  425                        sc->sc_dev.dv_xname, err);
  426                 return;
  427         }
  428 
  429         sc->sc_ac_ifaceh = uaa->iface;
  430         /* Pick up the AS interface. */
  431         for (i = 0; i < uaa->nifaces; i++) {
  432                 if (uaa->ifaces[i] == NULL)
  433                         continue;
  434                 id = usbd_get_interface_descriptor(uaa->ifaces[i]);
  435                 if (id == NULL)
  436                         continue;
  437                 found = 0;
  438                 for (j = 0; j < sc->sc_nalts; j++) {
  439                         if (id->bInterfaceNumber ==
  440                             sc->sc_alts[j].idesc->bInterfaceNumber) {
  441                                 sc->sc_alts[j].ifaceh = uaa->ifaces[i];
  442                                 found = 1;
  443                         }
  444                 }
  445                 if (found)
  446                         uaa->ifaces[i] = NULL;
  447         }
  448 
  449         for (j = 0; j < sc->sc_nalts; j++) {
  450                 if (sc->sc_alts[j].ifaceh == NULL) {
  451                         printf("%s: alt %d missing AS interface(s)\n",
  452                             sc->sc_dev.dv_xname, j);
  453                         return;
  454                 }
  455         }
  456 
  457         printf("%s: audio rev %d.%02x", sc->sc_dev.dv_xname,
  458                sc->sc_audio_rev >> 8, sc->sc_audio_rev & 0xff);
  459 
  460         sc->sc_playchan.sc = sc->sc_recchan.sc = sc;
  461         sc->sc_playchan.altidx = -1;
  462         sc->sc_recchan.altidx = -1;
  463 
  464         if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_FRAC)
  465                 sc->sc_altflags |= UA_NOFRAC;
  466 
  467         printf(", %d mixer controls\n", sc->sc_nctls);
  468 
  469         usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
  470                            &sc->sc_dev);
  471 
  472         DPRINTF(("uaudio_attach: doing audio_attach_mi\n"));
  473         sc->sc_audiodev = audio_attach_mi(&uaudio_hw_if, sc, &sc->sc_dev);
  474 }
  475 
  476 /*
  477  * Macros to help sync OpenBSD to NetBSD
  478  */
  479 #define hw_channels channels
  480 #define hw_sample_rate sample_rate
  481 #define hw_precision precision
  482 #define hw_encoding encoding
  483 
  484 int
  485 uaudio_activate(struct device *self, enum devact act)
  486 {
  487         struct uaudio_softc *sc = (struct uaudio_softc *)self;
  488         int rv = 0;
  489 
  490         switch (act) {
  491         case DVACT_ACTIVATE:
  492                 break;
  493         case DVACT_DEACTIVATE:
  494                 if (sc->sc_audiodev != NULL)
  495                         rv = config_deactivate(sc->sc_audiodev);
  496                 sc->sc_dying = 1;
  497                 break;
  498         }
  499         return (rv);
  500 }
  501 
  502 int
  503 uaudio_detach(struct device *self, int flags)
  504 {
  505         struct uaudio_softc *sc = (struct uaudio_softc *)self;
  506         int rv = 0;
  507 
  508         /* Wait for outstanding requests to complete. */
  509         usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
  510 
  511         if (sc->sc_audiodev != NULL)
  512                 rv = config_detach(sc->sc_audiodev, flags);
  513 
  514         usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
  515                            &sc->sc_dev);
  516 
  517         return (rv);
  518 }
  519 
  520 int
  521 uaudio_query_encoding(void *addr, struct audio_encoding *fp)
  522 {
  523         struct uaudio_softc *sc = addr;
  524         int flags = sc->sc_altflags;
  525         int idx;
  526 
  527         if (sc->sc_dying)
  528                 return (EIO);
  529 
  530         if (sc->sc_nalts == 0 || flags == 0)
  531                 return (ENXIO);
  532 
  533         idx = fp->index;
  534         switch (idx) {
  535         case 0:
  536                 strlcpy(fp->name, AudioEulinear, sizeof(fp->name));
  537                 fp->encoding = AUDIO_ENCODING_ULINEAR;
  538                 fp->precision = 8;
  539                 fp->flags = flags&HAS_8U ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
  540                 return (0);
  541         case 1:
  542                 strlcpy(fp->name, AudioEmulaw, sizeof(fp->name));
  543                 fp->encoding = AUDIO_ENCODING_ULAW;
  544                 fp->precision = 8;
  545                 fp->flags = flags&HAS_MULAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
  546                 return (0);
  547         case 2:
  548                 strlcpy(fp->name, AudioEalaw, sizeof(fp->name));
  549                 fp->encoding = AUDIO_ENCODING_ALAW;
  550                 fp->precision = 8;
  551                 fp->flags = flags&HAS_ALAW ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
  552                 return (0);
  553         case 3:
  554                 strlcpy(fp->name, AudioEslinear, sizeof(fp->name));
  555                 fp->encoding = AUDIO_ENCODING_SLINEAR;
  556                 fp->precision = 8;
  557                 fp->flags = flags&HAS_8 ? 0 : AUDIO_ENCODINGFLAG_EMULATED;
  558                 return (0);
  559         case 4:
  560                 strlcpy(fp->name, AudioEslinear_le, sizeof(fp->name));
  561                 fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
  562                 fp->precision = 16;
  563                 fp->flags = 0;
  564                 return (0);
  565         case 5:
  566                 strlcpy(fp->name, AudioEulinear_le, sizeof(fp->name));
  567                 fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
  568                 fp->precision = 16;
  569                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  570                 return (0);
  571         case 6:
  572                 strlcpy(fp->name, AudioEslinear_be, sizeof(fp->name));
  573                 fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
  574                 fp->precision = 16;
  575                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  576                 return (0);
  577         case 7:
  578                 strlcpy(fp->name, AudioEulinear_be, sizeof(fp->name));
  579                 fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
  580                 fp->precision = 16;
  581                 fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
  582                 return (0);
  583         default:
  584                 return (EINVAL);
  585         }
  586 }
  587 
  588 const usb_interface_descriptor_t *
  589 uaudio_find_iface(const char *buf, int size, int *offsp, int subtype)
  590 {
  591         const usb_interface_descriptor_t *d;
  592 
  593         while (*offsp < size) {
  594                 d = (const void *)(buf + *offsp);
  595                 *offsp += d->bLength;
  596                 if (d->bDescriptorType == UDESC_INTERFACE &&
  597                     d->bInterfaceClass == UICLASS_AUDIO &&
  598                     d->bInterfaceSubClass == subtype)
  599                         return (d);
  600         }
  601         return (NULL);
  602 }
  603 
  604 void
  605 uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct mixerctl *mc)
  606 {
  607         int res;
  608         size_t len;
  609         struct mixerctl *nmc;
  610 
  611         if (mc->class < UAC_NCLASSES) {
  612                 DPRINTF(("%s: adding %s.%s\n",
  613                          __func__, uac_names[mc->class], mc->ctlname));
  614         } else {
  615                 DPRINTF(("%s: adding %s\n", __func__, mc->ctlname));
  616         }
  617         len = sizeof(*mc) * (sc->sc_nctls + 1);
  618         nmc = malloc(len, M_USBDEV, M_NOWAIT);
  619         if (nmc == NULL) {
  620                 printf("uaudio_mixer_add_ctl: no memory\n");
  621                 return;
  622         }
  623         /* Copy old data, if there was any */
  624         if (sc->sc_nctls != 0) {
  625                 bcopy(sc->sc_ctls, nmc, sizeof(*mc) * (sc->sc_nctls));
  626                 free(sc->sc_ctls, M_USBDEV);
  627         }
  628         sc->sc_ctls = nmc;
  629 
  630         mc->delta = 0;
  631         if (mc->type == MIX_ON_OFF) {
  632                 mc->minval = 0;
  633                 mc->maxval = 1;
  634         } else if (mc->type == MIX_SELECTOR) {
  635                 ;
  636         } else {
  637                 /* Determine min and max values. */
  638                 mc->minval = uaudio_signext(mc->type,
  639                         uaudio_get(sc, GET_MIN, UT_READ_CLASS_INTERFACE,
  640                                    mc->wValue[0], mc->wIndex,
  641                                    MIX_SIZE(mc->type)));
  642                 mc->maxval = 1 + uaudio_signext(mc->type,
  643                         uaudio_get(sc, GET_MAX, UT_READ_CLASS_INTERFACE,
  644                                    mc->wValue[0], mc->wIndex,
  645                                    MIX_SIZE(mc->type)));
  646                 mc->mul = mc->maxval - mc->minval;
  647                 if (mc->mul == 0)
  648                         mc->mul = 1;
  649                 res = uaudio_get(sc, GET_RES, UT_READ_CLASS_INTERFACE,
  650                                  mc->wValue[0], mc->wIndex,
  651                                  MIX_SIZE(mc->type));
  652                 if (res > 0)
  653                         mc->delta = (res * 255 + mc->mul/2) / mc->mul;
  654         }
  655 
  656         sc->sc_ctls[sc->sc_nctls++] = *mc;
  657 
  658 #ifdef UAUDIO_DEBUG
  659         if (uaudiodebug > 2) {
  660                 int i;
  661                 DPRINTF(("uaudio_mixer_add_ctl: wValue=%04x",mc->wValue[0]));
  662                 for (i = 1; i < mc->nchan; i++)
  663                         DPRINTF((",%04x", mc->wValue[i]));
  664                 DPRINTF((" wIndex=%04x type=%d name='%s' unit='%s' "
  665                          "min=%d max=%d\n",
  666                          mc->wIndex, mc->type, mc->ctlname, mc->ctlunit,
  667                          mc->minval, mc->maxval));
  668         }
  669 #endif
  670 }
  671 
  672 char *
  673 uaudio_id_name(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
  674 {
  675         static char buf[32];
  676         snprintf(buf, sizeof(buf), "i%d", id);
  677         return (buf);
  678 }
  679 
  680 struct usb_audio_cluster
  681 uaudio_get_cluster(int id, const struct io_terminal *iot)
  682 {
  683         struct usb_audio_cluster r;
  684         const usb_descriptor_t *dp;
  685         int i;
  686 
  687         for (i = 0; i < 25; i++) { /* avoid infinite loops */
  688                 dp = iot[id].d.desc;
  689                 if (dp == 0)
  690                         goto bad;
  691                 switch (dp->bDescriptorSubtype) {
  692                 case UDESCSUB_AC_INPUT:
  693                         r.bNrChannels = iot[id].d.it->bNrChannels;
  694                         USETW(r.wChannelConfig, UGETW(iot[id].d.it->wChannelConfig));
  695                         r.iChannelNames = iot[id].d.it->iChannelNames;
  696                         return (r);
  697                 case UDESCSUB_AC_OUTPUT:
  698                         id = iot[id].d.ot->bSourceId;
  699                         break;
  700                 case UDESCSUB_AC_MIXER:
  701                         r = *(struct usb_audio_cluster *)
  702                                 &iot[id].d.mu->baSourceId[iot[id].d.mu->bNrInPins];
  703                         return (r);
  704                 case UDESCSUB_AC_SELECTOR:
  705                         /* XXX This is not really right */
  706                         id = iot[id].d.su->baSourceId[0];
  707                         break;
  708                 case UDESCSUB_AC_FEATURE:
  709                         id = iot[id].d.fu->bSourceId;
  710                         break;
  711                 case UDESCSUB_AC_PROCESSING:
  712                         r = *(struct usb_audio_cluster *)
  713                                 &iot[id].d.pu->baSourceId[iot[id].d.pu->bNrInPins];
  714                         return (r);
  715                 case UDESCSUB_AC_EXTENSION:
  716                         r = *(struct usb_audio_cluster *)
  717                                 &iot[id].d.eu->baSourceId[iot[id].d.eu->bNrInPins];
  718                         return (r);
  719                 default:
  720                         goto bad;
  721                 }
  722         }
  723  bad:
  724         printf("uaudio_get_cluster: bad data\n");
  725         memset(&r, 0, sizeof r);
  726         return (r);
  727 
  728 }
  729 
  730 void
  731 uaudio_add_input(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
  732 {
  733 #ifdef UAUDIO_DEBUG
  734         const struct usb_audio_input_terminal *d = iot[id].d.it;
  735 
  736         DPRINTFN(2,("uaudio_add_input: bTerminalId=%d wTerminalType=0x%04x "
  737                     "bAssocTerminal=%d bNrChannels=%d wChannelConfig=%d "
  738                     "iChannelNames=%d iTerminal=%d\n",
  739                     d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
  740                     d->bNrChannels, UGETW(d->wChannelConfig),
  741                     d->iChannelNames, d->iTerminal));
  742 #endif
  743 }
  744 
  745 void
  746 uaudio_add_output(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
  747 {
  748 #ifdef UAUDIO_DEBUG
  749         const struct usb_audio_output_terminal *d = iot[id].d.ot;
  750 
  751         DPRINTFN(2,("uaudio_add_output: bTerminalId=%d wTerminalType=0x%04x "
  752                     "bAssocTerminal=%d bSourceId=%d iTerminal=%d\n",
  753                     d->bTerminalId, UGETW(d->wTerminalType), d->bAssocTerminal,
  754                     d->bSourceId, d->iTerminal));
  755 #endif
  756 }
  757 
  758 void
  759 uaudio_add_mixer(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
  760 {
  761         const struct usb_audio_mixer_unit *d = iot[id].d.mu;
  762         struct usb_audio_mixer_unit_1 *d1;
  763         int c, chs, ichs, ochs, i, o, bno, p, mo, mc, k;
  764         uByte *bm;
  765         struct mixerctl mix;
  766 
  767         DPRINTFN(2,("uaudio_add_mixer: bUnitId=%d bNrInPins=%d\n",
  768                     d->bUnitId, d->bNrInPins));
  769 
  770         /* Compute the number of input channels */
  771         ichs = 0;
  772         for (i = 0; i < d->bNrInPins; i++)
  773                 ichs += uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels;
  774 
  775         /* and the number of output channels */
  776         d1 = (struct usb_audio_mixer_unit_1 *)&d->baSourceId[d->bNrInPins];
  777         ochs = d1->bNrChannels;
  778         DPRINTFN(2,("uaudio_add_mixer: ichs=%d ochs=%d\n", ichs, ochs));
  779 
  780         bm = d1->bmControls;
  781         mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
  782         uaudio_determine_class(&iot[id], &mix);
  783         mix.type = MIX_SIGNED_16;
  784         mix.ctlunit = AudioNvolume;
  785 #define BIT(bno) ((bm[bno / 8] >> (7 - bno % 8)) & 1)
  786         for (p = i = 0; i < d->bNrInPins; i++) {
  787                 chs = uaudio_get_cluster(d->baSourceId[i], iot).bNrChannels;
  788                 mc = 0;
  789                 for (c = 0; c < chs; c++) {
  790                         mo = 0;
  791                         for (o = 0; o < ochs; o++) {
  792                                 bno = (p + c) * ochs + o;
  793                                 if (BIT(bno))
  794                                         mo++;
  795                         }
  796                         if (mo == 1)
  797                                 mc++;
  798                 }
  799                 if (mc == chs && chs <= MIX_MAX_CHAN) {
  800                         k = 0;
  801                         for (c = 0; c < chs; c++)
  802                                 for (o = 0; o < ochs; o++) {
  803                                         bno = (p + c) * ochs + o;
  804                                         if (BIT(bno))
  805                                                 mix.wValue[k++] =
  806                                                         MAKE(p+c+1, o+1);
  807                                 }
  808                         snprintf(mix.ctlname, sizeof(mix.ctlname), "mix%d-%s",
  809                             d->bUnitId, uaudio_id_name(sc, iot,
  810                             d->baSourceId[i]));
  811                         mix.nchan = chs;
  812                         uaudio_mixer_add_ctl(sc, &mix);
  813                 } else {
  814                         /* XXX */
  815                 }
  816 #undef BIT
  817                 p += chs;
  818         }
  819 
  820 }
  821 
  822 void
  823 uaudio_add_selector(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
  824 {
  825         const struct usb_audio_selector_unit *d = iot[id].d.su;
  826         struct mixerctl mix;
  827         int i, wp;
  828 
  829         DPRINTFN(2,("uaudio_add_selector: bUnitId=%d bNrInPins=%d\n",
  830                     d->bUnitId, d->bNrInPins));
  831         mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
  832         mix.wValue[0] = MAKE(0, 0);
  833         uaudio_determine_class(&iot[id], &mix);
  834         mix.nchan = 1;
  835         mix.type = MIX_SELECTOR;
  836         mix.ctlunit = "";
  837         mix.minval = 1;
  838         mix.maxval = d->bNrInPins;
  839         mix.mul = mix.maxval - mix.minval;
  840         wp = snprintf(mix.ctlname, MAX_AUDIO_DEV_LEN, "sel%d-", d->bUnitId);
  841         for (i = 1; i <= d->bNrInPins; i++) {
  842                 wp += snprintf(mix.ctlname + wp, MAX_AUDIO_DEV_LEN - wp,
  843                                "i%d", d->baSourceId[i - 1]);
  844                 if (wp > MAX_AUDIO_DEV_LEN - 1)
  845                         break;
  846         }
  847         uaudio_mixer_add_ctl(sc, &mix);
  848 }
  849 
  850 #ifdef UAUDIO_DEBUG
  851 const char *
  852 uaudio_get_terminal_name(int terminal_type)
  853 {
  854         static char buf[100];
  855 
  856         switch (terminal_type) {
  857         /* USB terminal types */
  858         case UAT_UNDEFINED:     return "UAT_UNDEFINED";
  859         case UAT_STREAM:        return "UAT_STREAM";
  860         case UAT_VENDOR:        return "UAT_VENDOR";
  861         /* input terminal types */
  862         case UATI_UNDEFINED:    return "UATI_UNDEFINED";
  863         case UATI_MICROPHONE:   return "UATI_MICROPHONE";
  864         case UATI_DESKMICROPHONE:       return "UATI_DESKMICROPHONE";
  865         case UATI_PERSONALMICROPHONE:   return "UATI_PERSONALMICROPHONE";
  866         case UATI_OMNIMICROPHONE:       return "UATI_OMNIMICROPHONE";
  867         case UATI_MICROPHONEARRAY:      return "UATI_MICROPHONEARRAY";
  868         case UATI_PROCMICROPHONEARR:    return "UATI_PROCMICROPHONEARR";
  869         /* output terminal types */
  870         case UATO_UNDEFINED:    return "UATO_UNDEFINED";
  871         case UATO_SPEAKER:      return "UATO_SPEAKER";
  872         case UATO_HEADPHONES:   return "UATO_HEADPHONES";
  873         case UATO_DISPLAYAUDIO: return "UATO_DISPLAYAUDIO";
  874         case UATO_DESKTOPSPEAKER:       return "UATO_DESKTOPSPEAKER";
  875         case UATO_ROOMSPEAKER:  return "UATO_ROOMSPEAKER";
  876         case UATO_COMMSPEAKER:  return "UATO_COMMSPEAKER";
  877         case UATO_SUBWOOFER:    return "UATO_SUBWOOFER";
  878         /* bidir terminal types */
  879         case UATB_UNDEFINED:    return "UATB_UNDEFINED";
  880         case UATB_HANDSET:      return "UATB_HANDSET";
  881         case UATB_HEADSET:      return "UATB_HEADSET";
  882         case UATB_SPEAKERPHONE: return "UATB_SPEAKERPHONE";
  883         case UATB_SPEAKERPHONEESUP:     return "UATB_SPEAKERPHONEESUP";
  884         case UATB_SPEAKERPHONEECANC:    return "UATB_SPEAKERPHONEECANC";
  885         /* telephony terminal types */
  886         case UATT_UNDEFINED:    return "UATT_UNDEFINED";
  887         case UATT_PHONELINE:    return "UATT_PHONELINE";
  888         case UATT_TELEPHONE:    return "UATT_TELEPHONE";
  889         case UATT_DOWNLINEPHONE:        return "UATT_DOWNLINEPHONE";
  890         /* external terminal types */
  891         case UATE_UNDEFINED:    return "UATE_UNDEFINED";
  892         case UATE_ANALOGCONN:   return "UATE_ANALOGCONN";
  893         case UATE_LINECONN:     return "UATE_LINECONN";
  894         case UATE_LEGACYCONN:   return "UATE_LEGACYCONN";
  895         case UATE_DIGITALAUIFC: return "UATE_DIGITALAUIFC";
  896         case UATE_SPDIF:        return "UATE_SPDIF";
  897         case UATE_1394DA:       return "UATE_1394DA";
  898         case UATE_1394DV:       return "UATE_1394DV";
  899         /* embedded function terminal types */
  900         case UATF_UNDEFINED:    return "UATF_UNDEFINED";
  901         case UATF_CALIBNOISE:   return "UATF_CALIBNOISE";
  902         case UATF_EQUNOISE:     return "UATF_EQUNOISE";
  903         case UATF_CDPLAYER:     return "UATF_CDPLAYER";
  904         case UATF_DAT:  return "UATF_DAT";
  905         case UATF_DCC:  return "UATF_DCC";
  906         case UATF_MINIDISK:     return "UATF_MINIDISK";
  907         case UATF_ANALOGTAPE:   return "UATF_ANALOGTAPE";
  908         case UATF_PHONOGRAPH:   return "UATF_PHONOGRAPH";
  909         case UATF_VCRAUDIO:     return "UATF_VCRAUDIO";
  910         case UATF_VIDEODISCAUDIO:       return "UATF_VIDEODISCAUDIO";
  911         case UATF_DVDAUDIO:     return "UATF_DVDAUDIO";
  912         case UATF_TVTUNERAUDIO: return "UATF_TVTUNERAUDIO";
  913         case UATF_SATELLITE:    return "UATF_SATELLITE";
  914         case UATF_CABLETUNER:   return "UATF_CABLETUNER";
  915         case UATF_DSS:  return "UATF_DSS";
  916         case UATF_RADIORECV:    return "UATF_RADIORECV";
  917         case UATF_RADIOXMIT:    return "UATF_RADIOXMIT";
  918         case UATF_MULTITRACK:   return "UATF_MULTITRACK";
  919         case UATF_SYNTHESIZER:  return "UATF_SYNTHESIZER";
  920         default:
  921                 snprintf(buf, sizeof(buf), "unknown type (0x%.4x)", terminal_type);
  922                 return buf;
  923         }
  924 }
  925 #endif
  926 
  927 int
  928 uaudio_determine_class(const struct io_terminal *iot, struct mixerctl *mix)
  929 {
  930         int terminal_type;
  931 
  932         if (iot == NULL || iot->output == NULL) {
  933                 mix->class = UAC_OUTPUT;
  934                 return 0;
  935         }
  936         terminal_type = 0;
  937         if (iot->output->size == 1)
  938                 terminal_type = iot->output->terminals[0];
  939         /*
  940          * If the only output terminal is USB,
  941          * the class is UAC_RECORD.
  942          */
  943         if ((terminal_type & 0xff00) == (UAT_UNDEFINED & 0xff00)) {
  944                 mix->class = UAC_RECORD;
  945                 if (iot->inputs_size == 1
  946                     && iot->inputs[0] != NULL
  947                     && iot->inputs[0]->size == 1)
  948                         return iot->inputs[0]->terminals[0];
  949                 else
  950                         return 0;
  951         }
  952         /*
  953          * If the ultimate destination of the unit is just one output
  954          * terminal and the unit is connected to the output terminal
  955          * directly, the class is UAC_OUTPUT.
  956          */
  957         if (terminal_type != 0 && iot->direct) {
  958                 mix->class = UAC_OUTPUT;
  959                 return terminal_type;
  960         }
  961         /*
  962          * If the unit is connected to just one input terminal,
  963          * the class is UAC_INPUT.
  964          */
  965         if (iot->inputs_size == 1 && iot->inputs[0] != NULL
  966             && iot->inputs[0]->size == 1) {
  967                 mix->class = UAC_INPUT;
  968                 return iot->inputs[0]->terminals[0];
  969         }
  970         /*
  971          * Otherwise, the class is UAC_OUTPUT.
  972          */
  973         mix->class = UAC_OUTPUT;
  974         return terminal_type;
  975 }
  976 
  977 const char *
  978 uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix)
  979 {
  980         int terminal_type;
  981 
  982         terminal_type = uaudio_determine_class(iot, mix);
  983         if (mix->class == UAC_RECORD && terminal_type == 0)
  984                 return AudioNmixerout;
  985         DPRINTF(("%s: terminal_type=%s\n", __func__,
  986                  uaudio_get_terminal_name(terminal_type)));
  987         switch (terminal_type) {
  988         case UAT_STREAM:
  989                 return AudioNdac;
  990 
  991         case UATI_MICROPHONE:
  992         case UATI_DESKMICROPHONE:
  993         case UATI_PERSONALMICROPHONE:
  994         case UATI_OMNIMICROPHONE:
  995         case UATI_MICROPHONEARRAY:
  996         case UATI_PROCMICROPHONEARR:
  997                 return AudioNmicrophone;
  998 
  999         case UATO_SPEAKER:
 1000         case UATO_DESKTOPSPEAKER:
 1001         case UATO_ROOMSPEAKER:
 1002         case UATO_COMMSPEAKER:
 1003                 return AudioNspeaker;
 1004 
 1005         case UATO_HEADPHONES:
 1006                 return AudioNheadphone;
 1007 
 1008         case UATO_SUBWOOFER:
 1009                 return AudioNlfe;
 1010 
 1011         /* telephony terminal types */
 1012         case UATT_UNDEFINED:
 1013         case UATT_PHONELINE:
 1014         case UATT_TELEPHONE:
 1015         case UATT_DOWNLINEPHONE:
 1016                 return "phone";
 1017 
 1018         case UATE_ANALOGCONN:
 1019         case UATE_LINECONN:
 1020         case UATE_LEGACYCONN:
 1021                 return AudioNline;
 1022 
 1023         case UATE_DIGITALAUIFC:
 1024         case UATE_SPDIF:
 1025         case UATE_1394DA:
 1026         case UATE_1394DV:
 1027                 return AudioNaux;
 1028 
 1029         case UATF_CDPLAYER:
 1030                 return AudioNcd;
 1031 
 1032         case UATF_SYNTHESIZER:
 1033                 return AudioNfmsynth;
 1034 
 1035         case UATF_VIDEODISCAUDIO:
 1036         case UATF_DVDAUDIO:
 1037         case UATF_TVTUNERAUDIO:
 1038                 return AudioNvideo;
 1039 
 1040         case UAT_UNDEFINED:
 1041         case UAT_VENDOR:
 1042         case UATI_UNDEFINED:
 1043 /* output terminal types */
 1044         case UATO_UNDEFINED:
 1045         case UATO_DISPLAYAUDIO:
 1046 /* bidir terminal types */
 1047         case UATB_UNDEFINED:
 1048         case UATB_HANDSET:
 1049         case UATB_HEADSET:
 1050         case UATB_SPEAKERPHONE:
 1051         case UATB_SPEAKERPHONEESUP:
 1052         case UATB_SPEAKERPHONEECANC:
 1053 /* external terminal types */
 1054         case UATE_UNDEFINED:
 1055 /* embedded function terminal types */
 1056         case UATF_UNDEFINED:
 1057         case UATF_CALIBNOISE:
 1058         case UATF_EQUNOISE:
 1059         case UATF_DAT:
 1060         case UATF_DCC:
 1061         case UATF_MINIDISK:
 1062         case UATF_ANALOGTAPE:
 1063         case UATF_PHONOGRAPH:
 1064         case UATF_VCRAUDIO:
 1065         case UATF_SATELLITE:
 1066         case UATF_CABLETUNER:
 1067         case UATF_DSS:
 1068         case UATF_RADIORECV:
 1069         case UATF_RADIOXMIT:
 1070         case UATF_MULTITRACK:
 1071         case 0xffff:
 1072         default:
 1073                 DPRINTF(("%s: 'master' for 0x%.4x\n", __func__, terminal_type));
 1074                 return AudioNmaster;
 1075         }
 1076 }
 1077 
 1078 void
 1079 uaudio_add_feature(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
 1080 {
 1081         const struct usb_audio_feature_unit *d = iot[id].d.fu;
 1082         uByte *ctls = d->bmaControls;
 1083         int ctlsize = d->bControlSize;
 1084         int nchan = (d->bLength - 7) / ctlsize;
 1085         u_int fumask, mmask, cmask;
 1086         struct mixerctl mix;
 1087         int chan, ctl, i, unit;
 1088         const char *mixername;
 1089 
 1090 #define GET(i) (ctls[(i)*ctlsize] | \
 1091                 (ctlsize > 1 ? ctls[(i)*ctlsize+1] << 8 : 0))
 1092 
 1093         mmask = GET(0);
 1094         /* Figure out what we can control */
 1095         for (cmask = 0, chan = 1; chan < nchan; chan++) {
 1096                 DPRINTFN(9,("uaudio_add_feature: chan=%d mask=%x\n",
 1097                             chan, GET(chan)));
 1098                 cmask |= GET(chan);
 1099         }
 1100 
 1101         DPRINTFN(1,("uaudio_add_feature: bUnitId=%d, "
 1102                     "%d channels, mmask=0x%04x, cmask=0x%04x\n",
 1103                     d->bUnitId, nchan, mmask, cmask));
 1104 
 1105         if (nchan > MIX_MAX_CHAN)
 1106                 nchan = MIX_MAX_CHAN;
 1107         unit = d->bUnitId;
 1108         mix.wIndex = MAKE(unit, sc->sc_ac_iface);
 1109         for (ctl = MUTE_CONTROL; ctl < LOUDNESS_CONTROL; ctl++) {
 1110                 fumask = FU_MASK(ctl);
 1111                 DPRINTFN(4,("uaudio_add_feature: ctl=%d fumask=0x%04x\n",
 1112                             ctl, fumask));
 1113                 if (mmask & fumask) {
 1114                         mix.nchan = 1;
 1115                         mix.wValue[0] = MAKE(ctl, 0);
 1116                 } else if (cmask & fumask) {
 1117                         mix.nchan = nchan - 1;
 1118                         for (i = 1; i < nchan; i++) {
 1119                                 if (GET(i) & fumask)
 1120                                         mix.wValue[i-1] = MAKE(ctl, i);
 1121                                 else
 1122                                         mix.wValue[i-1] = -1;
 1123                         }
 1124                 } else {
 1125                         continue;
 1126                 }
 1127 #undef GET
 1128                 mixername = uaudio_feature_name(&iot[id], &mix);
 1129                 switch (ctl) {
 1130                 case MUTE_CONTROL:
 1131                         mix.type = MIX_ON_OFF;
 1132                         mix.ctlunit = "";
 1133                         snprintf(mix.ctlname, sizeof(mix.ctlname),
 1134                                  "%s.%s", mixername, AudioNmute);
 1135                         break;
 1136                 case VOLUME_CONTROL:
 1137                         mix.type = MIX_SIGNED_16;
 1138                         mix.ctlunit = AudioNvolume;
 1139                         strlcpy(mix.ctlname, mixername, sizeof(mix.ctlname));
 1140                         break;
 1141                 case BASS_CONTROL:
 1142                         mix.type = MIX_SIGNED_8;
 1143                         mix.ctlunit = AudioNbass;
 1144                         snprintf(mix.ctlname, sizeof(mix.ctlname),
 1145                                  "%s.%s", mixername, AudioNbass);
 1146                         break;
 1147                 case MID_CONTROL:
 1148                         mix.type = MIX_SIGNED_8;
 1149                         mix.ctlunit = AudioNmid;
 1150                         snprintf(mix.ctlname, sizeof(mix.ctlname),
 1151                                  "%s.%s", mixername, AudioNmid);
 1152                         break;
 1153                 case TREBLE_CONTROL:
 1154                         mix.type = MIX_SIGNED_8;
 1155                         mix.ctlunit = AudioNtreble;
 1156                         snprintf(mix.ctlname, sizeof(mix.ctlname),
 1157                                  "%s.%s", mixername, AudioNtreble);
 1158                         break;
 1159                 case GRAPHIC_EQUALIZER_CONTROL:
 1160                         continue; /* XXX don't add anything */
 1161                         break;
 1162                 case AGC_CONTROL:
 1163                         mix.type = MIX_ON_OFF;
 1164                         mix.ctlunit = "";
 1165                         snprintf(mix.ctlname, sizeof(mix.ctlname), "%s.%s",
 1166                                  mixername, AudioNagc);
 1167                         break;
 1168                 case DELAY_CONTROL:
 1169                         mix.type = MIX_UNSIGNED_16;
 1170                         mix.ctlunit = "4 ms";
 1171                         snprintf(mix.ctlname, sizeof(mix.ctlname),
 1172                                  "%s.%s", mixername, AudioNdelay);
 1173                         break;
 1174                 case BASS_BOOST_CONTROL:
 1175                         mix.type = MIX_ON_OFF;
 1176                         mix.ctlunit = "";
 1177                         snprintf(mix.ctlname, sizeof(mix.ctlname),
 1178                                  "%s.%s", mixername, AudioNbassboost);
 1179                         break;
 1180                 case LOUDNESS_CONTROL:
 1181                         mix.type = MIX_ON_OFF;
 1182                         mix.ctlunit = "";
 1183                         snprintf(mix.ctlname, sizeof(mix.ctlname),
 1184                                  "%s.%s", mixername, AudioNloudness);
 1185                         break;
 1186                 }
 1187                 uaudio_mixer_add_ctl(sc, &mix);
 1188         }
 1189 }
 1190 
 1191 void
 1192 uaudio_add_processing_updown(struct uaudio_softc *sc,
 1193                              const struct io_terminal *iot, int id)
 1194 {
 1195         const struct usb_audio_processing_unit *d = iot[id].d.pu;
 1196         const struct usb_audio_processing_unit_1 *d1 =
 1197             (const struct usb_audio_processing_unit_1 *)&d->baSourceId[d->bNrInPins];
 1198         const struct usb_audio_processing_unit_updown *ud =
 1199             (const struct usb_audio_processing_unit_updown *)
 1200                 &d1->bmControls[d1->bControlSize];
 1201         struct mixerctl mix;
 1202         int i;
 1203 
 1204         DPRINTFN(2,("uaudio_add_processing_updown: bUnitId=%d bNrModes=%d\n",
 1205                     d->bUnitId, ud->bNrModes));
 1206 
 1207         if (!(d1->bmControls[0] & UA_PROC_MASK(UD_MODE_SELECT_CONTROL))) {
 1208                 DPRINTF(("uaudio_add_processing_updown: no mode select\n"));
 1209                 return;
 1210         }
 1211 
 1212         mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
 1213         mix.nchan = 1;
 1214         mix.wValue[0] = MAKE(UD_MODE_SELECT_CONTROL, 0);
 1215         uaudio_determine_class(&iot[id], &mix);
 1216         mix.type = MIX_ON_OFF;  /* XXX */
 1217         mix.ctlunit = "";
 1218         snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d-mode", d->bUnitId);
 1219 
 1220         for (i = 0; i < ud->bNrModes; i++) {
 1221                 DPRINTFN(2,("uaudio_add_processing_updown: i=%d bm=0x%x\n",
 1222                             i, UGETW(ud->waModes[i])));
 1223                 /* XXX */
 1224         }
 1225         uaudio_mixer_add_ctl(sc, &mix);
 1226 }
 1227 
 1228 void
 1229 uaudio_add_processing(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
 1230 {
 1231         const struct usb_audio_processing_unit *d = iot[id].d.pu;
 1232         const struct usb_audio_processing_unit_1 *d1 =
 1233             (const struct usb_audio_processing_unit_1 *)&d->baSourceId[d->bNrInPins];
 1234         int ptype = UGETW(d->wProcessType);
 1235         struct mixerctl mix;
 1236 
 1237         DPRINTFN(2,("uaudio_add_processing: wProcessType=%d bUnitId=%d "
 1238                     "bNrInPins=%d\n", ptype, d->bUnitId, d->bNrInPins));
 1239 
 1240         if (d1->bmControls[0] & UA_PROC_ENABLE_MASK) {
 1241                 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
 1242                 mix.nchan = 1;
 1243                 mix.wValue[0] = MAKE(XX_ENABLE_CONTROL, 0);
 1244                 uaudio_determine_class(&iot[id], &mix);
 1245                 mix.type = MIX_ON_OFF;
 1246                 mix.ctlunit = "";
 1247                 snprintf(mix.ctlname, sizeof(mix.ctlname), "pro%d.%d-enable",
 1248                     d->bUnitId, ptype);
 1249                 uaudio_mixer_add_ctl(sc, &mix);
 1250         }
 1251 
 1252         switch(ptype) {
 1253         case UPDOWNMIX_PROCESS:
 1254                 uaudio_add_processing_updown(sc, iot, id);
 1255                 break;
 1256         case DOLBY_PROLOGIC_PROCESS:
 1257         case P3D_STEREO_EXTENDER_PROCESS:
 1258         case REVERBATION_PROCESS:
 1259         case CHORUS_PROCESS:
 1260         case DYN_RANGE_COMP_PROCESS:
 1261         default:
 1262 #ifdef UAUDIO_DEBUG
 1263                 printf("uaudio_add_processing: unit %d, type=%d not impl.\n",
 1264                        d->bUnitId, ptype);
 1265 #endif
 1266                 break;
 1267         }
 1268 }
 1269 
 1270 void
 1271 uaudio_add_extension(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
 1272 {
 1273         const struct usb_audio_extension_unit *d = iot[id].d.eu;
 1274         const struct usb_audio_extension_unit_1 *d1 =
 1275             (const struct usb_audio_extension_unit_1 *)&d->baSourceId[d->bNrInPins];
 1276         struct mixerctl mix;
 1277 
 1278         DPRINTFN(2,("uaudio_add_extension: bUnitId=%d bNrInPins=%d\n",
 1279                     d->bUnitId, d->bNrInPins));
 1280 
 1281         if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_XU)
 1282                 return;
 1283 
 1284         if (d1->bmControls[0] & UA_EXT_ENABLE_MASK) {
 1285                 mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
 1286                 mix.nchan = 1;
 1287                 mix.wValue[0] = MAKE(UA_EXT_ENABLE, 0);
 1288                 uaudio_determine_class(&iot[id], &mix);
 1289                 mix.type = MIX_ON_OFF;
 1290                 mix.ctlunit = "";
 1291                 snprintf(mix.ctlname, sizeof(mix.ctlname), "ext%d-enable",
 1292                     d->bUnitId);
 1293                 uaudio_mixer_add_ctl(sc, &mix);
 1294         }
 1295 }
 1296 
 1297 struct terminal_list*
 1298 uaudio_merge_terminal_list(const struct io_terminal *iot)
 1299 {
 1300         struct terminal_list *tml;
 1301         uint16_t *ptm;
 1302         int i, len;
 1303 
 1304         len = 0;
 1305         if (iot->inputs == NULL)
 1306                 return NULL;
 1307         for (i = 0; i < iot->inputs_size; i++) {
 1308                 if (iot->inputs[i] != NULL)
 1309                         len += iot->inputs[i]->size;
 1310         }
 1311         tml = malloc(TERMINAL_LIST_SIZE(len), M_TEMP, M_NOWAIT);
 1312         if (tml == NULL) {
 1313                 printf("uaudio_merge_terminal_list: no memory\n");
 1314                 return NULL;
 1315         }
 1316         tml->size = 0;
 1317         ptm = tml->terminals;
 1318         for (i = 0; i < iot->inputs_size; i++) {
 1319                 if (iot->inputs[i] == NULL)
 1320                         continue;
 1321                 if (iot->inputs[i]->size > len)
 1322                         break;
 1323                 memcpy(ptm, iot->inputs[i]->terminals,
 1324                        iot->inputs[i]->size * sizeof(uint16_t));
 1325                 tml->size += iot->inputs[i]->size;
 1326                 ptm += iot->inputs[i]->size;
 1327                 len -= iot->inputs[i]->size;
 1328         }
 1329         return tml;
 1330 }
 1331 
 1332 struct terminal_list *
 1333 uaudio_io_terminaltype(int outtype, struct io_terminal *iot, int id)
 1334 {
 1335         struct terminal_list *tml;
 1336         struct io_terminal *it;
 1337         int src_id, i;
 1338 
 1339         it = &iot[id];
 1340         if (it->output != NULL) {
 1341                 /* already has outtype? */
 1342                 for (i = 0; i < it->output->size; i++)
 1343                         if (it->output->terminals[i] == outtype)
 1344                                 return uaudio_merge_terminal_list(it);
 1345                 tml = malloc(TERMINAL_LIST_SIZE(it->output->size + 1),
 1346                              M_TEMP, M_NOWAIT);
 1347                 if (tml == NULL) {
 1348                         printf("uaudio_io_terminaltype: no memory\n");
 1349                         return uaudio_merge_terminal_list(it);
 1350                 }
 1351                 memcpy(tml, it->output, TERMINAL_LIST_SIZE(it->output->size));
 1352                 tml->terminals[it->output->size] = outtype;
 1353                 tml->size++;
 1354                 free(it->output, M_TEMP);
 1355                 it->output = tml;
 1356                 if (it->inputs != NULL) {
 1357                         for (i = 0; i < it->inputs_size; i++)
 1358                                 if (it->inputs[i] != NULL)
 1359                                         free(it->inputs[i], M_TEMP);
 1360                         free(it->inputs, M_TEMP);
 1361                 }
 1362                 it->inputs_size = 0;
 1363                 it->inputs = NULL;
 1364         } else {                /* end `iot[id] != NULL' */
 1365                 it->inputs_size = 0;
 1366                 it->inputs = NULL;
 1367                 it->output = malloc(TERMINAL_LIST_SIZE(1), M_TEMP, M_NOWAIT);
 1368                 if (it->output == NULL) {
 1369                         printf("uaudio_io_terminaltype: no memory\n");
 1370                         return NULL;
 1371                 }
 1372                 it->output->terminals[0] = outtype;
 1373                 it->output->size = 1;
 1374                 it->direct = FALSE;
 1375         }
 1376 
 1377         switch (it->d.desc->bDescriptorSubtype) {
 1378         case UDESCSUB_AC_INPUT:
 1379                 it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT);
 1380                 if (it->inputs == NULL) {
 1381                         printf("uaudio_io_terminaltype: no memory\n");
 1382                         return NULL;
 1383                 }
 1384                 tml = malloc(TERMINAL_LIST_SIZE(1), M_TEMP, M_NOWAIT);
 1385                 if (tml == NULL) {
 1386                         printf("uaudio_io_terminaltype: no memory\n");
 1387                         free(it->inputs, M_TEMP);
 1388                         it->inputs = NULL;
 1389                         return NULL;
 1390                 }
 1391                 it->inputs[0] = tml;
 1392                 tml->terminals[0] = UGETW(it->d.it->wTerminalType);
 1393                 tml->size = 1;
 1394                 it->inputs_size = 1;
 1395                 return uaudio_merge_terminal_list(it);
 1396         case UDESCSUB_AC_FEATURE:
 1397                 src_id = it->d.fu->bSourceId;
 1398                 it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT);
 1399                 if (it->inputs == NULL) {
 1400                         printf("uaudio_io_terminaltype: no memory\n");
 1401                         return uaudio_io_terminaltype(outtype, iot, src_id);
 1402                 }
 1403                 it->inputs[0] = uaudio_io_terminaltype(outtype, iot, src_id);
 1404                 it->inputs_size = 1;
 1405                 return uaudio_merge_terminal_list(it);
 1406         case UDESCSUB_AC_OUTPUT:
 1407                 it->inputs = malloc(sizeof(struct terminal_list *), M_TEMP, M_NOWAIT);
 1408                 if (it->inputs == NULL) {
 1409                         printf("uaudio_io_terminaltype: no memory\n");
 1410                         return NULL;
 1411                 }
 1412                 src_id = it->d.ot->bSourceId;
 1413                 it->inputs[0] = uaudio_io_terminaltype(outtype, iot, src_id);
 1414                 it->inputs_size = 1;
 1415                 iot[src_id].direct = TRUE;
 1416                 return NULL;
 1417         case UDESCSUB_AC_MIXER:
 1418                 it->inputs_size = 0;
 1419                 it->inputs = malloc(sizeof(struct terminal_list *)
 1420                                     * it->d.mu->bNrInPins, M_TEMP, M_NOWAIT);
 1421                 if (it->inputs == NULL) {
 1422                         printf("uaudio_io_terminaltype: no memory\n");
 1423                         return NULL;
 1424                 }
 1425                 for (i = 0; i < it->d.mu->bNrInPins; i++) {
 1426                         src_id = it->d.mu->baSourceId[i];
 1427                         it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
 1428                                                                src_id);
 1429                         it->inputs_size++;
 1430                 }
 1431                 return uaudio_merge_terminal_list(it);
 1432         case UDESCSUB_AC_SELECTOR:
 1433                 it->inputs_size = 0;
 1434                 it->inputs = malloc(sizeof(struct terminal_list *)
 1435                                     * it->d.su->bNrInPins, M_TEMP, M_NOWAIT);
 1436                 if (it->inputs == NULL) {
 1437                         printf("uaudio_io_terminaltype: no memory\n");
 1438                         return NULL;
 1439                 }
 1440                 for (i = 0; i < it->d.su->bNrInPins; i++) {
 1441                         src_id = it->d.su->baSourceId[i];
 1442                         it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
 1443                                                                src_id);
 1444                         it->inputs_size++;
 1445                 }
 1446                 return uaudio_merge_terminal_list(it);
 1447         case UDESCSUB_AC_PROCESSING:
 1448                 it->inputs_size = 0;
 1449                 it->inputs = malloc(sizeof(struct terminal_list *)
 1450                                     * it->d.pu->bNrInPins, M_TEMP, M_NOWAIT);
 1451                 if (it->inputs == NULL) {
 1452                         printf("uaudio_io_terminaltype: no memory\n");
 1453                         return NULL;
 1454                 }
 1455                 for (i = 0; i < it->d.pu->bNrInPins; i++) {
 1456                         src_id = it->d.pu->baSourceId[i];
 1457                         it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
 1458                                                                src_id);
 1459                         it->inputs_size++;
 1460                 }
 1461                 return uaudio_merge_terminal_list(it);
 1462         case UDESCSUB_AC_EXTENSION:
 1463                 it->inputs_size = 0;
 1464                 it->inputs = malloc(sizeof(struct terminal_list *)
 1465                                     * it->d.eu->bNrInPins, M_TEMP, M_NOWAIT);
 1466                 if (it->inputs == NULL) {
 1467                         printf("uaudio_io_terminaltype: no memory\n");
 1468                         return NULL;
 1469                 }
 1470                 for (i = 0; i < it->d.eu->bNrInPins; i++) {
 1471                         src_id = it->d.eu->baSourceId[i];
 1472                         it->inputs[i] = uaudio_io_terminaltype(outtype, iot,
 1473                                                                src_id);
 1474                         it->inputs_size++;
 1475                 }
 1476                 return uaudio_merge_terminal_list(it);
 1477         case UDESCSUB_AC_HEADER:
 1478         default:
 1479                 return NULL;
 1480         }
 1481 }
 1482 
 1483 usbd_status
 1484 uaudio_identify(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc)
 1485 {
 1486         usbd_status err;
 1487 
 1488         err = uaudio_identify_ac(sc, cdesc);
 1489         if (err)
 1490                 return (err);
 1491         return (uaudio_identify_as(sc, cdesc));
 1492 }
 1493 
 1494 void
 1495 uaudio_add_alt(struct uaudio_softc *sc, const struct as_info *ai)
 1496 {
 1497         size_t len;
 1498         struct as_info *nai;
 1499 
 1500         len = sizeof(*ai) * (sc->sc_nalts + 1);
 1501         nai = malloc(len, M_USBDEV, M_NOWAIT);
 1502         if (nai == NULL) {
 1503                 printf("uaudio_add_alt: no memory\n");
 1504                 return;
 1505         }
 1506         /* Copy old data, if there was any */
 1507         if (sc->sc_nalts != 0) {
 1508                 bcopy(sc->sc_alts, nai, sizeof(*ai) * (sc->sc_nalts));
 1509                 free(sc->sc_alts, M_USBDEV);
 1510         }
 1511         sc->sc_alts = nai;
 1512         DPRINTFN(2,("uaudio_add_alt: adding alt=%d, enc=%d\n",
 1513                     ai->alt, ai->encoding));
 1514         sc->sc_alts[sc->sc_nalts++] = *ai;
 1515 }
 1516 
 1517 usbd_status
 1518 uaudio_process_as(struct uaudio_softc *sc, const char *buf, int *offsp,
 1519                   int size, const usb_interface_descriptor_t *id)
 1520 #define offs (*offsp)
 1521 {
 1522         const struct usb_audio_streaming_interface_descriptor *asid;
 1523         const struct usb_audio_streaming_type1_descriptor *asf1d;
 1524         const usb_endpoint_descriptor_audio_t *ed;
 1525         const usb_endpoint_descriptor_audio_t *epdesc1;
 1526         const struct usb_audio_streaming_endpoint_descriptor *sed;
 1527         int format, chan, prec, enc;
 1528         int dir, type, sync;
 1529         struct as_info ai;
 1530         const char *format_str;
 1531 
 1532         asid = (const void *)(buf + offs);
 1533         if (asid->bDescriptorType != UDESC_CS_INTERFACE ||
 1534             asid->bDescriptorSubtype != AS_GENERAL)
 1535                 return (USBD_INVAL);
 1536         DPRINTF(("uaudio_process_as: asid: bTerminakLink=%d wFormatTag=%d\n",
 1537                  asid->bTerminalLink, UGETW(asid->wFormatTag)));
 1538         offs += asid->bLength;
 1539         if (offs > size)
 1540                 return (USBD_INVAL);
 1541 
 1542         asf1d = (const void *)(buf + offs);
 1543         if (asf1d->bDescriptorType != UDESC_CS_INTERFACE ||
 1544             asf1d->bDescriptorSubtype != FORMAT_TYPE)
 1545                 return (USBD_INVAL);
 1546         offs += asf1d->bLength;
 1547         if (offs > size)
 1548                 return (USBD_INVAL);
 1549 
 1550         if (asf1d->bFormatType != FORMAT_TYPE_I) {
 1551                 printf("%s: ignored setting with type %d format\n",
 1552                        sc->sc_dev.dv_xname, UGETW(asid->wFormatTag));
 1553                 return (USBD_NORMAL_COMPLETION);
 1554         }
 1555 
 1556         ed = (const void *)(buf + offs);
 1557         if (ed->bDescriptorType != UDESC_ENDPOINT)
 1558                 return (USBD_INVAL);
 1559         DPRINTF(("uaudio_process_as: endpoint[0] bLength=%d bDescriptorType=%d "
 1560                  "bEndpointAddress=%d bmAttributes=0x%x wMaxPacketSize=%d "
 1561                  "bInterval=%d bRefresh=%d bSynchAddress=%d\n",
 1562                  ed->bLength, ed->bDescriptorType, ed->bEndpointAddress,
 1563                  ed->bmAttributes, UGETW(ed->wMaxPacketSize),
 1564                  ed->bInterval, ed->bRefresh, ed->bSynchAddress));
 1565         offs += ed->bLength;
 1566         if (offs > size)
 1567                 return (USBD_INVAL);
 1568         if (UE_GET_XFERTYPE(ed->bmAttributes) != UE_ISOCHRONOUS)
 1569                 return (USBD_INVAL);
 1570 
 1571         dir = UE_GET_DIR(ed->bEndpointAddress);
 1572         type = UE_GET_ISO_TYPE(ed->bmAttributes);
 1573         if ((usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_INP_ASYNC) &&
 1574             dir == UE_DIR_IN && type == UE_ISO_ADAPT)
 1575                 type = UE_ISO_ASYNC;
 1576 
 1577         /* We can't handle endpoints that need a sync pipe yet. */
 1578         sync = FALSE;
 1579         if (dir == UE_DIR_IN && type == UE_ISO_ADAPT) {
 1580                 sync = TRUE;
 1581 #ifndef UAUDIO_MULTIPLE_ENDPOINTS
 1582                 printf("%s: ignored input endpoint of type adaptive\n",
 1583                        sc->sc_dev.dv_xname);
 1584                 return (USBD_NORMAL_COMPLETION);
 1585 #endif
 1586         }
 1587         if (dir != UE_DIR_IN && type == UE_ISO_ASYNC) {
 1588                 sync = TRUE;
 1589 #ifndef UAUDIO_MULTIPLE_ENDPOINTS
 1590                 printf("%s: ignored output endpoint of type async\n",
 1591                        sc->sc_dev.dv_xname);
 1592                 return (USBD_NORMAL_COMPLETION);
 1593 #endif
 1594         }
 1595 
 1596         sed = (const void *)(buf + offs);
 1597         if (sed->bDescriptorType != UDESC_CS_ENDPOINT ||
 1598             sed->bDescriptorSubtype != AS_GENERAL)
 1599                 return (USBD_INVAL);
 1600         DPRINTF((" streadming_endpoint: offset=%d bLength=%d\n", offs, sed->bLength));
 1601         offs += sed->bLength;
 1602         if (offs > size)
 1603                 return (USBD_INVAL);
 1604 
 1605         if (sync && id->bNumEndpoints <= 1) {
 1606                 printf("%s: a sync-pipe endpoint but no other endpoint\n",
 1607                        sc->sc_dev.dv_xname);
 1608                 return USBD_INVAL;
 1609         }
 1610         if (!sync && id->bNumEndpoints > 1) {
 1611                 printf("%s: non sync-pipe endpoint but multiple endpoints\n",
 1612                        sc->sc_dev.dv_xname);
 1613                 return USBD_INVAL;
 1614         }
 1615         epdesc1 = NULL;
 1616         if (id->bNumEndpoints > 1) {
 1617                 epdesc1 = (const void*)(buf + offs);
 1618                 if (epdesc1->bDescriptorType != UDESC_ENDPOINT)
 1619                         return USBD_INVAL;
 1620                 DPRINTF(("uaudio_process_as: endpoint[1] bLength=%d "
 1621                          "bDescriptorType=%d bEndpointAddress=%d "
 1622                          "bmAttributes=0x%x wMaxPacketSize=%d bInterval=%d "
 1623                          "bRefresh=%d bSynchAddress=%d\n",
 1624                          epdesc1->bLength, epdesc1->bDescriptorType,
 1625                          epdesc1->bEndpointAddress, epdesc1->bmAttributes,
 1626                          UGETW(epdesc1->wMaxPacketSize), epdesc1->bInterval,
 1627                          epdesc1->bRefresh, epdesc1->bSynchAddress));
 1628                 offs += epdesc1->bLength;
 1629                 if (offs > size)
 1630                         return USBD_INVAL;
 1631                 if (epdesc1->bSynchAddress != 0) {
 1632                         printf("%s: invalid endpoint: bSynchAddress=0\n",
 1633                                sc->sc_dev.dv_xname);
 1634                         return USBD_INVAL;
 1635                 }
 1636                 if (UE_GET_XFERTYPE(epdesc1->bmAttributes) != UE_ISOCHRONOUS) {
 1637                         printf("%s: invalid endpoint: bmAttributes=0x%x\n",
 1638                                sc->sc_dev.dv_xname, epdesc1->bmAttributes);
 1639                         return USBD_INVAL;
 1640                 }
 1641                 if (epdesc1->bEndpointAddress != ed->bSynchAddress) {
 1642                         printf("%s: invalid endpoint addresses: "
 1643                                "ep[0]->bSynchAddress=0x%x "
 1644                                "ep[1]->bEndpointAddress=0x%x\n",
 1645                                sc->sc_dev.dv_xname, ed->bSynchAddress,
 1646                                epdesc1->bEndpointAddress);
 1647                         return USBD_INVAL;
 1648                 }
 1649                 /* UE_GET_ADDR(epdesc1->bEndpointAddress), and epdesc1->bRefresh */
 1650         }
 1651 
 1652         format = UGETW(asid->wFormatTag);
 1653         chan = asf1d->bNrChannels;
 1654         prec = asf1d->bBitResolution;
 1655         if (prec != 8 && prec != 16 && prec != 24) {
 1656                 printf("%s: ignored setting with precision %d\n",
 1657                        sc->sc_dev.dv_xname, prec);
 1658                 return (USBD_NORMAL_COMPLETION);
 1659         }
 1660         switch (format) {
 1661         case UA_FMT_PCM:
 1662                 if (prec == 8) {
 1663                         sc->sc_altflags |= HAS_8;
 1664                 } else if (prec == 16) {
 1665                         sc->sc_altflags |= HAS_16;
 1666                 } else if (prec == 24) {
 1667                         sc->sc_altflags |= HAS_24;
 1668                 }
 1669                 enc = AUDIO_ENCODING_SLINEAR_LE;
 1670                 format_str = "pcm";
 1671                 break;
 1672         case UA_FMT_PCM8:
 1673                 enc = AUDIO_ENCODING_ULINEAR_LE;
 1674                 sc->sc_altflags |= HAS_8U;
 1675                 format_str = "pcm8";
 1676                 break;
 1677         case UA_FMT_ALAW:
 1678                 enc = AUDIO_ENCODING_ALAW;
 1679                 sc->sc_altflags |= HAS_ALAW;
 1680                 format_str = "alaw";
 1681                 break;
 1682         case UA_FMT_MULAW:
 1683                 enc = AUDIO_ENCODING_ULAW;
 1684                 sc->sc_altflags |= HAS_MULAW;
 1685                 format_str = "mulaw";
 1686                 break;
 1687         case UA_FMT_IEEE_FLOAT:
 1688         default:
 1689                 printf("%s: ignored setting with format %d\n",
 1690                        sc->sc_dev.dv_xname, format);
 1691                 return (USBD_NORMAL_COMPLETION);
 1692         }
 1693 #ifdef UAUDIO_DEBUG
 1694         printf("%s: %s: %dch, %d/%dbit, %s,", sc->sc_dev.dv_xname,
 1695                dir == UE_DIR_IN ? "recording" : "playback",
 1696                chan, prec, asf1d->bSubFrameSize * 8, format_str);
 1697         if (asf1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
 1698                 printf(" %d-%dHz\n", UA_SAMP_LO(asf1d), UA_SAMP_HI(asf1d));
 1699         } else {
 1700                 int r;
 1701                 printf(" %d", UA_GETSAMP(asf1d, 0));
 1702                 for (r = 1; r < asf1d->bSamFreqType; r++)
 1703                         printf(",%d", UA_GETSAMP(asf1d, r));
 1704                 printf("Hz\n");
 1705         }
 1706 #endif
 1707         ai.alt = id->bAlternateSetting;
 1708         ai.encoding = enc;
 1709         ai.attributes = sed->bmAttributes;
 1710         ai.idesc = id;
 1711         ai.edesc = ed;
 1712         ai.edesc1 = epdesc1;
 1713         ai.asf1desc = asf1d;
 1714         ai.sc_busy = 0;
 1715         uaudio_add_alt(sc, &ai);
 1716 #ifdef UAUDIO_DEBUG
 1717         if (ai.attributes & UA_SED_FREQ_CONTROL)
 1718                 DPRINTFN(1, ("uaudio_process_as:  FREQ_CONTROL\n"));
 1719         if (ai.attributes & UA_SED_PITCH_CONTROL)
 1720                 DPRINTFN(1, ("uaudio_process_as:  PITCH_CONTROL\n"));
 1721 #endif
 1722         sc->sc_mode |= (dir == UE_DIR_OUT) ? AUMODE_PLAY : AUMODE_RECORD;
 1723 
 1724         return (USBD_NORMAL_COMPLETION);
 1725 }
 1726 #undef offs
 1727 
 1728 usbd_status
 1729 uaudio_identify_as(struct uaudio_softc *sc,
 1730                    const usb_config_descriptor_t *cdesc)
 1731 {
 1732         const usb_interface_descriptor_t *id;
 1733         const char *buf;
 1734         int size, offs;
 1735 
 1736         size = UGETW(cdesc->wTotalLength);
 1737         buf = (const char *)cdesc;
 1738 
 1739         /* Locate the AudioStreaming interface descriptor. */
 1740         offs = 0;
 1741         id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOSTREAM);
 1742         if (id == NULL)
 1743                 return (USBD_INVAL);
 1744 
 1745         /* Loop through all the alternate settings. */
 1746         while (offs <= size) {
 1747                 DPRINTFN(2, ("uaudio_identify: interface=%d offset=%d\n",
 1748                     id->bInterfaceNumber, offs));
 1749                 switch (id->bNumEndpoints) {
 1750                 case 0:
 1751                         DPRINTFN(2, ("uaudio_identify: AS null alt=%d\n",
 1752                                      id->bAlternateSetting));
 1753                         sc->sc_nullalt = id->bAlternateSetting;
 1754                         break;
 1755                 case 1:
 1756 #ifdef UAUDIO_MULTIPLE_ENDPOINTS
 1757                 case 2:
 1758 #endif
 1759                         uaudio_process_as(sc, buf, &offs, size, id);
 1760                         break;
 1761                 default:
 1762                         printf("%s: ignored audio interface with %d "
 1763                                "endpoints\n",
 1764                                sc->sc_dev.dv_xname, id->bNumEndpoints);
 1765                         break;
 1766                 }
 1767                 id = uaudio_find_iface(buf, size, &offs,UISUBCLASS_AUDIOSTREAM);
 1768                 if (id == NULL)
 1769                         break;
 1770         }
 1771         if (offs > size)
 1772                 return (USBD_INVAL);
 1773         DPRINTF(("uaudio_identify_as: %d alts available\n", sc->sc_nalts));
 1774 
 1775         if (sc->sc_mode == 0) {
 1776                 printf("%s: no usable endpoint found\n",
 1777                        sc->sc_dev.dv_xname);
 1778                 return (USBD_INVAL);
 1779         }
 1780 
 1781         return (USBD_NORMAL_COMPLETION);
 1782 }
 1783 
 1784 usbd_status
 1785 uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc)
 1786 {
 1787         struct io_terminal* iot;
 1788         const usb_interface_descriptor_t *id;
 1789         const struct usb_audio_control_descriptor *acdp;
 1790         const usb_descriptor_t *dp;
 1791         const struct usb_audio_output_terminal *pot;
 1792         struct terminal_list *tml;
 1793         const char *buf, *ibuf, *ibufend;
 1794         int size, offs, aclen, ndps, i, j;
 1795 
 1796         size = UGETW(cdesc->wTotalLength);
 1797         buf = (char *)cdesc;
 1798 
 1799         /* Locate the AudioControl interface descriptor. */
 1800         offs = 0;
 1801         id = uaudio_find_iface(buf, size, &offs, UISUBCLASS_AUDIOCONTROL);
 1802         if (id == NULL)
 1803                 return (USBD_INVAL);
 1804         if (offs + sizeof *acdp > size)
 1805                 return (USBD_INVAL);
 1806         sc->sc_ac_iface = id->bInterfaceNumber;
 1807         DPRINTFN(2,("uaudio_identify_ac: AC interface is %d\n", sc->sc_ac_iface));
 1808 
 1809         /* A class-specific AC interface header should follow. */
 1810         ibuf = buf + offs;
 1811         acdp = (const struct usb_audio_control_descriptor *)ibuf;
 1812         if (acdp->bDescriptorType != UDESC_CS_INTERFACE ||
 1813             acdp->bDescriptorSubtype != UDESCSUB_AC_HEADER)
 1814                 return (USBD_INVAL);
 1815         aclen = UGETW(acdp->wTotalLength);
 1816         if (offs + aclen > size)
 1817                 return (USBD_INVAL);
 1818 
 1819         if (!(usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_BAD_ADC) &&
 1820              UGETW(acdp->bcdADC) != UAUDIO_VERSION)
 1821                 return (USBD_INVAL);
 1822 
 1823         sc->sc_audio_rev = UGETW(acdp->bcdADC);
 1824         DPRINTFN(2,("uaudio_identify_ac: found AC header, vers=%03x, len=%d\n",
 1825                  sc->sc_audio_rev, aclen));
 1826 
 1827         sc->sc_nullalt = -1;
 1828 
 1829         /* Scan through all the AC specific descriptors */
 1830         ibufend = ibuf + aclen;
 1831         dp = (const usb_descriptor_t *)ibuf;
 1832         ndps = 0;
 1833         iot = malloc(sizeof(struct io_terminal) * 256, M_TEMP, M_NOWAIT);
 1834         if (iot == NULL) {
 1835                 printf("%s: no memory\n", __func__);
 1836                 return USBD_NOMEM;
 1837         }
 1838         bzero(iot, sizeof(struct io_terminal) * 256);
 1839         for (;;) {
 1840                 ibuf += dp->bLength;
 1841                 if (ibuf >= ibufend)
 1842                         break;
 1843                 dp = (const usb_descriptor_t *)ibuf;
 1844                 if (ibuf + dp->bLength > ibufend) {
 1845                         free(iot, M_TEMP);
 1846                         return (USBD_INVAL);
 1847                 }
 1848                 if (dp->bDescriptorType != UDESC_CS_INTERFACE) {
 1849                         printf("uaudio_identify_ac: skip desc type=0x%02x\n",
 1850                                dp->bDescriptorType);
 1851                         continue;
 1852                 }
 1853                 i = ((const struct usb_audio_input_terminal *)dp)->bTerminalId;
 1854                 iot[i].d.desc = dp;
 1855                 if (i > ndps)
 1856                         ndps = i;
 1857         }
 1858         ndps++;
 1859 
 1860         /* construct io_terminal */
 1861         for (i = 0; i < ndps; i++) {
 1862                 dp = iot[i].d.desc;
 1863                 if (dp == NULL)
 1864                         continue;
 1865                 if (dp->bDescriptorSubtype != UDESCSUB_AC_OUTPUT)
 1866                         continue;
 1867                 pot = iot[i].d.ot;
 1868                 tml = uaudio_io_terminaltype(UGETW(pot->wTerminalType), iot, i);
 1869                 if (tml != NULL)
 1870                         free(tml, M_TEMP);
 1871         }
 1872 
 1873 #ifdef UAUDIO_DEBUG
 1874         for (i = 0; i < 256; i++) {
 1875                 if (iot[i].d.desc == NULL)
 1876                         continue;
 1877                 printf("id %d:\t", i);
 1878                 switch (iot[i].d.desc->bDescriptorSubtype) {
 1879                 case UDESCSUB_AC_INPUT:
 1880                         printf("AC_INPUT type=%s\n", uaudio_get_terminal_name
 1881                                (UGETW(iot[i].d.it->wTerminalType)));
 1882                         break;
 1883                 case UDESCSUB_AC_OUTPUT:
 1884                         printf("AC_OUTPUT type=%s ", uaudio_get_terminal_name
 1885                                (UGETW(iot[i].d.ot->wTerminalType)));
 1886                         printf("src=%d\n", iot[i].d.ot->bSourceId);
 1887                         break;
 1888                 case UDESCSUB_AC_MIXER:
 1889                         printf("AC_MIXER src=");
 1890                         for (j = 0; j < iot[i].d.mu->bNrInPins; j++)
 1891                                 printf("%d ", iot[i].d.mu->baSourceId[j]);
 1892                         printf("\n");
 1893                         break;
 1894                 case UDESCSUB_AC_SELECTOR:
 1895                         printf("AC_SELECTOR src=");
 1896                         for (j = 0; j < iot[i].d.su->bNrInPins; j++)
 1897                                 printf("%d ", iot[i].d.su->baSourceId[j]);
 1898                         printf("\n");
 1899                         break;
 1900                 case UDESCSUB_AC_FEATURE:
 1901                         printf("AC_FEATURE src=%d\n", iot[i].d.fu->bSourceId);
 1902                         break;
 1903                 case UDESCSUB_AC_PROCESSING:
 1904                         printf("AC_PROCESSING src=");
 1905                         for (j = 0; j < iot[i].d.pu->bNrInPins; j++)
 1906                                 printf("%d ", iot[i].d.pu->baSourceId[j]);
 1907                         printf("\n");
 1908                         break;
 1909                 case UDESCSUB_AC_EXTENSION:
 1910                         printf("AC_EXTENSION src=");
 1911                         for (j = 0; j < iot[i].d.eu->bNrInPins; j++)
 1912                                 printf("%d ", iot[i].d.eu->baSourceId[j]);
 1913                         printf("\n");
 1914                         break;
 1915                 default:
 1916                         printf("unknown audio control (subtype=%d)\n",
 1917                                iot[i].d.desc->bDescriptorSubtype);
 1918                 }
 1919                 for (j = 0; j < iot[i].inputs_size; j++) {
 1920                         int k;
 1921                         printf("\tinput%d: ", j);
 1922                         tml = iot[i].inputs[j];
 1923                         if (tml == NULL) {
 1924                                 printf("NULL\n");
 1925                                 continue;
 1926                         }
 1927                         for (k = 0; k < tml->size; k++)
 1928                                 printf("%s ", uaudio_get_terminal_name
 1929                                        (tml->terminals[k]));
 1930                         printf("\n");
 1931                 }
 1932                 printf("\toutput: ");
 1933                 tml = iot[i].output;
 1934                 for (j = 0; j < tml->size; j++)
 1935                         printf("%s ", uaudio_get_terminal_name(tml->terminals[j]));
 1936                 printf("\n");
 1937         }
 1938 #endif
 1939 
 1940         for (i = 0; i < ndps; i++) {
 1941                 dp = iot[i].d.desc;
 1942                 if (dp == NULL)
 1943                         continue;
 1944                 DPRINTF(("uaudio_identify_ac: id=%d subtype=%d\n",
 1945                          i, dp->bDescriptorSubtype));
 1946                 switch (dp->bDescriptorSubtype) {
 1947                 case UDESCSUB_AC_HEADER:
 1948                         printf("uaudio_identify_ac: unexpected AC header\n");
 1949                         break;
 1950                 case UDESCSUB_AC_INPUT:
 1951                         uaudio_add_input(sc, iot, i);
 1952                         break;
 1953                 case UDESCSUB_AC_OUTPUT:
 1954                         uaudio_add_output(sc, iot, i);
 1955                         break;
 1956                 case UDESCSUB_AC_MIXER:
 1957                         uaudio_add_mixer(sc, iot, i);
 1958                         break;
 1959                 case UDESCSUB_AC_SELECTOR:
 1960                         uaudio_add_selector(sc, iot, i);
 1961                         break;
 1962                 case UDESCSUB_AC_FEATURE:
 1963                         uaudio_add_feature(sc, iot, i);
 1964                         break;
 1965                 case UDESCSUB_AC_PROCESSING:
 1966                         uaudio_add_processing(sc, iot, i);
 1967                         break;
 1968                 case UDESCSUB_AC_EXTENSION:
 1969                         uaudio_add_extension(sc, iot, i);
 1970                         break;
 1971                 default:
 1972                         printf("uaudio_identify_ac: bad AC desc subtype=0x%02x\n",
 1973                                dp->bDescriptorSubtype);
 1974                         break;
 1975                 }
 1976         }
 1977 
 1978         /* delete io_terminal */
 1979         for (i = 0; i < 256; i++) {
 1980                 if (iot[i].d.desc == NULL)
 1981                         continue;
 1982                 if (iot[i].inputs != NULL) {
 1983                         for (j = 0; j < iot[i].inputs_size; j++) {
 1984                                 if (iot[i].inputs[j] != NULL)
 1985                                         free(iot[i].inputs[j], M_TEMP);
 1986                         }
 1987                         free(iot[i].inputs, M_TEMP);
 1988                 }
 1989                 if (iot[i].output != NULL)
 1990                         free(iot[i].output, M_TEMP);
 1991                 iot[i].d.desc = NULL;
 1992         }
 1993         free(iot, M_TEMP);
 1994 
 1995         return (USBD_NORMAL_COMPLETION);
 1996 }
 1997 
 1998 int
 1999 uaudio_query_devinfo(void *addr, mixer_devinfo_t *mi)
 2000 {
 2001         struct uaudio_softc *sc = addr;
 2002         struct mixerctl *mc;
 2003         int n, nctls, i;
 2004 
 2005         DPRINTFN(2,("uaudio_query_devinfo: index=%d\n", mi->index));
 2006         if (sc->sc_dying)
 2007                 return (EIO);
 2008 
 2009         n = mi->index;
 2010         nctls = sc->sc_nctls;
 2011 
 2012         switch (n) {
 2013         case UAC_OUTPUT:
 2014                 mi->type = AUDIO_MIXER_CLASS;
 2015                 mi->mixer_class = UAC_OUTPUT;
 2016                 mi->next = mi->prev = AUDIO_MIXER_LAST;
 2017                 strlcpy(mi->label.name, AudioCoutputs, sizeof(mi->label.name));
 2018                 return (0);
 2019         case UAC_INPUT:
 2020                 mi->type = AUDIO_MIXER_CLASS;
 2021                 mi->mixer_class = UAC_INPUT;
 2022                 mi->next = mi->prev = AUDIO_MIXER_LAST;
 2023                 strlcpy(mi->label.name, AudioCinputs, sizeof(mi->label.name));
 2024                 return (0);
 2025         case UAC_EQUAL:
 2026                 mi->type = AUDIO_MIXER_CLASS;
 2027                 mi->mixer_class = UAC_EQUAL;
 2028                 mi->next = mi->prev = AUDIO_MIXER_LAST;
 2029                 strlcpy(mi->label.name, AudioCequalization,
 2030                     sizeof(mi->label.name));
 2031                 return (0);
 2032         case UAC_RECORD:
 2033                 mi->type = AUDIO_MIXER_CLASS;
 2034                 mi->mixer_class = UAC_RECORD;
 2035                 mi->next = mi->prev = AUDIO_MIXER_LAST;
 2036                 strlcpy(mi->label.name, AudioCrecord, sizeof(mi->label.name));
 2037                 return 0;
 2038         default:
 2039                 break;
 2040         }
 2041 
 2042         n -= UAC_NCLASSES;
 2043         if (n < 0 || n >= nctls)
 2044                 return (ENXIO);
 2045 
 2046         mc = &sc->sc_ctls[n];
 2047         strlcpy(mi->label.name, mc->ctlname, sizeof(mi->label.name));
 2048         mi->mixer_class = mc->class;
 2049         mi->next = mi->prev = AUDIO_MIXER_LAST; /* XXX */
 2050         switch (mc->type) {
 2051         case MIX_ON_OFF:
 2052                 mi->type = AUDIO_MIXER_ENUM;
 2053                 mi->un.e.num_mem = 2;
 2054                 strlcpy(mi->un.e.member[0].label.name, AudioNoff,
 2055                     sizeof(mi->un.e.member[0].label.name));
 2056                 mi->un.e.member[0].ord = 0;
 2057                 strlcpy(mi->un.e.member[1].label.name, AudioNon,
 2058                     sizeof(mi->un.e.member[1].label.name));
 2059                 mi->un.e.member[1].ord = 1;
 2060                 break;
 2061         case MIX_SELECTOR:
 2062                 mi->type = AUDIO_MIXER_ENUM;
 2063                 mi->un.e.num_mem = mc->maxval - mc->minval + 1;
 2064                 for (i = 0; i <= mc->maxval - mc->minval; i++) {
 2065                         snprintf(mi->un.e.member[i].label.name,
 2066                                  sizeof(mi->un.e.member[i].label.name),
 2067                                  "%d", i + mc->minval);
 2068                         mi->un.e.member[i].ord = i + mc->minval;
 2069                 }
 2070                 break;
 2071         default:
 2072                 mi->type = AUDIO_MIXER_VALUE;
 2073                 strlcpy(mi->un.v.units.name, mc->ctlunit,
 2074                     sizeof(mi->un.v.units.name));
 2075                 mi->un.v.num_channels = mc->nchan;
 2076                 mi->un.v.delta = mc->delta;
 2077                 break;
 2078         }
 2079         return (0);
 2080 }
 2081 
 2082 int
 2083 uaudio_open(void *addr, int flags)
 2084 {
 2085         struct uaudio_softc *sc = addr;
 2086 
 2087         DPRINTF(("uaudio_open: sc=%p\n", sc));
 2088         if (sc->sc_dying)
 2089                 return (EIO);
 2090 
 2091         if ((flags & FWRITE) && !(sc->sc_mode & AUMODE_PLAY))
 2092                 return (EACCES);
 2093         if ((flags & FREAD) && !(sc->sc_mode & AUMODE_RECORD))
 2094                 return (EACCES);
 2095 
 2096         return (0);
 2097 }
 2098 
 2099 /*
 2100  * Close function is called at splaudio().
 2101  */
 2102 void
 2103 uaudio_close(void *addr)
 2104 {
 2105         struct uaudio_softc *sc = addr;
 2106 
 2107         if (sc->sc_playchan.altidx != -1)
 2108                 uaudio_chan_close(sc, &sc->sc_playchan);
 2109         if (sc->sc_recchan.altidx != -1)
 2110                 uaudio_chan_close(sc, &sc->sc_recchan);
 2111 }
 2112 
 2113 int
 2114 uaudio_drain(void *addr)
 2115 {
 2116         struct uaudio_softc *sc = addr;
 2117 
 2118         usbd_delay_ms(sc->sc_udev, UAUDIO_NCHANBUFS * UAUDIO_NFRAMES);
 2119 
 2120         return (0);
 2121 }
 2122 
 2123 int
 2124 uaudio_halt_out_dma(void *addr)
 2125 {
 2126         struct uaudio_softc *sc = addr;
 2127 
 2128         DPRINTF(("uaudio_halt_out_dma: enter\n"));
 2129         if (sc->sc_playchan.pipe != NULL) {
 2130                 uaudio_chan_close(sc, &sc->sc_playchan);
 2131                 sc->sc_playchan.pipe = NULL;
 2132                 uaudio_chan_free_buffers(sc, &sc->sc_playchan);
 2133                 sc->sc_playchan.intr = NULL;
 2134         }
 2135         return (0);
 2136 }
 2137 
 2138 int
 2139 uaudio_halt_in_dma(void *addr)
 2140 {
 2141         struct uaudio_softc *sc = addr;
 2142 
 2143         DPRINTF(("uaudio_halt_in_dma: enter\n"));
 2144         if (sc->sc_recchan.pipe != NULL) {
 2145                 uaudio_chan_close(sc, &sc->sc_recchan);
 2146                 sc->sc_recchan.pipe = NULL;
 2147                 uaudio_chan_free_buffers(sc, &sc->sc_recchan);
 2148                 sc->sc_recchan.intr = NULL;
 2149         }
 2150         return (0);
 2151 }
 2152 
 2153 int
 2154 uaudio_getdev(void *addr, struct audio_device *retp)
 2155 {
 2156         struct uaudio_softc *sc = addr;
 2157 
 2158         DPRINTF(("uaudio_mixer_getdev:\n"));
 2159         if (sc->sc_dying)
 2160                 return (EIO);
 2161 
 2162         *retp = uaudio_device;
 2163         return (0);
 2164 }
 2165 
 2166 /*
 2167  * Make sure the block size is large enough to hold all outstanding transfers.
 2168  */
 2169 int
 2170 uaudio_round_blocksize(void *addr, int blk)
 2171 {
 2172         struct uaudio_softc *sc = addr;
 2173         int bpf;
 2174 
 2175         DPRINTF(("uaudio_round_blocksize: p.bpf=%d r.bpf=%d\n",
 2176                  sc->sc_playchan.bytes_per_frame,
 2177                  sc->sc_recchan.bytes_per_frame));
 2178         if (sc->sc_playchan.bytes_per_frame > sc->sc_recchan.bytes_per_frame) {
 2179                 bpf = sc->sc_playchan.bytes_per_frame
 2180                     + sc->sc_playchan.sample_size;
 2181         } else {
 2182                 bpf = sc->sc_recchan.bytes_per_frame
 2183                     + sc->sc_recchan.sample_size;
 2184         }
 2185         /* XXX */
 2186         bpf *= UAUDIO_NFRAMES * UAUDIO_NCHANBUFS;
 2187 
 2188         bpf = (bpf + 15) &~ 15;
 2189 
 2190         if (blk < bpf)
 2191                 blk = bpf;
 2192 
 2193 #ifdef DIAGNOSTIC
 2194         if (blk <= 0) {
 2195                 printf("uaudio_round_blocksize: blk=%d\n", blk);
 2196                 blk = 512;
 2197         }
 2198 #endif
 2199 
 2200         DPRINTFN(1,("uaudio_round_blocksize: blk=%d\n", blk));
 2201         return (blk);
 2202 }
 2203 
 2204 int
 2205 uaudio_get_props(void *addr)
 2206 {
 2207         return (AUDIO_PROP_FULLDUPLEX | AUDIO_PROP_INDEPENDENT);
 2208 
 2209 }
 2210 
 2211 int
 2212 uaudio_get(struct uaudio_softc *sc, int which, int type, int wValue,
 2213            int wIndex, int len)
 2214 {
 2215         usb_device_request_t req;
 2216         u_int8_t data[4];
 2217         usbd_status err;
 2218         int val;
 2219 
 2220         if (wValue == -1)
 2221                 return (0);
 2222 
 2223         req.bmRequestType = type;
 2224         req.bRequest = which;
 2225         USETW(req.wValue, wValue);
 2226         USETW(req.wIndex, wIndex);
 2227         USETW(req.wLength, len);
 2228         DPRINTFN(2,("uaudio_get: type=0x%02x req=0x%02x wValue=0x%04x "
 2229                     "wIndex=0x%04x len=%d\n",
 2230                     type, which, wValue, wIndex, len));
 2231         err = usbd_do_request(sc->sc_udev, &req, data);
 2232         if (err) {
 2233                 DPRINTF(("uaudio_get: err=%s\n", usbd_errstr(err)));
 2234                 return (-1);
 2235         }
 2236         switch (len) {
 2237         case 1:
 2238                 val = data[0];
 2239                 break;
 2240         case 2:
 2241                 val = data[0] | (data[1] << 8);
 2242                 break;
 2243         default:
 2244                 DPRINTF(("uaudio_get: bad length=%d\n", len));
 2245                 return (-1);
 2246         }
 2247         DPRINTFN(2,("uaudio_get: val=%d\n", val));
 2248         return (val);
 2249 }
 2250 
 2251 void
 2252 uaudio_set(struct uaudio_softc *sc, int which, int type, int wValue,
 2253            int wIndex, int len, int val)
 2254 {
 2255         usb_device_request_t req;
 2256         u_int8_t data[4];
 2257         usbd_status err;
 2258 
 2259         if (wValue == -1)
 2260                 return;
 2261 
 2262         req.bmRequestType = type;
 2263         req.bRequest = which;
 2264         USETW(req.wValue, wValue);
 2265         USETW(req.wIndex, wIndex);
 2266         USETW(req.wLength, len);
 2267         switch (len) {
 2268         case 1:
 2269                 data[0] = val;
 2270                 break;
 2271         case 2:
 2272                 data[0] = val;
 2273                 data[1] = val >> 8;
 2274                 break;
 2275         default:
 2276                 return;
 2277         }
 2278         DPRINTFN(2,("uaudio_set: type=0x%02x req=0x%02x wValue=0x%04x "
 2279                     "wIndex=0x%04x len=%d, val=%d\n",
 2280                     type, which, wValue, wIndex, len, val & 0xffff));
 2281         err = usbd_do_request(sc->sc_udev, &req, data);
 2282 #ifdef UAUDIO_DEBUG
 2283         if (err)
 2284                 DPRINTF(("uaudio_set: err=%d\n", err));
 2285 #endif
 2286 }
 2287 
 2288 int
 2289 uaudio_signext(int type, int val)
 2290 {
 2291         if (!MIX_UNSIGNED(type)) {
 2292                 if (MIX_SIZE(type) == 2)
 2293                         val = (int16_t)val;
 2294                 else
 2295                         val = (int8_t)val;
 2296         }
 2297         return (val);
 2298 }
 2299 
 2300 int
 2301 uaudio_value2bsd(struct mixerctl *mc, int val)
 2302 {
 2303         DPRINTFN(5, ("uaudio_value2bsd: type=%03x val=%d min=%d max=%d ",
 2304                      mc->type, val, mc->minval, mc->maxval));
 2305         if (mc->type == MIX_ON_OFF) {
 2306                 val = (val != 0);
 2307         } else if (mc->type == MIX_SELECTOR) {
 2308                 if (val < mc->minval || val > mc->maxval)
 2309                         val = mc->minval;
 2310         } else
 2311                 val = ((uaudio_signext(mc->type, val) - mc->minval) * 255
 2312                         + mc->mul/2) / mc->mul;
 2313         DPRINTFN(5, ("val'=%d\n", val));
 2314         return (val);
 2315 }
 2316 
 2317 int
 2318 uaudio_bsd2value(struct mixerctl *mc, int val)
 2319 {
 2320         DPRINTFN(5,("uaudio_bsd2value: type=%03x val=%d min=%d max=%d ",
 2321                     mc->type, val, mc->minval, mc->maxval));
 2322         if (mc->type == MIX_ON_OFF) {
 2323                 val = (val != 0);
 2324         } else if (mc->type == MIX_SELECTOR) {
 2325                 if (val < mc->minval || val > mc->maxval)
 2326                         val = mc->minval;
 2327         } else
 2328                 val = (val + mc->delta/2) * mc->mul / 255 + mc->minval;
 2329         DPRINTFN(5, ("val'=%d\n", val));
 2330         return (val);
 2331 }
 2332 
 2333 int
 2334 uaudio_ctl_get(struct uaudio_softc *sc, int which, struct mixerctl *mc,
 2335                int chan)
 2336 {
 2337         int val;
 2338 
 2339         DPRINTFN(5,("uaudio_ctl_get: which=%d chan=%d\n", which, chan));
 2340         val = uaudio_get(sc, which, UT_READ_CLASS_INTERFACE, mc->wValue[chan],
 2341                          mc->wIndex, MIX_SIZE(mc->type));
 2342         return (uaudio_value2bsd(mc, val));
 2343 }
 2344 
 2345 void
 2346 uaudio_ctl_set(struct uaudio_softc *sc, int which, struct mixerctl *mc,
 2347                int chan, int val)
 2348 {
 2349         val = uaudio_bsd2value(mc, val);
 2350         uaudio_set(sc, which, UT_WRITE_CLASS_INTERFACE, mc->wValue[chan],
 2351                    mc->wIndex, MIX_SIZE(mc->type), val);
 2352 }
 2353 
 2354 int
 2355 uaudio_mixer_get_port(void *addr, mixer_ctrl_t *cp)
 2356 {
 2357         struct uaudio_softc *sc = addr;
 2358         struct mixerctl *mc;
 2359         int i, n, vals[MIX_MAX_CHAN], val;
 2360 
 2361         DPRINTFN(2,("uaudio_mixer_get_port: index=%d\n", cp->dev));
 2362 
 2363         if (sc->sc_dying)
 2364                 return (EIO);
 2365 
 2366         n = cp->dev - UAC_NCLASSES;
 2367         if (n < 0 || n >= sc->sc_nctls)
 2368                 return (ENXIO);
 2369         mc = &sc->sc_ctls[n];
 2370 
 2371         if (mc->type == MIX_ON_OFF) {
 2372                 if (cp->type != AUDIO_MIXER_ENUM)
 2373                         return (EINVAL);
 2374                 cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0);
 2375         } else if (mc->type == MIX_SELECTOR) {
 2376                 if (cp->type != AUDIO_MIXER_ENUM)
 2377                         return (EINVAL);
 2378                 cp->un.ord = uaudio_ctl_get(sc, GET_CUR, mc, 0);
 2379         } else {
 2380                 if (cp->type != AUDIO_MIXER_VALUE)
 2381                         return (EINVAL);
 2382                 if (cp->un.value.num_channels != 1 &&
 2383                     cp->un.value.num_channels != mc->nchan)
 2384                         return (EINVAL);
 2385                 for (i = 0; i < mc->nchan; i++)
 2386                         vals[i] = uaudio_ctl_get(sc, GET_CUR, mc, i);
 2387                 if (cp->un.value.num_channels == 1 && mc->nchan != 1) {
 2388                         for (val = 0, i = 0; i < mc->nchan; i++)
 2389                                 val += vals[i];
 2390                         vals[0] = val / mc->nchan;
 2391                 }
 2392                 for (i = 0; i < cp->un.value.num_channels; i++)
 2393                         cp->un.value.level[i] = vals[i];
 2394         }
 2395 
 2396         return (0);
 2397 }
 2398 
 2399 int
 2400 uaudio_mixer_set_port(void *addr, mixer_ctrl_t *cp)
 2401 {
 2402         struct uaudio_softc *sc = addr;
 2403         struct mixerctl *mc;
 2404         int i, n, vals[MIX_MAX_CHAN];
 2405 
 2406         DPRINTFN(2,("uaudio_mixer_set_port: index = %d\n", cp->dev));
 2407         if (sc->sc_dying)
 2408                 return (EIO);
 2409 
 2410         n = cp->dev - UAC_NCLASSES;
 2411         if (n < 0 || n >= sc->sc_nctls)
 2412                 return (ENXIO);
 2413         mc = &sc->sc_ctls[n];
 2414 
 2415         if (mc->type == MIX_ON_OFF) {
 2416                 if (cp->type != AUDIO_MIXER_ENUM)
 2417                         return (EINVAL);
 2418                 uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord);
 2419         } else if (mc->type == MIX_SELECTOR) {
 2420                 if (cp->type != AUDIO_MIXER_ENUM)
 2421                         return (EINVAL);
 2422                 uaudio_ctl_set(sc, SET_CUR, mc, 0, cp->un.ord);
 2423         } else {
 2424                 if (cp->type != AUDIO_MIXER_VALUE)
 2425                         return (EINVAL);
 2426                 if (cp->un.value.num_channels == 1)
 2427                         for (i = 0; i < mc->nchan; i++)
 2428                                 vals[i] = cp->un.value.level[0];
 2429                 else if (cp->un.value.num_channels == mc->nchan)
 2430                         for (i = 0; i < mc->nchan; i++)
 2431                                 vals[i] = cp->un.value.level[i];
 2432                 else
 2433                         return (EINVAL);
 2434                 for (i = 0; i < mc->nchan; i++)
 2435                         uaudio_ctl_set(sc, SET_CUR, mc, i, vals[i]);
 2436         }
 2437         return (0);
 2438 }
 2439 
 2440 int
 2441 uaudio_trigger_input(void *addr, void *start, void *end, int blksize,
 2442                      void (*intr)(void *), void *arg,
 2443                      struct audio_params *param)
 2444 {
 2445         struct uaudio_softc *sc = addr;
 2446         struct chan *ch = &sc->sc_recchan;
 2447         usbd_status err;
 2448         int i, s;
 2449 
 2450         if (sc->sc_dying)
 2451                 return (EIO);
 2452 
 2453         DPRINTFN(3,("uaudio_trigger_input: sc=%p start=%p end=%p "
 2454                     "blksize=%d\n", sc, start, end, blksize));
 2455 
 2456         uaudio_chan_set_param(ch, start, end, blksize);
 2457         DPRINTFN(3,("uaudio_trigger_input: sample_size=%d bytes/frame=%d "
 2458                     "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
 2459                     ch->fraction));
 2460 
 2461         err = uaudio_chan_alloc_buffers(sc, ch);
 2462         if (err)
 2463                 return (EIO);
 2464 
 2465         err = uaudio_chan_open(sc, ch);
 2466         if (err) {
 2467                 uaudio_chan_free_buffers(sc, ch);
 2468                 return (EIO);
 2469         }
 2470 
 2471         ch->intr = intr;
 2472         ch->arg = arg;
 2473 
 2474         s = splusb();
 2475         for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */
 2476                 uaudio_chan_rtransfer(ch);
 2477         splx(s);
 2478 
 2479         return (0);
 2480 }
 2481 
 2482 int
 2483 uaudio_trigger_output(void *addr, void *start, void *end, int blksize,
 2484                       void (*intr)(void *), void *arg,
 2485                       struct audio_params *param)
 2486 {
 2487         struct uaudio_softc *sc = addr;
 2488         struct chan *ch = &sc->sc_playchan;
 2489         usbd_status err;
 2490         int i, s;
 2491 
 2492         if (sc->sc_dying)
 2493                 return (EIO);
 2494 
 2495         DPRINTFN(3,("uaudio_trigger_output: sc=%p start=%p end=%p "
 2496                     "blksize=%d\n", sc, start, end, blksize));
 2497 
 2498         uaudio_chan_set_param(ch, start, end, blksize);
 2499         DPRINTFN(3,("uaudio_trigger_output: sample_size=%d bytes/frame=%d "
 2500                     "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
 2501                     ch->fraction));
 2502 
 2503         err = uaudio_chan_alloc_buffers(sc, ch);
 2504         if (err)
 2505                 return (EIO);
 2506 
 2507         err = uaudio_chan_open(sc, ch);
 2508         if (err) {
 2509                 uaudio_chan_free_buffers(sc, ch);
 2510                 return (EIO);
 2511         }
 2512 
 2513         ch->intr = intr;
 2514         ch->arg = arg;
 2515 
 2516         s = splusb();
 2517         for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */
 2518                 uaudio_chan_ptransfer(ch);
 2519         splx(s);
 2520 
 2521         return (0);
 2522 }
 2523 
 2524 /* Set up a pipe for a channel. */
 2525 usbd_status
 2526 uaudio_chan_open(struct uaudio_softc *sc, struct chan *ch)
 2527 {
 2528         struct as_info *as = &sc->sc_alts[ch->altidx];
 2529         int endpt = as->edesc->bEndpointAddress;
 2530         usbd_status err;
 2531 
 2532         DPRINTF(("uaudio_chan_open: endpt=0x%02x, speed=%d, alt=%d\n",
 2533                  endpt, ch->sample_rate, as->alt));
 2534 
 2535         /* Set alternate interface corresponding to the mode. */
 2536         err = usbd_set_interface(as->ifaceh, as->alt);
 2537         if (err)
 2538                 return (err);
 2539 
 2540         /*
 2541          * If just one sampling rate is supported,
 2542          * no need to call uaudio_set_speed().
 2543          * Roland SD-90 freezes by a SAMPLING_FREQ_CONTROL request.
 2544          */
 2545         if (as->asf1desc->bSamFreqType != 1) {
 2546                 err = uaudio_set_speed(sc, endpt, ch->sample_rate);
 2547                 if (err)
 2548                         DPRINTF(("uaudio_chan_open: set_speed failed err=%s\n",
 2549                                  usbd_errstr(err)));
 2550         }
 2551 
 2552         ch->pipe = 0;
 2553         ch->sync_pipe = 0;
 2554         DPRINTF(("uaudio_chan_open: create pipe to 0x%02x\n", endpt));
 2555         err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->pipe);
 2556         if (err)
 2557                 return err;
 2558         if (as->edesc1 != NULL) {
 2559                 endpt = as->edesc1->bEndpointAddress;
 2560                 DPRINTF(("uaudio_chan_open: create sync-pipe to 0x%02x\n", endpt));
 2561                 err = usbd_open_pipe(as->ifaceh, endpt, 0, &ch->sync_pipe);
 2562         }
 2563         return err;
 2564 }
 2565 
 2566 void
 2567 uaudio_chan_close(struct uaudio_softc *sc, struct chan *ch)
 2568 {
 2569         struct as_info *as = &sc->sc_alts[ch->altidx];
 2570 
 2571         as->sc_busy = 0;
 2572         if (sc->sc_nullalt >= 0) {
 2573                 DPRINTF(("uaudio_chan_close: set null alt=%d\n",
 2574                          sc->sc_nullalt));
 2575                 usbd_set_interface(as->ifaceh, sc->sc_nullalt);
 2576         }
 2577         if (ch->pipe) {
 2578                 usbd_abort_pipe(ch->pipe);
 2579                 usbd_close_pipe(ch->pipe);
 2580         }
 2581         if (ch->sync_pipe) {
 2582                 usbd_abort_pipe(ch->sync_pipe);
 2583                 usbd_close_pipe(ch->sync_pipe);
 2584         }
 2585 }
 2586 
 2587 usbd_status
 2588 uaudio_chan_alloc_buffers(struct uaudio_softc *sc, struct chan *ch)
 2589 {
 2590         usbd_xfer_handle xfer;
 2591         void *buf;
 2592         int i, size;
 2593 
 2594         size = (ch->bytes_per_frame + ch->sample_size) * UAUDIO_NFRAMES;
 2595         for (i = 0; i < UAUDIO_NCHANBUFS; i++) {
 2596                 xfer = usbd_alloc_xfer(sc->sc_udev);
 2597                 if (xfer == 0)
 2598                         goto bad;
 2599                 ch->chanbufs[i].xfer = xfer;
 2600                 buf = usbd_alloc_buffer(xfer, size);
 2601                 if (buf == 0) {
 2602                         i++;
 2603                         goto bad;
 2604                 }
 2605                 ch->chanbufs[i].buffer = buf;
 2606                 ch->chanbufs[i].chan = ch;
 2607         }
 2608 
 2609         return (USBD_NORMAL_COMPLETION);
 2610 
 2611 bad:
 2612         while (--i >= 0)
 2613                 /* implicit buffer free */
 2614                 usbd_free_xfer(ch->chanbufs[i].xfer);
 2615         return (USBD_NOMEM);
 2616 }
 2617 
 2618 void
 2619 uaudio_chan_free_buffers(struct uaudio_softc *sc, struct chan *ch)
 2620 {
 2621         int i;
 2622 
 2623         for (i = 0; i < UAUDIO_NCHANBUFS; i++)
 2624                 usbd_free_xfer(ch->chanbufs[i].xfer);
 2625 }
 2626 
 2627 /* Called at splusb() */
 2628 void
 2629 uaudio_chan_ptransfer(struct chan *ch)
 2630 {
 2631         struct chanbuf *cb;
 2632         int i, n, size, residue, total;
 2633 
 2634         if (ch->sc->sc_dying)
 2635                 return;
 2636 
 2637         /* Pick the next channel buffer. */
 2638         cb = &ch->chanbufs[ch->curchanbuf];
 2639         if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
 2640                 ch->curchanbuf = 0;
 2641 
 2642         /* Compute the size of each frame in the next transfer. */
 2643         residue = ch->residue;
 2644         total = 0;
 2645         for (i = 0; i < UAUDIO_NFRAMES; i++) {
 2646                 size = ch->bytes_per_frame;
 2647                 residue += ch->fraction;
 2648                 if (residue >= USB_FRAMES_PER_SECOND) {
 2649                         if ((ch->sc->sc_altflags & UA_NOFRAC) == 0)
 2650                                 size += ch->sample_size;
 2651                         residue -= USB_FRAMES_PER_SECOND;
 2652                 }
 2653                 cb->sizes[i] = size;
 2654                 total += size;
 2655         }
 2656         ch->residue = residue;
 2657         cb->size = total;
 2658 
 2659         /*
 2660          * Transfer data from upper layer buffer to channel buffer, taking
 2661          * care of wrapping the upper layer buffer.
 2662          */
 2663         n = min(total, ch->end - ch->cur);
 2664         memcpy(cb->buffer, ch->cur, n);
 2665         ch->cur += n;
 2666         if (ch->cur >= ch->end)
 2667                 ch->cur = ch->start;
 2668         if (total > n) {
 2669                 total -= n;
 2670                 memcpy(cb->buffer + n, ch->cur, total);
 2671                 ch->cur += total;
 2672         }
 2673 
 2674 #ifdef UAUDIO_DEBUG
 2675         if (uaudiodebug > 8) {
 2676                 DPRINTF(("uaudio_chan_ptransfer: buffer=%p, residue=0.%03d\n",
 2677                          cb->buffer, ch->residue));
 2678                 for (i = 0; i < UAUDIO_NFRAMES; i++) {
 2679                         DPRINTF(("   [%d] length %d\n", i, cb->sizes[i]));
 2680                 }
 2681         }
 2682 #endif
 2683 
 2684         DPRINTFN(5,("uaudio_chan_transfer: ptransfer xfer=%p\n", cb->xfer));
 2685         /* Fill the request */
 2686         usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes,
 2687                              UAUDIO_NFRAMES, USBD_NO_COPY,
 2688                              uaudio_chan_pintr);
 2689 
 2690         (void)usbd_transfer(cb->xfer);
 2691 }
 2692 
 2693 void
 2694 uaudio_chan_pintr(usbd_xfer_handle xfer, usbd_private_handle priv,
 2695                   usbd_status status)
 2696 {
 2697         struct chanbuf *cb = priv;
 2698         struct chan *ch = cb->chan;
 2699         u_int32_t count;
 2700         int s;
 2701 
 2702         /* Return if we are aborting. */
 2703         if (status == USBD_CANCELLED)
 2704                 return;
 2705 
 2706         usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
 2707         DPRINTFN(5,("uaudio_chan_pintr: count=%d, transferred=%d\n",
 2708                     count, ch->transferred));
 2709 #ifdef DIAGNOSTIC
 2710         if (count != cb->size) {
 2711                 printf("uaudio_chan_pintr: count(%d) != size(%d)\n",
 2712                        count, cb->size);
 2713         }
 2714 #endif
 2715 
 2716         ch->transferred += cb->size;
 2717         s = splaudio();
 2718         /* Call back to upper layer */
 2719         while (ch->transferred >= ch->blksize) {
 2720                 ch->transferred -= ch->blksize;
 2721                 DPRINTFN(5,("uaudio_chan_pintr: call %p(%p)\n",
 2722                             ch->intr, ch->arg));
 2723                 ch->intr(ch->arg);
 2724         }
 2725         splx(s);
 2726 
 2727         /* start next transfer */
 2728         uaudio_chan_ptransfer(ch);
 2729 }
 2730 
 2731 /* Called at splusb() */
 2732 void
 2733 uaudio_chan_rtransfer(struct chan *ch)
 2734 {
 2735         struct chanbuf *cb;
 2736         int i, size, residue, total;
 2737 
 2738         if (ch->sc->sc_dying)
 2739                 return;
 2740 
 2741         /* Pick the next channel buffer. */
 2742         cb = &ch->chanbufs[ch->curchanbuf];
 2743         if (++ch->curchanbuf >= UAUDIO_NCHANBUFS)
 2744                 ch->curchanbuf = 0;
 2745 
 2746         /* Compute the size of each frame in the next transfer. */
 2747         residue = ch->residue;
 2748         total = 0;
 2749         for (i = 0; i < UAUDIO_NFRAMES; i++) {
 2750                 size = ch->bytes_per_frame;
 2751                 cb->sizes[i] = size;
 2752                 cb->offsets[i] = total;
 2753                 total += size;
 2754         }
 2755         ch->residue = residue;
 2756         cb->size = total;
 2757 
 2758 #ifdef UAUDIO_DEBUG
 2759         if (uaudiodebug > 8) {
 2760                 DPRINTF(("uaudio_chan_rtransfer: buffer=%p, residue=0.%03d\n",
 2761                          cb->buffer, ch->residue));
 2762                 for (i = 0; i < UAUDIO_NFRAMES; i++) {
 2763                         DPRINTF(("   [%d] length %d\n", i, cb->sizes[i]));
 2764                 }
 2765         }
 2766 #endif
 2767 
 2768         DPRINTFN(5,("uaudio_chan_rtransfer: transfer xfer=%p\n", cb->xfer));
 2769         /* Fill the request */
 2770         usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes,
 2771                              UAUDIO_NFRAMES, USBD_NO_COPY,
 2772                              uaudio_chan_rintr);
 2773 
 2774         (void)usbd_transfer(cb->xfer);
 2775 }
 2776 
 2777 void
 2778 uaudio_chan_rintr(usbd_xfer_handle xfer, usbd_private_handle priv,
 2779                   usbd_status status)
 2780 {
 2781         struct chanbuf *cb = priv;
 2782         struct chan *ch = cb->chan;
 2783         u_int32_t count;
 2784         int s, i, n, frsize;
 2785 
 2786         /* Return if we are aborting. */
 2787         if (status == USBD_CANCELLED)
 2788                 return;
 2789 
 2790         usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
 2791         DPRINTFN(5,("uaudio_chan_rintr: count=%d, transferred=%d\n",
 2792                     count, ch->transferred));
 2793 
 2794         /* count < cb->size is normal for asynchronous source */
 2795 #ifdef DIAGNOSTIC
 2796         if (count > cb->size) {
 2797                 printf("uaudio_chan_rintr: count(%d) > size(%d)\n",
 2798                        count, cb->size);
 2799         }
 2800 #endif
 2801 
 2802         /*
 2803          * Transfer data from channel buffer to upper layer buffer, taking
 2804          * care of wrapping the upper layer buffer.
 2805          */
 2806         for(i = 0; i < UAUDIO_NFRAMES; i++) {
 2807                 frsize = cb->sizes[i];
 2808                 n = min(frsize, ch->end - ch->cur);
 2809                 memcpy(ch->cur, cb->buffer + cb->offsets[i], n);
 2810                 ch->cur += n;
 2811                 if (ch->cur >= ch->end)
 2812                         ch->cur = ch->start;
 2813                 if (frsize > n) {
 2814                         memcpy(ch->cur, cb->buffer + cb->offsets[i] + n,
 2815                             frsize - n);
 2816                         ch->cur += frsize - n;
 2817                 }
 2818         }
 2819 
 2820         /* Call back to upper layer */
 2821         ch->transferred += count;
 2822         s = splaudio();
 2823         while (ch->transferred >= ch->blksize) {
 2824                 ch->transferred -= ch->blksize;
 2825                 DPRINTFN(5,("uaudio_chan_rintr: call %p(%p)\n",
 2826                             ch->intr, ch->arg));
 2827                 ch->intr(ch->arg);
 2828         }
 2829         splx(s);
 2830 
 2831         /* start next transfer */
 2832         uaudio_chan_rtransfer(ch);
 2833 }
 2834 
 2835 void
 2836 uaudio_chan_init(struct chan *ch, int altidx, const struct audio_params *param,
 2837     int maxpktsize)
 2838 {
 2839         int samples_per_frame, sample_size;
 2840 
 2841         ch->altidx = altidx;
 2842         sample_size = param->precision * param->factor * param->hw_channels / 8;
 2843         samples_per_frame = param->hw_sample_rate / USB_FRAMES_PER_SECOND;
 2844         ch->sample_size = sample_size;
 2845         ch->sample_rate = param->hw_sample_rate;
 2846         if (maxpktsize == 0) {
 2847                 ch->fraction = param->hw_sample_rate % USB_FRAMES_PER_SECOND;
 2848                 ch->bytes_per_frame = samples_per_frame * sample_size;
 2849         } else {
 2850                 ch->fraction = 0;
 2851                 ch->bytes_per_frame = maxpktsize;
 2852         }
 2853         ch->residue = 0;
 2854 }
 2855 
 2856 void
 2857 uaudio_chan_set_param(struct chan *ch, u_char *start, u_char *end, int blksize)
 2858 {
 2859         ch->start = start;
 2860         ch->end = end;
 2861         ch->cur = start;
 2862         ch->blksize = blksize;
 2863         ch->transferred = 0;
 2864 
 2865         ch->curchanbuf = 0;
 2866 }
 2867 
 2868 void
 2869 uaudio_get_minmax_rates(int nalts, const struct as_info *alts,
 2870                         const struct audio_params *p, int mode,
 2871                         u_long *min, u_long *max)
 2872 {
 2873         const struct usb_audio_streaming_type1_descriptor *a1d;
 2874         int i, j;
 2875 
 2876         *min = ULONG_MAX;
 2877         *max = 0;
 2878         for (i = 0; i < nalts; i++) {
 2879                 a1d = alts[i].asf1desc;
 2880                 if (alts[i].sc_busy)
 2881                         continue;
 2882                 if (p->hw_channels != a1d->bNrChannels)
 2883                         continue;
 2884                 if (p->hw_precision != a1d->bBitResolution)
 2885                         continue;
 2886                 if (p->hw_encoding != alts[i].encoding)
 2887                         continue;
 2888                 if (mode != UE_GET_DIR(alts[i].edesc->bEndpointAddress))
 2889                         continue;
 2890                 if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
 2891                         DPRINTFN(2,("uaudio_get_minmax_rates: cont %d-%d\n",
 2892                                     UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
 2893                         if (UA_SAMP_LO(a1d) < *min)
 2894                                 *min = UA_SAMP_LO(a1d);
 2895                         if (UA_SAMP_HI(a1d) > *max)
 2896                                 *max = UA_SAMP_HI(a1d);
 2897                 } else {
 2898                         for (j = 0; j < a1d->bSamFreqType; j++) {
 2899                                 DPRINTFN(2,("uaudio_get_minmax_rates: disc #%d: %d\n",
 2900                                             j, UA_GETSAMP(a1d, j)));
 2901                                 if (UA_GETSAMP(a1d, j) < *min)
 2902                                         *min = UA_GETSAMP(a1d, j);
 2903                                 if (UA_GETSAMP(a1d, j) > *max)
 2904                                         *max = UA_GETSAMP(a1d, j);
 2905                         }
 2906                 }
 2907         }
 2908 }
 2909 
 2910 int
 2911 uaudio_match_alt_sub(int nalts, const struct as_info *alts,
 2912                      const struct audio_params *p, int mode, u_long rate)
 2913 {
 2914         const struct usb_audio_streaming_type1_descriptor *a1d;
 2915         int i, j;
 2916 
 2917         DPRINTF(("uaudio_match_alt_sub: search for %luHz %dch\n",
 2918                  rate, p->hw_channels));
 2919         for (i = 0; i < nalts; i++) {
 2920                 a1d = alts[i].asf1desc;
 2921                 if (alts[i].sc_busy)
 2922                         continue;
 2923                 if (p->hw_channels != a1d->bNrChannels)
 2924                         continue;
 2925                 if (p->hw_precision != a1d->bBitResolution)
 2926                         continue;
 2927                 if (p->hw_encoding != alts[i].encoding)
 2928                         continue;
 2929                 if (mode != UE_GET_DIR(alts[i].edesc->bEndpointAddress))
 2930                         continue;
 2931                 if (a1d->bSamFreqType == UA_SAMP_CONTNUOUS) {
 2932                         DPRINTFN(3,("uaudio_match_alt_sub: cont %d-%d\n",
 2933                                     UA_SAMP_LO(a1d), UA_SAMP_HI(a1d)));
 2934                         if (UA_SAMP_LO(a1d) <= rate && rate <= UA_SAMP_HI(a1d))
 2935                                 return i;
 2936                 } else {
 2937                         for (j = 0; j < a1d->bSamFreqType; j++) {
 2938                                 DPRINTFN(3,("uaudio_match_alt_sub: disc #%d: %d\n",
 2939                                             j, UA_GETSAMP(a1d, j)));
 2940                                 /* XXX allow for some slack */
 2941                                 if (UA_GETSAMP(a1d, j) == rate)
 2942                                         return i;
 2943                         }
 2944                 }
 2945         }
 2946         return -1;
 2947 }
 2948 
 2949 int
 2950 uaudio_match_alt_chan(int nalts, const struct as_info *alts,
 2951                       struct audio_params *p, int mode)
 2952 {
 2953         int i, n;
 2954         u_long min, max;
 2955         u_long rate;
 2956 
 2957         /* Exact match */
 2958         DPRINTF(("uaudio_match_alt_chan: examine %ldHz %dch %dbit.\n",
 2959                  p->sample_rate, p->hw_channels, p->hw_precision));
 2960         i = uaudio_match_alt_sub(nalts, alts, p, mode, p->sample_rate);
 2961         if (i >= 0)
 2962                 return i;
 2963 
 2964         uaudio_get_minmax_rates(nalts, alts, p, mode, &min, &max);
 2965         DPRINTF(("uaudio_match_alt_chan: min=%lu max=%lu\n", min, max));
 2966         if (max <= 0)
 2967                 return -1;
 2968         /* Search for biggers */
 2969         n = 2;
 2970         while ((rate = p->sample_rate * n++) <= max) {
 2971                 i = uaudio_match_alt_sub(nalts, alts, p, mode, rate);
 2972                 if (i >= 0) {
 2973                         p->hw_sample_rate = rate;
 2974                         return i;
 2975                 }
 2976         }
 2977         if (p->sample_rate >= min) {
 2978                 i = uaudio_match_alt_sub(nalts, alts, p, mode, max);
 2979                 if (i >= 0) {
 2980                         p->hw_sample_rate = max;
 2981                         return i;
 2982                 }
 2983         } else {
 2984                 i = uaudio_match_alt_sub(nalts, alts, p, mode, min);
 2985                 if (i >= 0) {
 2986                         p->hw_sample_rate = min;
 2987                         return i;
 2988                 }
 2989         }
 2990         return -1;
 2991 }
 2992 
 2993 int
 2994 uaudio_match_alt(int nalts, const struct as_info *alts,
 2995                  struct audio_params *p, int mode)
 2996 {
 2997         int i, n;
 2998 
 2999         mode = mode == AUMODE_PLAY ? UE_DIR_OUT : UE_DIR_IN;
 3000         i = uaudio_match_alt_chan(nalts, alts, p, mode);
 3001         if (i >= 0)
 3002                 return i;
 3003 
 3004         for (n = p->channels + 1; n <= AUDIO_MAX_CHANNELS; n++) {
 3005                 p->hw_channels = n;
 3006                 i = uaudio_match_alt_chan(nalts, alts, p, mode);
 3007                 if (i >= 0)
 3008                         return i;
 3009         }
 3010 
 3011         if (p->channels != 2)
 3012                 return -1;
 3013         p->hw_channels = 1;
 3014         return uaudio_match_alt_chan(nalts, alts, p, mode);
 3015 }
 3016 
 3017 int
 3018 uaudio_set_params(void *addr, int setmode, int usemode,
 3019                   struct audio_params *play, struct audio_params *rec)
 3020 {
 3021         struct uaudio_softc *sc = addr;
 3022         int flags = sc->sc_altflags;
 3023         int factor;
 3024         int enc, i;
 3025         int paltidx=-1, raltidx=-1;
 3026         void (*swcode)(void *, u_char *buf, int cnt);
 3027         struct audio_params *p;
 3028         int mode;
 3029 
 3030         if (sc->sc_dying)
 3031                 return (EIO);
 3032 
 3033         if (((usemode & AUMODE_PLAY) && sc->sc_playchan.pipe != NULL) ||
 3034             ((usemode & AUMODE_RECORD) && sc->sc_recchan.pipe != NULL))
 3035                 return (EBUSY);
 3036 
 3037         if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1)
 3038                 sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 0;
 3039         if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1)
 3040                 sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 0;
 3041 
 3042         /* Some uaudio devices are unidirectional.  Don't try to find a
 3043            matching mode for the unsupported direction. */
 3044         setmode &= sc->sc_mode;
 3045 
 3046         for (mode = AUMODE_RECORD; mode != -1;
 3047              mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
 3048                 if ((setmode & mode) == 0)
 3049                         continue;
 3050 
 3051                 p = (mode == AUMODE_PLAY) ? play : rec;
 3052 
 3053                 factor = 1;
 3054                 swcode = 0;
 3055                 enc = p->encoding;
 3056                 switch (enc) {
 3057                 case AUDIO_ENCODING_SLINEAR_BE:
 3058                         /* FALLTHROUGH */
 3059                 case AUDIO_ENCODING_SLINEAR_LE:
 3060                         if (enc == AUDIO_ENCODING_SLINEAR_BE
 3061                             && p->precision == 16 && (flags & HAS_16)) {
 3062                                 swcode = swap_bytes;
 3063                                 enc = AUDIO_ENCODING_SLINEAR_LE;
 3064                         } else if (p->precision == 8) {
 3065                                 if (flags & HAS_8) {
 3066                                         /* No conversion */
 3067                                 } else if (flags & HAS_8U) {
 3068                                         swcode = change_sign8;
 3069                                         enc = AUDIO_ENCODING_ULINEAR_LE;
 3070                                 } else if (flags & HAS_16) {
 3071                                         factor = 2;
 3072                                         p->hw_precision = 16;
 3073                                         if (mode == AUMODE_PLAY)
 3074                                                 swcode = linear8_to_linear16_le;
 3075                                         else
 3076                                                 swcode = linear16_to_linear8_le;
 3077                                 }
 3078                         }
 3079                         break;
 3080                 case AUDIO_ENCODING_ULINEAR_BE:
 3081                         /* FALLTHROUGH */
 3082                 case AUDIO_ENCODING_ULINEAR_LE:
 3083                         if (p->precision == 16) {
 3084                                 if (enc == AUDIO_ENCODING_ULINEAR_LE)
 3085                                         swcode = change_sign16;
 3086                                 else if (mode == AUMODE_PLAY)
 3087                                         swcode = swap_bytes_change_sign16;
 3088                                 else
 3089                                         swcode = change_sign16_swap_bytes;
 3090                                 enc = AUDIO_ENCODING_SLINEAR_LE;
 3091                         } else if (p->precision == 8) {
 3092                                 if (flags & HAS_8U) {
 3093                                         /* No conversion */
 3094                                 } else if (flags & HAS_8) {
 3095                                         swcode = change_sign8;
 3096                                         enc = AUDIO_ENCODING_SLINEAR_LE;
 3097                                 } else if (flags & HAS_16) {
 3098                                         factor = 2;
 3099                                         p->hw_precision = 16;
 3100                                         enc = AUDIO_ENCODING_SLINEAR_LE;
 3101                                         if (mode == AUMODE_PLAY)
 3102                                                 swcode = ulinear8_to_linear16_le;
 3103                                         else
 3104                                                 swcode = linear16_to_ulinear8_le;
 3105                                 }
 3106                         }
 3107                         break;
 3108                 case AUDIO_ENCODING_ULAW:
 3109                         if (flags & HAS_MULAW)
 3110                                 break;
 3111                         if (flags & HAS_16) {
 3112                                 if (mode == AUMODE_PLAY)
 3113                                         swcode = mulaw_to_slinear16_le;
 3114                                 else
 3115                                         swcode = slinear16_to_mulaw_le;
 3116                                 factor = 2;
 3117                                 enc = AUDIO_ENCODING_SLINEAR_LE;
 3118                                 p->hw_precision = 16;
 3119                         } else if (flags & HAS_8U) {
 3120                                 if (mode == AUMODE_PLAY)
 3121                                         swcode = mulaw_to_ulinear8;
 3122                                 else
 3123                                         swcode = ulinear8_to_mulaw;
 3124                                 enc = AUDIO_ENCODING_ULINEAR_LE;
 3125                         } else if (flags & HAS_8) {
 3126                                 if (mode == AUMODE_PLAY)
 3127                                         swcode = mulaw_to_slinear8;
 3128                                 else
 3129                                         swcode = slinear8_to_mulaw;
 3130                                 enc = AUDIO_ENCODING_SLINEAR_LE;
 3131                         } else
 3132                                 return (EINVAL);
 3133                         break;
 3134                 case AUDIO_ENCODING_ALAW:
 3135                         if (flags & HAS_ALAW)
 3136                                 break;
 3137                         if (mode == AUMODE_PLAY && (flags & HAS_16)) {
 3138                                 swcode = alaw_to_slinear16_le;
 3139                                 factor = 2;
 3140                                 enc = AUDIO_ENCODING_SLINEAR_LE;
 3141                                 p->hw_precision = 16;
 3142                         } else if (flags & HAS_8U) {
 3143                                 if (mode == AUMODE_PLAY)
 3144                                         swcode = alaw_to_ulinear8;
 3145                                 else
 3146                                         swcode = ulinear8_to_alaw;
 3147                                 enc = AUDIO_ENCODING_ULINEAR_LE;
 3148                         } else if (flags & HAS_8) {
 3149                                 if (mode == AUMODE_PLAY)
 3150                                         swcode = alaw_to_slinear8;
 3151                                 else
 3152                                         swcode = slinear8_to_alaw;
 3153                                 enc = AUDIO_ENCODING_SLINEAR_LE;
 3154                         } else
 3155                                 return (EINVAL);
 3156                         break;
 3157                 default:
 3158                         return (EINVAL);
 3159                 }
 3160                 /* XXX do some other conversions... */
 3161 
 3162                 DPRINTF(("uaudio_set_params: chan=%d prec=%d enc=%d rate=%ld\n",
 3163                          p->channels, p->hw_precision, enc, p->sample_rate));
 3164 
 3165                 p->hw_encoding = enc;
 3166                 i = uaudio_match_alt(sc->sc_nalts, sc->sc_alts, p, mode);
 3167                 if (i < 0)
 3168                         return (EINVAL);
 3169 
 3170                 p->sw_code = swcode;
 3171                 p->factor  = factor;
 3172 
 3173                 if (mode == AUMODE_PLAY)
 3174                         paltidx = i;
 3175                 else
 3176                         raltidx = i;
 3177         }
 3178 
 3179         if ((setmode & AUMODE_PLAY)) {
 3180                 /* XXX abort transfer if currently happening? */
 3181                 uaudio_chan_init(&sc->sc_playchan, paltidx, play, 0);
 3182         }
 3183         if ((setmode & AUMODE_RECORD)) {
 3184                 /* XXX abort transfer if currently happening? */
 3185                 uaudio_chan_init(&sc->sc_recchan, raltidx, rec,
 3186                     UGETW(sc->sc_alts[raltidx].edesc->wMaxPacketSize));
 3187         }
 3188 
 3189         if ((usemode & AUMODE_PLAY) && sc->sc_playchan.altidx != -1)
 3190                 sc->sc_alts[sc->sc_playchan.altidx].sc_busy = 1;
 3191         if ((usemode & AUMODE_RECORD) && sc->sc_recchan.altidx != -1)
 3192                 sc->sc_alts[sc->sc_recchan.altidx].sc_busy = 1;
 3193 
 3194         DPRINTF(("uaudio_set_params: use altidx=p%d/r%d, altno=p%d/r%d\n",
 3195                  sc->sc_playchan.altidx, sc->sc_recchan.altidx,
 3196                  (sc->sc_playchan.altidx >= 0)
 3197                    ?sc->sc_alts[sc->sc_playchan.altidx].idesc->bAlternateSetting
 3198                    : -1,
 3199                  (sc->sc_recchan.altidx >= 0)
 3200                    ? sc->sc_alts[sc->sc_recchan.altidx].idesc->bAlternateSetting
 3201                    : -1));
 3202 
 3203         return (0);
 3204 }
 3205 
 3206 usbd_status
 3207 uaudio_set_speed(struct uaudio_softc *sc, int endpt, u_int speed)
 3208 {
 3209         usb_device_request_t req;
 3210         u_int8_t data[3];
 3211 
 3212         DPRINTFN(5,("uaudio_set_speed: endpt=%d speed=%u\n", endpt, speed));
 3213         req.bmRequestType = UT_WRITE_CLASS_ENDPOINT;
 3214         req.bRequest = SET_CUR;
 3215         USETW2(req.wValue, SAMPLING_FREQ_CONTROL, 0);
 3216         USETW(req.wIndex, endpt);
 3217         USETW(req.wLength, 3);
 3218         data[0] = speed;
 3219         data[1] = speed >> 8;
 3220         data[2] = speed >> 16;
 3221 
 3222         return (usbd_do_request(sc->sc_udev, &req, data));
 3223 }

/* [<][>][^][v][top][bottom][index][help] */