Skip to content

Commit

Permalink
usb: common: debug: Check non-standard control requests
Browse files Browse the repository at this point in the history
[ Upstream commit b6155ea ]

Previously usb_decode_ctrl() only decodes standard control requests, but
it was used for non-standard requests also. If it's non-standard or
unknown standard bRequest, print the Setup data values.

Fixes: af32423 ("usb: dwc3: trace: decode ctrl request")
Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Link: https://lore.kernel.org/r/8d6a30f2f2f953eff833a5bc5aac640a4cc2fc9f.1658971571.git.Thinh.Nguyen@synopsys.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Thinh Nguyen authored and gregkh committed Oct 21, 2022
1 parent a0bd43b commit b62f30a
Showing 1 changed file with 64 additions and 32 deletions.
96 changes: 64 additions & 32 deletions drivers/usb/common/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,30 +208,28 @@ static void usb_decode_set_isoch_delay(__u8 wValue, char *str, size_t size)
snprintf(str, size, "Set Isochronous Delay(Delay = %d ns)", wValue);
}

/**
* 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)
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:
Expand Down Expand Up @@ -272,14 +270,48 @@ const char *usb_decode_ctrl(char *str, size_t size, __u8 bRequestType,
usb_decode_set_isoch_delay(wValue, str, size);
break;
default:
snprintf(str, size, "%02x %02x %02x %02x %02x %02x %02x %02x",
bRequestType, bRequest,
(u8)(cpu_to_le16(wValue) & 0xff),
(u8)(cpu_to_le16(wValue) >> 8),
(u8)(cpu_to_le16(wIndex) & 0xff),
(u8)(cpu_to_le16(wIndex) >> 8),
(u8)(cpu_to_le16(wLength) & 0xff),
(u8)(cpu_to_le16(wLength) >> 8));
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;
Expand Down

0 comments on commit b62f30a

Please sign in to comment.