diff options
Diffstat (limited to 'docs/usb-api.md')
-rw-r--r-- | docs/usb-api.md | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/docs/usb-api.md b/docs/usb-api.md new file mode 100644 index 0000000000..a21d6fd703 --- /dev/null +++ b/docs/usb-api.md | |||
@@ -0,0 +1,144 @@ | |||
1 | Handling USB control requests | ||
2 | ============================= | ||
3 | |||
4 | API overview | ||
5 | ------------ | ||
6 | |||
7 | enum usb_control_response { | ||
8 | USB_CONTROL_ACK, | ||
9 | USB_CONTROL_STALL, | ||
10 | USB_CONTROL_RECEIVE, | ||
11 | }; | ||
12 | |||
13 | void usb_core_control_request(struct usb_ctrlrequest* req, void* reqdata); | ||
14 | void usb_core_control_complete(int status); | ||
15 | void usb_drv_control_response(enum usb_control_response resp, | ||
16 | void* data, int length); | ||
17 | |||
18 | The two `usb_core` functions are common to all targets with a USB stack and | ||
19 | are implemented in `usb_core.c`. The USB driver calls them to inform the core | ||
20 | when a control request arrives or is completed. | ||
21 | |||
22 | Each USB driver implements `usb_drv_control_response()`. The core calls this | ||
23 | to let the driver know how to respond to each control request. | ||
24 | |||
25 | ### Legacy API | ||
26 | |||
27 | void usb_core_legacy_control_request(struct usb_ctrlrequest* req); | ||
28 | |||
29 | The old control request API is available through this function. Drivers which | ||
30 | don't yet implement the new API can use the legacy API instead. To support | ||
31 | legacy drivers, the USB core implements all functions in the new API and | ||
32 | emulates the old control request handling behavior, bugs included. | ||
33 | |||
34 | This is intended as a stopgap measure so that old drivers keep working as-is. | ||
35 | The core can start using the new API right away, and drivers can be ported | ||
36 | one-by-one as time allows. Once all drivers are ported to the new API, all | ||
37 | legacy driver support can be removed. | ||
38 | |||
39 | Request handling process | ||
40 | ------------------------ | ||
41 | |||
42 | The driver submits control requests to the USB core one at a time. Once a | ||
43 | request is submitted, it must be completed before the next request can be | ||
44 | submitted. This mirrors normal USB operation. | ||
45 | |||
46 | When the USB driver receives a setup packet from the host, it submits it | ||
47 | to the core to begin handling the control transfer. The driver calls | ||
48 | `usb_core_control_request(req, NULL)`, passing the setup packet in `req`. | ||
49 | The second argument, `reqdata`, is not used at this time and is passed | ||
50 | as `NULL`. | ||
51 | |||
52 | The core processes the setup packet and calls `usb_drv_control_response()` | ||
53 | when it's done. The allowed responses depend on the type of control transfer | ||
54 | being processed. | ||
55 | |||
56 | ### Non-data transfers | ||
57 | |||
58 | - `USB_CONTROL_ACK`, to indicate the request was processed successfully. | ||
59 | - `USB_CONTROL_STALL`, if the request is unsupported or cannot be processed. | ||
60 | |||
61 | ### Control read transfers | ||
62 | |||
63 | - `USB_CONTROL_ACK`, to indicate the request was processed successfully. | ||
64 | The core must provide a valid `data` buffer with `length` not exceeding | ||
65 | the `wLength` field in the setup packet; otherwise, driver behavior is | ||
66 | undefined. The driver will transfer this data to the host during the | ||
67 | data phase of the control transfer, and then acknowledge the host's OUT | ||
68 | packet to complete the transfer successfully. | ||
69 | - `USB_CONTROL_STALL`, if the request is unsupported or cannot be processed. | ||
70 | |||
71 | ### Control write transfers | ||
72 | |||
73 | The driver calls `usb_core_control_request()` twice to handle control writes. | ||
74 | The first call allows the core to handle the setup packet, and if the core | ||
75 | decides to accept the data phase, the second call is made when the data has | ||
76 | been received without error. | ||
77 | |||
78 | #### Setup phase | ||
79 | |||
80 | The first call is made at the end of the setup phase, after receiving the | ||
81 | setup packet. The driver passes `reqdata = NULL` to indicate this. | ||
82 | |||
83 | The core can decide whether it wants to receive the data phase: | ||
84 | |||
85 | - `USB_CONTROL_RECEIVE`, if the core wishes to continue to the data phase. | ||
86 | The core must provide a valid `data` buffer with `length` greater than or | ||
87 | equal to the `wLength` specified in the setup packet; otherwise, driver | ||
88 | behavior is undefined. The driver will proceed to the data phase and store | ||
89 | received data into the provided buffer. | ||
90 | - `USB_CONTROL_STALL`, if the request is unsupported or cannot be processed. | ||
91 | |||
92 | If the core accepts the data phase, the driver will re-submit the request | ||
93 | when the data phase is completed correctly. If any error occurs during the | ||
94 | data phase, the driver will not re-submit the request; instead, it will | ||
95 | call `usb_core_control_complete()` with a non-zero status code. | ||
96 | |||
97 | #### Status phase | ||
98 | |||
99 | The second call to `usb_core_control_request()` is made at the end of the data | ||
100 | phase. The `reqdata` passed by the driver is the same one that the core passed | ||
101 | in its `USB_CONTROL_RECEIVE` response. | ||
102 | |||
103 | The core's allowed responses are: | ||
104 | |||
105 | - `USB_CONTROL_ACK`, to indicate the request was processed successfully. | ||
106 | - `USB_CONTROL_STALL`, if the request is unsupported or cannot be processed. | ||
107 | |||
108 | ### Request completion | ||
109 | |||
110 | The driver will notify the core when a request has completed by calling | ||
111 | `usb_core_control_complete()`. A status code of zero means the request was | ||
112 | completed successfully; a non-zero code means it failed. Note that failure | ||
113 | can occur even if the request was successful from the core's perspective. | ||
114 | |||
115 | If the core response is `USB_CONTROL_STALL` at any point, the request is | ||
116 | considered complete. In this case, the driver won't deliver a completion | ||
117 | notification because it would be redundant. | ||
118 | |||
119 | The driver may only complete a request after the core has provided a response | ||
120 | to any pending `usb_core_control_request()` call. Specifically, if the core | ||
121 | has not yet responded to a request, the driver needs to defer the completion | ||
122 | notification until it sees the core's response. If the core's response is a | ||
123 | stall, then the notification should be silently dropped. | ||
124 | |||
125 | ### Notes | ||
126 | |||
127 | - Driver behavior is undefined if the core makes an inappropriate response | ||
128 | to a request, for example, responding with `USB_CONTROL_ACK` in the setup | ||
129 | phase of a control write or `USB_CONTROL_RECEIVE` to a non-data request. | ||
130 | The only permissible responses are the documented ones. | ||
131 | |||
132 | - If a response requires a buffer, then `data` must be non-NULL unless the | ||
133 | `length` is also zero. If a buffer is not required, the core must pass | ||
134 | `data = NULL` and `length = 0`. Otherwise, driver behavior is undefined. | ||
135 | There are two responses which require a buffer: | ||
136 | + `USB_CONTROL_ACK` to a control read | ||
137 | + `USB_CONTROL_RECEIVE` to the setup phase of a control write | ||
138 | |||
139 | - Drivers must be prepared to accept a setup packet at any time, including | ||
140 | in the middle of a control request. In such a case, devices are required | ||
141 | to abort the ongoing request and start handling the new request. (This is | ||
142 | intended as an error recovery mechanism and should not be abused by hosts | ||
143 | in normal operation.) The driver must take care to notify the core of the | ||
144 | current request's failure, and then submit the new request. | ||