|  | /* SPDX-License-Identifier: GPL-2.0 */ | 
|  | /* | 
|  | * debug.h - DesignWare USB3 DRD Controller Debug Header | 
|  | * | 
|  | * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com | 
|  | * | 
|  | * Authors: Felipe Balbi <[email protected]>, | 
|  | *	    Sebastian Andrzej Siewior <[email protected]> | 
|  | */ | 
|  |  | 
|  | #ifndef __DWC3_DEBUG_H | 
|  | #define __DWC3_DEBUG_H | 
|  |  | 
|  | #include "core.h" | 
|  |  | 
|  | /** | 
|  | * dwc3_gadget_ep_cmd_string - returns endpoint command string | 
|  | * @cmd: command code | 
|  | */ | 
|  | static inline const char * | 
|  | dwc3_gadget_ep_cmd_string(u8 cmd) | 
|  | { | 
|  | switch (cmd) { | 
|  | case DWC3_DEPCMD_DEPSTARTCFG: | 
|  | return "Start New Configuration"; | 
|  | case DWC3_DEPCMD_ENDTRANSFER: | 
|  | return "End Transfer"; | 
|  | case DWC3_DEPCMD_UPDATETRANSFER: | 
|  | return "Update Transfer"; | 
|  | case DWC3_DEPCMD_STARTTRANSFER: | 
|  | return "Start Transfer"; | 
|  | case DWC3_DEPCMD_CLEARSTALL: | 
|  | return "Clear Stall"; | 
|  | case DWC3_DEPCMD_SETSTALL: | 
|  | return "Set Stall"; | 
|  | case DWC3_DEPCMD_GETEPSTATE: | 
|  | return "Get Endpoint State"; | 
|  | case DWC3_DEPCMD_SETTRANSFRESOURCE: | 
|  | return "Set Endpoint Transfer Resource"; | 
|  | case DWC3_DEPCMD_SETEPCONFIG: | 
|  | return "Set Endpoint Configuration"; | 
|  | default: | 
|  | return "UNKNOWN command"; | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * dwc3_gadget_generic_cmd_string - returns generic command string | 
|  | * @cmd: command code | 
|  | */ | 
|  | static inline const char * | 
|  | dwc3_gadget_generic_cmd_string(u8 cmd) | 
|  | { | 
|  | switch (cmd) { | 
|  | case DWC3_DGCMD_SET_LMP: | 
|  | return "Set LMP"; | 
|  | case DWC3_DGCMD_SET_PERIODIC_PAR: | 
|  | return "Set Periodic Parameters"; | 
|  | case DWC3_DGCMD_XMIT_FUNCTION: | 
|  | return "Transmit Function Wake Device Notification"; | 
|  | case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_LO: | 
|  | return "Set Scratchpad Buffer Array Address Lo"; | 
|  | case DWC3_DGCMD_SET_SCRATCHPAD_ADDR_HI: | 
|  | return "Set Scratchpad Buffer Array Address Hi"; | 
|  | case DWC3_DGCMD_SELECTED_FIFO_FLUSH: | 
|  | return "Selected FIFO Flush"; | 
|  | case DWC3_DGCMD_ALL_FIFO_FLUSH: | 
|  | return "All FIFO Flush"; | 
|  | case DWC3_DGCMD_SET_ENDPOINT_NRDY: | 
|  | return "Set Endpoint NRDY"; | 
|  | case DWC3_DGCMD_SET_ENDPOINT_PRIME: | 
|  | return "Set Endpoint Prime"; | 
|  | case DWC3_DGCMD_RUN_SOC_BUS_LOOPBACK: | 
|  | return "Run SoC Bus Loopback Test"; | 
|  | case DWC3_DGCMD_DEV_NOTIFICATION: | 
|  | return "Device Notification"; | 
|  | default: | 
|  | return "UNKNOWN"; | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * dwc3_gadget_link_string - returns link name | 
|  | * @link_state: link state code | 
|  | */ | 
|  | static inline const char * | 
|  | dwc3_gadget_link_string(enum dwc3_link_state link_state) | 
|  | { | 
|  | switch (link_state) { | 
|  | case DWC3_LINK_STATE_U0: | 
|  | return "U0"; | 
|  | case DWC3_LINK_STATE_U1: | 
|  | return "U1"; | 
|  | case DWC3_LINK_STATE_U2: | 
|  | return "U2"; | 
|  | case DWC3_LINK_STATE_U3: | 
|  | return "U3"; | 
|  | case DWC3_LINK_STATE_SS_DIS: | 
|  | return "SS.Disabled"; | 
|  | case DWC3_LINK_STATE_RX_DET: | 
|  | return "RX.Detect"; | 
|  | case DWC3_LINK_STATE_SS_INACT: | 
|  | return "SS.Inactive"; | 
|  | case DWC3_LINK_STATE_POLL: | 
|  | return "Polling"; | 
|  | case DWC3_LINK_STATE_RECOV: | 
|  | return "Recovery"; | 
|  | case DWC3_LINK_STATE_HRESET: | 
|  | return "Hot Reset"; | 
|  | case DWC3_LINK_STATE_CMPLY: | 
|  | return "Compliance"; | 
|  | case DWC3_LINK_STATE_LPBK: | 
|  | return "Loopback"; | 
|  | case DWC3_LINK_STATE_RESET: | 
|  | return "Reset"; | 
|  | case DWC3_LINK_STATE_RESUME: | 
|  | return "Resume"; | 
|  | default: | 
|  | return "UNKNOWN link state"; | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * dwc3_gadget_hs_link_string - returns highspeed and below link name | 
|  | * @link_state: link state code | 
|  | */ | 
|  | static inline const char * | 
|  | dwc3_gadget_hs_link_string(enum dwc3_link_state link_state) | 
|  | { | 
|  | switch (link_state) { | 
|  | case DWC3_LINK_STATE_U0: | 
|  | return "On"; | 
|  | case DWC3_LINK_STATE_U2: | 
|  | return "Sleep"; | 
|  | case DWC3_LINK_STATE_U3: | 
|  | return "Suspend"; | 
|  | case DWC3_LINK_STATE_SS_DIS: | 
|  | return "Disconnected"; | 
|  | case DWC3_LINK_STATE_RX_DET: | 
|  | return "Early Suspend"; | 
|  | case DWC3_LINK_STATE_RECOV: | 
|  | return "Recovery"; | 
|  | case DWC3_LINK_STATE_RESET: | 
|  | return "Reset"; | 
|  | case DWC3_LINK_STATE_RESUME: | 
|  | return "Resume"; | 
|  | default: | 
|  | return "UNKNOWN link state"; | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * dwc3_trb_type_string - returns TRB type as a string | 
|  | * @type: the type of the TRB | 
|  | */ | 
|  | static inline const char *dwc3_trb_type_string(unsigned int type) | 
|  | { | 
|  | switch (type) { | 
|  | case DWC3_TRBCTL_NORMAL: | 
|  | return "normal"; | 
|  | case DWC3_TRBCTL_CONTROL_SETUP: | 
|  | return "setup"; | 
|  | case DWC3_TRBCTL_CONTROL_STATUS2: | 
|  | return "status2"; | 
|  | case DWC3_TRBCTL_CONTROL_STATUS3: | 
|  | return "status3"; | 
|  | case DWC3_TRBCTL_CONTROL_DATA: | 
|  | return "data"; | 
|  | case DWC3_TRBCTL_ISOCHRONOUS_FIRST: | 
|  | return "isoc-first"; | 
|  | case DWC3_TRBCTL_ISOCHRONOUS: | 
|  | return "isoc"; | 
|  | case DWC3_TRBCTL_LINK_TRB: | 
|  | return "link"; | 
|  | default: | 
|  | return "UNKNOWN"; | 
|  | } | 
|  | } | 
|  |  | 
|  | static inline const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) | 
|  | { | 
|  | switch (state) { | 
|  | case EP0_UNCONNECTED: | 
|  | return "Unconnected"; | 
|  | case EP0_SETUP_PHASE: | 
|  | return "Setup Phase"; | 
|  | case EP0_DATA_PHASE: | 
|  | return "Data Phase"; | 
|  | case EP0_STATUS_PHASE: | 
|  | return "Status Phase"; | 
|  | default: | 
|  | return "UNKNOWN"; | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * dwc3_gadget_event_string - returns event name | 
|  | * @event: the event code | 
|  | */ | 
|  | static inline const char *dwc3_gadget_event_string(char *str, size_t size, | 
|  | const struct dwc3_event_devt *event) | 
|  | { | 
|  | enum dwc3_link_state state = event->event_info & DWC3_LINK_STATE_MASK; | 
|  |  | 
|  | switch (event->type) { | 
|  | case DWC3_DEVICE_EVENT_DISCONNECT: | 
|  | snprintf(str, size, "Disconnect: [%s]", | 
|  | dwc3_gadget_link_string(state)); | 
|  | break; | 
|  | case DWC3_DEVICE_EVENT_RESET: | 
|  | snprintf(str, size, "Reset [%s]", | 
|  | dwc3_gadget_link_string(state)); | 
|  | break; | 
|  | case DWC3_DEVICE_EVENT_CONNECT_DONE: | 
|  | snprintf(str, size, "Connection Done [%s]", | 
|  | dwc3_gadget_link_string(state)); | 
|  | break; | 
|  | case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: | 
|  | snprintf(str, size, "Link Change [%s]", | 
|  | dwc3_gadget_link_string(state)); | 
|  | break; | 
|  | case DWC3_DEVICE_EVENT_WAKEUP: | 
|  | snprintf(str, size, "WakeUp [%s]", | 
|  | dwc3_gadget_link_string(state)); | 
|  | break; | 
|  | case DWC3_DEVICE_EVENT_SUSPEND: | 
|  | snprintf(str, size, "Suspend [%s]", | 
|  | dwc3_gadget_link_string(state)); | 
|  | break; | 
|  | case DWC3_DEVICE_EVENT_SOF: | 
|  | snprintf(str, size, "Start-Of-Frame [%s]", | 
|  | dwc3_gadget_link_string(state)); | 
|  | break; | 
|  | case DWC3_DEVICE_EVENT_ERRATIC_ERROR: | 
|  | snprintf(str, size, "Erratic Error [%s]", | 
|  | dwc3_gadget_link_string(state)); | 
|  | break; | 
|  | case DWC3_DEVICE_EVENT_CMD_CMPL: | 
|  | snprintf(str, size, "Command Complete [%s]", | 
|  | dwc3_gadget_link_string(state)); | 
|  | break; | 
|  | case DWC3_DEVICE_EVENT_OVERFLOW: | 
|  | snprintf(str, size, "Overflow [%s]", | 
|  | dwc3_gadget_link_string(state)); | 
|  | break; | 
|  | default: | 
|  | snprintf(str, size, "UNKNOWN"); | 
|  | } | 
|  |  | 
|  | return str; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * dwc3_ep_event_string - returns event name | 
|  | * @event: then event code | 
|  | */ | 
|  | static inline const char *dwc3_ep_event_string(char *str, size_t size, | 
|  | const struct dwc3_event_depevt *event, u32 ep0state) | 
|  | { | 
|  | u8 epnum = event->endpoint_number; | 
|  | size_t len; | 
|  | int status; | 
|  |  | 
|  | len = scnprintf(str, size, "ep%d%s: ", epnum >> 1, | 
|  | (epnum & 1) ? "in" : "out"); | 
|  |  | 
|  | status = event->status; | 
|  |  | 
|  | switch (event->endpoint_event) { | 
|  | case DWC3_DEPEVT_XFERCOMPLETE: | 
|  | len += scnprintf(str + len, size - len, | 
|  | "Transfer Complete (%c%c%c)", | 
|  | status & DEPEVT_STATUS_SHORT ? 'S' : 's', | 
|  | status & DEPEVT_STATUS_IOC ? 'I' : 'i', | 
|  | status & DEPEVT_STATUS_LST ? 'L' : 'l'); | 
|  |  | 
|  | if (epnum <= 1) | 
|  | scnprintf(str + len, size - len, " [%s]", | 
|  | dwc3_ep0_state_string(ep0state)); | 
|  | break; | 
|  | case DWC3_DEPEVT_XFERINPROGRESS: | 
|  | scnprintf(str + len, size - len, | 
|  | "Transfer In Progress [%08x] (%c%c%c)", | 
|  | event->parameters, | 
|  | status & DEPEVT_STATUS_SHORT ? 'S' : 's', | 
|  | status & DEPEVT_STATUS_IOC ? 'I' : 'i', | 
|  | status & DEPEVT_STATUS_LST ? 'M' : 'm'); | 
|  | break; | 
|  | case DWC3_DEPEVT_XFERNOTREADY: | 
|  | len += scnprintf(str + len, size - len, | 
|  | "Transfer Not Ready [%08x]%s", | 
|  | event->parameters, | 
|  | status & DEPEVT_STATUS_TRANSFER_ACTIVE ? | 
|  | " (Active)" : " (Not Active)"); | 
|  |  | 
|  | /* Control Endpoints */ | 
|  | if (epnum <= 1) { | 
|  | int phase = DEPEVT_STATUS_CONTROL_PHASE(event->status); | 
|  |  | 
|  | switch (phase) { | 
|  | case DEPEVT_STATUS_CONTROL_DATA: | 
|  | scnprintf(str + len, size - len, | 
|  | " [Data Phase]"); | 
|  | break; | 
|  | case DEPEVT_STATUS_CONTROL_STATUS: | 
|  | scnprintf(str + len, size - len, | 
|  | " [Status Phase]"); | 
|  | } | 
|  | } | 
|  | break; | 
|  | case DWC3_DEPEVT_RXTXFIFOEVT: | 
|  | scnprintf(str + len, size - len, "FIFO"); | 
|  | break; | 
|  | case DWC3_DEPEVT_STREAMEVT: | 
|  | status = event->status; | 
|  |  | 
|  | switch (status) { | 
|  | case DEPEVT_STREAMEVT_FOUND: | 
|  | scnprintf(str + len, size - len, " Stream %d Found", | 
|  | event->parameters); | 
|  | break; | 
|  | case DEPEVT_STREAMEVT_NOTFOUND: | 
|  | default: | 
|  | scnprintf(str + len, size - len, " Stream Not Found"); | 
|  | break; | 
|  | } | 
|  |  | 
|  | break; | 
|  | case DWC3_DEPEVT_EPCMDCMPLT: | 
|  | scnprintf(str + len, size - len, "Endpoint Command Complete"); | 
|  | break; | 
|  | default: | 
|  | scnprintf(str + len, size - len, "UNKNOWN"); | 
|  | } | 
|  |  | 
|  | return str; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * dwc3_gadget_event_type_string - return event name | 
|  | * @event: the event code | 
|  | */ | 
|  | static inline const char *dwc3_gadget_event_type_string(u8 event) | 
|  | { | 
|  | switch (event) { | 
|  | case DWC3_DEVICE_EVENT_DISCONNECT: | 
|  | return "Disconnect"; | 
|  | case DWC3_DEVICE_EVENT_RESET: | 
|  | return "Reset"; | 
|  | case DWC3_DEVICE_EVENT_CONNECT_DONE: | 
|  | return "Connect Done"; | 
|  | case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: | 
|  | return "Link Status Change"; | 
|  | case DWC3_DEVICE_EVENT_WAKEUP: | 
|  | return "Wake-Up"; | 
|  | case DWC3_DEVICE_EVENT_HIBER_REQ: | 
|  | return "Hibernation"; | 
|  | case DWC3_DEVICE_EVENT_SUSPEND: | 
|  | return "Suspend"; | 
|  | case DWC3_DEVICE_EVENT_SOF: | 
|  | return "Start of Frame"; | 
|  | case DWC3_DEVICE_EVENT_ERRATIC_ERROR: | 
|  | return "Erratic Error"; | 
|  | case DWC3_DEVICE_EVENT_CMD_CMPL: | 
|  | return "Command Complete"; | 
|  | case DWC3_DEVICE_EVENT_OVERFLOW: | 
|  | return "Overflow"; | 
|  | default: | 
|  | return "UNKNOWN"; | 
|  | } | 
|  | } | 
|  |  | 
|  | static inline const char *dwc3_decode_event(char *str, size_t size, u32 event, | 
|  | u32 ep0state) | 
|  | { | 
|  | union dwc3_event evt; | 
|  |  | 
|  | memcpy(&evt, &event, sizeof(event)); | 
|  |  | 
|  | if (evt.type.is_devspec) | 
|  | return dwc3_gadget_event_string(str, size, &evt.devt); | 
|  | else | 
|  | return dwc3_ep_event_string(str, size, &evt.depevt, ep0state); | 
|  | } | 
|  |  | 
|  | static inline const char *dwc3_ep_cmd_status_string(int status) | 
|  | { | 
|  | switch (status) { | 
|  | case -ETIMEDOUT: | 
|  | return "Timed Out"; | 
|  | case 0: | 
|  | return "Successful"; | 
|  | case DEPEVT_TRANSFER_NO_RESOURCE: | 
|  | return "No Resource"; | 
|  | case DEPEVT_TRANSFER_BUS_EXPIRY: | 
|  | return "Bus Expiry"; | 
|  | default: | 
|  | return "UNKNOWN"; | 
|  | } | 
|  | } | 
|  |  | 
|  | static inline const char *dwc3_gadget_generic_cmd_status_string(int status) | 
|  | { | 
|  | switch (status) { | 
|  | case -ETIMEDOUT: | 
|  | return "Timed Out"; | 
|  | case 0: | 
|  | return "Successful"; | 
|  | case 1: | 
|  | return "Error"; | 
|  | default: | 
|  | return "UNKNOWN"; | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | #ifdef CONFIG_DEBUG_FS | 
|  | extern void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep); | 
|  | extern void dwc3_debugfs_remove_endpoint_dir(struct dwc3_ep *dep); | 
|  | extern void dwc3_debugfs_init(struct dwc3 *d); | 
|  | extern void dwc3_debugfs_exit(struct dwc3 *d); | 
|  | #else | 
|  | static inline void dwc3_debugfs_create_endpoint_dir(struct dwc3_ep *dep) | 
|  | {  } | 
|  | static inline void dwc3_debugfs_remove_endpoint_dir(struct dwc3_ep *dep) | 
|  | {  } | 
|  | static inline void dwc3_debugfs_init(struct dwc3 *d) | 
|  | {  } | 
|  | static inline void dwc3_debugfs_exit(struct dwc3 *d) | 
|  | {  } | 
|  | #endif | 
|  | #endif /* __DWC3_DEBUG_H */ |