debug.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Common USB debugging functions
  4. *
  5. * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com
  6. *
  7. * Authors: Felipe Balbi <[email protected]>,
  8. * Sebastian Andrzej Siewior <[email protected]>
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/usb/ch9.h>
  12. static void usb_decode_get_status(__u8 bRequestType, __u16 wIndex,
  13. __u16 wLength, char *str, size_t size)
  14. {
  15. switch (bRequestType & USB_RECIP_MASK) {
  16. case USB_RECIP_DEVICE:
  17. snprintf(str, size, "Get Device Status(Length = %d)", wLength);
  18. break;
  19. case USB_RECIP_INTERFACE:
  20. snprintf(str, size,
  21. "Get Interface Status(Intf = %d, Length = %d)",
  22. wIndex, wLength);
  23. break;
  24. case USB_RECIP_ENDPOINT:
  25. snprintf(str, size, "Get Endpoint Status(ep%d%s)",
  26. wIndex & ~USB_DIR_IN,
  27. wIndex & USB_DIR_IN ? "in" : "out");
  28. break;
  29. }
  30. }
  31. static const char *usb_decode_device_feature(u16 wValue)
  32. {
  33. switch (wValue) {
  34. case USB_DEVICE_SELF_POWERED:
  35. return "Self Powered";
  36. case USB_DEVICE_REMOTE_WAKEUP:
  37. return "Remote Wakeup";
  38. case USB_DEVICE_TEST_MODE:
  39. return "Test Mode";
  40. case USB_DEVICE_U1_ENABLE:
  41. return "U1 Enable";
  42. case USB_DEVICE_U2_ENABLE:
  43. return "U2 Enable";
  44. case USB_DEVICE_LTM_ENABLE:
  45. return "LTM Enable";
  46. default:
  47. return "UNKNOWN";
  48. }
  49. }
  50. static const char *usb_decode_test_mode(u16 wIndex)
  51. {
  52. switch (wIndex) {
  53. case USB_TEST_J:
  54. return ": TEST_J";
  55. case USB_TEST_K:
  56. return ": TEST_K";
  57. case USB_TEST_SE0_NAK:
  58. return ": TEST_SE0_NAK";
  59. case USB_TEST_PACKET:
  60. return ": TEST_PACKET";
  61. case USB_TEST_FORCE_ENABLE:
  62. return ": TEST_FORCE_EN";
  63. default:
  64. return ": UNKNOWN";
  65. }
  66. }
  67. static void usb_decode_set_clear_feature(__u8 bRequestType,
  68. __u8 bRequest, __u16 wValue,
  69. __u16 wIndex, char *str, size_t size)
  70. {
  71. switch (bRequestType & USB_RECIP_MASK) {
  72. case USB_RECIP_DEVICE:
  73. snprintf(str, size, "%s Device Feature(%s%s)",
  74. bRequest == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set",
  75. usb_decode_device_feature(wValue),
  76. wValue == USB_DEVICE_TEST_MODE ?
  77. usb_decode_test_mode(wIndex) : "");
  78. break;
  79. case USB_RECIP_INTERFACE:
  80. snprintf(str, size, "%s Interface Feature(%s)",
  81. bRequest == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set",
  82. wValue == USB_INTRF_FUNC_SUSPEND ?
  83. "Function Suspend" : "UNKNOWN");
  84. break;
  85. case USB_RECIP_ENDPOINT:
  86. snprintf(str, size, "%s Endpoint Feature(%s ep%d%s)",
  87. bRequest == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set",
  88. wValue == USB_ENDPOINT_HALT ? "Halt" : "UNKNOWN",
  89. wIndex & ~USB_DIR_IN,
  90. wIndex & USB_DIR_IN ? "in" : "out");
  91. break;
  92. }
  93. }
  94. static void usb_decode_set_address(__u16 wValue, char *str, size_t size)
  95. {
  96. snprintf(str, size, "Set Address(Addr = %02x)", wValue);
  97. }
  98. static void usb_decode_get_set_descriptor(__u8 bRequestType, __u8 bRequest,
  99. __u16 wValue, __u16 wIndex,
  100. __u16 wLength, char *str, size_t size)
  101. {
  102. char *s;
  103. switch (wValue >> 8) {
  104. case USB_DT_DEVICE:
  105. s = "Device";
  106. break;
  107. case USB_DT_CONFIG:
  108. s = "Configuration";
  109. break;
  110. case USB_DT_STRING:
  111. s = "String";
  112. break;
  113. case USB_DT_INTERFACE:
  114. s = "Interface";
  115. break;
  116. case USB_DT_ENDPOINT:
  117. s = "Endpoint";
  118. break;
  119. case USB_DT_DEVICE_QUALIFIER:
  120. s = "Device Qualifier";
  121. break;
  122. case USB_DT_OTHER_SPEED_CONFIG:
  123. s = "Other Speed Config";
  124. break;
  125. case USB_DT_INTERFACE_POWER:
  126. s = "Interface Power";
  127. break;
  128. case USB_DT_OTG:
  129. s = "OTG";
  130. break;
  131. case USB_DT_DEBUG:
  132. s = "Debug";
  133. break;
  134. case USB_DT_INTERFACE_ASSOCIATION:
  135. s = "Interface Association";
  136. break;
  137. case USB_DT_BOS:
  138. s = "BOS";
  139. break;
  140. case USB_DT_DEVICE_CAPABILITY:
  141. s = "Device Capability";
  142. break;
  143. case USB_DT_PIPE_USAGE:
  144. s = "Pipe Usage";
  145. break;
  146. case USB_DT_SS_ENDPOINT_COMP:
  147. s = "SS Endpoint Companion";
  148. break;
  149. case USB_DT_SSP_ISOC_ENDPOINT_COMP:
  150. s = "SSP Isochronous Endpoint Companion";
  151. break;
  152. default:
  153. s = "UNKNOWN";
  154. break;
  155. }
  156. snprintf(str, size, "%s %s Descriptor(Index = %d, Length = %d)",
  157. bRequest == USB_REQ_GET_DESCRIPTOR ? "Get" : "Set",
  158. s, wValue & 0xff, wLength);
  159. }
  160. static void usb_decode_get_configuration(__u16 wLength, char *str, size_t size)
  161. {
  162. snprintf(str, size, "Get Configuration(Length = %d)", wLength);
  163. }
  164. static void usb_decode_set_configuration(__u8 wValue, char *str, size_t size)
  165. {
  166. snprintf(str, size, "Set Configuration(Config = %d)", wValue);
  167. }
  168. static void usb_decode_get_intf(__u16 wIndex, __u16 wLength, char *str,
  169. size_t size)
  170. {
  171. snprintf(str, size, "Get Interface(Intf = %d, Length = %d)",
  172. wIndex, wLength);
  173. }
  174. static void usb_decode_set_intf(__u8 wValue, __u16 wIndex, char *str,
  175. size_t size)
  176. {
  177. snprintf(str, size, "Set Interface(Intf = %d, Alt.Setting = %d)",
  178. wIndex, wValue);
  179. }
  180. static void usb_decode_synch_frame(__u16 wIndex, __u16 wLength,
  181. char *str, size_t size)
  182. {
  183. snprintf(str, size, "Synch Frame(Endpoint = %d, Length = %d)",
  184. wIndex, wLength);
  185. }
  186. static void usb_decode_set_sel(__u16 wLength, char *str, size_t size)
  187. {
  188. snprintf(str, size, "Set SEL(Length = %d)", wLength);
  189. }
  190. static void usb_decode_set_isoch_delay(__u8 wValue, char *str, size_t size)
  191. {
  192. snprintf(str, size, "Set Isochronous Delay(Delay = %d ns)", wValue);
  193. }
  194. static void usb_decode_ctrl_generic(char *str, size_t size, __u8 bRequestType,
  195. __u8 bRequest, __u16 wValue, __u16 wIndex,
  196. __u16 wLength)
  197. {
  198. u8 recip = bRequestType & USB_RECIP_MASK;
  199. u8 type = bRequestType & USB_TYPE_MASK;
  200. snprintf(str, size,
  201. "Type=%s Recipient=%s Dir=%s bRequest=%u wValue=%u wIndex=%u wLength=%u",
  202. (type == USB_TYPE_STANDARD) ? "Standard" :
  203. (type == USB_TYPE_VENDOR) ? "Vendor" :
  204. (type == USB_TYPE_CLASS) ? "Class" : "Unknown",
  205. (recip == USB_RECIP_DEVICE) ? "Device" :
  206. (recip == USB_RECIP_INTERFACE) ? "Interface" :
  207. (recip == USB_RECIP_ENDPOINT) ? "Endpoint" : "Unknown",
  208. (bRequestType & USB_DIR_IN) ? "IN" : "OUT",
  209. bRequest, wValue, wIndex, wLength);
  210. }
  211. static void usb_decode_ctrl_standard(char *str, size_t size, __u8 bRequestType,
  212. __u8 bRequest, __u16 wValue, __u16 wIndex,
  213. __u16 wLength)
  214. {
  215. switch (bRequest) {
  216. case USB_REQ_GET_STATUS:
  217. usb_decode_get_status(bRequestType, wIndex, wLength, str, size);
  218. break;
  219. case USB_REQ_CLEAR_FEATURE:
  220. case USB_REQ_SET_FEATURE:
  221. usb_decode_set_clear_feature(bRequestType, bRequest, wValue,
  222. wIndex, str, size);
  223. break;
  224. case USB_REQ_SET_ADDRESS:
  225. usb_decode_set_address(wValue, str, size);
  226. break;
  227. case USB_REQ_GET_DESCRIPTOR:
  228. case USB_REQ_SET_DESCRIPTOR:
  229. usb_decode_get_set_descriptor(bRequestType, bRequest, wValue,
  230. wIndex, wLength, str, size);
  231. break;
  232. case USB_REQ_GET_CONFIGURATION:
  233. usb_decode_get_configuration(wLength, str, size);
  234. break;
  235. case USB_REQ_SET_CONFIGURATION:
  236. usb_decode_set_configuration(wValue, str, size);
  237. break;
  238. case USB_REQ_GET_INTERFACE:
  239. usb_decode_get_intf(wIndex, wLength, str, size);
  240. break;
  241. case USB_REQ_SET_INTERFACE:
  242. usb_decode_set_intf(wValue, wIndex, str, size);
  243. break;
  244. case USB_REQ_SYNCH_FRAME:
  245. usb_decode_synch_frame(wIndex, wLength, str, size);
  246. break;
  247. case USB_REQ_SET_SEL:
  248. usb_decode_set_sel(wLength, str, size);
  249. break;
  250. case USB_REQ_SET_ISOCH_DELAY:
  251. usb_decode_set_isoch_delay(wValue, str, size);
  252. break;
  253. default:
  254. usb_decode_ctrl_generic(str, size, bRequestType, bRequest,
  255. wValue, wIndex, wLength);
  256. break;
  257. }
  258. }
  259. /**
  260. * usb_decode_ctrl - Returns human readable representation of control request.
  261. * @str: buffer to return a human-readable representation of control request.
  262. * This buffer should have about 200 bytes.
  263. * @size: size of str buffer.
  264. * @bRequestType: matches the USB bmRequestType field
  265. * @bRequest: matches the USB bRequest field
  266. * @wValue: matches the USB wValue field (CPU byte order)
  267. * @wIndex: matches the USB wIndex field (CPU byte order)
  268. * @wLength: matches the USB wLength field (CPU byte order)
  269. *
  270. * Function returns decoded, formatted and human-readable description of
  271. * control request packet.
  272. *
  273. * The usage scenario for this is for tracepoints, so function as a return
  274. * use the same value as in parameters. This approach allows to use this
  275. * function in TP_printk
  276. *
  277. * Important: wValue, wIndex, wLength parameters before invoking this function
  278. * should be processed by le16_to_cpu macro.
  279. */
  280. const char *usb_decode_ctrl(char *str, size_t size, __u8 bRequestType,
  281. __u8 bRequest, __u16 wValue, __u16 wIndex,
  282. __u16 wLength)
  283. {
  284. switch (bRequestType & USB_TYPE_MASK) {
  285. case USB_TYPE_STANDARD:
  286. usb_decode_ctrl_standard(str, size, bRequestType, bRequest,
  287. wValue, wIndex, wLength);
  288. break;
  289. case USB_TYPE_VENDOR:
  290. case USB_TYPE_CLASS:
  291. default:
  292. usb_decode_ctrl_generic(str, size, bRequestType, bRequest,
  293. wValue, wIndex, wLength);
  294. break;
  295. }
  296. return str;
  297. }
  298. EXPORT_SYMBOL_GPL(usb_decode_ctrl);