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