Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Common USB debugging functions
0004  *
0005  * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com
0006  *
0007  * Authors: Felipe Balbi <balbi@ti.com>,
0008  *      Sebastian Andrzej Siewior <bigeasy@linutronix.de>
0009  */
0010 
0011 #include <linux/kernel.h>
0012 #include <linux/usb/ch9.h>
0013 
0014 static void usb_decode_get_status(__u8 bRequestType, __u16 wIndex,
0015                   __u16 wLength, char *str, size_t size)
0016 {
0017     switch (bRequestType & USB_RECIP_MASK) {
0018     case USB_RECIP_DEVICE:
0019         snprintf(str, size, "Get Device Status(Length = %d)", wLength);
0020         break;
0021     case USB_RECIP_INTERFACE:
0022         snprintf(str, size,
0023              "Get Interface Status(Intf = %d, Length = %d)",
0024              wIndex, wLength);
0025         break;
0026     case USB_RECIP_ENDPOINT:
0027         snprintf(str, size, "Get Endpoint Status(ep%d%s)",
0028              wIndex & ~USB_DIR_IN,
0029              wIndex & USB_DIR_IN ? "in" : "out");
0030         break;
0031     }
0032 }
0033 
0034 static const char *usb_decode_device_feature(u16 wValue)
0035 {
0036     switch (wValue) {
0037     case USB_DEVICE_SELF_POWERED:
0038         return "Self Powered";
0039     case USB_DEVICE_REMOTE_WAKEUP:
0040         return "Remote Wakeup";
0041     case USB_DEVICE_TEST_MODE:
0042         return "Test Mode";
0043     case USB_DEVICE_U1_ENABLE:
0044         return "U1 Enable";
0045     case USB_DEVICE_U2_ENABLE:
0046         return "U2 Enable";
0047     case USB_DEVICE_LTM_ENABLE:
0048         return "LTM Enable";
0049     default:
0050         return "UNKNOWN";
0051     }
0052 }
0053 
0054 static const char *usb_decode_test_mode(u16 wIndex)
0055 {
0056     switch (wIndex) {
0057     case USB_TEST_J:
0058         return ": TEST_J";
0059     case USB_TEST_K:
0060         return ": TEST_K";
0061     case USB_TEST_SE0_NAK:
0062         return ": TEST_SE0_NAK";
0063     case USB_TEST_PACKET:
0064         return ": TEST_PACKET";
0065     case USB_TEST_FORCE_ENABLE:
0066         return ": TEST_FORCE_EN";
0067     default:
0068         return ": UNKNOWN";
0069     }
0070 }
0071 
0072 static void usb_decode_set_clear_feature(__u8 bRequestType,
0073                      __u8 bRequest, __u16 wValue,
0074                      __u16 wIndex, char *str, size_t size)
0075 {
0076     switch (bRequestType & USB_RECIP_MASK) {
0077     case USB_RECIP_DEVICE:
0078         snprintf(str, size, "%s Device Feature(%s%s)",
0079              bRequest == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set",
0080              usb_decode_device_feature(wValue),
0081              wValue == USB_DEVICE_TEST_MODE ?
0082              usb_decode_test_mode(wIndex) : "");
0083         break;
0084     case USB_RECIP_INTERFACE:
0085         snprintf(str, size, "%s Interface Feature(%s)",
0086              bRequest == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set",
0087              wValue == USB_INTRF_FUNC_SUSPEND ?
0088              "Function Suspend" : "UNKNOWN");
0089         break;
0090     case USB_RECIP_ENDPOINT:
0091         snprintf(str, size, "%s Endpoint Feature(%s ep%d%s)",
0092              bRequest == USB_REQ_CLEAR_FEATURE ? "Clear" : "Set",
0093              wValue == USB_ENDPOINT_HALT ? "Halt" : "UNKNOWN",
0094              wIndex & ~USB_DIR_IN,
0095              wIndex & USB_DIR_IN ? "in" : "out");
0096         break;
0097     }
0098 }
0099 
0100 static void usb_decode_set_address(__u16 wValue, char *str, size_t size)
0101 {
0102     snprintf(str, size, "Set Address(Addr = %02x)", wValue);
0103 }
0104 
0105 static void usb_decode_get_set_descriptor(__u8 bRequestType, __u8 bRequest,
0106                       __u16 wValue, __u16 wIndex,
0107                       __u16 wLength, char *str, size_t size)
0108 {
0109     char *s;
0110 
0111     switch (wValue >> 8) {
0112     case USB_DT_DEVICE:
0113         s = "Device";
0114         break;
0115     case USB_DT_CONFIG:
0116         s = "Configuration";
0117         break;
0118     case USB_DT_STRING:
0119         s = "String";
0120         break;
0121     case USB_DT_INTERFACE:
0122         s = "Interface";
0123         break;
0124     case USB_DT_ENDPOINT:
0125         s = "Endpoint";
0126         break;
0127     case USB_DT_DEVICE_QUALIFIER:
0128         s = "Device Qualifier";
0129         break;
0130     case USB_DT_OTHER_SPEED_CONFIG:
0131         s = "Other Speed Config";
0132         break;
0133     case USB_DT_INTERFACE_POWER:
0134         s = "Interface Power";
0135         break;
0136     case USB_DT_OTG:
0137         s = "OTG";
0138         break;
0139     case USB_DT_DEBUG:
0140         s = "Debug";
0141         break;
0142     case USB_DT_INTERFACE_ASSOCIATION:
0143         s = "Interface Association";
0144         break;
0145     case USB_DT_BOS:
0146         s = "BOS";
0147         break;
0148     case USB_DT_DEVICE_CAPABILITY:
0149         s = "Device Capability";
0150         break;
0151     case USB_DT_PIPE_USAGE:
0152         s = "Pipe Usage";
0153         break;
0154     case USB_DT_SS_ENDPOINT_COMP:
0155         s = "SS Endpoint Companion";
0156         break;
0157     case USB_DT_SSP_ISOC_ENDPOINT_COMP:
0158         s = "SSP Isochronous Endpoint Companion";
0159         break;
0160     default:
0161         s = "UNKNOWN";
0162         break;
0163     }
0164 
0165     snprintf(str, size, "%s %s Descriptor(Index = %d, Length = %d)",
0166         bRequest == USB_REQ_GET_DESCRIPTOR ? "Get" : "Set",
0167         s, wValue & 0xff, wLength);
0168 }
0169 
0170 static void usb_decode_get_configuration(__u16 wLength, char *str, size_t size)
0171 {
0172     snprintf(str, size, "Get Configuration(Length = %d)", wLength);
0173 }
0174 
0175 static void usb_decode_set_configuration(__u8 wValue, char *str, size_t size)
0176 {
0177     snprintf(str, size, "Set Configuration(Config = %d)", wValue);
0178 }
0179 
0180 static void usb_decode_get_intf(__u16 wIndex, __u16 wLength, char *str,
0181                 size_t size)
0182 {
0183     snprintf(str, size, "Get Interface(Intf = %d, Length = %d)",
0184          wIndex, wLength);
0185 }
0186 
0187 static void usb_decode_set_intf(__u8 wValue, __u16 wIndex, char *str,
0188                 size_t size)
0189 {
0190     snprintf(str, size, "Set Interface(Intf = %d, Alt.Setting = %d)",
0191          wIndex, wValue);
0192 }
0193 
0194 static void usb_decode_synch_frame(__u16 wIndex, __u16 wLength,
0195                    char *str, size_t size)
0196 {
0197     snprintf(str, size, "Synch Frame(Endpoint = %d, Length = %d)",
0198          wIndex, wLength);
0199 }
0200 
0201 static void usb_decode_set_sel(__u16 wLength, char *str, size_t size)
0202 {
0203     snprintf(str, size, "Set SEL(Length = %d)", wLength);
0204 }
0205 
0206 static void usb_decode_set_isoch_delay(__u8 wValue, char *str, size_t size)
0207 {
0208     snprintf(str, size, "Set Isochronous Delay(Delay = %d ns)", wValue);
0209 }
0210 
0211 /**
0212  * usb_decode_ctrl - Returns human readable representation of control request.
0213  * @str: buffer to return a human-readable representation of control request.
0214  *       This buffer should have about 200 bytes.
0215  * @size: size of str buffer.
0216  * @bRequestType: matches the USB bmRequestType field
0217  * @bRequest: matches the USB bRequest field
0218  * @wValue: matches the USB wValue field (CPU byte order)
0219  * @wIndex: matches the USB wIndex field (CPU byte order)
0220  * @wLength: matches the USB wLength field (CPU byte order)
0221  *
0222  * Function returns decoded, formatted and human-readable description of
0223  * control request packet.
0224  *
0225  * The usage scenario for this is for tracepoints, so function as a return
0226  * use the same value as in parameters. This approach allows to use this
0227  * function in TP_printk
0228  *
0229  * Important: wValue, wIndex, wLength parameters before invoking this function
0230  * should be processed by le16_to_cpu macro.
0231  */
0232 const char *usb_decode_ctrl(char *str, size_t size, __u8 bRequestType,
0233                 __u8 bRequest, __u16 wValue, __u16 wIndex,
0234                 __u16 wLength)
0235 {
0236     switch (bRequest) {
0237     case USB_REQ_GET_STATUS:
0238         usb_decode_get_status(bRequestType, wIndex, wLength, str, size);
0239         break;
0240     case USB_REQ_CLEAR_FEATURE:
0241     case USB_REQ_SET_FEATURE:
0242         usb_decode_set_clear_feature(bRequestType, bRequest, wValue,
0243                          wIndex, str, size);
0244         break;
0245     case USB_REQ_SET_ADDRESS:
0246         usb_decode_set_address(wValue, str, size);
0247         break;
0248     case USB_REQ_GET_DESCRIPTOR:
0249     case USB_REQ_SET_DESCRIPTOR:
0250         usb_decode_get_set_descriptor(bRequestType, bRequest, wValue,
0251                           wIndex, wLength, str, size);
0252         break;
0253     case USB_REQ_GET_CONFIGURATION:
0254         usb_decode_get_configuration(wLength, str, size);
0255         break;
0256     case USB_REQ_SET_CONFIGURATION:
0257         usb_decode_set_configuration(wValue, str, size);
0258         break;
0259     case USB_REQ_GET_INTERFACE:
0260         usb_decode_get_intf(wIndex, wLength, str, size);
0261         break;
0262     case USB_REQ_SET_INTERFACE:
0263         usb_decode_set_intf(wValue, wIndex, str, size);
0264         break;
0265     case USB_REQ_SYNCH_FRAME:
0266         usb_decode_synch_frame(wIndex, wLength, str, size);
0267         break;
0268     case USB_REQ_SET_SEL:
0269         usb_decode_set_sel(wLength, str, size);
0270         break;
0271     case USB_REQ_SET_ISOCH_DELAY:
0272         usb_decode_set_isoch_delay(wValue, str, size);
0273         break;
0274     default:
0275         snprintf(str, size, "%02x %02x %02x %02x %02x %02x %02x %02x",
0276              bRequestType, bRequest,
0277              (u8)(cpu_to_le16(wValue) & 0xff),
0278              (u8)(cpu_to_le16(wValue) >> 8),
0279              (u8)(cpu_to_le16(wIndex) & 0xff),
0280              (u8)(cpu_to_le16(wIndex) >> 8),
0281              (u8)(cpu_to_le16(wLength) & 0xff),
0282              (u8)(cpu_to_le16(wLength) >> 8));
0283     }
0284 
0285     return str;
0286 }
0287 EXPORT_SYMBOL_GPL(usb_decode_ctrl);