blob: d5a469bc67a33bd71ff35f0162186b6d457fb300 [file] [log] [blame]
Pawel Laszczak91f255a2019-08-26 12:19:27 +01001// SPDX-License-Identifier: GPL-2.0
2/**
3 * Common USB debugging functions
4 *
5 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
6 *
7 * Authors: Felipe Balbi <balbi@ti.com>,
8 * Sebastian Andrzej Siewior <bigeasy@linutronix.de>
9 */
10
11#include <linux/usb/ch9.h>
12
13static void usb_decode_get_status(__u8 bRequestType, __u16 wIndex,
14 __u16 wLength, char *str, size_t size)
15{
16 switch (bRequestType & USB_RECIP_MASK) {
17 case USB_RECIP_DEVICE:
18 snprintf(str, size, "Get Device Status(Length = %d)", wLength);
19 break;
20 case USB_RECIP_INTERFACE:
21 snprintf(str, size,
22 "Get Interface Status(Intf = %d, Length = %d)",
23 wIndex, wLength);
24 break;
25 case USB_RECIP_ENDPOINT:
26 snprintf(str, size, "Get Endpoint Status(ep%d%s)",
27 wIndex & ~USB_DIR_IN,
28 wIndex & USB_DIR_IN ? "in" : "out");
29 break;
30 }
31}
32
33static void usb_decode_set_clear_feature(__u8 bRequestType, __u8 bRequest,
34 __u16 wValue, __u16 wIndex,
35 char *str, size_t size)
36{
37 switch (bRequestType & USB_RECIP_MASK) {
38 case USB_RECIP_DEVICE:
39 snprintf(str, size, "%s Device Feature(%s%s)",
40 bRequest == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set",
41 ({char *s;
42 switch (wValue) {
43 case USB_DEVICE_SELF_POWERED:
44 s = "Self Powered";
45 break;
46 case USB_DEVICE_REMOTE_WAKEUP:
47 s = "Remote Wakeup";
48 break;
49 case USB_DEVICE_TEST_MODE:
50 s = "Test Mode";
51 break;
52 case USB_DEVICE_U1_ENABLE:
53 s = "U1 Enable";
54 break;
55 case USB_DEVICE_U2_ENABLE:
56 s = "U2 Enable";
57 break;
58 case USB_DEVICE_LTM_ENABLE:
59 s = "LTM Enable";
60 break;
61 default:
62 s = "UNKNOWN";
63 } s; }),
64 wValue == USB_DEVICE_TEST_MODE ?
65 ({ char *s;
66 switch (wIndex) {
67 case TEST_J:
68 s = ": TEST_J";
69 break;
70 case TEST_K:
71 s = ": TEST_K";
72 break;
73 case TEST_SE0_NAK:
74 s = ": TEST_SE0_NAK";
75 break;
76 case TEST_PACKET:
77 s = ": TEST_PACKET";
78 break;
79 case TEST_FORCE_EN:
80 s = ": TEST_FORCE_EN";
81 break;
82 default:
83 s = ": UNKNOWN";
84 } s; }) : "");
85 break;
86 case USB_RECIP_INTERFACE:
87 snprintf(str, size, "%s Interface Feature(%s)",
88 bRequest == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set",
89 wValue == USB_INTRF_FUNC_SUSPEND ?
90 "Function Suspend" : "UNKNOWN");
91 break;
92 case USB_RECIP_ENDPOINT:
93 snprintf(str, size, "%s Endpoint Feature(%s ep%d%s)",
94 bRequest == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set",
95 wValue == USB_ENDPOINT_HALT ? "Halt" : "UNKNOWN",
96 wIndex & ~USB_DIR_IN,
97 wIndex & USB_DIR_IN ? "in" : "out");
98 break;
99 }
100}
101
102static void usb_decode_set_address(__u16 wValue, char *str, size_t size)
103{
104 snprintf(str, size, "Set Address(Addr = %02x)", wValue);
105}
106
107static void usb_decode_get_set_descriptor(__u8 bRequestType, __u8 bRequest,
108 __u16 wValue, __u16 wIndex,
109 __u16 wLength, char *str, size_t size)
110{
111 snprintf(str, size, "%s %s Descriptor(Index = %d, Length = %d)",
112 bRequest == USB_REQ_GET_DESCRIPTOR ? "Get" : "Set",
113 ({ char *s;
114 switch (wValue >> 8) {
115 case USB_DT_DEVICE:
116 s = "Device";
117 break;
118 case USB_DT_CONFIG:
119 s = "Configuration";
120 break;
121 case USB_DT_STRING:
122 s = "String";
123 break;
124 case USB_DT_INTERFACE:
125 s = "Interface";
126 break;
127 case USB_DT_ENDPOINT:
128 s = "Endpoint";
129 break;
130 case USB_DT_DEVICE_QUALIFIER:
131 s = "Device Qualifier";
132 break;
133 case USB_DT_OTHER_SPEED_CONFIG:
134 s = "Other Speed Config";
135 break;
136 case USB_DT_INTERFACE_POWER:
137 s = "Interface Power";
138 break;
139 case USB_DT_OTG:
140 s = "OTG";
141 break;
142 case USB_DT_DEBUG:
143 s = "Debug";
144 break;
145 case USB_DT_INTERFACE_ASSOCIATION:
146 s = "Interface Association";
147 break;
148 case USB_DT_BOS:
149 s = "BOS";
150 break;
151 case USB_DT_DEVICE_CAPABILITY:
152 s = "Device Capability";
153 break;
154 case USB_DT_PIPE_USAGE:
155 s = "Pipe Usage";
156 break;
157 case USB_DT_SS_ENDPOINT_COMP:
158 s = "SS Endpoint Companion";
159 break;
160 case USB_DT_SSP_ISOC_ENDPOINT_COMP:
161 s = "SSP Isochronous Endpoint Companion";
162 break;
163 default:
164 s = "UNKNOWN";
165 break;
166 } s; }), wValue & 0xff, wLength);
167}
168
169static void usb_decode_get_configuration(__u16 wLength, char *str, size_t size)
170{
171 snprintf(str, size, "Get Configuration(Length = %d)", wLength);
172}
173
174static void usb_decode_set_configuration(__u8 wValue, char *str, size_t size)
175{
176 snprintf(str, size, "Set Configuration(Config = %d)", wValue);
177}
178
179static void usb_decode_get_intf(__u16 wIndex, __u16 wLength, char *str,
180 size_t size)
181{
182 snprintf(str, size, "Get Interface(Intf = %d, Length = %d)",
183 wIndex, wLength);
184}
185
186static void usb_decode_set_intf(__u8 wValue, __u16 wIndex, char *str,
187 size_t size)
188{
189 snprintf(str, size, "Set Interface(Intf = %d, Alt.Setting = %d)",
190 wIndex, wValue);
191}
192
193static void usb_decode_synch_frame(__u16 wIndex, __u16 wLength,
194 char *str, size_t size)
195{
196 snprintf(str, size, "Synch Frame(Endpoint = %d, Length = %d)",
197 wIndex, wLength);
198}
199
200static void usb_decode_set_sel(__u16 wLength, char *str, size_t size)
201{
202 snprintf(str, size, "Set SEL(Length = %d)", wLength);
203}
204
205static void usb_decode_set_isoch_delay(__u8 wValue, char *str, size_t size)
206{
207 snprintf(str, size, "Set Isochronous Delay(Delay = %d ns)", wValue);
208}
209
210/**
211 * usb_decode_ctrl - returns a string representation of ctrl request
212 */
213const char *usb_decode_ctrl(char *str, size_t size, __u8 bRequestType,
214 __u8 bRequest, __u16 wValue, __u16 wIndex,
215 __u16 wLength)
216{
217 switch (bRequest) {
218 case USB_REQ_GET_STATUS:
219 usb_decode_get_status(bRequestType, wIndex, wLength, str, size);
220 break;
221 case USB_REQ_CLEAR_FEATURE:
222 case USB_REQ_SET_FEATURE:
223 usb_decode_set_clear_feature(bRequestType, bRequest, wValue,
224 wIndex, str, size);
225 break;
226 case USB_REQ_SET_ADDRESS:
227 usb_decode_set_address(wValue, str, size);
228 break;
229 case USB_REQ_GET_DESCRIPTOR:
230 case USB_REQ_SET_DESCRIPTOR:
231 usb_decode_get_set_descriptor(bRequestType, bRequest, wValue,
232 wIndex, wLength, str, size);
233 break;
234 case USB_REQ_GET_CONFIGURATION:
235 usb_decode_get_configuration(wLength, str, size);
236 break;
237 case USB_REQ_SET_CONFIGURATION:
238 usb_decode_set_configuration(wValue, str, size);
239 break;
240 case USB_REQ_GET_INTERFACE:
241 usb_decode_get_intf(wIndex, wLength, str, size);
242 break;
243 case USB_REQ_SET_INTERFACE:
244 usb_decode_set_intf(wValue, wIndex, str, size);
245 break;
246 case USB_REQ_SYNCH_FRAME:
247 usb_decode_synch_frame(wIndex, wLength, str, size);
248 break;
249 case USB_REQ_SET_SEL:
250 usb_decode_set_sel(wLength, str, size);
251 break;
252 case USB_REQ_SET_ISOCH_DELAY:
253 usb_decode_set_isoch_delay(wValue, str, size);
254 break;
255 default:
256 snprintf(str, size, "%02x %02x %02x %02x %02x %02x %02x %02x",
257 bRequestType, bRequest,
258 (u8)(cpu_to_le16(wValue) & 0xff),
259 (u8)(cpu_to_le16(wValue) >> 8),
260 (u8)(cpu_to_le16(wIndex) & 0xff),
261 (u8)(cpu_to_le16(wIndex) >> 8),
262 (u8)(cpu_to_le16(wLength) & 0xff),
263 (u8)(cpu_to_le16(wLength) >> 8));
264 }
265
266 return str;
267}
268EXPORT_SYMBOL_GPL(usb_decode_ctrl);