123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- // SPDX-License-Identifier: GPL-2.0
- /*
- * Common USB debugging functions
- *
- * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com
- *
- * Authors: Felipe Balbi <[email protected]>,
- * Sebastian Andrzej Siewior <[email protected]>
- */
- #include <linux/kernel.h>
- #include <linux/usb/ch9.h>
- static void usb_decode_get_status(__u8 bRequestType, __u16 wIndex,
- __u16 wLength, char *str, size_t size)
- {
- switch (bRequestType & USB_RECIP_MASK) {
- case USB_RECIP_DEVICE:
- snprintf(str, size, "Get Device Status(Length = %d)", wLength);
- break;
- case USB_RECIP_INTERFACE:
- snprintf(str, size,
- "Get Interface Status(Intf = %d, Length = %d)",
- wIndex, wLength);
- break;
- case USB_RECIP_ENDPOINT:
- snprintf(str, size, "Get Endpoint Status(ep%d%s)",
- wIndex & ~USB_DIR_IN,
- wIndex & USB_DIR_IN ? "in" : "out");
- break;
- }
- }
- static const char *usb_decode_device_feature(u16 wValue)
- {
- switch (wValue) {
- case USB_DEVICE_SELF_POWERED:
- return "Self Powered";
- case USB_DEVICE_REMOTE_WAKEUP:
- return "Remote Wakeup";
- case USB_DEVICE_TEST_MODE:
- return "Test Mode";
- case USB_DEVICE_U1_ENABLE:
- return "U1 Enable";
- case USB_DEVICE_U2_ENABLE:
- return "U2 Enable";
- case USB_DEVICE_LTM_ENABLE:
- return "LTM Enable";
- default:
- return "UNKNOWN";
- }
- }
- static const char *usb_decode_test_mode(u16 wIndex)
- {
- switch (wIndex) {
- case USB_TEST_J:
- return ": TEST_J";
- case USB_TEST_K:
- return ": TEST_K";
- case USB_TEST_SE0_NAK:
- return ": TEST_SE0_NAK";
- case USB_TEST_PACKET:
- return ": TEST_PACKET";
- case USB_TEST_FORCE_ENABLE:
- return ": TEST_FORCE_EN";
- default:
- return ": UNKNOWN";
- }
- }
- static void usb_decode_set_clear_feature(__u8 bRequestType,
- __u8 bRequest, __u16 wValue,
- __u16 wIndex, char *str, size_t size)
- {
- switch (bRequestType & USB_RECIP_MASK) {
- case USB_RECIP_DEVICE:
- snprintf(str, size, "%s Device Feature(%s%s)",
- bRequest == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set",
- usb_decode_device_feature(wValue),
- wValue == USB_DEVICE_TEST_MODE ?
- usb_decode_test_mode(wIndex) : "");
- break;
- case USB_RECIP_INTERFACE:
- snprintf(str, size, "%s Interface Feature(%s)",
- bRequest == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set",
- wValue == USB_INTRF_FUNC_SUSPEND ?
- "Function Suspend" : "UNKNOWN");
- break;
- case USB_RECIP_ENDPOINT:
- snprintf(str, size, "%s Endpoint Feature(%s ep%d%s)",
- bRequest == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set",
- wValue == USB_ENDPOINT_HALT ? "Halt" : "UNKNOWN",
- wIndex & ~USB_DIR_IN,
- wIndex & USB_DIR_IN ? "in" : "out");
- break;
- }
- }
- static void usb_decode_set_address(__u16 wValue, char *str, size_t size)
- {
- snprintf(str, size, "Set Address(Addr = %02x)", wValue);
- }
- static void usb_decode_get_set_descriptor(__u8 bRequestType, __u8 bRequest,
- __u16 wValue, __u16 wIndex,
- __u16 wLength, char *str, size_t size)
- {
- char *s;
- switch (wValue >> 8) {
- case USB_DT_DEVICE:
- s = "Device";
- break;
- case USB_DT_CONFIG:
- s = "Configuration";
- break;
- case USB_DT_STRING:
- s = "String";
- break;
- case USB_DT_INTERFACE:
- s = "Interface";
- break;
- case USB_DT_ENDPOINT:
- s = "Endpoint";
- break;
- case USB_DT_DEVICE_QUALIFIER:
- s = "Device Qualifier";
- break;
- case USB_DT_OTHER_SPEED_CONFIG:
- s = "Other Speed Config";
- break;
- case USB_DT_INTERFACE_POWER:
- s = "Interface Power";
- break;
- case USB_DT_OTG:
- s = "OTG";
- break;
- case USB_DT_DEBUG:
- s = "Debug";
- break;
- case USB_DT_INTERFACE_ASSOCIATION:
- s = "Interface Association";
- break;
- case USB_DT_BOS:
- s = "BOS";
- break;
- case USB_DT_DEVICE_CAPABILITY:
- s = "Device Capability";
- break;
- case USB_DT_PIPE_USAGE:
- s = "Pipe Usage";
- break;
- case USB_DT_SS_ENDPOINT_COMP:
- s = "SS Endpoint Companion";
- break;
- case USB_DT_SSP_ISOC_ENDPOINT_COMP:
- s = "SSP Isochronous Endpoint Companion";
- break;
- default:
- s = "UNKNOWN";
- break;
- }
- snprintf(str, size, "%s %s Descriptor(Index = %d, Length = %d)",
- bRequest == USB_REQ_GET_DESCRIPTOR ? "Get" : "Set",
- s, wValue & 0xff, wLength);
- }
- static void usb_decode_get_configuration(__u16 wLength, char *str, size_t size)
- {
- snprintf(str, size, "Get Configuration(Length = %d)", wLength);
- }
- static void usb_decode_set_configuration(__u8 wValue, char *str, size_t size)
- {
- snprintf(str, size, "Set Configuration(Config = %d)", wValue);
- }
- static void usb_decode_get_intf(__u16 wIndex, __u16 wLength, char *str,
- size_t size)
- {
- snprintf(str, size, "Get Interface(Intf = %d, Length = %d)",
- wIndex, wLength);
- }
- static void usb_decode_set_intf(__u8 wValue, __u16 wIndex, char *str,
- size_t size)
- {
- snprintf(str, size, "Set Interface(Intf = %d, Alt.Setting = %d)",
- wIndex, wValue);
- }
- static void usb_decode_synch_frame(__u16 wIndex, __u16 wLength,
- char *str, size_t size)
- {
- snprintf(str, size, "Synch Frame(Endpoint = %d, Length = %d)",
- wIndex, wLength);
- }
- static void usb_decode_set_sel(__u16 wLength, char *str, size_t size)
- {
- snprintf(str, size, "Set SEL(Length = %d)", wLength);
- }
- static void usb_decode_set_isoch_delay(__u8 wValue, char *str, size_t size)
- {
- snprintf(str, size, "Set Isochronous Delay(Delay = %d ns)", wValue);
- }
- static void usb_decode_ctrl_generic(char *str, size_t size, __u8 bRequestType,
- __u8 bRequest, __u16 wValue, __u16 wIndex,
- __u16 wLength)
- {
- u8 recip = bRequestType & USB_RECIP_MASK;
- u8 type = bRequestType & USB_TYPE_MASK;
- snprintf(str, size,
- "Type=%s Recipient=%s Dir=%s bRequest=%u wValue=%u wIndex=%u wLength=%u",
- (type == USB_TYPE_STANDARD) ? "Standard" :
- (type == USB_TYPE_VENDOR) ? "Vendor" :
- (type == USB_TYPE_CLASS) ? "Class" : "Unknown",
- (recip == USB_RECIP_DEVICE) ? "Device" :
- (recip == USB_RECIP_INTERFACE) ? "Interface" :
- (recip == USB_RECIP_ENDPOINT) ? "Endpoint" : "Unknown",
- (bRequestType & USB_DIR_IN) ? "IN" : "OUT",
- bRequest, wValue, wIndex, wLength);
- }
- static void usb_decode_ctrl_standard(char *str, size_t size, __u8 bRequestType,
- __u8 bRequest, __u16 wValue, __u16 wIndex,
- __u16 wLength)
- {
- switch (bRequest) {
- case USB_REQ_GET_STATUS:
- usb_decode_get_status(bRequestType, wIndex, wLength, str, size);
- break;
- case USB_REQ_CLEAR_FEATURE:
- case USB_REQ_SET_FEATURE:
- usb_decode_set_clear_feature(bRequestType, bRequest, wValue,
- wIndex, str, size);
- break;
- case USB_REQ_SET_ADDRESS:
- usb_decode_set_address(wValue, str, size);
- break;
- case USB_REQ_GET_DESCRIPTOR:
- case USB_REQ_SET_DESCRIPTOR:
- usb_decode_get_set_descriptor(bRequestType, bRequest, wValue,
- wIndex, wLength, str, size);
- break;
- case USB_REQ_GET_CONFIGURATION:
- usb_decode_get_configuration(wLength, str, size);
- break;
- case USB_REQ_SET_CONFIGURATION:
- usb_decode_set_configuration(wValue, str, size);
- break;
- case USB_REQ_GET_INTERFACE:
- usb_decode_get_intf(wIndex, wLength, str, size);
- break;
- case USB_REQ_SET_INTERFACE:
- usb_decode_set_intf(wValue, wIndex, str, size);
- break;
- case USB_REQ_SYNCH_FRAME:
- usb_decode_synch_frame(wIndex, wLength, str, size);
- break;
- case USB_REQ_SET_SEL:
- usb_decode_set_sel(wLength, str, size);
- break;
- case USB_REQ_SET_ISOCH_DELAY:
- usb_decode_set_isoch_delay(wValue, str, size);
- break;
- default:
- usb_decode_ctrl_generic(str, size, bRequestType, bRequest,
- wValue, wIndex, wLength);
- break;
- }
- }
- /**
- * usb_decode_ctrl - Returns human readable representation of control request.
- * @str: buffer to return a human-readable representation of control request.
- * This buffer should have about 200 bytes.
- * @size: size of str buffer.
- * @bRequestType: matches the USB bmRequestType field
- * @bRequest: matches the USB bRequest field
- * @wValue: matches the USB wValue field (CPU byte order)
- * @wIndex: matches the USB wIndex field (CPU byte order)
- * @wLength: matches the USB wLength field (CPU byte order)
- *
- * Function returns decoded, formatted and human-readable description of
- * control request packet.
- *
- * The usage scenario for this is for tracepoints, so function as a return
- * use the same value as in parameters. This approach allows to use this
- * function in TP_printk
- *
- * Important: wValue, wIndex, wLength parameters before invoking this function
- * should be processed by le16_to_cpu macro.
- */
- const char *usb_decode_ctrl(char *str, size_t size, __u8 bRequestType,
- __u8 bRequest, __u16 wValue, __u16 wIndex,
- __u16 wLength)
- {
- switch (bRequestType & USB_TYPE_MASK) {
- case USB_TYPE_STANDARD:
- usb_decode_ctrl_standard(str, size, bRequestType, bRequest,
- wValue, wIndex, wLength);
- break;
- case USB_TYPE_VENDOR:
- case USB_TYPE_CLASS:
- default:
- usb_decode_ctrl_generic(str, size, bRequestType, bRequest,
- wValue, wIndex, wLength);
- break;
- }
- return str;
- }
- EXPORT_SYMBOL_GPL(usb_decode_ctrl);
|