1 /** 2 * debug.h - DesignWare USB3 DRD Controller Debug Header 3 * 4 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com 5 * 6 * Authors: Felipe Balbi <balbi@ti.com>, 7 * Sebastian Andrzej Siewior <bigeasy@linutronix.de> 8 * 9 * This program is free software: you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 of 11 * the License as published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 */ 18 19 #ifndef __DWC3_DEBUG_H 20 #define __DWC3_DEBUG_H 21 22 #include "core.h" 23 24 /** 25 * dwc3_gadget_ep_cmd_string - returns endpoint command string 26 * @cmd: command code 27 */ 28 static inline const char * 29 dwc3_gadget_ep_cmd_string(u8 cmd) 30 { 31 switch (cmd) { 32 case DWC3_DEPCMD_DEPSTARTCFG: 33 return "Start New Configuration"; 34 case DWC3_DEPCMD_ENDTRANSFER: 35 return "End Transfer"; 36 case DWC3_DEPCMD_UPDATETRANSFER: 37 return "Update Transfer"; 38 case DWC3_DEPCMD_STARTTRANSFER: 39 return "Start Transfer"; 40 case DWC3_DEPCMD_CLEARSTALL: 41 return "Clear Stall"; 42 case DWC3_DEPCMD_SETSTALL: 43 return "Set Stall"; 44 case DWC3_DEPCMD_GETEPSTATE: 45 return "Get Endpoint State"; 46 case DWC3_DEPCMD_SETTRANSFRESOURCE: 47 return "Set Endpoint Transfer Resource"; 48 case DWC3_DEPCMD_SETEPCONFIG: 49 return "Set Endpoint Configuration"; 50 default: 51 return "UNKNOWN command"; 52 } 53 } 54 55 /** 56 * dwc3_gadget_generic_cmd_string - returns generic command string 57 * @cmd: command code 58 */ 59 static inline const char * 60 dwc3_gadget_generic_cmd_string(u8 cmd) 61 { 62 switch (cmd) { 63 case DWC3_DGCMD_SET_LMP: 64 return "Set LMP"; 65 case DWC3_DGCMD_SET_PERIODIC_PAR: 66 return "Set Periodic Parameters"; 67 case DWC3_DGCMD_XMIT_FUNCTION: 68 return "Transmit Function Wake Device Notification"; 69 case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_LO: 70 return "Set Scratchpad Buffer Array Address Lo"; 71 case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_HI: 72 return "Set Scratchpad Buffer Array Address Hi"; 73 case DWC3_DGCMD_SELECTED_FIFO_FLUSH: 74 return "Selected FIFO Flush"; 75 case DWC3_DGCMD_ALL_FIFO_FLUSH: 76 return "All FIFO Flush"; 77 case DWC3_DGCMD_SET_ENDPOINT_NRDY: 78 return "Set Endpoint NRDY"; 79 case DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK: 80 return "Run SoC Bus Loopback Test"; 81 default: 82 return "UNKNOWN"; 83 } 84 } 85 86 /** 87 * dwc3_gadget_link_string - returns link name 88 * @link_state: link state code 89 */ 90 static inline const char * 91 dwc3_gadget_link_string(enum dwc3_link_state link_state) 92 { 93 switch (link_state) { 94 case DWC3_LINK_STATE_U0: 95 return "U0"; 96 case DWC3_LINK_STATE_U1: 97 return "U1"; 98 case DWC3_LINK_STATE_U2: 99 return "U2"; 100 case DWC3_LINK_STATE_U3: 101 return "U3"; 102 case DWC3_LINK_STATE_SS_DIS: 103 return "SS.Disabled"; 104 case DWC3_LINK_STATE_RX_DET: 105 return "RX.Detect"; 106 case DWC3_LINK_STATE_SS_INACT: 107 return "SS.Inactive"; 108 case DWC3_LINK_STATE_POLL: 109 return "Polling"; 110 case DWC3_LINK_STATE_RECOV: 111 return "Recovery"; 112 case DWC3_LINK_STATE_HRESET: 113 return "Hot Reset"; 114 case DWC3_LINK_STATE_CMPLY: 115 return "Compliance"; 116 case DWC3_LINK_STATE_LPBK: 117 return "Loopback"; 118 case DWC3_LINK_STATE_RESET: 119 return "Reset"; 120 case DWC3_LINK_STATE_RESUME: 121 return "Resume"; 122 default: 123 return "UNKNOWN link state\n"; 124 } 125 } 126 127 /** 128 * dwc3_trb_type_string - returns TRB type as a string 129 * @type: the type of the TRB 130 */ 131 static inline const char *dwc3_trb_type_string(unsigned int type) 132 { 133 switch (type) { 134 case DWC3_TRBCTL_NORMAL: 135 return "normal"; 136 case DWC3_TRBCTL_CONTROL_SETUP: 137 return "setup"; 138 case DWC3_TRBCTL_CONTROL_STATUS2: 139 return "status2"; 140 case DWC3_TRBCTL_CONTROL_STATUS3: 141 return "status3"; 142 case DWC3_TRBCTL_CONTROL_DATA: 143 return "data"; 144 case DWC3_TRBCTL_ISOCHRONOUS_FIRST: 145 return "isoc-first"; 146 case DWC3_TRBCTL_ISOCHRONOUS: 147 return "isoc"; 148 case DWC3_TRBCTL_LINK_TRB: 149 return "link"; 150 default: 151 return "UNKNOWN"; 152 } 153 } 154 155 static inline const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) 156 { 157 switch (state) { 158 case EP0_UNCONNECTED: 159 return "Unconnected"; 160 case EP0_SETUP_PHASE: 161 return "Setup Phase"; 162 case EP0_DATA_PHASE: 163 return "Data Phase"; 164 case EP0_STATUS_PHASE: 165 return "Status Phase"; 166 default: 167 return "UNKNOWN"; 168 } 169 } 170 171 /** 172 * dwc3_gadget_event_string - returns event name 173 * @event: the event code 174 */ 175 static inline const char * 176 dwc3_gadget_event_string(char *str, const struct dwc3_event_devt *event) 177 { 178 enum dwc3_link_state state = event->event_info & DWC3_LINK_STATE_MASK; 179 180 switch (event->type) { 181 case DWC3_DEVICE_EVENT_DISCONNECT: 182 sprintf(str, "Disconnect: [%s]", 183 dwc3_gadget_link_string(state)); 184 break; 185 case DWC3_DEVICE_EVENT_RESET: 186 sprintf(str, "Reset [%s]", dwc3_gadget_link_string(state)); 187 break; 188 case DWC3_DEVICE_EVENT_CONNECT_DONE: 189 sprintf(str, "Connection Done [%s]", 190 dwc3_gadget_link_string(state)); 191 break; 192 case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: 193 sprintf(str, "Link Change [%s]", 194 dwc3_gadget_link_string(state)); 195 break; 196 case DWC3_DEVICE_EVENT_WAKEUP: 197 sprintf(str, "WakeUp [%s]", dwc3_gadget_link_string(state)); 198 break; 199 case DWC3_DEVICE_EVENT_EOPF: 200 sprintf(str, "End-Of-Frame [%s]", 201 dwc3_gadget_link_string(state)); 202 break; 203 case DWC3_DEVICE_EVENT_SOF: 204 sprintf(str, "Start-Of-Frame [%s]", 205 dwc3_gadget_link_string(state)); 206 break; 207 case DWC3_DEVICE_EVENT_ERRATIC_ERROR: 208 sprintf(str, "Erratic Error [%s]", 209 dwc3_gadget_link_string(state)); 210 break; 211 case DWC3_DEVICE_EVENT_CMD_CMPL: 212 sprintf(str, "Command Complete [%s]", 213 dwc3_gadget_link_string(state)); 214 break; 215 case DWC3_DEVICE_EVENT_OVERFLOW: 216 sprintf(str, "Overflow [%s]", dwc3_gadget_link_string(state)); 217 break; 218 default: 219 sprintf(str, "UNKNOWN"); 220 } 221 222 return str; 223 } 224 225 static inline void dwc3_decode_get_status(__u8 t, __u16 i, __u16 l, char *str) 226 { 227 switch (t & USB_RECIP_MASK) { 228 case USB_RECIP_INTERFACE: 229 sprintf(str, "Get Interface Status(Intf = %d, Length = %d)", 230 i, l); 231 break; 232 case USB_RECIP_ENDPOINT: 233 sprintf(str, "Get Endpoint Status(ep%d%s)", 234 i & ~USB_DIR_IN, 235 i & USB_DIR_IN ? "in" : "out"); 236 break; 237 } 238 } 239 240 static inline void dwc3_decode_set_clear_feature(__u8 t, __u8 b, __u16 v, 241 __u16 i, char *str) 242 { 243 switch (t & USB_RECIP_MASK) { 244 case USB_RECIP_DEVICE: 245 sprintf(str, "%s Device Feature(%s%s)", 246 b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set", 247 ({char *s; 248 switch (v) { 249 case USB_DEVICE_SELF_POWERED: 250 s = "Self Powered"; 251 break; 252 case USB_DEVICE_REMOTE_WAKEUP: 253 s = "Remote Wakeup"; 254 break; 255 case USB_DEVICE_TEST_MODE: 256 s = "Test Mode"; 257 break; 258 default: 259 s = "UNKNOWN"; 260 } s; }), 261 v == USB_DEVICE_TEST_MODE ? 262 ({ char *s; 263 switch (i) { 264 case TEST_J: 265 s = ": TEST_J"; 266 break; 267 case TEST_K: 268 s = ": TEST_K"; 269 break; 270 case TEST_SE0_NAK: 271 s = ": TEST_SE0_NAK"; 272 break; 273 case TEST_PACKET: 274 s = ": TEST_PACKET"; 275 break; 276 case TEST_FORCE_EN: 277 s = ": TEST_FORCE_EN"; 278 break; 279 default: 280 s = ": UNKNOWN"; 281 } s; }) : ""); 282 break; 283 case USB_RECIP_INTERFACE: 284 sprintf(str, "%s Interface Feature(%s)", 285 b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set", 286 v == USB_INTRF_FUNC_SUSPEND ? 287 "Function Suspend" : "UNKNOWN"); 288 break; 289 case USB_RECIP_ENDPOINT: 290 sprintf(str, "%s Endpoint Feature(%s ep%d%s)", 291 b == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set", 292 v == USB_ENDPOINT_HALT ? "Halt" : "UNKNOWN", 293 i & ~USB_DIR_IN, 294 i & USB_DIR_IN ? "in" : "out"); 295 break; 296 } 297 } 298 299 static inline void dwc3_decode_set_address(__u16 v, char *str) 300 { 301 sprintf(str, "Set Address(Addr = %02x)", v); 302 } 303 304 static inline void dwc3_decode_get_set_descriptor(__u8 t, __u8 b, __u16 v, 305 __u16 i, __u16 l, char *str) 306 { 307 sprintf(str, "%s %s Descriptor(Index = %d, Length = %d)", 308 b == USB_REQ_GET_DESCRIPTOR ? "Get" : "Set", 309 ({ char *s; 310 switch (v >> 8) { 311 case USB_DT_DEVICE: 312 s = "Device"; 313 break; 314 case USB_DT_CONFIG: 315 s = "Configuration"; 316 break; 317 case USB_DT_STRING: 318 s = "String"; 319 break; 320 case USB_DT_INTERFACE: 321 s = "Interface"; 322 break; 323 case USB_DT_ENDPOINT: 324 s = "Endpoint"; 325 break; 326 case USB_DT_DEVICE_QUALIFIER: 327 s = "Device Qualifier"; 328 break; 329 case USB_DT_OTHER_SPEED_CONFIG: 330 s = "Other Speed Config"; 331 break; 332 case USB_DT_INTERFACE_POWER: 333 s = "Interface Power"; 334 break; 335 case USB_DT_OTG: 336 s = "OTG"; 337 break; 338 case USB_DT_DEBUG: 339 s = "Debug"; 340 break; 341 case USB_DT_INTERFACE_ASSOCIATION: 342 s = "Interface Association"; 343 break; 344 case USB_DT_BOS: 345 s = "BOS"; 346 break; 347 case USB_DT_DEVICE_CAPABILITY: 348 s = "Device Capability"; 349 break; 350 case USB_DT_PIPE_USAGE: 351 s = "Pipe Usage"; 352 break; 353 case USB_DT_SS_ENDPOINT_COMP: 354 s = "SS Endpoint Companion"; 355 break; 356 case USB_DT_SSP_ISOC_ENDPOINT_COMP: 357 s = "SSP Isochronous Endpoint Companion"; 358 break; 359 default: 360 s = "UNKNOWN"; 361 break; 362 } s; }), v & 0xff, l); 363 } 364 365 366 static inline void dwc3_decode_get_configuration(__u16 l, char *str) 367 { 368 sprintf(str, "Get Configuration(Length = %d)", l); 369 } 370 371 static inline void dwc3_decode_set_configuration(__u8 v, char *str) 372 { 373 sprintf(str, "Set Configuration(Config = %d)", v); 374 } 375 376 static inline void dwc3_decode_get_intf(__u16 i, __u16 l, char *str) 377 { 378 sprintf(str, "Get Interface(Intf = %d, Length = %d)", i, l); 379 } 380 381 static inline void dwc3_decode_set_intf(__u8 v, __u16 i, char *str) 382 { 383 sprintf(str, "Set Interface(Intf = %d, Alt.Setting = %d)", i, v); 384 } 385 386 static inline void dwc3_decode_synch_frame(__u16 i, __u16 l, char *str) 387 { 388 sprintf(str, "Synch Frame(Endpoint = %d, Length = %d)", i, l); 389 } 390 391 static inline void dwc3_decode_set_sel(__u16 l, char *str) 392 { 393 sprintf(str, "Set SEL(Length = %d)", l); 394 } 395 396 static inline void dwc3_decode_set_isoch_delay(__u8 v, char *str) 397 { 398 sprintf(str, "Set Isochronous Delay(Delay = %d ns)", v); 399 } 400 401 /** 402 * dwc3_decode_ctrl - returns a string represetion of ctrl request 403 */ 404 static inline const char *dwc3_decode_ctrl(char *str, __u8 bRequestType, 405 __u8 bRequest, __u16 wValue, __u16 wIndex, __u16 wLength) 406 { 407 switch (bRequest) { 408 case USB_REQ_GET_STATUS: 409 dwc3_decode_get_status(bRequestType, wIndex, wLength, str); 410 break; 411 case USB_REQ_CLEAR_FEATURE: 412 case USB_REQ_SET_FEATURE: 413 dwc3_decode_set_clear_feature(bRequestType, bRequest, wValue, 414 wIndex, str); 415 break; 416 case USB_REQ_SET_ADDRESS: 417 dwc3_decode_set_address(wValue, str); 418 break; 419 case USB_REQ_GET_DESCRIPTOR: 420 case USB_REQ_SET_DESCRIPTOR: 421 dwc3_decode_get_set_descriptor(bRequestType, bRequest, wValue, 422 wIndex, wLength, str); 423 break; 424 case USB_REQ_GET_CONFIGURATION: 425 dwc3_decode_get_configuration(wLength, str); 426 break; 427 case USB_REQ_SET_CONFIGURATION: 428 dwc3_decode_set_configuration(wValue, str); 429 break; 430 case USB_REQ_GET_INTERFACE: 431 dwc3_decode_get_intf(wIndex, wLength, str); 432 break; 433 case USB_REQ_SET_INTERFACE: 434 dwc3_decode_set_intf(wValue, wIndex, str); 435 break; 436 case USB_REQ_SYNCH_FRAME: 437 dwc3_decode_synch_frame(wIndex, wLength, str); 438 break; 439 case USB_REQ_SET_SEL: 440 dwc3_decode_set_sel(wLength, str); 441 break; 442 case USB_REQ_SET_ISOCH_DELAY: 443 dwc3_decode_set_isoch_delay(wValue, str); 444 break; 445 default: 446 sprintf(str, "%02x %02x %02x %02x %02x %02x %02x %02x", 447 bRequestType, bRequest, 448 cpu_to_le16(wValue) & 0xff, 449 cpu_to_le16(wValue) >> 8, 450 cpu_to_le16(wIndex) & 0xff, 451 cpu_to_le16(wIndex) >> 8, 452 cpu_to_le16(wLength) & 0xff, 453 cpu_to_le16(wLength) >> 8); 454 } 455 456 return str; 457 } 458 459 /** 460 * dwc3_ep_event_string - returns event name 461 * @event: then event code 462 */ 463 static inline const char * 464 dwc3_ep_event_string(char *str, const struct dwc3_event_depevt *event, 465 u32 ep0state) 466 { 467 u8 epnum = event->endpoint_number; 468 size_t len; 469 int status; 470 int ret; 471 472 ret = sprintf(str, "ep%d%s: ", epnum >> 1, 473 (epnum & 1) ? "in" : "out"); 474 if (ret < 0) 475 return "UNKNOWN"; 476 477 switch (event->endpoint_event) { 478 case DWC3_DEPEVT_XFERCOMPLETE: 479 strcat(str, "Transfer Complete"); 480 len = strlen(str); 481 482 if (epnum <= 1) 483 sprintf(str + len, " [%s]", dwc3_ep0_state_string(ep0state)); 484 break; 485 case DWC3_DEPEVT_XFERINPROGRESS: 486 strcat(str, "Transfer In-Progress"); 487 break; 488 case DWC3_DEPEVT_XFERNOTREADY: 489 strcat(str, "Transfer Not Ready"); 490 status = event->status & DEPEVT_STATUS_TRANSFER_ACTIVE; 491 strcat(str, status ? " (Active)" : " (Not Active)"); 492 493 /* Control Endpoints */ 494 if (epnum <= 1) { 495 int phase = DEPEVT_STATUS_CONTROL_PHASE(event->status); 496 497 switch (phase) { 498 case DEPEVT_STATUS_CONTROL_DATA: 499 strcat(str, " [Data Phase]"); 500 break; 501 case DEPEVT_STATUS_CONTROL_STATUS: 502 strcat(str, " [Status Phase]"); 503 } 504 } 505 break; 506 case DWC3_DEPEVT_RXTXFIFOEVT: 507 strcat(str, "FIFO"); 508 break; 509 case DWC3_DEPEVT_STREAMEVT: 510 status = event->status; 511 512 switch (status) { 513 case DEPEVT_STREAMEVT_FOUND: 514 sprintf(str + ret, " Stream %d Found", 515 event->parameters); 516 break; 517 case DEPEVT_STREAMEVT_NOTFOUND: 518 default: 519 strcat(str, " Stream Not Found"); 520 break; 521 } 522 523 break; 524 case DWC3_DEPEVT_EPCMDCMPLT: 525 strcat(str, "Endpoint Command Complete"); 526 break; 527 default: 528 sprintf(str, "UNKNOWN"); 529 } 530 531 return str; 532 } 533 534 /** 535 * dwc3_gadget_event_type_string - return event name 536 * @event: the event code 537 */ 538 static inline const char *dwc3_gadget_event_type_string(u8 event) 539 { 540 switch (event) { 541 case DWC3_DEVICE_EVENT_DISCONNECT: 542 return "Disconnect"; 543 case DWC3_DEVICE_EVENT_RESET: 544 return "Reset"; 545 case DWC3_DEVICE_EVENT_CONNECT_DONE: 546 return "Connect Done"; 547 case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: 548 return "Link Status Change"; 549 case DWC3_DEVICE_EVENT_WAKEUP: 550 return "Wake-Up"; 551 case DWC3_DEVICE_EVENT_HIBER_REQ: 552 return "Hibernation"; 553 case DWC3_DEVICE_EVENT_EOPF: 554 return "End of Periodic Frame"; 555 case DWC3_DEVICE_EVENT_SOF: 556 return "Start of Frame"; 557 case DWC3_DEVICE_EVENT_ERRATIC_ERROR: 558 return "Erratic Error"; 559 case DWC3_DEVICE_EVENT_CMD_CMPL: 560 return "Command Complete"; 561 case DWC3_DEVICE_EVENT_OVERFLOW: 562 return "Overflow"; 563 default: 564 return "UNKNOWN"; 565 } 566 } 567 568 static inline const char *dwc3_decode_event(char *str, u32 event, u32 ep0state) 569 { 570 const union dwc3_event evt = (union dwc3_event) event; 571 572 if (evt.type.is_devspec) 573 return dwc3_gadget_event_string(str, &evt.devt); 574 else 575 return dwc3_ep_event_string(str, &evt.depevt, ep0state); 576 } 577 578 static inline const char *dwc3_ep_cmd_status_string(int status) 579 { 580 switch (status) { 581 case -ETIMEDOUT: 582 return "Timed Out"; 583 case 0: 584 return "Successful"; 585 case DEPEVT_TRANSFER_NO_RESOURCE: 586 return "No Resource"; 587 case DEPEVT_TRANSFER_BUS_EXPIRY: 588 return "Bus Expiry"; 589 default: 590 return "UNKNOWN"; 591 } 592 } 593 594 static inline const char *dwc3_gadget_generic_cmd_status_string(int status) 595 { 596 switch (status) { 597 case -ETIMEDOUT: 598 return "Timed Out"; 599 case 0: 600 return "Successful"; 601 case 1: 602 return "Error"; 603 default: 604 return "UNKNOWN"; 605 } 606 } 607 608 609 #ifdef CONFIG_DEBUG_FS 610 extern void dwc3_debugfs_init(struct dwc3 *); 611 extern void dwc3_debugfs_exit(struct dwc3 *); 612 #else 613 static inline void dwc3_debugfs_init(struct dwc3 *d) 614 { } 615 static inline void dwc3_debugfs_exit(struct dwc3 *d) 616 { } 617 #endif 618 #endif /* __DWC3_DEBUG_H */ 619