usb_lookup.c revision 192984
1184610Salfred/* $FreeBSD: head/sys/dev/usb/usb_lookup.c 192984 2009-05-28 17:36:36Z thompsa $ */ 2184610Salfred/*- 3184610Salfred * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. 4184610Salfred * 5184610Salfred * Redistribution and use in source and binary forms, with or without 6184610Salfred * modification, are permitted provided that the following conditions 7184610Salfred * are met: 8184610Salfred * 1. Redistributions of source code must retain the above copyright 9184610Salfred * notice, this list of conditions and the following disclaimer. 10184610Salfred * 2. Redistributions in binary form must reproduce the above copyright 11184610Salfred * notice, this list of conditions and the following disclaimer in the 12184610Salfred * documentation and/or other materials provided with the distribution. 13184610Salfred * 14184610Salfred * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15184610Salfred * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16184610Salfred * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17184610Salfred * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18184610Salfred * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19184610Salfred * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20184610Salfred * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21184610Salfred * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22184610Salfred * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23184610Salfred * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24184610Salfred * SUCH DAMAGE. 25184610Salfred */ 26184610Salfred 27188942Sthompsa#include <dev/usb/usb_core.h> 28188942Sthompsa#include <dev/usb/usb_lookup.h> 29184610Salfred 30184610Salfred/*------------------------------------------------------------------------* 31184610Salfred * usb2_lookup_id_by_info 32184610Salfred * 33192984Sthompsa * This functions takes an array of "struct usb_device_id" and tries 34192984Sthompsa * to match the entries with the information in "struct usb_lookup_info". 35184610Salfred * 36184610Salfred * NOTE: The "sizeof_id" parameter must be a multiple of the 37192984Sthompsa * usb_device_id structure size. Else the behaviour of this function 38184610Salfred * is undefined. 39184610Salfred * 40184610Salfred * Return values: 41184610Salfred * NULL: No match found. 42184610Salfred * Else: Pointer to matching entry. 43184610Salfred *------------------------------------------------------------------------*/ 44192984Sthompsaconst struct usb_device_id * 45192984Sthompsausb2_lookup_id_by_info(const struct usb_device_id *id, usb2_size_t sizeof_id, 46192984Sthompsa const struct usb_lookup_info *info) 47184610Salfred{ 48192984Sthompsa const struct usb_device_id *id_end; 49184610Salfred 50184610Salfred if (id == NULL) { 51184610Salfred goto done; 52184610Salfred } 53184610Salfred id_end = (const void *)(((const uint8_t *)id) + sizeof_id); 54184610Salfred 55184610Salfred /* 56184610Salfred * Keep on matching array entries until we find a match or 57184610Salfred * until we reach the end of the matching array: 58184610Salfred */ 59184610Salfred for (; id != id_end; id++) { 60184610Salfred 61184610Salfred if ((id->match_flag_vendor) && 62184610Salfred (id->idVendor != info->idVendor)) { 63184610Salfred continue; 64184610Salfred } 65184610Salfred if ((id->match_flag_product) && 66184610Salfred (id->idProduct != info->idProduct)) { 67184610Salfred continue; 68184610Salfred } 69184610Salfred if ((id->match_flag_dev_lo) && 70184610Salfred (id->bcdDevice_lo > info->bcdDevice)) { 71184610Salfred continue; 72184610Salfred } 73184610Salfred if ((id->match_flag_dev_hi) && 74184610Salfred (id->bcdDevice_hi < info->bcdDevice)) { 75184610Salfred continue; 76184610Salfred } 77184610Salfred if ((id->match_flag_dev_class) && 78184610Salfred (id->bDeviceClass != info->bDeviceClass)) { 79184610Salfred continue; 80184610Salfred } 81184610Salfred if ((id->match_flag_dev_subclass) && 82184610Salfred (id->bDeviceSubClass != info->bDeviceSubClass)) { 83184610Salfred continue; 84184610Salfred } 85184610Salfred if ((id->match_flag_dev_protocol) && 86184610Salfred (id->bDeviceProtocol != info->bDeviceProtocol)) { 87184610Salfred continue; 88184610Salfred } 89184610Salfred if ((info->bDeviceClass == 0xFF) && 90184610Salfred (!(id->match_flag_vendor)) && 91184610Salfred ((id->match_flag_int_class) || 92184610Salfred (id->match_flag_int_subclass) || 93184610Salfred (id->match_flag_int_protocol))) { 94184610Salfred continue; 95184610Salfred } 96184610Salfred if ((id->match_flag_int_class) && 97184610Salfred (id->bInterfaceClass != info->bInterfaceClass)) { 98184610Salfred continue; 99184610Salfred } 100184610Salfred if ((id->match_flag_int_subclass) && 101184610Salfred (id->bInterfaceSubClass != info->bInterfaceSubClass)) { 102184610Salfred continue; 103184610Salfred } 104184610Salfred if ((id->match_flag_int_protocol) && 105184610Salfred (id->bInterfaceProtocol != info->bInterfaceProtocol)) { 106184610Salfred continue; 107184610Salfred } 108184610Salfred /* We found a match! */ 109184610Salfred return (id); 110184610Salfred } 111184610Salfred 112184610Salfreddone: 113184610Salfred return (NULL); 114184610Salfred} 115184610Salfred 116184610Salfred/*------------------------------------------------------------------------* 117184610Salfred * usb2_lookup_id_by_uaa - factored out code 118184610Salfred * 119184610Salfred * Return values: 120184610Salfred * 0: Success 121184610Salfred * Else: Failure 122184610Salfred *------------------------------------------------------------------------*/ 123184610Salfredint 124192984Sthompsausb2_lookup_id_by_uaa(const struct usb_device_id *id, usb2_size_t sizeof_id, 125192984Sthompsa struct usb_attach_arg *uaa) 126184610Salfred{ 127184610Salfred id = usb2_lookup_id_by_info(id, sizeof_id, &uaa->info); 128184610Salfred if (id) { 129184610Salfred /* copy driver info */ 130184610Salfred uaa->driver_info = id->driver_info; 131184610Salfred return (0); 132184610Salfred } 133184610Salfred return (ENXIO); 134184610Salfred} 135