123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 |
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
- */
- #include "debug-ipc.h"
- #include <linux/moduleparam.h>
- static unsigned int ep_addr_rxdbg_mask = 1;
- module_param(ep_addr_rxdbg_mask, uint, 0644);
- static unsigned int ep_addr_txdbg_mask = 1;
- module_param(ep_addr_txdbg_mask, uint, 0644);
- static int allow_dbg_print(u8 ep_num)
- {
- int dir, num;
- /* allow bus wide events */
- if (ep_num == 0xff)
- return 1;
- dir = ep_num & 0x1;
- num = ep_num >> 1;
- num = 1 << num;
- if (dir && (num & ep_addr_txdbg_mask))
- return 1;
- if (!dir && (num & ep_addr_rxdbg_mask))
- return 1;
- return 0;
- }
- void dwc3_dbg_trace_log_ctrl(void *log_ctxt, struct usb_ctrlrequest *ctrl)
- {
- char *ctrl_req_str;
- if (ctrl == NULL)
- return;
- ctrl_req_str = kzalloc(DWC3_MSG_MAX, GFP_ATOMIC);
- if (!ctrl_req_str)
- return;
- usb_decode_ctrl(ctrl_req_str, DWC3_MSG_MAX, ctrl->bRequestType,
- ctrl->bRequest, le16_to_cpu(ctrl->wValue),
- le16_to_cpu(ctrl->wIndex),
- le16_to_cpu(ctrl->wLength));
- ipc_log_string(log_ctxt, "dbg_trace_log_ctrl: %s", ctrl_req_str);
- kfree(ctrl_req_str);
- }
- void dwc3_dbg_trace_log_request(void *log_ctxt, struct dwc3_request *req,
- char *tag)
- {
- struct dwc3_ep *dep;
- if (req == NULL)
- return;
- dep = req->dep;
- ipc_log_string(log_ctxt, "%s: %s: req %p length %u/%u %s%s%s ==> %d",
- tag, dep->name, req, req->request.actual,
- req->request.length,
- req->request.zero ? "Z" : "z",
- req->request.short_not_ok ? "S" : "s",
- req->request.no_interrupt ? "i" : "I",
- req->request.status);
- }
- void dwc3_dbg_trace_ep_cmd(void *log_ctxt, struct dwc3_ep *dep,
- unsigned int cmd,
- struct dwc3_gadget_ep_cmd_params *params,
- int cmd_status)
- {
- ipc_log_string(log_ctxt,
- "dbg_send_ep_cmd: %s: cmd '%s' [%x] params %08x %08x %08x --> status: %s",
- dep->name, dwc3_gadget_ep_cmd_string(cmd), cmd, params->param0,
- params->param1, params->param2, dwc3_ep_cmd_status_string(cmd_status));
- }
- void dwc3_dbg_trace_trb_complete(void *log_ctxt, struct dwc3_ep *dep,
- struct dwc3_trb *trb, char *tag)
- {
- char *s;
- int pcm = ((trb->size >> 24) & 3) + 1;
- switch (usb_endpoint_type(dep->endpoint.desc)) {
- case USB_ENDPOINT_XFER_INT:
- case USB_ENDPOINT_XFER_ISOC:
- switch (pcm) {
- case 1:
- s = "1x ";
- break;
- case 2:
- s = "2x ";
- break;
- case 3:
- default:
- s = "3x ";
- break;
- }
- break;
- default:
- s = "";
- }
- ipc_log_string(log_ctxt,
- "%s: %s: trb %p (E%d:D%d) buf %08x%08x sz %s%d ctrl %08x (%c%c%c%c:%c%c:%s)",
- tag, dep->name, trb, dep->trb_enqueue,
- dep->trb_dequeue, trb->bph, trb->bpl, s, trb->size, trb->ctrl,
- trb->ctrl & DWC3_TRB_CTRL_HWO ? 'H' : 'h',
- trb->ctrl & DWC3_TRB_CTRL_LST ? 'L' : 'l',
- trb->ctrl & DWC3_TRB_CTRL_CHN ? 'C' : 'c',
- trb->ctrl & DWC3_TRB_CTRL_CSP ? 'S' : 's',
- trb->ctrl & DWC3_TRB_CTRL_ISP_IMI ? 'S' : 's',
- trb->ctrl & DWC3_TRB_CTRL_IOC ? 'C' : 'c',
- dwc3_trb_type_string(DWC3_TRBCTL_TYPE(trb->ctrl)));
- }
- void dwc3_dbg_trace_event(void *log_ctxt, u32 event, struct dwc3 *dwc)
- {
- char *event_str;
- event_str = kzalloc(DWC3_MSG_MAX, GFP_ATOMIC);
- if (!event_str)
- return;
- ipc_log_string(log_ctxt, "event (%08x): %s", event,
- dwc3_decode_event(event_str, DWC3_MSG_MAX,
- event, dwc->ep0state));
- kfree(event_str);
- }
- void dwc3_dbg_trace_ep(void *log_ctxt, struct dwc3_ep *dep)
- {
- ipc_log_string(log_ctxt,
- "%s: mps %d/%d streams %d burst %d ring %d/%d flags %c:%c%c%c%c:%c",
- dep->name, dep->endpoint.maxpacket,
- dep->endpoint.maxpacket_limit, dep->endpoint.max_streams,
- dep->endpoint.maxburst, dep->trb_enqueue,
- dep->trb_dequeue,
- dep->flags & DWC3_EP_ENABLED ? 'E' : 'e',
- dep->flags & DWC3_EP_STALL ? 'S' : 's',
- dep->flags & DWC3_EP_WEDGE ? 'W' : 'w',
- dep->flags & DWC3_EP_TRANSFER_STARTED ? 'B' : 'b',
- dep->flags & DWC3_EP_PENDING_REQUEST ? 'P' : 'p',
- dep->direction ? '<' : '>');
- }
- /**
- * dwc3_dbg_print: prints the common part of the event
- * @addr: endpoint address
- * @name: event name
- * @status: status
- * @extra: extra information
- * @dwc3: pointer to struct dwc3
- */
- void dwc3_dbg_print(void *log_ctxt, u8 ep_num, const char *name,
- int status, const char *extra)
- {
- if (!allow_dbg_print(ep_num))
- return;
- if (name == NULL)
- return;
- ipc_log_string(log_ctxt, "%02X %-25.25s %4i ?\t%s",
- ep_num, name, status, extra);
- }
- /**
- * dwc3_dbg_done: prints a DONE event
- * @addr: endpoint address
- * @td: transfer descriptor
- * @status: status
- * @dwc3: pointer to struct dwc3
- */
- void dwc3_dbg_done(void *log_ctxt, u8 ep_num,
- const u32 count, int status)
- {
- if (!allow_dbg_print(ep_num))
- return;
- ipc_log_string(log_ctxt, "%02X %-25.25s %4i ?\t%d",
- ep_num, "DONE", status, count);
- }
- /**
- * dwc3_dbg_event: prints a generic event
- * @addr: endpoint address
- * @name: event name
- * @status: status
- */
- void dwc3_dbg_event(void *log_ctxt, u8 ep_num, const char *name, int status)
- {
- if (!allow_dbg_print(ep_num))
- return;
- if (name != NULL)
- dwc3_dbg_print(log_ctxt, ep_num, name, status, "");
- }
- /*
- * dwc3_dbg_queue: prints a QUEUE event
- * @addr: endpoint address
- * @req: USB request
- * @status: status
- */
- void dwc3_dbg_queue(void *log_ctxt, u8 ep_num,
- const struct usb_request *req, int status)
- {
- if (!allow_dbg_print(ep_num))
- return;
- if (req != NULL) {
- ipc_log_string(log_ctxt,
- "%02X %-25.25s %4i ?\t%d %d", ep_num, "QUEUE", status,
- !req->no_interrupt, req->length);
- }
- }
- /**
- * dwc3_dbg_setup: prints a SETUP event
- * @addr: endpoint address
- * @req: setup request
- */
- void dwc3_dbg_setup(void *log_ctxt, u8 ep_num,
- const struct usb_ctrlrequest *req)
- {
- if (!allow_dbg_print(ep_num))
- return;
- if (req != NULL) {
- ipc_log_string(log_ctxt,
- "%02X %-25.25s ?\t%02X %02X %04X %04X %d",
- ep_num, "SETUP", req->bRequestType,
- req->bRequest, le16_to_cpu(req->wValue),
- le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength));
- }
- }
- /**
- * dwc3_dbg_print_reg: prints a reg value
- * @name: reg name
- * @reg: reg value to be printed
- */
- void dwc3_dbg_print_reg(void *log_ctxt, const char *name, int reg)
- {
- if (name == NULL)
- return;
- ipc_log_string(log_ctxt, "%s = 0x%08x", name, reg);
- }
- void dwc3_dbg_dma_unmap(void *log_ctxt, u8 ep_num, struct dwc3_request *req)
- {
- if (ep_num < 2)
- return;
- ipc_log_string(log_ctxt,
- "%02X-%-3.3s %-25.25s 0x%pK %pad %u %pad %s", ep_num >> 1,
- ep_num & 1 ? "IN":"OUT", "UNMAP", &req->request,
- &req->request.dma, req->request.length, &req->trb_dma,
- req->trb->ctrl & DWC3_TRB_CTRL_HWO ? "HWO" : "");
- }
- void dwc3_dbg_dma_map(void *log_ctxt, u8 ep_num, struct dwc3_request *req)
- {
- if (ep_num < 2)
- return;
- ipc_log_string(log_ctxt,
- "%02X-%-3.3s %-25.25s 0x%pK %pad %u %pad", ep_num >> 1,
- ep_num & 1 ? "IN":"OUT", "MAP", &req->request,
- &req->request.dma, req->request.length, &req->trb_dma);
- }
- void dwc3_dbg_dma_dequeue(void *log_ctxt, u8 ep_num, struct dwc3_request *req)
- {
- if (ep_num < 2)
- return;
- ipc_log_string(log_ctxt,
- "%02X-%-3.3s %-25.25s 0x%pK %pad %pad", ep_num >> 1,
- ep_num & 1 ? "IN":"OUT", "DEQUEUE", &req->request,
- &req->request.dma, &req->trb_dma);
- }
- void dwc3_dbg_dma_queue(void *log_ctxt, u8 ep_num, struct dwc3_request *req)
- {
- if (ep_num < 2)
- return;
- ipc_log_string(log_ctxt,
- "%02X-%-3.3s %-25.25s 0x%pK", ep_num >> 1,
- ep_num & 1 ? "IN":"OUT", "QUEUE", &req->request);
- }
|