mirror of
https://github.com/torvalds/linux.git
synced 2024-11-17 01:22:07 +00:00
usb: gadget: f_hid: added GET_IDLE and SET_IDLE handlers
The USB HID standard declares mandatory support for GET_IDLE and SET_IDLE requests for Boot Keyboard. Most hosts can handle their absence, but others like some old/strange UEFIs and BIOSes consider this a critical error and refuse to work with f_hid. This primitive implementation of saving and returning idle is sufficient to meet the requirements of the standard and these devices. Acked-by: Felipe Balbi <balbi@kernel.org> Cc: stable <stable@vger.kernel.org> Signed-off-by: Maxim Devaev <mdevaev@gmail.com> Link: https://lore.kernel.org/r/20210721180351.129450-1-mdevaev@gmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
2867652e47
commit
afcff6dc69
@ -41,6 +41,7 @@ struct f_hidg {
|
||||
unsigned char bInterfaceSubClass;
|
||||
unsigned char bInterfaceProtocol;
|
||||
unsigned char protocol;
|
||||
unsigned char idle;
|
||||
unsigned short report_desc_length;
|
||||
char *report_desc;
|
||||
unsigned short report_length;
|
||||
@ -537,6 +538,14 @@ static int hidg_setup(struct usb_function *f,
|
||||
goto respond;
|
||||
break;
|
||||
|
||||
case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
|
||||
| HID_REQ_GET_IDLE):
|
||||
VDBG(cdev, "get_idle\n");
|
||||
length = min_t(unsigned int, length, 1);
|
||||
((u8 *) req->buf)[0] = hidg->idle;
|
||||
goto respond;
|
||||
break;
|
||||
|
||||
case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
|
||||
| HID_REQ_SET_REPORT):
|
||||
VDBG(cdev, "set_report | wLength=%d\n", ctrl->wLength);
|
||||
@ -560,6 +569,14 @@ static int hidg_setup(struct usb_function *f,
|
||||
goto stall;
|
||||
break;
|
||||
|
||||
case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
|
||||
| HID_REQ_SET_IDLE):
|
||||
VDBG(cdev, "set_idle\n");
|
||||
length = 0;
|
||||
hidg->idle = value;
|
||||
goto respond;
|
||||
break;
|
||||
|
||||
case ((USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) << 8
|
||||
| USB_REQ_GET_DESCRIPTOR):
|
||||
switch (value >> 8) {
|
||||
@ -787,6 +804,7 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass;
|
||||
hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol;
|
||||
hidg->protocol = HID_REPORT_PROTOCOL;
|
||||
hidg->idle = 1;
|
||||
hidg_ss_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
|
||||
hidg_ss_in_comp_desc.wBytesPerInterval =
|
||||
cpu_to_le16(hidg->report_length);
|
||||
|
Loading…
Reference in New Issue
Block a user