Skip to content

Commit 67be15b

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 fd52f34 commit 67be15b

File tree

3 files changed

+1365
-66
lines changed

3 files changed

+1365
-66
lines changed

docs/opentitan/usbdev.md

Lines changed: 145 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,16 +105,19 @@ The following commands are defined.
105105
| **Command** | **Value** | **Direction** | **Description** | **Reference** |
106106
| ----------- | --------- | ------------- | --------------- | ------------- |
107107
| Invalid | 0 | N/A | To avoid 0 meaning something | |
108-
| Hello | 1 | Both | First packet sent when connecting | [`Hello` command](#hello-command) |
108+
| Hello | 1 | Both | First packet sent when connecting | [Hello command](#hello-command) |
109109
| VBUS On | 2 | Host to device | Turn VBUS on | [Bus commands](#bus-commands) |
110110
| VBUS Off | 3 | Host to device | Turn VBUS off | [Bus commands](#bus-commands) |
111111
| Connect | 4 | Device to host | Report device connection | [Bus commands](#bus-commands) |
112112
| Disconnect | 5 | Device to host | Report device disconnection | [Bus commands](#bus-commands) |
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) |
119+
116120

117-
**TODO** Add transfer commands
118121

119122
#### Hello command
120123

@@ -132,5 +135,143 @@ The payload of this command is defined as follows.
132135
These commands (VBUS On/Off, (Dis)connection, Reset, Suspend/Resume) do not have any payload.
133136
See the [bus states](#bus-states) section for more detail.
134137

135-
For the Connect/Disconnect commands, which are sent by the device, the ID should be the ID of the *last command*
136-
processed by the device.
138+
For the Connect/Disconnect commands, which are sent by the device, the ID should be the ID of the
139+
*last command* processed by the device.
140+
141+
Sending a `Reset`, `VBUS Off` or `Suspend` command to the device automatically cancels any pending
142+
`Transfer` command.
143+
The device *may* send a `Complete` event with 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 pending transfer on this
159+
endpoint.
160+
The device *may* send a `Complete` 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 after
195+
the header.
196+
For IN transfers, the `Transfer Size` field indicates the maximum size of the transfers to return
197+
to the host.
198+
199+
Sending a `Transfer` command to an endpoint while one is already in progress is an error.
200+
The device must immediately reply with a `Complete` event with the `Error` status.
201+
202+
#### Complete command
203+
204+
The ID of this command must be the ID of the corresponding `Transfer` command.
205+
See [Transfer handling](#transfer-handling) for more details.
206+
The payload of this command is defined as follows.
207+
208+
| **Field** | **Offset** | **Size** | **Value** |
209+
| --------- | ---------- | -------- | --------- |
210+
| Status | 0 | 1 | Status of the transfer (see below) |
211+
| Reserved | 1 | 3 | Set to 0 |
212+
| Transfer Size | 4 | 4 | Amount of data transferred |
213+
| Data | 8 | variable | Transfer data (see below) |
214+
215+
The `Transfer Size` field indicates the size of the data.
216+
The data must only be present when completing an IN transaction.
217+
218+
The following status codes are defined:
219+
220+
| **Status** | **Value** | **Meaning** |
221+
| -------- | ------- | ----------- |
222+
| Success | 0 | The data was successfully transferred |
223+
| Stalled | 1 | The device stalled the transfer |
224+
| Cancelled | 2 | Transfer was cancelled (see below) |
225+
| Error | 3 | An unspecified error occurred |
226+
227+
A transfer may be cancelled by any bus event such a turning VBUS off, the device disconnecting,
228+
the host resetting or suspending the device, or the host sending a `Setup` command.
229+
230+
231+
### Transfer handling
232+
233+
In order to perform data transfers, the host must send a correct sequence
234+
of Setup and Data commands, in accordance to the USB specification. The
235+
protocol is designed to be very low-level and only provides minimal help.
236+
The host is allowed to send non-spec compliant sequences to fuzz the device.
237+
For properly sequenced transfers, the host should follow the guidelines below.
238+
239+
Note that the `Transfer` command allows the host to send/receive more data than the
240+
indicated packet size.
241+
In this case, the transfer will automatically be split into multiple packets
242+
of size `Packet Size`.
243+
For OUT transfers, all packets except possibly the last one will be of the size
244+
indicated in the command. For IN transfers, the transfer stops as soon as a
245+
short packet is received (packet of size less than the one indicated in the
246+
command).
247+
If the `ZLP` flag is set for an OUT transfer, the device will additionally
248+
receive a zero-length packet.
249+
If at any point during this sequence, the device stalls the transfer,
250+
the transfer stops and the device must send a `Complete` event to the host with the
251+
`Stalled` status and the `Size` field indicating how much data was transferred successfully
252+
(and for IN transfers, the data must be present in the payload).
253+
If the transfer succeeds, the device must send a `Complete` event with the `Success` status,
254+
the `Size` field indicating how much data was transferred successfully
255+
(and for IN transfers, the data must be present in the payload).
256+
257+
### Control transfers
258+
259+
The host should first send a `Setup` command at the selected address and endpoint.
260+
The device does not reply to this command. Note that the USB specification specifies
261+
that sending a SETUP packet to an endpoint immediately cancels any transaction on this
262+
endpoint. The device *may* send a `Complete` events for such transfers with the `Cancelled`
263+
status.
264+
265+
The rest of the sequence depends on the direction of the transfer:
266+
- OUT transfers: the host should send one or more `Transfer` commands to the endpoint
267+
(with the OUT direction) with the control data.
268+
Once all transfers are complete, the host should send a `Transfer` command to the endpoint
269+
with the IN direction and `Size` set to 0.
270+
- IN transfers: the host should send one or more `Transfer` commands to the endpoint,
271+
(with the IN direction) to receive the control data.
272+
Once all transfers are complete, the host should send a `Transfer` command to the endpoint
273+
with the OUT direction and `Size` set to 0.
274+
275+
### Bulk and interrupt transfers
276+
277+
TODO

0 commit comments

Comments
 (0)