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