[PATCH v12 5/6] usb: gadget: arm the function for triggering remote wakeup

From: Elson Roy Serrao
Date: Thu Mar 16 2023 - 19:39:32 EST


When host sends function suspend feature selector to the device,
arm the function for remote wakeup based on the received packet.
Also host queries the function wakeup capability through a get
status request. Handle such requests in composite layer for cases
where function driver has not exposed a get_status callback.

Signed-off-by: Elson Roy Serrao <quic_eserrao@xxxxxxxxxxx>
---
drivers/usb/gadget/composite.c | 26 +++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 2111732..2c1100e 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -2006,9 +2006,20 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
f = cdev->config->interface[intf];
if (!f)
break;
- status = f->get_status ? f->get_status(f) : 0;
- if (status < 0)
- break;
+
+ if (f->get_status) {
+ status = f->get_status(f);
+ if (status < 0)
+ break;
+ } else {
+ /* Set D0 and D1 bits based on func wakeup capability */
+ if (f->config->bmAttributes & USB_CONFIG_ATT_WAKEUP) {
+ status |= USB_INTRF_STAT_FUNC_RW_CAP;
+ if (f->func_wakeup_armed)
+ status |= USB_INTRF_STAT_FUNC_RW;
+ }
+ }
+
put_unaligned_le16(status & 0x0000ffff, req->buf);
break;
/*
@@ -2029,6 +2040,15 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
f = cdev->config->interface[intf];
if (!f)
break;
+
+ if (w_index & USB_INTRF_FUNC_SUSPEND_RW) {
+ if (!(f->config->bmAttributes &
+ USB_CONFIG_ATT_WAKEUP))
+ break;
+ f->func_wakeup_armed = (ctrl->bRequest ==
+ USB_REQ_SET_FEATURE);
+ }
+
value = 0;
if (f->func_suspend)
value = f->func_suspend(f, w_index >> 8);
--
2.7.4