xref: /linux-6.15/drivers/usb/common/debug.c (revision 91f255a2)
1 // 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 <[email protected]>,
8  *	    Sebastian Andrzej Siewior <[email protected]>
9  */
10 
11 #include <linux/usb/ch9.h>
12 
13 static 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 
33 static 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 
102 static void usb_decode_set_address(__u16 wValue, char *str, size_t size)
103 {
104 	snprintf(str, size, "Set Address(Addr = %02x)", wValue);
105 }
106 
107 static 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 
169 static void usb_decode_get_configuration(__u16 wLength, char *str, size_t size)
170 {
171 	snprintf(str, size, "Get Configuration(Length = %d)", wLength);
172 }
173 
174 static void usb_decode_set_configuration(__u8 wValue, char *str, size_t size)
175 {
176 	snprintf(str, size, "Set Configuration(Config = %d)", wValue);
177 }
178 
179 static 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 
186 static 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 
193 static 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 
200 static void usb_decode_set_sel(__u16 wLength, char *str, size_t size)
201 {
202 	snprintf(str, size, "Set SEL(Length = %d)", wLength);
203 }
204 
205 static 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  */
213 const 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 }
268 EXPORT_SYMBOL_GPL(usb_decode_ctrl);
269