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_phone.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) 2014 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 phone 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         PHONE_LANG_INDEX,
   72         PHONE_MIXER_INDEX,
   73         PHONE_RECORD_INDEX,
   74         PHONE_PLAYBACK_INDEX,
   75         PHONE_HID_INDEX,
   76         PHONE_MANUFACTURER_INDEX,
   77         PHONE_PRODUCT_INDEX,
   78         PHONE_SERIAL_NUMBER_INDEX,
   79         PHONE_MAX_INDEX,
   80 };
   81 
   82 #define PHONE_DEFAULT_VENDOR_ID         USB_TEMPLATE_VENDOR
   83 #define PHONE_DEFAULT_PRODUCT_ID        0x05dc
   84 #define PHONE_DEFAULT_MIXER             "Mixer interface"
   85 #define PHONE_DEFAULT_RECORD            "Record interface"
   86 #define PHONE_DEFAULT_PLAYBACK          "Playback interface"
   87 #define PHONE_DEFAULT_HID               "HID interface"
   88 #define PHONE_DEFAULT_MANUFACTURER      USB_TEMPLATE_MANUFACTURER
   89 #define PHONE_DEFAULT_PRODUCT           "USB Phone Device"
   90 #define PHONE_DEFAULT_SERIAL_NUMBER     "March 2008"
   91 
   92 static struct usb_string_descriptor     phone_mixer;
   93 static struct usb_string_descriptor     phone_record;
   94 static struct usb_string_descriptor     phone_playback;
   95 static struct usb_string_descriptor     phone_hid;
   96 static struct usb_string_descriptor     phone_manufacturer;
   97 static struct usb_string_descriptor     phone_product;
   98 static struct usb_string_descriptor     phone_serial_number;
   99 
  100 static struct sysctl_ctx_list           phone_ctx_list;
  101 
  102 /* prototypes */
  103 
  104 /*
  105  * Phone Mixer description structures
  106  *
  107  * Some of the phone descriptors were dumped from no longer in
  108  * production Yealink VOIP USB phone adapter:
  109  */
  110 static uint8_t phone_hid_descriptor[] = {
  111         0x05, 0x0b, 0x09, 0x01, 0xa1, 0x01, 0x05, 0x09,
  112         0x19, 0x01, 0x29, 0x3f, 0x15, 0x00, 0x25, 0x01,
  113         0x75, 0x01, 0x95, 0x80, 0x81, 0x00, 0x05, 0x08,
  114         0x19, 0x01, 0x29, 0x10, 0x15, 0x00, 0x25, 0x01,
  115         0x75, 0x01, 0x95, 0x80, 0x91, 0x00, 0xc0
  116 };
  117 
  118 static const uint8_t phone_raw_desc_0[] = {
  119         0x0a, 0x24, 0x01, 0x00, 0x01, 0x4a, 0x00, 0x02,
  120         0x01, 0x02
  121 };
  122 
  123 static const uint8_t phone_raw_desc_1[] = {
  124         0x0c, 0x24, 0x02, 0x01, 0x01, 0x02, 0x00, 0x01,
  125         0x00, 0x00, 0x00, 0x00
  126 };
  127 
  128 static const uint8_t phone_raw_desc_2[] = {
  129         0x0c, 0x24, 0x02, 0x02, 0x01, 0x01, 0x00, 0x01,
  130         0x00, 0x00, 0x00, 0x00
  131 };
  132 
  133 static const uint8_t phone_raw_desc_3[] = {
  134         0x09, 0x24, 0x03, 0x03, 0x01, 0x03, 0x00, 0x06,
  135         0x00
  136 };
  137 
  138 static const uint8_t phone_raw_desc_4[] = {
  139         0x09, 0x24, 0x03, 0x04, 0x01, 0x01, 0x00, 0x05,
  140         0x00
  141 };
  142 
  143 static const uint8_t phone_raw_desc_5[] = {
  144         0x0b, 0x24, 0x06, 0x05, 0x01, 0x02, 0x03, 0x00,
  145         0x03, 0x00, 0x00
  146 };
  147 
  148 static const uint8_t phone_raw_desc_6[] = {
  149         0x0b, 0x24, 0x06, 0x06, 0x02, 0x02, 0x03, 0x00,
  150         0x03, 0x00, 0x00
  151 };
  152 
  153 static const void *phone_raw_iface_0_desc[] = {
  154         phone_raw_desc_0,
  155         phone_raw_desc_1,
  156         phone_raw_desc_2,
  157         phone_raw_desc_3,
  158         phone_raw_desc_4,
  159         phone_raw_desc_5,
  160         phone_raw_desc_6,
  161         NULL,
  162 };
  163 
  164 static const struct usb_temp_interface_desc phone_iface_0 = {
  165         .ppEndpoints = NULL,            /* no endpoints */
  166         .ppRawDesc = phone_raw_iface_0_desc,
  167         .bInterfaceClass = UICLASS_AUDIO,
  168         .bInterfaceSubClass = UISUBCLASS_AUDIOCONTROL,
  169         .bInterfaceProtocol = 0,
  170         .iInterface = PHONE_MIXER_INDEX,
  171 };
  172 
  173 static const uint8_t phone_raw_desc_20[] = {
  174         0x07, 0x24, 0x01, 0x04, 0x01, 0x01, 0x00
  175 };
  176 
  177 static const uint8_t phone_raw_desc_21[] = {
  178         0x0b, 0x24, 0x02, 0x01, 0x01, 0x02, 0x10, 0x01,
  179         /* 8kHz */
  180         0x40, 0x1f, 0x00
  181 };
  182 
  183 static const uint8_t phone_raw_desc_22[] = {
  184         0x07, 0x25, 0x01, 0x00, 0x00, 0x00, 0x00
  185 };
  186 
  187 static const void *phone_raw_iface_1_desc[] = {
  188         phone_raw_desc_20,
  189         phone_raw_desc_21,
  190         NULL,
  191 };
  192 
  193 static const void *phone_raw_ep_1_desc[] = {
  194         phone_raw_desc_22,
  195         NULL,
  196 };
  197 
  198 static const struct usb_temp_packet_size phone_isoc_mps = {
  199         .mps[USB_SPEED_FULL] = 0x10,
  200         .mps[USB_SPEED_HIGH] = 0x10,
  201 };
  202 
  203 static const struct usb_temp_interval phone_isoc_interval = {
  204         .bInterval[USB_SPEED_FULL] = 1, /* 1:1 */
  205         .bInterval[USB_SPEED_HIGH] = 4, /* 1:8 */
  206 };
  207 
  208 static const struct usb_temp_endpoint_desc phone_isoc_in_ep = {
  209         .ppRawDesc = phone_raw_ep_1_desc,
  210         .pPacketSize = &phone_isoc_mps,
  211         .pIntervals = &phone_isoc_interval,
  212         .bEndpointAddress = UE_DIR_IN,
  213         .bmAttributes = UE_ISOCHRONOUS,
  214 };
  215 
  216 static const struct usb_temp_endpoint_desc *phone_iface_1_ep[] = {
  217         &phone_isoc_in_ep,
  218         NULL,
  219 };
  220 
  221 static const struct usb_temp_interface_desc phone_iface_1_alt_0 = {
  222         .ppEndpoints = NULL,            /* no endpoints */
  223         .ppRawDesc = NULL,              /* no raw descriptors */
  224         .bInterfaceClass = UICLASS_AUDIO,
  225         .bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM,
  226         .bInterfaceProtocol = 0,
  227         .iInterface = PHONE_PLAYBACK_INDEX,
  228 };
  229 
  230 static const struct usb_temp_interface_desc phone_iface_1_alt_1 = {
  231         .ppEndpoints = phone_iface_1_ep,
  232         .ppRawDesc = phone_raw_iface_1_desc,
  233         .bInterfaceClass = UICLASS_AUDIO,
  234         .bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM,
  235         .bInterfaceProtocol = 0,
  236         .iInterface = PHONE_PLAYBACK_INDEX,
  237         .isAltInterface = 1,            /* this is an alternate setting */
  238 };
  239 
  240 static const uint8_t phone_raw_desc_30[] = {
  241         0x07, 0x24, 0x01, 0x02, 0x01, 0x01, 0x00
  242 };
  243 
  244 static const uint8_t phone_raw_desc_31[] = {
  245         0x0b, 0x24, 0x02, 0x01, 0x01, 0x02, 0x10, 0x01,
  246         /* 8kHz */
  247         0x40, 0x1f, 0x00
  248 };
  249 
  250 static const uint8_t phone_raw_desc_32[] = {
  251         0x07, 0x25, 0x01, 0x00, 0x00, 0x00, 0x00
  252 };
  253 
  254 static const void *phone_raw_iface_2_desc[] = {
  255         phone_raw_desc_30,
  256         phone_raw_desc_31,
  257         NULL,
  258 };
  259 
  260 static const void *phone_raw_ep_2_desc[] = {
  261         phone_raw_desc_32,
  262         NULL,
  263 };
  264 
  265 static const struct usb_temp_endpoint_desc phone_isoc_out_ep = {
  266         .ppRawDesc = phone_raw_ep_2_desc,
  267         .pPacketSize = &phone_isoc_mps,
  268         .pIntervals = &phone_isoc_interval,
  269         .bEndpointAddress = UE_DIR_OUT,
  270         .bmAttributes = UE_ISOCHRONOUS,
  271 };
  272 
  273 static const struct usb_temp_endpoint_desc *phone_iface_2_ep[] = {
  274         &phone_isoc_out_ep,
  275         NULL,
  276 };
  277 
  278 static const struct usb_temp_interface_desc phone_iface_2_alt_0 = {
  279         .ppEndpoints = NULL,            /* no endpoints */
  280         .ppRawDesc = NULL,              /* no raw descriptors */
  281         .bInterfaceClass = UICLASS_AUDIO,
  282         .bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM,
  283         .bInterfaceProtocol = 0,
  284         .iInterface = PHONE_RECORD_INDEX,
  285 };
  286 
  287 static const struct usb_temp_interface_desc phone_iface_2_alt_1 = {
  288         .ppEndpoints = phone_iface_2_ep,
  289         .ppRawDesc = phone_raw_iface_2_desc,
  290         .bInterfaceClass = UICLASS_AUDIO,
  291         .bInterfaceSubClass = UISUBCLASS_AUDIOSTREAM,
  292         .bInterfaceProtocol = 0,
  293         .iInterface = PHONE_RECORD_INDEX,
  294         .isAltInterface = 1,            /* this is an alternate setting */
  295 };
  296 
  297 static const uint8_t phone_hid_raw_desc_0[] = {
  298         0x09, 0x21, 0x00, 0x01, 0x00, 0x01, 0x22, sizeof(phone_hid_descriptor),
  299         0x00
  300 };
  301 
  302 static const void *phone_hid_desc_0[] = {
  303         phone_hid_raw_desc_0,
  304         NULL,
  305 };
  306 
  307 static const struct usb_temp_packet_size phone_hid_mps = {
  308         .mps[USB_SPEED_FULL] = 0x10,
  309         .mps[USB_SPEED_HIGH] = 0x10,
  310 };
  311 
  312 static const struct usb_temp_interval phone_hid_interval = {
  313         .bInterval[USB_SPEED_FULL] = 2,         /* 2ms */
  314         .bInterval[USB_SPEED_HIGH] = 2,         /* 2ms */
  315 };
  316 
  317 static const struct usb_temp_endpoint_desc phone_hid_in_ep = {
  318         .pPacketSize = &phone_hid_mps,
  319         .pIntervals = &phone_hid_interval,
  320         .bEndpointAddress = UE_DIR_IN,
  321         .bmAttributes = UE_INTERRUPT,
  322 };
  323 
  324 static const struct usb_temp_endpoint_desc *phone_iface_3_ep[] = {
  325         &phone_hid_in_ep,
  326         NULL,
  327 };
  328 
  329 static const struct usb_temp_interface_desc phone_iface_3 = {
  330         .ppEndpoints = phone_iface_3_ep,
  331         .ppRawDesc = phone_hid_desc_0,
  332         .bInterfaceClass = UICLASS_HID,
  333         .bInterfaceSubClass = 0,
  334         .bInterfaceProtocol = 0,
  335         .iInterface = PHONE_HID_INDEX,
  336 };
  337 
  338 static const struct usb_temp_interface_desc *phone_interfaces[] = {
  339         &phone_iface_0,
  340         &phone_iface_1_alt_0,
  341         &phone_iface_1_alt_1,
  342         &phone_iface_2_alt_0,
  343         &phone_iface_2_alt_1,
  344         &phone_iface_3,
  345         NULL,
  346 };
  347 
  348 static const struct usb_temp_config_desc phone_config_desc = {
  349         .ppIfaceDesc = phone_interfaces,
  350         .bmAttributes = 0,
  351         .bMaxPower = 0,
  352         .iConfiguration = PHONE_PRODUCT_INDEX,
  353 };
  354 
  355 static const struct usb_temp_config_desc *phone_configs[] = {
  356         &phone_config_desc,
  357         NULL,
  358 };
  359 
  360 static usb_temp_get_string_desc_t phone_get_string_desc;
  361 static usb_temp_get_vendor_desc_t phone_get_vendor_desc;
  362 
  363 struct usb_temp_device_desc usb_template_phone = {
  364         .getStringDesc = &phone_get_string_desc,
  365         .getVendorDesc = &phone_get_vendor_desc,
  366         .ppConfigDesc = phone_configs,
  367         .idVendor = PHONE_DEFAULT_VENDOR_ID,
  368         .idProduct = PHONE_DEFAULT_PRODUCT_ID,
  369         .bcdDevice = 0x0100,
  370         .bDeviceClass = UDCLASS_IN_INTERFACE,
  371         .bDeviceSubClass = 0,
  372         .bDeviceProtocol = 0,
  373         .iManufacturer = PHONE_MANUFACTURER_INDEX,
  374         .iProduct = PHONE_PRODUCT_INDEX,
  375         .iSerialNumber = PHONE_SERIAL_NUMBER_INDEX,
  376 };
  377 
  378 /*------------------------------------------------------------------------*
  379  *      phone_get_vendor_desc
  380  *
  381  * Return values:
  382  * NULL: Failure. No such vendor descriptor.
  383  * Else: Success. Pointer to vendor descriptor is returned.
  384  *------------------------------------------------------------------------*/
  385 static const void *
  386 phone_get_vendor_desc(const struct usb_device_request *req, uint16_t *plen)
  387 {
  388         if ((req->bmRequestType == 0x81) && (req->bRequest == 0x06) &&
  389             (req->wValue[0] == 0x00) && (req->wValue[1] == 0x22) &&
  390             (req->wIndex[1] == 0) && (req->wIndex[0] == 3 /* iface */)) {
  391                 *plen = sizeof(phone_hid_descriptor);
  392                 return (phone_hid_descriptor);
  393         }
  394         return (NULL);
  395 }
  396 
  397 /*------------------------------------------------------------------------*
  398  *      phone_get_string_desc
  399  *
  400  * Return values:
  401  * NULL: Failure. No such string.
  402  * Else: Success. Pointer to string descriptor is returned.
  403  *------------------------------------------------------------------------*/
  404 static const void *
  405 phone_get_string_desc(uint16_t lang_id, uint8_t string_index)
  406 {
  407         static const void *ptr[PHONE_MAX_INDEX] = {
  408                 [PHONE_LANG_INDEX] = &usb_string_lang_en,
  409                 [PHONE_MIXER_INDEX] = &phone_mixer,
  410                 [PHONE_RECORD_INDEX] = &phone_record,
  411                 [PHONE_PLAYBACK_INDEX] = &phone_playback,
  412                 [PHONE_HID_INDEX] = &phone_hid,
  413                 [PHONE_MANUFACTURER_INDEX] = &phone_manufacturer,
  414                 [PHONE_PRODUCT_INDEX] = &phone_product,
  415                 [PHONE_SERIAL_NUMBER_INDEX] = &phone_serial_number,
  416         };
  417 
  418         if (string_index == 0) {
  419                 return (&usb_string_lang_en);
  420         }
  421         if (lang_id != 0x0409) {
  422                 return (NULL);
  423         }
  424         if (string_index < PHONE_MAX_INDEX) {
  425                 return (ptr[string_index]);
  426         }
  427         return (NULL);
  428 }
  429 
  430 static void
  431 phone_init(void *arg __unused)
  432 {
  433         struct sysctl_oid *parent;
  434         char parent_name[3];
  435 
  436         usb_make_str_desc(&phone_mixer, sizeof(phone_mixer),
  437             PHONE_DEFAULT_MIXER);
  438         usb_make_str_desc(&phone_record, sizeof(phone_record),
  439             PHONE_DEFAULT_RECORD);
  440         usb_make_str_desc(&phone_playback, sizeof(phone_playback),
  441             PHONE_DEFAULT_PLAYBACK);
  442         usb_make_str_desc(&phone_hid, sizeof(phone_hid),
  443             PHONE_DEFAULT_HID);
  444         usb_make_str_desc(&phone_manufacturer, sizeof(phone_manufacturer),
  445             PHONE_DEFAULT_MANUFACTURER);
  446         usb_make_str_desc(&phone_product, sizeof(phone_product),
  447             PHONE_DEFAULT_PRODUCT);
  448         usb_make_str_desc(&phone_serial_number, sizeof(phone_serial_number),
  449             PHONE_DEFAULT_SERIAL_NUMBER);
  450 
  451         snprintf(parent_name, sizeof(parent_name), "%d", USB_TEMP_PHONE);
  452         sysctl_ctx_init(&phone_ctx_list);
  453 
  454         parent = SYSCTL_ADD_NODE(&phone_ctx_list,
  455             SYSCTL_STATIC_CHILDREN(_hw_usb_templates), OID_AUTO,
  456             parent_name, CTLFLAG_RW | CTLFLAG_MPSAFE,
  457             0, "USB Phone device side template");
  458         SYSCTL_ADD_U16(&phone_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  459             "vendor_id", CTLFLAG_RWTUN,
  460             &usb_template_cdce.idVendor, 1, "Vendor identifier");
  461         SYSCTL_ADD_U16(&phone_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  462             "product_id", CTLFLAG_RWTUN,
  463             &usb_template_cdce.idProduct, 1, "Product identifier");
  464 #if 0
  465         SYSCTL_ADD_PROC(&phone_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  466             "mixer", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  467             &phone_mixer, sizeof(phone_mixer), usb_temp_sysctl,
  468             "A", "Mixer interface string");
  469         SYSCTL_ADD_PROC(&phone_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  470             "record", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  471             &phone_record, sizeof(phone_record), usb_temp_sysctl,
  472             "A", "Record interface string");
  473         SYSCTL_ADD_PROC(&phone_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  474             "playback", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  475             &phone_playback, sizeof(phone_playback), usb_temp_sysctl,
  476             "A", "Playback interface string");
  477         SYSCTL_ADD_PROC(&phone_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  478             "hid", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  479             &phone_hid, sizeof(phone_hid), usb_temp_sysctl,
  480             "A", "HID interface string");
  481 #endif
  482         SYSCTL_ADD_PROC(&phone_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  483             "manufacturer", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  484             &phone_manufacturer, sizeof(phone_manufacturer), usb_temp_sysctl,
  485             "A", "Manufacturer string");
  486         SYSCTL_ADD_PROC(&phone_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  487             "product", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  488             &phone_product, sizeof(phone_product), usb_temp_sysctl,
  489             "A", "Product string");
  490         SYSCTL_ADD_PROC(&phone_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  491             "serial_number", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  492             &phone_serial_number, sizeof(phone_serial_number), usb_temp_sysctl,
  493             "A", "Serial number string");
  494 }
  495 
  496 static void
  497 phone_uninit(void *arg __unused)
  498 {
  499 
  500         sysctl_ctx_free(&phone_ctx_list);
  501 }
  502 
  503 SYSINIT(phone_init, SI_SUB_LOCK, SI_ORDER_FIRST, phone_init, NULL);
  504 SYSUNINIT(phone_uninit, SI_SUB_LOCK, SI_ORDER_FIRST, phone_uninit, NULL);

Cache object: 3298c18247a84b11dcb265e3c27fcc8a


[ 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.