1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
/*
* 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 Whitelist is the OTG "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 [] = {
/* hubs are optional in OTG, but very handy ... */
{ USB_DEVICE_INFO(USB_CLASS_HUB, 0, 0), },
{ USB_DEVICE_INFO(USB_CLASS_HUB, 0, 1), },
#ifdef CONFIG_USB_PRINTER /* ignoring nonstatic linkage! */
/* FIXME actually, printers are NOT supposed to use device classes;
* they're supposed to use interface classes...
*/
{ USB_DEVICE_INFO(7, 1, 1) },
{ USB_DEVICE_INFO(7, 1, 2) },
{ USB_DEVICE_INFO(7, 1, 3) },
#endif
#ifdef CONFIG_USB_NET_CDCETHER
/* Linux-USB CDC Ethernet gadget */
{ USB_DEVICE(0x0525, 0xa4a1), },
/* Linux-USB CDC Ethernet + RNDIS gadget */
{ USB_DEVICE(0x0525, 0xa4a2), },
#endif
#if defined(CONFIG_USB_TEST) || defined(CONFIG_USB_TEST_MODULE)
/* gadget zero, for testing */
{ USB_DEVICE(0x0525, 0xa4a0), },
#endif
#ifdef CONFIG_USB_OTG_20
{ USB_DEVICE_INFO(8, 6, 80) },/* Mass Storage Devices */
{ USB_DEVICE_INFO(1, 1, 0) },/* Audio Devices */
{ USB_DEVICE_INFO(3, 0, 0) },/* keyboard Devices */
{ USB_DEVICE_INFO(3, 1, 2) },/* Mouse Devices */
/* Test Devices */
{ USB_DEVICE(0x1A0A, 0x0101), },/* Test_SE0_NAK */
{ USB_DEVICE(0x1A0A, 0x0102), },/* Test_J */
{ USB_DEVICE(0x1A0A, 0x0103), },/* Test_K */
{ USB_DEVICE(0x1A0A, 0x0104), },/* Test_Packet */
{ USB_DEVICE(0x1A0A, 0x0106), },/* HS_HOST_PORT_SUSPEND_RESUME */
{ USB_DEVICE(0x1A0A, 0x0107), },/* SINGLE_STEP_GET_DEV_DESC */
{ USB_DEVICE(0x1A0A, 0x0108), },/* SINGLE_STEP_ GET_DEV_DESC_DATA*/
{ USB_DEVICE(0x1A0A, 0x0201), },/* OTG 2 TEST DEVICE*/
#endif
{ } /* Terminating entry */
};
/* The TEST_MODE Definition for OTG as per 6.4 of OTG Rev 2.0 */
#ifdef CONFIG_USB_OTG_20
#define USB_OTG_TEST_MODE_VID 0x1A0A
#define USB_OTG_TEST_SE0_NAK_PID 0x0101
#define USB_OTG_TEST_J_PID 0x0102
#define USB_OTG_TEST_K_PID 0x0103
#define USB_OTG_TEST_PACKET_PID 0x0104
#define USB_OTG_TEST_HS_HOST_PORT_SUSPEND_RESUME_PID 0x0106
#define USB_OTG_TEST_SINGLE_STEP_GET_DEV_DESC_PID 0x0107
#define USB_OTG_TEST_SINGLE_STEP_GET_DEV_DESC_DATA_PID 0x0108
#define USB_OTG_TEST_SE0_NAK 0x01
#define USB_OTG_TEST_J 0x02
#define USB_OTG_TEST_K 0x03
#define USB_OTG_TEST_PACKET 0x04
#endif
static int is_targeted(struct usb_device *dev)
{
struct usb_device_id *id = whitelist_table;
#ifdef CONFIG_USB_OTG_20
u8 number_configs = 0;
u8 number_interface = 0;
#endif
/* possible in developer configs only! */
if (!dev->bus->otg_port)
return 1;
/* 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;
/* 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;
return 1;
}
/* add other match criteria here ... */
#ifdef CONFIG_USB_OTG_20
/* Checking class,subclass and protocal at interface level */
for (number_configs = dev->descriptor.bNumConfigurations;
number_configs > 0; number_configs--)
for (number_interface = dev->config->desc.bNumInterfaces;
number_interface > 0;
number_interface--)
for (id = whitelist_table; id->match_flags; id++) {
if ((id->match_flags &
USB_DEVICE_ID_MATCH_DEV_CLASS) &&
(id->bDeviceClass !=
dev->config->intf_cache[number_interface-1]
->altsetting[0].desc.bInterfaceClass))
continue;
if ((id->match_flags &
USB_DEVICE_ID_MATCH_DEV_SUBCLASS)
&& (id->bDeviceSubClass !=
dev->config->intf_cache[number_interface-1]
->altsetting[0].desc.bInterfaceSubClass))
continue;
if ((id->match_flags &
USB_DEVICE_ID_MATCH_DEV_PROTOCOL)
&& (id->bDeviceProtocol !=
dev->config->intf_cache[number_interface-1]
->altsetting[0].desc.bInterfaceProtocol))
continue;
return 1;
}
#endif
/* 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));
#ifdef CONFIG_USB_OTG_WHITELIST
return 0;
#else
return 1;
#endif
}
|