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_mouse.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 Mouse 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         MOUSE_LANG_INDEX,
   72         MOUSE_INTERFACE_INDEX,
   73         MOUSE_MANUFACTURER_INDEX,
   74         MOUSE_PRODUCT_INDEX,
   75         MOUSE_SERIAL_NUMBER_INDEX,
   76         MOUSE_MAX_INDEX,
   77 };
   78 
   79 #define MOUSE_DEFAULT_VENDOR_ID         USB_TEMPLATE_VENDOR
   80 #define MOUSE_DEFAULT_PRODUCT_ID        0x27da
   81 #define MOUSE_DEFAULT_INTERFACE         "Mouse interface"
   82 #define MOUSE_DEFAULT_MANUFACTURER      USB_TEMPLATE_MANUFACTURER
   83 #define MOUSE_DEFAULT_PRODUCT           "Mouse Test Interface"
   84 #define MOUSE_DEFAULT_SERIAL_NUMBER     "March 2008"
   85 
   86 static struct usb_string_descriptor     mouse_interface;
   87 static struct usb_string_descriptor     mouse_manufacturer;
   88 static struct usb_string_descriptor     mouse_product;
   89 static struct usb_string_descriptor     mouse_serial_number;
   90 
   91 static struct sysctl_ctx_list           mouse_ctx_list;
   92 
   93 /* prototypes */
   94 
   95 /* The following HID descriptor was dumped from a HP mouse. */
   96 
   97 static uint8_t mouse_hid_descriptor[] = {
   98         0x05, 0x01, 0x09, 0x02, 0xa1, 0x01, 0x09, 0x01,
   99         0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03,
  100         0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01,
  101         0x81, 0x02, 0x95, 0x05, 0x81, 0x03, 0x05, 0x01,
  102         0x09, 0x30, 0x09, 0x31, 0x09, 0x38, 0x15, 0x81,
  103         0x25, 0x7f, 0x75, 0x08, 0x95, 0x03, 0x81, 0x06,
  104         0xc0, 0xc0
  105 };
  106 
  107 static const struct usb_temp_packet_size mouse_intr_mps = {
  108         .mps[USB_SPEED_LOW] = 8,
  109         .mps[USB_SPEED_FULL] = 8,
  110         .mps[USB_SPEED_HIGH] = 8,
  111 };
  112 
  113 static const struct usb_temp_interval mouse_intr_interval = {
  114         .bInterval[USB_SPEED_LOW] = 2,          /* 2ms */
  115         .bInterval[USB_SPEED_FULL] = 2,         /* 2ms */
  116         .bInterval[USB_SPEED_HIGH] = 5,         /* 2ms */
  117 };
  118 
  119 static const struct usb_temp_endpoint_desc mouse_ep_0 = {
  120         .ppRawDesc = NULL,              /* no raw descriptors */
  121         .pPacketSize = &mouse_intr_mps,
  122         .pIntervals = &mouse_intr_interval,
  123         .bEndpointAddress = UE_DIR_IN,
  124         .bmAttributes = UE_INTERRUPT,
  125 };
  126 
  127 static const struct usb_temp_endpoint_desc *mouse_endpoints[] = {
  128         &mouse_ep_0,
  129         NULL,
  130 };
  131 
  132 static const uint8_t mouse_raw_desc[] = {
  133         0x09, 0x21, 0x10, 0x01, 0x00, 0x01, 0x22, sizeof(mouse_hid_descriptor),
  134         0x00
  135 };
  136 
  137 static const void *mouse_iface_0_desc[] = {
  138         mouse_raw_desc,
  139         NULL,
  140 };
  141 
  142 static const struct usb_temp_interface_desc mouse_iface_0 = {
  143         .ppRawDesc = mouse_iface_0_desc,
  144         .ppEndpoints = mouse_endpoints,
  145         .bInterfaceClass = UICLASS_HID,
  146         .bInterfaceSubClass = UISUBCLASS_BOOT,
  147         .bInterfaceProtocol = UIPROTO_MOUSE,
  148         .iInterface = MOUSE_INTERFACE_INDEX,
  149 };
  150 
  151 static const struct usb_temp_interface_desc *mouse_interfaces[] = {
  152         &mouse_iface_0,
  153         NULL,
  154 };
  155 
  156 static const struct usb_temp_config_desc mouse_config_desc = {
  157         .ppIfaceDesc = mouse_interfaces,
  158         .bmAttributes = 0,
  159         .bMaxPower = 0,
  160         .iConfiguration = MOUSE_INTERFACE_INDEX,
  161 };
  162 
  163 static const struct usb_temp_config_desc *mouse_configs[] = {
  164         &mouse_config_desc,
  165         NULL,
  166 };
  167 
  168 static usb_temp_get_string_desc_t mouse_get_string_desc;
  169 static usb_temp_get_vendor_desc_t mouse_get_vendor_desc;
  170 
  171 struct usb_temp_device_desc usb_template_mouse = {
  172         .getStringDesc = &mouse_get_string_desc,
  173         .getVendorDesc = &mouse_get_vendor_desc,
  174         .ppConfigDesc = mouse_configs,
  175         .idVendor = MOUSE_DEFAULT_VENDOR_ID,
  176         .idProduct = MOUSE_DEFAULT_PRODUCT_ID,
  177         .bcdDevice = 0x0100,
  178         .bDeviceClass = UDCLASS_COMM,
  179         .bDeviceSubClass = 0,
  180         .bDeviceProtocol = 0,
  181         .iManufacturer = MOUSE_MANUFACTURER_INDEX,
  182         .iProduct = MOUSE_PRODUCT_INDEX,
  183         .iSerialNumber = MOUSE_SERIAL_NUMBER_INDEX,
  184 };
  185 
  186 /*------------------------------------------------------------------------*
  187  *      mouse_get_vendor_desc
  188  *
  189  * Return values:
  190  * NULL: Failure. No such vendor descriptor.
  191  * Else: Success. Pointer to vendor descriptor is returned.
  192  *------------------------------------------------------------------------*/
  193 static const void *
  194 mouse_get_vendor_desc(const struct usb_device_request *req, uint16_t *plen)
  195 {
  196         if ((req->bmRequestType == 0x81) && (req->bRequest == 0x06) &&
  197             (req->wValue[0] == 0x00) && (req->wValue[1] == 0x22) &&
  198             (req->wIndex[1] == 0) && (req->wIndex[0] == 0)) {
  199                 *plen = sizeof(mouse_hid_descriptor);
  200                 return (mouse_hid_descriptor);
  201         }
  202         return (NULL);
  203 }
  204 
  205 /*------------------------------------------------------------------------*
  206  *      mouse_get_string_desc
  207  *
  208  * Return values:
  209  * NULL: Failure. No such string.
  210  * Else: Success. Pointer to string descriptor is returned.
  211  *------------------------------------------------------------------------*/
  212 static const void *
  213 mouse_get_string_desc(uint16_t lang_id, uint8_t string_index)
  214 {
  215         static const void *ptr[MOUSE_MAX_INDEX] = {
  216                 [MOUSE_LANG_INDEX] = &usb_string_lang_en,
  217                 [MOUSE_INTERFACE_INDEX] = &mouse_interface,
  218                 [MOUSE_MANUFACTURER_INDEX] = &mouse_manufacturer,
  219                 [MOUSE_PRODUCT_INDEX] = &mouse_product,
  220                 [MOUSE_SERIAL_NUMBER_INDEX] = &mouse_serial_number,
  221         };
  222 
  223         if (string_index == 0) {
  224                 return (&usb_string_lang_en);
  225         }
  226         if (lang_id != 0x0409) {
  227                 return (NULL);
  228         }
  229         if (string_index < MOUSE_MAX_INDEX) {
  230                 return (ptr[string_index]);
  231         }
  232         return (NULL);
  233 }
  234 
  235 static void
  236 mouse_init(void *arg __unused)
  237 {
  238         struct sysctl_oid *parent;
  239         char parent_name[3];
  240 
  241         usb_make_str_desc(&mouse_interface, sizeof(mouse_interface),
  242             MOUSE_DEFAULT_INTERFACE);
  243         usb_make_str_desc(&mouse_manufacturer, sizeof(mouse_manufacturer),
  244             MOUSE_DEFAULT_MANUFACTURER);
  245         usb_make_str_desc(&mouse_product, sizeof(mouse_product),
  246             MOUSE_DEFAULT_PRODUCT);
  247         usb_make_str_desc(&mouse_serial_number, sizeof(mouse_serial_number),
  248             MOUSE_DEFAULT_SERIAL_NUMBER);
  249 
  250         snprintf(parent_name, sizeof(parent_name), "%d", USB_TEMP_MOUSE);
  251         sysctl_ctx_init(&mouse_ctx_list);
  252 
  253         parent = SYSCTL_ADD_NODE(&mouse_ctx_list,
  254             SYSCTL_STATIC_CHILDREN(_hw_usb_templates), OID_AUTO,
  255             parent_name, CTLFLAG_RW | CTLFLAG_MPSAFE,
  256             0, "USB Mouse device side template");
  257         SYSCTL_ADD_U16(&mouse_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  258             "vendor_id", CTLFLAG_RWTUN,
  259             &usb_template_mouse.idVendor, 1, "Vendor identifier");
  260         SYSCTL_ADD_U16(&mouse_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  261             "product_id", CTLFLAG_RWTUN,
  262             &usb_template_mouse.idProduct, 1, "Product identifier");
  263 #if 0
  264         SYSCTL_ADD_PROC(&mouse_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  265             "interface", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  266             &mouse_interface, sizeof(mouse_interface), usb_temp_sysctl,
  267             "A", "Interface string");
  268 #endif
  269         SYSCTL_ADD_PROC(&mouse_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  270             "manufacturer", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  271             &mouse_manufacturer, sizeof(mouse_manufacturer), usb_temp_sysctl,
  272             "A", "Manufacturer string");
  273         SYSCTL_ADD_PROC(&mouse_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  274             "product", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  275             &mouse_product, sizeof(mouse_product), usb_temp_sysctl,
  276             "A", "Product string");
  277         SYSCTL_ADD_PROC(&mouse_ctx_list, SYSCTL_CHILDREN(parent), OID_AUTO,
  278             "serial_number", CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
  279             &mouse_serial_number, sizeof(mouse_serial_number), usb_temp_sysctl,
  280             "A", "Serial number string");
  281 }
  282 
  283 static void
  284 mouse_uninit(void *arg __unused)
  285 {
  286 
  287         sysctl_ctx_free(&mouse_ctx_list);
  288 }
  289 
  290 SYSINIT(mouse_init, SI_SUB_LOCK, SI_ORDER_FIRST, mouse_init, NULL);
  291 SYSUNINIT(mouse_uninit, SI_SUB_LOCK, SI_ORDER_FIRST, mouse_uninit, NULL);

Cache object: 0891d90fd31104512feaec92da1976fe


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