10a76fe7cSHans Petter Selasky /* $FreeBSD$ */ 20a76fe7cSHans Petter Selasky /*- 342e42a9aSEdward Tomasz Napierala * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 442e42a9aSEdward Tomasz Napierala * 58e06491aSEdward Tomasz Napierala * Copyright (c) 2015 Hans Petter Selasky 68e06491aSEdward Tomasz Napierala * Copyright (c) 2018 The FreeBSD Foundation 78e06491aSEdward Tomasz Napierala * All rights reserved. 88e06491aSEdward Tomasz Napierala * 98e06491aSEdward Tomasz Napierala * Portions of this software were developed by Edward Tomasz Napierala 108e06491aSEdward Tomasz Napierala * under sponsorship from the FreeBSD Foundation. 110a76fe7cSHans Petter Selasky * 120a76fe7cSHans Petter Selasky * Redistribution and use in source and binary forms, with or without 130a76fe7cSHans Petter Selasky * modification, are permitted provided that the following conditions 140a76fe7cSHans Petter Selasky * are met: 150a76fe7cSHans Petter Selasky * 1. Redistributions of source code must retain the above copyright 160a76fe7cSHans Petter Selasky * notice, this list of conditions and the following disclaimer. 170a76fe7cSHans Petter Selasky * 2. Redistributions in binary form must reproduce the above copyright 180a76fe7cSHans Petter Selasky * notice, this list of conditions and the following disclaimer in the 190a76fe7cSHans Petter Selasky * documentation and/or other materials provided with the distribution. 200a76fe7cSHans Petter Selasky * 210a76fe7cSHans Petter Selasky * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 220a76fe7cSHans Petter Selasky * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 230a76fe7cSHans Petter Selasky * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 240a76fe7cSHans Petter Selasky * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 250a76fe7cSHans Petter Selasky * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 260a76fe7cSHans Petter Selasky * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 270a76fe7cSHans Petter Selasky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 280a76fe7cSHans Petter Selasky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 290a76fe7cSHans Petter Selasky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 300a76fe7cSHans Petter Selasky * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 310a76fe7cSHans Petter Selasky * SUCH DAMAGE. 320a76fe7cSHans Petter Selasky */ 330a76fe7cSHans Petter Selasky 340a76fe7cSHans Petter Selasky /* 350a76fe7cSHans Petter Selasky * This file contains the USB template for an USB MIDI Device. 360a76fe7cSHans Petter Selasky */ 370a76fe7cSHans Petter Selasky 380a76fe7cSHans Petter Selasky #ifdef USB_GLOBAL_INCLUDE_FILE 390a76fe7cSHans Petter Selasky #include USB_GLOBAL_INCLUDE_FILE 400a76fe7cSHans Petter Selasky #else 410a76fe7cSHans Petter Selasky #include <sys/stdint.h> 420a76fe7cSHans Petter Selasky #include <sys/stddef.h> 430a76fe7cSHans Petter Selasky #include <sys/param.h> 440a76fe7cSHans Petter Selasky #include <sys/queue.h> 450a76fe7cSHans Petter Selasky #include <sys/types.h> 460a76fe7cSHans Petter Selasky #include <sys/systm.h> 470a76fe7cSHans Petter Selasky #include <sys/kernel.h> 480a76fe7cSHans Petter Selasky #include <sys/bus.h> 490a76fe7cSHans Petter Selasky #include <sys/module.h> 500a76fe7cSHans Petter Selasky #include <sys/lock.h> 510a76fe7cSHans Petter Selasky #include <sys/mutex.h> 520a76fe7cSHans Petter Selasky #include <sys/condvar.h> 530a76fe7cSHans Petter Selasky #include <sys/sysctl.h> 540a76fe7cSHans Petter Selasky #include <sys/sx.h> 550a76fe7cSHans Petter Selasky #include <sys/unistd.h> 560a76fe7cSHans Petter Selasky #include <sys/callout.h> 570a76fe7cSHans Petter Selasky #include <sys/malloc.h> 580a76fe7cSHans Petter Selasky #include <sys/priv.h> 590a76fe7cSHans Petter Selasky 600a76fe7cSHans Petter Selasky #include <dev/usb/usb.h> 610a76fe7cSHans Petter Selasky #include <dev/usb/usbdi.h> 620a76fe7cSHans Petter Selasky #include <dev/usb/usb_core.h> 638e06491aSEdward Tomasz Napierala #include <dev/usb/usb_ioctl.h> 648e06491aSEdward Tomasz Napierala #include <dev/usb/usb_util.h> 650a76fe7cSHans Petter Selasky 660a76fe7cSHans Petter Selasky #include <dev/usb/template/usb_template.h> 670a76fe7cSHans Petter Selasky #endif /* USB_GLOBAL_INCLUDE_FILE */ 680a76fe7cSHans Petter Selasky 690a76fe7cSHans Petter Selasky enum { 708e06491aSEdward Tomasz Napierala MIDI_LANG_INDEX, 718e06491aSEdward Tomasz Napierala MIDI_INTERFACE_INDEX, 721ee5bed7SEdward Tomasz Napierala MIDI_MANUFACTURER_INDEX, 738e06491aSEdward Tomasz Napierala MIDI_PRODUCT_INDEX, 741ee5bed7SEdward Tomasz Napierala MIDI_SERIAL_NUMBER_INDEX, 758e06491aSEdward Tomasz Napierala MIDI_MAX_INDEX, 760a76fe7cSHans Petter Selasky }; 770a76fe7cSHans Petter Selasky 781558eec6SEdward Tomasz Napierala #define MIDI_DEFAULT_VENDOR_ID USB_TEMPLATE_VENDOR 79d01c1c8bSEdward Tomasz Napierala #define MIDI_DEFAULT_PRODUCT_ID 0x27de 808e06491aSEdward Tomasz Napierala #define MIDI_DEFAULT_INTERFACE "MIDI interface" 81d01c1c8bSEdward Tomasz Napierala #define MIDI_DEFAULT_MANUFACTURER USB_TEMPLATE_MANUFACTURER 828e06491aSEdward Tomasz Napierala #define MIDI_DEFAULT_PRODUCT "MIDI Test Device" 831ee5bed7SEdward Tomasz Napierala #define MIDI_DEFAULT_SERIAL_NUMBER "March 2008" 840a76fe7cSHans Petter Selasky 858e06491aSEdward Tomasz Napierala static struct usb_string_descriptor midi_interface; 861ee5bed7SEdward Tomasz Napierala static struct usb_string_descriptor midi_manufacturer; 878e06491aSEdward Tomasz Napierala static struct usb_string_descriptor midi_product; 881ee5bed7SEdward Tomasz Napierala static struct usb_string_descriptor midi_serial_number; 890a76fe7cSHans Petter Selasky 908e06491aSEdward Tomasz Napierala static struct sysctl_ctx_list midi_ctx_list; 910a76fe7cSHans Petter Selasky 920a76fe7cSHans Petter Selasky /* prototypes */ 930a76fe7cSHans Petter Selasky 940a76fe7cSHans Petter Selasky static const uint8_t midi_desc_raw_0[9] = { 950a76fe7cSHans Petter Selasky 0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01 960a76fe7cSHans Petter Selasky }; 970a76fe7cSHans Petter Selasky 980a76fe7cSHans Petter Selasky static const void *midi_descs_0[] = { 990a76fe7cSHans Petter Selasky &midi_desc_raw_0, 1000a76fe7cSHans Petter Selasky NULL 1010a76fe7cSHans Petter Selasky }; 1020a76fe7cSHans Petter Selasky 1030a76fe7cSHans Petter Selasky static const struct usb_temp_interface_desc midi_iface_0 = { 1040a76fe7cSHans Petter Selasky .ppEndpoints = NULL, /* no endpoints */ 1050a76fe7cSHans Petter Selasky .ppRawDesc = midi_descs_0, 1064ffeccf1SEdward Tomasz Napierala .bInterfaceClass = UICLASS_AUDIO, 1074ffeccf1SEdward Tomasz Napierala .bInterfaceSubClass = UISUBCLASS_AUDIOCONTROL, 1080a76fe7cSHans Petter Selasky .bInterfaceProtocol = 0, 1098e06491aSEdward Tomasz Napierala .iInterface = MIDI_INTERFACE_INDEX, 1100a76fe7cSHans Petter Selasky }; 1110a76fe7cSHans Petter Selasky 1120a76fe7cSHans Petter Selasky static const struct usb_temp_packet_size midi_mps = { 1130a76fe7cSHans Petter Selasky .mps[USB_SPEED_LOW] = 8, 1140a76fe7cSHans Petter Selasky .mps[USB_SPEED_FULL] = 64, 1150a76fe7cSHans Petter Selasky .mps[USB_SPEED_HIGH] = 512, 1160a76fe7cSHans Petter Selasky }; 1170a76fe7cSHans Petter Selasky 1180a76fe7cSHans Petter Selasky static const uint8_t midi_desc_raw_7[5] = { 1190a76fe7cSHans Petter Selasky 0x05, 0x25, 0x01, 0x01, 0x01 1200a76fe7cSHans Petter Selasky }; 1210a76fe7cSHans Petter Selasky 1220a76fe7cSHans Petter Selasky static const void *midi_descs_2[] = { 1230a76fe7cSHans Petter Selasky &midi_desc_raw_7, 1240a76fe7cSHans Petter Selasky NULL 1250a76fe7cSHans Petter Selasky }; 1260a76fe7cSHans Petter Selasky 1270a76fe7cSHans Petter Selasky static const struct usb_temp_endpoint_desc midi_bulk_out_ep = { 1280a76fe7cSHans Petter Selasky .ppRawDesc = midi_descs_2, 1290a76fe7cSHans Petter Selasky .pPacketSize = &midi_mps, 1300a76fe7cSHans Petter Selasky .bEndpointAddress = UE_DIR_OUT, 1310a76fe7cSHans Petter Selasky .bmAttributes = UE_BULK, 1320a76fe7cSHans Petter Selasky }; 1330a76fe7cSHans Petter Selasky 1340a76fe7cSHans Petter Selasky static const uint8_t midi_desc_raw_6[5] = { 1350a76fe7cSHans Petter Selasky 0x05, 0x25, 0x01, 0x01, 0x03, 1360a76fe7cSHans Petter Selasky }; 1370a76fe7cSHans Petter Selasky 1380a76fe7cSHans Petter Selasky static const void *midi_descs_3[] = { 1390a76fe7cSHans Petter Selasky &midi_desc_raw_6, 1400a76fe7cSHans Petter Selasky NULL 1410a76fe7cSHans Petter Selasky }; 1420a76fe7cSHans Petter Selasky 1430a76fe7cSHans Petter Selasky static const struct usb_temp_endpoint_desc midi_bulk_in_ep = { 1440a76fe7cSHans Petter Selasky .ppRawDesc = midi_descs_3, 1450a76fe7cSHans Petter Selasky .pPacketSize = &midi_mps, 1460a76fe7cSHans Petter Selasky .bEndpointAddress = UE_DIR_IN, 1470a76fe7cSHans Petter Selasky .bmAttributes = UE_BULK, 1480a76fe7cSHans Petter Selasky }; 1490a76fe7cSHans Petter Selasky 1500a76fe7cSHans Petter Selasky static const struct usb_temp_endpoint_desc *midi_iface_1_ep[] = { 1510a76fe7cSHans Petter Selasky &midi_bulk_out_ep, 1520a76fe7cSHans Petter Selasky &midi_bulk_in_ep, 1530a76fe7cSHans Petter Selasky NULL, 1540a76fe7cSHans Petter Selasky }; 1550a76fe7cSHans Petter Selasky 1560a76fe7cSHans Petter Selasky static const uint8_t midi_desc_raw_1[7] = { 1570a76fe7cSHans Petter Selasky 0x07, 0x24, 0x01, 0x00, 0x01, /* wTotalLength: */ 0x41, 0x00 1580a76fe7cSHans Petter Selasky }; 1590a76fe7cSHans Petter Selasky 1600a76fe7cSHans Petter Selasky static const uint8_t midi_desc_raw_2[6] = { 1610a76fe7cSHans Petter Selasky 0x06, 0x24, 0x02, 0x01, 0x01, 0x00 1620a76fe7cSHans Petter Selasky }; 1630a76fe7cSHans Petter Selasky 1640a76fe7cSHans Petter Selasky static const uint8_t midi_desc_raw_3[6] = { 1650a76fe7cSHans Petter Selasky 0x06, 0x24, 0x02, 0x02, 0x02, 0x00 1660a76fe7cSHans Petter Selasky }; 1670a76fe7cSHans Petter Selasky 1680a76fe7cSHans Petter Selasky static const uint8_t midi_desc_raw_4[9] = { 1690a76fe7cSHans Petter Selasky 0x09, 0x24, 0x03, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00 1700a76fe7cSHans Petter Selasky }; 1710a76fe7cSHans Petter Selasky 1720a76fe7cSHans Petter Selasky static const uint8_t midi_desc_raw_5[9] = { 1730a76fe7cSHans Petter Selasky 0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x01, 0x01, 0x00 1740a76fe7cSHans Petter Selasky }; 1750a76fe7cSHans Petter Selasky 1760a76fe7cSHans Petter Selasky static const void *midi_descs_1[] = { 1770a76fe7cSHans Petter Selasky &midi_desc_raw_1, 1780a76fe7cSHans Petter Selasky &midi_desc_raw_2, 1790a76fe7cSHans Petter Selasky &midi_desc_raw_3, 1800a76fe7cSHans Petter Selasky &midi_desc_raw_4, 1810a76fe7cSHans Petter Selasky &midi_desc_raw_5, 1820a76fe7cSHans Petter Selasky NULL 1830a76fe7cSHans Petter Selasky }; 1840a76fe7cSHans Petter Selasky 1850a76fe7cSHans Petter Selasky static const struct usb_temp_interface_desc midi_iface_1 = { 1860a76fe7cSHans Petter Selasky .ppRawDesc = midi_descs_1, 1870a76fe7cSHans Petter Selasky .ppEndpoints = midi_iface_1_ep, 1884ffeccf1SEdward Tomasz Napierala .bInterfaceClass = UICLASS_AUDIO, 1894ffeccf1SEdward Tomasz Napierala .bInterfaceSubClass = UISUBCLASS_MIDISTREAM, 1900a76fe7cSHans Petter Selasky .bInterfaceProtocol = 0, 1918e06491aSEdward Tomasz Napierala .iInterface = MIDI_INTERFACE_INDEX, 1920a76fe7cSHans Petter Selasky }; 1930a76fe7cSHans Petter Selasky 1940a76fe7cSHans Petter Selasky static const struct usb_temp_interface_desc *midi_interfaces[] = { 1950a76fe7cSHans Petter Selasky &midi_iface_0, 1960a76fe7cSHans Petter Selasky &midi_iface_1, 1970a76fe7cSHans Petter Selasky NULL, 1980a76fe7cSHans Petter Selasky }; 1990a76fe7cSHans Petter Selasky 2000a76fe7cSHans Petter Selasky static const struct usb_temp_config_desc midi_config_desc = { 2010a76fe7cSHans Petter Selasky .ppIfaceDesc = midi_interfaces, 202*d008c0d7SEdward Tomasz Napierala .bmAttributes = 0, 203*d008c0d7SEdward Tomasz Napierala .bMaxPower = 0, 2048e06491aSEdward Tomasz Napierala .iConfiguration = MIDI_PRODUCT_INDEX, 2050a76fe7cSHans Petter Selasky }; 2060a76fe7cSHans Petter Selasky 2070a76fe7cSHans Petter Selasky static const struct usb_temp_config_desc *midi_configs[] = { 2080a76fe7cSHans Petter Selasky &midi_config_desc, 2090a76fe7cSHans Petter Selasky NULL, 2100a76fe7cSHans Petter Selasky }; 2110a76fe7cSHans Petter Selasky 2120a76fe7cSHans Petter Selasky static usb_temp_get_string_desc_t midi_get_string_desc; 2130a76fe7cSHans Petter Selasky 2148e06491aSEdward Tomasz Napierala struct usb_temp_device_desc usb_template_midi = { 2150a76fe7cSHans Petter Selasky .getStringDesc = &midi_get_string_desc, 2160a76fe7cSHans Petter Selasky .ppConfigDesc = midi_configs, 2171558eec6SEdward Tomasz Napierala .idVendor = MIDI_DEFAULT_VENDOR_ID, 2181558eec6SEdward Tomasz Napierala .idProduct = MIDI_DEFAULT_PRODUCT_ID, 2190a76fe7cSHans Petter Selasky .bcdDevice = 0x0100, 2200a76fe7cSHans Petter Selasky .bDeviceClass = 0, 2210a76fe7cSHans Petter Selasky .bDeviceSubClass = 0, 2220a76fe7cSHans Petter Selasky .bDeviceProtocol = 0, 2231ee5bed7SEdward Tomasz Napierala .iManufacturer = MIDI_MANUFACTURER_INDEX, 2248e06491aSEdward Tomasz Napierala .iProduct = MIDI_PRODUCT_INDEX, 2251ee5bed7SEdward Tomasz Napierala .iSerialNumber = MIDI_SERIAL_NUMBER_INDEX, 2260a76fe7cSHans Petter Selasky }; 2270a76fe7cSHans Petter Selasky 2280a76fe7cSHans Petter Selasky /*------------------------------------------------------------------------* 2290a76fe7cSHans Petter Selasky * midi_get_string_desc 2300a76fe7cSHans Petter Selasky * 2310a76fe7cSHans Petter Selasky * Return values: 2320a76fe7cSHans Petter Selasky * NULL: Failure. No such string. 2330a76fe7cSHans Petter Selasky * Else: Success. Pointer to string descriptor is returned. 2340a76fe7cSHans Petter Selasky *------------------------------------------------------------------------*/ 2350a76fe7cSHans Petter Selasky static const void * 2360a76fe7cSHans Petter Selasky midi_get_string_desc(uint16_t lang_id, uint8_t string_index) 2370a76fe7cSHans Petter Selasky { 2388e06491aSEdward Tomasz Napierala static const void *ptr[MIDI_MAX_INDEX] = { 2398e06491aSEdward Tomasz Napierala [MIDI_LANG_INDEX] = &usb_string_lang_en, 2408e06491aSEdward Tomasz Napierala [MIDI_INTERFACE_INDEX] = &midi_interface, 2411ee5bed7SEdward Tomasz Napierala [MIDI_MANUFACTURER_INDEX] = &midi_manufacturer, 2428e06491aSEdward Tomasz Napierala [MIDI_PRODUCT_INDEX] = &midi_product, 2431ee5bed7SEdward Tomasz Napierala [MIDI_SERIAL_NUMBER_INDEX] = &midi_serial_number, 2440a76fe7cSHans Petter Selasky }; 2450a76fe7cSHans Petter Selasky 2460a76fe7cSHans Petter Selasky if (string_index == 0) { 2470a76fe7cSHans Petter Selasky return (&usb_string_lang_en); 2480a76fe7cSHans Petter Selasky } 2490a76fe7cSHans Petter Selasky if (lang_id != 0x0409) { 2500a76fe7cSHans Petter Selasky return (NULL); 2510a76fe7cSHans Petter Selasky } 2528e06491aSEdward Tomasz Napierala if (string_index < MIDI_MAX_INDEX) { 2530a76fe7cSHans Petter Selasky return (ptr[string_index]); 2540a76fe7cSHans Petter Selasky } 2550a76fe7cSHans Petter Selasky return (NULL); 2560a76fe7cSHans Petter Selasky } 2578e06491aSEdward Tomasz Napierala 2588e06491aSEdward Tomasz Napierala static void 2598e06491aSEdward Tomasz Napierala midi_init(void *arg __unused) 2608e06491aSEdward Tomasz Napierala { 2618e06491aSEdward Tomasz Napierala struct sysctl_oid *parent; 2628e06491aSEdward Tomasz Napierala char parent_name[3]; 2638e06491aSEdward Tomasz Napierala 2648e06491aSEdward Tomasz Napierala usb_make_str_desc(&midi_interface, sizeof(midi_interface), 2658e06491aSEdward Tomasz Napierala MIDI_DEFAULT_INTERFACE); 2661ee5bed7SEdward Tomasz Napierala usb_make_str_desc(&midi_manufacturer, sizeof(midi_manufacturer), 2671ee5bed7SEdward Tomasz Napierala MIDI_DEFAULT_MANUFACTURER); 2688e06491aSEdward Tomasz Napierala usb_make_str_desc(&midi_product, sizeof(midi_product), 2698e06491aSEdward Tomasz Napierala MIDI_DEFAULT_PRODUCT); 2701ee5bed7SEdward Tomasz Napierala usb_make_str_desc(&midi_serial_number, sizeof(midi_serial_number), 2711ee5bed7SEdward Tomasz Napierala MIDI_DEFAULT_SERIAL_NUMBER); 2728e06491aSEdward Tomasz Napierala 2738e06491aSEdward Tomasz Napierala snprintf(parent_name, sizeof(parent_name), "%d", USB_TEMP_MIDI); 2748e06491aSEdward Tomasz Napierala sysctl_ctx_init(&midi_ctx_list); 2758e06491aSEdward Tomasz Napierala 2768e06491aSEdward Tomasz Napierala parent = SYSCTL_ADD_NODE(&midi_ctx_list, 2778e06491aSEdward Tomasz Napierala SYSCTL_STATIC_CHILDREN(_hw_usb_templates), OID_AUTO, 2788e06491aSEdward Tomasz Napierala parent_name, CTLFLAG_RW, 2798e06491aSEdward Tomasz Napierala 0, "USB MIDI device side template"); 2808e06491aSEdward Tomasz Napierala SYSCTL_ADD_U16(&midi_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO, 2818e06491aSEdward Tomasz Napierala "vendor_id", CTLFLAG_RWTUN, 2828e06491aSEdward Tomasz Napierala &usb_template_midi.idVendor, 1, "Vendor identifier"); 2838e06491aSEdward Tomasz Napierala SYSCTL_ADD_U16(&midi_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO, 2848e06491aSEdward Tomasz Napierala "product_id", CTLFLAG_RWTUN, 2858e06491aSEdward Tomasz Napierala &usb_template_midi.idProduct, 1, "Product identifier"); 2868e06491aSEdward Tomasz Napierala #if 0 2878e06491aSEdward Tomasz Napierala SYSCTL_ADD_PROC(&midi_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO, 2888e06491aSEdward Tomasz Napierala "interface", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 2898e06491aSEdward Tomasz Napierala &midi_interface, sizeof(midi_interface), usb_temp_sysctl, 2908e06491aSEdward Tomasz Napierala "A", "Interface string"); 2918e06491aSEdward Tomasz Napierala #endif 2928e06491aSEdward Tomasz Napierala SYSCTL_ADD_PROC(&midi_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO, 2931ee5bed7SEdward Tomasz Napierala "manufacturer", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 2941ee5bed7SEdward Tomasz Napierala &midi_manufacturer, sizeof(midi_manufacturer), usb_temp_sysctl, 2951ee5bed7SEdward Tomasz Napierala "A", "Manufacturer string"); 2961ee5bed7SEdward Tomasz Napierala SYSCTL_ADD_PROC(&midi_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO, 2978e06491aSEdward Tomasz Napierala "product", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 2988e06491aSEdward Tomasz Napierala &midi_product, sizeof(midi_product), usb_temp_sysctl, 2998e06491aSEdward Tomasz Napierala "A", "Product string"); 3001ee5bed7SEdward Tomasz Napierala SYSCTL_ADD_PROC(&midi_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO, 3011ee5bed7SEdward Tomasz Napierala "serial_number", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 3021ee5bed7SEdward Tomasz Napierala &midi_serial_number, sizeof(midi_serial_number), usb_temp_sysctl, 3031ee5bed7SEdward Tomasz Napierala "A", "Serial number string"); 3048e06491aSEdward Tomasz Napierala } 3058e06491aSEdward Tomasz Napierala 3068e06491aSEdward Tomasz Napierala static void 3078e06491aSEdward Tomasz Napierala midi_uninit(void *arg __unused) 3088e06491aSEdward Tomasz Napierala { 3098e06491aSEdward Tomasz Napierala 3108e06491aSEdward Tomasz Napierala sysctl_ctx_free(&midi_ctx_list); 3118e06491aSEdward Tomasz Napierala } 3128e06491aSEdward Tomasz Napierala 3138e06491aSEdward Tomasz Napierala SYSINIT(midi_init, SI_SUB_LOCK, SI_ORDER_FIRST, midi_init, NULL); 314c70e38e4SHans Petter Selasky SYSUNINIT(midi_uninit, SI_SUB_LOCK, SI_ORDER_FIRST, midi_uninit, NULL); 315