| /** |
| * debug.h - DesignWare USB3 DRD Controller Debug Header |
| * |
| * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com |
| * |
| * Authors: Felipe Balbi <balbi@ti.com>, |
| * Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| * |
| * This program is free software: you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 of |
| * the License as published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| */ |
| |
| #ifndef __DWC3_DEBUG_H |
| #define __DWC3_DEBUG_H |
| |
| #include "core.h" |
| #include <linux/ipc_logging.h> |
| |
| /* |
| * NOTE: Make sure to have dwc as local variable in function before using |
| * below macros. |
| */ |
| #define dbg_event(ep_num, name, status) \ |
| dwc3_dbg_print(dwc, ep_num, name, status, "") |
| |
| #define dbg_print(ep_num, name, status, extra) \ |
| dwc3_dbg_print(dwc, ep_num, name, status, extra) |
| |
| #define dbg_print_reg(name, reg) \ |
| dwc3_dbg_print_reg(dwc, name, reg) |
| |
| #define dbg_done(ep_num, count, status) \ |
| dwc3_dbg_done(dwc, ep_num, count, status) |
| |
| #define dbg_queue(ep_num, req, status) \ |
| dwc3_dbg_queue(dwc, ep_num, req, status) |
| |
| #define dbg_setup(ep_num, req) \ |
| dwc3_dbg_setup(dwc, ep_num, req) |
| /** |
| * 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_RUN_SOC_BUS_LOOPBACK: |
| return "Run SoC Bus Loopback Test"; |
| 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\n"; |
| } |
| } |
| |
| /** |
| * dwc3_gadget_event_string - returns event name |
| * @event: the event code |
| */ |
| static inline const char * |
| dwc3_gadget_event_string(const struct dwc3_event_devt *event) |
| { |
| static char str[256]; |
| enum dwc3_link_state state = event->event_info & DWC3_LINK_STATE_MASK; |
| |
| switch (event->type) { |
| case DWC3_DEVICE_EVENT_DISCONNECT: |
| sprintf(str, "Disconnect: [%s]", |
| dwc3_gadget_link_string(state)); |
| break; |
| case DWC3_DEVICE_EVENT_RESET: |
| sprintf(str, "Reset [%s]", dwc3_gadget_link_string(state)); |
| break; |
| case DWC3_DEVICE_EVENT_CONNECT_DONE: |
| sprintf(str, "Connection Done [%s]", |
| dwc3_gadget_link_string(state)); |
| break; |
| case DWC3_DEVICE_EVENT_LINK_STATUS_CHANGE: |
| sprintf(str, "Link Change [%s]", |
| dwc3_gadget_link_string(state)); |
| break; |
| case DWC3_DEVICE_EVENT_WAKEUP: |
| sprintf(str, "WakeUp [%s]", dwc3_gadget_link_string(state)); |
| break; |
| case DWC3_DEVICE_EVENT_EOPF: |
| sprintf(str, "End-Of-Frame [%s]", |
| dwc3_gadget_link_string(state)); |
| break; |
| case DWC3_DEVICE_EVENT_SOF: |
| sprintf(str, "Start-Of-Frame [%s]", |
| dwc3_gadget_link_string(state)); |
| break; |
| case DWC3_DEVICE_EVENT_ERRATIC_ERROR: |
| sprintf(str, "Erratic Error [%s]", |
| dwc3_gadget_link_string(state)); |
| break; |
| case DWC3_DEVICE_EVENT_CMD_CMPL: |
| sprintf(str, "Command Complete [%s]", |
| dwc3_gadget_link_string(state)); |
| break; |
| case DWC3_DEVICE_EVENT_OVERFLOW: |
| sprintf(str, "Overflow [%s]", dwc3_gadget_link_string(state)); |
| break; |
| default: |
| sprintf(str, "UNKNOWN"); |
| } |
| |
| return str; |
| } |
| |
| /** |
| * dwc3_ep_event_string - returns event name |
| * @event: then event code |
| */ |
| static inline const char * |
| dwc3_ep_event_string(const struct dwc3_event_depevt *event) |
| { |
| u8 epnum = event->endpoint_number; |
| static char str[256]; |
| int status; |
| int ret; |
| |
| ret = sprintf(str, "ep%d%s: ", epnum >> 1, |
| (epnum & 1) ? "in" : "out"); |
| if (ret < 0) |
| return "UNKNOWN"; |
| |
| switch (event->endpoint_event) { |
| case DWC3_DEPEVT_XFERCOMPLETE: |
| strcat(str, "Transfer Complete"); |
| break; |
| case DWC3_DEPEVT_XFERINPROGRESS: |
| strcat(str, "Transfer In-Progress"); |
| break; |
| case DWC3_DEPEVT_XFERNOTREADY: |
| strcat(str, "Transfer Not Ready"); |
| status = event->status & DEPEVT_STATUS_TRANSFER_ACTIVE; |
| strcat(str, status ? " (Active)" : " (Not Active)"); |
| break; |
| case DWC3_DEPEVT_RXTXFIFOEVT: |
| strcat(str, "FIFO"); |
| break; |
| case DWC3_DEPEVT_STREAMEVT: |
| status = event->status; |
| |
| switch (status) { |
| case DEPEVT_STREAMEVT_FOUND: |
| sprintf(str + ret, " Stream %d Found", |
| event->parameters); |
| break; |
| case DEPEVT_STREAMEVT_NOTFOUND: |
| default: |
| strcat(str, " Stream Not Found"); |
| break; |
| } |
| |
| break; |
| case DWC3_DEPEVT_EPCMDCMPLT: |
| strcat(str, "Endpoint Command Complete"); |
| break; |
| default: |
| sprintf(str, "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_EOPF: |
| return "End of Periodic Frame"; |
| 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(u32 event) |
| { |
| const union dwc3_event evt = (union dwc3_event) event; |
| |
| if (evt.type.is_devspec) |
| return dwc3_gadget_event_string(&evt.devt); |
| else |
| return dwc3_ep_event_string(&evt.depevt); |
| } |
| |
| 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"; |
| } |
| } |
| |
| void dwc3_trace(void (*trace)(struct va_format *), const char *fmt, ...); |
| void dwc3_dbg_print(struct dwc3 *dwc, u8 ep_num, |
| const char *name, int status, const char *extra); |
| void dwc3_dbg_done(struct dwc3 *dwc, u8 ep_num, |
| const u32 count, int status); |
| void dwc3_dbg_event(struct dwc3 *dwc, u8 ep_num, |
| const char *name, int status); |
| void dwc3_dbg_queue(struct dwc3 *dwc, u8 ep_num, |
| const struct usb_request *req, int status); |
| void dwc3_dbg_setup(struct dwc3 *dwc, u8 ep_num, |
| const struct usb_ctrlrequest *req); |
| void dwc3_dbg_print_reg(struct dwc3 *dwc, |
| const char *name, int reg); |
| |
| #ifdef CONFIG_DEBUG_FS |
| extern int dwc3_debugfs_init(struct dwc3 *); |
| extern void dwc3_debugfs_exit(struct dwc3 *); |
| #else |
| static inline int dwc3_debugfs_init(struct dwc3 *d) |
| { return 0; } |
| static inline void dwc3_debugfs_exit(struct dwc3 *d) |
| { } |
| #endif |
| #endif /* __DWC3_DEBUG_H */ |