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\n"; 116 } 117 } 118 119 /** 120 * dwc3_trb_type_string - returns TRB type as a string 121 * @type: the type of the TRB 122 */ 123 static inline const char *dwc3_trb_type_string(unsigned int type) 124 { 125 switch (type) { 126 case DWC3_TRBCTL_NORMAL: 127 return "normal"; 128 case DWC3_TRBCTL_CONTROL_SETUP: 129 return "setup"; 130 case DWC3_TRBCTL_CONTROL_STATUS2: 131 return "status2"; 132 case DWC3_TRBCTL_CONTROL_STATUS3: 133 return "status3"; 134 case DWC3_TRBCTL_CONTROL_DATA: 135 return "data"; 136 case DWC3_TRBCTL_ISOCHRONOUS_FIRST: 137 return "isoc-first"; 138 case DWC3_TRBCTL_ISOCHRONOUS: 139 return "isoc"; 140 case DWC3_TRBCTL_LINK_TRB: 141 return "link"; 142 default: 143 return "UNKNOWN"; 144 } 145 } 146 147 static inline const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) 148 { 149 switch (state) { 150 case EP0_UNCONNECTED: 151 return "Unconnected"; 152 case EP0_SETUP_PHASE: 153 return "Setup Phase"; 154 case EP0_DATA_PHASE: 155 return "Data Phase"; 156 case EP0_STATUS_PHASE: 157 return "Status Phase"; 158 default: 159 return "UNKNOWN"; 160 } 161 } 162 163 /** 164 * dwc3_gadget_event_string - returns event name 165 * @event: the event code 166 */ 167 static inline const char * 168 dwc3_gadget_event_string(char *str, const struct dwc3_event_devt *event) 169 { 170 enum dwc3_link_state state = event->event_info & DWC3_LINK_STATE_MASK; 171 172 switch (event->type) { 173 case DWC3_DEVICE_EVENT_DISCONNECT: 174 sprintf(str, "Disconnect: [%s]", 175 dwc3_gadget_link_string(state)); 176 break; 177 case DWC3_DEVICE_EVENT_RESET: 178 sprintf(str, "Reset [%s]", dwc3_gadget_link_string(state)); 179 break; 180 case DWC3_DEVICE_EVENT_CONNECT_DONE: 181 sprintf(str, "Connection Done [%s]", 182 dwc3_gadget_link_string(state)); 183 break; 184 case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: 185 sprintf(str, "Link Change [%s]", 186 dwc3_gadget_link_string(state)); 187 break; 188 case DWC3_DEVICE_EVENT_WAKEUP: 189 sprintf(str, "WakeUp [%s]", dwc3_gadget_link_string(state)); 190 break; 191 case DWC3_DEVICE_EVENT_EOPF: 192 sprintf(str, "End-Of-Frame [%s]", 193 dwc3_gadget_link_string(state)); 194 break; 195 case DWC3_DEVICE_EVENT_SOF: 196 sprintf(str, "Start-Of-Frame [%s]", 197 dwc3_gadget_link_string(state)); 198 break; 199 case DWC3_DEVICE_EVENT_ERRATIC_ERROR: 200 sprintf(str, "Erratic Error [%s]", 201 dwc3_gadget_link_string(state)); 202 break; 203 case DWC3_DEVICE_EVENT_CMD_CMPL: 204 sprintf(str, "Command Complete [%s]", 205 dwc3_gadget_link_string(state)); 206 break; 207 case DWC3_DEVICE_EVENT_OVERFLOW: 208 sprintf(str, "Overflow [%s]", dwc3_gadget_link_string(state)); 209 break; 210 default: 211 sprintf(str, "UNKNOWN"); 212 } 213 214 return str; 215 } 216 217 static inline void dwc3_decode_get_status(__u8 t, __u16 i, __u16 l, char *str) 218 { 219 switch (t & USB_RECIP_MASK) { 220 case USB_RECIP_INTERFACE: 221 sprintf(str, "Get Interface Status(Intf = %d, Length = %d)", 222 i, l); 223 break; 224 case USB_RECIP_ENDPOINT: 225 sprintf(str, "Get Endpoint Status(ep%d%s)", 226 i & ~USB_DIR_IN, 227 i & USB_DIR_IN ? "in" : "out"); 228 break; 229 } 230 } 231 232 static inline void dwc3_decode_set_clear_feature(__u8 t, __u8 b, __u16 v, 233 __u16 i, char *str) 234 { 235 switch (t & USB_RECIP_MASK) { 236 case USB_RECIP_DEVICE: 237 sprintf(str, "%s Device Feature(%s%s)", 238 b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set", 239 ({char *s; 240 switch (v) { 241 case USB_DEVICE_SELF_POWERED: 242 s = "Self Powered"; 243 break; 244 case USB_DEVICE_REMOTE_WAKEUP: 245 s = "Remote Wakeup"; 246 break; 247 case USB_DEVICE_TEST_MODE: 248 s = "Test Mode"; 249 break; 250 default: 251 s = "UNKNOWN"; 252 } s; }), 253 v == USB_DEVICE_TEST_MODE ? 254 ({ char *s; 255 switch (i) { 256 case TEST_J: 257 s = ": TEST_J"; 258 break; 259 case TEST_K: 260 s = ": TEST_K"; 261 break; 262 case TEST_SE0_NAK: 263 s = ": TEST_SE0_NAK"; 264 break; 265 case TEST_PACKET: 266 s = ": TEST_PACKET"; 267 break; 268 case TEST_FORCE_EN: 269 s = ": TEST_FORCE_EN"; 270 break; 271 default: 272 s = ": UNKNOWN"; 273 } s; }) : ""); 274 break; 275 case USB_RECIP_INTERFACE: 276 sprintf(str, "%s Interface Feature(%s)", 277 b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set", 278 v == USB_INTRF_FUNC_SUSPEND ? 279 "Function Suspend" : "UNKNOWN"); 280 break; 281 case USB_RECIP_ENDPOINT: 282 sprintf(str, "%s Endpoint Feature(%s ep%d%s)", 283 b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set", 284 v == USB_ENDPOINT_HALT ? "Halt" : "UNKNOWN", 285 i & ~USB_DIR_IN, 286 i & USB_DIR_IN ? "in" : "out"); 287 break; 288 } 289 } 290 291 static inline void dwc3_decode_set_address(__u16 v, char *str) 292 { 293 sprintf(str, "Set Address(Addr = %02x)", v); 294 } 295 296 static inline void dwc3_decode_get_set_descriptor(__u8 t, __u8 b, __u16 v, 297 __u16 i, __u16 l, char *str) 298 { 299 sprintf(str, "%s %s Descriptor(Index = %d, Length = %d)", 300 b == USB_REQ_GET_DESCRIPTOR ? "Get" : "Set", 301 ({ char *s; 302 switch (v >> 8) { 303 case USB_DT_DEVICE: 304 s = "Device"; 305 break; 306 case USB_DT_CONFIG: 307 s = "Configuration"; 308 break; 309 case USB_DT_STRING: 310 s = "String"; 311 break; 312 case USB_DT_INTERFACE: 313 s = "Interface"; 314 break; 315 case USB_DT_ENDPOINT: 316 s = "Endpoint"; 317 break; 318 case USB_DT_DEVICE_QUALIFIER: 319 s = "Device Qualifier"; 320 break; 321 case USB_DT_OTHER_SPEED_CONFIG: 322 s = "Other Speed Config"; 323 break; 324 case USB_DT_INTERFACE_POWER: 325 s = "Interface Power"; 326 break; 327 case USB_DT_OTG: 328 s = "OTG"; 329 break; 330 case USB_DT_DEBUG: 331 s = "Debug"; 332 break; 333 case USB_DT_INTERFACE_ASSOCIATION: 334 s = "Interface Association"; 335 break; 336 case USB_DT_BOS: 337 s = "BOS"; 338 break; 339 case USB_DT_DEVICE_CAPABILITY: 340 s = "Device Capability"; 341 break; 342 case USB_DT_PIPE_USAGE: 343 s = "Pipe Usage"; 344 break; 345 case USB_DT_SS_ENDPOINT_COMP: 346 s = "SS Endpoint Companion"; 347 break; 348 case USB_DT_SSP_ISOC_ENDPOINT_COMP: 349 s = "SSP Isochronous Endpoint Companion"; 350 break; 351 default: 352 s = "UNKNOWN"; 353 break; 354 } s; }), v & 0xff, l); 355 } 356 357 358 static inline void dwc3_decode_get_configuration(__u16 l, char *str) 359 { 360 sprintf(str, "Get Configuration(Length = %d)", l); 361 } 362 363 static inline void dwc3_decode_set_configuration(__u8 v, char *str) 364 { 365 sprintf(str, "Set Configuration(Config = %d)", v); 366 } 367 368 static inline void dwc3_decode_get_intf(__u16 i, __u16 l, char *str) 369 { 370 sprintf(str, "Get Interface(Intf = %d, Length = %d)", i, l); 371 } 372 373 static inline void dwc3_decode_set_intf(__u8 v, __u16 i, char *str) 374 { 375 sprintf(str, "Set Interface(Intf = %d, Alt.Setting = %d)", i, v); 376 } 377 378 static inline void dwc3_decode_synch_frame(__u16 i, __u16 l, char *str) 379 { 380 sprintf(str, "Synch Frame(Endpoint = %d, Length = %d)", i, l); 381 } 382 383 static inline void dwc3_decode_set_sel(__u16 l, char *str) 384 { 385 sprintf(str, "Set SEL(Length = %d)", l); 386 } 387 388 static inline void dwc3_decode_set_isoch_delay(__u8 v, char *str) 389 { 390 sprintf(str, "Set Isochronous Delay(Delay = %d ns)", v); 391 } 392 393 /** 394 * dwc3_decode_ctrl - returns a string represetion of ctrl request 395 */ 396 static inline const char *dwc3_decode_ctrl(char *str, __u8 bRequestType, 397 __u8 bRequest, __u16 wValue, __u16 wIndex, __u16 wLength) 398 { 399 switch (bRequest) { 400 case USB_REQ_GET_STATUS: 401 dwc3_decode_get_status(bRequestType, wIndex, wLength, str); 402 break; 403 case USB_REQ_CLEAR_FEATURE: 404 case USB_REQ_SET_FEATURE: 405 dwc3_decode_set_clear_feature(bRequestType, bRequest, wValue, 406 wIndex, str); 407 break; 408 case USB_REQ_SET_ADDRESS: 409 dwc3_decode_set_address(wValue, str); 410 break; 411 case USB_REQ_GET_DESCRIPTOR: 412 case USB_REQ_SET_DESCRIPTOR: 413 dwc3_decode_get_set_descriptor(bRequestType, bRequest, wValue, 414 wIndex, wLength, str); 415 break; 416 case USB_REQ_GET_CONFIGURATION: 417 dwc3_decode_get_configuration(wLength, str); 418 break; 419 case USB_REQ_SET_CONFIGURATION: 420 dwc3_decode_set_configuration(wValue, str); 421 break; 422 case USB_REQ_GET_INTERFACE: 423 dwc3_decode_get_intf(wIndex, wLength, str); 424 break; 425 case USB_REQ_SET_INTERFACE: 426 dwc3_decode_set_intf(wValue, wIndex, str); 427 break; 428 case USB_REQ_SYNCH_FRAME: 429 dwc3_decode_synch_frame(wIndex, wLength, str); 430 break; 431 case USB_REQ_SET_SEL: 432 dwc3_decode_set_sel(wLength, str); 433 break; 434 case USB_REQ_SET_ISOCH_DELAY: 435 dwc3_decode_set_isoch_delay(wValue, str); 436 break; 437 default: 438 sprintf(str, "%02x %02x %02x %02x %02x %02x %02x %02x", 439 bRequestType, bRequest, 440 cpu_to_le16(wValue) & 0xff, 441 cpu_to_le16(wValue) >> 8, 442 cpu_to_le16(wIndex) & 0xff, 443 cpu_to_le16(wIndex) >> 8, 444 cpu_to_le16(wLength) & 0xff, 445 cpu_to_le16(wLength) >> 8); 446 } 447 448 return str; 449 } 450 451 /** 452 * dwc3_ep_event_string - returns event name 453 * @event: then event code 454 */ 455 static inline const char * 456 dwc3_ep_event_string(char *str, const struct dwc3_event_depevt *event, 457 u32 ep0state) 458 { 459 u8 epnum = event->endpoint_number; 460 size_t len; 461 int status; 462 int ret; 463 464 ret = sprintf(str, "ep%d%s: ", epnum >> 1, 465 (epnum & 1) ? "in" : "out"); 466 if (ret < 0) 467 return "UNKNOWN"; 468 469 switch (event->endpoint_event) { 470 case DWC3_DEPEVT_XFERCOMPLETE: 471 strcat(str, "Transfer Complete"); 472 len = strlen(str); 473 474 if (epnum <= 1) 475 sprintf(str + len, " [%s]", dwc3_ep0_state_string(ep0state)); 476 break; 477 case DWC3_DEPEVT_XFERINPROGRESS: 478 strcat(str, "Transfer In-Progress"); 479 break; 480 case DWC3_DEPEVT_XFERNOTREADY: 481 strcat(str, "Transfer Not Ready"); 482 status = event->status & DEPEVT_STATUS_TRANSFER_ACTIVE; 483 strcat(str, status ? " (Active)" : " (Not Active)"); 484 485 /* Control Endpoints */ 486 if (epnum <= 1) { 487 int phase = DEPEVT_STATUS_CONTROL_PHASE(event->status); 488 489 switch (phase) { 490 case DEPEVT_STATUS_CONTROL_DATA: 491 strcat(str, " [Data Phase]"); 492 break; 493 case DEPEVT_STATUS_CONTROL_STATUS: 494 strcat(str, " [Status Phase]"); 495 } 496 } 497 break; 498 case DWC3_DEPEVT_RXTXFIFOEVT: 499 strcat(str, "FIFO"); 500 break; 501 case DWC3_DEPEVT_STREAMEVT: 502 status = event->status; 503 504 switch (status) { 505 case DEPEVT_STREAMEVT_FOUND: 506 sprintf(str + ret, " Stream %d Found", 507 event->parameters); 508 break; 509 case DEPEVT_STREAMEVT_NOTFOUND: 510 default: 511 strcat(str, " Stream Not Found"); 512 break; 513 } 514 515 break; 516 case DWC3_DEPEVT_EPCMDCMPLT: 517 strcat(str, "Endpoint Command Complete"); 518 break; 519 default: 520 sprintf(str, "UNKNOWN"); 521 } 522 523 return str; 524 } 525 526 /** 527 * dwc3_gadget_event_type_string - return event name 528 * @event: the event code 529 */ 530 static inline const char *dwc3_gadget_event_type_string(u8 event) 531 { 532 switch (event) { 533 case DWC3_DEVICE_EVENT_DISCONNECT: 534 return "Disconnect"; 535 case DWC3_DEVICE_EVENT_RESET: 536 return "Reset"; 537 case DWC3_DEVICE_EVENT_CONNECT_DONE: 538 return "Connect Done"; 539 case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: 540 return "Link Status Change"; 541 case DWC3_DEVICE_EVENT_WAKEUP: 542 return "Wake-Up"; 543 case DWC3_DEVICE_EVENT_HIBER_REQ: 544 return "Hibernation"; 545 case DWC3_DEVICE_EVENT_EOPF: 546 return "End of Periodic Frame"; 547 case DWC3_DEVICE_EVENT_SOF: 548 return "Start of Frame"; 549 case DWC3_DEVICE_EVENT_ERRATIC_ERROR: 550 return "Erratic Error"; 551 case DWC3_DEVICE_EVENT_CMD_CMPL: 552 return "Command Complete"; 553 case DWC3_DEVICE_EVENT_OVERFLOW: 554 return "Overflow"; 555 default: 556 return "UNKNOWN"; 557 } 558 } 559 560 static inline const char *dwc3_decode_event(char *str, u32 event, u32 ep0state) 561 { 562 const union dwc3_event evt = (union dwc3_event) event; 563 564 if (evt.type.is_devspec) 565 return dwc3_gadget_event_string(str, &evt.devt); 566 else 567 return dwc3_ep_event_string(str, &evt.depevt, ep0state); 568 } 569 570 static inline const char *dwc3_ep_cmd_status_string(int status) 571 { 572 switch (status) { 573 case -ETIMEDOUT: 574 return "Timed Out"; 575 case 0: 576 return "Successful"; 577 case DEPEVT_TRANSFER_NO_RESOURCE: 578 return "No Resource"; 579 case DEPEVT_TRANSFER_BUS_EXPIRY: 580 return "Bus Expiry"; 581 default: 582 return "UNKNOWN"; 583 } 584 } 585 586 static inline const char *dwc3_gadget_generic_cmd_status_string(int status) 587 { 588 switch (status) { 589 case -ETIMEDOUT: 590 return "Timed Out"; 591 case 0: 592 return "Successful"; 593 case 1: 594 return "Error"; 595 default: 596 return "UNKNOWN"; 597 } 598 } 599 600 601 #ifdef CONFIG_DEBUG_FS 602 extern void dwc3_debugfs_init(struct dwc3 *); 603 extern void dwc3_debugfs_exit(struct dwc3 *); 604 #else 605 static inline void dwc3_debugfs_init(struct dwc3 *d) 606 { } 607 static inline void dwc3_debugfs_exit(struct dwc3 *d) 608 { } 609 #endif 610 #endif /* __DWC3_DEBUG_H */ 611