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/usb_lookup.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: releng/8.3/sys/dev/usb/usb_lookup.c 223605 2011-06-27 20:59:43Z hselasky $ */
    2 /*-
    3  * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/stdint.h>
   28 #include <sys/stddef.h>
   29 #include <sys/param.h>
   30 #include <sys/queue.h>
   31 #include <sys/types.h>
   32 #include <sys/systm.h>
   33 #include <sys/kernel.h>
   34 #include <sys/bus.h>
   35 #include <sys/module.h>
   36 #include <sys/lock.h>
   37 #include <sys/mutex.h>
   38 #include <sys/condvar.h>
   39 #include <sys/sysctl.h>
   40 #include <sys/sx.h>
   41 #include <sys/unistd.h>
   42 #include <sys/callout.h>
   43 #include <sys/malloc.h>
   44 #include <sys/priv.h>
   45 #include <sys/limits.h>
   46 #include <sys/endian.h>
   47 
   48 #include <dev/usb/usb.h>
   49 #include <dev/usb/usbdi.h>
   50 
   51 /*------------------------------------------------------------------------*
   52  *      usbd_lookup_id_by_info
   53  *
   54  * This functions takes an array of "struct usb_device_id" and tries
   55  * to match the entries with the information in "struct usbd_lookup_info".
   56  *
   57  * NOTE: The "sizeof_id" parameter must be a multiple of the
   58  * usb_device_id structure size. Else the behaviour of this function
   59  * is undefined.
   60  *
   61  * Return values:
   62  * NULL: No match found.
   63  * Else: Pointer to matching entry.
   64  *------------------------------------------------------------------------*/
   65 const struct usb_device_id *
   66 usbd_lookup_id_by_info(const struct usb_device_id *id, usb_size_t sizeof_id,
   67     const struct usbd_lookup_info *info)
   68 {
   69         const struct usb_device_id *id_end;
   70 
   71         if (id == NULL) {
   72                 goto done;
   73         }
   74         id_end = (const void *)(((const uint8_t *)id) + sizeof_id);
   75 
   76         /*
   77          * Keep on matching array entries until we find a match or
   78          * until we reach the end of the matching array:
   79          */
   80         for (; id != id_end; id++) {
   81 
   82                 if ((id->match_flag_vendor) &&
   83                     (id->idVendor != info->idVendor)) {
   84                         continue;
   85                 }
   86                 if ((id->match_flag_product) &&
   87                     (id->idProduct != info->idProduct)) {
   88                         continue;
   89                 }
   90                 if ((id->match_flag_dev_lo) &&
   91                     (id->bcdDevice_lo > info->bcdDevice)) {
   92                         continue;
   93                 }
   94                 if ((id->match_flag_dev_hi) &&
   95                     (id->bcdDevice_hi < info->bcdDevice)) {
   96                         continue;
   97                 }
   98                 if ((id->match_flag_dev_class) &&
   99                     (id->bDeviceClass != info->bDeviceClass)) {
  100                         continue;
  101                 }
  102                 if ((id->match_flag_dev_subclass) &&
  103                     (id->bDeviceSubClass != info->bDeviceSubClass)) {
  104                         continue;
  105                 }
  106                 if ((id->match_flag_dev_protocol) &&
  107                     (id->bDeviceProtocol != info->bDeviceProtocol)) {
  108                         continue;
  109                 }
  110                 if ((id->match_flag_int_class) &&
  111                     (id->bInterfaceClass != info->bInterfaceClass)) {
  112                         continue;
  113                 }
  114                 if ((id->match_flag_int_subclass) &&
  115                     (id->bInterfaceSubClass != info->bInterfaceSubClass)) {
  116                         continue;
  117                 }
  118                 if ((id->match_flag_int_protocol) &&
  119                     (id->bInterfaceProtocol != info->bInterfaceProtocol)) {
  120                         continue;
  121                 }
  122                 /* We found a match! */
  123                 return (id);
  124         }
  125 
  126 done:
  127         return (NULL);
  128 }
  129 
  130 /*------------------------------------------------------------------------*
  131  *      usbd_lookup_id_by_uaa - factored out code
  132  *
  133  * Return values:
  134  *    0: Success
  135  * Else: Failure
  136  *------------------------------------------------------------------------*/
  137 int
  138 usbd_lookup_id_by_uaa(const struct usb_device_id *id, usb_size_t sizeof_id,
  139     struct usb_attach_arg *uaa)
  140 {
  141         id = usbd_lookup_id_by_info(id, sizeof_id, &uaa->info);
  142         if (id) {
  143                 /* copy driver info */
  144                 uaa->driver_info = id->driver_info;
  145                 return (0);
  146         }
  147         return (ENXIO);
  148 }
  149 
  150 /*------------------------------------------------------------------------*
  151  *      Export the USB device ID format we use to userspace tools.
  152  *------------------------------------------------------------------------*/
  153 #if BYTE_ORDER == BIG_ENDIAN
  154 #define U16_XOR "8"
  155 #define U32_XOR "12"
  156 #define U64_XOR "56"
  157 #define U8_BITFIELD_XOR "7"
  158 #define U16_BITFIELD_XOR "15"
  159 #define U32_BITFIELD_XOR "31"
  160 #define U64_BITFIELD_XOR "63"
  161 #else
  162 #define U16_XOR ""
  163 #define U32_XOR ""
  164 #define U64_XOR ""
  165 #define U8_BITFIELD_XOR ""
  166 #define U16_BITFIELD_XOR ""
  167 #define U32_BITFIELD_XOR ""
  168 #define U64_BITFIELD_XOR ""
  169 #endif
  170 
  171 #if USB_HAVE_COMPAT_LINUX
  172 #define MFL_SIZE "1"
  173 #else
  174 #define MFL_SIZE ""
  175 #endif
  176 
  177 #ifdef KLD_MODULE
  178 static const char __section("bus_autoconf_format") __used usb_id_format[] = {
  179 
  180         /* Declare that three different sections use the same format */
  181 
  182         "usb_host_id{256,:}"
  183         "usb_device_id{256,:}"
  184         "usb_dual_id{256,:}"
  185 
  186         /* List size of fields in the usb_device_id structure */
  187 
  188 #if ULONG_MAX >= 0xFFFFFFFFUL
  189         "unused{0,8}"
  190         "unused{0,8}"
  191         "unused{0,8}"
  192         "unused{0,8}"
  193 #if ULONG_MAX >= 0xFFFFFFFFFFFFFFFFULL
  194         "unused{0,8}"
  195         "unused{0,8}"
  196         "unused{0,8}"
  197         "unused{0,8}"
  198 #endif
  199 #else
  200 #error "Please update code."
  201 #endif
  202 
  203         "idVendor[0]{" U16_XOR ",8}"
  204         "idVendor[1]{" U16_XOR ",8}"
  205         "idProduct[0]{" U16_XOR ",8}"
  206         "idProduct[1]{" U16_XOR ",8}"
  207         "bcdDevice_lo[0]{" U16_XOR ",8}"
  208         "bcdDevice_lo[1]{" U16_XOR ",8}"
  209         "bcdDevice_hi[0]{" U16_XOR ",8}"
  210         "bcdDevice_hi[1]{" U16_XOR ",8}"
  211 
  212         "bDeviceClass{0,8}"
  213         "bDeviceSubClass{0,8}"
  214         "bDeviceProtocol{0,8}"
  215         "bInterfaceClass{0,8}"
  216         "bInterfaceSubClass{0,8}"
  217         "bInterfaceProtocol{0,8}"
  218 
  219         "mf_vendor{" U8_BITFIELD_XOR ",1}"
  220         "mf_product{" U8_BITFIELD_XOR ",1}"
  221         "mf_dev_lo{" U8_BITFIELD_XOR ",1}"
  222         "mf_dev_hi{" U8_BITFIELD_XOR ",1}"
  223 
  224         "mf_dev_class{" U8_BITFIELD_XOR ",1}"
  225         "mf_dev_subclass{" U8_BITFIELD_XOR ",1}"
  226         "mf_dev_protocol{" U8_BITFIELD_XOR ",1}"
  227         "mf_int_class{" U8_BITFIELD_XOR ",1}"
  228 
  229         "mf_int_subclass{" U8_BITFIELD_XOR ",1}"
  230         "mf_int_protocol{" U8_BITFIELD_XOR ",1}"
  231         "unused{" U8_BITFIELD_XOR ",6}"
  232 
  233         "mfl_vendor{" U16_XOR "," MFL_SIZE "}"
  234         "mfl_product{" U16_XOR "," MFL_SIZE "}"
  235         "mfl_dev_lo{" U16_XOR "," MFL_SIZE "}"
  236         "mfl_dev_hi{" U16_XOR "," MFL_SIZE "}"
  237 
  238         "mfl_dev_class{" U16_XOR "," MFL_SIZE "}"
  239         "mfl_dev_subclass{" U16_XOR "," MFL_SIZE "}"
  240         "mfl_dev_protocol{" U16_XOR "," MFL_SIZE "}"
  241         "mfl_int_class{" U16_XOR "," MFL_SIZE "}"
  242 
  243         "mfl_int_subclass{" U16_XOR "," MFL_SIZE "}"
  244         "mfl_int_protocol{" U16_XOR "," MFL_SIZE "}"
  245         "unused{" U16_XOR "," MFL_SIZE "}"
  246         "unused{" U16_XOR "," MFL_SIZE "}"
  247 
  248         "unused{" U16_XOR "," MFL_SIZE "}"
  249         "unused{" U16_XOR "," MFL_SIZE "}"
  250         "unused{" U16_XOR "," MFL_SIZE "}"
  251         "unused{" U16_XOR "," MFL_SIZE "}"
  252 };
  253 #endif

Cache object: 314d790103a2086729b902cb0e868438


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