mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-10-10 08:03:04 -04:00
this commit is a combination of the following changes, which significantly refactors usb core and class drivers. 1. unify usb buffers of each class driver to reduce iram usage currently, many class drivers allocate their own buffer to receive control out data, which is a waste of iram. share one common buffer for that usage to address the issue. 2. simplify control request handling by implicitly receiving write request data packets change 1 above fixed the data destination. therefore, having the core receive the data allows us to reduce the class driver's work and simplifies the api. 3. enhance usb core's control request handling and unify the legacy driver api in order to implement change 2, both the legacy and new driver apis should be supported. so that, using the designware driver as a reference, the new driver api functionality is move into usb core. this simplifies the usb device drivers by requiring them to implement only the functionalities equivalent to the legacy api. tested with ipodvideo(arc) and erosqnative(designware) Change-Id: I3627daa90278751f599e2108ec150ec3f8f6c524
44 lines
2 KiB
Markdown
44 lines
2 KiB
Markdown
Handling USB control requests
|
|
=============================
|
|
|
|
API overview
|
|
------------
|
|
A control request goes through from device driver to class drivers, via usb core.
|
|
Each step is done by those functions:
|
|
|
|
# from device driver to usb core
|
|
void usb_core_setup_received(struct usb_ctrlrequest* req);
|
|
# from usb core to class drivers
|
|
bool usb_class_driver::control_request(struct usb_ctrlrequest* req);
|
|
|
|
Also control response goes through the inverse steps, and the following
|
|
functions are used:
|
|
|
|
# from class drivers to usb core
|
|
void usb_core_control_response(enum usb_control_response response, const void* data, size_t size);
|
|
# from usb core to device drivers
|
|
int usb_drv_{send,recv}_nonblocking(int endpoint, void *ptr, int length);
|
|
|
|
Request handling process
|
|
------------------------
|
|
|
|
The driver submits control requests to the USB core one at a time. Once a
|
|
request is submitted, it must be completed before the next request can be
|
|
submitted. This mirrors normal USB operation.
|
|
|
|
When the USB driver receives a setup packet from the host, it submits it
|
|
to the core to begin handling the control transfer. The driver calls
|
|
`usb_core_setup_received(req)`, passing the setup packet in `req`.
|
|
|
|
If the request was a Non-data transfer, the core or recipient class driver will
|
|
call `usb_core_control_response(USB_CONTROL_ACK, NULL, 0)` for ACK or
|
|
`usb_core_control_response(USB_CONTROL_STALL, NULL, 0)` for NAK.
|
|
|
|
If the request was a Control read transfer, the core or recipient class driver
|
|
will call `usb_core_control_response(USB_CONTROL_ACK, data, size)` to send data packets,
|
|
or `usb_core_control_response(false, USB_CONTROL_STALL, 0)` for NAK.
|
|
|
|
If the request was a Control write transfer, the core firstly receive data packets
|
|
using `usb_drv_recv_nonblocking`. Once it's done, the core or recipient class
|
|
driver will process it, then `usb_core_control_response(USB_CONTROL_ACK, NULL, 0)` for ACK
|
|
or `usb_core_control_response(USB_CONTROL_STALL, NULL, 0)` for NAK.
|