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