// SPDX-License-Identifier: GPL-2.0+ /* * drivers/usb/core/otg_whitelist.h * * Copyright (C) 2004 Texas Instruments */ /* * 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 { 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) }, #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; /* 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; }