Statistics
| Branch: | Revision:

root / usb-redir.c @ be40edcd

History | View | Annotate | Download (38.3 kB)

1 69354a83 Hans de Goede
/*
2 69354a83 Hans de Goede
 * USB redirector usb-guest
3 69354a83 Hans de Goede
 *
4 69354a83 Hans de Goede
 * Copyright (c) 2011 Red Hat, Inc.
5 69354a83 Hans de Goede
 *
6 69354a83 Hans de Goede
 * Red Hat Authors:
7 69354a83 Hans de Goede
 * Hans de Goede <hdegoede@redhat.com>
8 69354a83 Hans de Goede
 *
9 69354a83 Hans de Goede
 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 69354a83 Hans de Goede
 * of this software and associated documentation files (the "Software"), to deal
11 69354a83 Hans de Goede
 * in the Software without restriction, including without limitation the rights
12 69354a83 Hans de Goede
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 69354a83 Hans de Goede
 * copies of the Software, and to permit persons to whom the Software is
14 69354a83 Hans de Goede
 * furnished to do so, subject to the following conditions:
15 69354a83 Hans de Goede
 *
16 69354a83 Hans de Goede
 * The above copyright notice and this permission notice shall be included in
17 69354a83 Hans de Goede
 * all copies or substantial portions of the Software.
18 69354a83 Hans de Goede
 *
19 69354a83 Hans de Goede
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 69354a83 Hans de Goede
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 69354a83 Hans de Goede
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 69354a83 Hans de Goede
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 69354a83 Hans de Goede
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 69354a83 Hans de Goede
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 69354a83 Hans de Goede
 * THE SOFTWARE.
26 69354a83 Hans de Goede
 */
27 69354a83 Hans de Goede
28 69354a83 Hans de Goede
#include "qemu-common.h"
29 69354a83 Hans de Goede
#include "qemu-timer.h"
30 69354a83 Hans de Goede
#include "monitor.h"
31 69354a83 Hans de Goede
#include "sysemu.h"
32 69354a83 Hans de Goede
33 69354a83 Hans de Goede
#include <dirent.h>
34 69354a83 Hans de Goede
#include <sys/ioctl.h>
35 69354a83 Hans de Goede
#include <signal.h>
36 69354a83 Hans de Goede
#include <usbredirparser.h>
37 69354a83 Hans de Goede
38 69354a83 Hans de Goede
#include "hw/usb.h"
39 69354a83 Hans de Goede
40 69354a83 Hans de Goede
#define MAX_ENDPOINTS 32
41 69354a83 Hans de Goede
#define EP2I(ep_address) (((ep_address & 0x80) >> 3) | (ep_address & 0x0f))
42 69354a83 Hans de Goede
#define I2EP(i) (((i & 0x10) << 3) | (i & 0x0f))
43 69354a83 Hans de Goede
44 69354a83 Hans de Goede
typedef struct AsyncURB AsyncURB;
45 69354a83 Hans de Goede
typedef struct USBRedirDevice USBRedirDevice;
46 69354a83 Hans de Goede
47 69354a83 Hans de Goede
/* Struct to hold buffered packets (iso or int input packets) */
48 69354a83 Hans de Goede
struct buf_packet {
49 69354a83 Hans de Goede
    uint8_t *data;
50 69354a83 Hans de Goede
    int len;
51 69354a83 Hans de Goede
    int status;
52 69354a83 Hans de Goede
    QTAILQ_ENTRY(buf_packet)next;
53 69354a83 Hans de Goede
};
54 69354a83 Hans de Goede
55 69354a83 Hans de Goede
struct endp_data {
56 69354a83 Hans de Goede
    uint8_t type;
57 69354a83 Hans de Goede
    uint8_t interval;
58 69354a83 Hans de Goede
    uint8_t interface; /* bInterfaceNumber this ep belongs to */
59 69354a83 Hans de Goede
    uint8_t iso_started;
60 69354a83 Hans de Goede
    uint8_t iso_error; /* For reporting iso errors to the HC */
61 69354a83 Hans de Goede
    uint8_t interrupt_started;
62 69354a83 Hans de Goede
    uint8_t interrupt_error;
63 69354a83 Hans de Goede
    QTAILQ_HEAD(, buf_packet) bufpq;
64 69354a83 Hans de Goede
};
65 69354a83 Hans de Goede
66 69354a83 Hans de Goede
struct USBRedirDevice {
67 69354a83 Hans de Goede
    USBDevice dev;
68 69354a83 Hans de Goede
    /* Properties */
69 69354a83 Hans de Goede
    CharDriverState *cs;
70 69354a83 Hans de Goede
    uint8_t debug;
71 69354a83 Hans de Goede
    /* Data passed from chardev the fd_read cb to the usbredirparser read cb */
72 69354a83 Hans de Goede
    const uint8_t *read_buf;
73 69354a83 Hans de Goede
    int read_buf_size;
74 69354a83 Hans de Goede
    /* For async handling of open/close */
75 69354a83 Hans de Goede
    QEMUBH *open_close_bh;
76 69354a83 Hans de Goede
    /* To delay the usb attach in case of quick chardev close + open */
77 69354a83 Hans de Goede
    QEMUTimer *attach_timer;
78 69354a83 Hans de Goede
    int64_t next_attach_time;
79 69354a83 Hans de Goede
    struct usbredirparser *parser;
80 69354a83 Hans de Goede
    struct endp_data endpoint[MAX_ENDPOINTS];
81 69354a83 Hans de Goede
    uint32_t packet_id;
82 69354a83 Hans de Goede
    QTAILQ_HEAD(, AsyncURB) asyncq;
83 69354a83 Hans de Goede
};
84 69354a83 Hans de Goede
85 69354a83 Hans de Goede
struct AsyncURB {
86 69354a83 Hans de Goede
    USBRedirDevice *dev;
87 69354a83 Hans de Goede
    USBPacket *packet;
88 69354a83 Hans de Goede
    uint32_t packet_id;
89 69354a83 Hans de Goede
    int get;
90 69354a83 Hans de Goede
    union {
91 69354a83 Hans de Goede
        struct usb_redir_control_packet_header control_packet;
92 69354a83 Hans de Goede
        struct usb_redir_bulk_packet_header bulk_packet;
93 69354a83 Hans de Goede
        struct usb_redir_interrupt_packet_header interrupt_packet;
94 69354a83 Hans de Goede
    };
95 69354a83 Hans de Goede
    QTAILQ_ENTRY(AsyncURB)next;
96 69354a83 Hans de Goede
};
97 69354a83 Hans de Goede
98 69354a83 Hans de Goede
static void usbredir_device_connect(void *priv,
99 69354a83 Hans de Goede
    struct usb_redir_device_connect_header *device_connect);
100 69354a83 Hans de Goede
static void usbredir_device_disconnect(void *priv);
101 69354a83 Hans de Goede
static void usbredir_interface_info(void *priv,
102 69354a83 Hans de Goede
    struct usb_redir_interface_info_header *interface_info);
103 69354a83 Hans de Goede
static void usbredir_ep_info(void *priv,
104 69354a83 Hans de Goede
    struct usb_redir_ep_info_header *ep_info);
105 69354a83 Hans de Goede
static void usbredir_configuration_status(void *priv, uint32_t id,
106 69354a83 Hans de Goede
    struct usb_redir_configuration_status_header *configuration_status);
107 69354a83 Hans de Goede
static void usbredir_alt_setting_status(void *priv, uint32_t id,
108 69354a83 Hans de Goede
    struct usb_redir_alt_setting_status_header *alt_setting_status);
109 69354a83 Hans de Goede
static void usbredir_iso_stream_status(void *priv, uint32_t id,
110 69354a83 Hans de Goede
    struct usb_redir_iso_stream_status_header *iso_stream_status);
111 69354a83 Hans de Goede
static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
112 69354a83 Hans de Goede
    struct usb_redir_interrupt_receiving_status_header
113 69354a83 Hans de Goede
    *interrupt_receiving_status);
114 69354a83 Hans de Goede
static void usbredir_bulk_streams_status(void *priv, uint32_t id,
115 69354a83 Hans de Goede
    struct usb_redir_bulk_streams_status_header *bulk_streams_status);
116 69354a83 Hans de Goede
static void usbredir_control_packet(void *priv, uint32_t id,
117 69354a83 Hans de Goede
    struct usb_redir_control_packet_header *control_packet,
118 69354a83 Hans de Goede
    uint8_t *data, int data_len);
119 69354a83 Hans de Goede
static void usbredir_bulk_packet(void *priv, uint32_t id,
120 69354a83 Hans de Goede
    struct usb_redir_bulk_packet_header *bulk_packet,
121 69354a83 Hans de Goede
    uint8_t *data, int data_len);
122 69354a83 Hans de Goede
static void usbredir_iso_packet(void *priv, uint32_t id,
123 69354a83 Hans de Goede
    struct usb_redir_iso_packet_header *iso_packet,
124 69354a83 Hans de Goede
    uint8_t *data, int data_len);
125 69354a83 Hans de Goede
static void usbredir_interrupt_packet(void *priv, uint32_t id,
126 69354a83 Hans de Goede
    struct usb_redir_interrupt_packet_header *interrupt_header,
127 69354a83 Hans de Goede
    uint8_t *data, int data_len);
128 69354a83 Hans de Goede
129 69354a83 Hans de Goede
static int usbredir_handle_status(USBRedirDevice *dev,
130 69354a83 Hans de Goede
                                       int status, int actual_len);
131 69354a83 Hans de Goede
132 69354a83 Hans de Goede
#define VERSION "qemu usb-redir guest " QEMU_VERSION
133 69354a83 Hans de Goede
134 69354a83 Hans de Goede
/*
135 69354a83 Hans de Goede
 * Logging stuff
136 69354a83 Hans de Goede
 */
137 69354a83 Hans de Goede
138 69354a83 Hans de Goede
#define ERROR(...) \
139 69354a83 Hans de Goede
    do { \
140 69354a83 Hans de Goede
        if (dev->debug >= usbredirparser_error) { \
141 69354a83 Hans de Goede
            error_report("usb-redir error: " __VA_ARGS__); \
142 69354a83 Hans de Goede
        } \
143 69354a83 Hans de Goede
    } while (0)
144 69354a83 Hans de Goede
#define WARNING(...) \
145 69354a83 Hans de Goede
    do { \
146 69354a83 Hans de Goede
        if (dev->debug >= usbredirparser_warning) { \
147 69354a83 Hans de Goede
            error_report("usb-redir warning: " __VA_ARGS__); \
148 69354a83 Hans de Goede
        } \
149 69354a83 Hans de Goede
    } while (0)
150 69354a83 Hans de Goede
#define INFO(...) \
151 69354a83 Hans de Goede
    do { \
152 69354a83 Hans de Goede
        if (dev->debug >= usbredirparser_info) { \
153 69354a83 Hans de Goede
            error_report("usb-redir: " __VA_ARGS__); \
154 69354a83 Hans de Goede
        } \
155 69354a83 Hans de Goede
    } while (0)
156 69354a83 Hans de Goede
#define DPRINTF(...) \
157 69354a83 Hans de Goede
    do { \
158 69354a83 Hans de Goede
        if (dev->debug >= usbredirparser_debug) { \
159 69354a83 Hans de Goede
            error_report("usb-redir: " __VA_ARGS__); \
160 69354a83 Hans de Goede
        } \
161 69354a83 Hans de Goede
    } while (0)
162 69354a83 Hans de Goede
#define DPRINTF2(...) \
163 69354a83 Hans de Goede
    do { \
164 69354a83 Hans de Goede
        if (dev->debug >= usbredirparser_debug_data) { \
165 69354a83 Hans de Goede
            error_report("usb-redir: " __VA_ARGS__); \
166 69354a83 Hans de Goede
        } \
167 69354a83 Hans de Goede
    } while (0)
168 69354a83 Hans de Goede
169 69354a83 Hans de Goede
static void usbredir_log(void *priv, int level, const char *msg)
170 69354a83 Hans de Goede
{
171 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
172 69354a83 Hans de Goede
173 69354a83 Hans de Goede
    if (dev->debug < level) {
174 69354a83 Hans de Goede
        return;
175 69354a83 Hans de Goede
    }
176 69354a83 Hans de Goede
177 69354a83 Hans de Goede
    error_report("%s\n", msg);
178 69354a83 Hans de Goede
}
179 69354a83 Hans de Goede
180 69354a83 Hans de Goede
static void usbredir_log_data(USBRedirDevice *dev, const char *desc,
181 69354a83 Hans de Goede
    const uint8_t *data, int len)
182 69354a83 Hans de Goede
{
183 69354a83 Hans de Goede
    int i, j, n;
184 69354a83 Hans de Goede
185 69354a83 Hans de Goede
    if (dev->debug < usbredirparser_debug_data) {
186 69354a83 Hans de Goede
        return;
187 69354a83 Hans de Goede
    }
188 69354a83 Hans de Goede
189 69354a83 Hans de Goede
    for (i = 0; i < len; i += j) {
190 69354a83 Hans de Goede
        char buf[128];
191 69354a83 Hans de Goede
192 69354a83 Hans de Goede
        n = sprintf(buf, "%s", desc);
193 69354a83 Hans de Goede
        for (j = 0; j < 8 && i + j < len; j++) {
194 69354a83 Hans de Goede
            n += sprintf(buf + n, " %02X", data[i + j]);
195 69354a83 Hans de Goede
        }
196 69354a83 Hans de Goede
        error_report("%s\n", buf);
197 69354a83 Hans de Goede
    }
198 69354a83 Hans de Goede
}
199 69354a83 Hans de Goede
200 69354a83 Hans de Goede
/*
201 69354a83 Hans de Goede
 * usbredirparser io functions
202 69354a83 Hans de Goede
 */
203 69354a83 Hans de Goede
204 69354a83 Hans de Goede
static int usbredir_read(void *priv, uint8_t *data, int count)
205 69354a83 Hans de Goede
{
206 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
207 69354a83 Hans de Goede
208 69354a83 Hans de Goede
    if (dev->read_buf_size < count) {
209 69354a83 Hans de Goede
        count = dev->read_buf_size;
210 69354a83 Hans de Goede
    }
211 69354a83 Hans de Goede
212 69354a83 Hans de Goede
    memcpy(data, dev->read_buf, count);
213 69354a83 Hans de Goede
214 69354a83 Hans de Goede
    dev->read_buf_size -= count;
215 69354a83 Hans de Goede
    if (dev->read_buf_size) {
216 69354a83 Hans de Goede
        dev->read_buf += count;
217 69354a83 Hans de Goede
    } else {
218 69354a83 Hans de Goede
        dev->read_buf = NULL;
219 69354a83 Hans de Goede
    }
220 69354a83 Hans de Goede
221 69354a83 Hans de Goede
    return count;
222 69354a83 Hans de Goede
}
223 69354a83 Hans de Goede
224 69354a83 Hans de Goede
static int usbredir_write(void *priv, uint8_t *data, int count)
225 69354a83 Hans de Goede
{
226 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
227 69354a83 Hans de Goede
228 2cc6e0a1 Anthony Liguori
    return qemu_chr_fe_write(dev->cs, data, count);
229 69354a83 Hans de Goede
}
230 69354a83 Hans de Goede
231 69354a83 Hans de Goede
/*
232 69354a83 Hans de Goede
 * Async and buffered packets helpers
233 69354a83 Hans de Goede
 */
234 69354a83 Hans de Goede
235 69354a83 Hans de Goede
static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p)
236 69354a83 Hans de Goede
{
237 7267c094 Anthony Liguori
    AsyncURB *aurb = (AsyncURB *) g_malloc0(sizeof(AsyncURB));
238 69354a83 Hans de Goede
    aurb->dev = dev;
239 69354a83 Hans de Goede
    aurb->packet = p;
240 69354a83 Hans de Goede
    aurb->packet_id = dev->packet_id;
241 69354a83 Hans de Goede
    QTAILQ_INSERT_TAIL(&dev->asyncq, aurb, next);
242 69354a83 Hans de Goede
    dev->packet_id++;
243 69354a83 Hans de Goede
244 69354a83 Hans de Goede
    return aurb;
245 69354a83 Hans de Goede
}
246 69354a83 Hans de Goede
247 69354a83 Hans de Goede
static void async_free(USBRedirDevice *dev, AsyncURB *aurb)
248 69354a83 Hans de Goede
{
249 69354a83 Hans de Goede
    QTAILQ_REMOVE(&dev->asyncq, aurb, next);
250 7267c094 Anthony Liguori
    g_free(aurb);
251 69354a83 Hans de Goede
}
252 69354a83 Hans de Goede
253 69354a83 Hans de Goede
static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id)
254 69354a83 Hans de Goede
{
255 69354a83 Hans de Goede
    AsyncURB *aurb;
256 69354a83 Hans de Goede
257 69354a83 Hans de Goede
    QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
258 69354a83 Hans de Goede
        if (aurb->packet_id == packet_id) {
259 69354a83 Hans de Goede
            return aurb;
260 69354a83 Hans de Goede
        }
261 69354a83 Hans de Goede
    }
262 69354a83 Hans de Goede
    ERROR("could not find async urb for packet_id %u\n", packet_id);
263 69354a83 Hans de Goede
    return NULL;
264 69354a83 Hans de Goede
}
265 69354a83 Hans de Goede
266 69354a83 Hans de Goede
static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
267 69354a83 Hans de Goede
{
268 69354a83 Hans de Goede
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
269 69354a83 Hans de Goede
    AsyncURB *aurb;
270 69354a83 Hans de Goede
271 69354a83 Hans de Goede
    QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
272 69354a83 Hans de Goede
        if (p != aurb->packet) {
273 69354a83 Hans de Goede
            continue;
274 69354a83 Hans de Goede
        }
275 69354a83 Hans de Goede
276 69354a83 Hans de Goede
        DPRINTF("async cancel id %u\n", aurb->packet_id);
277 69354a83 Hans de Goede
        usbredirparser_send_cancel_data_packet(dev->parser, aurb->packet_id);
278 69354a83 Hans de Goede
        usbredirparser_do_write(dev->parser);
279 69354a83 Hans de Goede
280 69354a83 Hans de Goede
        /* Mark it as dead */
281 69354a83 Hans de Goede
        aurb->packet = NULL;
282 69354a83 Hans de Goede
        break;
283 69354a83 Hans de Goede
    }
284 69354a83 Hans de Goede
}
285 69354a83 Hans de Goede
286 69354a83 Hans de Goede
static struct buf_packet *bufp_alloc(USBRedirDevice *dev,
287 69354a83 Hans de Goede
    uint8_t *data, int len, int status, uint8_t ep)
288 69354a83 Hans de Goede
{
289 7267c094 Anthony Liguori
    struct buf_packet *bufp = g_malloc(sizeof(struct buf_packet));
290 69354a83 Hans de Goede
    bufp->data   = data;
291 69354a83 Hans de Goede
    bufp->len    = len;
292 69354a83 Hans de Goede
    bufp->status = status;
293 69354a83 Hans de Goede
    QTAILQ_INSERT_TAIL(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
294 69354a83 Hans de Goede
    return bufp;
295 69354a83 Hans de Goede
}
296 69354a83 Hans de Goede
297 69354a83 Hans de Goede
static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp,
298 69354a83 Hans de Goede
    uint8_t ep)
299 69354a83 Hans de Goede
{
300 69354a83 Hans de Goede
    QTAILQ_REMOVE(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
301 69354a83 Hans de Goede
    free(bufp->data);
302 7267c094 Anthony Liguori
    g_free(bufp);
303 69354a83 Hans de Goede
}
304 69354a83 Hans de Goede
305 69354a83 Hans de Goede
static void usbredir_free_bufpq(USBRedirDevice *dev, uint8_t ep)
306 69354a83 Hans de Goede
{
307 69354a83 Hans de Goede
    struct buf_packet *buf, *buf_next;
308 69354a83 Hans de Goede
309 69354a83 Hans de Goede
    QTAILQ_FOREACH_SAFE(buf, &dev->endpoint[EP2I(ep)].bufpq, next, buf_next) {
310 69354a83 Hans de Goede
        bufp_free(dev, buf, ep);
311 69354a83 Hans de Goede
    }
312 69354a83 Hans de Goede
}
313 69354a83 Hans de Goede
314 69354a83 Hans de Goede
/*
315 69354a83 Hans de Goede
 * USBDevice callbacks
316 69354a83 Hans de Goede
 */
317 69354a83 Hans de Goede
318 69354a83 Hans de Goede
static void usbredir_handle_reset(USBDevice *udev)
319 69354a83 Hans de Goede
{
320 69354a83 Hans de Goede
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
321 69354a83 Hans de Goede
322 69354a83 Hans de Goede
    DPRINTF("reset device\n");
323 69354a83 Hans de Goede
    usbredirparser_send_reset(dev->parser);
324 69354a83 Hans de Goede
    usbredirparser_do_write(dev->parser);
325 69354a83 Hans de Goede
}
326 69354a83 Hans de Goede
327 69354a83 Hans de Goede
static int usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p,
328 69354a83 Hans de Goede
                                     uint8_t ep)
329 69354a83 Hans de Goede
{
330 69354a83 Hans de Goede
    int status, len;
331 69354a83 Hans de Goede
332 69354a83 Hans de Goede
    if (!dev->endpoint[EP2I(ep)].iso_started &&
333 69354a83 Hans de Goede
            !dev->endpoint[EP2I(ep)].iso_error) {
334 69354a83 Hans de Goede
        struct usb_redir_start_iso_stream_header start_iso = {
335 69354a83 Hans de Goede
            .endpoint = ep,
336 69354a83 Hans de Goede
            /* TODO maybe do something with these depending on ep interval? */
337 69354a83 Hans de Goede
            .pkts_per_urb = 32,
338 69354a83 Hans de Goede
            .no_urbs = 3,
339 69354a83 Hans de Goede
        };
340 69354a83 Hans de Goede
        /* No id, we look at the ep when receiving a status back */
341 69354a83 Hans de Goede
        usbredirparser_send_start_iso_stream(dev->parser, 0, &start_iso);
342 69354a83 Hans de Goede
        usbredirparser_do_write(dev->parser);
343 69354a83 Hans de Goede
        DPRINTF("iso stream started ep %02X\n", ep);
344 69354a83 Hans de Goede
        dev->endpoint[EP2I(ep)].iso_started = 1;
345 69354a83 Hans de Goede
    }
346 69354a83 Hans de Goede
347 69354a83 Hans de Goede
    if (ep & USB_DIR_IN) {
348 69354a83 Hans de Goede
        struct buf_packet *isop;
349 69354a83 Hans de Goede
350 69354a83 Hans de Goede
        isop = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
351 69354a83 Hans de Goede
        if (isop == NULL) {
352 69354a83 Hans de Goede
            DPRINTF2("iso-token-in ep %02X, no isop\n", ep);
353 69354a83 Hans de Goede
            /* Check iso_error for stream errors, otherwise its an underrun */
354 69354a83 Hans de Goede
            status = dev->endpoint[EP2I(ep)].iso_error;
355 69354a83 Hans de Goede
            dev->endpoint[EP2I(ep)].iso_error = 0;
356 69354a83 Hans de Goede
            return usbredir_handle_status(dev, status, 0);
357 69354a83 Hans de Goede
        }
358 69354a83 Hans de Goede
        DPRINTF2("iso-token-in ep %02X status %d len %d\n", ep, isop->status,
359 69354a83 Hans de Goede
                 isop->len);
360 69354a83 Hans de Goede
361 69354a83 Hans de Goede
        status = isop->status;
362 69354a83 Hans de Goede
        if (status != usb_redir_success) {
363 69354a83 Hans de Goede
            bufp_free(dev, isop, ep);
364 69354a83 Hans de Goede
            return usbredir_handle_status(dev, status, 0);
365 69354a83 Hans de Goede
        }
366 69354a83 Hans de Goede
367 69354a83 Hans de Goede
        len = isop->len;
368 4f4321c1 Gerd Hoffmann
        if (len > p->iov.size) {
369 69354a83 Hans de Goede
            ERROR("received iso data is larger then packet ep %02X\n", ep);
370 69354a83 Hans de Goede
            bufp_free(dev, isop, ep);
371 69354a83 Hans de Goede
            return USB_RET_NAK;
372 69354a83 Hans de Goede
        }
373 4f4321c1 Gerd Hoffmann
        usb_packet_copy(p, isop->data, len);
374 69354a83 Hans de Goede
        bufp_free(dev, isop, ep);
375 69354a83 Hans de Goede
        return len;
376 69354a83 Hans de Goede
    } else {
377 69354a83 Hans de Goede
        /* If the stream was not started because of a pending error don't
378 69354a83 Hans de Goede
           send the packet to the usb-host */
379 69354a83 Hans de Goede
        if (dev->endpoint[EP2I(ep)].iso_started) {
380 69354a83 Hans de Goede
            struct usb_redir_iso_packet_header iso_packet = {
381 69354a83 Hans de Goede
                .endpoint = ep,
382 4f4321c1 Gerd Hoffmann
                .length = p->iov.size
383 69354a83 Hans de Goede
            };
384 4f4321c1 Gerd Hoffmann
            uint8_t buf[p->iov.size];
385 69354a83 Hans de Goede
            /* No id, we look at the ep when receiving a status back */
386 4f4321c1 Gerd Hoffmann
            usb_packet_copy(p, buf, p->iov.size);
387 69354a83 Hans de Goede
            usbredirparser_send_iso_packet(dev->parser, 0, &iso_packet,
388 4f4321c1 Gerd Hoffmann
                                           buf, p->iov.size);
389 69354a83 Hans de Goede
            usbredirparser_do_write(dev->parser);
390 69354a83 Hans de Goede
        }
391 69354a83 Hans de Goede
        status = dev->endpoint[EP2I(ep)].iso_error;
392 69354a83 Hans de Goede
        dev->endpoint[EP2I(ep)].iso_error = 0;
393 4f4321c1 Gerd Hoffmann
        DPRINTF2("iso-token-out ep %02X status %d len %zd\n", ep, status,
394 4f4321c1 Gerd Hoffmann
                 p->iov.size);
395 4f4321c1 Gerd Hoffmann
        return usbredir_handle_status(dev, status, p->iov.size);
396 69354a83 Hans de Goede
    }
397 69354a83 Hans de Goede
}
398 69354a83 Hans de Goede
399 69354a83 Hans de Goede
static void usbredir_stop_iso_stream(USBRedirDevice *dev, uint8_t ep)
400 69354a83 Hans de Goede
{
401 69354a83 Hans de Goede
    struct usb_redir_stop_iso_stream_header stop_iso_stream = {
402 69354a83 Hans de Goede
        .endpoint = ep
403 69354a83 Hans de Goede
    };
404 69354a83 Hans de Goede
    if (dev->endpoint[EP2I(ep)].iso_started) {
405 69354a83 Hans de Goede
        usbredirparser_send_stop_iso_stream(dev->parser, 0, &stop_iso_stream);
406 69354a83 Hans de Goede
        DPRINTF("iso stream stopped ep %02X\n", ep);
407 69354a83 Hans de Goede
        dev->endpoint[EP2I(ep)].iso_started = 0;
408 69354a83 Hans de Goede
    }
409 69354a83 Hans de Goede
    usbredir_free_bufpq(dev, ep);
410 69354a83 Hans de Goede
}
411 69354a83 Hans de Goede
412 69354a83 Hans de Goede
static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
413 69354a83 Hans de Goede
                                      uint8_t ep)
414 69354a83 Hans de Goede
{
415 69354a83 Hans de Goede
    AsyncURB *aurb = async_alloc(dev, p);
416 69354a83 Hans de Goede
    struct usb_redir_bulk_packet_header bulk_packet;
417 69354a83 Hans de Goede
418 4f4321c1 Gerd Hoffmann
    DPRINTF("bulk-out ep %02X len %zd id %u\n", ep,
419 4f4321c1 Gerd Hoffmann
            p->iov.size, aurb->packet_id);
420 69354a83 Hans de Goede
421 69354a83 Hans de Goede
    bulk_packet.endpoint  = ep;
422 4f4321c1 Gerd Hoffmann
    bulk_packet.length    = p->iov.size;
423 69354a83 Hans de Goede
    bulk_packet.stream_id = 0;
424 69354a83 Hans de Goede
    aurb->bulk_packet = bulk_packet;
425 69354a83 Hans de Goede
426 69354a83 Hans de Goede
    if (ep & USB_DIR_IN) {
427 69354a83 Hans de Goede
        usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
428 69354a83 Hans de Goede
                                        &bulk_packet, NULL, 0);
429 69354a83 Hans de Goede
    } else {
430 4f4321c1 Gerd Hoffmann
        uint8_t buf[p->iov.size];
431 4f4321c1 Gerd Hoffmann
        usb_packet_copy(p, buf, p->iov.size);
432 4f4321c1 Gerd Hoffmann
        usbredir_log_data(dev, "bulk data out:", buf, p->iov.size);
433 69354a83 Hans de Goede
        usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
434 4f4321c1 Gerd Hoffmann
                                        &bulk_packet, buf, p->iov.size);
435 69354a83 Hans de Goede
    }
436 69354a83 Hans de Goede
    usbredirparser_do_write(dev->parser);
437 69354a83 Hans de Goede
    return USB_RET_ASYNC;
438 69354a83 Hans de Goede
}
439 69354a83 Hans de Goede
440 69354a83 Hans de Goede
static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
441 69354a83 Hans de Goede
                                           USBPacket *p, uint8_t ep)
442 69354a83 Hans de Goede
{
443 69354a83 Hans de Goede
    if (ep & USB_DIR_IN) {
444 69354a83 Hans de Goede
        /* Input interrupt endpoint, buffered packet input */
445 69354a83 Hans de Goede
        struct buf_packet *intp;
446 69354a83 Hans de Goede
        int status, len;
447 69354a83 Hans de Goede
448 69354a83 Hans de Goede
        if (!dev->endpoint[EP2I(ep)].interrupt_started &&
449 69354a83 Hans de Goede
                !dev->endpoint[EP2I(ep)].interrupt_error) {
450 69354a83 Hans de Goede
            struct usb_redir_start_interrupt_receiving_header start_int = {
451 69354a83 Hans de Goede
                .endpoint = ep,
452 69354a83 Hans de Goede
            };
453 69354a83 Hans de Goede
            /* No id, we look at the ep when receiving a status back */
454 69354a83 Hans de Goede
            usbredirparser_send_start_interrupt_receiving(dev->parser, 0,
455 69354a83 Hans de Goede
                                                          &start_int);
456 69354a83 Hans de Goede
            usbredirparser_do_write(dev->parser);
457 69354a83 Hans de Goede
            DPRINTF("interrupt recv started ep %02X\n", ep);
458 69354a83 Hans de Goede
            dev->endpoint[EP2I(ep)].interrupt_started = 1;
459 69354a83 Hans de Goede
        }
460 69354a83 Hans de Goede
461 69354a83 Hans de Goede
        intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
462 69354a83 Hans de Goede
        if (intp == NULL) {
463 69354a83 Hans de Goede
            DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep);
464 69354a83 Hans de Goede
            /* Check interrupt_error for stream errors */
465 69354a83 Hans de Goede
            status = dev->endpoint[EP2I(ep)].interrupt_error;
466 69354a83 Hans de Goede
            dev->endpoint[EP2I(ep)].interrupt_error = 0;
467 69354a83 Hans de Goede
            return usbredir_handle_status(dev, status, 0);
468 69354a83 Hans de Goede
        }
469 69354a83 Hans de Goede
        DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep,
470 69354a83 Hans de Goede
                intp->status, intp->len);
471 69354a83 Hans de Goede
472 69354a83 Hans de Goede
        status = intp->status;
473 69354a83 Hans de Goede
        if (status != usb_redir_success) {
474 69354a83 Hans de Goede
            bufp_free(dev, intp, ep);
475 69354a83 Hans de Goede
            return usbredir_handle_status(dev, status, 0);
476 69354a83 Hans de Goede
        }
477 69354a83 Hans de Goede
478 69354a83 Hans de Goede
        len = intp->len;
479 4f4321c1 Gerd Hoffmann
        if (len > p->iov.size) {
480 69354a83 Hans de Goede
            ERROR("received int data is larger then packet ep %02X\n", ep);
481 69354a83 Hans de Goede
            bufp_free(dev, intp, ep);
482 69354a83 Hans de Goede
            return USB_RET_NAK;
483 69354a83 Hans de Goede
        }
484 4f4321c1 Gerd Hoffmann
        usb_packet_copy(p, intp->data, len);
485 69354a83 Hans de Goede
        bufp_free(dev, intp, ep);
486 69354a83 Hans de Goede
        return len;
487 69354a83 Hans de Goede
    } else {
488 69354a83 Hans de Goede
        /* Output interrupt endpoint, normal async operation */
489 69354a83 Hans de Goede
        AsyncURB *aurb = async_alloc(dev, p);
490 69354a83 Hans de Goede
        struct usb_redir_interrupt_packet_header interrupt_packet;
491 4f4321c1 Gerd Hoffmann
        uint8_t buf[p->iov.size];
492 69354a83 Hans de Goede
493 4f4321c1 Gerd Hoffmann
        DPRINTF("interrupt-out ep %02X len %zd id %u\n", ep, p->iov.size,
494 69354a83 Hans de Goede
                aurb->packet_id);
495 69354a83 Hans de Goede
496 69354a83 Hans de Goede
        interrupt_packet.endpoint  = ep;
497 4f4321c1 Gerd Hoffmann
        interrupt_packet.length    = p->iov.size;
498 69354a83 Hans de Goede
        aurb->interrupt_packet     = interrupt_packet;
499 69354a83 Hans de Goede
500 4f4321c1 Gerd Hoffmann
        usb_packet_copy(p, buf, p->iov.size);
501 4f4321c1 Gerd Hoffmann
        usbredir_log_data(dev, "interrupt data out:", buf, p->iov.size);
502 69354a83 Hans de Goede
        usbredirparser_send_interrupt_packet(dev->parser, aurb->packet_id,
503 4f4321c1 Gerd Hoffmann
                                        &interrupt_packet, buf, p->iov.size);
504 69354a83 Hans de Goede
        usbredirparser_do_write(dev->parser);
505 69354a83 Hans de Goede
        return USB_RET_ASYNC;
506 69354a83 Hans de Goede
    }
507 69354a83 Hans de Goede
}
508 69354a83 Hans de Goede
509 69354a83 Hans de Goede
static void usbredir_stop_interrupt_receiving(USBRedirDevice *dev,
510 69354a83 Hans de Goede
    uint8_t ep)
511 69354a83 Hans de Goede
{
512 69354a83 Hans de Goede
    struct usb_redir_stop_interrupt_receiving_header stop_interrupt_recv = {
513 69354a83 Hans de Goede
        .endpoint = ep
514 69354a83 Hans de Goede
    };
515 69354a83 Hans de Goede
    if (dev->endpoint[EP2I(ep)].interrupt_started) {
516 69354a83 Hans de Goede
        usbredirparser_send_stop_interrupt_receiving(dev->parser, 0,
517 69354a83 Hans de Goede
                                                     &stop_interrupt_recv);
518 69354a83 Hans de Goede
        DPRINTF("interrupt recv stopped ep %02X\n", ep);
519 69354a83 Hans de Goede
        dev->endpoint[EP2I(ep)].interrupt_started = 0;
520 69354a83 Hans de Goede
    }
521 69354a83 Hans de Goede
    usbredir_free_bufpq(dev, ep);
522 69354a83 Hans de Goede
}
523 69354a83 Hans de Goede
524 69354a83 Hans de Goede
static int usbredir_handle_data(USBDevice *udev, USBPacket *p)
525 69354a83 Hans de Goede
{
526 69354a83 Hans de Goede
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
527 69354a83 Hans de Goede
    uint8_t ep;
528 69354a83 Hans de Goede
529 69354a83 Hans de Goede
    ep = p->devep;
530 69354a83 Hans de Goede
    if (p->pid == USB_TOKEN_IN) {
531 69354a83 Hans de Goede
        ep |= USB_DIR_IN;
532 69354a83 Hans de Goede
    }
533 69354a83 Hans de Goede
534 69354a83 Hans de Goede
    switch (dev->endpoint[EP2I(ep)].type) {
535 69354a83 Hans de Goede
    case USB_ENDPOINT_XFER_CONTROL:
536 69354a83 Hans de Goede
        ERROR("handle_data called for control transfer on ep %02X\n", ep);
537 69354a83 Hans de Goede
        return USB_RET_NAK;
538 69354a83 Hans de Goede
    case USB_ENDPOINT_XFER_ISOC:
539 69354a83 Hans de Goede
        return usbredir_handle_iso_data(dev, p, ep);
540 69354a83 Hans de Goede
    case USB_ENDPOINT_XFER_BULK:
541 69354a83 Hans de Goede
        return usbredir_handle_bulk_data(dev, p, ep);;
542 69354a83 Hans de Goede
    case USB_ENDPOINT_XFER_INT:
543 69354a83 Hans de Goede
        return usbredir_handle_interrupt_data(dev, p, ep);;
544 69354a83 Hans de Goede
    default:
545 69354a83 Hans de Goede
        ERROR("handle_data ep %02X has unknown type %d\n", ep,
546 69354a83 Hans de Goede
              dev->endpoint[EP2I(ep)].type);
547 69354a83 Hans de Goede
        return USB_RET_NAK;
548 69354a83 Hans de Goede
    }
549 69354a83 Hans de Goede
}
550 69354a83 Hans de Goede
551 69354a83 Hans de Goede
static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
552 69354a83 Hans de Goede
                                int config)
553 69354a83 Hans de Goede
{
554 69354a83 Hans de Goede
    struct usb_redir_set_configuration_header set_config;
555 69354a83 Hans de Goede
    AsyncURB *aurb = async_alloc(dev, p);
556 69354a83 Hans de Goede
    int i;
557 69354a83 Hans de Goede
558 69354a83 Hans de Goede
    DPRINTF("set config %d id %u\n", config, aurb->packet_id);
559 69354a83 Hans de Goede
560 69354a83 Hans de Goede
    for (i = 0; i < MAX_ENDPOINTS; i++) {
561 69354a83 Hans de Goede
        switch (dev->endpoint[i].type) {
562 69354a83 Hans de Goede
        case USB_ENDPOINT_XFER_ISOC:
563 69354a83 Hans de Goede
            usbredir_stop_iso_stream(dev, I2EP(i));
564 69354a83 Hans de Goede
            break;
565 69354a83 Hans de Goede
        case USB_ENDPOINT_XFER_INT:
566 69354a83 Hans de Goede
            if (i & 0x10) {
567 69354a83 Hans de Goede
                usbredir_stop_interrupt_receiving(dev, I2EP(i));
568 69354a83 Hans de Goede
            }
569 69354a83 Hans de Goede
            break;
570 69354a83 Hans de Goede
        }
571 69354a83 Hans de Goede
        usbredir_free_bufpq(dev, I2EP(i));
572 69354a83 Hans de Goede
    }
573 69354a83 Hans de Goede
574 69354a83 Hans de Goede
    set_config.configuration = config;
575 69354a83 Hans de Goede
    usbredirparser_send_set_configuration(dev->parser, aurb->packet_id,
576 69354a83 Hans de Goede
                                          &set_config);
577 69354a83 Hans de Goede
    usbredirparser_do_write(dev->parser);
578 69354a83 Hans de Goede
    return USB_RET_ASYNC;
579 69354a83 Hans de Goede
}
580 69354a83 Hans de Goede
581 69354a83 Hans de Goede
static int usbredir_get_config(USBRedirDevice *dev, USBPacket *p)
582 69354a83 Hans de Goede
{
583 69354a83 Hans de Goede
    AsyncURB *aurb = async_alloc(dev, p);
584 69354a83 Hans de Goede
585 69354a83 Hans de Goede
    DPRINTF("get config id %u\n", aurb->packet_id);
586 69354a83 Hans de Goede
587 69354a83 Hans de Goede
    aurb->get = 1;
588 69354a83 Hans de Goede
    usbredirparser_send_get_configuration(dev->parser, aurb->packet_id);
589 69354a83 Hans de Goede
    usbredirparser_do_write(dev->parser);
590 69354a83 Hans de Goede
    return USB_RET_ASYNC;
591 69354a83 Hans de Goede
}
592 69354a83 Hans de Goede
593 69354a83 Hans de Goede
static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
594 69354a83 Hans de Goede
                                   int interface, int alt)
595 69354a83 Hans de Goede
{
596 69354a83 Hans de Goede
    struct usb_redir_set_alt_setting_header set_alt;
597 69354a83 Hans de Goede
    AsyncURB *aurb = async_alloc(dev, p);
598 69354a83 Hans de Goede
    int i;
599 69354a83 Hans de Goede
600 69354a83 Hans de Goede
    DPRINTF("set interface %d alt %d id %u\n", interface, alt,
601 69354a83 Hans de Goede
            aurb->packet_id);
602 69354a83 Hans de Goede
603 69354a83 Hans de Goede
    for (i = 0; i < MAX_ENDPOINTS; i++) {
604 69354a83 Hans de Goede
        if (dev->endpoint[i].interface == interface) {
605 69354a83 Hans de Goede
            switch (dev->endpoint[i].type) {
606 69354a83 Hans de Goede
            case USB_ENDPOINT_XFER_ISOC:
607 69354a83 Hans de Goede
                usbredir_stop_iso_stream(dev, I2EP(i));
608 69354a83 Hans de Goede
                break;
609 69354a83 Hans de Goede
            case USB_ENDPOINT_XFER_INT:
610 69354a83 Hans de Goede
                if (i & 0x10) {
611 69354a83 Hans de Goede
                    usbredir_stop_interrupt_receiving(dev, I2EP(i));
612 69354a83 Hans de Goede
                }
613 69354a83 Hans de Goede
                break;
614 69354a83 Hans de Goede
            }
615 69354a83 Hans de Goede
            usbredir_free_bufpq(dev, I2EP(i));
616 69354a83 Hans de Goede
        }
617 69354a83 Hans de Goede
    }
618 69354a83 Hans de Goede
619 69354a83 Hans de Goede
    set_alt.interface = interface;
620 69354a83 Hans de Goede
    set_alt.alt = alt;
621 69354a83 Hans de Goede
    usbredirparser_send_set_alt_setting(dev->parser, aurb->packet_id,
622 69354a83 Hans de Goede
                                        &set_alt);
623 69354a83 Hans de Goede
    usbredirparser_do_write(dev->parser);
624 69354a83 Hans de Goede
    return USB_RET_ASYNC;
625 69354a83 Hans de Goede
}
626 69354a83 Hans de Goede
627 69354a83 Hans de Goede
static int usbredir_get_interface(USBRedirDevice *dev, USBPacket *p,
628 69354a83 Hans de Goede
                                   int interface)
629 69354a83 Hans de Goede
{
630 69354a83 Hans de Goede
    struct usb_redir_get_alt_setting_header get_alt;
631 69354a83 Hans de Goede
    AsyncURB *aurb = async_alloc(dev, p);
632 69354a83 Hans de Goede
633 69354a83 Hans de Goede
    DPRINTF("get interface %d id %u\n", interface, aurb->packet_id);
634 69354a83 Hans de Goede
635 69354a83 Hans de Goede
    get_alt.interface = interface;
636 69354a83 Hans de Goede
    aurb->get = 1;
637 69354a83 Hans de Goede
    usbredirparser_send_get_alt_setting(dev->parser, aurb->packet_id,
638 69354a83 Hans de Goede
                                        &get_alt);
639 69354a83 Hans de Goede
    usbredirparser_do_write(dev->parser);
640 69354a83 Hans de Goede
    return USB_RET_ASYNC;
641 69354a83 Hans de Goede
}
642 69354a83 Hans de Goede
643 69354a83 Hans de Goede
static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
644 69354a83 Hans de Goede
        int request, int value, int index, int length, uint8_t *data)
645 69354a83 Hans de Goede
{
646 69354a83 Hans de Goede
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
647 69354a83 Hans de Goede
    struct usb_redir_control_packet_header control_packet;
648 69354a83 Hans de Goede
    AsyncURB *aurb;
649 69354a83 Hans de Goede
650 69354a83 Hans de Goede
    /* Special cases for certain standard device requests */
651 69354a83 Hans de Goede
    switch (request) {
652 69354a83 Hans de Goede
    case DeviceOutRequest | USB_REQ_SET_ADDRESS:
653 69354a83 Hans de Goede
        DPRINTF("set address %d\n", value);
654 69354a83 Hans de Goede
        dev->dev.addr = value;
655 69354a83 Hans de Goede
        return 0;
656 69354a83 Hans de Goede
    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
657 69354a83 Hans de Goede
        return usbredir_set_config(dev, p, value & 0xff);
658 69354a83 Hans de Goede
    case DeviceRequest | USB_REQ_GET_CONFIGURATION:
659 69354a83 Hans de Goede
        return usbredir_get_config(dev, p);
660 69354a83 Hans de Goede
    case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
661 69354a83 Hans de Goede
        return usbredir_set_interface(dev, p, index, value);
662 69354a83 Hans de Goede
    case InterfaceRequest | USB_REQ_GET_INTERFACE:
663 69354a83 Hans de Goede
        return usbredir_get_interface(dev, p, index);
664 69354a83 Hans de Goede
    }
665 69354a83 Hans de Goede
666 69354a83 Hans de Goede
    /* "Normal" ctrl requests */
667 69354a83 Hans de Goede
    aurb = async_alloc(dev, p);
668 69354a83 Hans de Goede
669 69354a83 Hans de Goede
    /* Note request is (bRequestType << 8) | bRequest */
670 69354a83 Hans de Goede
    DPRINTF("ctrl-out type 0x%x req 0x%x val 0x%x index %d len %d id %u\n",
671 69354a83 Hans de Goede
            request >> 8, request & 0xff, value, index, length,
672 69354a83 Hans de Goede
            aurb->packet_id);
673 69354a83 Hans de Goede
674 69354a83 Hans de Goede
    control_packet.request     = request & 0xFF;
675 69354a83 Hans de Goede
    control_packet.requesttype = request >> 8;
676 69354a83 Hans de Goede
    control_packet.endpoint    = control_packet.requesttype & USB_DIR_IN;
677 69354a83 Hans de Goede
    control_packet.value       = value;
678 69354a83 Hans de Goede
    control_packet.index       = index;
679 69354a83 Hans de Goede
    control_packet.length      = length;
680 69354a83 Hans de Goede
    aurb->control_packet       = control_packet;
681 69354a83 Hans de Goede
682 69354a83 Hans de Goede
    if (control_packet.requesttype & USB_DIR_IN) {
683 69354a83 Hans de Goede
        usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
684 69354a83 Hans de Goede
                                           &control_packet, NULL, 0);
685 69354a83 Hans de Goede
    } else {
686 69354a83 Hans de Goede
        usbredir_log_data(dev, "ctrl data out:", data, length);
687 69354a83 Hans de Goede
        usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
688 69354a83 Hans de Goede
                                           &control_packet, data, length);
689 69354a83 Hans de Goede
    }
690 69354a83 Hans de Goede
    usbredirparser_do_write(dev->parser);
691 69354a83 Hans de Goede
    return USB_RET_ASYNC;
692 69354a83 Hans de Goede
}
693 69354a83 Hans de Goede
694 69354a83 Hans de Goede
/*
695 69354a83 Hans de Goede
 * Close events can be triggered by usbredirparser_do_write which gets called
696 69354a83 Hans de Goede
 * from within the USBDevice data / control packet callbacks and doing a
697 69354a83 Hans de Goede
 * usb_detach from within these callbacks is not a good idea.
698 69354a83 Hans de Goede
 *
699 69354a83 Hans de Goede
 * So we use a bh handler to take care of close events. We also handle
700 69354a83 Hans de Goede
 * open events from this callback to make sure that a close directly followed
701 69354a83 Hans de Goede
 * by an open gets handled in the right order.
702 69354a83 Hans de Goede
 */
703 69354a83 Hans de Goede
static void usbredir_open_close_bh(void *opaque)
704 69354a83 Hans de Goede
{
705 69354a83 Hans de Goede
    USBRedirDevice *dev = opaque;
706 69354a83 Hans de Goede
707 69354a83 Hans de Goede
    usbredir_device_disconnect(dev);
708 69354a83 Hans de Goede
709 69354a83 Hans de Goede
    if (dev->parser) {
710 69354a83 Hans de Goede
        usbredirparser_destroy(dev->parser);
711 69354a83 Hans de Goede
        dev->parser = NULL;
712 69354a83 Hans de Goede
    }
713 69354a83 Hans de Goede
714 69354a83 Hans de Goede
    if (dev->cs->opened) {
715 69354a83 Hans de Goede
        dev->parser = qemu_oom_check(usbredirparser_create());
716 69354a83 Hans de Goede
        dev->parser->priv = dev;
717 69354a83 Hans de Goede
        dev->parser->log_func = usbredir_log;
718 69354a83 Hans de Goede
        dev->parser->read_func = usbredir_read;
719 69354a83 Hans de Goede
        dev->parser->write_func = usbredir_write;
720 69354a83 Hans de Goede
        dev->parser->device_connect_func = usbredir_device_connect;
721 69354a83 Hans de Goede
        dev->parser->device_disconnect_func = usbredir_device_disconnect;
722 69354a83 Hans de Goede
        dev->parser->interface_info_func = usbredir_interface_info;
723 69354a83 Hans de Goede
        dev->parser->ep_info_func = usbredir_ep_info;
724 69354a83 Hans de Goede
        dev->parser->configuration_status_func = usbredir_configuration_status;
725 69354a83 Hans de Goede
        dev->parser->alt_setting_status_func = usbredir_alt_setting_status;
726 69354a83 Hans de Goede
        dev->parser->iso_stream_status_func = usbredir_iso_stream_status;
727 69354a83 Hans de Goede
        dev->parser->interrupt_receiving_status_func =
728 69354a83 Hans de Goede
            usbredir_interrupt_receiving_status;
729 69354a83 Hans de Goede
        dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
730 69354a83 Hans de Goede
        dev->parser->control_packet_func = usbredir_control_packet;
731 69354a83 Hans de Goede
        dev->parser->bulk_packet_func = usbredir_bulk_packet;
732 69354a83 Hans de Goede
        dev->parser->iso_packet_func = usbredir_iso_packet;
733 69354a83 Hans de Goede
        dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
734 69354a83 Hans de Goede
        dev->read_buf = NULL;
735 69354a83 Hans de Goede
        dev->read_buf_size = 0;
736 69354a83 Hans de Goede
        usbredirparser_init(dev->parser, VERSION, NULL, 0, 0);
737 69354a83 Hans de Goede
        usbredirparser_do_write(dev->parser);
738 69354a83 Hans de Goede
    }
739 69354a83 Hans de Goede
}
740 69354a83 Hans de Goede
741 69354a83 Hans de Goede
static void usbredir_do_attach(void *opaque)
742 69354a83 Hans de Goede
{
743 69354a83 Hans de Goede
    USBRedirDevice *dev = opaque;
744 69354a83 Hans de Goede
745 69354a83 Hans de Goede
    usb_device_attach(&dev->dev);
746 69354a83 Hans de Goede
}
747 69354a83 Hans de Goede
748 69354a83 Hans de Goede
/*
749 69354a83 Hans de Goede
 * chardev callbacks
750 69354a83 Hans de Goede
 */
751 69354a83 Hans de Goede
752 69354a83 Hans de Goede
static int usbredir_chardev_can_read(void *opaque)
753 69354a83 Hans de Goede
{
754 69354a83 Hans de Goede
    USBRedirDevice *dev = opaque;
755 69354a83 Hans de Goede
756 69354a83 Hans de Goede
    if (dev->parser) {
757 69354a83 Hans de Goede
        /* usbredir_parser_do_read will consume *all* data we give it */
758 69354a83 Hans de Goede
        return 1024 * 1024;
759 69354a83 Hans de Goede
    } else {
760 69354a83 Hans de Goede
        /* usbredir_open_close_bh hasn't handled the open event yet */
761 69354a83 Hans de Goede
        return 0;
762 69354a83 Hans de Goede
    }
763 69354a83 Hans de Goede
}
764 69354a83 Hans de Goede
765 69354a83 Hans de Goede
static void usbredir_chardev_read(void *opaque, const uint8_t *buf, int size)
766 69354a83 Hans de Goede
{
767 69354a83 Hans de Goede
    USBRedirDevice *dev = opaque;
768 69354a83 Hans de Goede
769 69354a83 Hans de Goede
    /* No recursion allowed! */
770 69354a83 Hans de Goede
    assert(dev->read_buf == NULL);
771 69354a83 Hans de Goede
772 69354a83 Hans de Goede
    dev->read_buf = buf;
773 69354a83 Hans de Goede
    dev->read_buf_size = size;
774 69354a83 Hans de Goede
775 69354a83 Hans de Goede
    usbredirparser_do_read(dev->parser);
776 69354a83 Hans de Goede
    /* Send any acks, etc. which may be queued now */
777 69354a83 Hans de Goede
    usbredirparser_do_write(dev->parser);
778 69354a83 Hans de Goede
}
779 69354a83 Hans de Goede
780 69354a83 Hans de Goede
static void usbredir_chardev_event(void *opaque, int event)
781 69354a83 Hans de Goede
{
782 69354a83 Hans de Goede
    USBRedirDevice *dev = opaque;
783 69354a83 Hans de Goede
784 69354a83 Hans de Goede
    switch (event) {
785 69354a83 Hans de Goede
    case CHR_EVENT_OPENED:
786 69354a83 Hans de Goede
    case CHR_EVENT_CLOSED:
787 69354a83 Hans de Goede
        qemu_bh_schedule(dev->open_close_bh);
788 69354a83 Hans de Goede
        break;
789 69354a83 Hans de Goede
    }
790 69354a83 Hans de Goede
}
791 69354a83 Hans de Goede
792 69354a83 Hans de Goede
/*
793 69354a83 Hans de Goede
 * init + destroy
794 69354a83 Hans de Goede
 */
795 69354a83 Hans de Goede
796 69354a83 Hans de Goede
static int usbredir_initfn(USBDevice *udev)
797 69354a83 Hans de Goede
{
798 69354a83 Hans de Goede
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
799 69354a83 Hans de Goede
    int i;
800 69354a83 Hans de Goede
801 69354a83 Hans de Goede
    if (dev->cs == NULL) {
802 69354a83 Hans de Goede
        qerror_report(QERR_MISSING_PARAMETER, "chardev");
803 69354a83 Hans de Goede
        return -1;
804 69354a83 Hans de Goede
    }
805 69354a83 Hans de Goede
806 69354a83 Hans de Goede
    dev->open_close_bh = qemu_bh_new(usbredir_open_close_bh, dev);
807 69354a83 Hans de Goede
    dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
808 69354a83 Hans de Goede
809 69354a83 Hans de Goede
    QTAILQ_INIT(&dev->asyncq);
810 69354a83 Hans de Goede
    for (i = 0; i < MAX_ENDPOINTS; i++) {
811 69354a83 Hans de Goede
        QTAILQ_INIT(&dev->endpoint[i].bufpq);
812 69354a83 Hans de Goede
    }
813 69354a83 Hans de Goede
814 69354a83 Hans de Goede
    /* We'll do the attach once we receive the speed from the usb-host */
815 69354a83 Hans de Goede
    udev->auto_attach = 0;
816 69354a83 Hans de Goede
817 69354a83 Hans de Goede
    qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
818 69354a83 Hans de Goede
                          usbredir_chardev_read, usbredir_chardev_event, dev);
819 69354a83 Hans de Goede
820 69354a83 Hans de Goede
    return 0;
821 69354a83 Hans de Goede
}
822 69354a83 Hans de Goede
823 69354a83 Hans de Goede
static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
824 69354a83 Hans de Goede
{
825 69354a83 Hans de Goede
    AsyncURB *aurb, *next_aurb;
826 69354a83 Hans de Goede
    int i;
827 69354a83 Hans de Goede
828 69354a83 Hans de Goede
    QTAILQ_FOREACH_SAFE(aurb, &dev->asyncq, next, next_aurb) {
829 69354a83 Hans de Goede
        async_free(dev, aurb);
830 69354a83 Hans de Goede
    }
831 69354a83 Hans de Goede
    for (i = 0; i < MAX_ENDPOINTS; i++) {
832 69354a83 Hans de Goede
        usbredir_free_bufpq(dev, I2EP(i));
833 69354a83 Hans de Goede
    }
834 69354a83 Hans de Goede
}
835 69354a83 Hans de Goede
836 69354a83 Hans de Goede
static void usbredir_handle_destroy(USBDevice *udev)
837 69354a83 Hans de Goede
{
838 69354a83 Hans de Goede
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
839 69354a83 Hans de Goede
840 70f24fb6 Anthony Liguori
    qemu_chr_delete(dev->cs);
841 69354a83 Hans de Goede
    /* Note must be done after qemu_chr_close, as that causes a close event */
842 69354a83 Hans de Goede
    qemu_bh_delete(dev->open_close_bh);
843 69354a83 Hans de Goede
844 69354a83 Hans de Goede
    qemu_del_timer(dev->attach_timer);
845 69354a83 Hans de Goede
    qemu_free_timer(dev->attach_timer);
846 69354a83 Hans de Goede
847 69354a83 Hans de Goede
    usbredir_cleanup_device_queues(dev);
848 69354a83 Hans de Goede
849 69354a83 Hans de Goede
    if (dev->parser) {
850 69354a83 Hans de Goede
        usbredirparser_destroy(dev->parser);
851 69354a83 Hans de Goede
    }
852 69354a83 Hans de Goede
}
853 69354a83 Hans de Goede
854 69354a83 Hans de Goede
/*
855 69354a83 Hans de Goede
 * usbredirparser packet complete callbacks
856 69354a83 Hans de Goede
 */
857 69354a83 Hans de Goede
858 69354a83 Hans de Goede
static int usbredir_handle_status(USBRedirDevice *dev,
859 69354a83 Hans de Goede
                                       int status, int actual_len)
860 69354a83 Hans de Goede
{
861 69354a83 Hans de Goede
    switch (status) {
862 69354a83 Hans de Goede
    case usb_redir_success:
863 69354a83 Hans de Goede
        return actual_len;
864 69354a83 Hans de Goede
    case usb_redir_stall:
865 69354a83 Hans de Goede
        return USB_RET_STALL;
866 69354a83 Hans de Goede
    case usb_redir_cancelled:
867 69354a83 Hans de Goede
        WARNING("returning cancelled packet to HC?\n");
868 69354a83 Hans de Goede
    case usb_redir_inval:
869 69354a83 Hans de Goede
    case usb_redir_ioerror:
870 69354a83 Hans de Goede
    case usb_redir_timeout:
871 69354a83 Hans de Goede
    default:
872 69354a83 Hans de Goede
        return USB_RET_NAK;
873 69354a83 Hans de Goede
    }
874 69354a83 Hans de Goede
}
875 69354a83 Hans de Goede
876 69354a83 Hans de Goede
static void usbredir_device_connect(void *priv,
877 69354a83 Hans de Goede
    struct usb_redir_device_connect_header *device_connect)
878 69354a83 Hans de Goede
{
879 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
880 69354a83 Hans de Goede
881 69354a83 Hans de Goede
    switch (device_connect->speed) {
882 69354a83 Hans de Goede
    case usb_redir_speed_low:
883 69354a83 Hans de Goede
        DPRINTF("attaching low speed device\n");
884 69354a83 Hans de Goede
        dev->dev.speed = USB_SPEED_LOW;
885 69354a83 Hans de Goede
        break;
886 69354a83 Hans de Goede
    case usb_redir_speed_full:
887 69354a83 Hans de Goede
        DPRINTF("attaching full speed device\n");
888 69354a83 Hans de Goede
        dev->dev.speed = USB_SPEED_FULL;
889 69354a83 Hans de Goede
        break;
890 69354a83 Hans de Goede
    case usb_redir_speed_high:
891 69354a83 Hans de Goede
        DPRINTF("attaching high speed device\n");
892 69354a83 Hans de Goede
        dev->dev.speed = USB_SPEED_HIGH;
893 69354a83 Hans de Goede
        break;
894 69354a83 Hans de Goede
    case usb_redir_speed_super:
895 69354a83 Hans de Goede
        DPRINTF("attaching super speed device\n");
896 69354a83 Hans de Goede
        dev->dev.speed = USB_SPEED_SUPER;
897 69354a83 Hans de Goede
        break;
898 69354a83 Hans de Goede
    default:
899 69354a83 Hans de Goede
        DPRINTF("attaching unknown speed device, assuming full speed\n");
900 69354a83 Hans de Goede
        dev->dev.speed = USB_SPEED_FULL;
901 69354a83 Hans de Goede
    }
902 69354a83 Hans de Goede
    dev->dev.speedmask = (1 << dev->dev.speed);
903 69354a83 Hans de Goede
    qemu_mod_timer(dev->attach_timer, dev->next_attach_time);
904 69354a83 Hans de Goede
}
905 69354a83 Hans de Goede
906 69354a83 Hans de Goede
static void usbredir_device_disconnect(void *priv)
907 69354a83 Hans de Goede
{
908 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
909 69354a83 Hans de Goede
910 69354a83 Hans de Goede
    /* Stop any pending attaches */
911 69354a83 Hans de Goede
    qemu_del_timer(dev->attach_timer);
912 69354a83 Hans de Goede
913 69354a83 Hans de Goede
    if (dev->dev.attached) {
914 69354a83 Hans de Goede
        usb_device_detach(&dev->dev);
915 69354a83 Hans de Goede
        usbredir_cleanup_device_queues(dev);
916 69354a83 Hans de Goede
        /*
917 69354a83 Hans de Goede
         * Delay next usb device attach to give the guest a chance to see
918 69354a83 Hans de Goede
         * see the detach / attach in case of quick close / open succession
919 69354a83 Hans de Goede
         */
920 69354a83 Hans de Goede
        dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;
921 69354a83 Hans de Goede
    }
922 69354a83 Hans de Goede
}
923 69354a83 Hans de Goede
924 69354a83 Hans de Goede
static void usbredir_interface_info(void *priv,
925 69354a83 Hans de Goede
    struct usb_redir_interface_info_header *interface_info)
926 69354a83 Hans de Goede
{
927 69354a83 Hans de Goede
    /* The intention is to allow specifying acceptable interface classes
928 69354a83 Hans de Goede
       for redirection on the cmdline and in the future verify this here,
929 69354a83 Hans de Goede
       and disconnect (or never connect) the device if a not accepted
930 69354a83 Hans de Goede
       interface class is detected */
931 69354a83 Hans de Goede
}
932 69354a83 Hans de Goede
933 69354a83 Hans de Goede
static void usbredir_ep_info(void *priv,
934 69354a83 Hans de Goede
    struct usb_redir_ep_info_header *ep_info)
935 69354a83 Hans de Goede
{
936 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
937 69354a83 Hans de Goede
    int i;
938 69354a83 Hans de Goede
939 69354a83 Hans de Goede
    for (i = 0; i < MAX_ENDPOINTS; i++) {
940 69354a83 Hans de Goede
        dev->endpoint[i].type = ep_info->type[i];
941 69354a83 Hans de Goede
        dev->endpoint[i].interval = ep_info->interval[i];
942 69354a83 Hans de Goede
        dev->endpoint[i].interface = ep_info->interface[i];
943 69354a83 Hans de Goede
        if (dev->endpoint[i].type != usb_redir_type_invalid) {
944 69354a83 Hans de Goede
            DPRINTF("ep: %02X type: %d interface: %d\n", I2EP(i),
945 69354a83 Hans de Goede
                    dev->endpoint[i].type, dev->endpoint[i].interface);
946 69354a83 Hans de Goede
        }
947 69354a83 Hans de Goede
    }
948 69354a83 Hans de Goede
}
949 69354a83 Hans de Goede
950 69354a83 Hans de Goede
static void usbredir_configuration_status(void *priv, uint32_t id,
951 69354a83 Hans de Goede
    struct usb_redir_configuration_status_header *config_status)
952 69354a83 Hans de Goede
{
953 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
954 69354a83 Hans de Goede
    AsyncURB *aurb;
955 69354a83 Hans de Goede
    int len = 0;
956 69354a83 Hans de Goede
957 69354a83 Hans de Goede
    DPRINTF("set config status %d config %d id %u\n", config_status->status,
958 69354a83 Hans de Goede
            config_status->configuration, id);
959 69354a83 Hans de Goede
960 69354a83 Hans de Goede
    aurb = async_find(dev, id);
961 69354a83 Hans de Goede
    if (!aurb) {
962 69354a83 Hans de Goede
        return;
963 69354a83 Hans de Goede
    }
964 69354a83 Hans de Goede
    if (aurb->packet) {
965 69354a83 Hans de Goede
        if (aurb->get) {
966 69354a83 Hans de Goede
            dev->dev.data_buf[0] = config_status->configuration;
967 69354a83 Hans de Goede
            len = 1;
968 69354a83 Hans de Goede
        }
969 4f4321c1 Gerd Hoffmann
        aurb->packet->result =
970 69354a83 Hans de Goede
            usbredir_handle_status(dev, config_status->status, len);
971 69354a83 Hans de Goede
        usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
972 69354a83 Hans de Goede
    }
973 69354a83 Hans de Goede
    async_free(dev, aurb);
974 69354a83 Hans de Goede
}
975 69354a83 Hans de Goede
976 69354a83 Hans de Goede
static void usbredir_alt_setting_status(void *priv, uint32_t id,
977 69354a83 Hans de Goede
    struct usb_redir_alt_setting_status_header *alt_setting_status)
978 69354a83 Hans de Goede
{
979 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
980 69354a83 Hans de Goede
    AsyncURB *aurb;
981 69354a83 Hans de Goede
    int len = 0;
982 69354a83 Hans de Goede
983 69354a83 Hans de Goede
    DPRINTF("alt status %d intf %d alt %d id: %u\n",
984 69354a83 Hans de Goede
            alt_setting_status->status,
985 69354a83 Hans de Goede
            alt_setting_status->interface,
986 69354a83 Hans de Goede
            alt_setting_status->alt, id);
987 69354a83 Hans de Goede
988 69354a83 Hans de Goede
    aurb = async_find(dev, id);
989 69354a83 Hans de Goede
    if (!aurb) {
990 69354a83 Hans de Goede
        return;
991 69354a83 Hans de Goede
    }
992 69354a83 Hans de Goede
    if (aurb->packet) {
993 69354a83 Hans de Goede
        if (aurb->get) {
994 69354a83 Hans de Goede
            dev->dev.data_buf[0] = alt_setting_status->alt;
995 69354a83 Hans de Goede
            len = 1;
996 69354a83 Hans de Goede
        }
997 4f4321c1 Gerd Hoffmann
        aurb->packet->result =
998 69354a83 Hans de Goede
            usbredir_handle_status(dev, alt_setting_status->status, len);
999 69354a83 Hans de Goede
        usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1000 69354a83 Hans de Goede
    }
1001 69354a83 Hans de Goede
    async_free(dev, aurb);
1002 69354a83 Hans de Goede
}
1003 69354a83 Hans de Goede
1004 69354a83 Hans de Goede
static void usbredir_iso_stream_status(void *priv, uint32_t id,
1005 69354a83 Hans de Goede
    struct usb_redir_iso_stream_status_header *iso_stream_status)
1006 69354a83 Hans de Goede
{
1007 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
1008 69354a83 Hans de Goede
    uint8_t ep = iso_stream_status->endpoint;
1009 69354a83 Hans de Goede
1010 69354a83 Hans de Goede
    DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status,
1011 69354a83 Hans de Goede
            ep, id);
1012 69354a83 Hans de Goede
1013 69354a83 Hans de Goede
    dev->endpoint[EP2I(ep)].iso_error = iso_stream_status->status;
1014 69354a83 Hans de Goede
    if (iso_stream_status->status == usb_redir_stall) {
1015 69354a83 Hans de Goede
        DPRINTF("iso stream stopped by peer ep %02X\n", ep);
1016 69354a83 Hans de Goede
        dev->endpoint[EP2I(ep)].iso_started = 0;
1017 69354a83 Hans de Goede
    }
1018 69354a83 Hans de Goede
}
1019 69354a83 Hans de Goede
1020 69354a83 Hans de Goede
static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
1021 69354a83 Hans de Goede
    struct usb_redir_interrupt_receiving_status_header
1022 69354a83 Hans de Goede
    *interrupt_receiving_status)
1023 69354a83 Hans de Goede
{
1024 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
1025 69354a83 Hans de Goede
    uint8_t ep = interrupt_receiving_status->endpoint;
1026 69354a83 Hans de Goede
1027 69354a83 Hans de Goede
    DPRINTF("interrupt recv status %d ep %02X id %u\n",
1028 69354a83 Hans de Goede
            interrupt_receiving_status->status, ep, id);
1029 69354a83 Hans de Goede
1030 69354a83 Hans de Goede
    dev->endpoint[EP2I(ep)].interrupt_error =
1031 69354a83 Hans de Goede
        interrupt_receiving_status->status;
1032 69354a83 Hans de Goede
    if (interrupt_receiving_status->status == usb_redir_stall) {
1033 69354a83 Hans de Goede
        DPRINTF("interrupt receiving stopped by peer ep %02X\n", ep);
1034 69354a83 Hans de Goede
        dev->endpoint[EP2I(ep)].interrupt_started = 0;
1035 69354a83 Hans de Goede
    }
1036 69354a83 Hans de Goede
}
1037 69354a83 Hans de Goede
1038 69354a83 Hans de Goede
static void usbredir_bulk_streams_status(void *priv, uint32_t id,
1039 69354a83 Hans de Goede
    struct usb_redir_bulk_streams_status_header *bulk_streams_status)
1040 69354a83 Hans de Goede
{
1041 69354a83 Hans de Goede
}
1042 69354a83 Hans de Goede
1043 69354a83 Hans de Goede
static void usbredir_control_packet(void *priv, uint32_t id,
1044 69354a83 Hans de Goede
    struct usb_redir_control_packet_header *control_packet,
1045 69354a83 Hans de Goede
    uint8_t *data, int data_len)
1046 69354a83 Hans de Goede
{
1047 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
1048 69354a83 Hans de Goede
    int len = control_packet->length;
1049 69354a83 Hans de Goede
    AsyncURB *aurb;
1050 69354a83 Hans de Goede
1051 69354a83 Hans de Goede
    DPRINTF("ctrl-in status %d len %d id %u\n", control_packet->status,
1052 69354a83 Hans de Goede
            len, id);
1053 69354a83 Hans de Goede
1054 69354a83 Hans de Goede
    aurb = async_find(dev, id);
1055 69354a83 Hans de Goede
    if (!aurb) {
1056 69354a83 Hans de Goede
        free(data);
1057 69354a83 Hans de Goede
        return;
1058 69354a83 Hans de Goede
    }
1059 69354a83 Hans de Goede
1060 69354a83 Hans de Goede
    aurb->control_packet.status = control_packet->status;
1061 69354a83 Hans de Goede
    aurb->control_packet.length = control_packet->length;
1062 69354a83 Hans de Goede
    if (memcmp(&aurb->control_packet, control_packet,
1063 69354a83 Hans de Goede
               sizeof(*control_packet))) {
1064 69354a83 Hans de Goede
        ERROR("return control packet mismatch, please report this!\n");
1065 69354a83 Hans de Goede
        len = USB_RET_NAK;
1066 69354a83 Hans de Goede
    }
1067 69354a83 Hans de Goede
1068 69354a83 Hans de Goede
    if (aurb->packet) {
1069 69354a83 Hans de Goede
        len = usbredir_handle_status(dev, control_packet->status, len);
1070 69354a83 Hans de Goede
        if (len > 0) {
1071 69354a83 Hans de Goede
            usbredir_log_data(dev, "ctrl data in:", data, data_len);
1072 69354a83 Hans de Goede
            if (data_len <= sizeof(dev->dev.data_buf)) {
1073 69354a83 Hans de Goede
                memcpy(dev->dev.data_buf, data, data_len);
1074 69354a83 Hans de Goede
            } else {
1075 69354a83 Hans de Goede
                ERROR("ctrl buffer too small (%d > %zu)\n",
1076 69354a83 Hans de Goede
                      data_len, sizeof(dev->dev.data_buf));
1077 69354a83 Hans de Goede
                len = USB_RET_STALL;
1078 69354a83 Hans de Goede
            }
1079 69354a83 Hans de Goede
        }
1080 4f4321c1 Gerd Hoffmann
        aurb->packet->result = len;
1081 69354a83 Hans de Goede
        usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1082 69354a83 Hans de Goede
    }
1083 69354a83 Hans de Goede
    async_free(dev, aurb);
1084 69354a83 Hans de Goede
    free(data);
1085 69354a83 Hans de Goede
}
1086 69354a83 Hans de Goede
1087 69354a83 Hans de Goede
static void usbredir_bulk_packet(void *priv, uint32_t id,
1088 69354a83 Hans de Goede
    struct usb_redir_bulk_packet_header *bulk_packet,
1089 69354a83 Hans de Goede
    uint8_t *data, int data_len)
1090 69354a83 Hans de Goede
{
1091 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
1092 69354a83 Hans de Goede
    uint8_t ep = bulk_packet->endpoint;
1093 69354a83 Hans de Goede
    int len = bulk_packet->length;
1094 69354a83 Hans de Goede
    AsyncURB *aurb;
1095 69354a83 Hans de Goede
1096 69354a83 Hans de Goede
    DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet->status,
1097 69354a83 Hans de Goede
            ep, len, id);
1098 69354a83 Hans de Goede
1099 69354a83 Hans de Goede
    aurb = async_find(dev, id);
1100 69354a83 Hans de Goede
    if (!aurb) {
1101 69354a83 Hans de Goede
        free(data);
1102 69354a83 Hans de Goede
        return;
1103 69354a83 Hans de Goede
    }
1104 69354a83 Hans de Goede
1105 69354a83 Hans de Goede
    if (aurb->bulk_packet.endpoint != bulk_packet->endpoint ||
1106 69354a83 Hans de Goede
            aurb->bulk_packet.stream_id != bulk_packet->stream_id) {
1107 69354a83 Hans de Goede
        ERROR("return bulk packet mismatch, please report this!\n");
1108 69354a83 Hans de Goede
        len = USB_RET_NAK;
1109 69354a83 Hans de Goede
    }
1110 69354a83 Hans de Goede
1111 69354a83 Hans de Goede
    if (aurb->packet) {
1112 69354a83 Hans de Goede
        len = usbredir_handle_status(dev, bulk_packet->status, len);
1113 69354a83 Hans de Goede
        if (len > 0) {
1114 69354a83 Hans de Goede
            usbredir_log_data(dev, "bulk data in:", data, data_len);
1115 4f4321c1 Gerd Hoffmann
            if (data_len <= aurb->packet->iov.size) {
1116 4f4321c1 Gerd Hoffmann
                usb_packet_copy(aurb->packet, data, data_len);
1117 69354a83 Hans de Goede
            } else {
1118 4f4321c1 Gerd Hoffmann
                ERROR("bulk buffer too small (%d > %zd)\n", data_len,
1119 4f4321c1 Gerd Hoffmann
                      aurb->packet->iov.size);
1120 69354a83 Hans de Goede
                len = USB_RET_STALL;
1121 69354a83 Hans de Goede
            }
1122 69354a83 Hans de Goede
        }
1123 4f4321c1 Gerd Hoffmann
        aurb->packet->result = len;
1124 69354a83 Hans de Goede
        usb_packet_complete(&dev->dev, aurb->packet);
1125 69354a83 Hans de Goede
    }
1126 69354a83 Hans de Goede
    async_free(dev, aurb);
1127 69354a83 Hans de Goede
    free(data);
1128 69354a83 Hans de Goede
}
1129 69354a83 Hans de Goede
1130 69354a83 Hans de Goede
static void usbredir_iso_packet(void *priv, uint32_t id,
1131 69354a83 Hans de Goede
    struct usb_redir_iso_packet_header *iso_packet,
1132 69354a83 Hans de Goede
    uint8_t *data, int data_len)
1133 69354a83 Hans de Goede
{
1134 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
1135 69354a83 Hans de Goede
    uint8_t ep = iso_packet->endpoint;
1136 69354a83 Hans de Goede
1137 69354a83 Hans de Goede
    DPRINTF2("iso-in status %d ep %02X len %d id %u\n", iso_packet->status, ep,
1138 69354a83 Hans de Goede
             data_len, id);
1139 69354a83 Hans de Goede
1140 69354a83 Hans de Goede
    if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_ISOC) {
1141 69354a83 Hans de Goede
        ERROR("received iso packet for non iso endpoint %02X\n", ep);
1142 69354a83 Hans de Goede
        free(data);
1143 69354a83 Hans de Goede
        return;
1144 69354a83 Hans de Goede
    }
1145 69354a83 Hans de Goede
1146 69354a83 Hans de Goede
    if (dev->endpoint[EP2I(ep)].iso_started == 0) {
1147 69354a83 Hans de Goede
        DPRINTF("received iso packet for non started stream ep %02X\n", ep);
1148 69354a83 Hans de Goede
        free(data);
1149 69354a83 Hans de Goede
        return;
1150 69354a83 Hans de Goede
    }
1151 69354a83 Hans de Goede
1152 69354a83 Hans de Goede
    /* bufp_alloc also adds the packet to the ep queue */
1153 69354a83 Hans de Goede
    bufp_alloc(dev, data, data_len, iso_packet->status, ep);
1154 69354a83 Hans de Goede
}
1155 69354a83 Hans de Goede
1156 69354a83 Hans de Goede
static void usbredir_interrupt_packet(void *priv, uint32_t id,
1157 69354a83 Hans de Goede
    struct usb_redir_interrupt_packet_header *interrupt_packet,
1158 69354a83 Hans de Goede
    uint8_t *data, int data_len)
1159 69354a83 Hans de Goede
{
1160 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
1161 69354a83 Hans de Goede
    uint8_t ep = interrupt_packet->endpoint;
1162 69354a83 Hans de Goede
1163 69354a83 Hans de Goede
    DPRINTF("interrupt-in status %d ep %02X len %d id %u\n",
1164 69354a83 Hans de Goede
            interrupt_packet->status, ep, data_len, id);
1165 69354a83 Hans de Goede
1166 69354a83 Hans de Goede
    if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) {
1167 69354a83 Hans de Goede
        ERROR("received int packet for non interrupt endpoint %02X\n", ep);
1168 69354a83 Hans de Goede
        free(data);
1169 69354a83 Hans de Goede
        return;
1170 69354a83 Hans de Goede
    }
1171 69354a83 Hans de Goede
1172 69354a83 Hans de Goede
    if (ep & USB_DIR_IN) {
1173 69354a83 Hans de Goede
        if (dev->endpoint[EP2I(ep)].interrupt_started == 0) {
1174 69354a83 Hans de Goede
            DPRINTF("received int packet while not started ep %02X\n", ep);
1175 69354a83 Hans de Goede
            free(data);
1176 69354a83 Hans de Goede
            return;
1177 69354a83 Hans de Goede
        }
1178 69354a83 Hans de Goede
1179 69354a83 Hans de Goede
        /* bufp_alloc also adds the packet to the ep queue */
1180 69354a83 Hans de Goede
        bufp_alloc(dev, data, data_len, interrupt_packet->status, ep);
1181 69354a83 Hans de Goede
    } else {
1182 69354a83 Hans de Goede
        int len = interrupt_packet->length;
1183 69354a83 Hans de Goede
1184 69354a83 Hans de Goede
        AsyncURB *aurb = async_find(dev, id);
1185 69354a83 Hans de Goede
        if (!aurb) {
1186 69354a83 Hans de Goede
            return;
1187 69354a83 Hans de Goede
        }
1188 69354a83 Hans de Goede
1189 69354a83 Hans de Goede
        if (aurb->interrupt_packet.endpoint != interrupt_packet->endpoint) {
1190 69354a83 Hans de Goede
            ERROR("return int packet mismatch, please report this!\n");
1191 69354a83 Hans de Goede
            len = USB_RET_NAK;
1192 69354a83 Hans de Goede
        }
1193 69354a83 Hans de Goede
1194 69354a83 Hans de Goede
        if (aurb->packet) {
1195 4f4321c1 Gerd Hoffmann
            aurb->packet->result = usbredir_handle_status(dev,
1196 69354a83 Hans de Goede
                                               interrupt_packet->status, len);
1197 69354a83 Hans de Goede
            usb_packet_complete(&dev->dev, aurb->packet);
1198 69354a83 Hans de Goede
        }
1199 69354a83 Hans de Goede
        async_free(dev, aurb);
1200 69354a83 Hans de Goede
    }
1201 69354a83 Hans de Goede
}
1202 69354a83 Hans de Goede
1203 69354a83 Hans de Goede
static struct USBDeviceInfo usbredir_dev_info = {
1204 69354a83 Hans de Goede
    .product_desc   = "USB Redirection Device",
1205 69354a83 Hans de Goede
    .qdev.name      = "usb-redir",
1206 69354a83 Hans de Goede
    .qdev.size      = sizeof(USBRedirDevice),
1207 69354a83 Hans de Goede
    .init           = usbredir_initfn,
1208 69354a83 Hans de Goede
    .handle_destroy = usbredir_handle_destroy,
1209 69354a83 Hans de Goede
    .handle_packet  = usb_generic_handle_packet,
1210 69354a83 Hans de Goede
    .cancel_packet  = usbredir_cancel_packet,
1211 69354a83 Hans de Goede
    .handle_reset   = usbredir_handle_reset,
1212 69354a83 Hans de Goede
    .handle_data    = usbredir_handle_data,
1213 69354a83 Hans de Goede
    .handle_control = usbredir_handle_control,
1214 69354a83 Hans de Goede
    .qdev.props     = (Property[]) {
1215 69354a83 Hans de Goede
        DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
1216 69354a83 Hans de Goede
        DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0),
1217 69354a83 Hans de Goede
        DEFINE_PROP_END_OF_LIST(),
1218 69354a83 Hans de Goede
    },
1219 69354a83 Hans de Goede
};
1220 69354a83 Hans de Goede
1221 69354a83 Hans de Goede
static void usbredir_register_devices(void)
1222 69354a83 Hans de Goede
{
1223 69354a83 Hans de Goede
    usb_qdev_register(&usbredir_dev_info);
1224 69354a83 Hans de Goede
}
1225 69354a83 Hans de Goede
device_init(usbredir_register_devices);