blob: 68b4f7e80b47cdacc436d4607552dd0b250a66cc [file] [log] [blame]
/*
* drivers/usb/core/otg_whitelist.h
*
* Copyright (C) 2004 Texas Instruments
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
/*
* This OTG and Embedded Host Whitelist is "Targeted Peripheral List".
* It should mostly use of USB_DEVICE() or USB_DEVICE_VER() entries..
*
* YOU _SHOULD_ CHANGE THIS LIST TO MATCH YOUR PRODUCT AND ITS TESTING!
*/
static struct usb_device_id whitelist_table[] = {
/* Add FSL i.mx whitelist, the default list is for USB Compliance Test */
#if defined(CONFIG_USB_EHSET_TEST_FIXTURE) \
|| defined(CONFIG_USB_EHSET_TEST_FIXTURE_MODULE)
#define TEST_SE0_NAK_PID 0x0101
#define TEST_J_PID 0x0102
#define TEST_K_PID 0x0103
#define TEST_PACKET_PID 0x0104
#define TEST_HS_HOST_PORT_SUSPEND_RESUME 0x0106
#define TEST_SINGLE_STEP_GET_DEV_DESC 0x0107
#define TEST_SINGLE_STEP_SET_FEATURE 0x0108
#define TEST_OTG_TEST_DEVICE_SUPPORT 0x0200
{ USB_DEVICE(0x1a0a, TEST_SE0_NAK_PID) },
{ USB_DEVICE(0x1a0a, TEST_J_PID) },
{ USB_DEVICE(0x1a0a, TEST_K_PID) },
{ USB_DEVICE(0x1a0a, TEST_PACKET_PID) },
{ USB_DEVICE(0x1a0a, TEST_HS_HOST_PORT_SUSPEND_RESUME) },
{ USB_DEVICE(0x1a0a, TEST_SINGLE_STEP_GET_DEV_DESC) },
{ USB_DEVICE(0x1a0a, TEST_SINGLE_STEP_SET_FEATURE) },
{ USB_DEVICE(0x1a0a, TEST_OTG_TEST_DEVICE_SUPPORT) },
#endif
#define USB_INTERFACE_CLASS_INFO(cl) \
.match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, \
.bInterfaceClass = (cl)
{USB_INTERFACE_CLASS_INFO(USB_CLASS_HUB) },
#if defined(CONFIG_USB_STORAGE) || defined(CONFIG_USB_STORAGE_MODULE)
{USB_INTERFACE_CLASS_INFO(USB_CLASS_MASS_STORAGE) },
#endif
#if defined(CONFIG_USB_HID) || defined(CONFIG_USB_HID_MODULE)
{USB_INTERFACE_CLASS_INFO(USB_CLASS_HID) },
#endif
{ } /* Terminating entry */
};
static bool match_int_class(struct usb_device_id *id, struct usb_device *udev)
{
struct usb_host_config *c;
int num_configs, i;
/* Copy the code from generic.c */
c = udev->config;
num_configs = udev->descriptor.bNumConfigurations;
for (i = 0; i < num_configs; (i++, c++)) {
struct usb_interface_descriptor *desc = NULL;
/* It's possible that a config has no interfaces! */
if (c->desc.bNumInterfaces > 0)
desc = &c->intf_cache[0]->altsetting->desc;
if (desc && (desc->bInterfaceClass == id->bInterfaceClass))
return true;
}
return false;
}
static int is_targeted(struct usb_device *dev)
{
struct usb_device_id *id = whitelist_table;
/* HNP test device is _never_ targeted (see OTG spec 6.6.6) */
if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a0a &&
le16_to_cpu(dev->descriptor.idProduct) == 0xbadd))
return 0;
/* OTG PET device is always targeted (see OTG 2.0 ECN 6.4.2) */
if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a0a &&
le16_to_cpu(dev->descriptor.idProduct) == 0x0200))
return 1;
/* Unknown Device Not Supporting HNP */
if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a0a &&
le16_to_cpu(dev->descriptor.idProduct) == 0x0201)) {
dev_warn(&dev->dev, "Unsupported Device\n");
return 0;
}
/* Unknown Device Supporting HNP */
if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a0a &&
le16_to_cpu(dev->descriptor.idProduct) == 0x0202)) {
dev_warn(&dev->dev, "Device no Responding\n");
return 0;
}
/* NOTE: can't use usb_match_id() since interface caches
* aren't set up yet. this is cut/paste from that code.
*/
for (id = whitelist_table; id->match_flags; id++) {
if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
continue;
if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
id->idProduct != le16_to_cpu(dev->descriptor.idProduct))
continue;
/* No need to test id->bcdDevice_lo != 0, since 0 is never
greater than any unsigned number. */
if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
(id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice)))
continue;
if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
(id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice)))
continue;
if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
(id->bDeviceClass != dev->descriptor.bDeviceClass))
continue;
if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&
(id->bDeviceSubClass != dev->descriptor.bDeviceSubClass))
continue;
if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&
(id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
continue;
if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
(!match_int_class(id, dev)))
continue;
return 1;
}
/* add other match criteria here ... */
/* OTG MESSAGE: report errors here, customize to match your product */
dev_err(&dev->dev, "device v%04x p%04x is not supported\n",
le16_to_cpu(dev->descriptor.idVendor),
le16_to_cpu(dev->descriptor.idProduct));
return 0;
}