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_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\n"; 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 * 197 dwc3_gadget_event_string(char *str, 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 sprintf(str, "Disconnect: [%s]", 204 dwc3_gadget_link_string(state)); 205 break; 206 case DWC3_DEVICE_EVENT_RESET: 207 sprintf(str, "Reset [%s]", dwc3_gadget_link_string(state)); 208 break; 209 case DWC3_DEVICE_EVENT_CONNECT_DONE: 210 sprintf(str, "Connection Done [%s]", 211 dwc3_gadget_link_string(state)); 212 break; 213 case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: 214 sprintf(str, "Link Change [%s]", 215 dwc3_gadget_link_string(state)); 216 break; 217 case DWC3_DEVICE_EVENT_WAKEUP: 218 sprintf(str, "WakeUp [%s]", dwc3_gadget_link_string(state)); 219 break; 220 case DWC3_DEVICE_EVENT_EOPF: 221 sprintf(str, "End-Of-Frame [%s]", 222 dwc3_gadget_link_string(state)); 223 break; 224 case DWC3_DEVICE_EVENT_SOF: 225 sprintf(str, "Start-Of-Frame [%s]", 226 dwc3_gadget_link_string(state)); 227 break; 228 case DWC3_DEVICE_EVENT_ERRATIC_ERROR: 229 sprintf(str, "Erratic Error [%s]", 230 dwc3_gadget_link_string(state)); 231 break; 232 case DWC3_DEVICE_EVENT_CMD_CMPL: 233 sprintf(str, "Command Complete [%s]", 234 dwc3_gadget_link_string(state)); 235 break; 236 case DWC3_DEVICE_EVENT_OVERFLOW: 237 sprintf(str, "Overflow [%s]", dwc3_gadget_link_string(state)); 238 break; 239 default: 240 sprintf(str, "UNKNOWN"); 241 } 242 243 return str; 244 } 245 246 static inline void dwc3_decode_get_status(__u8 t, __u16 i, __u16 l, char *str) 247 { 248 switch (t & USB_RECIP_MASK) { 249 case USB_RECIP_INTERFACE: 250 sprintf(str, "Get Interface Status(Intf = %d, Length = %d)", 251 i, l); 252 break; 253 case USB_RECIP_ENDPOINT: 254 sprintf(str, "Get Endpoint Status(ep%d%s)", 255 i & ~USB_DIR_IN, 256 i & USB_DIR_IN ? "in" : "out"); 257 break; 258 } 259 } 260 261 static inline void dwc3_decode_set_clear_feature(__u8 t, __u8 b, __u16 v, 262 __u16 i, char *str) 263 { 264 switch (t & USB_RECIP_MASK) { 265 case USB_RECIP_DEVICE: 266 sprintf(str, "%s Device Feature(%s%s)", 267 b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set", 268 ({char *s; 269 switch (v) { 270 case USB_DEVICE_SELF_POWERED: 271 s = "Self Powered"; 272 break; 273 case USB_DEVICE_REMOTE_WAKEUP: 274 s = "Remote Wakeup"; 275 break; 276 case USB_DEVICE_TEST_MODE: 277 s = "Test Mode"; 278 break; 279 case USB_DEVICE_U1_ENABLE: 280 s = "U1 Enable"; 281 break; 282 case USB_DEVICE_U2_ENABLE: 283 s = "U2 Enable"; 284 break; 285 case USB_DEVICE_LTM_ENABLE: 286 s = "LTM Enable"; 287 break; 288 default: 289 s = "UNKNOWN"; 290 } s; }), 291 v == USB_DEVICE_TEST_MODE ? 292 ({ char *s; 293 switch (i) { 294 case TEST_J: 295 s = ": TEST_J"; 296 break; 297 case TEST_K: 298 s = ": TEST_K"; 299 break; 300 case TEST_SE0_NAK: 301 s = ": TEST_SE0_NAK"; 302 break; 303 case TEST_PACKET: 304 s = ": TEST_PACKET"; 305 break; 306 case TEST_FORCE_EN: 307 s = ": TEST_FORCE_EN"; 308 break; 309 default: 310 s = ": UNKNOWN"; 311 } s; }) : ""); 312 break; 313 case USB_RECIP_INTERFACE: 314 sprintf(str, "%s Interface Feature(%s)", 315 b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set", 316 v == USB_INTRF_FUNC_SUSPEND ? 317 "Function Suspend" : "UNKNOWN"); 318 break; 319 case USB_RECIP_ENDPOINT: 320 sprintf(str, "%s Endpoint Feature(%s ep%d%s)", 321 b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set", 322 v == USB_ENDPOINT_HALT ? "Halt" : "UNKNOWN", 323 i & ~USB_DIR_IN, 324 i & USB_DIR_IN ? "in" : "out"); 325 break; 326 } 327 } 328 329 static inline void dwc3_decode_set_address(__u16 v, char *str) 330 { 331 sprintf(str, "Set Address(Addr = %02x)", v); 332 } 333 334 static inline void dwc3_decode_get_set_descriptor(__u8 t, __u8 b, __u16 v, 335 __u16 i, __u16 l, char *str) 336 { 337 sprintf(str, "%s %s Descriptor(Index = %d, Length = %d)", 338 b == USB_REQ_GET_DESCRIPTOR ? "Get" : "Set", 339 ({ char *s; 340 switch (v >> 8) { 341 case USB_DT_DEVICE: 342 s = "Device"; 343 break; 344 case USB_DT_CONFIG: 345 s = "Configuration"; 346 break; 347 case USB_DT_STRING: 348 s = "String"; 349 break; 350 case USB_DT_INTERFACE: 351 s = "Interface"; 352 break; 353 case USB_DT_ENDPOINT: 354 s = "Endpoint"; 355 break; 356 case USB_DT_DEVICE_QUALIFIER: 357 s = "Device Qualifier"; 358 break; 359 case USB_DT_OTHER_SPEED_CONFIG: 360 s = "Other Speed Config"; 361 break; 362 case USB_DT_INTERFACE_POWER: 363 s = "Interface Power"; 364 break; 365 case USB_DT_OTG: 366 s = "OTG"; 367 break; 368 case USB_DT_DEBUG: 369 s = "Debug"; 370 break; 371 case USB_DT_INTERFACE_ASSOCIATION: 372 s = "Interface Association"; 373 break; 374 case USB_DT_BOS: 375 s = "BOS"; 376 break; 377 case USB_DT_DEVICE_CAPABILITY: 378 s = "Device Capability"; 379 break; 380 case USB_DT_PIPE_USAGE: 381 s = "Pipe Usage"; 382 break; 383 case USB_DT_SS_ENDPOINT_COMP: 384 s = "SS Endpoint Companion"; 385 break; 386 case USB_DT_SSP_ISOC_ENDPOINT_COMP: 387 s = "SSP Isochronous Endpoint Companion"; 388 break; 389 default: 390 s = "UNKNOWN"; 391 break; 392 } s; }), v & 0xff, l); 393 } 394 395 396 static inline void dwc3_decode_get_configuration(__u16 l, char *str) 397 { 398 sprintf(str, "Get Configuration(Length = %d)", l); 399 } 400 401 static inline void dwc3_decode_set_configuration(__u8 v, char *str) 402 { 403 sprintf(str, "Set Configuration(Config = %d)", v); 404 } 405 406 static inline void dwc3_decode_get_intf(__u16 i, __u16 l, char *str) 407 { 408 sprintf(str, "Get Interface(Intf = %d, Length = %d)", i, l); 409 } 410 411 static inline void dwc3_decode_set_intf(__u8 v, __u16 i, char *str) 412 { 413 sprintf(str, "Set Interface(Intf = %d, Alt.Setting = %d)", i, v); 414 } 415 416 static inline void dwc3_decode_synch_frame(__u16 i, __u16 l, char *str) 417 { 418 sprintf(str, "Synch Frame(Endpoint = %d, Length = %d)", i, l); 419 } 420 421 static inline void dwc3_decode_set_sel(__u16 l, char *str) 422 { 423 sprintf(str, "Set SEL(Length = %d)", l); 424 } 425 426 static inline void dwc3_decode_set_isoch_delay(__u8 v, char *str) 427 { 428 sprintf(str, "Set Isochronous Delay(Delay = %d ns)", v); 429 } 430 431 /** 432 * dwc3_decode_ctrl - returns a string represetion of ctrl request 433 */ 434 static inline const char *dwc3_decode_ctrl(char *str, __u8 bRequestType, 435 __u8 bRequest, __u16 wValue, __u16 wIndex, __u16 wLength) 436 { 437 switch (bRequest) { 438 case USB_REQ_GET_STATUS: 439 dwc3_decode_get_status(bRequestType, wIndex, wLength, str); 440 break; 441 case USB_REQ_CLEAR_FEATURE: 442 case USB_REQ_SET_FEATURE: 443 dwc3_decode_set_clear_feature(bRequestType, bRequest, wValue, 444 wIndex, str); 445 break; 446 case USB_REQ_SET_ADDRESS: 447 dwc3_decode_set_address(wValue, str); 448 break; 449 case USB_REQ_GET_DESCRIPTOR: 450 case USB_REQ_SET_DESCRIPTOR: 451 dwc3_decode_get_set_descriptor(bRequestType, bRequest, wValue, 452 wIndex, wLength, str); 453 break; 454 case USB_REQ_GET_CONFIGURATION: 455 dwc3_decode_get_configuration(wLength, str); 456 break; 457 case USB_REQ_SET_CONFIGURATION: 458 dwc3_decode_set_configuration(wValue, str); 459 break; 460 case USB_REQ_GET_INTERFACE: 461 dwc3_decode_get_intf(wIndex, wLength, str); 462 break; 463 case USB_REQ_SET_INTERFACE: 464 dwc3_decode_set_intf(wValue, wIndex, str); 465 break; 466 case USB_REQ_SYNCH_FRAME: 467 dwc3_decode_synch_frame(wIndex, wLength, str); 468 break; 469 case USB_REQ_SET_SEL: 470 dwc3_decode_set_sel(wLength, str); 471 break; 472 case USB_REQ_SET_ISOCH_DELAY: 473 dwc3_decode_set_isoch_delay(wValue, str); 474 break; 475 default: 476 sprintf(str, "%02x %02x %02x %02x %02x %02x %02x %02x", 477 bRequestType, bRequest, 478 cpu_to_le16(wValue) & 0xff, 479 cpu_to_le16(wValue) >> 8, 480 cpu_to_le16(wIndex) & 0xff, 481 cpu_to_le16(wIndex) >> 8, 482 cpu_to_le16(wLength) & 0xff, 483 cpu_to_le16(wLength) >> 8); 484 } 485 486 return str; 487 } 488 489 /** 490 * dwc3_ep_event_string - returns event name 491 * @event: then event code 492 */ 493 static inline const char * 494 dwc3_ep_event_string(char *str, const struct dwc3_event_depevt *event, 495 u32 ep0state) 496 { 497 u8 epnum = event->endpoint_number; 498 size_t len; 499 int status; 500 int ret; 501 502 ret = sprintf(str, "ep%d%s: ", epnum >> 1, 503 (epnum & 1) ? "in" : "out"); 504 if (ret < 0) 505 return "UNKNOWN"; 506 507 status = event->status; 508 509 switch (event->endpoint_event) { 510 case DWC3_DEPEVT_XFERCOMPLETE: 511 len = strlen(str); 512 sprintf(str + len, "Transfer Complete (%c%c%c)", 513 status & DEPEVT_STATUS_SHORT ? 'S' : 's', 514 status & DEPEVT_STATUS_IOC ? 'I' : 'i', 515 status & DEPEVT_STATUS_LST ? 'L' : 'l'); 516 517 len = strlen(str); 518 519 if (epnum <= 1) 520 sprintf(str + len, " [%s]", dwc3_ep0_state_string(ep0state)); 521 break; 522 case DWC3_DEPEVT_XFERINPROGRESS: 523 len = strlen(str); 524 525 sprintf(str + len, "Transfer In Progress [%d] (%c%c%c)", 526 event->parameters, 527 status & DEPEVT_STATUS_SHORT ? 'S' : 's', 528 status & DEPEVT_STATUS_IOC ? 'I' : 'i', 529 status & DEPEVT_STATUS_LST ? 'M' : 'm'); 530 break; 531 case DWC3_DEPEVT_XFERNOTREADY: 532 len = strlen(str); 533 534 sprintf(str + len, "Transfer Not Ready [%d]%s", 535 event->parameters, 536 status & DEPEVT_STATUS_TRANSFER_ACTIVE ? 537 " (Active)" : " (Not Active)"); 538 539 /* Control Endpoints */ 540 if (epnum <= 1) { 541 int phase = DEPEVT_STATUS_CONTROL_PHASE(event->status); 542 543 switch (phase) { 544 case DEPEVT_STATUS_CONTROL_DATA: 545 strcat(str, " [Data Phase]"); 546 break; 547 case DEPEVT_STATUS_CONTROL_STATUS: 548 strcat(str, " [Status Phase]"); 549 } 550 } 551 break; 552 case DWC3_DEPEVT_RXTXFIFOEVT: 553 strcat(str, "FIFO"); 554 break; 555 case DWC3_DEPEVT_STREAMEVT: 556 status = event->status; 557 558 switch (status) { 559 case DEPEVT_STREAMEVT_FOUND: 560 sprintf(str + ret, " Stream %d Found", 561 event->parameters); 562 break; 563 case DEPEVT_STREAMEVT_NOTFOUND: 564 default: 565 strcat(str, " Stream Not Found"); 566 break; 567 } 568 569 break; 570 case DWC3_DEPEVT_EPCMDCMPLT: 571 strcat(str, "Endpoint Command Complete"); 572 break; 573 default: 574 sprintf(str, "UNKNOWN"); 575 } 576 577 return str; 578 } 579 580 /** 581 * dwc3_gadget_event_type_string - return event name 582 * @event: the event code 583 */ 584 static inline const char *dwc3_gadget_event_type_string(u8 event) 585 { 586 switch (event) { 587 case DWC3_DEVICE_EVENT_DISCONNECT: 588 return "Disconnect"; 589 case DWC3_DEVICE_EVENT_RESET: 590 return "Reset"; 591 case DWC3_DEVICE_EVENT_CONNECT_DONE: 592 return "Connect Done"; 593 case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: 594 return "Link Status Change"; 595 case DWC3_DEVICE_EVENT_WAKEUP: 596 return "Wake-Up"; 597 case DWC3_DEVICE_EVENT_HIBER_REQ: 598 return "Hibernation"; 599 case DWC3_DEVICE_EVENT_EOPF: 600 return "End of Periodic Frame"; 601 case DWC3_DEVICE_EVENT_SOF: 602 return "Start of Frame"; 603 case DWC3_DEVICE_EVENT_ERRATIC_ERROR: 604 return "Erratic Error"; 605 case DWC3_DEVICE_EVENT_CMD_CMPL: 606 return "Command Complete"; 607 case DWC3_DEVICE_EVENT_OVERFLOW: 608 return "Overflow"; 609 default: 610 return "UNKNOWN"; 611 } 612 } 613 614 static inline const char *dwc3_decode_event(char *str, u32 event, u32 ep0state) 615 { 616 const union dwc3_event evt = (union dwc3_event) event; 617 618 if (evt.type.is_devspec) 619 return dwc3_gadget_event_string(str, &evt.devt); 620 else 621 return dwc3_ep_event_string(str, &evt.depevt, ep0state); 622 } 623 624 static inline const char *dwc3_ep_cmd_status_string(int status) 625 { 626 switch (status) { 627 case -ETIMEDOUT: 628 return "Timed Out"; 629 case 0: 630 return "Successful"; 631 case DEPEVT_TRANSFER_NO_RESOURCE: 632 return "No Resource"; 633 case DEPEVT_TRANSFER_BUS_EXPIRY: 634 return "Bus Expiry"; 635 default: 636 return "UNKNOWN"; 637 } 638 } 639 640 static inline const char *dwc3_gadget_generic_cmd_status_string(int status) 641 { 642 switch (status) { 643 case -ETIMEDOUT: 644 return "Timed Out"; 645 case 0: 646 return "Successful"; 647 case 1: 648 return "Error"; 649 default: 650 return "UNKNOWN"; 651 } 652 } 653 654 655 #ifdef CONFIG_DEBUG_FS 656 extern void dwc3_debugfs_init(struct dwc3 *); 657 extern void dwc3_debugfs_exit(struct dwc3 *); 658 #else 659 static inline void dwc3_debugfs_init(struct dwc3 *d) 660 { } 661 static inline void dwc3_debugfs_exit(struct dwc3 *d) 662 { } 663 #endif 664 #endif /* __DWC3_DEBUG_H */ 665