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_serialnet.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 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
    5  * Copyright (c) 2018 The FreeBSD Foundation
    6  * All rights reserved.
    7  *
    8  * This software was developed by SRI International and the University of
    9  * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
   10  * ("CTSRD"), as part of the DARPA CRASH research programme.
   11  *
   12  * Portions of this software were developed by Edward Tomasz Napierala
   13  * under sponsorship from the FreeBSD Foundation.
   14  *
   15  * Redistribution and use in source and binary forms, with or without
   16  * modification, are permitted provided that the following conditions
   17  * are met:
   18  * 1. Redistributions of source code must retain the above copyright
   19  *    notice, this list of conditions and the following disclaimer.
   20  * 2. Redistributions in binary form must reproduce the above copyright
   21  *    notice, this list of conditions and the following disclaimer in the
   22  *    documentation and/or other materials provided with the distribution.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   34  * SUCH DAMAGE.
   35  */
   36 /*
   37  * This file contains the USB template for USB Networking and Serial
   38  */
   39 
   40 #include <sys/cdefs.h>
   41 __FBSDID("$FreeBSD$");
   42 
   43 #ifdef USB_GLOBAL_INCLUDE_FILE
   44 #include USB_GLOBAL_INCLUDE_FILE
   45 #else
   46 #include <sys/stdint.h>
   47 #include <sys/stddef.h>
   48 #include <sys/param.h>
   49 #include <sys/queue.h>
   50 #include <sys/types.h>
   51 #include <sys/systm.h>
   52 #include <sys/kernel.h>
   53 #include <sys/bus.h>
   54 #include <sys/module.h>
   55 #include <sys/lock.h>
   56 #include <sys/mutex.h>
   57 #include <sys/condvar.h>
   58 #include <sys/sysctl.h>
   59 #include <sys/sx.h>
   60 #include <sys/unistd.h>
   61 #include <sys/callout.h>
   62 #include <sys/malloc.h>
   63 #include <sys/priv.h>
   64 
   65 #include <dev/usb/usb.h>
   66 #include <dev/usb/usbdi.h>
   67 #include <dev/usb/usb_core.h>
   68 #include <dev/usb/usb_cdc.h>
   69 #include <dev/usb/usb_ioctl.h>
   70 #include <dev/usb/usb_util.h>
   71 
   72 #include <dev/usb/template/usb_template.h>
   73 #endif          /* USB_GLOBAL_INCLUDE_FILE */
   74 
   75 #define MODEM_IFACE_0 0
   76 #define MODEM_IFACE_1 1
   77 
   78 enum {
   79         SERIALNET_LANG_INDEX,
   80         SERIALNET_MODEM_INDEX,
   81         SERIALNET_ETH_MAC_INDEX,
   82         SERIALNET_ETH_CONTROL_INDEX,
   83         SERIALNET_ETH_DATA_INDEX,
   84         SERIALNET_CONFIGURATION_INDEX,
   85         SERIALNET_MANUFACTURER_INDEX,
   86         SERIALNET_PRODUCT_INDEX,
   87         SERIALNET_SERIAL_NUMBER_INDEX,
   88         SERIALNET_MAX_INDEX,
   89 };
   90 
   91 #define SERIALNET_DEFAULT_VENDOR_ID     USB_TEMPLATE_VENDOR
   92 #define SERIALNET_DEFAULT_PRODUCT_ID    0x05dc
   93 #define SERIALNET_DEFAULT_MODEM         "Virtual serial port"
   94 #define SERIALNET_DEFAULT_ETH_MAC       "2A02030405060789AB"
   95 #define SERIALNET_DEFAULT_ETH_CONTROL   "USB Ethernet Comm Interface"
   96 #define SERIALNET_DEFAULT_ETH_DATA      "USB Ethernet Data Interface"
   97 #define SERIALNET_DEFAULT_CONFIGURATION "Default configuration"
   98 #define SERIALNET_DEFAULT_MANUFACTURER  USB_TEMPLATE_MANUFACTURER
   99 #define SERIALNET_DEFAULT_PRODUCT       "Serial/Ethernet device"
  100 /*
  101  * The reason for this being called like this is that OSX
  102  * derives the device node name from it, resulting in a somewhat
  103  * user-friendly "/dev/cu.usbmodemFreeBSD1".  And yes, the "1"
  104  * needs to be there, otherwise OSX will mangle it.
  105  */
  106 #define SERIALNET_DEFAULT_SERIAL_NUMBER "FreeBSD1"
  107 
  108 static struct usb_string_descriptor     serialnet_modem;
  109 static struct usb_string_descriptor     serialnet_eth_mac;
  110 static struct usb_string_descriptor     serialnet_eth_control;
  111 static struct usb_string_descriptor     serialnet_eth_data;
  112 static struct usb_string_descriptor     serialnet_configuration;
  113 static struct usb_string_descriptor     serialnet_manufacturer;
  114 static struct usb_string_descriptor     serialnet_product;
  115 static struct usb_string_descriptor     serialnet_serial_number;
  116 
  117 static struct sysctl_ctx_list           serialnet_ctx_list;
  118 
  119 /* prototypes */
  120 
  121 static usb_temp_get_string_desc_t serialnet_get_string_desc;
  122 
  123 static const struct usb_cdc_union_descriptor eth_union_desc = {
  124         .bLength = sizeof(eth_union_desc),
  125         .bDescriptorType = UDESC_CS_INTERFACE,
  126         .bDescriptorSubtype = UDESCSUB_CDC_UNION,
  127         .bMasterInterface = 0,          /* this is automatically updated */
  128         .bSlaveInterface[0] = 1,        /* this is automatically updated */
  129 };
  130 
  131 static const struct usb_cdc_header_descriptor eth_header_desc = {
  132         .bLength = sizeof(eth_header_desc),
  133         .bDescriptorType = UDESC_CS_INTERFACE,
  134         .bDescriptorSubtype = UDESCSUB_CDC_HEADER,
  135         .bcdCDC[0] = 0x10,
  136         .bcdCDC[1] = 0x01,
  137 };
  138 
  139 static const struct usb_cdc_ethernet_descriptor eth_enf_desc = {
  140         .bLength = sizeof(eth_enf_desc),
  141         .bDescriptorType = UDESC_CS_INTERFACE,
  142         .bDescriptorSubtype = UDESCSUB_CDC_ENF,
  143         .iMacAddress = SERIALNET_ETH_MAC_INDEX,
  144         .bmEthernetStatistics = {0, 0, 0, 0},
  145         .wMaxSegmentSize = {0xEA, 0x05},/* 1514 bytes */
  146         .wNumberMCFilters = {0, 0},
  147         .bNumberPowerFilters = 0,
  148 };
  149 
  150 static const void *eth_control_if_desc[] = {
  151         &eth_union_desc,
  152         &eth_header_desc,
  153         &eth_enf_desc,
  154         NULL,
  155 };
  156 
  157 static const struct usb_temp_packet_size bulk_mps = {
  158         .mps[USB_SPEED_FULL] = 64,
  159         .mps[USB_SPEED_HIGH] = 512,
  160 };
  161 
  162 static const struct usb_temp_packet_size intr_mps = {
  163         .mps[USB_SPEED_FULL] = 8,
  164         .mps[USB_SPEED_HIGH] = 8,
  165 };
  166 
  167 static const struct usb_temp_endpoint_desc bulk_in_ep = {
  168         .pPacketSize = &bulk_mps,
  169 #ifdef USB_HIP_IN_EP_0
  170         .bEndpointAddress = USB_HIP_IN_EP_0,
  171 #else
  172         .bEndpointAddress = UE_DIR_IN,
  173 #endif
  174         .bmAttributes = UE_BULK,
  175 };
  176 
  177 static const struct usb_temp_endpoint_desc bulk_out_ep = {
  178         .pPacketSize = &bulk_mps,
  179 #ifdef USB_HIP_OUT_EP_0
  180         .bEndpointAddress = USB_HIP_OUT_EP_0,
  181 #else
  182         .bEndpointAddress = UE_DIR_OUT,
  183 #endif
  184         .bmAttributes = UE_BULK,
  185 };
  186 
  187 static const struct usb_temp_endpoint_desc intr_in_ep = {
  188         .pPacketSize = &intr_mps,
  189         .bEndpointAddress = UE_DIR_IN,
  190         .bmAttributes = UE_INTERRUPT,
  191 };
  192 
  193 static const struct usb_temp_endpoint_desc *eth_intr_endpoints[] = {
  194         &intr_in_ep,
  195         NULL,
  196 };
  197 
  198 static const struct usb_temp_interface_desc eth_control_interface = {
  199         .ppEndpoints = eth_intr_endpoints,
  200         .ppRawDesc = eth_control_if_desc,
  201         .bInterfaceClass = UICLASS_CDC,
  202         .bInterfaceSubClass = UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL,
  203         .bInterfaceProtocol = UIPROTO_CDC_NONE,
  204         .iInterface = SERIALNET_ETH_CONTROL_INDEX,
  205 };
  206 
  207 static const struct usb_temp_endpoint_desc *eth_data_endpoints[] = {
  208         &bulk_in_ep,
  209         &bulk_out_ep,
  210         NULL,
  211 };
  212 
  213 static const struct usb_temp_interface_desc eth_data_null_interface = {
  214         .ppEndpoints = NULL,            /* no endpoints */
  215         .bInterfaceClass = UICLASS_CDC_DATA,
  216         .bInterfaceSubClass = UISUBCLASS_DATA,
  217         .bInterfaceProtocol = 0,
  218         .iInterface = SERIALNET_ETH_DATA_INDEX,
  219 };
  220 
  221 static const struct usb_temp_interface_desc eth_data_interface = {
  222         .ppEndpoints = eth_data_endpoints,
  223         .bInterfaceClass = UICLASS_CDC_DATA,
  224         .bInterfaceSubClass = UISUBCLASS_DATA,
  225         .bInterfaceProtocol = 0,
  226         .iInterface = SERIALNET_ETH_DATA_INDEX,
  227         .isAltInterface = 1,            /* this is an alternate setting */
  228 };
  229 
  230 static const struct usb_temp_packet_size modem_bulk_mps = {
  231         .mps[USB_SPEED_LOW] = 8,
  232         .mps[USB_SPEED_FULL] = 64,
  233         .mps[USB_SPEED_HIGH] = 512,
  234 };
  235 
  236 static const struct usb_temp_packet_size modem_intr_mps = {
  237         .mps[USB_SPEED_LOW] = 8,
  238         .mps[USB_SPEED_FULL] = 8,
  239         .mps[USB_SPEED_HIGH] = 8,
  240 };
  241 
  242 static const struct usb_temp_interval modem_intr_interval = {
  243         .bInterval[USB_SPEED_LOW] = 8,  /* 8ms */
  244         .bInterval[USB_SPEED_FULL] = 8, /* 8ms */
  245         .bInterval[USB_SPEED_HIGH] = 7, /* 8ms */
  246 };
  247 
  248 static const struct usb_temp_endpoint_desc modem_ep_0 = {
  249         .pPacketSize = &modem_intr_mps,
  250         .pIntervals = &modem_intr_interval,
  251         .bEndpointAddress = UE_DIR_IN,
  252         .bmAttributes = UE_INTERRUPT,
  253 };
  254 
  255 static const struct usb_temp_endpoint_desc modem_ep_1 = {
  256         .pPacketSize = &modem_bulk_mps,
  257         .bEndpointAddress = UE_DIR_OUT,
  258         .bmAttributes = UE_BULK,
  259 };
  260 
  261 static const struct usb_temp_endpoint_desc modem_ep_2 = {
  262         .pPacketSize = &modem_bulk_mps,
  263         .bEndpointAddress = UE_DIR_IN,
  264         .bmAttributes = UE_BULK,
  265 };
  266 
  267 static const struct usb_temp_endpoint_desc *modem_iface_0_ep[] = {
  268         &modem_ep_0,
  269         NULL,
  270 };
  271 
  272 static const struct usb_temp_endpoint_desc *modem_iface_1_ep[] = {
  273         &modem_ep_1,
  274         &modem_ep_2,
  275         NULL,
  276 };
  277 
  278 static const uint8_t modem_raw_desc_0[] = {
  279         0x05, 0x24, 0x00, 0x10, 0x01
  280 };
  281 
  282 static const uint8_t modem_raw_desc_1[] = {
  283         0x05, 0x24, 0x06, MODEM_IFACE_0, MODEM_IFACE_1
  284 };
  285 
  286 static const uint8_t modem_raw_desc_2[] = {
  287         0x05, 0x24, 0x01, 0x03, MODEM_IFACE_1
  288 };
  289 
  290 static const uint8_t modem_raw_desc_3[] = {
  291         0x04, 0x24, 0x02, 0x07
  292 };
  293 
  294 static const void *modem_iface_0_desc[] = {
  295         &modem_raw_desc_0,
  296         &modem_raw_desc_1,
  297         &modem_raw_desc_2,
  298         &modem_raw_desc_3,
  299         NULL,
  300 };
  301 
  302 static const struct usb_temp_interface_desc modem_iface_0 = {
  303         .ppRawDesc = modem_iface_0_desc,
  304         .ppEndpoints = modem_iface_0_ep,
  305         .bInterfaceClass = UICLASS_CDC,
  306         .bInterfaceSubClass = UISUBCLASS_ABSTRACT_CONTROL_MODEL,
  307         .bInterfaceProtocol = UIPROTO_CDC_NONE,
  308         .iInterface = SERIALNET_MODEM_INDEX,
  309 };
  310 
  311 static const struct usb_temp_interface_desc modem_iface_1 = {
  312         .ppEndpoints = modem_iface_1_ep,
  313         .bInterfaceClass = UICLASS_CDC_DATA,
  314         .bInterfaceSubClass = UISUBCLASS_DATA,
  315         .bInterfaceProtocol = 0,
  316         .iInterface = SERIALNET_MODEM_INDEX,
  317 };
  318 
  319 static const struct usb_temp_interface_desc *serialnet_interfaces[] = {
  320         &modem_iface_0,
  321         &modem_iface_1,
  322         &eth_control_interface,
  323         &eth_data_null_interface,
  324         &eth_data_interface,
  325         NULL,
  326 };
  327 
  328 static const struct usb_temp_config_desc serialnet_config_desc = {
  329         .ppIfaceDesc = serialnet_interfaces,
  330         .bmAttributes = 0,
  331         .bMaxPower = 0,
  332         .iConfiguration = SERIALNET_CONFIGURATION_INDEX,
  333 };
  334 static const struct usb_temp_config_desc *serialnet_configs[] = {
  335         &serialnet_config_desc,
  336         NULL,
  337 };
  338 
  339 struct usb_temp_device_desc usb_template_serialnet = {
  340         .getStringDesc = &serialnet_get_string_desc,
  341         .ppConfigDesc = serialnet_configs,
  342         .idVendor = SERIALNET_DEFAULT_VENDOR_ID,
  343         .idProduct = SERIALNET_DEFAULT_PRODUCT_ID,
  344         .bcdDevice = 0x0100,
  345         .bDeviceClass = UDCLASS_IN_INTERFACE,
  346         .bDeviceSubClass = 0,
  347         .bDeviceProtocol = 0,
  348         .iManufacturer = SERIALNET_MANUFACTURER_INDEX,
  349         .iProduct = SERIALNET_PRODUCT_INDEX,
  350         .iSerialNumber = SERIALNET_SERIAL_NUMBER_INDEX,
  351 };
  352 
  353 /*------------------------------------------------------------------------*
  354  *      serialnet_get_string_desc
  355  *
  356  * Return values:
  357  * NULL: Failure. No such string.
  358  * Else: Success. Pointer to string descriptor is returned.
  359  *------------------------------------------------------------------------*/
  360 static const void *
  361 serialnet_get_string_desc(uint16_t lang_id, uint8_t string_index)
  362 {
  363         static const void *ptr[SERIALNET_MAX_INDEX] = {
  364                 [SERIALNET_LANG_INDEX] = &usb_string_lang_en,
  365                 [SERIALNET_MODEM_INDEX] = &serialnet_modem,
  366                 [SERIALNET_ETH_MAC_INDEX] = &serialnet_eth_mac,
  367                 [SERIALNET_ETH_CONTROL_INDEX] = &serialnet_eth_control,
  368                 [SERIALNET_ETH_DATA_INDEX] = &serialnet_eth_data,
  369                 [SERIALNET_CONFIGURATION_INDEX] = &serialnet_configuration,
  370                 [SERIALNET_MANUFACTURER_INDEX] = &serialnet_manufacturer,
  371                 [SERIALNET_PRODUCT_INDEX] = &serialnet_product,
  372                 [SERIALNET_SERIAL_NUMBER_INDEX] = &serialnet_serial_number,
  373         };
  374 
  375         if (string_index == 0) {
  376                 return (&usb_string_lang_en);
  377         }
  378         if (lang_id != 0x0409) {
  379                 return (NULL);
  380         }
  381         if (string_index < SERIALNET_MAX_INDEX) {
  382                 return (ptr[string_index]);
  383         }
  384         return (NULL);
  385 }
  386 
  387 static void
  388 serialnet_init(void *arg __unused)
  389 {
  390         struct sysctl_oid *parent;
  391         char parent_name[3];
  392 
  393         usb_make_str_desc(&serialnet_modem, sizeof(serialnet_modem),
  394             SERIALNET_DEFAULT_MODEM);
  395         usb_make_str_desc(&serialnet_eth_mac, sizeof(serialnet_eth_mac),
  396             SERIALNET_DEFAULT_ETH_MAC);
  397         usb_make_str_desc(&serialnet_eth_control, sizeof(serialnet_eth_control),
  398             SERIALNET_DEFAULT_ETH_CONTROL);
  399         usb_make_str_desc(&serialnet_eth_data, sizeof(serialnet_eth_data),
  400             SERIALNET_DEFAULT_ETH_DATA);
  401         usb_make_str_desc(&serialnet_configuration, sizeof(serialnet_configuration),
  402             SERIALNET_DEFAULT_CONFIGURATION);
  403         usb_make_str_desc(&serialnet_manufacturer, sizeof(serialnet_manufacturer),
  404             SERIALNET_DEFAULT_MANUFACTURER);
  405         usb_make_str_desc(&serialnet_product, sizeof(serialnet_product),
  406             SERIALNET_DEFAULT_PRODUCT);
  407         usb_make_str_desc(&serialnet_serial_number, sizeof(serialnet_serial_number),
  408             SERIALNET_DEFAULT_SERIAL_NUMBER);
  409 
  410         snprintf(parent_name, sizeof(parent_name), "%d", USB_TEMP_SERIALNET);
  411         sysctl_ctx_init(&serialnet_ctx_list);
  412 
  413         parent = SYSCTL_ADD_NODE(&serialnet_ctx_list,
  414             SYSCTL_STATIC_CHILDREN(_hw_usb_templates), OID_AUTO,
  415             parent_name, CTLFLAG_RW | CTLFLAG_MPSAFE,
  416             0, "USB CDC Serial/Ethernet device side template");
  417         SYSCTL_ADD_U16(&serialnet_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  418             "vendor_id", CTLFLAG_RWTUN,
  419             &usb_template_serialnet.idVendor, 1, "Vendor identifier");
  420         SYSCTL_ADD_U16(&serialnet_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  421             "product_id", CTLFLAG_RWTUN,
  422             &usb_template_serialnet.idProduct, 1, "Product identifier");
  423         SYSCTL_ADD_PROC(&serialnet_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  424             "eth_mac", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  425             &serialnet_eth_mac, sizeof(serialnet_eth_mac), usb_temp_sysctl,
  426             "A", "Ethernet MAC address string");
  427 #if 0
  428         SYSCTL_ADD_PROC(&serialnet_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  429             "modem", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  430             &serialnet_modem, sizeof(serialnet_modem), usb_temp_sysctl,
  431             "A", "Modem interface string");
  432         SYSCTL_ADD_PROC(&serialnet_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  433             "eth_control", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  434             &serialnet_eth_control, sizeof(serialnet_eth_data), usb_temp_sysctl,
  435             "A", "Ethernet control interface string");
  436         SYSCTL_ADD_PROC(&serialnet_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  437             "eth_data", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  438             &serialnet_eth_data, sizeof(serialnet_eth_data), usb_temp_sysctl,
  439             "A", "Ethernet data interface string");
  440         SYSCTL_ADD_PROC(&serialnet_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  441             "configuration", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  442             &serialnet_configuration, sizeof(serialnet_configuration), usb_temp_sysctl,
  443             "A", "Configuration string");
  444 #endif
  445         SYSCTL_ADD_PROC(&serialnet_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  446             "manufacturer", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  447             &serialnet_manufacturer, sizeof(serialnet_manufacturer), usb_temp_sysctl,
  448             "A", "Manufacturer string");
  449         SYSCTL_ADD_PROC(&serialnet_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  450             "product", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  451             &serialnet_product, sizeof(serialnet_product), usb_temp_sysctl,
  452             "A", "Product string");
  453         SYSCTL_ADD_PROC(&serialnet_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  454             "serial_number", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  455             &serialnet_serial_number, sizeof(serialnet_serial_number), usb_temp_sysctl,
  456             "A", "Serial number string");
  457 }
  458 
  459 static void
  460 serialnet_uninit(void *arg __unused)
  461 {
  462 
  463         sysctl_ctx_free(&serialnet_ctx_list);
  464 }
  465 
  466 SYSINIT(serialnet_init, SI_SUB_LOCK, SI_ORDER_FIRST, serialnet_init, NULL);
  467 SYSUNINIT(serialnet_uninit, SI_SUB_LOCK, SI_ORDER_FIRST, serialnet_uninit, NULL);

Cache object: 3e9db16450bd88a767a468788c33faa8


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