GNU Linux-libre 6.8.7-gnu
[releases.git] / drivers / usb / common / debug.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Common USB debugging functions
4  *
5  * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com
6  *
7  * Authors: Felipe Balbi <balbi@ti.com>,
8  *          Sebastian Andrzej Siewior <bigeasy@linutronix.de>
9  */
10
11 #include <linux/kernel.h>
12 #include <linux/usb/ch9.h>
13
14 static void usb_decode_get_status(__u8 bRequestType, __u16 wIndex,
15                                   __u16 wLength, char *str, size_t size)
16 {
17         switch (bRequestType & USB_RECIP_MASK) {
18         case USB_RECIP_DEVICE:
19                 snprintf(str, size, "Get Device Status(Length = %d)", wLength);
20                 break;
21         case USB_RECIP_INTERFACE:
22                 snprintf(str, size,
23                          "Get Interface Status(Intf = %d, Length = %d)",
24                          wIndex, wLength);
25                 break;
26         case USB_RECIP_ENDPOINT:
27                 snprintf(str, size, "Get Endpoint Status(ep%d%s)",
28                          wIndex & ~USB_DIR_IN,
29                          wIndex & USB_DIR_IN ? "in" : "out");
30                 break;
31         }
32 }
33
34 static const char *usb_decode_device_feature(u16 wValue)
35 {
36         switch (wValue) {
37         case USB_DEVICE_SELF_POWERED:
38                 return "Self Powered";
39         case USB_DEVICE_REMOTE_WAKEUP:
40                 return "Remote Wakeup";
41         case USB_DEVICE_TEST_MODE:
42                 return "Test Mode";
43         case USB_DEVICE_U1_ENABLE:
44                 return "U1 Enable";
45         case USB_DEVICE_U2_ENABLE:
46                 return "U2 Enable";
47         case USB_DEVICE_LTM_ENABLE:
48                 return "LTM Enable";
49         default:
50                 return "UNKNOWN";
51         }
52 }
53
54 static const char *usb_decode_test_mode(u16 wIndex)
55 {
56         switch (wIndex) {
57         case USB_TEST_J:
58                 return ": TEST_J";
59         case USB_TEST_K:
60                 return ": TEST_K";
61         case USB_TEST_SE0_NAK:
62                 return ": TEST_SE0_NAK";
63         case USB_TEST_PACKET:
64                 return ": TEST_PACKET";
65         case USB_TEST_FORCE_ENABLE:
66                 return ": TEST_FORCE_EN";
67         default:
68                 return ": UNKNOWN";
69         }
70 }
71
72 static void usb_decode_set_clear_feature(__u8 bRequestType,
73                                          __u8 bRequest, __u16 wValue,
74                                          __u16 wIndex, char *str, size_t size)
75 {
76         switch (bRequestType & USB_RECIP_MASK) {
77         case USB_RECIP_DEVICE:
78                 snprintf(str, size, "%s Device Feature(%s%s)",
79                          bRequest == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set",
80                          usb_decode_device_feature(wValue),
81                          wValue == USB_DEVICE_TEST_MODE ?
82                          usb_decode_test_mode(wIndex) : "");
83                 break;
84         case USB_RECIP_INTERFACE:
85                 snprintf(str, size, "%s Interface Feature(%s)",
86                          bRequest == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set",
87                          wValue == USB_INTRF_FUNC_SUSPEND ?
88                          "Function Suspend" : "UNKNOWN");
89                 break;
90         case USB_RECIP_ENDPOINT:
91                 snprintf(str, size, "%s Endpoint Feature(%s ep%d%s)",
92                          bRequest == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set",
93                          wValue == USB_ENDPOINT_HALT ? "Halt" : "UNKNOWN",
94                          wIndex & ~USB_DIR_IN,
95                          wIndex & USB_DIR_IN ? "in" : "out");
96                 break;
97         }
98 }
99
100 static void usb_decode_set_address(__u16 wValue, char *str, size_t size)
101 {
102         snprintf(str, size, "Set Address(Addr = %02x)", wValue);
103 }
104
105 static void usb_decode_get_set_descriptor(__u8 bRequestType, __u8 bRequest,
106                                           __u16 wValue, __u16 wIndex,
107                                           __u16 wLength, char *str, size_t size)
108 {
109         char *s;
110
111         switch (wValue >> 8) {
112         case USB_DT_DEVICE:
113                 s = "Device";
114                 break;
115         case USB_DT_CONFIG:
116                 s = "Configuration";
117                 break;
118         case USB_DT_STRING:
119                 s = "String";
120                 break;
121         case USB_DT_INTERFACE:
122                 s = "Interface";
123                 break;
124         case USB_DT_ENDPOINT:
125                 s = "Endpoint";
126                 break;
127         case USB_DT_DEVICE_QUALIFIER:
128                 s = "Device Qualifier";
129                 break;
130         case USB_DT_OTHER_SPEED_CONFIG:
131                 s = "Other Speed Config";
132                 break;
133         case USB_DT_INTERFACE_POWER:
134                 s = "Interface Power";
135                 break;
136         case USB_DT_OTG:
137                 s = "OTG";
138                 break;
139         case USB_DT_DEBUG:
140                 s = "Debug";
141                 break;
142         case USB_DT_INTERFACE_ASSOCIATION:
143                 s = "Interface Association";
144                 break;
145         case USB_DT_BOS:
146                 s = "BOS";
147                 break;
148         case USB_DT_DEVICE_CAPABILITY:
149                 s = "Device Capability";
150                 break;
151         case USB_DT_PIPE_USAGE:
152                 s = "Pipe Usage";
153                 break;
154         case USB_DT_SS_ENDPOINT_COMP:
155                 s = "SS Endpoint Companion";
156                 break;
157         case USB_DT_SSP_ISOC_ENDPOINT_COMP:
158                 s = "SSP Isochronous Endpoint Companion";
159                 break;
160         default:
161                 s = "UNKNOWN";
162                 break;
163         }
164
165         snprintf(str, size, "%s %s Descriptor(Index = %d, Length = %d)",
166                 bRequest == USB_REQ_GET_DESCRIPTOR ? "Get" : "Set",
167                 s, wValue & 0xff, wLength);
168 }
169
170 static void usb_decode_get_configuration(__u16 wLength, char *str, size_t size)
171 {
172         snprintf(str, size, "Get Configuration(Length = %d)", wLength);
173 }
174
175 static void usb_decode_set_configuration(__u8 wValue, char *str, size_t size)
176 {
177         snprintf(str, size, "Set Configuration(Config = %d)", wValue);
178 }
179
180 static void usb_decode_get_intf(__u16 wIndex, __u16 wLength, char *str,
181                                 size_t size)
182 {
183         snprintf(str, size, "Get Interface(Intf = %d, Length = %d)",
184                  wIndex, wLength);
185 }
186
187 static void usb_decode_set_intf(__u8 wValue, __u16 wIndex, char *str,
188                                 size_t size)
189 {
190         snprintf(str, size, "Set Interface(Intf = %d, Alt.Setting = %d)",
191                  wIndex, wValue);
192 }
193
194 static void usb_decode_synch_frame(__u16 wIndex, __u16 wLength,
195                                    char *str, size_t size)
196 {
197         snprintf(str, size, "Synch Frame(Endpoint = %d, Length = %d)",
198                  wIndex, wLength);
199 }
200
201 static void usb_decode_set_sel(__u16 wLength, char *str, size_t size)
202 {
203         snprintf(str, size, "Set SEL(Length = %d)", wLength);
204 }
205
206 static void usb_decode_set_isoch_delay(__u8 wValue, char *str, size_t size)
207 {
208         snprintf(str, size, "Set Isochronous Delay(Delay = %d ns)", wValue);
209 }
210
211 static void usb_decode_ctrl_generic(char *str, size_t size, __u8 bRequestType,
212                                     __u8 bRequest, __u16 wValue, __u16 wIndex,
213                                     __u16 wLength)
214 {
215         u8 recip = bRequestType & USB_RECIP_MASK;
216         u8 type = bRequestType & USB_TYPE_MASK;
217
218         snprintf(str, size,
219                  "Type=%s Recipient=%s Dir=%s bRequest=%u wValue=%u wIndex=%u wLength=%u",
220                  (type == USB_TYPE_STANDARD)    ? "Standard" :
221                  (type == USB_TYPE_VENDOR)      ? "Vendor" :
222                  (type == USB_TYPE_CLASS)       ? "Class" : "Unknown",
223                  (recip == USB_RECIP_DEVICE)    ? "Device" :
224                  (recip == USB_RECIP_INTERFACE) ? "Interface" :
225                  (recip == USB_RECIP_ENDPOINT)  ? "Endpoint" : "Unknown",
226                  (bRequestType & USB_DIR_IN)    ? "IN" : "OUT",
227                  bRequest, wValue, wIndex, wLength);
228 }
229
230 static void usb_decode_ctrl_standard(char *str, size_t size, __u8 bRequestType,
231                                      __u8 bRequest, __u16 wValue, __u16 wIndex,
232                                      __u16 wLength)
233 {
234         switch (bRequest) {
235         case USB_REQ_GET_STATUS:
236                 usb_decode_get_status(bRequestType, wIndex, wLength, str, size);
237                 break;
238         case USB_REQ_CLEAR_FEATURE:
239         case USB_REQ_SET_FEATURE:
240                 usb_decode_set_clear_feature(bRequestType, bRequest, wValue,
241                                              wIndex, str, size);
242                 break;
243         case USB_REQ_SET_ADDRESS:
244                 usb_decode_set_address(wValue, str, size);
245                 break;
246         case USB_REQ_GET_DESCRIPTOR:
247         case USB_REQ_SET_DESCRIPTOR:
248                 usb_decode_get_set_descriptor(bRequestType, bRequest, wValue,
249                                               wIndex, wLength, str, size);
250                 break;
251         case USB_REQ_GET_CONFIGURATION:
252                 usb_decode_get_configuration(wLength, str, size);
253                 break;
254         case USB_REQ_SET_CONFIGURATION:
255                 usb_decode_set_configuration(wValue, str, size);
256                 break;
257         case USB_REQ_GET_INTERFACE:
258                 usb_decode_get_intf(wIndex, wLength, str, size);
259                 break;
260         case USB_REQ_SET_INTERFACE:
261                 usb_decode_set_intf(wValue, wIndex, str, size);
262                 break;
263         case USB_REQ_SYNCH_FRAME:
264                 usb_decode_synch_frame(wIndex, wLength, str, size);
265                 break;
266         case USB_REQ_SET_SEL:
267                 usb_decode_set_sel(wLength, str, size);
268                 break;
269         case USB_REQ_SET_ISOCH_DELAY:
270                 usb_decode_set_isoch_delay(wValue, str, size);
271                 break;
272         default:
273                 usb_decode_ctrl_generic(str, size, bRequestType, bRequest,
274                                         wValue, wIndex, wLength);
275                 break;
276         }
277 }
278
279 /**
280  * usb_decode_ctrl - Returns human readable representation of control request.
281  * @str: buffer to return a human-readable representation of control request.
282  *       This buffer should have about 200 bytes.
283  * @size: size of str buffer.
284  * @bRequestType: matches the USB bmRequestType field
285  * @bRequest: matches the USB bRequest field
286  * @wValue: matches the USB wValue field (CPU byte order)
287  * @wIndex: matches the USB wIndex field (CPU byte order)
288  * @wLength: matches the USB wLength field (CPU byte order)
289  *
290  * Function returns decoded, formatted and human-readable description of
291  * control request packet.
292  *
293  * The usage scenario for this is for tracepoints, so function as a return
294  * use the same value as in parameters. This approach allows to use this
295  * function in TP_printk
296  *
297  * Important: wValue, wIndex, wLength parameters before invoking this function
298  * should be processed by le16_to_cpu macro.
299  */
300 const char *usb_decode_ctrl(char *str, size_t size, __u8 bRequestType,
301                             __u8 bRequest, __u16 wValue, __u16 wIndex,
302                             __u16 wLength)
303 {
304         switch (bRequestType & USB_TYPE_MASK) {
305         case USB_TYPE_STANDARD:
306                 usb_decode_ctrl_standard(str, size, bRequestType, bRequest,
307                                          wValue, wIndex, wLength);
308                 break;
309         case USB_TYPE_VENDOR:
310         case USB_TYPE_CLASS:
311         default:
312                 usb_decode_ctrl_generic(str, size, bRequestType, bRequest,
313                                         wValue, wIndex, wLength);
314                 break;
315         }
316
317         return str;
318 }
319 EXPORT_SYMBOL_GPL(usb_decode_ctrl);