usb: fix wrong init of keyboard/mouse's if first interface is not boot protocol
There is always some endpoint descriptors after each interface descriptor, We should only decrement num_iface if interface type is USB_DT_INTERFACE, see https://www.beyondlogic.org/usbnutshell/usb5.shtml#ConfigurationDescriptors Signed-off-by: Qi Zhou <atmgnd@outlook.com>
This commit is contained in:
parent
3208b098f5
commit
645a64b491
|
@ -22,13 +22,13 @@ struct usb_pipe *mouse_pipe VARFSEG;
|
|||
|
||||
// Send USB HID protocol message.
|
||||
static int
|
||||
set_protocol(struct usb_pipe *pipe, u16 val)
|
||||
set_protocol(struct usb_pipe *pipe, u16 val, u16 inferface)
|
||||
{
|
||||
struct usb_ctrlrequest req;
|
||||
req.bRequestType = USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
|
||||
req.bRequest = HID_REQ_SET_PROTOCOL;
|
||||
req.wValue = val;
|
||||
req.wIndex = 0;
|
||||
req.wIndex = inferface;
|
||||
req.wLength = 0;
|
||||
return usb_send_default_control(pipe, &req, NULL);
|
||||
}
|
||||
|
@ -76,9 +76,12 @@ usb_kbd_setup(struct usbdevice_s *usbdev
|
|||
}
|
||||
|
||||
// Enable "boot" protocol.
|
||||
int ret = set_protocol(usbdev->defpipe, 0);
|
||||
if (ret)
|
||||
int ret = set_protocol(usbdev->defpipe, 0, usbdev->iface->bInterfaceNumber);
|
||||
if (ret) {
|
||||
dprintf(3, "Failed to set boot protocol\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Periodically send reports to enable key repeat.
|
||||
ret = set_idle(usbdev->defpipe, KEYREPEATMS);
|
||||
if (ret)
|
||||
|
@ -118,7 +121,7 @@ usb_mouse_setup(struct usbdevice_s *usbdev
|
|||
}
|
||||
|
||||
// Enable "boot" protocol.
|
||||
int ret = set_protocol(usbdev->defpipe, 0);
|
||||
int ret = set_protocol(usbdev->defpipe, 0, usbdev->iface->bInterfaceNumber);
|
||||
if (ret)
|
||||
return -1;
|
||||
|
||||
|
|
12
src/hw/usb.c
12
src/hw/usb.c
|
@ -372,17 +372,19 @@ configure_usb_device(struct usbdevice_s *usbdev)
|
|||
void *config_end = (void*)config + config->wTotalLength;
|
||||
struct usb_interface_descriptor *iface = (void*)(&config[1]);
|
||||
for (;;) {
|
||||
if (!num_iface-- || (void*)iface + iface->bLength > config_end)
|
||||
if (!num_iface || (void*)iface + iface->bLength > config_end)
|
||||
// Not a supported device.
|
||||
goto fail;
|
||||
if (iface->bDescriptorType == USB_DT_INTERFACE
|
||||
&& (iface->bInterfaceClass == USB_CLASS_HUB
|
||||
if (iface->bDescriptorType == USB_DT_INTERFACE) {
|
||||
num_iface--;
|
||||
if (iface->bInterfaceClass == USB_CLASS_HUB
|
||||
|| (iface->bInterfaceClass == USB_CLASS_MASS_STORAGE
|
||||
&& (iface->bInterfaceProtocol == US_PR_BULK
|
||||
|| iface->bInterfaceProtocol == US_PR_UAS))
|
||||
|| (iface->bInterfaceClass == USB_CLASS_HID
|
||||
&& iface->bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT)))
|
||||
break;
|
||||
&& iface->bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT))
|
||||
break;
|
||||
}
|
||||
iface = (void*)iface + iface->bLength;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue