Skip to content

Commit 084dcac

Browse files
committed
[ot] hw/opentitan: ot_usbdev: Implementation data transfers
This commit implements the logic to support data transfers and wire them in the server. The protocol is updated with commands to support this. Isochronous transfers are not properly supported at the moment. Signed-off-by: Amaury Pouly <[email protected]>
1 parent b03205a commit 084dcac

File tree

3 files changed

+1186
-38
lines changed

3 files changed

+1186
-38
lines changed

docs/opentitan/usbdev.md

Lines changed: 145 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,11 @@ The following commands are defined.
113113
| Reset | 6 | Host to device | Reset the device | [Bus commands](#bus-commands) |
114114
| Resume | 7 | Host to device | Resume the device | [Bus commands](#bus-commands) |
115115
| Suspend | 8 | Host to device | Suspend the device | [Bus commands](#bus-commands) |
116+
| Setup | 9 | Host to device | Send a SETUP packet | [SETUP command](#setup-command) |
117+
| Transfer | 10 | Host to device | Start a transfer | [Transfer command](#transfer-command) |
118+
| Complete | 11 | Device to host | Complete a transfer | [Complete command](#complete-command) |
116119

117-
**TODO** Add transfer commands
120+
**TODO** Add cancel command?
118121

119122
#### Hello command
120123

@@ -134,3 +137,144 @@ See the [bus states](#bus-states) section for more detail.
134137

135138
For the Connect/Disconnect commands, which are sent by the device, the ID should be the ID of the *last command*
136139
processed by the device.
140+
141+
Sending a `Reset`, `VBUS Off` or `Suspend` command to the device automatically cancels
142+
any pending `Transfer` command. The device *may* send a `Complete` event with
143+
the `Cancelled` status for such transfers.
144+
145+
#### Setup command
146+
147+
This command is used to send a SETUP packet to the device.
148+
The payload of this command starts with a header defined as follows.
149+
See [Transfer handling](#transfer-handling) for more details.
150+
151+
| **Field** | **Offset** | **Size** | **Value** |
152+
| --------- | ---------- | -------- | --------- |
153+
| Address | 0 | 1 | Device address |
154+
| Endpoint | 1 | 1 | Endpoint number |
155+
| Reserved | 2 | 2 | Set to zero |
156+
| Setup | 4 | 8 | SETUP packet |
157+
158+
Sending a `Setup` command to an endpoint automatically cancels any
159+
pending transfer on this endpoint. The device *may* send a `Complete`
160+
event to the host with the `Cancelled` status.
161+
162+
#### Transfer command
163+
164+
This command is used to start a transfer to or from the device.
165+
See [Transfer handling](#transfer-handling) for more details.
166+
The payload of this command is defined below.
167+
168+
| **Field** | **Offset** | **Size** | **Value** |
169+
| --------- | ---------- | -------- | --------- |
170+
| Address | 0 | 1 | Device address |
171+
| Endpoint | 1 | 1 | Endpoint (see below) |
172+
| Packet Size | 2 | 2 | Packet size (see [Transfer handling](#transfer-handling)) |
173+
| Flags | 4 | 1 | Transfer flags (see below) |
174+
| Reserved | 5 | 3 | Set to 0 |
175+
| Transfer Size | 8 | 4 | Size of the data |
176+
| Data | 12 | variable | Transfer data (see below) |
177+
178+
The `Endpoint` field is encoded as follows:
179+
| **Field** | **Bits** | **Value** |
180+
| --------- | -------- | -------- |
181+
| EP Number | 3:0 | The endpoint number |
182+
| Reserved | 6:4 | Set to 0 |
183+
| Direction | 7 | Set to 1 for IN endpoint and 0 for OUT endpoint |
184+
185+
Note that when submitting a control transfer, the `Direction` field must be set
186+
to indicate whether this is control OUT or IN transaction.
187+
188+
The following flags are defined.
189+
190+
| **Flag** | **Bit** | **Meaning** |
191+
| -------- | ------- | ----------- |
192+
| ZLP | 0 | A zero-length packet must be sent after the data (only valid for OUT transfers) |
193+
194+
For OUT transfers, the `Transfer Size` field indicates the size of the data in the payload
195+
after the header. For IN transfers, the `Transfer Size` field indicates the maximum size
196+
of the transfers to return to the host.
197+
198+
**TODO** Clarifies what happens if sending a `Transfer` command to an endpoint while
199+
one is already in progress. Is queuing allowed? Should it immediately return a `Complete` command
200+
with a dedicated status code?
201+
202+
**TODO** Add a flag to indicate whether short transfers stop the transfer or not?
203+
204+
#### Complete command
205+
206+
The ID of this command must be the ID of the corresponding `Transfer` command.
207+
See [Transfer handling](#transfer-handling) for more details.
208+
The payload of this command is defined as follows.
209+
210+
| **Field** | **Offset** | **Size** | **Value** |
211+
| --------- | ---------- | -------- | --------- |
212+
| Status | 0 | 1 | Status of the transfer (see below) |
213+
| Reserved | 1 | 3 | Set to 0 |
214+
| Transfer Size | 4 | 4 | Amount of data transferred |
215+
| Data | 8 | variable | Transfer data (see below) |
216+
217+
The `Size` field indicates the size of the data. The data must only be present
218+
when completing an IN transaction.
219+
220+
The following status codes are defined:
221+
222+
| **Status** | **Value** | **Meaning** |
223+
| -------- | ------- | ----------- |
224+
| Success | 0 | The data was successfully transferred |
225+
| Stalled | 1 | The device stalled the transfer |
226+
| Cancelled | 2 | Transfer was cancelled (see below) |
227+
| Error | 3 | An unspecified error occured |
228+
229+
A transfer may be cancelled by any bus event such a turning VBUS off,
230+
the device disconnecting, the host resetting or suspending the device,
231+
or the host sending a `Setup` command.
232+
233+
234+
### Transfer handling
235+
236+
In order to perform data transfers, the host must send a correct sequence
237+
of Setup and Data commands, in accordance to the USB specification. The
238+
protocol is designed to be very low-level and only provides minimal help.
239+
The host is allowed to send non-spec compliants sequences to fuzz the device.
240+
For properly sequenced transfers, the host should the guidelines below.
241+
242+
Note that the `Transfer` command allows the host to send/receive more data than the
243+
indicated packet size.
244+
In this case, the transfer will automatically be split into multiple packets
245+
of size `Packet Size`.
246+
For OUT transfers, all packets except possibly the last one will be of the size
247+
indicated in the command. For IN transfers, the transfer stops as soon as a
248+
short packet is received (packet of size less than the one indicated in the
249+
command).
250+
If the `ZLP` flag is set for an OUT transfer, the device will additionally
251+
receive a zero-length packet.
252+
If at any point during this sequence, the device stalls the transfer,
253+
the transfer stops and the device must send a `Complete` event to the host with the
254+
`Stalled` status and the `Size` field indicating how much data was transferred successfully
255+
(and for IN transfers, the data must be present in the payload).
256+
If the transfer succeeds, the device must send a `Complete` event with the `Success` status,
257+
the `Size` field indicating how much data was transferred successfully
258+
(and for IN transfers, the data must be present in the payload).
259+
260+
### Control transfers
261+
262+
The host should first send a `Setup` command at the selected address and endpoint.
263+
The device does not reply to this command. Note that the USB specification specifies
264+
that sending a SETUP packet to an endpoint immediately cancels any transaction on this
265+
endpoint. The device *may* send a `Complete` events for such transfers with the `Cancelled`
266+
status.
267+
268+
The rest of the sequence depends on the direction of the transfer:
269+
- OUT transfers: the host should send one or more `Transfer` commands to the endpoint
270+
(with the OUT direction) with the control data.
271+
Once all transfers are complete, the host should send a `Transfer` command to the endpoint
272+
with the IN direction and `Size` set to 0.
273+
- IN transfers: the host should send one or more `Transfer` commands to the endpoint,
274+
(with the IN direction) to receive the control data.
275+
Once all transfers are complete, the host should send a `Transfer` command to the endpoint
276+
with the OUT direction and `Size` set to 0.
277+
278+
### Bulk and interrupt transfers
279+
280+
TODO

0 commit comments

Comments
 (0)