xref: /freebsd/sys/dev/usb/template/usb_template_mouse.c (revision 71625ec9ad2a9bc8c09784fbd23b759830e0ee5f)
1399e6543SHans Petter Selasky /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3718cf2ccSPedro F. Giffuni  *
48e06491aSEdward Tomasz Napierala  * Copyright (c) 2010 Hans Petter Selasky
58e06491aSEdward Tomasz Napierala  * Copyright (c) 2018 The FreeBSD Foundation
68e06491aSEdward Tomasz Napierala  * All rights reserved.
78e06491aSEdward Tomasz Napierala  *
88e06491aSEdward Tomasz Napierala  * Portions of this software were developed by Edward Tomasz Napierala
98e06491aSEdward Tomasz Napierala  * under sponsorship from the FreeBSD Foundation.
10399e6543SHans Petter Selasky  *
11399e6543SHans Petter Selasky  * Redistribution and use in source and binary forms, with or without
12399e6543SHans Petter Selasky  * modification, are permitted provided that the following conditions
13399e6543SHans Petter Selasky  * are met:
14399e6543SHans Petter Selasky  * 1. Redistributions of source code must retain the above copyright
15399e6543SHans Petter Selasky  *    notice, this list of conditions and the following disclaimer.
16399e6543SHans Petter Selasky  * 2. Redistributions in binary form must reproduce the above copyright
17399e6543SHans Petter Selasky  *    notice, this list of conditions and the following disclaimer in the
18399e6543SHans Petter Selasky  *    documentation and/or other materials provided with the distribution.
19399e6543SHans Petter Selasky  *
20399e6543SHans Petter Selasky  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21399e6543SHans Petter Selasky  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22399e6543SHans Petter Selasky  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23399e6543SHans Petter Selasky  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24399e6543SHans Petter Selasky  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25399e6543SHans Petter Selasky  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26399e6543SHans Petter Selasky  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27399e6543SHans Petter Selasky  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28399e6543SHans Petter Selasky  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29399e6543SHans Petter Selasky  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30399e6543SHans Petter Selasky  * SUCH DAMAGE.
31399e6543SHans Petter Selasky  */
32399e6543SHans Petter Selasky 
33399e6543SHans Petter Selasky /*
34399e6543SHans Petter Selasky  * This file contains the USB template for an USB Mouse Device.
35399e6543SHans Petter Selasky  */
36399e6543SHans Petter Selasky 
37d2b99310SHans Petter Selasky #ifdef USB_GLOBAL_INCLUDE_FILE
38d2b99310SHans Petter Selasky #include USB_GLOBAL_INCLUDE_FILE
39d2b99310SHans Petter Selasky #else
40399e6543SHans Petter Selasky #include <sys/stdint.h>
41399e6543SHans Petter Selasky #include <sys/stddef.h>
42399e6543SHans Petter Selasky #include <sys/param.h>
43399e6543SHans Petter Selasky #include <sys/queue.h>
44399e6543SHans Petter Selasky #include <sys/types.h>
45399e6543SHans Petter Selasky #include <sys/systm.h>
46399e6543SHans Petter Selasky #include <sys/kernel.h>
47399e6543SHans Petter Selasky #include <sys/bus.h>
48399e6543SHans Petter Selasky #include <sys/module.h>
49399e6543SHans Petter Selasky #include <sys/lock.h>
50399e6543SHans Petter Selasky #include <sys/mutex.h>
51399e6543SHans Petter Selasky #include <sys/condvar.h>
52399e6543SHans Petter Selasky #include <sys/sysctl.h>
53399e6543SHans Petter Selasky #include <sys/sx.h>
54399e6543SHans Petter Selasky #include <sys/unistd.h>
55399e6543SHans Petter Selasky #include <sys/callout.h>
56399e6543SHans Petter Selasky #include <sys/malloc.h>
57399e6543SHans Petter Selasky #include <sys/priv.h>
58399e6543SHans Petter Selasky 
59399e6543SHans Petter Selasky #include <dev/usb/usb.h>
60399e6543SHans Petter Selasky #include <dev/usb/usbdi.h>
6123ab0871SHans Petter Selasky #include <dev/usb/usb_core.h>
62399e6543SHans Petter Selasky #include <dev/usb/usb_cdc.h>
638e06491aSEdward Tomasz Napierala #include <dev/usb/usb_ioctl.h>
648e06491aSEdward Tomasz Napierala #include <dev/usb/usb_util.h>
65399e6543SHans Petter Selasky 
66399e6543SHans Petter Selasky #include <dev/usb/template/usb_template.h>
67d2b99310SHans Petter Selasky #endif			/* USB_GLOBAL_INCLUDE_FILE */
68399e6543SHans Petter Selasky 
69399e6543SHans Petter Selasky enum {
708e06491aSEdward Tomasz Napierala 	MOUSE_LANG_INDEX,
718e06491aSEdward Tomasz Napierala 	MOUSE_INTERFACE_INDEX,
721ee5bed7SEdward Tomasz Napierala 	MOUSE_MANUFACTURER_INDEX,
738e06491aSEdward Tomasz Napierala 	MOUSE_PRODUCT_INDEX,
741ee5bed7SEdward Tomasz Napierala 	MOUSE_SERIAL_NUMBER_INDEX,
758e06491aSEdward Tomasz Napierala 	MOUSE_MAX_INDEX,
76399e6543SHans Petter Selasky };
77399e6543SHans Petter Selasky 
781558eec6SEdward Tomasz Napierala #define	MOUSE_DEFAULT_VENDOR_ID		USB_TEMPLATE_VENDOR
79d01c1c8bSEdward Tomasz Napierala #define	MOUSE_DEFAULT_PRODUCT_ID	0x27da
808e06491aSEdward Tomasz Napierala #define	MOUSE_DEFAULT_INTERFACE		"Mouse interface"
81d01c1c8bSEdward Tomasz Napierala #define	MOUSE_DEFAULT_MANUFACTURER	USB_TEMPLATE_MANUFACTURER
828e06491aSEdward Tomasz Napierala #define	MOUSE_DEFAULT_PRODUCT		"Mouse Test Interface"
831ee5bed7SEdward Tomasz Napierala #define	MOUSE_DEFAULT_SERIAL_NUMBER	"March 2008"
84399e6543SHans Petter Selasky 
858e06491aSEdward Tomasz Napierala static struct usb_string_descriptor	mouse_interface;
861ee5bed7SEdward Tomasz Napierala static struct usb_string_descriptor	mouse_manufacturer;
878e06491aSEdward Tomasz Napierala static struct usb_string_descriptor	mouse_product;
881ee5bed7SEdward Tomasz Napierala static struct usb_string_descriptor	mouse_serial_number;
89399e6543SHans Petter Selasky 
908e06491aSEdward Tomasz Napierala static struct sysctl_ctx_list		mouse_ctx_list;
91399e6543SHans Petter Selasky 
92399e6543SHans Petter Selasky /* prototypes */
93399e6543SHans Petter Selasky 
94df142785SHans Petter Selasky /* The following HID descriptor was dumped from a HP mouse. */
95df142785SHans Petter Selasky 
96399e6543SHans Petter Selasky static uint8_t mouse_hid_descriptor[] = {
97399e6543SHans Petter Selasky 	0x05, 0x01, 0x09, 0x02, 0xa1, 0x01, 0x09, 0x01,
98399e6543SHans Petter Selasky 	0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03,
99399e6543SHans Petter Selasky 	0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01,
100399e6543SHans Petter Selasky 	0x81, 0x02, 0x95, 0x05, 0x81, 0x03, 0x05, 0x01,
101399e6543SHans Petter Selasky 	0x09, 0x30, 0x09, 0x31, 0x09, 0x38, 0x15, 0x81,
102399e6543SHans Petter Selasky 	0x25, 0x7f, 0x75, 0x08, 0x95, 0x03, 0x81, 0x06,
103399e6543SHans Petter Selasky 	0xc0, 0xc0
104399e6543SHans Petter Selasky };
105399e6543SHans Petter Selasky 
106399e6543SHans Petter Selasky static const struct usb_temp_packet_size mouse_intr_mps = {
107399e6543SHans Petter Selasky 	.mps[USB_SPEED_LOW] = 8,
108399e6543SHans Petter Selasky 	.mps[USB_SPEED_FULL] = 8,
109399e6543SHans Petter Selasky 	.mps[USB_SPEED_HIGH] = 8,
110399e6543SHans Petter Selasky };
111399e6543SHans Petter Selasky 
112399e6543SHans Petter Selasky static const struct usb_temp_interval mouse_intr_interval = {
113e6ee4f7dSHans Petter Selasky 	.bInterval[USB_SPEED_LOW] = 2,		/* 2ms */
114e6ee4f7dSHans Petter Selasky 	.bInterval[USB_SPEED_FULL] = 2,		/* 2ms */
115e6ee4f7dSHans Petter Selasky 	.bInterval[USB_SPEED_HIGH] = 5,		/* 2ms */
116399e6543SHans Petter Selasky };
117399e6543SHans Petter Selasky 
118399e6543SHans Petter Selasky static const struct usb_temp_endpoint_desc mouse_ep_0 = {
119399e6543SHans Petter Selasky 	.ppRawDesc = NULL,		/* no raw descriptors */
120399e6543SHans Petter Selasky 	.pPacketSize = &mouse_intr_mps,
121399e6543SHans Petter Selasky 	.pIntervals = &mouse_intr_interval,
122399e6543SHans Petter Selasky 	.bEndpointAddress = UE_DIR_IN,
123399e6543SHans Petter Selasky 	.bmAttributes = UE_INTERRUPT,
124399e6543SHans Petter Selasky };
125399e6543SHans Petter Selasky 
126399e6543SHans Petter Selasky static const struct usb_temp_endpoint_desc *mouse_endpoints[] = {
127399e6543SHans Petter Selasky 	&mouse_ep_0,
128399e6543SHans Petter Selasky 	NULL,
129399e6543SHans Petter Selasky };
130399e6543SHans Petter Selasky 
131399e6543SHans Petter Selasky static const uint8_t mouse_raw_desc[] = {
132399e6543SHans Petter Selasky 	0x09, 0x21, 0x10, 0x01, 0x00, 0x01, 0x22, sizeof(mouse_hid_descriptor),
133399e6543SHans Petter Selasky 	0x00
134399e6543SHans Petter Selasky };
135399e6543SHans Petter Selasky 
136399e6543SHans Petter Selasky static const void *mouse_iface_0_desc[] = {
137399e6543SHans Petter Selasky 	mouse_raw_desc,
138399e6543SHans Petter Selasky 	NULL,
139399e6543SHans Petter Selasky };
140399e6543SHans Petter Selasky 
141399e6543SHans Petter Selasky static const struct usb_temp_interface_desc mouse_iface_0 = {
142399e6543SHans Petter Selasky 	.ppRawDesc = mouse_iface_0_desc,
143399e6543SHans Petter Selasky 	.ppEndpoints = mouse_endpoints,
1444ffeccf1SEdward Tomasz Napierala 	.bInterfaceClass = UICLASS_HID,
1454ffeccf1SEdward Tomasz Napierala 	.bInterfaceSubClass = UISUBCLASS_BOOT,
1464ffeccf1SEdward Tomasz Napierala 	.bInterfaceProtocol = UIPROTO_MOUSE,
1478e06491aSEdward Tomasz Napierala 	.iInterface = MOUSE_INTERFACE_INDEX,
148399e6543SHans Petter Selasky };
149399e6543SHans Petter Selasky 
150399e6543SHans Petter Selasky static const struct usb_temp_interface_desc *mouse_interfaces[] = {
151399e6543SHans Petter Selasky 	&mouse_iface_0,
152399e6543SHans Petter Selasky 	NULL,
153399e6543SHans Petter Selasky };
154399e6543SHans Petter Selasky 
155399e6543SHans Petter Selasky static const struct usb_temp_config_desc mouse_config_desc = {
156399e6543SHans Petter Selasky 	.ppIfaceDesc = mouse_interfaces,
157d008c0d7SEdward Tomasz Napierala 	.bmAttributes = 0,
158d008c0d7SEdward Tomasz Napierala 	.bMaxPower = 0,
1598e06491aSEdward Tomasz Napierala 	.iConfiguration = MOUSE_INTERFACE_INDEX,
160399e6543SHans Petter Selasky };
161399e6543SHans Petter Selasky 
162399e6543SHans Petter Selasky static const struct usb_temp_config_desc *mouse_configs[] = {
163399e6543SHans Petter Selasky 	&mouse_config_desc,
164399e6543SHans Petter Selasky 	NULL,
165399e6543SHans Petter Selasky };
166399e6543SHans Petter Selasky 
167399e6543SHans Petter Selasky static usb_temp_get_string_desc_t mouse_get_string_desc;
168399e6543SHans Petter Selasky static usb_temp_get_vendor_desc_t mouse_get_vendor_desc;
169399e6543SHans Petter Selasky 
1708e06491aSEdward Tomasz Napierala struct usb_temp_device_desc usb_template_mouse = {
171399e6543SHans Petter Selasky 	.getStringDesc = &mouse_get_string_desc,
172399e6543SHans Petter Selasky 	.getVendorDesc = &mouse_get_vendor_desc,
173399e6543SHans Petter Selasky 	.ppConfigDesc = mouse_configs,
1741558eec6SEdward Tomasz Napierala 	.idVendor = MOUSE_DEFAULT_VENDOR_ID,
1751558eec6SEdward Tomasz Napierala 	.idProduct = MOUSE_DEFAULT_PRODUCT_ID,
176399e6543SHans Petter Selasky 	.bcdDevice = 0x0100,
177399e6543SHans Petter Selasky 	.bDeviceClass = UDCLASS_COMM,
178399e6543SHans Petter Selasky 	.bDeviceSubClass = 0,
179399e6543SHans Petter Selasky 	.bDeviceProtocol = 0,
1801ee5bed7SEdward Tomasz Napierala 	.iManufacturer = MOUSE_MANUFACTURER_INDEX,
1818e06491aSEdward Tomasz Napierala 	.iProduct = MOUSE_PRODUCT_INDEX,
1821ee5bed7SEdward Tomasz Napierala 	.iSerialNumber = MOUSE_SERIAL_NUMBER_INDEX,
183399e6543SHans Petter Selasky };
184399e6543SHans Petter Selasky 
185399e6543SHans Petter Selasky /*------------------------------------------------------------------------*
186399e6543SHans Petter Selasky  *      mouse_get_vendor_desc
187399e6543SHans Petter Selasky  *
188399e6543SHans Petter Selasky  * Return values:
189399e6543SHans Petter Selasky  * NULL: Failure. No such vendor descriptor.
190399e6543SHans Petter Selasky  * Else: Success. Pointer to vendor descriptor is returned.
191399e6543SHans Petter Selasky  *------------------------------------------------------------------------*/
192399e6543SHans Petter Selasky static const void *
mouse_get_vendor_desc(const struct usb_device_request * req,uint16_t * plen)193399e6543SHans Petter Selasky mouse_get_vendor_desc(const struct usb_device_request *req, uint16_t *plen)
194399e6543SHans Petter Selasky {
195399e6543SHans Petter Selasky 	if ((req->bmRequestType == 0x81) && (req->bRequest == 0x06) &&
196399e6543SHans Petter Selasky 	    (req->wValue[0] == 0x00) && (req->wValue[1] == 0x22) &&
197399e6543SHans Petter Selasky 	    (req->wIndex[1] == 0) && (req->wIndex[0] == 0)) {
198399e6543SHans Petter Selasky 		*plen = sizeof(mouse_hid_descriptor);
199399e6543SHans Petter Selasky 		return (mouse_hid_descriptor);
200399e6543SHans Petter Selasky 	}
201399e6543SHans Petter Selasky 	return (NULL);
202399e6543SHans Petter Selasky }
203399e6543SHans Petter Selasky 
204399e6543SHans Petter Selasky /*------------------------------------------------------------------------*
205399e6543SHans Petter Selasky  *	mouse_get_string_desc
206399e6543SHans Petter Selasky  *
207399e6543SHans Petter Selasky  * Return values:
208399e6543SHans Petter Selasky  * NULL: Failure. No such string.
209399e6543SHans Petter Selasky  * Else: Success. Pointer to string descriptor is returned.
210399e6543SHans Petter Selasky  *------------------------------------------------------------------------*/
211399e6543SHans Petter Selasky static const void *
mouse_get_string_desc(uint16_t lang_id,uint8_t string_index)212399e6543SHans Petter Selasky mouse_get_string_desc(uint16_t lang_id, uint8_t string_index)
213399e6543SHans Petter Selasky {
2148e06491aSEdward Tomasz Napierala 	static const void *ptr[MOUSE_MAX_INDEX] = {
2158e06491aSEdward Tomasz Napierala 		[MOUSE_LANG_INDEX] = &usb_string_lang_en,
2168e06491aSEdward Tomasz Napierala 		[MOUSE_INTERFACE_INDEX] = &mouse_interface,
2171ee5bed7SEdward Tomasz Napierala 		[MOUSE_MANUFACTURER_INDEX] = &mouse_manufacturer,
2188e06491aSEdward Tomasz Napierala 		[MOUSE_PRODUCT_INDEX] = &mouse_product,
2191ee5bed7SEdward Tomasz Napierala 		[MOUSE_SERIAL_NUMBER_INDEX] = &mouse_serial_number,
220399e6543SHans Petter Selasky 	};
221399e6543SHans Petter Selasky 
222399e6543SHans Petter Selasky 	if (string_index == 0) {
22323ab0871SHans Petter Selasky 		return (&usb_string_lang_en);
224399e6543SHans Petter Selasky 	}
225399e6543SHans Petter Selasky 	if (lang_id != 0x0409) {
226399e6543SHans Petter Selasky 		return (NULL);
227399e6543SHans Petter Selasky 	}
2288e06491aSEdward Tomasz Napierala 	if (string_index < MOUSE_MAX_INDEX) {
229399e6543SHans Petter Selasky 		return (ptr[string_index]);
230399e6543SHans Petter Selasky 	}
231399e6543SHans Petter Selasky 	return (NULL);
232399e6543SHans Petter Selasky }
2338e06491aSEdward Tomasz Napierala 
2348e06491aSEdward Tomasz Napierala static void
mouse_init(void * arg __unused)2358e06491aSEdward Tomasz Napierala mouse_init(void *arg __unused)
2368e06491aSEdward Tomasz Napierala {
2378e06491aSEdward Tomasz Napierala 	struct sysctl_oid *parent;
2388e06491aSEdward Tomasz Napierala 	char parent_name[3];
2398e06491aSEdward Tomasz Napierala 
2408e06491aSEdward Tomasz Napierala 	usb_make_str_desc(&mouse_interface, sizeof(mouse_interface),
2418e06491aSEdward Tomasz Napierala 	    MOUSE_DEFAULT_INTERFACE);
2421ee5bed7SEdward Tomasz Napierala 	usb_make_str_desc(&mouse_manufacturer, sizeof(mouse_manufacturer),
2431ee5bed7SEdward Tomasz Napierala 	    MOUSE_DEFAULT_MANUFACTURER);
2448e06491aSEdward Tomasz Napierala 	usb_make_str_desc(&mouse_product, sizeof(mouse_product),
2458e06491aSEdward Tomasz Napierala 	    MOUSE_DEFAULT_PRODUCT);
2461ee5bed7SEdward Tomasz Napierala 	usb_make_str_desc(&mouse_serial_number, sizeof(mouse_serial_number),
2471ee5bed7SEdward Tomasz Napierala 	    MOUSE_DEFAULT_SERIAL_NUMBER);
2488e06491aSEdward Tomasz Napierala 
2498e06491aSEdward Tomasz Napierala 	snprintf(parent_name, sizeof(parent_name), "%d", USB_TEMP_MOUSE);
2508e06491aSEdward Tomasz Napierala 	sysctl_ctx_init(&mouse_ctx_list);
2518e06491aSEdward Tomasz Napierala 
2528e06491aSEdward Tomasz Napierala 	parent = SYSCTL_ADD_NODE(&mouse_ctx_list,
2538e06491aSEdward Tomasz Napierala 	    SYSCTL_STATIC_CHILDREN(_hw_usb_templates), OID_AUTO,
254f8d2b1f3SPawel Biernacki 	    parent_name, CTLFLAG_RW | CTLFLAG_MPSAFE,
2558e06491aSEdward Tomasz Napierala 	    0, "USB Mouse device side template");
2568e06491aSEdward Tomasz Napierala 	SYSCTL_ADD_U16(&mouse_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
2578e06491aSEdward Tomasz Napierala 	    "vendor_id", CTLFLAG_RWTUN,
2588e06491aSEdward Tomasz Napierala 	    &usb_template_mouse.idVendor, 1, "Vendor identifier");
2598e06491aSEdward Tomasz Napierala 	SYSCTL_ADD_U16(&mouse_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
2608e06491aSEdward Tomasz Napierala 	    "product_id", CTLFLAG_RWTUN,
2618e06491aSEdward Tomasz Napierala 	    &usb_template_mouse.idProduct, 1, "Product identifier");
2628e06491aSEdward Tomasz Napierala #if 0
2638e06491aSEdward Tomasz Napierala 	SYSCTL_ADD_PROC(&mouse_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
2648e06491aSEdward Tomasz Napierala 	    "interface", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
2658e06491aSEdward Tomasz Napierala 	    &mouse_interface, sizeof(mouse_interface), usb_temp_sysctl,
2668e06491aSEdward Tomasz Napierala 	    "A", "Interface string");
2678e06491aSEdward Tomasz Napierala #endif
2688e06491aSEdward Tomasz Napierala 	SYSCTL_ADD_PROC(&mouse_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
2691ee5bed7SEdward Tomasz Napierala 	    "manufacturer", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
2701ee5bed7SEdward Tomasz Napierala 	    &mouse_manufacturer, sizeof(mouse_manufacturer), usb_temp_sysctl,
2711ee5bed7SEdward Tomasz Napierala 	    "A", "Manufacturer string");
2721ee5bed7SEdward Tomasz Napierala 	SYSCTL_ADD_PROC(&mouse_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
2738e06491aSEdward Tomasz Napierala 	    "product", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
2748e06491aSEdward Tomasz Napierala 	    &mouse_product, sizeof(mouse_product), usb_temp_sysctl,
2758e06491aSEdward Tomasz Napierala 	    "A", "Product string");
2761ee5bed7SEdward Tomasz Napierala 	SYSCTL_ADD_PROC(&mouse_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
2771ee5bed7SEdward Tomasz Napierala 	    "serial_number", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
2781ee5bed7SEdward Tomasz Napierala 	    &mouse_serial_number, sizeof(mouse_serial_number), usb_temp_sysctl,
2791ee5bed7SEdward Tomasz Napierala 	    "A", "Serial number string");
2808e06491aSEdward Tomasz Napierala }
2818e06491aSEdward Tomasz Napierala 
2828e06491aSEdward Tomasz Napierala static void
mouse_uninit(void * arg __unused)2838e06491aSEdward Tomasz Napierala mouse_uninit(void *arg __unused)
2848e06491aSEdward Tomasz Napierala {
2858e06491aSEdward Tomasz Napierala 
2868e06491aSEdward Tomasz Napierala 	sysctl_ctx_free(&mouse_ctx_list);
2878e06491aSEdward Tomasz Napierala }
2888e06491aSEdward Tomasz Napierala 
2898e06491aSEdward Tomasz Napierala SYSINIT(mouse_init, SI_SUB_LOCK, SI_ORDER_FIRST, mouse_init, NULL);
290c70e38e4SHans Petter Selasky SYSUNINIT(mouse_uninit, SI_SUB_LOCK, SI_ORDER_FIRST, mouse_uninit, NULL);
291