debug_ipc.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include "debug-ipc.h"
  7. #include <linux/moduleparam.h>
  8. static unsigned int ep_addr_rxdbg_mask = 1;
  9. module_param(ep_addr_rxdbg_mask, uint, 0644);
  10. static unsigned int ep_addr_txdbg_mask = 1;
  11. module_param(ep_addr_txdbg_mask, uint, 0644);
  12. static int allow_dbg_print(u8 ep_num)
  13. {
  14. int dir, num;
  15. /* allow bus wide events */
  16. if (ep_num == 0xff)
  17. return 1;
  18. dir = ep_num & 0x1;
  19. num = ep_num >> 1;
  20. num = 1 << num;
  21. if (dir && (num & ep_addr_txdbg_mask))
  22. return 1;
  23. if (!dir && (num & ep_addr_rxdbg_mask))
  24. return 1;
  25. return 0;
  26. }
  27. void dwc3_dbg_trace_log_ctrl(void *log_ctxt, struct usb_ctrlrequest *ctrl)
  28. {
  29. char *ctrl_req_str;
  30. if (ctrl == NULL)
  31. return;
  32. ctrl_req_str = kzalloc(DWC3_MSG_MAX, GFP_ATOMIC);
  33. if (!ctrl_req_str)
  34. return;
  35. usb_decode_ctrl(ctrl_req_str, DWC3_MSG_MAX, ctrl->bRequestType,
  36. ctrl->bRequest, le16_to_cpu(ctrl->wValue),
  37. le16_to_cpu(ctrl->wIndex),
  38. le16_to_cpu(ctrl->wLength));
  39. ipc_log_string(log_ctxt, "dbg_trace_log_ctrl: %s", ctrl_req_str);
  40. kfree(ctrl_req_str);
  41. }
  42. void dwc3_dbg_trace_log_request(void *log_ctxt, struct dwc3_request *req,
  43. char *tag)
  44. {
  45. struct dwc3_ep *dep;
  46. if (req == NULL)
  47. return;
  48. dep = req->dep;
  49. ipc_log_string(log_ctxt, "%s: %s: req %p length %u/%u %s%s%s ==> %d",
  50. tag, dep->name, req, req->request.actual,
  51. req->request.length,
  52. req->request.zero ? "Z" : "z",
  53. req->request.short_not_ok ? "S" : "s",
  54. req->request.no_interrupt ? "i" : "I",
  55. req->request.status);
  56. }
  57. void dwc3_dbg_trace_ep_cmd(void *log_ctxt, struct dwc3_ep *dep,
  58. unsigned int cmd,
  59. struct dwc3_gadget_ep_cmd_params *params,
  60. int cmd_status)
  61. {
  62. ipc_log_string(log_ctxt,
  63. "dbg_send_ep_cmd: %s: cmd '%s' [%x] params %08x %08x %08x --> status: %s",
  64. dep->name, dwc3_gadget_ep_cmd_string(cmd), cmd, params->param0,
  65. params->param1, params->param2, dwc3_ep_cmd_status_string(cmd_status));
  66. }
  67. void dwc3_dbg_trace_trb_complete(void *log_ctxt, struct dwc3_ep *dep,
  68. struct dwc3_trb *trb, char *tag)
  69. {
  70. char *s;
  71. int pcm = ((trb->size >> 24) & 3) + 1;
  72. switch (usb_endpoint_type(dep->endpoint.desc)) {
  73. case USB_ENDPOINT_XFER_INT:
  74. case USB_ENDPOINT_XFER_ISOC:
  75. switch (pcm) {
  76. case 1:
  77. s = "1x ";
  78. break;
  79. case 2:
  80. s = "2x ";
  81. break;
  82. case 3:
  83. default:
  84. s = "3x ";
  85. break;
  86. }
  87. break;
  88. default:
  89. s = "";
  90. }
  91. ipc_log_string(log_ctxt,
  92. "%s: %s: trb %p (E%d:D%d) buf %08x%08x sz %s%d ctrl %08x (%c%c%c%c:%c%c:%s)",
  93. tag, dep->name, trb, dep->trb_enqueue,
  94. dep->trb_dequeue, trb->bph, trb->bpl, s, trb->size, trb->ctrl,
  95. trb->ctrl & DWC3_TRB_CTRL_HWO ? 'H' : 'h',
  96. trb->ctrl & DWC3_TRB_CTRL_LST ? 'L' : 'l',
  97. trb->ctrl & DWC3_TRB_CTRL_CHN ? 'C' : 'c',
  98. trb->ctrl & DWC3_TRB_CTRL_CSP ? 'S' : 's',
  99. trb->ctrl & DWC3_TRB_CTRL_ISP_IMI ? 'S' : 's',
  100. trb->ctrl & DWC3_TRB_CTRL_IOC ? 'C' : 'c',
  101. dwc3_trb_type_string(DWC3_TRBCTL_TYPE(trb->ctrl)));
  102. }
  103. void dwc3_dbg_trace_event(void *log_ctxt, u32 event, struct dwc3 *dwc)
  104. {
  105. char *event_str;
  106. event_str = kzalloc(DWC3_MSG_MAX, GFP_ATOMIC);
  107. if (!event_str)
  108. return;
  109. ipc_log_string(log_ctxt, "event (%08x): %s", event,
  110. dwc3_decode_event(event_str, DWC3_MSG_MAX,
  111. event, dwc->ep0state));
  112. kfree(event_str);
  113. }
  114. void dwc3_dbg_trace_ep(void *log_ctxt, struct dwc3_ep *dep)
  115. {
  116. ipc_log_string(log_ctxt,
  117. "%s: mps %d/%d streams %d burst %d ring %d/%d flags %c:%c%c%c%c:%c",
  118. dep->name, dep->endpoint.maxpacket,
  119. dep->endpoint.maxpacket_limit, dep->endpoint.max_streams,
  120. dep->endpoint.maxburst, dep->trb_enqueue,
  121. dep->trb_dequeue,
  122. dep->flags & DWC3_EP_ENABLED ? 'E' : 'e',
  123. dep->flags & DWC3_EP_STALL ? 'S' : 's',
  124. dep->flags & DWC3_EP_WEDGE ? 'W' : 'w',
  125. dep->flags & DWC3_EP_TRANSFER_STARTED ? 'B' : 'b',
  126. dep->flags & DWC3_EP_PENDING_REQUEST ? 'P' : 'p',
  127. dep->direction ? '<' : '>');
  128. }
  129. /**
  130. * dwc3_dbg_print: prints the common part of the event
  131. * @addr: endpoint address
  132. * @name: event name
  133. * @status: status
  134. * @extra: extra information
  135. * @dwc3: pointer to struct dwc3
  136. */
  137. void dwc3_dbg_print(void *log_ctxt, u8 ep_num, const char *name,
  138. int status, const char *extra)
  139. {
  140. if (!allow_dbg_print(ep_num))
  141. return;
  142. if (name == NULL)
  143. return;
  144. ipc_log_string(log_ctxt, "%02X %-25.25s %4i ?\t%s",
  145. ep_num, name, status, extra);
  146. }
  147. /**
  148. * dwc3_dbg_done: prints a DONE event
  149. * @addr: endpoint address
  150. * @td: transfer descriptor
  151. * @status: status
  152. * @dwc3: pointer to struct dwc3
  153. */
  154. void dwc3_dbg_done(void *log_ctxt, u8 ep_num,
  155. const u32 count, int status)
  156. {
  157. if (!allow_dbg_print(ep_num))
  158. return;
  159. ipc_log_string(log_ctxt, "%02X %-25.25s %4i ?\t%d",
  160. ep_num, "DONE", status, count);
  161. }
  162. /**
  163. * dwc3_dbg_event: prints a generic event
  164. * @addr: endpoint address
  165. * @name: event name
  166. * @status: status
  167. */
  168. void dwc3_dbg_event(void *log_ctxt, u8 ep_num, const char *name, int status)
  169. {
  170. if (!allow_dbg_print(ep_num))
  171. return;
  172. if (name != NULL)
  173. dwc3_dbg_print(log_ctxt, ep_num, name, status, "");
  174. }
  175. /*
  176. * dwc3_dbg_queue: prints a QUEUE event
  177. * @addr: endpoint address
  178. * @req: USB request
  179. * @status: status
  180. */
  181. void dwc3_dbg_queue(void *log_ctxt, u8 ep_num,
  182. const struct usb_request *req, int status)
  183. {
  184. if (!allow_dbg_print(ep_num))
  185. return;
  186. if (req != NULL) {
  187. ipc_log_string(log_ctxt,
  188. "%02X %-25.25s %4i ?\t%d %d", ep_num, "QUEUE", status,
  189. !req->no_interrupt, req->length);
  190. }
  191. }
  192. /**
  193. * dwc3_dbg_setup: prints a SETUP event
  194. * @addr: endpoint address
  195. * @req: setup request
  196. */
  197. void dwc3_dbg_setup(void *log_ctxt, u8 ep_num,
  198. const struct usb_ctrlrequest *req)
  199. {
  200. if (!allow_dbg_print(ep_num))
  201. return;
  202. if (req != NULL) {
  203. ipc_log_string(log_ctxt,
  204. "%02X %-25.25s ?\t%02X %02X %04X %04X %d",
  205. ep_num, "SETUP", req->bRequestType,
  206. req->bRequest, le16_to_cpu(req->wValue),
  207. le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength));
  208. }
  209. }
  210. /**
  211. * dwc3_dbg_print_reg: prints a reg value
  212. * @name: reg name
  213. * @reg: reg value to be printed
  214. */
  215. void dwc3_dbg_print_reg(void *log_ctxt, const char *name, int reg)
  216. {
  217. if (name == NULL)
  218. return;
  219. ipc_log_string(log_ctxt, "%s = 0x%08x", name, reg);
  220. }
  221. void dwc3_dbg_dma_unmap(void *log_ctxt, u8 ep_num, struct dwc3_request *req)
  222. {
  223. if (ep_num < 2)
  224. return;
  225. ipc_log_string(log_ctxt,
  226. "%02X-%-3.3s %-25.25s 0x%pK %pad %u %pad %s", ep_num >> 1,
  227. ep_num & 1 ? "IN":"OUT", "UNMAP", &req->request,
  228. &req->request.dma, req->request.length, &req->trb_dma,
  229. req->trb->ctrl & DWC3_TRB_CTRL_HWO ? "HWO" : "");
  230. }
  231. void dwc3_dbg_dma_map(void *log_ctxt, u8 ep_num, struct dwc3_request *req)
  232. {
  233. if (ep_num < 2)
  234. return;
  235. ipc_log_string(log_ctxt,
  236. "%02X-%-3.3s %-25.25s 0x%pK %pad %u %pad", ep_num >> 1,
  237. ep_num & 1 ? "IN":"OUT", "MAP", &req->request,
  238. &req->request.dma, req->request.length, &req->trb_dma);
  239. }
  240. void dwc3_dbg_dma_dequeue(void *log_ctxt, u8 ep_num, struct dwc3_request *req)
  241. {
  242. if (ep_num < 2)
  243. return;
  244. ipc_log_string(log_ctxt,
  245. "%02X-%-3.3s %-25.25s 0x%pK %pad %pad", ep_num >> 1,
  246. ep_num & 1 ? "IN":"OUT", "DEQUEUE", &req->request,
  247. &req->request.dma, &req->trb_dma);
  248. }
  249. void dwc3_dbg_dma_queue(void *log_ctxt, u8 ep_num, struct dwc3_request *req)
  250. {
  251. if (ep_num < 2)
  252. return;
  253. ipc_log_string(log_ctxt,
  254. "%02X-%-3.3s %-25.25s 0x%pK", ep_num >> 1,
  255. ep_num & 1 ? "IN":"OUT", "QUEUE", &req->request);
  256. }