Commit b3c4ec71 authored by Abdulhadi Mohamed's avatar Abdulhadi Mohamed Committed by Felipe Balbi

usb: gadget: f_hid: {GET,SET} PROTOCOL Support

The current f_hid driver doesn't handle GET_PROCOTOL and
SET_PROCOTOL requests, which are required to operate HID
gadgets in BOOT mode. This patch implements this feature for
devices that have the same implementation for REPORT and BOOT mode
so that these devices are recognized by older BIOSes.
Signed-off-by: default avatarAbdulhadi Mohamed <abdulahhadi2@gmail.com>
Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
parent 4a10a937
...@@ -44,6 +44,7 @@ struct f_hidg { ...@@ -44,6 +44,7 @@ struct f_hidg {
/* configuration */ /* configuration */
unsigned char bInterfaceSubClass; unsigned char bInterfaceSubClass;
unsigned char bInterfaceProtocol; unsigned char bInterfaceProtocol;
unsigned char protocol;
unsigned short report_desc_length; unsigned short report_desc_length;
char *report_desc; char *report_desc;
unsigned short report_length; unsigned short report_length;
...@@ -527,7 +528,9 @@ static int hidg_setup(struct usb_function *f, ...@@ -527,7 +528,9 @@ static int hidg_setup(struct usb_function *f,
case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
| HID_REQ_GET_PROTOCOL): | HID_REQ_GET_PROTOCOL):
VDBG(cdev, "get_protocol\n"); VDBG(cdev, "get_protocol\n");
goto stall; length = min_t(unsigned int, length, 1);
((u8 *) req->buf)[0] = hidg->protocol;
goto respond;
break; break;
case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
...@@ -539,6 +542,17 @@ static int hidg_setup(struct usb_function *f, ...@@ -539,6 +542,17 @@ static int hidg_setup(struct usb_function *f,
case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
| HID_REQ_SET_PROTOCOL): | HID_REQ_SET_PROTOCOL):
VDBG(cdev, "set_protocol\n"); VDBG(cdev, "set_protocol\n");
if (value > HID_REPORT_PROTOCOL)
goto stall;
length = 0;
/*
* We assume that programs implementing the Boot protocol
* are also compatible with the Report Protocol
*/
if (hidg->bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT) {
hidg->protocol = value;
goto respond;
}
goto stall; goto stall;
break; break;
...@@ -768,6 +782,7 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) ...@@ -768,6 +782,7 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
/* set descriptor dynamic values */ /* set descriptor dynamic values */
hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass; hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass;
hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol; hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol;
hidg->protocol = HID_REPORT_PROTOCOL;
hidg_ss_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); hidg_ss_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length);
hidg_ss_in_comp_desc.wBytesPerInterval = hidg_ss_in_comp_desc.wBytesPerInterval =
cpu_to_le16(hidg->report_length); cpu_to_le16(hidg->report_length);
......
...@@ -362,6 +362,12 @@ struct hid_item { ...@@ -362,6 +362,12 @@ struct hid_item {
#define HID_GROUP_WACOM 0x0101 #define HID_GROUP_WACOM 0x0101
#define HID_GROUP_LOGITECH_DJ_DEVICE 0x0102 #define HID_GROUP_LOGITECH_DJ_DEVICE 0x0102
/*
* HID protocol status
*/
#define HID_REPORT_PROTOCOL 1
#define HID_BOOT_PROTOCOL 0
/* /*
* This is the global environment of the parser. This information is * This is the global environment of the parser. This information is
* persistent for main-items. The global environment can be saved and * persistent for main-items. The global environment can be saved and
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment