Skip to content

Commit a8141da

Browse files
jlianadamshiervani
authored andcommitted
feat(usb): gadget: f_hid: add wakeup_on_write support (#57)
* usb: gadget: f_hid: add wakeup_on_write support Add an opt-in wakeup_on_write configfs attribute to the HID function driver. When enabled, each write to /dev/hidgN calls usb_gadget_wakeup() before queuing the USB request, allowing HID input to wake a suspended host. The configuration descriptor must also advertise remote wakeup capability (bmAttributes bit 5) for the host to arm the feature during enumeration. This is useful for KVM-over-IP devices that need to wake a sleeping host machine by sending keyboard or mouse input. Tested on JetKVM v2 (RV1106 SoC, DWC3 v3.30a) waking a Windows 11 host from S3 sleep via Intel xHCI USB 3.1 controller. Host wakes in ~4 seconds from HID keystroke. Closes: jetkvm/kvm#120 Closes: jetkvm/kvm#674 * fix: guard func.config dereference in f_hidg_write Move the hidg->func.config->cdev dereference inside the wakeup_on_write guard block and add a NULL check on func.config before accessing cdev. This prevents a potential NULL pointer dereference if f_hidg_write races with unbind, where func.config can be NULL before the spinlock is acquired. The cdev variable was only used for the wakeup call, so scoping it to the guard block is safe.
1 parent 802ad20 commit a8141da

2 files changed

Lines changed: 19 additions & 0 deletions

File tree

sysdrv/source/kernel/drivers/usb/gadget/function/f_hid.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ struct f_hidg {
5454
* will be used to receive reports.
5555
*/
5656
bool use_out_ep;
57+
/* attempt to wake the host when writing a report */
58+
bool wakeup_on_write;
5759

5860
/* recv report */
5961
spinlock_t read_spinlock;
@@ -434,6 +436,19 @@ static ssize_t f_hidg_write(struct file *file, const char __user *buffer,
434436
unsigned long flags;
435437
ssize_t status = -ENOMEM;
436438

439+
/*
440+
* Try to wake the host if it suspended the bus. The wakeup request
441+
* is only honoured when the host has negotiated remote-wakeup during
442+
* enumeration (indicated by the bmAttributes remote-wakeup bit in the
443+
* configuration descriptor). If the UDC or the host does not support
444+
* wakeup the call simply returns an error we can safely ignore.
445+
*/
446+
if (hidg->wakeup_on_write && hidg->func.config) {
447+
struct usb_composite_dev *cdev = hidg->func.config->cdev;
448+
if (cdev && cdev->gadget)
449+
usb_gadget_wakeup(cdev->gadget);
450+
}
451+
437452
spin_lock_irqsave(&hidg->write_spinlock, flags);
438453

439454
if (!hidg->req) {
@@ -1097,6 +1112,7 @@ CONFIGFS_ATTR(f_hid_opts_, name)
10971112
F_HID_OPT(subclass, 8, 255);
10981113
F_HID_OPT(protocol, 8, 255);
10991114
F_HID_OPT(no_out_endpoint, 8, 1);
1115+
F_HID_OPT(wakeup_on_write, 8, 1);
11001116
F_HID_OPT(report_length, 16, 65535);
11011117

11021118
static ssize_t f_hid_opts_report_desc_show(struct config_item *item, char *page)
@@ -1157,6 +1173,7 @@ static struct configfs_attribute *hid_attrs[] = {
11571173
&f_hid_opts_attr_subclass,
11581174
&f_hid_opts_attr_protocol,
11591175
&f_hid_opts_attr_no_out_endpoint,
1176+
&f_hid_opts_attr_wakeup_on_write,
11601177
&f_hid_opts_attr_report_length,
11611178
&f_hid_opts_attr_report_desc,
11621179
&f_hid_opts_attr_dev,
@@ -1297,6 +1314,7 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi)
12971314
}
12981315
}
12991316
hidg->use_out_ep = !opts->no_out_endpoint;
1317+
hidg->wakeup_on_write = opts->wakeup_on_write;
13001318

13011319
mutex_unlock(&opts->lock);
13021320

sysdrv/source/kernel/drivers/usb/gadget/function/u_hid.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct f_hid_opts {
2121
unsigned char subclass;
2222
unsigned char protocol;
2323
unsigned char no_out_endpoint;
24+
unsigned char wakeup_on_write;
2425
unsigned short report_length;
2526
unsigned short report_desc_length;
2627
unsigned char *report_desc;

0 commit comments

Comments
 (0)