1/*
2 * Copyright (c) 2007-2013 ETH Zurich.
3 * All rights reserved.
4 *
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
8 */
9
10#ifndef USB_XFER_H_
11#define USB_XFER_H_
12
13
14/*
15 * prototypes
16 */
17struct usb_xfer;
18struct usb_endpoint;
19struct usb_device;
20struct usb_host_controller;
21struct usb_dma_page;
22struct usb_hcdi_pipe_fn;
23struct usb_request_state;
24struct usb_manager_binding;
25
26typedef void xfer_done_cb_t (struct usb_xfer *xfer, usb_error_t error);
27
28/*
29 * ------------------------------------------------------------------------
30 * USB Transfer Flags (Internal)
31 * ------------------------------------------------------------------------
32 * This data structure represents a set of flags that are used internally
33 * for keeping track of the transfer state
34 *
35 * Fields:
36 *  - usb_mode              the host controller mode
37 *  - remaining_bytes       remaining bytes of the transfer
38 *  - pipe_open             the pipe used for the transfer is opened
39 *  - transferring          transfer is currently in progress
40 *  - dma_wait              indicates that we are waiting for HW DMA
41 *  - transfer_closed       indicates that we have closed the transfer
42 *  - draining              indicates that we are draining the transfer
43 *  - started               transfer is started / stopped
44 *  - bandwidth_reclaimed   set if the bandwidth has been reclaimed
45 *  - ctrl_xfer             set if this transfer is a control transfer
46 *  - ctrl_header           set if the ctrl header needs to be sent
47 *  - ctrl_active           set if the ctrl transfer is active
48 *  - ctrl_stall            set if the ctrl transfer should be stalled
49 *  - short_frames_ok       allows non full frames
50 *  - short_transfer_ok     allows non full transfers
51 *  - isoc_xfer             set if this transfer is isochronus
52 *  - curr_dma_set          is used by the host controller driver
53 *  - cancellable           set if this transfer can immediately be cancelled
54 *  - notify                set if the device driver is being notified
55 */
56struct usb_xfer_flags_internal {
57    usb_mode_t usb_mode;
58
59    uint16_t remaining_bytes;
60
61    uint8_t pipe_open :1;
62    uint8_t transferring :1;
63    uint8_t done : 1;
64
65    uint8_t dma_wait :1;
66    uint8_t transfer_closed :1;
67
68    uint8_t draining :1;
69    uint8_t started :1;
70
71    uint8_t bandwidth_reclaimed :1;
72
73    uint8_t ctrl_xfer :1;
74    uint8_t ctrl_header :1;
75    uint8_t ctrl_active :1;
76    uint8_t ctrl_stall :1;
77
78    uint8_t short_frames_ok :1;
79    uint8_t short_transfer_ok :1;
80
81    uint8_t isoc_xfer :1;
82    uint8_t curr_dma_set :1;
83    uint8_t cancellable :1;
84    uint8_t notify :1;
85};
86
87/*
88 * ------------------------------------------------------------------------
89 * USB Transfer Flags
90 * ------------------------------------------------------------------------
91 * This data structure represents a set of flags that are used internally
92 * for keeping track of the transfer state
93 *
94 * Fields:
95 *  - short_xfer_forced     force a short transmit transfer on last packet
96 *  - short_xfer_ok         allow short transfers (small packets)
97 *  - short_frames_ok       allow short frames
98 *  - pipe_on_falure        block pipe had a failure condition
99 *  - buf_size_frame        buffer size shall be multiple of frame size
100 *  - ext_buffer            use external DMA buffer
101 *  - manual_status         disables automatic status stage on ctrl transfers
102 *  - pipe_none_ok          ingore USB_ERR_NO_PIPE errors
103 *  - pipe_stalled          stall the endpoint before starting the transfer
104 *  - prescale              prescale to frames for isochr transfers
105 */
106struct usb_xfer_flags {
107    uint8_t _unused : 5;            ///< unused bits to fill up the 2 bytes
108    uint8_t auto_restart:1;
109    uint8_t short_xfer_forced :1;
110    uint8_t short_xfer_ok :1;
111    uint8_t short_frames_ok :1;
112    uint8_t pipe_on_falure :1;
113    uint8_t buf_size_frame :1;
114    uint8_t ext_buffer :1;
115    uint8_t manual_status :1;
116    uint8_t pipe_none_ok :1;
117    uint8_t pipe_stalled :1;
118    uint8_t prescale :1;
119};
120
121/*
122 * ------------------------------------------------------------------------
123 * USB Transfer Queue
124 * ------------------------------------------------------------------------
125 * This data structure is a commonly used structure for transfer queues
126 *
127 * Fields:
128 *  - head:     struct containing pointers to the list elements
129 *      - first:    the head of the queue (first element)
130 *      - last:     the address of last next element
131 *  - current:  the current USB transfer being processed
132 *  - command:  a function pointer to a command to execute
133 *  - recurse:
134 */
135struct usb_xfer_queue {
136    struct {
137        struct usb_xfer *first;
138        struct usb_xfer **last_next;
139    } head;
140
141    struct usb_xfer *current;
142    void (*command)(struct usb_xfer_queue *pq);
143    uint8_t recurse_1 :1;
144    uint8_t recurse_2 :1;
145};
146
147/*
148 * ------------------------------------------------------------------------
149 * USB Transfer
150 * ------------------------------------------------------------------------
151 * This data structure defines an USB transfer
152 *
153 * Fields:
154 *  -
155 */
156struct usb_xfer {
157    struct usb_manager_binding *usb_manager_binding;  // flounder ref
158    struct usb_driver_binding *usb_driver_binding;
159    struct usb_request_state *usb_manager_request_state;
160    xfer_done_cb_t *xfer_done_cb;
161    uint32_t xfer_id;
162    struct usb_xfer *device_xfers_next;
163
164    struct {
165        struct usb_xfer *next; /* next element */
166        struct usb_xfer **prev_next; /* address of previous next element */
167    } wait_entry;
168
169    struct usb_xfer_queue *wait_queue;
170
171    usb_type_t type;
172    uint16_t intr_qh_pos;            // position in the queue head intr list
173
174    struct usb_endpoint *endpoint;
175    void *hcd_qh_start[2];
176    void *hcd_td_start[2];
177    void *hcd_td_first;  // first td in the list
178    void *hcd_td_last;  // last td in the list
179    void *hcd_td_cache;  // a field used to swap the tds
180
181    uint32_t sum_bytes;
182    uint32_t actual_bytes;
183
184    uint32_t num_frames;
185    uint32_t actual_frames;
186    uint32_t *frame_lengths;    // pointer to an array of frame lengths
187    uint8_t frame_shift;
188    struct usb_dma_page **frame_buffers;  // pointer to an array of DMA frames where the device reads / writes to mem
189
190    uint32_t max_packet_count;
191    uint16_t max_packet_size;
192    uint16_t max_frame_size;    // maximum size of a frame
193    uint16_t max_hc_frame_size;
194    uint32_t max_data_length;
195    uint32_t max_frame_count;   // size of array frame_length
196
197    struct usb_host_controller *host_controller;
198    struct usb_device *device;
199    uint8_t device_address;
200    uint8_t endpoint_number;
201    uint8_t usb_state;
202    uint8_t ed_direction;
203
204    uint16_t isoc_time_complete;
205    uint16_t interval;          // for isoc and intr
206    uint16_t timeout;
207    usb_error_t error;
208
209    struct usb_xfer_flags flags;
210    struct usb_xfer_flags_internal flags_internal;
211
212};
213
214/**
215 * ------------------------------------------------------------------------
216 * USB Transfer Configuration
217 * ------------------------------------------------------------------------
218 * This data structure contains an USB configuration used for setting up
219 * new USB transfers.
220 *
221 * Fields:
222 *  - bufsize   total pipe buffer size in bytes
223 *  - frames    maximum number of USB frames to be used
224 *  - interval  interval in milliseconds
225 *  - timeout   transfer timeout in milliseconds
226 *  - flags     transfer flags
227 *  - usb_mode  host or device mode
228 *  - type      transfer type
229 *  - endpoint  endpoint number to be used
230 *  - direction the direction of the transfer
231 *  - ep_index  the endpoint index to be used
232 *  - if_index  the interface index to be used
233 */
234struct usb_xfer_config {
235    uint32_t bufsize;
236    uint32_t frames;
237    uint32_t interval;
238    uint32_t timeout;
239    struct usb_xfer_flags flags;
240    uint8_t type;
241    uint8_t direction;
242    uint8_t endpoint;
243    uint8_t interface;
244    usb_type_t usb_type;
245    usb_mode_t usb_mode;
246    xfer_done_cb_t *xfer_done_cb;
247};
248
249/*
250 * ------------------------------------------------------------------------
251 * USB Transfer Setup Parameters
252 * ------------------------------------------------------------------------
253 * This data structure contains all the relevant information needed to
254 * setup a new USB transfer
255 *
256 * Fields:
257 *  -
258 */
259struct usb_xfer_setup_params {
260    struct usb_device *device;
261    struct usb_xfer *curr_xfer;
262    const struct usb_xfer_config *xfer_setup;
263    const struct usb_hcdi_pipe_fn *pipe_fn;
264    usb_type_t type;
265    void *buf;
266    uint32_t *xfer_length_ptr;
267    uint32_t bufsize;
268    uint32_t size[7];
269
270    uint32_t bufsize_max;
271    struct usb_dma_page *dma_page;
272    uint8_t num_pages;
273    uint32_t hc_max_frame_size;
274    uint16_t hc_max_packet_size;
275    uint8_t hc_max_packet_count;
276    usb_speed_t speed;
277    usb_error_t err;
278};
279
280
281/*
282 * ------------------------------------------------------------------------
283 * USB Endpoint
284 * ------------------------------------------------------------------------
285 * This data structure defines an USB tendpoint reflecting the state on a
286 * physical endpoint on the device.
287 *
288 * Fields:
289 *  - transfers         queue of usb_xfers of this endpoint
290 *  - descriptor        the endpoint descriptor
291 *  - pipe_fn           pointer to the pipe functions (set by HC driver)
292 *  - isoc_next         the next isochronus transfer
293 *  - toggle_next       the next data toggle value
294 *  - is_stalled        set if the endpoint is stalled
295 *  - is_sync           is set if the data structure is in sync
296 *  - unused            unused
297 *  - iface             pointer to the interface
298 *  - iface_index       the index of the interface
299 *  - endpoint_address  the address of this endpoint
300 *  - ref_allocation    reference count allocation
301 *  - ref_bandwidth     reference count bandwidth
302 *  - hs_start          high speed resource allocation start mask
303 *  - hs_complete       high speed resource allocation complete mask
304 *  - hs_uframe;        high speed micro frame
305 *  - max_packet_size   the maximum packet size to be used for this endponit
306 *  - status            the status uf this endpoint
307 */
308struct usb_endpoint
309{
310    struct usb_xfer_queue transfers;
311
312    struct usb_endpoint_descriptor *descriptor;
313
314    struct usb_hcdi_pipe_fn *pipe_fn;
315
316    uint16_t isoc_next;
317
318    uint8_t data_toggle : 1;
319    uint8_t is_stalled : 1;
320    uint8_t is_sync : 1;
321    uint8_t unused : 5;
322
323    struct usb_interface *iface;
324    uint8_t iface_index;
325    uint8_t endpoint_address;
326
327    uint8_t ref_allocation;
328    uint8_t ref_bandwidth;
329    uint8_t hs_smask;
330    uint8_t hs_cmask;
331    uint8_t hs_uframe;
332
333    uint16_t max_packet_size;
334
335    uint32_t status;
336};
337
338// endpoint status flag for usb_status_t
339#define USB_ENDPOINT_STATUS_HALT 0x0001
340
341// the USB control endpoint
342#define USB_ENDPOINT_CONTROL 0
343
344// the maximum number of endpoints
345#define USB_ENDPOINT_MAX 32
346
347
348
349void usb_xfer_enqueue(struct usb_xfer_queue *queue, struct usb_xfer *xfer);
350void usb_xfer_dequeue(struct usb_xfer *xfer);
351void usb_xfer_done(struct usb_xfer *xfer, usb_error_t err);
352void usb_xfer_setup_struct(struct usb_xfer_setup_params *param);
353
354#endif  /* USB_XFER_H_ */
355