1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * debug.h - DesignWare USB3 DRD Controller Debug Header 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 #ifndef __DWC3_DEBUG_H 12 #define __DWC3_DEBUG_H 13 14 #include "core.h" 15 16 /** 17 * dwc3_gadget_ep_cmd_string - returns endpoint command string 18 * @cmd: command code 19 */ 20 static inline const char * 21 dwc3_gadget_ep_cmd_string(u8 cmd) 22 { 23 switch (cmd) { 24 case DWC3_DEPCMD_DEPSTARTCFG: 25 return "Start New Configuration"; 26 case DWC3_DEPCMD_ENDTRANSFER: 27 return "End Transfer"; 28 case DWC3_DEPCMD_UPDATETRANSFER: 29 return "Update Transfer"; 30 case DWC3_DEPCMD_STARTTRANSFER: 31 return "Start Transfer"; 32 case DWC3_DEPCMD_CLEARSTALL: 33 return "Clear Stall"; 34 case DWC3_DEPCMD_SETSTALL: 35 return "Set Stall"; 36 case DWC3_DEPCMD_GETEPSTATE: 37 return "Get Endpoint State"; 38 case DWC3_DEPCMD_SETTRANSFRESOURCE: 39 return "Set Endpoint Transfer Resource"; 40 case DWC3_DEPCMD_SETEPCONFIG: 41 return "Set Endpoint Configuration"; 42 default: 43 return "UNKNOWN command"; 44 } 45 } 46 47 /** 48 * dwc3_gadget_generic_cmd_string - returns generic command string 49 * @cmd: command code 50 */ 51 static inline const char * 52 dwc3_gadget_generic_cmd_string(u8 cmd) 53 { 54 switch (cmd) { 55 case DWC3_DGCMD_SET_LMP: 56 return "Set LMP"; 57 case DWC3_DGCMD_SET_PERIODIC_PAR: 58 return "Set Periodic Parameters"; 59 case DWC3_DGCMD_XMIT_FUNCTION: 60 return "Transmit Function Wake Device Notification"; 61 case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_LO: 62 return "Set Scratchpad Buffer Array Address Lo"; 63 case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_HI: 64 return "Set Scratchpad Buffer Array Address Hi"; 65 case DWC3_DGCMD_SELECTED_FIFO_FLUSH: 66 return "Selected FIFO Flush"; 67 case DWC3_DGCMD_ALL_FIFO_FLUSH: 68 return "All FIFO Flush"; 69 case DWC3_DGCMD_SET_ENDPOINT_NRDY: 70 return "Set Endpoint NRDY"; 71 case DWC3_DGCMD_SET_ENDPOINT_PRIME: 72 return "Set Endpoint Prime"; 73 case DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK: 74 return "Run SoC Bus Loopback Test"; 75 default: 76 return "UNKNOWN"; 77 } 78 } 79 80 /** 81 * dwc3_gadget_link_string - returns link name 82 * @link_state: link state code 83 */ 84 static inline const char * 85 dwc3_gadget_link_string(enum dwc3_link_state link_state) 86 { 87 switch (link_state) { 88 case DWC3_LINK_STATE_U0: 89 return "U0"; 90 case DWC3_LINK_STATE_U1: 91 return "U1"; 92 case DWC3_LINK_STATE_U2: 93 return "U2"; 94 case DWC3_LINK_STATE_U3: 95 return "U3"; 96 case DWC3_LINK_STATE_SS_DIS: 97 return "SS.Disabled"; 98 case DWC3_LINK_STATE_RX_DET: 99 return "RX.Detect"; 100 case DWC3_LINK_STATE_SS_INACT: 101 return "SS.Inactive"; 102 case DWC3_LINK_STATE_POLL: 103 return "Polling"; 104 case DWC3_LINK_STATE_RECOV: 105 return "Recovery"; 106 case DWC3_LINK_STATE_HRESET: 107 return "Hot Reset"; 108 case DWC3_LINK_STATE_CMPLY: 109 return "Compliance"; 110 case DWC3_LINK_STATE_LPBK: 111 return "Loopback"; 112 case DWC3_LINK_STATE_RESET: 113 return "Reset"; 114 case DWC3_LINK_STATE_RESUME: 115 return "Resume"; 116 default: 117 return "UNKNOWN link state"; 118 } 119 } 120 121 /** 122 * dwc3_gadget_hs_link_string - returns highspeed and below link name 123 * @link_state: link state code 124 */ 125 static inline const char * 126 dwc3_gadget_hs_link_string(enum dwc3_link_state link_state) 127 { 128 switch (link_state) { 129 case DWC3_LINK_STATE_U0: 130 return "On"; 131 case DWC3_LINK_STATE_U2: 132 return "Sleep"; 133 case DWC3_LINK_STATE_U3: 134 return "Suspend"; 135 case DWC3_LINK_STATE_SS_DIS: 136 return "Disconnected"; 137 case DWC3_LINK_STATE_RX_DET: 138 return "Early Suspend"; 139 case DWC3_LINK_STATE_RECOV: 140 return "Recovery"; 141 case DWC3_LINK_STATE_RESET: 142 return "Reset"; 143 case DWC3_LINK_STATE_RESUME: 144 return "Resume"; 145 default: 146 return "UNKNOWN link state"; 147 } 148 } 149 150 /** 151 * dwc3_trb_type_string - returns TRB type as a string 152 * @type: the type of the TRB 153 */ 154 static inline const char *dwc3_trb_type_string(unsigned int type) 155 { 156 switch (type) { 157 case DWC3_TRBCTL_NORMAL: 158 return "normal"; 159 case DWC3_TRBCTL_CONTROL_SETUP: 160 return "setup"; 161 case DWC3_TRBCTL_CONTROL_STATUS2: 162 return "status2"; 163 case DWC3_TRBCTL_CONTROL_STATUS3: 164 return "status3"; 165 case DWC3_TRBCTL_CONTROL_DATA: 166 return "data"; 167 case DWC3_TRBCTL_ISOCHRONOUS_FIRST: 168 return "isoc-first"; 169 case DWC3_TRBCTL_ISOCHRONOUS: 170 return "isoc"; 171 case DWC3_TRBCTL_LINK_TRB: 172 return "link"; 173 default: 174 return "UNKNOWN"; 175 } 176 } 177 178 static inline const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) 179 { 180 switch (state) { 181 case EP0_UNCONNECTED: 182 return "Unconnected"; 183 case EP0_SETUP_PHASE: 184 return "Setup Phase"; 185 case EP0_DATA_PHASE: 186 return "Data Phase"; 187 case EP0_STATUS_PHASE: 188 return "Status Phase"; 189 default: 190 return "UNKNOWN"; 191 } 192 } 193 194 /** 195 * dwc3_gadget_event_string - returns event name 196 * @event: the event code 197 */ 198 static inline const char *dwc3_gadget_event_string(char *str, size_t size, 199 const struct dwc3_event_devt *event) 200 { 201 enum dwc3_link_state state = event->event_info & DWC3_LINK_STATE_MASK; 202 203 switch (event->type) { 204 case DWC3_DEVICE_EVENT_DISCONNECT: 205 snprintf(str, size, "Disconnect: [%s]", 206 dwc3_gadget_link_string(state)); 207 break; 208 case DWC3_DEVICE_EVENT_RESET: 209 snprintf(str, size, "Reset [%s]", 210 dwc3_gadget_link_string(state)); 211 break; 212 case DWC3_DEVICE_EVENT_CONNECT_DONE: 213 snprintf(str, size, "Connection Done [%s]", 214 dwc3_gadget_link_string(state)); 215 break; 216 case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: 217 snprintf(str, size, "Link Change [%s]", 218 dwc3_gadget_link_string(state)); 219 break; 220 case DWC3_DEVICE_EVENT_WAKEUP: 221 snprintf(str, size, "WakeUp [%s]", 222 dwc3_gadget_link_string(state)); 223 break; 224 case DWC3_DEVICE_EVENT_SUSPEND: 225 snprintf(str, size, "Suspend [%s]", 226 dwc3_gadget_link_string(state)); 227 break; 228 case DWC3_DEVICE_EVENT_SOF: 229 snprintf(str, size, "Start-Of-Frame [%s]", 230 dwc3_gadget_link_string(state)); 231 break; 232 case DWC3_DEVICE_EVENT_ERRATIC_ERROR: 233 snprintf(str, size, "Erratic Error [%s]", 234 dwc3_gadget_link_string(state)); 235 break; 236 case DWC3_DEVICE_EVENT_CMD_CMPL: 237 snprintf(str, size, "Command Complete [%s]", 238 dwc3_gadget_link_string(state)); 239 break; 240 case DWC3_DEVICE_EVENT_OVERFLOW: 241 snprintf(str, size, "Overflow [%s]", 242 dwc3_gadget_link_string(state)); 243 break; 244 default: 245 snprintf(str, size, "UNKNOWN"); 246 } 247 248 return str; 249 } 250 251 /** 252 * dwc3_ep_event_string - returns event name 253 * @event: then event code 254 */ 255 static inline const char *dwc3_ep_event_string(char *str, size_t size, 256 const struct dwc3_event_depevt *event, u32 ep0state) 257 { 258 u8 epnum = event->endpoint_number; 259 size_t len; 260 int status; 261 262 len = scnprintf(str, size, "ep%d%s: ", epnum >> 1, 263 (epnum & 1) ? "in" : "out"); 264 265 status = event->status; 266 267 switch (event->endpoint_event) { 268 case DWC3_DEPEVT_XFERCOMPLETE: 269 len += scnprintf(str + len, size - len, 270 "Transfer Complete (%c%c%c)", 271 status & DEPEVT_STATUS_SHORT ? 'S' : 's', 272 status & DEPEVT_STATUS_IOC ? 'I' : 'i', 273 status & DEPEVT_STATUS_LST ? 'L' : 'l'); 274 275 if (epnum <= 1) 276 scnprintf(str + len, size - len, " [%s]", 277 dwc3_ep0_state_string(ep0state)); 278 break; 279 case DWC3_DEPEVT_XFERINPROGRESS: 280 scnprintf(str + len, size - len, 281 "Transfer In Progress [%08x] (%c%c%c)", 282 event->parameters, 283 status & DEPEVT_STATUS_SHORT ? 'S' : 's', 284 status & DEPEVT_STATUS_IOC ? 'I' : 'i', 285 status & DEPEVT_STATUS_LST ? 'M' : 'm'); 286 break; 287 case DWC3_DEPEVT_XFERNOTREADY: 288 len += scnprintf(str + len, size - len, 289 "Transfer Not Ready [%08x]%s", 290 event->parameters, 291 status & DEPEVT_STATUS_TRANSFER_ACTIVE ? 292 " (Active)" : " (Not Active)"); 293 294 /* Control Endpoints */ 295 if (epnum <= 1) { 296 int phase = DEPEVT_STATUS_CONTROL_PHASE(event->status); 297 298 switch (phase) { 299 case DEPEVT_STATUS_CONTROL_DATA: 300 scnprintf(str + len, size - len, 301 " [Data Phase]"); 302 break; 303 case DEPEVT_STATUS_CONTROL_STATUS: 304 scnprintf(str + len, size - len, 305 " [Status Phase]"); 306 } 307 } 308 break; 309 case DWC3_DEPEVT_RXTXFIFOEVT: 310 scnprintf(str + len, size - len, "FIFO"); 311 break; 312 case DWC3_DEPEVT_STREAMEVT: 313 status = event->status; 314 315 switch (status) { 316 case DEPEVT_STREAMEVT_FOUND: 317 scnprintf(str + len, size - len, " Stream %d Found", 318 event->parameters); 319 break; 320 case DEPEVT_STREAMEVT_NOTFOUND: 321 default: 322 scnprintf(str + len, size - len, " Stream Not Found"); 323 break; 324 } 325 326 break; 327 case DWC3_DEPEVT_EPCMDCMPLT: 328 scnprintf(str + len, size - len, "Endpoint Command Complete"); 329 break; 330 default: 331 scnprintf(str + len, size - len, "UNKNOWN"); 332 } 333 334 return str; 335 } 336 337 /** 338 * dwc3_gadget_event_type_string - return event name 339 * @event: the event code 340 */ 341 static inline const char *dwc3_gadget_event_type_string(u8 event) 342 { 343 switch (event) { 344 case DWC3_DEVICE_EVENT_DISCONNECT: 345 return "Disconnect"; 346 case DWC3_DEVICE_EVENT_RESET: 347 return "Reset"; 348 case DWC3_DEVICE_EVENT_CONNECT_DONE: 349 return "Connect Done"; 350 case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: 351 return "Link Status Change"; 352 case DWC3_DEVICE_EVENT_WAKEUP: 353 return "Wake-Up"; 354 case DWC3_DEVICE_EVENT_HIBER_REQ: 355 return "Hibernation"; 356 case DWC3_DEVICE_EVENT_SUSPEND: 357 return "Suspend"; 358 case DWC3_DEVICE_EVENT_SOF: 359 return "Start of Frame"; 360 case DWC3_DEVICE_EVENT_ERRATIC_ERROR: 361 return "Erratic Error"; 362 case DWC3_DEVICE_EVENT_CMD_CMPL: 363 return "Command Complete"; 364 case DWC3_DEVICE_EVENT_OVERFLOW: 365 return "Overflow"; 366 default: 367 return "UNKNOWN"; 368 } 369 } 370 371 static inline const char *dwc3_decode_event(char *str, size_t size, u32 event, 372 u32 ep0state) 373 { 374 union dwc3_event evt; 375 376 memcpy(&evt, &event, sizeof(event)); 377 378 if (evt.type.is_devspec) 379 return dwc3_gadget_event_string(str, size, &evt.devt); 380 else 381 return dwc3_ep_event_string(str, size, &evt.depevt, ep0state); 382 } 383 384 static inline const char *dwc3_ep_cmd_status_string(int status) 385 { 386 switch (status) { 387 case -ETIMEDOUT: 388 return "Timed Out"; 389 case 0: 390 return "Successful"; 391 case DEPEVT_TRANSFER_NO_RESOURCE: 392 return "No Resource"; 393 case DEPEVT_TRANSFER_BUS_EXPIRY: 394 return "Bus Expiry"; 395 default: 396 return "UNKNOWN"; 397 } 398 } 399 400 static inline const char *dwc3_gadget_generic_cmd_status_string(int status) 401 { 402 switch (status) { 403 case -ETIMEDOUT: 404 return "Timed Out"; 405 case 0: 406 return "Successful"; 407 case 1: 408 return "Error"; 409 default: 410 return "UNKNOWN"; 411 } 412 } 413 414 415 #ifdef CONFIG_DEBUG_FS 416 extern void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep); 417 extern void dwc3_debugfs_remove_endpoint_dir(struct dwc3_ep *dep); 418 extern void dwc3_debugfs_init(struct dwc3 *d); 419 extern void dwc3_debugfs_exit(struct dwc3 *d); 420 #else 421 static inline void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep) 422 { } 423 static inline void dwc3_debugfs_remove_endpoint_dir(struct dwc3_ep *dep) 424 { } 425 static inline void dwc3_debugfs_init(struct dwc3 *d) 426 { } 427 static inline void dwc3_debugfs_exit(struct dwc3 *d) 428 { } 429 #endif 430 #endif /* __DWC3_DEBUG_H */ 431