Skip to content

Commit 5977a58

Browse files
Prashanth Kgregkh
authored andcommitted
usb: gadget: Use get_status callback to set remote wakeup capability
Currently when the host sends GET_STATUS request for an interface, we use get_status callbacks to set/clear remote wakeup capability of that interface. And if get_status callback isn't present for that interface, then we assume its remote wakeup capability based on bmAttributes. Now consider a scenario, where we have a USB configuration with multiple interfaces (say ECM + ADB), here ECM is remote wakeup capable and as of now ADB isn't. And bmAttributes will indicate the device as wakeup capable. With the current implementation, when host sends GET_STATUS request for both interfaces, we will set FUNC_RW_CAP for both. This results in USB3 CV Chapter 9.15 (Function Remote Wakeup Test) failures as host expects remote wakeup from both interfaces. The above scenario is just an example, and the failure can be observed if we use configuration with any interface except ECM. Hence avoid configuring remote wakeup capability from composite driver based on bmAttributes, instead use get_status callbacks and let the function drivers decide this. Cc: stable <stable@kernel.org> Fixes: 481c225 ("usb: gadget: Handle function suspend feature selector") Signed-off-by: Prashanth K <prashanth.k@oss.qualcomm.com> Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Link: https://lore.kernel.org/r/20250422103231.1954387-3-prashanth.k@oss.qualcomm.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 8e38202 commit 5977a58

File tree

1 file changed

+5
-7
lines changed

1 file changed

+5
-7
lines changed

drivers/usb/gadget/composite.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2011,15 +2011,13 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
20112011

20122012
if (f->get_status) {
20132013
status = f->get_status(f);
2014+
20142015
if (status < 0)
20152016
break;
2016-
} else {
2017-
/* Set D0 and D1 bits based on func wakeup capability */
2018-
if (f->config->bmAttributes & USB_CONFIG_ATT_WAKEUP) {
2019-
status |= USB_INTRF_STAT_FUNC_RW_CAP;
2020-
if (f->func_wakeup_armed)
2021-
status |= USB_INTRF_STAT_FUNC_RW;
2022-
}
2017+
2018+
/* if D5 is not set, then device is not wakeup capable */
2019+
if (!(f->config->bmAttributes & USB_CONFIG_ATT_WAKEUP))
2020+
status &= ~(USB_INTRF_STAT_FUNC_RW_CAP | USB_INTRF_STAT_FUNC_RW);
20232021
}
20242022

20252023
put_unaligned_le16(status & 0x0000ffff, req->buf);

0 commit comments

Comments
 (0)