]> Git Repo - linux.git/blob - drivers/usb/common/debug.c
Merge tag 'perf-tools-for-v6.0-2022-08-04' of git://git.kernel.org/pub/scm/linux...
[linux.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 <[email protected]>,
8  *          Sebastian Andrzej Siewior <[email protected]>
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 /**
212  * usb_decode_ctrl - Returns human readable representation of control request.
213  * @str: buffer to return a human-readable representation of control request.
214  *       This buffer should have about 200 bytes.
215  * @size: size of str buffer.
216  * @bRequestType: matches the USB bmRequestType field
217  * @bRequest: matches the USB bRequest field
218  * @wValue: matches the USB wValue field (CPU byte order)
219  * @wIndex: matches the USB wIndex field (CPU byte order)
220  * @wLength: matches the USB wLength field (CPU byte order)
221  *
222  * Function returns decoded, formatted and human-readable description of
223  * control request packet.
224  *
225  * The usage scenario for this is for tracepoints, so function as a return
226  * use the same value as in parameters. This approach allows to use this
227  * function in TP_printk
228  *
229  * Important: wValue, wIndex, wLength parameters before invoking this function
230  * should be processed by le16_to_cpu macro.
231  */
232 const char *usb_decode_ctrl(char *str, size_t size, __u8 bRequestType,
233                             __u8 bRequest, __u16 wValue, __u16 wIndex,
234                             __u16 wLength)
235 {
236         switch (bRequest) {
237         case USB_REQ_GET_STATUS:
238                 usb_decode_get_status(bRequestType, wIndex, wLength, str, size);
239                 break;
240         case USB_REQ_CLEAR_FEATURE:
241         case USB_REQ_SET_FEATURE:
242                 usb_decode_set_clear_feature(bRequestType, bRequest, wValue,
243                                              wIndex, str, size);
244                 break;
245         case USB_REQ_SET_ADDRESS:
246                 usb_decode_set_address(wValue, str, size);
247                 break;
248         case USB_REQ_GET_DESCRIPTOR:
249         case USB_REQ_SET_DESCRIPTOR:
250                 usb_decode_get_set_descriptor(bRequestType, bRequest, wValue,
251                                               wIndex, wLength, str, size);
252                 break;
253         case USB_REQ_GET_CONFIGURATION:
254                 usb_decode_get_configuration(wLength, str, size);
255                 break;
256         case USB_REQ_SET_CONFIGURATION:
257                 usb_decode_set_configuration(wValue, str, size);
258                 break;
259         case USB_REQ_GET_INTERFACE:
260                 usb_decode_get_intf(wIndex, wLength, str, size);
261                 break;
262         case USB_REQ_SET_INTERFACE:
263                 usb_decode_set_intf(wValue, wIndex, str, size);
264                 break;
265         case USB_REQ_SYNCH_FRAME:
266                 usb_decode_synch_frame(wIndex, wLength, str, size);
267                 break;
268         case USB_REQ_SET_SEL:
269                 usb_decode_set_sel(wLength, str, size);
270                 break;
271         case USB_REQ_SET_ISOCH_DELAY:
272                 usb_decode_set_isoch_delay(wValue, str, size);
273                 break;
274         default:
275                 snprintf(str, size, "%02x %02x %02x %02x %02x %02x %02x %02x",
276                          bRequestType, bRequest,
277                          (u8)(cpu_to_le16(wValue) & 0xff),
278                          (u8)(cpu_to_le16(wValue) >> 8),
279                          (u8)(cpu_to_le16(wIndex) & 0xff),
280                          (u8)(cpu_to_le16(wIndex) >> 8),
281                          (u8)(cpu_to_le16(wLength) & 0xff),
282                          (u8)(cpu_to_le16(wLength) >> 8));
283         }
284
285         return str;
286 }
287 EXPORT_SYMBOL_GPL(usb_decode_ctrl);
This page took 0.05071 seconds and 4 git commands to generate.