Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: gadget: f_hid: optional SETUP/SET_REPORT mode

f_hid provides the OUT Endpoint as only way for receiving reports
from the host. SETUP/SET_REPORT method is not supported, and this causes
a number of compatibility problems with various host drivers, especially
in the case of keyboard emulation using f_hid.

- Some hosts do not support the OUT Endpoint and ignore it,
so it becomes impossible for the gadget to receive a report
from the host. In the case of a keyboard, the gadget loses
the ability to receive the status of the LEDs.

- Some BIOSes/UEFIs can't work with HID devices with the OUT Endpoint
at all. This may be due to their bugs or incomplete implementation
of the HID standard.
For example, absolutely all Apple UEFIs can't handle the OUT Endpoint
if it goes after IN Endpoint in the descriptor and require the reverse
order (OUT, IN) which is a violation of the standard.
Other hosts either do not initialize gadgets with a descriptor
containing the OUT Endpoint completely (like some HP and DELL BIOSes
and embedded firmwares like on KVM switches), or initialize them,
but will not poll the IN Endpoint.

This patch adds configfs option no_out_endpoint=1 to disable
the OUT Endpoint and allows f_hid to receive reports from the host
via SETUP/SET_REPORT.

Previously, there was such a feature in f_hid, but it was replaced
by the OUT Endpoint [1] in the commit 99c515005857 ("usb: gadget: hidg:
register OUT INT endpoint for SET_REPORT"). So this patch actually
returns the removed functionality while making it optional.
For backward compatibility reasons, the OUT Endpoint mode remains
the default behaviour.

- The OUT Endpoint mode provides the report queue and reduces
USB overhead (eliminating SETUP routine) on transmitting a report
from the host.

- If the SETUP/SET_REPORT mode is used, there is no report queue,
so the userspace will only read last report. For classic HID devices
like keyboards this is not a problem, since it's intended to transmit
the status of the LEDs and only the last report is important.
This mode provides better compatibility with strange and buggy
host drivers.

Both modes passed USBCV tests. Checking with the USB protocol analyzer
also confirmed that everything is working as it should and the new mode
ensures operability in all of the described cases.

Link: https://www.spinics.net/lists/linux-usb/msg65494.html [1]
Reviewed-by: Maciej Żenczykowski <zenczykowski@gmail.com>
Acked-by: Felipe Balbi <balbi@kernel.org>
Signed-off-by: Maxim Devaev <mdevaev@gmail.com>
Link: https://lore.kernel.org/r/20210821134004.363217-1-mdevaev@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Maxim Devaev and committed by
Greg Kroah-Hartman
d7428bc2 bfa109d7

+188 -33
+187 -33
drivers/usb/gadget/function/f_hid.c
··· 45 45 unsigned short report_desc_length; 46 46 char *report_desc; 47 47 unsigned short report_length; 48 + /* 49 + * use_out_ep - if true, the OUT Endpoint (interrupt out method) 50 + * will be used to receive reports from the host 51 + * using functions with the "intout" suffix. 52 + * Otherwise, the OUT Endpoint will not be configured 53 + * and the SETUP/SET_REPORT method ("ssreport" suffix) 54 + * will be used to receive reports. 55 + */ 56 + bool use_out_ep; 48 57 49 58 /* recv report */ 50 - struct list_head completed_out_req; 51 59 spinlock_t read_spinlock; 52 60 wait_queue_head_t read_queue; 61 + /* recv report - interrupt out only (use_out_ep == 1) */ 62 + struct list_head completed_out_req; 53 63 unsigned int qlen; 64 + /* recv report - setup set_report only (use_out_ep == 0) */ 65 + char *set_report_buf; 66 + unsigned int set_report_length; 54 67 55 68 /* send report */ 56 69 spinlock_t write_spinlock; ··· 92 79 .bDescriptorType = USB_DT_INTERFACE, 93 80 /* .bInterfaceNumber = DYNAMIC */ 94 81 .bAlternateSetting = 0, 95 - .bNumEndpoints = 2, 82 + /* .bNumEndpoints = DYNAMIC (depends on use_out_ep) */ 96 83 .bInterfaceClass = USB_CLASS_HID, 97 84 /* .bInterfaceSubClass = DYNAMIC */ 98 85 /* .bInterfaceProtocol = DYNAMIC */ ··· 153 140 /* .wBytesPerInterval = DYNAMIC */ 154 141 }; 155 142 156 - static struct usb_descriptor_header *hidg_ss_descriptors[] = { 143 + static struct usb_descriptor_header *hidg_ss_descriptors_intout[] = { 157 144 (struct usb_descriptor_header *)&hidg_interface_desc, 158 145 (struct usb_descriptor_header *)&hidg_desc, 159 146 (struct usb_descriptor_header *)&hidg_ss_in_ep_desc, 160 147 (struct usb_descriptor_header *)&hidg_ss_in_comp_desc, 161 148 (struct usb_descriptor_header *)&hidg_ss_out_ep_desc, 162 149 (struct usb_descriptor_header *)&hidg_ss_out_comp_desc, 150 + NULL, 151 + }; 152 + 153 + static struct usb_descriptor_header *hidg_ss_descriptors_ssreport[] = { 154 + (struct usb_descriptor_header *)&hidg_interface_desc, 155 + (struct usb_descriptor_header *)&hidg_desc, 156 + (struct usb_descriptor_header *)&hidg_ss_in_ep_desc, 157 + (struct usb_descriptor_header *)&hidg_ss_in_comp_desc, 163 158 NULL, 164 159 }; 165 160 ··· 197 176 */ 198 177 }; 199 178 200 - static struct usb_descriptor_header *hidg_hs_descriptors[] = { 179 + static struct usb_descriptor_header *hidg_hs_descriptors_intout[] = { 201 180 (struct usb_descriptor_header *)&hidg_interface_desc, 202 181 (struct usb_descriptor_header *)&hidg_desc, 203 182 (struct usb_descriptor_header *)&hidg_hs_in_ep_desc, 204 183 (struct usb_descriptor_header *)&hidg_hs_out_ep_desc, 184 + NULL, 185 + }; 186 + 187 + static struct usb_descriptor_header *hidg_hs_descriptors_ssreport[] = { 188 + (struct usb_descriptor_header *)&hidg_interface_desc, 189 + (struct usb_descriptor_header *)&hidg_desc, 190 + (struct usb_descriptor_header *)&hidg_hs_in_ep_desc, 205 191 NULL, 206 192 }; 207 193 ··· 238 210 */ 239 211 }; 240 212 241 - static struct usb_descriptor_header *hidg_fs_descriptors[] = { 213 + static struct usb_descriptor_header *hidg_fs_descriptors_intout[] = { 242 214 (struct usb_descriptor_header *)&hidg_interface_desc, 243 215 (struct usb_descriptor_header *)&hidg_desc, 244 216 (struct usb_descriptor_header *)&hidg_fs_in_ep_desc, 245 217 (struct usb_descriptor_header *)&hidg_fs_out_ep_desc, 218 + NULL, 219 + }; 220 + 221 + static struct usb_descriptor_header *hidg_fs_descriptors_ssreport[] = { 222 + (struct usb_descriptor_header *)&hidg_interface_desc, 223 + (struct usb_descriptor_header *)&hidg_desc, 224 + (struct usb_descriptor_header *)&hidg_fs_in_ep_desc, 246 225 NULL, 247 226 }; 248 227 ··· 276 241 /*-------------------------------------------------------------------------*/ 277 242 /* Char Device */ 278 243 279 - static ssize_t f_hidg_read(struct file *file, char __user *buffer, 280 - size_t count, loff_t *ptr) 244 + static ssize_t f_hidg_intout_read(struct file *file, char __user *buffer, 245 + size_t count, loff_t *ptr) 281 246 { 282 247 struct f_hidg *hidg = file->private_data; 283 248 struct f_hidg_req_list *list; ··· 290 255 291 256 spin_lock_irqsave(&hidg->read_spinlock, flags); 292 257 293 - #define READ_COND (!list_empty(&hidg->completed_out_req)) 258 + #define READ_COND_INTOUT (!list_empty(&hidg->completed_out_req)) 294 259 295 260 /* wait for at least one buffer to complete */ 296 - while (!READ_COND) { 261 + while (!READ_COND_INTOUT) { 297 262 spin_unlock_irqrestore(&hidg->read_spinlock, flags); 298 263 if (file->f_flags & O_NONBLOCK) 299 264 return -EAGAIN; 300 265 301 - if (wait_event_interruptible(hidg->read_queue, READ_COND)) 266 + if (wait_event_interruptible(hidg->read_queue, READ_COND_INTOUT)) 302 267 return -ERESTARTSYS; 303 268 304 269 spin_lock_irqsave(&hidg->read_spinlock, flags); ··· 346 311 } 347 312 348 313 return count; 314 + } 315 + 316 + #define READ_COND_SSREPORT (hidg->set_report_buf != NULL) 317 + 318 + static ssize_t f_hidg_ssreport_read(struct file *file, char __user *buffer, 319 + size_t count, loff_t *ptr) 320 + { 321 + struct f_hidg *hidg = file->private_data; 322 + char *tmp_buf = NULL; 323 + unsigned long flags; 324 + 325 + if (!count) 326 + return 0; 327 + 328 + spin_lock_irqsave(&hidg->read_spinlock, flags); 329 + 330 + while (!READ_COND_SSREPORT) { 331 + spin_unlock_irqrestore(&hidg->read_spinlock, flags); 332 + if (file->f_flags & O_NONBLOCK) 333 + return -EAGAIN; 334 + 335 + if (wait_event_interruptible(hidg->read_queue, READ_COND_SSREPORT)) 336 + return -ERESTARTSYS; 337 + 338 + spin_lock_irqsave(&hidg->read_spinlock, flags); 339 + } 340 + 341 + count = min_t(unsigned int, count, hidg->set_report_length); 342 + tmp_buf = hidg->set_report_buf; 343 + hidg->set_report_buf = NULL; 344 + 345 + spin_unlock_irqrestore(&hidg->read_spinlock, flags); 346 + 347 + if (tmp_buf != NULL) { 348 + count -= copy_to_user(buffer, tmp_buf, count); 349 + kfree(tmp_buf); 350 + } else { 351 + count = -ENOMEM; 352 + } 353 + 354 + wake_up(&hidg->read_queue); 355 + 356 + return count; 357 + } 358 + 359 + static ssize_t f_hidg_read(struct file *file, char __user *buffer, 360 + size_t count, loff_t *ptr) 361 + { 362 + struct f_hidg *hidg = file->private_data; 363 + 364 + if (hidg->use_out_ep) 365 + return f_hidg_intout_read(file, buffer, count, ptr); 366 + else 367 + return f_hidg_ssreport_read(file, buffer, count, ptr); 349 368 } 350 369 351 370 static void f_hidg_req_complete(struct usb_ep *ep, struct usb_request *req) ··· 522 433 if (WRITE_COND) 523 434 ret |= EPOLLOUT | EPOLLWRNORM; 524 435 525 - if (READ_COND) 526 - ret |= EPOLLIN | EPOLLRDNORM; 436 + if (hidg->use_out_ep) { 437 + if (READ_COND_INTOUT) 438 + ret |= EPOLLIN | EPOLLRDNORM; 439 + } else { 440 + if (READ_COND_SSREPORT) 441 + ret |= EPOLLIN | EPOLLRDNORM; 442 + } 527 443 528 444 return ret; 529 445 } 530 446 531 447 #undef WRITE_COND 532 - #undef READ_COND 448 + #undef READ_COND_SSREPORT 449 + #undef READ_COND_INTOUT 533 450 534 451 static int f_hidg_release(struct inode *inode, struct file *fd) 535 452 { ··· 562 467 return alloc_ep_req(ep, length); 563 468 } 564 469 565 - static void hidg_set_report_complete(struct usb_ep *ep, struct usb_request *req) 470 + static void hidg_intout_complete(struct usb_ep *ep, struct usb_request *req) 566 471 { 567 472 struct f_hidg *hidg = (struct f_hidg *) req->context; 568 473 struct usb_composite_dev *cdev = hidg->func.config->cdev; ··· 595 500 free_ep_req(ep, req); 596 501 return; 597 502 } 503 + } 504 + 505 + static void hidg_ssreport_complete(struct usb_ep *ep, struct usb_request *req) 506 + { 507 + struct f_hidg *hidg = (struct f_hidg *)req->context; 508 + struct usb_composite_dev *cdev = hidg->func.config->cdev; 509 + char *new_buf = NULL; 510 + unsigned long flags; 511 + 512 + if (req->status != 0 || req->buf == NULL || req->actual == 0) { 513 + ERROR(cdev, 514 + "%s FAILED: status=%d, buf=%p, actual=%d\n", 515 + __func__, req->status, req->buf, req->actual); 516 + return; 517 + } 518 + 519 + spin_lock_irqsave(&hidg->read_spinlock, flags); 520 + 521 + new_buf = krealloc(hidg->set_report_buf, req->actual, GFP_ATOMIC); 522 + if (new_buf == NULL) { 523 + spin_unlock_irqrestore(&hidg->read_spinlock, flags); 524 + return; 525 + } 526 + hidg->set_report_buf = new_buf; 527 + 528 + hidg->set_report_length = req->actual; 529 + memcpy(hidg->set_report_buf, req->buf, req->actual); 530 + 531 + spin_unlock_irqrestore(&hidg->read_spinlock, flags); 532 + 533 + wake_up(&hidg->read_queue); 598 534 } 599 535 600 536 static int hidg_setup(struct usb_function *f, ··· 675 549 case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 676 550 | HID_REQ_SET_REPORT): 677 551 VDBG(cdev, "set_report | wLength=%d\n", ctrl->wLength); 678 - goto stall; 552 + if (hidg->use_out_ep) 553 + goto stall; 554 + req->complete = hidg_ssreport_complete; 555 + req->context = hidg; 556 + goto respond; 679 557 break; 680 558 681 559 case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8 ··· 767 637 unsigned long flags; 768 638 769 639 usb_ep_disable(hidg->in_ep); 770 - usb_ep_disable(hidg->out_ep); 771 640 772 - spin_lock_irqsave(&hidg->read_spinlock, flags); 773 - list_for_each_entry_safe(list, next, &hidg->completed_out_req, list) { 774 - free_ep_req(hidg->out_ep, list->req); 775 - list_del(&list->list); 776 - kfree(list); 641 + if (hidg->out_ep) { 642 + usb_ep_disable(hidg->out_ep); 643 + 644 + spin_lock_irqsave(&hidg->read_spinlock, flags); 645 + list_for_each_entry_safe(list, next, &hidg->completed_out_req, list) { 646 + free_ep_req(hidg->out_ep, list->req); 647 + list_del(&list->list); 648 + kfree(list); 649 + } 650 + spin_unlock_irqrestore(&hidg->read_spinlock, flags); 777 651 } 778 - spin_unlock_irqrestore(&hidg->read_spinlock, flags); 779 652 780 653 spin_lock_irqsave(&hidg->write_spinlock, flags); 781 654 if (!hidg->write_pending) { ··· 824 691 } 825 692 } 826 693 827 - 828 - if (hidg->out_ep != NULL) { 694 + if (hidg->use_out_ep && hidg->out_ep != NULL) { 829 695 /* restart endpoint */ 830 696 usb_ep_disable(hidg->out_ep); 831 697 ··· 849 717 hidg_alloc_ep_req(hidg->out_ep, 850 718 hidg->report_length); 851 719 if (req) { 852 - req->complete = hidg_set_report_complete; 720 + req->complete = hidg_intout_complete; 853 721 req->context = hidg; 854 722 status = usb_ep_queue(hidg->out_ep, req, 855 723 GFP_ATOMIC); ··· 875 743 } 876 744 return 0; 877 745 disable_out_ep: 878 - usb_ep_disable(hidg->out_ep); 746 + if (hidg->out_ep) 747 + usb_ep_disable(hidg->out_ep); 879 748 free_req_in: 880 749 if (req_in) 881 750 free_ep_req(hidg->in_ep, req_in); ··· 928 795 goto fail; 929 796 hidg->in_ep = ep; 930 797 931 - ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_out_ep_desc); 932 - if (!ep) 933 - goto fail; 934 - hidg->out_ep = ep; 798 + hidg->out_ep = NULL; 799 + if (hidg->use_out_ep) { 800 + ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_out_ep_desc); 801 + if (!ep) 802 + goto fail; 803 + hidg->out_ep = ep; 804 + } 805 + 806 + /* used only if use_out_ep == 1 */ 807 + hidg->set_report_buf = NULL; 935 808 936 809 /* set descriptor dynamic values */ 937 810 hidg_interface_desc.bInterfaceSubClass = hidg->bInterfaceSubClass; 938 811 hidg_interface_desc.bInterfaceProtocol = hidg->bInterfaceProtocol; 812 + hidg_interface_desc.bNumEndpoints = hidg->use_out_ep ? 2 : 1; 939 813 hidg->protocol = HID_REPORT_PROTOCOL; 940 814 hidg->idle = 1; 941 815 hidg_ss_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); ··· 973 833 hidg_ss_out_ep_desc.bEndpointAddress = 974 834 hidg_fs_out_ep_desc.bEndpointAddress; 975 835 976 - status = usb_assign_descriptors(f, hidg_fs_descriptors, 977 - hidg_hs_descriptors, hidg_ss_descriptors, 978 - hidg_ss_descriptors); 836 + if (hidg->use_out_ep) 837 + status = usb_assign_descriptors(f, 838 + hidg_fs_descriptors_intout, 839 + hidg_hs_descriptors_intout, 840 + hidg_ss_descriptors_intout, 841 + hidg_ss_descriptors_intout); 842 + else 843 + status = usb_assign_descriptors(f, 844 + hidg_fs_descriptors_ssreport, 845 + hidg_hs_descriptors_ssreport, 846 + hidg_ss_descriptors_ssreport, 847 + hidg_ss_descriptors_ssreport); 848 + 979 849 if (status) 980 850 goto fail; 981 851 ··· 1100 950 1101 951 F_HID_OPT(subclass, 8, 255); 1102 952 F_HID_OPT(protocol, 8, 255); 953 + F_HID_OPT(no_out_endpoint, 8, 1); 1103 954 F_HID_OPT(report_length, 16, 65535); 1104 955 1105 956 static ssize_t f_hid_opts_report_desc_show(struct config_item *item, char *page) ··· 1160 1009 static struct configfs_attribute *hid_attrs[] = { 1161 1010 &f_hid_opts_attr_subclass, 1162 1011 &f_hid_opts_attr_protocol, 1012 + &f_hid_opts_attr_no_out_endpoint, 1163 1013 &f_hid_opts_attr_report_length, 1164 1014 &f_hid_opts_attr_report_desc, 1165 1015 &f_hid_opts_attr_dev, ··· 1245 1093 hidg = func_to_hidg(f); 1246 1094 opts = container_of(f->fi, struct f_hid_opts, func_inst); 1247 1095 kfree(hidg->report_desc); 1096 + kfree(hidg->set_report_buf); 1248 1097 kfree(hidg); 1249 1098 mutex_lock(&opts->lock); 1250 1099 --opts->refcnt; ··· 1292 1139 return ERR_PTR(-ENOMEM); 1293 1140 } 1294 1141 } 1142 + hidg->use_out_ep = !opts->no_out_endpoint; 1295 1143 1296 1144 mutex_unlock(&opts->lock); 1297 1145
+1
drivers/usb/gadget/function/u_hid.h
··· 20 20 int minor; 21 21 unsigned char subclass; 22 22 unsigned char protocol; 23 + unsigned char no_out_endpoint; 23 24 unsigned short report_length; 24 25 unsigned short report_desc_length; 25 26 unsigned char *report_desc;