From c32fced52760f73414dfd9a122572e26e8d1e538 Mon Sep 17 00:00:00 2001 From: Sriharsha Allenki Date: Wed, 10 Jul 2019 11:44:51 +0530 Subject: [PATCH] usb: gadget: Add new ipc log buffer to log request and dma Add new IPC log buffer to log the events in the cycle of requests like queue, mapping the associated buffer, unmapping it and finally dequeuing it. This logging will help us in debugging the SMMU faults for which the traces has to be enabled. These logs helps to trace the faulty address in the first incident. The logs can be accessed on the target using the command echo 0 > /proc/sys/kernel/kptr_restrict cat /sys/kernel/debug/ipc_logging/a600000.dwc3.ep_events/log. Change-Id: Icc7063da7a251902cbb257022eaff6656e972a07 Signed-off-by: Sriharsha Allenki Signed-off-by: Jack Pham --- drivers/usb/dwc3/core.c | 8 +++++++ drivers/usb/dwc3/core.h | 1 + drivers/usb/dwc3/debug.h | 20 ++++++++++++++++ drivers/usb/dwc3/debug_ipc.c | 46 +++++++++++++++++++++++++++++++++++- drivers/usb/dwc3/gadget.c | 8 +++++-- 5 files changed, 80 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index f9a1103c7ff2..340fdea4a345 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1485,6 +1485,7 @@ static int dwc3_probe(struct platform_device *pdev) void __iomem *regs; int irq; + char dma_ipc_log_ctx_name[40]; if (count >= DWC_CTRL_COUNT) { dev_err(dev, "Err dwc instance %d >= %d available\n", @@ -1640,6 +1641,13 @@ static int dwc3_probe(struct platform_device *pdev) if (!dwc->dwc_ipc_log_ctxt) dev_err(dwc->dev, "Error getting ipc_log_ctxt\n"); + snprintf(dma_ipc_log_ctx_name, sizeof(dma_ipc_log_ctx_name), + "%s.ep_events", dev_name(dwc->dev)); + dwc->dwc_dma_ipc_log_ctxt = ipc_log_context_create(NUM_LOG_PAGES, + dma_ipc_log_ctx_name, 0); + if (!dwc->dwc_dma_ipc_log_ctxt) + dev_err(dwc->dev, "Error getting ipc_log_ctxt for ep_events\n"); + dwc3_instance[count] = dwc; dwc->index = count; count++; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index c08682fc63d1..de7c8afc43af 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1326,6 +1326,7 @@ struct dwc3 { unsigned int index; void *dwc_ipc_log_ctxt; + void *dwc_dma_ipc_log_ctxt; struct dwc3_gadget_events dbg_gadget_events; int tx_fifo_size; int last_fifo_depth; diff --git a/drivers/usb/dwc3/debug.h b/drivers/usb/dwc3/debug.h index 84350b90457e..b71cfbdb590a 100644 --- a/drivers/usb/dwc3/debug.h +++ b/drivers/usb/dwc3/debug.h @@ -36,6 +36,18 @@ #define dbg_setup(ep_num, req) \ dwc3_dbg_setup(dwc, ep_num, req) +#define dbg_ep_queue(ep_num, req) \ + dwc3_dbg_dma_queue(dwc, ep_num, req) + +#define dbg_ep_dequeue(ep_num, req) \ + dwc3_dbg_dma_dequeue(dwc, ep_num, req) + +#define dbg_ep_unmap(ep_num, req) \ + dwc3_dbg_dma_unmap(dwc, ep_num, req) + +#define dbg_ep_map(ep_num, req) \ + dwc3_dbg_dma_map(dwc, ep_num, req) + #define dbg_log_string(fmt, ...) \ ipc_log_string(dwc->dwc_ipc_log_ctxt,\ "%s: " fmt, __func__, ##__VA_ARGS__) @@ -455,6 +467,14 @@ 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); +void dwc3_dbg_dma_queue(struct dwc3 *dwc, u8 ep_num, + struct dwc3_request *req); +void dwc3_dbg_dma_dequeue(struct dwc3 *dwc, u8 ep_num, + struct dwc3_request *req); +void dwc3_dbg_dma_map(struct dwc3 *dwc, u8 ep_num, + struct dwc3_request *req); +void dwc3_dbg_dma_unmap(struct dwc3 *dwc, u8 ep_num, + struct dwc3_request *req); #ifdef CONFIG_DEBUG_FS extern void dwc3_debugfs_init(struct dwc3 *); diff --git a/drivers/usb/dwc3/debug_ipc.c b/drivers/usb/dwc3/debug_ipc.c index 247d3cd4e61b..7f9ae3293e9a 100644 --- a/drivers/usb/dwc3/debug_ipc.c +++ b/drivers/usb/dwc3/debug_ipc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. */ #include "debug.h" @@ -137,3 +137,47 @@ void dwc3_dbg_print_reg(struct dwc3 *dwc, const char *name, int reg) ipc_log_string(dwc->dwc_ipc_log_ctxt, "%s = 0x%08x", name, reg); } + +void dwc3_dbg_dma_unmap(struct dwc3 *dwc, u8 ep_num, struct dwc3_request *req) +{ + if (ep_num < 2) + return; + + ipc_log_string(dwc->dwc_dma_ipc_log_ctxt, + "%02X-%-3.3s %-25.25s 0x%pK 0x%lx %u 0x%lx %d", 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); +} + +void dwc3_dbg_dma_map(struct dwc3 *dwc, u8 ep_num, struct dwc3_request *req) +{ + if (ep_num < 2) + return; + + ipc_log_string(dwc->dwc_dma_ipc_log_ctxt, + "%02X-%-3.3s %-25.25s 0x%pK 0x%lx %u 0x%lx", 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(struct dwc3 *dwc, u8 ep_num, struct dwc3_request *req) +{ + if (ep_num < 2) + return; + + ipc_log_string(dwc->dwc_dma_ipc_log_ctxt, + "%02X-%-3.3s %-25.25s 0x%pK 0x%lx 0x%lx", ep_num >> 1, + ep_num & 1 ? "IN":"OUT", "DEQUEUE", &req->request, + req->request.dma, req->trb_dma); +} + +void dwc3_dbg_dma_queue(struct dwc3 *dwc, u8 ep_num, struct dwc3_request *req) +{ + if (ep_num < 2) + return; + + ipc_log_string(dwc->dwc_dma_ipc_log_ctxt, + "%02X-%-3.3s %-25.25s 0x%pK", ep_num >> 1, + ep_num & 1 ? "IN":"OUT", "QUEUE", &req->request); +} diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index f2b4b53866a8..51ab0b0bca19 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -278,9 +278,11 @@ static void dwc3_gadget_del_and_unmap_request(struct dwc3_ep *dep, if (req->request.status == -EINPROGRESS) req->request.status = status; - if (req->trb) + if (req->trb) { + dbg_ep_unmap(dep->number, req); usb_gadget_unmap_request_by_dev(dwc->sysdev, &req->request, req->direction); + } req->trb = NULL; trace_dwc3_gadget_giveback(req); @@ -1341,6 +1343,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep) else dwc3_prepare_one_trb_linear(dep, req); + dbg_ep_map(dep->number, req); if (!dwc3_calc_trbs_left(dep)) return; } @@ -1583,6 +1586,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) list_add_tail(&req->list, &dep->pending_list); req->status = DWC3_REQUEST_STATUS_QUEUED; + dbg_ep_queue(dep->number, req); /* * NOTICE: Isochronous endpoints should NEVER be prestarted. We must * wait for a XferNotReady event so we will know what's the current @@ -1711,7 +1715,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, } out1: - dbg_event(dep->number, "DEQUEUE", 0); + dbg_ep_dequeue(dep->number, req); dwc3_gadget_giveback(dep, req, -ECONNRESET); out0: