Statistics
| Branch: | Revision:

root / hw / usb / core.c @ cba933b2

History | View | Annotate | Download (22.8 kB)

1 bb36d470 bellard
/*
2 bb36d470 bellard
 * QEMU USB emulation
3 bb36d470 bellard
 *
4 bb36d470 bellard
 * Copyright (c) 2005 Fabrice Bellard
5 5fafdf24 ths
 *
6 89b9b79f aliguori
 * 2008 Generic packet handler rewrite by Max Krasnyansky
7 89b9b79f aliguori
 *
8 bb36d470 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 bb36d470 bellard
 * of this software and associated documentation files (the "Software"), to deal
10 bb36d470 bellard
 * in the Software without restriction, including without limitation the rights
11 bb36d470 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 bb36d470 bellard
 * copies of the Software, and to permit persons to whom the Software is
13 bb36d470 bellard
 * furnished to do so, subject to the following conditions:
14 bb36d470 bellard
 *
15 bb36d470 bellard
 * The above copyright notice and this permission notice shall be included in
16 bb36d470 bellard
 * all copies or substantial portions of the Software.
17 bb36d470 bellard
 *
18 bb36d470 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 bb36d470 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 bb36d470 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 bb36d470 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 bb36d470 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 bb36d470 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 bb36d470 bellard
 * THE SOFTWARE.
25 bb36d470 bellard
 */
26 87ecb68b pbrook
#include "qemu-common.h"
27 f1ae32a1 Gerd Hoffmann
#include "hw/usb.h"
28 1de7afc9 Paolo Bonzini
#include "qemu/iov.h"
29 808aeb98 Gerd Hoffmann
#include "trace.h"
30 bb36d470 bellard
31 891fb2cd Gerd Hoffmann
void usb_attach(USBPort *port)
32 bb36d470 bellard
{
33 891fb2cd Gerd Hoffmann
    USBDevice *dev = port->dev;
34 891fb2cd Gerd Hoffmann
35 891fb2cd Gerd Hoffmann
    assert(dev != NULL);
36 891fb2cd Gerd Hoffmann
    assert(dev->attached);
37 e0b8e72d Gerd Hoffmann
    assert(dev->state == USB_STATE_NOTATTACHED);
38 891fb2cd Gerd Hoffmann
    port->ops->attach(port);
39 d1f8b536 Gerd Hoffmann
    dev->state = USB_STATE_ATTACHED;
40 d1f8b536 Gerd Hoffmann
    usb_device_handle_attach(dev);
41 891fb2cd Gerd Hoffmann
}
42 891fb2cd Gerd Hoffmann
43 891fb2cd Gerd Hoffmann
void usb_detach(USBPort *port)
44 891fb2cd Gerd Hoffmann
{
45 891fb2cd Gerd Hoffmann
    USBDevice *dev = port->dev;
46 891fb2cd Gerd Hoffmann
47 891fb2cd Gerd Hoffmann
    assert(dev != NULL);
48 e0b8e72d Gerd Hoffmann
    assert(dev->state != USB_STATE_NOTATTACHED);
49 891fb2cd Gerd Hoffmann
    port->ops->detach(port);
50 d1f8b536 Gerd Hoffmann
    dev->state = USB_STATE_NOTATTACHED;
51 bb36d470 bellard
}
52 bb36d470 bellard
53 d28f4e2d Gerd Hoffmann
void usb_port_reset(USBPort *port)
54 e0b8e72d Gerd Hoffmann
{
55 e0b8e72d Gerd Hoffmann
    USBDevice *dev = port->dev;
56 e0b8e72d Gerd Hoffmann
57 e0b8e72d Gerd Hoffmann
    assert(dev != NULL);
58 e0b8e72d Gerd Hoffmann
    usb_detach(port);
59 e0b8e72d Gerd Hoffmann
    usb_attach(port);
60 d28f4e2d Gerd Hoffmann
    usb_device_reset(dev);
61 d28f4e2d Gerd Hoffmann
}
62 d28f4e2d Gerd Hoffmann
63 d28f4e2d Gerd Hoffmann
void usb_device_reset(USBDevice *dev)
64 d28f4e2d Gerd Hoffmann
{
65 d28f4e2d Gerd Hoffmann
    if (dev == NULL || !dev->attached) {
66 d28f4e2d Gerd Hoffmann
        return;
67 d28f4e2d Gerd Hoffmann
    }
68 d28f4e2d Gerd Hoffmann
    dev->remote_wakeup = 0;
69 d28f4e2d Gerd Hoffmann
    dev->addr = 0;
70 d28f4e2d Gerd Hoffmann
    dev->state = USB_STATE_DEFAULT;
71 d28f4e2d Gerd Hoffmann
    usb_device_handle_reset(dev);
72 e0b8e72d Gerd Hoffmann
}
73 e0b8e72d Gerd Hoffmann
74 8550a02d Gerd Hoffmann
void usb_wakeup(USBEndpoint *ep, unsigned int stream)
75 01eacab6 Gerd Hoffmann
{
76 7567b51f Gerd Hoffmann
    USBDevice *dev = ep->dev;
77 37f32f0f Gerd Hoffmann
    USBBus *bus = usb_bus_from_device(dev);
78 7567b51f Gerd Hoffmann
79 01eacab6 Gerd Hoffmann
    if (dev->remote_wakeup && dev->port && dev->port->ops->wakeup) {
80 d47e59b8 Hans de Goede
        dev->port->ops->wakeup(dev->port);
81 01eacab6 Gerd Hoffmann
    }
82 37f32f0f Gerd Hoffmann
    if (bus->ops->wakeup_endpoint) {
83 8550a02d Gerd Hoffmann
        bus->ops->wakeup_endpoint(bus, ep, stream);
84 37f32f0f Gerd Hoffmann
    }
85 01eacab6 Gerd Hoffmann
}
86 01eacab6 Gerd Hoffmann
87 bb36d470 bellard
/**********************/
88 89b9b79f aliguori
89 bb36d470 bellard
/* generic USB device helpers (you are not forced to use them when
90 bb36d470 bellard
   writing your USB device driver, but they help handling the
91 5fafdf24 ths
   protocol)
92 bb36d470 bellard
*/
93 bb36d470 bellard
94 50b7963e Hans de Goede
#define SETUP_STATE_IDLE  0
95 50b7963e Hans de Goede
#define SETUP_STATE_SETUP 1
96 50b7963e Hans de Goede
#define SETUP_STATE_DATA  2
97 50b7963e Hans de Goede
#define SETUP_STATE_ACK   3
98 1b4b29a1 Gerd Hoffmann
#define SETUP_STATE_PARAM 4
99 bb36d470 bellard
100 9a77a0f5 Hans de Goede
static void do_token_setup(USBDevice *s, USBPacket *p)
101 89b9b79f aliguori
{
102 89b9b79f aliguori
    int request, value, index;
103 89b9b79f aliguori
104 4f4321c1 Gerd Hoffmann
    if (p->iov.size != 8) {
105 9a77a0f5 Hans de Goede
        p->status = USB_RET_STALL;
106 9a77a0f5 Hans de Goede
        return;
107 4f4321c1 Gerd Hoffmann
    }
108 4f4321c1 Gerd Hoffmann
109 4f4321c1 Gerd Hoffmann
    usb_packet_copy(p, s->setup_buf, p->iov.size);
110 9a77a0f5 Hans de Goede
    p->actual_length = 0;
111 89b9b79f aliguori
    s->setup_len   = (s->setup_buf[7] << 8) | s->setup_buf[6];
112 89b9b79f aliguori
    s->setup_index = 0;
113 89b9b79f aliguori
114 89b9b79f aliguori
    request = (s->setup_buf[0] << 8) | s->setup_buf[1];
115 89b9b79f aliguori
    value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
116 89b9b79f aliguori
    index   = (s->setup_buf[5] << 8) | s->setup_buf[4];
117 007fd62f Hans de Goede
118 89b9b79f aliguori
    if (s->setup_buf[0] & USB_DIR_IN) {
119 9a77a0f5 Hans de Goede
        usb_device_handle_control(s, p, request, value, index,
120 9a77a0f5 Hans de Goede
                                  s->setup_len, s->data_buf);
121 9a77a0f5 Hans de Goede
        if (p->status == USB_RET_ASYNC) {
122 9a77a0f5 Hans de Goede
            s->setup_state = SETUP_STATE_SETUP;
123 9a77a0f5 Hans de Goede
        }
124 9a77a0f5 Hans de Goede
        if (p->status != USB_RET_SUCCESS) {
125 9a77a0f5 Hans de Goede
            return;
126 50b7963e Hans de Goede
        }
127 89b9b79f aliguori
128 9a77a0f5 Hans de Goede
        if (p->actual_length < s->setup_len) {
129 9a77a0f5 Hans de Goede
            s->setup_len = p->actual_length;
130 9a77a0f5 Hans de Goede
        }
131 89b9b79f aliguori
        s->setup_state = SETUP_STATE_DATA;
132 89b9b79f aliguori
    } else {
133 19f33223 Hans de Goede
        if (s->setup_len > sizeof(s->data_buf)) {
134 19f33223 Hans de Goede
            fprintf(stderr,
135 19f33223 Hans de Goede
                "usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n",
136 19f33223 Hans de Goede
                s->setup_len, sizeof(s->data_buf));
137 9a77a0f5 Hans de Goede
            p->status = USB_RET_STALL;
138 9a77a0f5 Hans de Goede
            return;
139 19f33223 Hans de Goede
        }
140 89b9b79f aliguori
        if (s->setup_len == 0)
141 89b9b79f aliguori
            s->setup_state = SETUP_STATE_ACK;
142 89b9b79f aliguori
        else
143 89b9b79f aliguori
            s->setup_state = SETUP_STATE_DATA;
144 89b9b79f aliguori
    }
145 89b9b79f aliguori
146 9a77a0f5 Hans de Goede
    p->actual_length = 8;
147 89b9b79f aliguori
}
148 89b9b79f aliguori
149 9a77a0f5 Hans de Goede
static void do_token_in(USBDevice *s, USBPacket *p)
150 bb36d470 bellard
{
151 89b9b79f aliguori
    int request, value, index;
152 89b9b79f aliguori
153 079d0b7f Gerd Hoffmann
    assert(p->ep->nr == 0);
154 89b9b79f aliguori
155 89b9b79f aliguori
    request = (s->setup_buf[0] << 8) | s->setup_buf[1];
156 89b9b79f aliguori
    value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
157 89b9b79f aliguori
    index   = (s->setup_buf[5] << 8) | s->setup_buf[4];
158 89b9b79f aliguori
 
159 89b9b79f aliguori
    switch(s->setup_state) {
160 89b9b79f aliguori
    case SETUP_STATE_ACK:
161 89b9b79f aliguori
        if (!(s->setup_buf[0] & USB_DIR_IN)) {
162 9a77a0f5 Hans de Goede
            usb_device_handle_control(s, p, request, value, index,
163 9a77a0f5 Hans de Goede
                                      s->setup_len, s->data_buf);
164 9a77a0f5 Hans de Goede
            if (p->status == USB_RET_ASYNC) {
165 9a77a0f5 Hans de Goede
                return;
166 007fd62f Hans de Goede
            }
167 007fd62f Hans de Goede
            s->setup_state = SETUP_STATE_IDLE;
168 9a77a0f5 Hans de Goede
            p->actual_length = 0;
169 89b9b79f aliguori
        }
170 9a77a0f5 Hans de Goede
        break;
171 89b9b79f aliguori
172 89b9b79f aliguori
    case SETUP_STATE_DATA:
173 89b9b79f aliguori
        if (s->setup_buf[0] & USB_DIR_IN) {
174 89b9b79f aliguori
            int len = s->setup_len - s->setup_index;
175 4f4321c1 Gerd Hoffmann
            if (len > p->iov.size) {
176 4f4321c1 Gerd Hoffmann
                len = p->iov.size;
177 4f4321c1 Gerd Hoffmann
            }
178 4f4321c1 Gerd Hoffmann
            usb_packet_copy(p, s->data_buf + s->setup_index, len);
179 89b9b79f aliguori
            s->setup_index += len;
180 9a77a0f5 Hans de Goede
            if (s->setup_index >= s->setup_len) {
181 89b9b79f aliguori
                s->setup_state = SETUP_STATE_ACK;
182 9a77a0f5 Hans de Goede
            }
183 9a77a0f5 Hans de Goede
            return;
184 89b9b79f aliguori
        }
185 89b9b79f aliguori
        s->setup_state = SETUP_STATE_IDLE;
186 9a77a0f5 Hans de Goede
        p->status = USB_RET_STALL;
187 9a77a0f5 Hans de Goede
        break;
188 89b9b79f aliguori
189 89b9b79f aliguori
    default:
190 9a77a0f5 Hans de Goede
        p->status = USB_RET_STALL;
191 89b9b79f aliguori
    }
192 89b9b79f aliguori
}
193 89b9b79f aliguori
194 9a77a0f5 Hans de Goede
static void do_token_out(USBDevice *s, USBPacket *p)
195 89b9b79f aliguori
{
196 079d0b7f Gerd Hoffmann
    assert(p->ep->nr == 0);
197 89b9b79f aliguori
198 89b9b79f aliguori
    switch(s->setup_state) {
199 89b9b79f aliguori
    case SETUP_STATE_ACK:
200 89b9b79f aliguori
        if (s->setup_buf[0] & USB_DIR_IN) {
201 89b9b79f aliguori
            s->setup_state = SETUP_STATE_IDLE;
202 89b9b79f aliguori
            /* transfer OK */
203 89b9b79f aliguori
        } else {
204 89b9b79f aliguori
            /* ignore additional output */
205 89b9b79f aliguori
        }
206 9a77a0f5 Hans de Goede
        break;
207 89b9b79f aliguori
208 89b9b79f aliguori
    case SETUP_STATE_DATA:
209 89b9b79f aliguori
        if (!(s->setup_buf[0] & USB_DIR_IN)) {
210 89b9b79f aliguori
            int len = s->setup_len - s->setup_index;
211 4f4321c1 Gerd Hoffmann
            if (len > p->iov.size) {
212 4f4321c1 Gerd Hoffmann
                len = p->iov.size;
213 4f4321c1 Gerd Hoffmann
            }
214 4f4321c1 Gerd Hoffmann
            usb_packet_copy(p, s->data_buf + s->setup_index, len);
215 89b9b79f aliguori
            s->setup_index += len;
216 9a77a0f5 Hans de Goede
            if (s->setup_index >= s->setup_len) {
217 89b9b79f aliguori
                s->setup_state = SETUP_STATE_ACK;
218 9a77a0f5 Hans de Goede
            }
219 9a77a0f5 Hans de Goede
            return;
220 89b9b79f aliguori
        }
221 89b9b79f aliguori
        s->setup_state = SETUP_STATE_IDLE;
222 9a77a0f5 Hans de Goede
        p->status = USB_RET_STALL;
223 9a77a0f5 Hans de Goede
        break;
224 89b9b79f aliguori
225 89b9b79f aliguori
    default:
226 9a77a0f5 Hans de Goede
        p->status = USB_RET_STALL;
227 89b9b79f aliguori
    }
228 89b9b79f aliguori
}
229 bb36d470 bellard
230 9a77a0f5 Hans de Goede
static void do_parameter(USBDevice *s, USBPacket *p)
231 1b4b29a1 Gerd Hoffmann
{
232 9a77a0f5 Hans de Goede
    int i, request, value, index;
233 1b4b29a1 Gerd Hoffmann
234 1b4b29a1 Gerd Hoffmann
    for (i = 0; i < 8; i++) {
235 1b4b29a1 Gerd Hoffmann
        s->setup_buf[i] = p->parameter >> (i*8);
236 1b4b29a1 Gerd Hoffmann
    }
237 1b4b29a1 Gerd Hoffmann
238 1b4b29a1 Gerd Hoffmann
    s->setup_state = SETUP_STATE_PARAM;
239 1b4b29a1 Gerd Hoffmann
    s->setup_len   = (s->setup_buf[7] << 8) | s->setup_buf[6];
240 1b4b29a1 Gerd Hoffmann
    s->setup_index = 0;
241 1b4b29a1 Gerd Hoffmann
242 1b4b29a1 Gerd Hoffmann
    request = (s->setup_buf[0] << 8) | s->setup_buf[1];
243 1b4b29a1 Gerd Hoffmann
    value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
244 1b4b29a1 Gerd Hoffmann
    index   = (s->setup_buf[5] << 8) | s->setup_buf[4];
245 1b4b29a1 Gerd Hoffmann
246 1b4b29a1 Gerd Hoffmann
    if (s->setup_len > sizeof(s->data_buf)) {
247 1b4b29a1 Gerd Hoffmann
        fprintf(stderr,
248 1b4b29a1 Gerd Hoffmann
                "usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n",
249 1b4b29a1 Gerd Hoffmann
                s->setup_len, sizeof(s->data_buf));
250 9a77a0f5 Hans de Goede
        p->status = USB_RET_STALL;
251 9a77a0f5 Hans de Goede
        return;
252 1b4b29a1 Gerd Hoffmann
    }
253 1b4b29a1 Gerd Hoffmann
254 1b4b29a1 Gerd Hoffmann
    if (p->pid == USB_TOKEN_OUT) {
255 1b4b29a1 Gerd Hoffmann
        usb_packet_copy(p, s->data_buf, s->setup_len);
256 1b4b29a1 Gerd Hoffmann
    }
257 1b4b29a1 Gerd Hoffmann
258 9a77a0f5 Hans de Goede
    usb_device_handle_control(s, p, request, value, index,
259 9a77a0f5 Hans de Goede
                              s->setup_len, s->data_buf);
260 9a77a0f5 Hans de Goede
    if (p->status == USB_RET_ASYNC) {
261 9a77a0f5 Hans de Goede
        return;
262 1b4b29a1 Gerd Hoffmann
    }
263 1b4b29a1 Gerd Hoffmann
264 9a77a0f5 Hans de Goede
    if (p->actual_length < s->setup_len) {
265 9a77a0f5 Hans de Goede
        s->setup_len = p->actual_length;
266 1b4b29a1 Gerd Hoffmann
    }
267 1b4b29a1 Gerd Hoffmann
    if (p->pid == USB_TOKEN_IN) {
268 9a77a0f5 Hans de Goede
        p->actual_length = 0;
269 1b4b29a1 Gerd Hoffmann
        usb_packet_copy(p, s->data_buf, s->setup_len);
270 1b4b29a1 Gerd Hoffmann
    }
271 1b4b29a1 Gerd Hoffmann
}
272 1b4b29a1 Gerd Hoffmann
273 50b7963e Hans de Goede
/* ctrl complete function for devices which use usb_generic_handle_packet and
274 50b7963e Hans de Goede
   may return USB_RET_ASYNC from their handle_control callback. Device code
275 50b7963e Hans de Goede
   which does this *must* call this function instead of the normal
276 50b7963e Hans de Goede
   usb_packet_complete to complete their async control packets. */
277 50b7963e Hans de Goede
void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p)
278 50b7963e Hans de Goede
{
279 9a77a0f5 Hans de Goede
    if (p->status < 0) {
280 50b7963e Hans de Goede
        s->setup_state = SETUP_STATE_IDLE;
281 50b7963e Hans de Goede
    }
282 50b7963e Hans de Goede
283 50b7963e Hans de Goede
    switch (s->setup_state) {
284 50b7963e Hans de Goede
    case SETUP_STATE_SETUP:
285 9a77a0f5 Hans de Goede
        if (p->actual_length < s->setup_len) {
286 9a77a0f5 Hans de Goede
            s->setup_len = p->actual_length;
287 50b7963e Hans de Goede
        }
288 50b7963e Hans de Goede
        s->setup_state = SETUP_STATE_DATA;
289 9a77a0f5 Hans de Goede
        p->actual_length = 8;
290 50b7963e Hans de Goede
        break;
291 50b7963e Hans de Goede
292 50b7963e Hans de Goede
    case SETUP_STATE_ACK:
293 50b7963e Hans de Goede
        s->setup_state = SETUP_STATE_IDLE;
294 9a77a0f5 Hans de Goede
        p->actual_length = 0;
295 50b7963e Hans de Goede
        break;
296 50b7963e Hans de Goede
297 1b4b29a1 Gerd Hoffmann
    case SETUP_STATE_PARAM:
298 9a77a0f5 Hans de Goede
        if (p->actual_length < s->setup_len) {
299 9a77a0f5 Hans de Goede
            s->setup_len = p->actual_length;
300 1b4b29a1 Gerd Hoffmann
        }
301 1b4b29a1 Gerd Hoffmann
        if (p->pid == USB_TOKEN_IN) {
302 9a77a0f5 Hans de Goede
            p->actual_length = 0;
303 1b4b29a1 Gerd Hoffmann
            usb_packet_copy(p, s->data_buf, s->setup_len);
304 1b4b29a1 Gerd Hoffmann
        }
305 1b4b29a1 Gerd Hoffmann
        break;
306 1b4b29a1 Gerd Hoffmann
307 50b7963e Hans de Goede
    default:
308 50b7963e Hans de Goede
        break;
309 50b7963e Hans de Goede
    }
310 50b7963e Hans de Goede
    usb_packet_complete(s, p);
311 50b7963e Hans de Goede
}
312 50b7963e Hans de Goede
313 bb36d470 bellard
/* XXX: fix overflow */
314 bb36d470 bellard
int set_usb_string(uint8_t *buf, const char *str)
315 bb36d470 bellard
{
316 bb36d470 bellard
    int len, i;
317 bb36d470 bellard
    uint8_t *q;
318 bb36d470 bellard
319 bb36d470 bellard
    q = buf;
320 bb36d470 bellard
    len = strlen(str);
321 ce5c37c2 pbrook
    *q++ = 2 * len + 2;
322 bb36d470 bellard
    *q++ = 3;
323 bb36d470 bellard
    for(i = 0; i < len; i++) {
324 bb36d470 bellard
        *q++ = str[i];
325 bb36d470 bellard
        *q++ = 0;
326 bb36d470 bellard
    }
327 bb36d470 bellard
    return q - buf;
328 bb36d470 bellard
}
329 4d611c9a pbrook
330 73796fe6 Gerd Hoffmann
USBDevice *usb_find_device(USBPort *port, uint8_t addr)
331 73796fe6 Gerd Hoffmann
{
332 73796fe6 Gerd Hoffmann
    USBDevice *dev = port->dev;
333 73796fe6 Gerd Hoffmann
334 73796fe6 Gerd Hoffmann
    if (dev == NULL || !dev->attached || dev->state != USB_STATE_DEFAULT) {
335 73796fe6 Gerd Hoffmann
        return NULL;
336 73796fe6 Gerd Hoffmann
    }
337 73796fe6 Gerd Hoffmann
    if (dev->addr == addr) {
338 73796fe6 Gerd Hoffmann
        return dev;
339 73796fe6 Gerd Hoffmann
    }
340 73796fe6 Gerd Hoffmann
    return usb_device_find_device(dev, addr);
341 73796fe6 Gerd Hoffmann
}
342 73796fe6 Gerd Hoffmann
343 9a77a0f5 Hans de Goede
static void usb_process_one(USBPacket *p)
344 db4be873 Gerd Hoffmann
{
345 db4be873 Gerd Hoffmann
    USBDevice *dev = p->ep->dev;
346 db4be873 Gerd Hoffmann
347 9a77a0f5 Hans de Goede
    /*
348 9a77a0f5 Hans de Goede
     * Handlers expect status to be initialized to USB_RET_SUCCESS, but it
349 9a77a0f5 Hans de Goede
     * can be USB_RET_NAK here from a previous usb_process_one() call,
350 9a77a0f5 Hans de Goede
     * or USB_RET_ASYNC from going through usb_queue_one().
351 9a77a0f5 Hans de Goede
     */
352 9a77a0f5 Hans de Goede
    p->status = USB_RET_SUCCESS;
353 9a77a0f5 Hans de Goede
354 db4be873 Gerd Hoffmann
    if (p->ep->nr == 0) {
355 db4be873 Gerd Hoffmann
        /* control pipe */
356 1b4b29a1 Gerd Hoffmann
        if (p->parameter) {
357 9a77a0f5 Hans de Goede
            do_parameter(dev, p);
358 9a77a0f5 Hans de Goede
            return;
359 1b4b29a1 Gerd Hoffmann
        }
360 db4be873 Gerd Hoffmann
        switch (p->pid) {
361 db4be873 Gerd Hoffmann
        case USB_TOKEN_SETUP:
362 9a77a0f5 Hans de Goede
            do_token_setup(dev, p);
363 9a77a0f5 Hans de Goede
            break;
364 db4be873 Gerd Hoffmann
        case USB_TOKEN_IN:
365 9a77a0f5 Hans de Goede
            do_token_in(dev, p);
366 9a77a0f5 Hans de Goede
            break;
367 db4be873 Gerd Hoffmann
        case USB_TOKEN_OUT:
368 9a77a0f5 Hans de Goede
            do_token_out(dev, p);
369 9a77a0f5 Hans de Goede
            break;
370 db4be873 Gerd Hoffmann
        default:
371 9a77a0f5 Hans de Goede
            p->status = USB_RET_STALL;
372 db4be873 Gerd Hoffmann
        }
373 db4be873 Gerd Hoffmann
    } else {
374 db4be873 Gerd Hoffmann
        /* data pipe */
375 9a77a0f5 Hans de Goede
        usb_device_handle_data(dev, p);
376 db4be873 Gerd Hoffmann
    }
377 db4be873 Gerd Hoffmann
}
378 db4be873 Gerd Hoffmann
379 9a77a0f5 Hans de Goede
static void usb_queue_one(USBPacket *p)
380 9a77a0f5 Hans de Goede
{
381 9a77a0f5 Hans de Goede
    usb_packet_set_state(p, USB_PACKET_QUEUED);
382 9a77a0f5 Hans de Goede
    QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue);
383 9a77a0f5 Hans de Goede
    p->status = USB_RET_ASYNC;
384 9a77a0f5 Hans de Goede
}
385 9a77a0f5 Hans de Goede
386 9a77a0f5 Hans de Goede
/* Hand over a packet to a device for processing.  p->status ==
387 53aa8c0e Gerd Hoffmann
   USB_RET_ASYNC indicates the processing isn't finished yet, the
388 53aa8c0e Gerd Hoffmann
   driver will call usb_packet_complete() when done processing it. */
389 9a77a0f5 Hans de Goede
void usb_handle_packet(USBDevice *dev, USBPacket *p)
390 53aa8c0e Gerd Hoffmann
{
391 98861f51 Gerd Hoffmann
    if (dev == NULL) {
392 9a77a0f5 Hans de Goede
        p->status = USB_RET_NODEV;
393 9a77a0f5 Hans de Goede
        return;
394 98861f51 Gerd Hoffmann
    }
395 079d0b7f Gerd Hoffmann
    assert(dev == p->ep->dev);
396 1977f93d Gerd Hoffmann
    assert(dev->state == USB_STATE_DEFAULT);
397 5ac2731c Gerd Hoffmann
    usb_packet_check_state(p, USB_PACKET_SETUP);
398 db4be873 Gerd Hoffmann
    assert(p->ep != NULL);
399 1977f93d Gerd Hoffmann
400 0132b4b6 Hans de Goede
    /* Submitting a new packet clears halt */
401 0132b4b6 Hans de Goede
    if (p->ep->halted) {
402 0132b4b6 Hans de Goede
        assert(QTAILQ_EMPTY(&p->ep->queue));
403 0132b4b6 Hans de Goede
        p->ep->halted = false;
404 0132b4b6 Hans de Goede
    }
405 0132b4b6 Hans de Goede
406 c96c41ed Gerd Hoffmann
    if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline || p->stream) {
407 9a77a0f5 Hans de Goede
        usb_process_one(p);
408 9a77a0f5 Hans de Goede
        if (p->status == USB_RET_ASYNC) {
409 be41efde Hans de Goede
            /* hcd drivers cannot handle async for isoc */
410 aaac7434 Hans de Goede
            assert(p->ep->type != USB_ENDPOINT_XFER_ISOC);
411 be41efde Hans de Goede
            /* using async for interrupt packets breaks migration */
412 be41efde Hans de Goede
            assert(p->ep->type != USB_ENDPOINT_XFER_INT ||
413 75633529 Michael Marineau
                   (dev->flags & (1 << USB_DEV_FLAG_IS_HOST)));
414 db4be873 Gerd Hoffmann
            usb_packet_set_state(p, USB_PACKET_ASYNC);
415 db4be873 Gerd Hoffmann
            QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue);
416 9a77a0f5 Hans de Goede
        } else if (p->status == USB_RET_ADD_TO_QUEUE) {
417 9a77a0f5 Hans de Goede
            usb_queue_one(p);
418 db4be873 Gerd Hoffmann
        } else {
419 0132b4b6 Hans de Goede
            /*
420 0132b4b6 Hans de Goede
             * When pipelining is enabled usb-devices must always return async,
421 0132b4b6 Hans de Goede
             * otherwise packets can complete out of order!
422 0132b4b6 Hans de Goede
             */
423 c96c41ed Gerd Hoffmann
            assert(p->stream || !p->ep->pipeline ||
424 c96c41ed Gerd Hoffmann
                   QTAILQ_EMPTY(&p->ep->queue));
425 9a77a0f5 Hans de Goede
            if (p->status != USB_RET_NAK) {
426 cc409974 Hans de Goede
                usb_packet_set_state(p, USB_PACKET_COMPLETE);
427 cc409974 Hans de Goede
            }
428 1977f93d Gerd Hoffmann
        }
429 1977f93d Gerd Hoffmann
    } else {
430 9a77a0f5 Hans de Goede
        usb_queue_one(p);
431 4ff658fb Gerd Hoffmann
    }
432 89b9b79f aliguori
}
433 4ff658fb Gerd Hoffmann
434 d0ff81b8 Hans de Goede
void usb_packet_complete_one(USBDevice *dev, USBPacket *p)
435 0132b4b6 Hans de Goede
{
436 0132b4b6 Hans de Goede
    USBEndpoint *ep = p->ep;
437 0132b4b6 Hans de Goede
438 c96c41ed Gerd Hoffmann
    assert(p->stream || QTAILQ_FIRST(&ep->queue) == p);
439 9a77a0f5 Hans de Goede
    assert(p->status != USB_RET_ASYNC && p->status != USB_RET_NAK);
440 0132b4b6 Hans de Goede
441 9a77a0f5 Hans de Goede
    if (p->status != USB_RET_SUCCESS ||
442 9a77a0f5 Hans de Goede
            (p->short_not_ok && (p->actual_length < p->iov.size))) {
443 0132b4b6 Hans de Goede
        ep->halted = true;
444 0132b4b6 Hans de Goede
    }
445 0132b4b6 Hans de Goede
    usb_packet_set_state(p, USB_PACKET_COMPLETE);
446 0132b4b6 Hans de Goede
    QTAILQ_REMOVE(&ep->queue, p, queue);
447 0132b4b6 Hans de Goede
    dev->port->ops->complete(dev->port, p);
448 0132b4b6 Hans de Goede
}
449 0132b4b6 Hans de Goede
450 4ff658fb Gerd Hoffmann
/* Notify the controller that an async packet is complete.  This should only
451 4ff658fb Gerd Hoffmann
   be called for packets previously deferred by returning USB_RET_ASYNC from
452 4ff658fb Gerd Hoffmann
   handle_packet. */
453 4ff658fb Gerd Hoffmann
void usb_packet_complete(USBDevice *dev, USBPacket *p)
454 4ff658fb Gerd Hoffmann
{
455 db4be873 Gerd Hoffmann
    USBEndpoint *ep = p->ep;
456 db4be873 Gerd Hoffmann
457 5ac2731c Gerd Hoffmann
    usb_packet_check_state(p, USB_PACKET_ASYNC);
458 d0ff81b8 Hans de Goede
    usb_packet_complete_one(dev, p);
459 db4be873 Gerd Hoffmann
460 0cae7b1a Hans de Goede
    while (!QTAILQ_EMPTY(&ep->queue)) {
461 db4be873 Gerd Hoffmann
        p = QTAILQ_FIRST(&ep->queue);
462 0cae7b1a Hans de Goede
        if (ep->halted) {
463 0cae7b1a Hans de Goede
            /* Empty the queue on a halt */
464 9a77a0f5 Hans de Goede
            p->status = USB_RET_REMOVE_FROM_QUEUE;
465 0cae7b1a Hans de Goede
            dev->port->ops->complete(dev->port, p);
466 0cae7b1a Hans de Goede
            continue;
467 0cae7b1a Hans de Goede
        }
468 eb9d4673 Gerd Hoffmann
        if (p->state == USB_PACKET_ASYNC) {
469 eb9d4673 Gerd Hoffmann
            break;
470 eb9d4673 Gerd Hoffmann
        }
471 5ac2731c Gerd Hoffmann
        usb_packet_check_state(p, USB_PACKET_QUEUED);
472 9a77a0f5 Hans de Goede
        usb_process_one(p);
473 9a77a0f5 Hans de Goede
        if (p->status == USB_RET_ASYNC) {
474 db4be873 Gerd Hoffmann
            usb_packet_set_state(p, USB_PACKET_ASYNC);
475 db4be873 Gerd Hoffmann
            break;
476 db4be873 Gerd Hoffmann
        }
477 d0ff81b8 Hans de Goede
        usb_packet_complete_one(ep->dev, p);
478 db4be873 Gerd Hoffmann
    }
479 4ff658fb Gerd Hoffmann
}
480 4ff658fb Gerd Hoffmann
481 4ff658fb Gerd Hoffmann
/* Cancel an active packet.  The packed must have been deferred by
482 4ff658fb Gerd Hoffmann
   returning USB_RET_ASYNC from handle_packet, and not yet
483 4ff658fb Gerd Hoffmann
   completed.  */
484 4ff658fb Gerd Hoffmann
void usb_cancel_packet(USBPacket * p)
485 4ff658fb Gerd Hoffmann
{
486 db4be873 Gerd Hoffmann
    bool callback = (p->state == USB_PACKET_ASYNC);
487 db4be873 Gerd Hoffmann
    assert(usb_packet_is_inflight(p));
488 db4be873 Gerd Hoffmann
    usb_packet_set_state(p, USB_PACKET_CANCELED);
489 db4be873 Gerd Hoffmann
    QTAILQ_REMOVE(&p->ep->queue, p, queue);
490 db4be873 Gerd Hoffmann
    if (callback) {
491 db4be873 Gerd Hoffmann
        usb_device_cancel_packet(p->ep->dev, p);
492 db4be873 Gerd Hoffmann
    }
493 4ff658fb Gerd Hoffmann
}
494 4f4321c1 Gerd Hoffmann
495 4f4321c1 Gerd Hoffmann
496 4f4321c1 Gerd Hoffmann
void usb_packet_init(USBPacket *p)
497 4f4321c1 Gerd Hoffmann
{
498 4f4321c1 Gerd Hoffmann
    qemu_iovec_init(&p->iov, 1);
499 4f4321c1 Gerd Hoffmann
}
500 4f4321c1 Gerd Hoffmann
501 5ac2731c Gerd Hoffmann
static const char *usb_packet_state_name(USBPacketState state)
502 db4be873 Gerd Hoffmann
{
503 db4be873 Gerd Hoffmann
    static const char *name[] = {
504 db4be873 Gerd Hoffmann
        [USB_PACKET_UNDEFINED] = "undef",
505 db4be873 Gerd Hoffmann
        [USB_PACKET_SETUP]     = "setup",
506 db4be873 Gerd Hoffmann
        [USB_PACKET_QUEUED]    = "queued",
507 db4be873 Gerd Hoffmann
        [USB_PACKET_ASYNC]     = "async",
508 db4be873 Gerd Hoffmann
        [USB_PACKET_COMPLETE]  = "complete",
509 db4be873 Gerd Hoffmann
        [USB_PACKET_CANCELED]  = "canceled",
510 db4be873 Gerd Hoffmann
    };
511 5ac2731c Gerd Hoffmann
    if (state < ARRAY_SIZE(name)) {
512 5ac2731c Gerd Hoffmann
        return name[state];
513 5ac2731c Gerd Hoffmann
    }
514 5ac2731c Gerd Hoffmann
    return "INVALID";
515 5ac2731c Gerd Hoffmann
}
516 5ac2731c Gerd Hoffmann
517 5ac2731c Gerd Hoffmann
void usb_packet_check_state(USBPacket *p, USBPacketState expected)
518 5ac2731c Gerd Hoffmann
{
519 5ac2731c Gerd Hoffmann
    USBDevice *dev;
520 5ac2731c Gerd Hoffmann
    USBBus *bus;
521 5ac2731c Gerd Hoffmann
522 5ac2731c Gerd Hoffmann
    if (p->state == expected) {
523 5ac2731c Gerd Hoffmann
        return;
524 5ac2731c Gerd Hoffmann
    }
525 5ac2731c Gerd Hoffmann
    dev = p->ep->dev;
526 5ac2731c Gerd Hoffmann
    bus = usb_bus_from_device(dev);
527 5ac2731c Gerd Hoffmann
    trace_usb_packet_state_fault(bus->busnr, dev->port->path, p->ep->nr, p,
528 5ac2731c Gerd Hoffmann
                                 usb_packet_state_name(p->state),
529 5ac2731c Gerd Hoffmann
                                 usb_packet_state_name(expected));
530 5ac2731c Gerd Hoffmann
    assert(!"usb packet state check failed");
531 5ac2731c Gerd Hoffmann
}
532 5ac2731c Gerd Hoffmann
533 5ac2731c Gerd Hoffmann
void usb_packet_set_state(USBPacket *p, USBPacketState state)
534 5ac2731c Gerd Hoffmann
{
535 f5bf14bf Gerd Hoffmann
    if (p->ep) {
536 f5bf14bf Gerd Hoffmann
        USBDevice *dev = p->ep->dev;
537 f5bf14bf Gerd Hoffmann
        USBBus *bus = usb_bus_from_device(dev);
538 f5bf14bf Gerd Hoffmann
        trace_usb_packet_state_change(bus->busnr, dev->port->path, p->ep->nr, p,
539 f5bf14bf Gerd Hoffmann
                                      usb_packet_state_name(p->state),
540 f5bf14bf Gerd Hoffmann
                                      usb_packet_state_name(state));
541 f5bf14bf Gerd Hoffmann
    } else {
542 f5bf14bf Gerd Hoffmann
        trace_usb_packet_state_change(-1, "", -1, p,
543 f5bf14bf Gerd Hoffmann
                                      usb_packet_state_name(p->state),
544 f5bf14bf Gerd Hoffmann
                                      usb_packet_state_name(state));
545 f5bf14bf Gerd Hoffmann
    }
546 db4be873 Gerd Hoffmann
    p->state = state;
547 db4be873 Gerd Hoffmann
}
548 db4be873 Gerd Hoffmann
549 8550a02d Gerd Hoffmann
void usb_packet_setup(USBPacket *p, int pid,
550 8550a02d Gerd Hoffmann
                      USBEndpoint *ep, unsigned int stream,
551 8550a02d Gerd Hoffmann
                      uint64_t id, bool short_not_ok, bool int_req)
552 4f4321c1 Gerd Hoffmann
{
553 f53c398a Gerd Hoffmann
    assert(!usb_packet_is_inflight(p));
554 0cc6a0f1 Gerd Hoffmann
    assert(p->iov.iov != NULL);
555 e983395d Gerd Hoffmann
    p->id = id;
556 4f4321c1 Gerd Hoffmann
    p->pid = pid;
557 079d0b7f Gerd Hoffmann
    p->ep = ep;
558 8550a02d Gerd Hoffmann
    p->stream = stream;
559 9a77a0f5 Hans de Goede
    p->status = USB_RET_SUCCESS;
560 9a77a0f5 Hans de Goede
    p->actual_length = 0;
561 1b4b29a1 Gerd Hoffmann
    p->parameter = 0;
562 6ba43f1f Hans de Goede
    p->short_not_ok = short_not_ok;
563 a6fb2ddb Hans de Goede
    p->int_req = int_req;
564 a552a966 Hans de Goede
    p->combined = NULL;
565 4f4321c1 Gerd Hoffmann
    qemu_iovec_reset(&p->iov);
566 db4be873 Gerd Hoffmann
    usb_packet_set_state(p, USB_PACKET_SETUP);
567 4f4321c1 Gerd Hoffmann
}
568 4f4321c1 Gerd Hoffmann
569 4f4321c1 Gerd Hoffmann
void usb_packet_addbuf(USBPacket *p, void *ptr, size_t len)
570 4f4321c1 Gerd Hoffmann
{
571 4f4321c1 Gerd Hoffmann
    qemu_iovec_add(&p->iov, ptr, len);
572 4f4321c1 Gerd Hoffmann
}
573 4f4321c1 Gerd Hoffmann
574 4f4321c1 Gerd Hoffmann
void usb_packet_copy(USBPacket *p, void *ptr, size_t bytes)
575 4f4321c1 Gerd Hoffmann
{
576 6a98d1c0 Gerd Hoffmann
    QEMUIOVector *iov = p->combined ? &p->combined->iov : &p->iov;
577 6a98d1c0 Gerd Hoffmann
578 9a77a0f5 Hans de Goede
    assert(p->actual_length >= 0);
579 6a98d1c0 Gerd Hoffmann
    assert(p->actual_length + bytes <= iov->size);
580 4f4321c1 Gerd Hoffmann
    switch (p->pid) {
581 4f4321c1 Gerd Hoffmann
    case USB_TOKEN_SETUP:
582 4f4321c1 Gerd Hoffmann
    case USB_TOKEN_OUT:
583 6a98d1c0 Gerd Hoffmann
        iov_to_buf(iov->iov, iov->niov, p->actual_length, ptr, bytes);
584 4f4321c1 Gerd Hoffmann
        break;
585 4f4321c1 Gerd Hoffmann
    case USB_TOKEN_IN:
586 6a98d1c0 Gerd Hoffmann
        iov_from_buf(iov->iov, iov->niov, p->actual_length, ptr, bytes);
587 4f4321c1 Gerd Hoffmann
        break;
588 4f4321c1 Gerd Hoffmann
    default:
589 4f4321c1 Gerd Hoffmann
        fprintf(stderr, "%s: invalid pid: %x\n", __func__, p->pid);
590 4f4321c1 Gerd Hoffmann
        abort();
591 4f4321c1 Gerd Hoffmann
    }
592 9a77a0f5 Hans de Goede
    p->actual_length += bytes;
593 4f4321c1 Gerd Hoffmann
}
594 4f4321c1 Gerd Hoffmann
595 4f4321c1 Gerd Hoffmann
void usb_packet_skip(USBPacket *p, size_t bytes)
596 4f4321c1 Gerd Hoffmann
{
597 6a98d1c0 Gerd Hoffmann
    QEMUIOVector *iov = p->combined ? &p->combined->iov : &p->iov;
598 6a98d1c0 Gerd Hoffmann
599 9a77a0f5 Hans de Goede
    assert(p->actual_length >= 0);
600 6a98d1c0 Gerd Hoffmann
    assert(p->actual_length + bytes <= iov->size);
601 4f4321c1 Gerd Hoffmann
    if (p->pid == USB_TOKEN_IN) {
602 6a98d1c0 Gerd Hoffmann
        iov_memset(iov->iov, iov->niov, p->actual_length, 0, bytes);
603 4f4321c1 Gerd Hoffmann
    }
604 9a77a0f5 Hans de Goede
    p->actual_length += bytes;
605 4f4321c1 Gerd Hoffmann
}
606 4f4321c1 Gerd Hoffmann
607 6a98d1c0 Gerd Hoffmann
size_t usb_packet_size(USBPacket *p)
608 6a98d1c0 Gerd Hoffmann
{
609 6a98d1c0 Gerd Hoffmann
    return p->combined ? p->combined->iov.size : p->iov.size;
610 6a98d1c0 Gerd Hoffmann
}
611 6a98d1c0 Gerd Hoffmann
612 4f4321c1 Gerd Hoffmann
void usb_packet_cleanup(USBPacket *p)
613 4f4321c1 Gerd Hoffmann
{
614 f53c398a Gerd Hoffmann
    assert(!usb_packet_is_inflight(p));
615 4f4321c1 Gerd Hoffmann
    qemu_iovec_destroy(&p->iov);
616 4f4321c1 Gerd Hoffmann
}
617 d8e17efd Gerd Hoffmann
618 19deaa08 Gerd Hoffmann
void usb_ep_reset(USBDevice *dev)
619 d8e17efd Gerd Hoffmann
{
620 d8e17efd Gerd Hoffmann
    int ep;
621 d8e17efd Gerd Hoffmann
622 63095ab5 Gerd Hoffmann
    dev->ep_ctl.nr = 0;
623 25d5de7d Gerd Hoffmann
    dev->ep_ctl.type = USB_ENDPOINT_XFER_CONTROL;
624 25d5de7d Gerd Hoffmann
    dev->ep_ctl.ifnum = 0;
625 9adbaad3 Hans de Goede
    dev->ep_ctl.max_packet_size = 64;
626 04b300f8 Hans de Goede
    dev->ep_ctl.max_streams = 0;
627 25d5de7d Gerd Hoffmann
    dev->ep_ctl.dev = dev;
628 7936e0f0 Gerd Hoffmann
    dev->ep_ctl.pipeline = false;
629 d8e17efd Gerd Hoffmann
    for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
630 63095ab5 Gerd Hoffmann
        dev->ep_in[ep].nr = ep + 1;
631 63095ab5 Gerd Hoffmann
        dev->ep_out[ep].nr = ep + 1;
632 63095ab5 Gerd Hoffmann
        dev->ep_in[ep].pid = USB_TOKEN_IN;
633 63095ab5 Gerd Hoffmann
        dev->ep_out[ep].pid = USB_TOKEN_OUT;
634 d8e17efd Gerd Hoffmann
        dev->ep_in[ep].type = USB_ENDPOINT_XFER_INVALID;
635 d8e17efd Gerd Hoffmann
        dev->ep_out[ep].type = USB_ENDPOINT_XFER_INVALID;
636 7c37e6a4 Gerd Hoffmann
        dev->ep_in[ep].ifnum = USB_INTERFACE_INVALID;
637 7c37e6a4 Gerd Hoffmann
        dev->ep_out[ep].ifnum = USB_INTERFACE_INVALID;
638 9adbaad3 Hans de Goede
        dev->ep_in[ep].max_packet_size = 0;
639 9adbaad3 Hans de Goede
        dev->ep_out[ep].max_packet_size = 0;
640 04b300f8 Hans de Goede
        dev->ep_in[ep].max_streams = 0;
641 04b300f8 Hans de Goede
        dev->ep_out[ep].max_streams = 0;
642 25d5de7d Gerd Hoffmann
        dev->ep_in[ep].dev = dev;
643 25d5de7d Gerd Hoffmann
        dev->ep_out[ep].dev = dev;
644 7936e0f0 Gerd Hoffmann
        dev->ep_in[ep].pipeline = false;
645 7936e0f0 Gerd Hoffmann
        dev->ep_out[ep].pipeline = false;
646 19deaa08 Gerd Hoffmann
    }
647 19deaa08 Gerd Hoffmann
}
648 19deaa08 Gerd Hoffmann
649 19deaa08 Gerd Hoffmann
void usb_ep_init(USBDevice *dev)
650 19deaa08 Gerd Hoffmann
{
651 19deaa08 Gerd Hoffmann
    int ep;
652 19deaa08 Gerd Hoffmann
653 19deaa08 Gerd Hoffmann
    usb_ep_reset(dev);
654 19deaa08 Gerd Hoffmann
    QTAILQ_INIT(&dev->ep_ctl.queue);
655 19deaa08 Gerd Hoffmann
    for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
656 db4be873 Gerd Hoffmann
        QTAILQ_INIT(&dev->ep_in[ep].queue);
657 db4be873 Gerd Hoffmann
        QTAILQ_INIT(&dev->ep_out[ep].queue);
658 d8e17efd Gerd Hoffmann
    }
659 d8e17efd Gerd Hoffmann
}
660 d8e17efd Gerd Hoffmann
661 5b6780d0 Gerd Hoffmann
void usb_ep_dump(USBDevice *dev)
662 5b6780d0 Gerd Hoffmann
{
663 5b6780d0 Gerd Hoffmann
    static const char *tname[] = {
664 5b6780d0 Gerd Hoffmann
        [USB_ENDPOINT_XFER_CONTROL] = "control",
665 5b6780d0 Gerd Hoffmann
        [USB_ENDPOINT_XFER_ISOC]    = "isoc",
666 5b6780d0 Gerd Hoffmann
        [USB_ENDPOINT_XFER_BULK]    = "bulk",
667 5b6780d0 Gerd Hoffmann
        [USB_ENDPOINT_XFER_INT]     = "int",
668 5b6780d0 Gerd Hoffmann
    };
669 5b6780d0 Gerd Hoffmann
    int ifnum, ep, first;
670 5b6780d0 Gerd Hoffmann
671 5b6780d0 Gerd Hoffmann
    fprintf(stderr, "Device \"%s\", config %d\n",
672 5b6780d0 Gerd Hoffmann
            dev->product_desc, dev->configuration);
673 5b6780d0 Gerd Hoffmann
    for (ifnum = 0; ifnum < 16; ifnum++) {
674 5b6780d0 Gerd Hoffmann
        first = 1;
675 5b6780d0 Gerd Hoffmann
        for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
676 5b6780d0 Gerd Hoffmann
            if (dev->ep_in[ep].type != USB_ENDPOINT_XFER_INVALID &&
677 5b6780d0 Gerd Hoffmann
                dev->ep_in[ep].ifnum == ifnum) {
678 5b6780d0 Gerd Hoffmann
                if (first) {
679 5b6780d0 Gerd Hoffmann
                    first = 0;
680 5b6780d0 Gerd Hoffmann
                    fprintf(stderr, "  Interface %d, alternative %d\n",
681 5b6780d0 Gerd Hoffmann
                            ifnum, dev->altsetting[ifnum]);
682 5b6780d0 Gerd Hoffmann
                }
683 f003397c Gerd Hoffmann
                fprintf(stderr, "    Endpoint %d, IN, %s, %d max\n", ep,
684 f003397c Gerd Hoffmann
                        tname[dev->ep_in[ep].type],
685 f003397c Gerd Hoffmann
                        dev->ep_in[ep].max_packet_size);
686 5b6780d0 Gerd Hoffmann
            }
687 5b6780d0 Gerd Hoffmann
            if (dev->ep_out[ep].type != USB_ENDPOINT_XFER_INVALID &&
688 5b6780d0 Gerd Hoffmann
                dev->ep_out[ep].ifnum == ifnum) {
689 5b6780d0 Gerd Hoffmann
                if (first) {
690 5b6780d0 Gerd Hoffmann
                    first = 0;
691 5b6780d0 Gerd Hoffmann
                    fprintf(stderr, "  Interface %d, alternative %d\n",
692 5b6780d0 Gerd Hoffmann
                            ifnum, dev->altsetting[ifnum]);
693 5b6780d0 Gerd Hoffmann
                }
694 f003397c Gerd Hoffmann
                fprintf(stderr, "    Endpoint %d, OUT, %s, %d max\n", ep,
695 f003397c Gerd Hoffmann
                        tname[dev->ep_out[ep].type],
696 f003397c Gerd Hoffmann
                        dev->ep_out[ep].max_packet_size);
697 5b6780d0 Gerd Hoffmann
            }
698 5b6780d0 Gerd Hoffmann
        }
699 5b6780d0 Gerd Hoffmann
    }
700 5b6780d0 Gerd Hoffmann
    fprintf(stderr, "--\n");
701 5b6780d0 Gerd Hoffmann
}
702 5b6780d0 Gerd Hoffmann
703 d8e17efd Gerd Hoffmann
struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep)
704 d8e17efd Gerd Hoffmann
{
705 079d0b7f Gerd Hoffmann
    struct USBEndpoint *eps;
706 079d0b7f Gerd Hoffmann
707 079d0b7f Gerd Hoffmann
    if (dev == NULL) {
708 079d0b7f Gerd Hoffmann
        return NULL;
709 079d0b7f Gerd Hoffmann
    }
710 079d0b7f Gerd Hoffmann
    eps = (pid == USB_TOKEN_IN) ? dev->ep_in : dev->ep_out;
711 25d5de7d Gerd Hoffmann
    if (ep == 0) {
712 25d5de7d Gerd Hoffmann
        return &dev->ep_ctl;
713 25d5de7d Gerd Hoffmann
    }
714 d8e17efd Gerd Hoffmann
    assert(pid == USB_TOKEN_IN || pid == USB_TOKEN_OUT);
715 d8e17efd Gerd Hoffmann
    assert(ep > 0 && ep <= USB_MAX_ENDPOINTS);
716 d8e17efd Gerd Hoffmann
    return eps + ep - 1;
717 d8e17efd Gerd Hoffmann
}
718 d8e17efd Gerd Hoffmann
719 d8e17efd Gerd Hoffmann
uint8_t usb_ep_get_type(USBDevice *dev, int pid, int ep)
720 d8e17efd Gerd Hoffmann
{
721 d8e17efd Gerd Hoffmann
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
722 d8e17efd Gerd Hoffmann
    return uep->type;
723 d8e17efd Gerd Hoffmann
}
724 d8e17efd Gerd Hoffmann
725 d8e17efd Gerd Hoffmann
void usb_ep_set_type(USBDevice *dev, int pid, int ep, uint8_t type)
726 d8e17efd Gerd Hoffmann
{
727 d8e17efd Gerd Hoffmann
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
728 d8e17efd Gerd Hoffmann
    uep->type = type;
729 d8e17efd Gerd Hoffmann
}
730 82f02fe9 Gerd Hoffmann
731 82f02fe9 Gerd Hoffmann
uint8_t usb_ep_get_ifnum(USBDevice *dev, int pid, int ep)
732 82f02fe9 Gerd Hoffmann
{
733 82f02fe9 Gerd Hoffmann
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
734 82f02fe9 Gerd Hoffmann
    return uep->ifnum;
735 82f02fe9 Gerd Hoffmann
}
736 82f02fe9 Gerd Hoffmann
737 82f02fe9 Gerd Hoffmann
void usb_ep_set_ifnum(USBDevice *dev, int pid, int ep, uint8_t ifnum)
738 82f02fe9 Gerd Hoffmann
{
739 82f02fe9 Gerd Hoffmann
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
740 82f02fe9 Gerd Hoffmann
    uep->ifnum = ifnum;
741 82f02fe9 Gerd Hoffmann
}
742 f003397c Gerd Hoffmann
743 f003397c Gerd Hoffmann
void usb_ep_set_max_packet_size(USBDevice *dev, int pid, int ep,
744 f003397c Gerd Hoffmann
                                uint16_t raw)
745 f003397c Gerd Hoffmann
{
746 f003397c Gerd Hoffmann
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
747 f003397c Gerd Hoffmann
    int size, microframes;
748 f003397c Gerd Hoffmann
749 f003397c Gerd Hoffmann
    size = raw & 0x7ff;
750 f003397c Gerd Hoffmann
    switch ((raw >> 11) & 3) {
751 f003397c Gerd Hoffmann
    case 1:
752 f003397c Gerd Hoffmann
        microframes = 2;
753 f003397c Gerd Hoffmann
        break;
754 f003397c Gerd Hoffmann
    case 2:
755 f003397c Gerd Hoffmann
        microframes = 3;
756 f003397c Gerd Hoffmann
        break;
757 f003397c Gerd Hoffmann
    default:
758 f003397c Gerd Hoffmann
        microframes = 1;
759 f003397c Gerd Hoffmann
        break;
760 f003397c Gerd Hoffmann
    }
761 f003397c Gerd Hoffmann
    uep->max_packet_size = size * microframes;
762 f003397c Gerd Hoffmann
}
763 f003397c Gerd Hoffmann
764 f003397c Gerd Hoffmann
int usb_ep_get_max_packet_size(USBDevice *dev, int pid, int ep)
765 f003397c Gerd Hoffmann
{
766 f003397c Gerd Hoffmann
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
767 f003397c Gerd Hoffmann
    return uep->max_packet_size;
768 f003397c Gerd Hoffmann
}
769 7936e0f0 Gerd Hoffmann
770 04b300f8 Hans de Goede
void usb_ep_set_max_streams(USBDevice *dev, int pid, int ep, uint8_t raw)
771 04b300f8 Hans de Goede
{
772 04b300f8 Hans de Goede
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
773 04b300f8 Hans de Goede
    int MaxStreams;
774 04b300f8 Hans de Goede
775 04b300f8 Hans de Goede
    MaxStreams = raw & 0x1f;
776 04b300f8 Hans de Goede
    if (MaxStreams) {
777 04b300f8 Hans de Goede
        uep->max_streams = 1 << MaxStreams;
778 04b300f8 Hans de Goede
    } else {
779 04b300f8 Hans de Goede
        uep->max_streams = 0;
780 04b300f8 Hans de Goede
    }
781 04b300f8 Hans de Goede
}
782 04b300f8 Hans de Goede
783 04b300f8 Hans de Goede
int usb_ep_get_max_streams(USBDevice *dev, int pid, int ep)
784 04b300f8 Hans de Goede
{
785 04b300f8 Hans de Goede
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
786 04b300f8 Hans de Goede
    return uep->max_streams;
787 04b300f8 Hans de Goede
}
788 04b300f8 Hans de Goede
789 7936e0f0 Gerd Hoffmann
void usb_ep_set_pipeline(USBDevice *dev, int pid, int ep, bool enabled)
790 7936e0f0 Gerd Hoffmann
{
791 7936e0f0 Gerd Hoffmann
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
792 7936e0f0 Gerd Hoffmann
    uep->pipeline = enabled;
793 7936e0f0 Gerd Hoffmann
}
794 c13a9e61 Hans de Goede
795 e382d966 Gerd Hoffmann
void usb_ep_set_halted(USBDevice *dev, int pid, int ep, bool halted)
796 e382d966 Gerd Hoffmann
{
797 e382d966 Gerd Hoffmann
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
798 e382d966 Gerd Hoffmann
    uep->halted = halted;
799 e382d966 Gerd Hoffmann
}
800 e382d966 Gerd Hoffmann
801 c13a9e61 Hans de Goede
USBPacket *usb_ep_find_packet_by_id(USBDevice *dev, int pid, int ep,
802 c13a9e61 Hans de Goede
                                    uint64_t id)
803 c13a9e61 Hans de Goede
{
804 c13a9e61 Hans de Goede
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
805 c13a9e61 Hans de Goede
    USBPacket *p;
806 c13a9e61 Hans de Goede
807 6735d433 Hans de Goede
    QTAILQ_FOREACH(p, &uep->queue, queue) {
808 c13a9e61 Hans de Goede
        if (p->id == id) {
809 c13a9e61 Hans de Goede
            return p;
810 c13a9e61 Hans de Goede
        }
811 c13a9e61 Hans de Goede
    }
812 c13a9e61 Hans de Goede
813 c13a9e61 Hans de Goede
    return NULL;
814 c13a9e61 Hans de Goede
}