The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/usb/template/usb_template_audio.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* $FreeBSD$ */
    2 /*-
    3  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    4  *
    5  * Copyright (c) 2010 Hans Petter Selasky
    6  * Copyright (c) 2018 The FreeBSD Foundation
    7  * All rights reserved.
    8  *
    9  * Portions of this software were developed by Edward Tomasz Napierala
   10  * under sponsorship from the FreeBSD Foundation.
   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  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31  * SUCH DAMAGE.
   32  */
   33 
   34 /*
   35  * This file contains the USB template for an USB Audio Device.
   36  */
   37 
   38 #ifdef USB_GLOBAL_INCLUDE_FILE
   39 #include USB_GLOBAL_INCLUDE_FILE
   40 #else
   41 #include <sys/stdint.h>
   42 #include <sys/stddef.h>
   43 #include <sys/param.h>
   44 #include <sys/queue.h>
   45 #include <sys/types.h>
   46 #include <sys/systm.h>
   47 #include <sys/kernel.h>
   48 #include <sys/bus.h>
   49 #include <sys/module.h>
   50 #include <sys/lock.h>
   51 #include <sys/mutex.h>
   52 #include <sys/condvar.h>
   53 #include <sys/sysctl.h>
   54 #include <sys/sx.h>
   55 #include <sys/unistd.h>
   56 #include <sys/callout.h>
   57 #include <sys/malloc.h>
   58 #include <sys/priv.h>
   59 
   60 #include <dev/usb/usb.h>
   61 #include <dev/usb/usbdi.h>
   62 #include <dev/usb/usb_core.h>
   63 #include <dev/usb/usb_cdc.h>
   64 #include <dev/usb/usb_ioctl.h>
   65 #include <dev/usb/usb_util.h>
   66 
   67 #include <dev/usb/template/usb_template.h>
   68 #endif                  /* USB_GLOBAL_INCLUDE_FILE */
   69 
   70 enum {
   71         AUDIO_LANG_INDEX,
   72         AUDIO_MIXER_INDEX,
   73         AUDIO_RECORD_INDEX,
   74         AUDIO_PLAYBACK_INDEX,
   75         AUDIO_MANUFACTURER_INDEX,
   76         AUDIO_PRODUCT_INDEX,
   77         AUDIO_SERIAL_NUMBER_INDEX,
   78         AUDIO_MAX_INDEX,
   79 };
   80 
   81 #define AUDIO_DEFAULT_VENDOR_ID         USB_TEMPLATE_VENDOR
   82 #define AUDIO_DEFAULT_PRODUCT_ID        0x27e0
   83 #define AUDIO_DEFAULT_MIXER             "Mixer interface"
   84 #define AUDIO_DEFAULT_RECORD            "Record interface"
   85 #define AUDIO_DEFAULT_PLAYBACK          "Playback interface"
   86 #define AUDIO_DEFAULT_MANUFACTURER      USB_TEMPLATE_MANUFACTURER
   87 #define AUDIO_DEFAULT_PRODUCT           "Audio Test Device"
   88 #define AUDIO_DEFAULT_SERIAL_NUMBER     "March 2008"
   89 
   90 static struct usb_string_descriptor     audio_mixer;
   91 static struct usb_string_descriptor     audio_record;
   92 static struct usb_string_descriptor     audio_playback;
   93 static struct usb_string_descriptor     audio_manufacturer;
   94 static struct usb_string_descriptor     audio_product;
   95 static struct usb_string_descriptor     audio_serial_number;
   96 
   97 static struct sysctl_ctx_list           audio_ctx_list;
   98 
   99 /* prototypes */
  100 
  101 /*
  102  * Audio Mixer description structures
  103  *
  104  * Some of the audio descriptors were dumped
  105  * from a Creative Labs USB audio device.
  106  */
  107 
  108 static const uint8_t audio_raw_desc_0[] = {
  109         0x0a, 0x24, 0x01, 0x00, 0x01, 0xa9, 0x00, 0x02,
  110         0x01, 0x02
  111 };
  112 
  113 static const uint8_t audio_raw_desc_1[] = {
  114         0x0c, 0x24, 0x02, 0x01, 0x01, 0x01, 0x00, 0x02,
  115         0x03, 0x00, 0x00, 0x00
  116 };
  117 
  118 static const uint8_t audio_raw_desc_2[] = {
  119         0x0c, 0x24, 0x02, 0x02, 0x01, 0x02, 0x00, 0x02,
  120         0x03, 0x00, 0x00, 0x00
  121 };
  122 
  123 static const uint8_t audio_raw_desc_3[] = {
  124         0x0c, 0x24, 0x02, 0x03, 0x03, 0x06, 0x00, 0x02,
  125         0x03, 0x00, 0x00, 0x00
  126 };
  127 
  128 static const uint8_t audio_raw_desc_4[] = {
  129         0x0c, 0x24, 0x02, 0x04, 0x05, 0x06, 0x00, 0x02,
  130         0x03, 0x00, 0x00, 0x00
  131 };
  132 
  133 static const uint8_t audio_raw_desc_5[] = {
  134         0x09, 0x24, 0x03, 0x05, 0x05, 0x06, 0x00, 0x01,
  135         0x00
  136 };
  137 
  138 static const uint8_t audio_raw_desc_6[] = {
  139         0x09, 0x24, 0x03, 0x06, 0x01, 0x03, 0x00, 0x09,
  140         0x00
  141 };
  142 
  143 static const uint8_t audio_raw_desc_7[] = {
  144         0x09, 0x24, 0x03, 0x07, 0x01, 0x01, 0x00, 0x08,
  145         0x00
  146 };
  147 
  148 static const uint8_t audio_raw_desc_8[] = {
  149         0x09, 0x24, 0x05, 0x08, 0x03, 0x0a, 0x0b, 0x0c,
  150         0x00
  151 };
  152 
  153 static const uint8_t audio_raw_desc_9[] = {
  154         0x0a, 0x24, 0x06, 0x09, 0x0f, 0x01, 0x01, 0x02,
  155         0x02, 0x00
  156 };
  157 
  158 static const uint8_t audio_raw_desc_10[] = {
  159         0x0a, 0x24, 0x06, 0x0a, 0x02, 0x01, 0x43, 0x00,
  160         0x00, 0x00
  161 };
  162 
  163 static const uint8_t audio_raw_desc_11[] = {
  164         0x0a, 0x24, 0x06, 0x0b, 0x03, 0x01, 0x01, 0x02,
  165         0x02, 0x00
  166 };
  167 
  168 static const uint8_t audio_raw_desc_12[] = {
  169         0x0a, 0x24, 0x06, 0x0c, 0x04, 0x01, 0x01, 0x00,
  170         0x00, 0x00
  171 };
  172 
  173 static const uint8_t audio_raw_desc_13[] = {
  174         0x0a, 0x24, 0x06, 0x0d, 0x02, 0x01, 0x03, 0x00,
  175         0x00, 0x00
  176 };
  177 
  178 static const uint8_t audio_raw_desc_14[] = {
  179         0x0a, 0x24, 0x06, 0x0e, 0x03, 0x01, 0x01, 0x02,
  180         0x02, 0x00
  181 };
  182 
  183 static const uint8_t audio_raw_desc_15[] = {
  184         0x0f, 0x24, 0x04, 0x0f, 0x03, 0x01, 0x0d, 0x0e,
  185         0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00
  186 };
  187 
  188 static const void *audio_raw_iface_0_desc[] = {
  189         audio_raw_desc_0,
  190         audio_raw_desc_1,
  191         audio_raw_desc_2,
  192         audio_raw_desc_3,
  193         audio_raw_desc_4,
  194         audio_raw_desc_5,
  195         audio_raw_desc_6,
  196         audio_raw_desc_7,
  197         audio_raw_desc_8,
  198         audio_raw_desc_9,
  199         audio_raw_desc_10,
  200         audio_raw_desc_11,
  201         audio_raw_desc_12,
  202         audio_raw_desc_13,
  203         audio_raw_desc_14,
  204         audio_raw_desc_15,
  205         NULL,
  206 };
  207 
  208 static const struct usb_temp_interface_desc audio_iface_0 = {
  209         .ppEndpoints = NULL,            /* no endpoints */
  210         .ppRawDesc = audio_raw_iface_0_desc,
  211         .bInterfaceClass = UICLASS_AUDIO,
  212         .bInterfaceSubClass = UISUBCLASS_AUDIOCONTROL,
  213         .bInterfaceProtocol = 0,
  214         .iInterface = AUDIO_MIXER_INDEX,
  215 };
  216 
  217 static const uint8_t audio_raw_desc_20[] = {
  218         0x07, 0x24, 0x01, 0x01, 0x03, 0x01, 0x00
  219 
  220 };
  221 
  222 static const uint8_t audio_raw_desc_21[] = {
  223         0x0b, 0x24, 0x02, 0x01, 0x02, 0x02, 0x10, 0x01,
  224         /* 48kHz */
  225         0x80, 0xbb, 0x00
  226 };
  227 
  228 static const uint8_t audio_raw_desc_22[] = {
  229         0x07, 0x25, 0x01, 0x00, 0x01, 0x04, 0x00
  230 };
  231 
  232 static const void *audio_raw_iface_1_desc[] = {
  233         audio_raw_desc_20,
  234         audio_raw_desc_21,
  235         NULL,
  236 };
  237 
  238 static const void *audio_raw_ep_1_desc[] = {
  239         audio_raw_desc_22,
  240         NULL,
  241 };
  242 
  243 static const struct usb_temp_packet_size audio_isoc_mps = {
  244   .mps[USB_SPEED_FULL] = 0xC8,
  245   .mps[USB_SPEED_HIGH] = 0xC8,
  246 };
  247 
  248 static const struct usb_temp_interval audio_isoc_interval = {
  249         .bInterval[USB_SPEED_FULL] = 1, /* 1:1 */
  250         .bInterval[USB_SPEED_HIGH] = 4, /* 1:8 */
  251 };
  252 
  253 static const struct usb_temp_endpoint_desc audio_isoc_out_ep = {
  254         .ppRawDesc = audio_raw_ep_1_desc,
  255         .pPacketSize = &audio_isoc_mps,
  256         .pIntervals = &audio_isoc_interval,
  257         .bEndpointAddress = UE_DIR_OUT,
  258         .bmAttributes = UE_ISOCHRONOUS | UE_ISO_ADAPT,
  259 };
  260 
  261 static const struct usb_temp_endpoint_desc *audio_iface_1_ep[] = {
  262         &audio_isoc_out_ep,
  263         NULL,
  264 };
  265 
  266 static const struct usb_temp_interface_desc audio_iface_1_alt_0 = {
  267         .ppEndpoints = NULL,            /* no endpoints */
  268         .ppRawDesc = NULL,              /* no raw descriptors */
  269         .bInterfaceClass = UICLASS_AUDIO,
  270         .bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM,
  271         .bInterfaceProtocol = 0,
  272         .iInterface = AUDIO_PLAYBACK_INDEX,
  273 };
  274 
  275 static const struct usb_temp_interface_desc audio_iface_1_alt_1 = {
  276         .ppEndpoints = audio_iface_1_ep,
  277         .ppRawDesc = audio_raw_iface_1_desc,
  278         .bInterfaceClass = UICLASS_AUDIO,
  279         .bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM,
  280         .bInterfaceProtocol = 0,
  281         .iInterface = AUDIO_PLAYBACK_INDEX,
  282         .isAltInterface = 1,            /* this is an alternate setting */
  283 };
  284 
  285 static const uint8_t audio_raw_desc_30[] = {
  286         0x07, 0x24, 0x01, 0x07, 0x01, 0x01, 0x00
  287 
  288 };
  289 
  290 static const uint8_t audio_raw_desc_31[] = {
  291         0x0b, 0x24, 0x02, 0x01, 0x02, 0x02, 0x10, 0x01,
  292         /* 48kHz */
  293         0x80, 0xbb, 0x00
  294 };
  295 
  296 static const uint8_t audio_raw_desc_32[] = {
  297         0x07, 0x25, 0x01, 0x01, 0x00, 0x00, 0x00
  298 };
  299 
  300 static const void *audio_raw_iface_2_desc[] = {
  301         audio_raw_desc_30,
  302         audio_raw_desc_31,
  303         NULL,
  304 };
  305 
  306 static const void *audio_raw_ep_2_desc[] = {
  307         audio_raw_desc_32,
  308         NULL,
  309 };
  310 
  311 static const struct usb_temp_endpoint_desc audio_isoc_in_ep = {
  312         .ppRawDesc = audio_raw_ep_2_desc,
  313         .pPacketSize = &audio_isoc_mps,
  314         .pIntervals = &audio_isoc_interval,
  315         .bEndpointAddress = UE_DIR_IN,
  316         .bmAttributes = UE_ISOCHRONOUS | UE_ISO_ADAPT,
  317 };
  318 
  319 static const struct usb_temp_endpoint_desc *audio_iface_2_ep[] = {
  320         &audio_isoc_in_ep,
  321         NULL,
  322 };
  323 
  324 static const struct usb_temp_interface_desc audio_iface_2_alt_0 = {
  325         .ppEndpoints = NULL,            /* no endpoints */
  326         .ppRawDesc = NULL,              /* no raw descriptors */
  327         .bInterfaceClass = UICLASS_AUDIO,
  328         .bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM,
  329         .bInterfaceProtocol = 0,
  330         .iInterface = AUDIO_RECORD_INDEX,
  331 };
  332 
  333 static const struct usb_temp_interface_desc audio_iface_2_alt_1 = {
  334         .ppEndpoints = audio_iface_2_ep,
  335         .ppRawDesc = audio_raw_iface_2_desc,
  336         .bInterfaceClass = UICLASS_AUDIO,
  337         .bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM,
  338         .bInterfaceProtocol = 0,
  339         .iInterface = AUDIO_RECORD_INDEX,
  340         .isAltInterface = 1,            /* this is an alternate setting */
  341 };
  342 
  343 static const struct usb_temp_interface_desc *audio_interfaces[] = {
  344         &audio_iface_0,
  345         &audio_iface_1_alt_0,
  346         &audio_iface_1_alt_1,
  347         &audio_iface_2_alt_0,
  348         &audio_iface_2_alt_1,
  349         NULL,
  350 };
  351 
  352 static const struct usb_temp_config_desc audio_config_desc = {
  353         .ppIfaceDesc = audio_interfaces,
  354         .bmAttributes = 0,
  355         .bMaxPower = 0,
  356         .iConfiguration = AUDIO_PRODUCT_INDEX,
  357 };
  358 
  359 static const struct usb_temp_config_desc *audio_configs[] = {
  360         &audio_config_desc,
  361         NULL,
  362 };
  363 
  364 static usb_temp_get_string_desc_t audio_get_string_desc;
  365 
  366 struct usb_temp_device_desc usb_template_audio = {
  367         .getStringDesc = &audio_get_string_desc,
  368         .ppConfigDesc = audio_configs,
  369         .idVendor = AUDIO_DEFAULT_VENDOR_ID,
  370         .idProduct = AUDIO_DEFAULT_PRODUCT_ID,
  371         .bcdDevice = 0x0100,
  372         .bDeviceClass = UDCLASS_COMM,
  373         .bDeviceSubClass = 0,
  374         .bDeviceProtocol = 0,
  375         .iManufacturer = AUDIO_MANUFACTURER_INDEX,
  376         .iProduct = AUDIO_PRODUCT_INDEX,
  377         .iSerialNumber = AUDIO_SERIAL_NUMBER_INDEX,
  378 };
  379 
  380 /*------------------------------------------------------------------------*
  381  *      audio_get_string_desc
  382  *
  383  * Return values:
  384  * NULL: Failure. No such string.
  385  * Else: Success. Pointer to string descriptor is returned.
  386  *------------------------------------------------------------------------*/
  387 static const void *
  388 audio_get_string_desc(uint16_t lang_id, uint8_t string_index)
  389 {
  390         static const void *ptr[AUDIO_MAX_INDEX] = {
  391                 [AUDIO_LANG_INDEX] = &usb_string_lang_en,
  392                 [AUDIO_MIXER_INDEX] = &audio_mixer,
  393                 [AUDIO_RECORD_INDEX] = &audio_record,
  394                 [AUDIO_PLAYBACK_INDEX] = &audio_playback,
  395                 [AUDIO_MANUFACTURER_INDEX] = &audio_manufacturer,
  396                 [AUDIO_PRODUCT_INDEX] = &audio_product,
  397                 [AUDIO_SERIAL_NUMBER_INDEX] = &audio_serial_number,
  398         };
  399 
  400         if (string_index == 0) {
  401                 return (&usb_string_lang_en);
  402         }
  403         if (lang_id != 0x0409) {
  404                 return (NULL);
  405         }
  406         if (string_index < AUDIO_MAX_INDEX) {
  407                 return (ptr[string_index]);
  408         }
  409         return (NULL);
  410 }
  411 
  412 static void
  413 audio_init(void *arg __unused)
  414 {
  415         struct sysctl_oid *parent;
  416         char parent_name[3];
  417 
  418         usb_make_str_desc(&audio_mixer, sizeof(audio_mixer),
  419             AUDIO_DEFAULT_MIXER);
  420         usb_make_str_desc(&audio_record, sizeof(audio_record),
  421             AUDIO_DEFAULT_RECORD);
  422         usb_make_str_desc(&audio_playback, sizeof(audio_playback),
  423             AUDIO_DEFAULT_PLAYBACK);
  424         usb_make_str_desc(&audio_manufacturer, sizeof(audio_manufacturer),
  425             AUDIO_DEFAULT_MANUFACTURER);
  426         usb_make_str_desc(&audio_product, sizeof(audio_product),
  427             AUDIO_DEFAULT_PRODUCT);
  428         usb_make_str_desc(&audio_serial_number, sizeof(audio_serial_number),
  429             AUDIO_DEFAULT_SERIAL_NUMBER);
  430 
  431         snprintf(parent_name, sizeof(parent_name), "%d", USB_TEMP_AUDIO);
  432         sysctl_ctx_init(&audio_ctx_list);
  433 
  434         parent = SYSCTL_ADD_NODE(&audio_ctx_list,
  435             SYSCTL_STATIC_CHILDREN(_hw_usb_templates), OID_AUTO,
  436             parent_name, CTLFLAG_RW | CTLFLAG_MPSAFE,
  437             0, "USB Audio Interface device side template");
  438         SYSCTL_ADD_U16(&audio_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  439             "vendor_id", CTLFLAG_RWTUN, &usb_template_audio.idVendor,
  440             1, "Vendor identifier");
  441         SYSCTL_ADD_U16(&audio_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  442             "product_id", CTLFLAG_RWTUN, &usb_template_audio.idProduct,
  443             1, "Product identifier");
  444 #if 0
  445         SYSCTL_ADD_PROC(&audio_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  446             "mixer", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  447             &audio_mixer, sizeof(audio_mixer), usb_temp_sysctl,
  448             "A", "Mixer interface string");
  449         SYSCTL_ADD_PROC(&audio_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  450             "record", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  451             &audio_record, sizeof(audio_record), usb_temp_sysctl,
  452             "A", "Record interface string");
  453         SYSCTL_ADD_PROC(&audio_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  454             "playback", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  455             &audio_playback, sizeof(audio_playback), usb_temp_sysctl,
  456             "A", "Playback interface string");
  457 #endif
  458         SYSCTL_ADD_PROC(&audio_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  459             "manufacturer", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  460             &audio_manufacturer, sizeof(audio_manufacturer), usb_temp_sysctl,
  461             "A", "Manufacturer string");
  462         SYSCTL_ADD_PROC(&audio_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  463             "product", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  464             &audio_product, sizeof(audio_product), usb_temp_sysctl,
  465             "A", "Product string");
  466         SYSCTL_ADD_PROC(&audio_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  467             "serial_number", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  468             &audio_serial_number, sizeof(audio_serial_number), usb_temp_sysctl,
  469             "A", "Serial number string");
  470 }
  471 
  472 static void
  473 audio_uninit(void *arg __unused)
  474 {
  475 
  476         sysctl_ctx_free(&audio_ctx_list);
  477 }
  478 
  479 SYSINIT(audio_init, SI_SUB_LOCK, SI_ORDER_FIRST, audio_init, NULL);
  480 SYSUNINIT(audio_uninit, SI_SUB_LOCK, SI_ORDER_FIRST, audio_uninit, NULL);

Cache object: 068cc2fbc8cee5f33c0f93fe32c4123e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.