mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-10-10 08:03:04 -04:00
FS#14011: Handle usb hosts whose first request is SET_ADDRESS (Anthony Fletcher)
Thanks for the SET_ADDRESS rework. I think it leaves one case uncovered:
a host whose first request is SET_ADDRESS ends up with a device whose
interfaces are all numbered 0.
Two things still depend on the core seeing a request before the address arrives:
1. usb_core assigns interfaces and endpoints only on the first control
request it handles in DEFAULT. When SET_ADDRESS comes first, the driver
completes it and usb_core_set_address() moves the state to ADDRESS. So
allocate_interfaces_and_endpoints() never runs.
2. Under USB_DETECT_BY_REQUEST, usb.c enables the class drivers only
on a USB_TRANSFER_COMPLETION event. The SET_ADDRESS status stage now
completes inside the driver, so the drivers are still disabled when the
address arrives.
Change-Id: Ifacb8b07cbdefb0dee3d414c2257a50a08759f3d
This commit is contained in:
parent
583f27d5e5
commit
2745e0b973
2 changed files with 24 additions and 7 deletions
|
|
@ -431,6 +431,15 @@ static void NORETURN_ATTR usb_thread(void)
|
|||
|
||||
#ifdef HAVE_USBSTACK
|
||||
case USB_NOTIFY_SET_ADDR:
|
||||
#ifdef USB_DETECT_BY_REQUEST
|
||||
/* first sign of a host that addresses before anything else;
|
||||
* the class drivers must be on before interfaces are assigned */
|
||||
if(usb_state > USB_EXTRACTED) {
|
||||
usb_state = USB_INSERTED;
|
||||
usb_set_host_present(true);
|
||||
}
|
||||
#endif
|
||||
/* intentional fallthrough */
|
||||
case USB_NOTIFY_SET_CONFIG:
|
||||
case USB_NOTIFY_BUS_RESET:
|
||||
case USB_NOTIFY_CLASS_DRIVER:
|
||||
|
|
|
|||
|
|
@ -863,9 +863,22 @@ static void request_handler_device_get_descriptor(struct usb_ctrlrequest* req, u
|
|||
}
|
||||
}
|
||||
|
||||
static void usb_core_init_interfaces(void)
|
||||
{
|
||||
if(usb_state == DEFAULT) {
|
||||
set_serial_descriptor();
|
||||
usb_core_set_serial_function_id();
|
||||
allocate_interfaces_and_endpoints();
|
||||
}
|
||||
}
|
||||
|
||||
static void usb_core_set_address(uint8_t address)
|
||||
{
|
||||
logf("usb_core: SET_ADR %d", address);
|
||||
/* A host may address the device before making any other request;
|
||||
* the driver answers SET_ADDRESS itself, so nothing has been
|
||||
* allocated yet. */
|
||||
usb_core_init_interfaces();
|
||||
usb_address = address;
|
||||
usb_state = ADDRESS;
|
||||
}
|
||||
|
|
@ -1134,12 +1147,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req, uint8_
|
|||
usb_charging_maxcurrent_change(usb_charging_maxcurrent());
|
||||
}
|
||||
#endif
|
||||
if(usb_state == DEFAULT) {
|
||||
set_serial_descriptor();
|
||||
usb_core_set_serial_function_id();
|
||||
|
||||
allocate_interfaces_and_endpoints();
|
||||
}
|
||||
usb_core_init_interfaces();
|
||||
|
||||
switch(req->bRequestType & USB_RECIP_MASK) {
|
||||
case USB_RECIP_DEVICE:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue