Statistics
| Branch: | Revision:

root / hw / usb.c @ 37f32f0f

History | View | Annotate | Download (16.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 87ecb68b pbrook
#include "usb.h"
28 4f4321c1 Gerd Hoffmann
#include "iov.h"
29 bb36d470 bellard
30 891fb2cd Gerd Hoffmann
void usb_attach(USBPort *port)
31 bb36d470 bellard
{
32 891fb2cd Gerd Hoffmann
    USBDevice *dev = port->dev;
33 891fb2cd Gerd Hoffmann
34 891fb2cd Gerd Hoffmann
    assert(dev != NULL);
35 891fb2cd Gerd Hoffmann
    assert(dev->attached);
36 e0b8e72d Gerd Hoffmann
    assert(dev->state == USB_STATE_NOTATTACHED);
37 891fb2cd Gerd Hoffmann
    port->ops->attach(port);
38 d1f8b536 Gerd Hoffmann
    dev->state = USB_STATE_ATTACHED;
39 d1f8b536 Gerd Hoffmann
    usb_device_handle_attach(dev);
40 891fb2cd Gerd Hoffmann
}
41 891fb2cd Gerd Hoffmann
42 891fb2cd Gerd Hoffmann
void usb_detach(USBPort *port)
43 891fb2cd Gerd Hoffmann
{
44 891fb2cd Gerd Hoffmann
    USBDevice *dev = port->dev;
45 891fb2cd Gerd Hoffmann
46 891fb2cd Gerd Hoffmann
    assert(dev != NULL);
47 e0b8e72d Gerd Hoffmann
    assert(dev->state != USB_STATE_NOTATTACHED);
48 891fb2cd Gerd Hoffmann
    port->ops->detach(port);
49 d1f8b536 Gerd Hoffmann
    dev->state = USB_STATE_NOTATTACHED;
50 bb36d470 bellard
}
51 bb36d470 bellard
52 d28f4e2d Gerd Hoffmann
void usb_port_reset(USBPort *port)
53 e0b8e72d Gerd Hoffmann
{
54 e0b8e72d Gerd Hoffmann
    USBDevice *dev = port->dev;
55 e0b8e72d Gerd Hoffmann
56 e0b8e72d Gerd Hoffmann
    assert(dev != NULL);
57 e0b8e72d Gerd Hoffmann
    usb_detach(port);
58 e0b8e72d Gerd Hoffmann
    usb_attach(port);
59 d28f4e2d Gerd Hoffmann
    usb_device_reset(dev);
60 d28f4e2d Gerd Hoffmann
}
61 d28f4e2d Gerd Hoffmann
62 d28f4e2d Gerd Hoffmann
void usb_device_reset(USBDevice *dev)
63 d28f4e2d Gerd Hoffmann
{
64 d28f4e2d Gerd Hoffmann
    if (dev == NULL || !dev->attached) {
65 d28f4e2d Gerd Hoffmann
        return;
66 d28f4e2d Gerd Hoffmann
    }
67 d28f4e2d Gerd Hoffmann
    dev->remote_wakeup = 0;
68 d28f4e2d Gerd Hoffmann
    dev->addr = 0;
69 d28f4e2d Gerd Hoffmann
    dev->state = USB_STATE_DEFAULT;
70 d28f4e2d Gerd Hoffmann
    usb_device_handle_reset(dev);
71 e0b8e72d Gerd Hoffmann
}
72 e0b8e72d Gerd Hoffmann
73 7567b51f Gerd Hoffmann
void usb_wakeup(USBEndpoint *ep)
74 01eacab6 Gerd Hoffmann
{
75 7567b51f Gerd Hoffmann
    USBDevice *dev = ep->dev;
76 37f32f0f Gerd Hoffmann
    USBBus *bus = usb_bus_from_device(dev);
77 7567b51f Gerd Hoffmann
78 01eacab6 Gerd Hoffmann
    if (dev->remote_wakeup && dev->port && dev->port->ops->wakeup) {
79 d47e59b8 Hans de Goede
        dev->port->ops->wakeup(dev->port);
80 01eacab6 Gerd Hoffmann
    }
81 37f32f0f Gerd Hoffmann
    if (bus->ops->wakeup_endpoint) {
82 37f32f0f Gerd Hoffmann
        bus->ops->wakeup_endpoint(bus, ep);
83 37f32f0f Gerd Hoffmann
    }
84 01eacab6 Gerd Hoffmann
}
85 01eacab6 Gerd Hoffmann
86 bb36d470 bellard
/**********************/
87 89b9b79f aliguori
88 bb36d470 bellard
/* generic USB device helpers (you are not forced to use them when
89 bb36d470 bellard
   writing your USB device driver, but they help handling the
90 5fafdf24 ths
   protocol)
91 bb36d470 bellard
*/
92 bb36d470 bellard
93 50b7963e Hans de Goede
#define SETUP_STATE_IDLE  0
94 50b7963e Hans de Goede
#define SETUP_STATE_SETUP 1
95 50b7963e Hans de Goede
#define SETUP_STATE_DATA  2
96 50b7963e Hans de Goede
#define SETUP_STATE_ACK   3
97 bb36d470 bellard
98 89b9b79f aliguori
static int do_token_setup(USBDevice *s, USBPacket *p)
99 89b9b79f aliguori
{
100 89b9b79f aliguori
    int request, value, index;
101 89b9b79f aliguori
    int ret = 0;
102 89b9b79f aliguori
103 4f4321c1 Gerd Hoffmann
    if (p->iov.size != 8) {
104 89b9b79f aliguori
        return USB_RET_STALL;
105 4f4321c1 Gerd Hoffmann
    }
106 4f4321c1 Gerd Hoffmann
107 4f4321c1 Gerd Hoffmann
    usb_packet_copy(p, s->setup_buf, p->iov.size);
108 89b9b79f aliguori
    s->setup_len   = (s->setup_buf[7] << 8) | s->setup_buf[6];
109 89b9b79f aliguori
    s->setup_index = 0;
110 89b9b79f aliguori
111 89b9b79f aliguori
    request = (s->setup_buf[0] << 8) | s->setup_buf[1];
112 89b9b79f aliguori
    value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
113 89b9b79f aliguori
    index   = (s->setup_buf[5] << 8) | s->setup_buf[4];
114 007fd62f Hans de Goede
115 89b9b79f aliguori
    if (s->setup_buf[0] & USB_DIR_IN) {
116 62aed765 Anthony Liguori
        ret = usb_device_handle_control(s, p, request, value, index,
117 62aed765 Anthony Liguori
                                        s->setup_len, s->data_buf);
118 50b7963e Hans de Goede
        if (ret == USB_RET_ASYNC) {
119 50b7963e Hans de Goede
             s->setup_state = SETUP_STATE_SETUP;
120 50b7963e Hans de Goede
             return USB_RET_ASYNC;
121 50b7963e Hans de Goede
        }
122 89b9b79f aliguori
        if (ret < 0)
123 89b9b79f aliguori
            return ret;
124 89b9b79f aliguori
125 89b9b79f aliguori
        if (ret < s->setup_len)
126 89b9b79f aliguori
            s->setup_len = ret;
127 89b9b79f aliguori
        s->setup_state = SETUP_STATE_DATA;
128 89b9b79f aliguori
    } else {
129 19f33223 Hans de Goede
        if (s->setup_len > sizeof(s->data_buf)) {
130 19f33223 Hans de Goede
            fprintf(stderr,
131 19f33223 Hans de Goede
                "usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n",
132 19f33223 Hans de Goede
                s->setup_len, sizeof(s->data_buf));
133 19f33223 Hans de Goede
            return USB_RET_STALL;
134 19f33223 Hans de Goede
        }
135 89b9b79f aliguori
        if (s->setup_len == 0)
136 89b9b79f aliguori
            s->setup_state = SETUP_STATE_ACK;
137 89b9b79f aliguori
        else
138 89b9b79f aliguori
            s->setup_state = SETUP_STATE_DATA;
139 89b9b79f aliguori
    }
140 89b9b79f aliguori
141 89b9b79f aliguori
    return ret;
142 89b9b79f aliguori
}
143 89b9b79f aliguori
144 89b9b79f aliguori
static int do_token_in(USBDevice *s, USBPacket *p)
145 bb36d470 bellard
{
146 89b9b79f aliguori
    int request, value, index;
147 89b9b79f aliguori
    int ret = 0;
148 89b9b79f aliguori
149 079d0b7f Gerd Hoffmann
    assert(p->ep->nr == 0);
150 89b9b79f aliguori
151 89b9b79f aliguori
    request = (s->setup_buf[0] << 8) | s->setup_buf[1];
152 89b9b79f aliguori
    value   = (s->setup_buf[3] << 8) | s->setup_buf[2];
153 89b9b79f aliguori
    index   = (s->setup_buf[5] << 8) | s->setup_buf[4];
154 89b9b79f aliguori
 
155 89b9b79f aliguori
    switch(s->setup_state) {
156 89b9b79f aliguori
    case SETUP_STATE_ACK:
157 89b9b79f aliguori
        if (!(s->setup_buf[0] & USB_DIR_IN)) {
158 62aed765 Anthony Liguori
            ret = usb_device_handle_control(s, p, request, value, index,
159 62aed765 Anthony Liguori
                                            s->setup_len, s->data_buf);
160 007fd62f Hans de Goede
            if (ret == USB_RET_ASYNC) {
161 007fd62f Hans de Goede
                return USB_RET_ASYNC;
162 007fd62f Hans de Goede
            }
163 007fd62f Hans de Goede
            s->setup_state = SETUP_STATE_IDLE;
164 89b9b79f aliguori
            if (ret > 0)
165 89b9b79f aliguori
                return 0;
166 89b9b79f aliguori
            return ret;
167 89b9b79f aliguori
        }
168 89b9b79f aliguori
169 89b9b79f aliguori
        /* return 0 byte */
170 89b9b79f aliguori
        return 0;
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 89b9b79f aliguori
            if (s->setup_index >= s->setup_len)
181 89b9b79f aliguori
                s->setup_state = SETUP_STATE_ACK;
182 89b9b79f aliguori
            return len;
183 89b9b79f aliguori
        }
184 89b9b79f aliguori
185 89b9b79f aliguori
        s->setup_state = SETUP_STATE_IDLE;
186 89b9b79f aliguori
        return USB_RET_STALL;
187 89b9b79f aliguori
188 89b9b79f aliguori
    default:
189 89b9b79f aliguori
        return USB_RET_STALL;
190 89b9b79f aliguori
    }
191 89b9b79f aliguori
}
192 89b9b79f aliguori
193 89b9b79f aliguori
static int do_token_out(USBDevice *s, USBPacket *p)
194 89b9b79f aliguori
{
195 079d0b7f Gerd Hoffmann
    assert(p->ep->nr == 0);
196 89b9b79f aliguori
197 89b9b79f aliguori
    switch(s->setup_state) {
198 89b9b79f aliguori
    case SETUP_STATE_ACK:
199 89b9b79f aliguori
        if (s->setup_buf[0] & USB_DIR_IN) {
200 89b9b79f aliguori
            s->setup_state = SETUP_STATE_IDLE;
201 89b9b79f aliguori
            /* transfer OK */
202 89b9b79f aliguori
        } else {
203 89b9b79f aliguori
            /* ignore additional output */
204 89b9b79f aliguori
        }
205 89b9b79f aliguori
        return 0;
206 89b9b79f aliguori
207 89b9b79f aliguori
    case SETUP_STATE_DATA:
208 89b9b79f aliguori
        if (!(s->setup_buf[0] & USB_DIR_IN)) {
209 89b9b79f aliguori
            int len = s->setup_len - s->setup_index;
210 4f4321c1 Gerd Hoffmann
            if (len > p->iov.size) {
211 4f4321c1 Gerd Hoffmann
                len = p->iov.size;
212 4f4321c1 Gerd Hoffmann
            }
213 4f4321c1 Gerd Hoffmann
            usb_packet_copy(p, s->data_buf + s->setup_index, len);
214 89b9b79f aliguori
            s->setup_index += len;
215 89b9b79f aliguori
            if (s->setup_index >= s->setup_len)
216 89b9b79f aliguori
                s->setup_state = SETUP_STATE_ACK;
217 89b9b79f aliguori
            return len;
218 89b9b79f aliguori
        }
219 89b9b79f aliguori
220 89b9b79f aliguori
        s->setup_state = SETUP_STATE_IDLE;
221 89b9b79f aliguori
        return USB_RET_STALL;
222 89b9b79f aliguori
223 89b9b79f aliguori
    default:
224 89b9b79f aliguori
        return USB_RET_STALL;
225 89b9b79f aliguori
    }
226 89b9b79f aliguori
}
227 bb36d470 bellard
228 50b7963e Hans de Goede
/* ctrl complete function for devices which use usb_generic_handle_packet and
229 50b7963e Hans de Goede
   may return USB_RET_ASYNC from their handle_control callback. Device code
230 50b7963e Hans de Goede
   which does this *must* call this function instead of the normal
231 50b7963e Hans de Goede
   usb_packet_complete to complete their async control packets. */
232 50b7963e Hans de Goede
void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p)
233 50b7963e Hans de Goede
{
234 4f4321c1 Gerd Hoffmann
    if (p->result < 0) {
235 50b7963e Hans de Goede
        s->setup_state = SETUP_STATE_IDLE;
236 50b7963e Hans de Goede
    }
237 50b7963e Hans de Goede
238 50b7963e Hans de Goede
    switch (s->setup_state) {
239 50b7963e Hans de Goede
    case SETUP_STATE_SETUP:
240 4f4321c1 Gerd Hoffmann
        if (p->result < s->setup_len) {
241 4f4321c1 Gerd Hoffmann
            s->setup_len = p->result;
242 50b7963e Hans de Goede
        }
243 50b7963e Hans de Goede
        s->setup_state = SETUP_STATE_DATA;
244 4f4321c1 Gerd Hoffmann
        p->result = 8;
245 50b7963e Hans de Goede
        break;
246 50b7963e Hans de Goede
247 50b7963e Hans de Goede
    case SETUP_STATE_ACK:
248 50b7963e Hans de Goede
        s->setup_state = SETUP_STATE_IDLE;
249 4f4321c1 Gerd Hoffmann
        p->result = 0;
250 50b7963e Hans de Goede
        break;
251 50b7963e Hans de Goede
252 50b7963e Hans de Goede
    default:
253 50b7963e Hans de Goede
        break;
254 50b7963e Hans de Goede
    }
255 50b7963e Hans de Goede
    usb_packet_complete(s, p);
256 50b7963e Hans de Goede
}
257 50b7963e Hans de Goede
258 bb36d470 bellard
/* XXX: fix overflow */
259 bb36d470 bellard
int set_usb_string(uint8_t *buf, const char *str)
260 bb36d470 bellard
{
261 bb36d470 bellard
    int len, i;
262 bb36d470 bellard
    uint8_t *q;
263 bb36d470 bellard
264 bb36d470 bellard
    q = buf;
265 bb36d470 bellard
    len = strlen(str);
266 ce5c37c2 pbrook
    *q++ = 2 * len + 2;
267 bb36d470 bellard
    *q++ = 3;
268 bb36d470 bellard
    for(i = 0; i < len; i++) {
269 bb36d470 bellard
        *q++ = str[i];
270 bb36d470 bellard
        *q++ = 0;
271 bb36d470 bellard
    }
272 bb36d470 bellard
    return q - buf;
273 bb36d470 bellard
}
274 4d611c9a pbrook
275 73796fe6 Gerd Hoffmann
USBDevice *usb_find_device(USBPort *port, uint8_t addr)
276 73796fe6 Gerd Hoffmann
{
277 73796fe6 Gerd Hoffmann
    USBDevice *dev = port->dev;
278 73796fe6 Gerd Hoffmann
279 73796fe6 Gerd Hoffmann
    if (dev == NULL || !dev->attached || dev->state != USB_STATE_DEFAULT) {
280 73796fe6 Gerd Hoffmann
        return NULL;
281 73796fe6 Gerd Hoffmann
    }
282 73796fe6 Gerd Hoffmann
    if (dev->addr == addr) {
283 73796fe6 Gerd Hoffmann
        return dev;
284 73796fe6 Gerd Hoffmann
    }
285 73796fe6 Gerd Hoffmann
    return usb_device_find_device(dev, addr);
286 73796fe6 Gerd Hoffmann
}
287 73796fe6 Gerd Hoffmann
288 db4be873 Gerd Hoffmann
static int usb_process_one(USBPacket *p)
289 db4be873 Gerd Hoffmann
{
290 db4be873 Gerd Hoffmann
    USBDevice *dev = p->ep->dev;
291 db4be873 Gerd Hoffmann
292 db4be873 Gerd Hoffmann
    if (p->ep->nr == 0) {
293 db4be873 Gerd Hoffmann
        /* control pipe */
294 db4be873 Gerd Hoffmann
        switch (p->pid) {
295 db4be873 Gerd Hoffmann
        case USB_TOKEN_SETUP:
296 db4be873 Gerd Hoffmann
            return do_token_setup(dev, p);
297 db4be873 Gerd Hoffmann
        case USB_TOKEN_IN:
298 db4be873 Gerd Hoffmann
            return do_token_in(dev, p);
299 db4be873 Gerd Hoffmann
        case USB_TOKEN_OUT:
300 db4be873 Gerd Hoffmann
            return do_token_out(dev, p);
301 db4be873 Gerd Hoffmann
        default:
302 db4be873 Gerd Hoffmann
            return USB_RET_STALL;
303 db4be873 Gerd Hoffmann
        }
304 db4be873 Gerd Hoffmann
    } else {
305 db4be873 Gerd Hoffmann
        /* data pipe */
306 db4be873 Gerd Hoffmann
        return usb_device_handle_data(dev, p);
307 db4be873 Gerd Hoffmann
    }
308 db4be873 Gerd Hoffmann
}
309 db4be873 Gerd Hoffmann
310 53aa8c0e Gerd Hoffmann
/* Hand over a packet to a device for processing.  Return value
311 53aa8c0e Gerd Hoffmann
   USB_RET_ASYNC indicates the processing isn't finished yet, the
312 53aa8c0e Gerd Hoffmann
   driver will call usb_packet_complete() when done processing it. */
313 53aa8c0e Gerd Hoffmann
int usb_handle_packet(USBDevice *dev, USBPacket *p)
314 53aa8c0e Gerd Hoffmann
{
315 53aa8c0e Gerd Hoffmann
    int ret;
316 53aa8c0e Gerd Hoffmann
317 98861f51 Gerd Hoffmann
    if (dev == NULL) {
318 98861f51 Gerd Hoffmann
        return USB_RET_NODEV;
319 98861f51 Gerd Hoffmann
    }
320 079d0b7f Gerd Hoffmann
    assert(dev == p->ep->dev);
321 1977f93d Gerd Hoffmann
    assert(dev->state == USB_STATE_DEFAULT);
322 f53c398a Gerd Hoffmann
    assert(p->state == USB_PACKET_SETUP);
323 db4be873 Gerd Hoffmann
    assert(p->ep != NULL);
324 1977f93d Gerd Hoffmann
325 db4be873 Gerd Hoffmann
    if (QTAILQ_EMPTY(&p->ep->queue)) {
326 db4be873 Gerd Hoffmann
        ret = usb_process_one(p);
327 db4be873 Gerd Hoffmann
        if (ret == USB_RET_ASYNC) {
328 db4be873 Gerd Hoffmann
            usb_packet_set_state(p, USB_PACKET_ASYNC);
329 db4be873 Gerd Hoffmann
            QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue);
330 db4be873 Gerd Hoffmann
        } else {
331 db4be873 Gerd Hoffmann
            p->result = ret;
332 db4be873 Gerd Hoffmann
            usb_packet_set_state(p, USB_PACKET_COMPLETE);
333 1977f93d Gerd Hoffmann
        }
334 1977f93d Gerd Hoffmann
    } else {
335 db4be873 Gerd Hoffmann
        ret = USB_RET_ASYNC;
336 db4be873 Gerd Hoffmann
        usb_packet_set_state(p, USB_PACKET_QUEUED);
337 db4be873 Gerd Hoffmann
        QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue);
338 4ff658fb Gerd Hoffmann
    }
339 53aa8c0e Gerd Hoffmann
    return ret;
340 89b9b79f aliguori
}
341 4ff658fb Gerd Hoffmann
342 4ff658fb Gerd Hoffmann
/* Notify the controller that an async packet is complete.  This should only
343 4ff658fb Gerd Hoffmann
   be called for packets previously deferred by returning USB_RET_ASYNC from
344 4ff658fb Gerd Hoffmann
   handle_packet. */
345 4ff658fb Gerd Hoffmann
void usb_packet_complete(USBDevice *dev, USBPacket *p)
346 4ff658fb Gerd Hoffmann
{
347 db4be873 Gerd Hoffmann
    USBEndpoint *ep = p->ep;
348 db4be873 Gerd Hoffmann
    int ret;
349 db4be873 Gerd Hoffmann
350 f53c398a Gerd Hoffmann
    assert(p->state == USB_PACKET_ASYNC);
351 db4be873 Gerd Hoffmann
    assert(QTAILQ_FIRST(&ep->queue) == p);
352 db4be873 Gerd Hoffmann
    usb_packet_set_state(p, USB_PACKET_COMPLETE);
353 db4be873 Gerd Hoffmann
    QTAILQ_REMOVE(&ep->queue, p, queue);
354 4d8debba Gerd Hoffmann
    dev->port->ops->complete(dev->port, p);
355 db4be873 Gerd Hoffmann
356 db4be873 Gerd Hoffmann
    while (!QTAILQ_EMPTY(&ep->queue)) {
357 db4be873 Gerd Hoffmann
        p = QTAILQ_FIRST(&ep->queue);
358 db4be873 Gerd Hoffmann
        assert(p->state == USB_PACKET_QUEUED);
359 db4be873 Gerd Hoffmann
        ret = usb_process_one(p);
360 db4be873 Gerd Hoffmann
        if (ret == USB_RET_ASYNC) {
361 db4be873 Gerd Hoffmann
            usb_packet_set_state(p, USB_PACKET_ASYNC);
362 db4be873 Gerd Hoffmann
            break;
363 db4be873 Gerd Hoffmann
        }
364 db4be873 Gerd Hoffmann
        p->result = ret;
365 db4be873 Gerd Hoffmann
        usb_packet_set_state(p, USB_PACKET_COMPLETE);
366 db4be873 Gerd Hoffmann
        QTAILQ_REMOVE(&ep->queue, p, queue);
367 db4be873 Gerd Hoffmann
        dev->port->ops->complete(dev->port, p);
368 db4be873 Gerd Hoffmann
    }
369 4ff658fb Gerd Hoffmann
}
370 4ff658fb Gerd Hoffmann
371 4ff658fb Gerd Hoffmann
/* Cancel an active packet.  The packed must have been deferred by
372 4ff658fb Gerd Hoffmann
   returning USB_RET_ASYNC from handle_packet, and not yet
373 4ff658fb Gerd Hoffmann
   completed.  */
374 4ff658fb Gerd Hoffmann
void usb_cancel_packet(USBPacket * p)
375 4ff658fb Gerd Hoffmann
{
376 db4be873 Gerd Hoffmann
    bool callback = (p->state == USB_PACKET_ASYNC);
377 db4be873 Gerd Hoffmann
    assert(usb_packet_is_inflight(p));
378 db4be873 Gerd Hoffmann
    usb_packet_set_state(p, USB_PACKET_CANCELED);
379 db4be873 Gerd Hoffmann
    QTAILQ_REMOVE(&p->ep->queue, p, queue);
380 db4be873 Gerd Hoffmann
    if (callback) {
381 db4be873 Gerd Hoffmann
        usb_device_cancel_packet(p->ep->dev, p);
382 db4be873 Gerd Hoffmann
    }
383 4ff658fb Gerd Hoffmann
}
384 4f4321c1 Gerd Hoffmann
385 4f4321c1 Gerd Hoffmann
386 4f4321c1 Gerd Hoffmann
void usb_packet_init(USBPacket *p)
387 4f4321c1 Gerd Hoffmann
{
388 4f4321c1 Gerd Hoffmann
    qemu_iovec_init(&p->iov, 1);
389 4f4321c1 Gerd Hoffmann
}
390 4f4321c1 Gerd Hoffmann
391 db4be873 Gerd Hoffmann
void usb_packet_set_state(USBPacket *p, USBPacketState state)
392 db4be873 Gerd Hoffmann
{
393 db4be873 Gerd Hoffmann
#ifdef DEBUG
394 db4be873 Gerd Hoffmann
    static const char *name[] = {
395 db4be873 Gerd Hoffmann
        [USB_PACKET_UNDEFINED] = "undef",
396 db4be873 Gerd Hoffmann
        [USB_PACKET_SETUP]     = "setup",
397 db4be873 Gerd Hoffmann
        [USB_PACKET_QUEUED]    = "queued",
398 db4be873 Gerd Hoffmann
        [USB_PACKET_ASYNC]     = "async",
399 db4be873 Gerd Hoffmann
        [USB_PACKET_COMPLETE]  = "complete",
400 db4be873 Gerd Hoffmann
        [USB_PACKET_CANCELED]  = "canceled",
401 db4be873 Gerd Hoffmann
    };
402 db4be873 Gerd Hoffmann
    static const char *rets[] = {
403 db4be873 Gerd Hoffmann
        [-USB_RET_NODEV]  = "NODEV",
404 db4be873 Gerd Hoffmann
        [-USB_RET_NAK]    = "NAK",
405 db4be873 Gerd Hoffmann
        [-USB_RET_STALL]  = "STALL",
406 db4be873 Gerd Hoffmann
        [-USB_RET_BABBLE] = "BABBLE",
407 db4be873 Gerd Hoffmann
        [-USB_RET_ASYNC]  = "ASYNC",
408 db4be873 Gerd Hoffmann
    };
409 db4be873 Gerd Hoffmann
    char add[16] = "";
410 db4be873 Gerd Hoffmann
411 db4be873 Gerd Hoffmann
    if (state == USB_PACKET_COMPLETE) {
412 db4be873 Gerd Hoffmann
        if (p->result < 0) {
413 db4be873 Gerd Hoffmann
            snprintf(add, sizeof(add), " - %s", rets[-p->result]);
414 db4be873 Gerd Hoffmann
        } else {
415 db4be873 Gerd Hoffmann
            snprintf(add, sizeof(add), " - %d", p->result);
416 db4be873 Gerd Hoffmann
        }
417 db4be873 Gerd Hoffmann
    }
418 db4be873 Gerd Hoffmann
    fprintf(stderr, "bus %s, port %s, dev %d, ep %d: packet %p: %s -> %s%s\n",
419 db4be873 Gerd Hoffmann
            p->ep->dev->qdev.parent_bus->name,
420 db4be873 Gerd Hoffmann
            p->ep->dev->port->path,
421 db4be873 Gerd Hoffmann
            p->ep->dev->addr, p->ep->nr,
422 db4be873 Gerd Hoffmann
            p, name[p->state], name[state], add);
423 db4be873 Gerd Hoffmann
#endif
424 db4be873 Gerd Hoffmann
    p->state = state;
425 db4be873 Gerd Hoffmann
}
426 db4be873 Gerd Hoffmann
427 079d0b7f Gerd Hoffmann
void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep)
428 4f4321c1 Gerd Hoffmann
{
429 f53c398a Gerd Hoffmann
    assert(!usb_packet_is_inflight(p));
430 4f4321c1 Gerd Hoffmann
    p->pid = pid;
431 079d0b7f Gerd Hoffmann
    p->ep = ep;
432 4f4321c1 Gerd Hoffmann
    p->result = 0;
433 4f4321c1 Gerd Hoffmann
    qemu_iovec_reset(&p->iov);
434 db4be873 Gerd Hoffmann
    usb_packet_set_state(p, USB_PACKET_SETUP);
435 4f4321c1 Gerd Hoffmann
}
436 4f4321c1 Gerd Hoffmann
437 4f4321c1 Gerd Hoffmann
void usb_packet_addbuf(USBPacket *p, void *ptr, size_t len)
438 4f4321c1 Gerd Hoffmann
{
439 4f4321c1 Gerd Hoffmann
    qemu_iovec_add(&p->iov, ptr, len);
440 4f4321c1 Gerd Hoffmann
}
441 4f4321c1 Gerd Hoffmann
442 4f4321c1 Gerd Hoffmann
void usb_packet_copy(USBPacket *p, void *ptr, size_t bytes)
443 4f4321c1 Gerd Hoffmann
{
444 4f4321c1 Gerd Hoffmann
    assert(p->result >= 0);
445 4f4321c1 Gerd Hoffmann
    assert(p->result + bytes <= p->iov.size);
446 4f4321c1 Gerd Hoffmann
    switch (p->pid) {
447 4f4321c1 Gerd Hoffmann
    case USB_TOKEN_SETUP:
448 4f4321c1 Gerd Hoffmann
    case USB_TOKEN_OUT:
449 4f4321c1 Gerd Hoffmann
        iov_to_buf(p->iov.iov, p->iov.niov, ptr, p->result, bytes);
450 4f4321c1 Gerd Hoffmann
        break;
451 4f4321c1 Gerd Hoffmann
    case USB_TOKEN_IN:
452 4f4321c1 Gerd Hoffmann
        iov_from_buf(p->iov.iov, p->iov.niov, ptr, p->result, bytes);
453 4f4321c1 Gerd Hoffmann
        break;
454 4f4321c1 Gerd Hoffmann
    default:
455 4f4321c1 Gerd Hoffmann
        fprintf(stderr, "%s: invalid pid: %x\n", __func__, p->pid);
456 4f4321c1 Gerd Hoffmann
        abort();
457 4f4321c1 Gerd Hoffmann
    }
458 4f4321c1 Gerd Hoffmann
    p->result += bytes;
459 4f4321c1 Gerd Hoffmann
}
460 4f4321c1 Gerd Hoffmann
461 4f4321c1 Gerd Hoffmann
void usb_packet_skip(USBPacket *p, size_t bytes)
462 4f4321c1 Gerd Hoffmann
{
463 4f4321c1 Gerd Hoffmann
    assert(p->result >= 0);
464 4f4321c1 Gerd Hoffmann
    assert(p->result + bytes <= p->iov.size);
465 4f4321c1 Gerd Hoffmann
    if (p->pid == USB_TOKEN_IN) {
466 4f4321c1 Gerd Hoffmann
        iov_clear(p->iov.iov, p->iov.niov, p->result, bytes);
467 4f4321c1 Gerd Hoffmann
    }
468 4f4321c1 Gerd Hoffmann
    p->result += bytes;
469 4f4321c1 Gerd Hoffmann
}
470 4f4321c1 Gerd Hoffmann
471 4f4321c1 Gerd Hoffmann
void usb_packet_cleanup(USBPacket *p)
472 4f4321c1 Gerd Hoffmann
{
473 f53c398a Gerd Hoffmann
    assert(!usb_packet_is_inflight(p));
474 4f4321c1 Gerd Hoffmann
    qemu_iovec_destroy(&p->iov);
475 4f4321c1 Gerd Hoffmann
}
476 d8e17efd Gerd Hoffmann
477 d8e17efd Gerd Hoffmann
void usb_ep_init(USBDevice *dev)
478 d8e17efd Gerd Hoffmann
{
479 d8e17efd Gerd Hoffmann
    int ep;
480 d8e17efd Gerd Hoffmann
481 63095ab5 Gerd Hoffmann
    dev->ep_ctl.nr = 0;
482 25d5de7d Gerd Hoffmann
    dev->ep_ctl.type = USB_ENDPOINT_XFER_CONTROL;
483 25d5de7d Gerd Hoffmann
    dev->ep_ctl.ifnum = 0;
484 25d5de7d Gerd Hoffmann
    dev->ep_ctl.dev = dev;
485 db4be873 Gerd Hoffmann
    QTAILQ_INIT(&dev->ep_ctl.queue);
486 d8e17efd Gerd Hoffmann
    for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
487 63095ab5 Gerd Hoffmann
        dev->ep_in[ep].nr = ep + 1;
488 63095ab5 Gerd Hoffmann
        dev->ep_out[ep].nr = ep + 1;
489 63095ab5 Gerd Hoffmann
        dev->ep_in[ep].pid = USB_TOKEN_IN;
490 63095ab5 Gerd Hoffmann
        dev->ep_out[ep].pid = USB_TOKEN_OUT;
491 d8e17efd Gerd Hoffmann
        dev->ep_in[ep].type = USB_ENDPOINT_XFER_INVALID;
492 d8e17efd Gerd Hoffmann
        dev->ep_out[ep].type = USB_ENDPOINT_XFER_INVALID;
493 82f02fe9 Gerd Hoffmann
        dev->ep_in[ep].ifnum = 0;
494 82f02fe9 Gerd Hoffmann
        dev->ep_out[ep].ifnum = 0;
495 25d5de7d Gerd Hoffmann
        dev->ep_in[ep].dev = dev;
496 25d5de7d Gerd Hoffmann
        dev->ep_out[ep].dev = dev;
497 db4be873 Gerd Hoffmann
        QTAILQ_INIT(&dev->ep_in[ep].queue);
498 db4be873 Gerd Hoffmann
        QTAILQ_INIT(&dev->ep_out[ep].queue);
499 d8e17efd Gerd Hoffmann
    }
500 d8e17efd Gerd Hoffmann
}
501 d8e17efd Gerd Hoffmann
502 5b6780d0 Gerd Hoffmann
void usb_ep_dump(USBDevice *dev)
503 5b6780d0 Gerd Hoffmann
{
504 5b6780d0 Gerd Hoffmann
    static const char *tname[] = {
505 5b6780d0 Gerd Hoffmann
        [USB_ENDPOINT_XFER_CONTROL] = "control",
506 5b6780d0 Gerd Hoffmann
        [USB_ENDPOINT_XFER_ISOC]    = "isoc",
507 5b6780d0 Gerd Hoffmann
        [USB_ENDPOINT_XFER_BULK]    = "bulk",
508 5b6780d0 Gerd Hoffmann
        [USB_ENDPOINT_XFER_INT]     = "int",
509 5b6780d0 Gerd Hoffmann
    };
510 5b6780d0 Gerd Hoffmann
    int ifnum, ep, first;
511 5b6780d0 Gerd Hoffmann
512 5b6780d0 Gerd Hoffmann
    fprintf(stderr, "Device \"%s\", config %d\n",
513 5b6780d0 Gerd Hoffmann
            dev->product_desc, dev->configuration);
514 5b6780d0 Gerd Hoffmann
    for (ifnum = 0; ifnum < 16; ifnum++) {
515 5b6780d0 Gerd Hoffmann
        first = 1;
516 5b6780d0 Gerd Hoffmann
        for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
517 5b6780d0 Gerd Hoffmann
            if (dev->ep_in[ep].type != USB_ENDPOINT_XFER_INVALID &&
518 5b6780d0 Gerd Hoffmann
                dev->ep_in[ep].ifnum == ifnum) {
519 5b6780d0 Gerd Hoffmann
                if (first) {
520 5b6780d0 Gerd Hoffmann
                    first = 0;
521 5b6780d0 Gerd Hoffmann
                    fprintf(stderr, "  Interface %d, alternative %d\n",
522 5b6780d0 Gerd Hoffmann
                            ifnum, dev->altsetting[ifnum]);
523 5b6780d0 Gerd Hoffmann
                }
524 f003397c Gerd Hoffmann
                fprintf(stderr, "    Endpoint %d, IN, %s, %d max\n", ep,
525 f003397c Gerd Hoffmann
                        tname[dev->ep_in[ep].type],
526 f003397c Gerd Hoffmann
                        dev->ep_in[ep].max_packet_size);
527 5b6780d0 Gerd Hoffmann
            }
528 5b6780d0 Gerd Hoffmann
            if (dev->ep_out[ep].type != USB_ENDPOINT_XFER_INVALID &&
529 5b6780d0 Gerd Hoffmann
                dev->ep_out[ep].ifnum == ifnum) {
530 5b6780d0 Gerd Hoffmann
                if (first) {
531 5b6780d0 Gerd Hoffmann
                    first = 0;
532 5b6780d0 Gerd Hoffmann
                    fprintf(stderr, "  Interface %d, alternative %d\n",
533 5b6780d0 Gerd Hoffmann
                            ifnum, dev->altsetting[ifnum]);
534 5b6780d0 Gerd Hoffmann
                }
535 f003397c Gerd Hoffmann
                fprintf(stderr, "    Endpoint %d, OUT, %s, %d max\n", ep,
536 f003397c Gerd Hoffmann
                        tname[dev->ep_out[ep].type],
537 f003397c Gerd Hoffmann
                        dev->ep_out[ep].max_packet_size);
538 5b6780d0 Gerd Hoffmann
            }
539 5b6780d0 Gerd Hoffmann
        }
540 5b6780d0 Gerd Hoffmann
    }
541 5b6780d0 Gerd Hoffmann
    fprintf(stderr, "--\n");
542 5b6780d0 Gerd Hoffmann
}
543 5b6780d0 Gerd Hoffmann
544 d8e17efd Gerd Hoffmann
struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep)
545 d8e17efd Gerd Hoffmann
{
546 079d0b7f Gerd Hoffmann
    struct USBEndpoint *eps;
547 079d0b7f Gerd Hoffmann
548 079d0b7f Gerd Hoffmann
    if (dev == NULL) {
549 079d0b7f Gerd Hoffmann
        return NULL;
550 079d0b7f Gerd Hoffmann
    }
551 079d0b7f Gerd Hoffmann
    eps = (pid == USB_TOKEN_IN) ? dev->ep_in : dev->ep_out;
552 25d5de7d Gerd Hoffmann
    if (ep == 0) {
553 25d5de7d Gerd Hoffmann
        return &dev->ep_ctl;
554 25d5de7d Gerd Hoffmann
    }
555 d8e17efd Gerd Hoffmann
    assert(pid == USB_TOKEN_IN || pid == USB_TOKEN_OUT);
556 d8e17efd Gerd Hoffmann
    assert(ep > 0 && ep <= USB_MAX_ENDPOINTS);
557 d8e17efd Gerd Hoffmann
    return eps + ep - 1;
558 d8e17efd Gerd Hoffmann
}
559 d8e17efd Gerd Hoffmann
560 d8e17efd Gerd Hoffmann
uint8_t usb_ep_get_type(USBDevice *dev, int pid, int ep)
561 d8e17efd Gerd Hoffmann
{
562 d8e17efd Gerd Hoffmann
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
563 d8e17efd Gerd Hoffmann
    return uep->type;
564 d8e17efd Gerd Hoffmann
}
565 d8e17efd Gerd Hoffmann
566 d8e17efd Gerd Hoffmann
void usb_ep_set_type(USBDevice *dev, int pid, int ep, uint8_t type)
567 d8e17efd Gerd Hoffmann
{
568 d8e17efd Gerd Hoffmann
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
569 d8e17efd Gerd Hoffmann
    uep->type = type;
570 d8e17efd Gerd Hoffmann
}
571 82f02fe9 Gerd Hoffmann
572 82f02fe9 Gerd Hoffmann
uint8_t usb_ep_get_ifnum(USBDevice *dev, int pid, int ep)
573 82f02fe9 Gerd Hoffmann
{
574 82f02fe9 Gerd Hoffmann
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
575 82f02fe9 Gerd Hoffmann
    return uep->ifnum;
576 82f02fe9 Gerd Hoffmann
}
577 82f02fe9 Gerd Hoffmann
578 82f02fe9 Gerd Hoffmann
void usb_ep_set_ifnum(USBDevice *dev, int pid, int ep, uint8_t ifnum)
579 82f02fe9 Gerd Hoffmann
{
580 82f02fe9 Gerd Hoffmann
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
581 82f02fe9 Gerd Hoffmann
    uep->ifnum = ifnum;
582 82f02fe9 Gerd Hoffmann
}
583 f003397c Gerd Hoffmann
584 f003397c Gerd Hoffmann
void usb_ep_set_max_packet_size(USBDevice *dev, int pid, int ep,
585 f003397c Gerd Hoffmann
                                uint16_t raw)
586 f003397c Gerd Hoffmann
{
587 f003397c Gerd Hoffmann
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
588 f003397c Gerd Hoffmann
    int size, microframes;
589 f003397c Gerd Hoffmann
590 f003397c Gerd Hoffmann
    size = raw & 0x7ff;
591 f003397c Gerd Hoffmann
    switch ((raw >> 11) & 3) {
592 f003397c Gerd Hoffmann
    case 1:
593 f003397c Gerd Hoffmann
        microframes = 2;
594 f003397c Gerd Hoffmann
        break;
595 f003397c Gerd Hoffmann
    case 2:
596 f003397c Gerd Hoffmann
        microframes = 3;
597 f003397c Gerd Hoffmann
        break;
598 f003397c Gerd Hoffmann
    default:
599 f003397c Gerd Hoffmann
        microframes = 1;
600 f003397c Gerd Hoffmann
        break;
601 f003397c Gerd Hoffmann
    }
602 f003397c Gerd Hoffmann
    uep->max_packet_size = size * microframes;
603 f003397c Gerd Hoffmann
}
604 f003397c Gerd Hoffmann
605 f003397c Gerd Hoffmann
int usb_ep_get_max_packet_size(USBDevice *dev, int pid, int ep)
606 f003397c Gerd Hoffmann
{
607 f003397c Gerd Hoffmann
    struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
608 f003397c Gerd Hoffmann
    return uep->max_packet_size;
609 f003397c Gerd Hoffmann
}