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