Statistics
| Branch: | Revision:

root / usb-redir.c @ 93148aa5

History | View | Annotate | Download (47.1 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 6af16589 Hans de Goede
#include <usbredirfilter.h>
38 69354a83 Hans de Goede
39 69354a83 Hans de Goede
#include "hw/usb.h"
40 69354a83 Hans de Goede
41 69354a83 Hans de Goede
#define MAX_ENDPOINTS 32
42 69354a83 Hans de Goede
#define EP2I(ep_address) (((ep_address & 0x80) >> 3) | (ep_address & 0x0f))
43 69354a83 Hans de Goede
#define I2EP(i) (((i & 0x10) << 3) | (i & 0x0f))
44 69354a83 Hans de Goede
45 69354a83 Hans de Goede
typedef struct AsyncURB AsyncURB;
46 69354a83 Hans de Goede
typedef struct USBRedirDevice USBRedirDevice;
47 69354a83 Hans de Goede
48 69354a83 Hans de Goede
/* Struct to hold buffered packets (iso or int input packets) */
49 69354a83 Hans de Goede
struct buf_packet {
50 69354a83 Hans de Goede
    uint8_t *data;
51 69354a83 Hans de Goede
    int len;
52 69354a83 Hans de Goede
    int status;
53 69354a83 Hans de Goede
    QTAILQ_ENTRY(buf_packet)next;
54 69354a83 Hans de Goede
};
55 69354a83 Hans de Goede
56 69354a83 Hans de Goede
struct endp_data {
57 69354a83 Hans de Goede
    uint8_t type;
58 69354a83 Hans de Goede
    uint8_t interval;
59 69354a83 Hans de Goede
    uint8_t interface; /* bInterfaceNumber this ep belongs to */
60 69354a83 Hans de Goede
    uint8_t iso_started;
61 69354a83 Hans de Goede
    uint8_t iso_error; /* For reporting iso errors to the HC */
62 69354a83 Hans de Goede
    uint8_t interrupt_started;
63 69354a83 Hans de Goede
    uint8_t interrupt_error;
64 e1537884 Hans de Goede
    uint8_t bufpq_prefilled;
65 81fd7b74 Hans de Goede
    uint8_t bufpq_dropping_packets;
66 69354a83 Hans de Goede
    QTAILQ_HEAD(, buf_packet) bufpq;
67 e1537884 Hans de Goede
    int bufpq_size;
68 e8a7dd29 Hans de Goede
    int bufpq_target_size;
69 69354a83 Hans de Goede
};
70 69354a83 Hans de Goede
71 69354a83 Hans de Goede
struct USBRedirDevice {
72 69354a83 Hans de Goede
    USBDevice dev;
73 69354a83 Hans de Goede
    /* Properties */
74 69354a83 Hans de Goede
    CharDriverState *cs;
75 69354a83 Hans de Goede
    uint8_t debug;
76 6af16589 Hans de Goede
    char *filter_str;
77 69354a83 Hans de Goede
    /* Data passed from chardev the fd_read cb to the usbredirparser read cb */
78 69354a83 Hans de Goede
    const uint8_t *read_buf;
79 69354a83 Hans de Goede
    int read_buf_size;
80 69354a83 Hans de Goede
    /* For async handling of open/close */
81 69354a83 Hans de Goede
    QEMUBH *open_close_bh;
82 69354a83 Hans de Goede
    /* To delay the usb attach in case of quick chardev close + open */
83 69354a83 Hans de Goede
    QEMUTimer *attach_timer;
84 69354a83 Hans de Goede
    int64_t next_attach_time;
85 69354a83 Hans de Goede
    struct usbredirparser *parser;
86 69354a83 Hans de Goede
    struct endp_data endpoint[MAX_ENDPOINTS];
87 69354a83 Hans de Goede
    uint32_t packet_id;
88 69354a83 Hans de Goede
    QTAILQ_HEAD(, AsyncURB) asyncq;
89 6af16589 Hans de Goede
    /* Data for device filtering */
90 6af16589 Hans de Goede
    struct usb_redir_device_connect_header device_info;
91 6af16589 Hans de Goede
    struct usb_redir_interface_info_header interface_info;
92 6af16589 Hans de Goede
    struct usbredirfilter_rule *filter_rules;
93 6af16589 Hans de Goede
    int filter_rules_count;
94 69354a83 Hans de Goede
};
95 69354a83 Hans de Goede
96 69354a83 Hans de Goede
struct AsyncURB {
97 69354a83 Hans de Goede
    USBRedirDevice *dev;
98 69354a83 Hans de Goede
    USBPacket *packet;
99 69354a83 Hans de Goede
    uint32_t packet_id;
100 69354a83 Hans de Goede
    int get;
101 69354a83 Hans de Goede
    union {
102 69354a83 Hans de Goede
        struct usb_redir_control_packet_header control_packet;
103 69354a83 Hans de Goede
        struct usb_redir_bulk_packet_header bulk_packet;
104 69354a83 Hans de Goede
        struct usb_redir_interrupt_packet_header interrupt_packet;
105 69354a83 Hans de Goede
    };
106 69354a83 Hans de Goede
    QTAILQ_ENTRY(AsyncURB)next;
107 69354a83 Hans de Goede
};
108 69354a83 Hans de Goede
109 097a66ef Hans de Goede
static void usbredir_hello(void *priv, struct usb_redir_hello_header *h);
110 69354a83 Hans de Goede
static void usbredir_device_connect(void *priv,
111 69354a83 Hans de Goede
    struct usb_redir_device_connect_header *device_connect);
112 69354a83 Hans de Goede
static void usbredir_device_disconnect(void *priv);
113 69354a83 Hans de Goede
static void usbredir_interface_info(void *priv,
114 69354a83 Hans de Goede
    struct usb_redir_interface_info_header *interface_info);
115 69354a83 Hans de Goede
static void usbredir_ep_info(void *priv,
116 69354a83 Hans de Goede
    struct usb_redir_ep_info_header *ep_info);
117 69354a83 Hans de Goede
static void usbredir_configuration_status(void *priv, uint32_t id,
118 69354a83 Hans de Goede
    struct usb_redir_configuration_status_header *configuration_status);
119 69354a83 Hans de Goede
static void usbredir_alt_setting_status(void *priv, uint32_t id,
120 69354a83 Hans de Goede
    struct usb_redir_alt_setting_status_header *alt_setting_status);
121 69354a83 Hans de Goede
static void usbredir_iso_stream_status(void *priv, uint32_t id,
122 69354a83 Hans de Goede
    struct usb_redir_iso_stream_status_header *iso_stream_status);
123 69354a83 Hans de Goede
static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
124 69354a83 Hans de Goede
    struct usb_redir_interrupt_receiving_status_header
125 69354a83 Hans de Goede
    *interrupt_receiving_status);
126 69354a83 Hans de Goede
static void usbredir_bulk_streams_status(void *priv, uint32_t id,
127 69354a83 Hans de Goede
    struct usb_redir_bulk_streams_status_header *bulk_streams_status);
128 69354a83 Hans de Goede
static void usbredir_control_packet(void *priv, uint32_t id,
129 69354a83 Hans de Goede
    struct usb_redir_control_packet_header *control_packet,
130 69354a83 Hans de Goede
    uint8_t *data, int data_len);
131 69354a83 Hans de Goede
static void usbredir_bulk_packet(void *priv, uint32_t id,
132 69354a83 Hans de Goede
    struct usb_redir_bulk_packet_header *bulk_packet,
133 69354a83 Hans de Goede
    uint8_t *data, int data_len);
134 69354a83 Hans de Goede
static void usbredir_iso_packet(void *priv, uint32_t id,
135 69354a83 Hans de Goede
    struct usb_redir_iso_packet_header *iso_packet,
136 69354a83 Hans de Goede
    uint8_t *data, int data_len);
137 69354a83 Hans de Goede
static void usbredir_interrupt_packet(void *priv, uint32_t id,
138 69354a83 Hans de Goede
    struct usb_redir_interrupt_packet_header *interrupt_header,
139 69354a83 Hans de Goede
    uint8_t *data, int data_len);
140 69354a83 Hans de Goede
141 69354a83 Hans de Goede
static int usbredir_handle_status(USBRedirDevice *dev,
142 69354a83 Hans de Goede
                                       int status, int actual_len);
143 69354a83 Hans de Goede
144 69354a83 Hans de Goede
#define VERSION "qemu usb-redir guest " QEMU_VERSION
145 69354a83 Hans de Goede
146 69354a83 Hans de Goede
/*
147 69354a83 Hans de Goede
 * Logging stuff
148 69354a83 Hans de Goede
 */
149 69354a83 Hans de Goede
150 69354a83 Hans de Goede
#define ERROR(...) \
151 69354a83 Hans de Goede
    do { \
152 69354a83 Hans de Goede
        if (dev->debug >= usbredirparser_error) { \
153 69354a83 Hans de Goede
            error_report("usb-redir error: " __VA_ARGS__); \
154 69354a83 Hans de Goede
        } \
155 69354a83 Hans de Goede
    } while (0)
156 69354a83 Hans de Goede
#define WARNING(...) \
157 69354a83 Hans de Goede
    do { \
158 69354a83 Hans de Goede
        if (dev->debug >= usbredirparser_warning) { \
159 69354a83 Hans de Goede
            error_report("usb-redir warning: " __VA_ARGS__); \
160 69354a83 Hans de Goede
        } \
161 69354a83 Hans de Goede
    } while (0)
162 69354a83 Hans de Goede
#define INFO(...) \
163 69354a83 Hans de Goede
    do { \
164 69354a83 Hans de Goede
        if (dev->debug >= usbredirparser_info) { \
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
#define DPRINTF(...) \
169 69354a83 Hans de Goede
    do { \
170 69354a83 Hans de Goede
        if (dev->debug >= usbredirparser_debug) { \
171 69354a83 Hans de Goede
            error_report("usb-redir: " __VA_ARGS__); \
172 69354a83 Hans de Goede
        } \
173 69354a83 Hans de Goede
    } while (0)
174 69354a83 Hans de Goede
#define DPRINTF2(...) \
175 69354a83 Hans de Goede
    do { \
176 69354a83 Hans de Goede
        if (dev->debug >= usbredirparser_debug_data) { \
177 69354a83 Hans de Goede
            error_report("usb-redir: " __VA_ARGS__); \
178 69354a83 Hans de Goede
        } \
179 69354a83 Hans de Goede
    } while (0)
180 69354a83 Hans de Goede
181 69354a83 Hans de Goede
static void usbredir_log(void *priv, int level, const char *msg)
182 69354a83 Hans de Goede
{
183 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
184 69354a83 Hans de Goede
185 69354a83 Hans de Goede
    if (dev->debug < level) {
186 69354a83 Hans de Goede
        return;
187 69354a83 Hans de Goede
    }
188 69354a83 Hans de Goede
189 be62a2eb Markus Armbruster
    error_report("%s", msg);
190 69354a83 Hans de Goede
}
191 69354a83 Hans de Goede
192 69354a83 Hans de Goede
static void usbredir_log_data(USBRedirDevice *dev, const char *desc,
193 69354a83 Hans de Goede
    const uint8_t *data, int len)
194 69354a83 Hans de Goede
{
195 69354a83 Hans de Goede
    int i, j, n;
196 69354a83 Hans de Goede
197 69354a83 Hans de Goede
    if (dev->debug < usbredirparser_debug_data) {
198 69354a83 Hans de Goede
        return;
199 69354a83 Hans de Goede
    }
200 69354a83 Hans de Goede
201 69354a83 Hans de Goede
    for (i = 0; i < len; i += j) {
202 69354a83 Hans de Goede
        char buf[128];
203 69354a83 Hans de Goede
204 69354a83 Hans de Goede
        n = sprintf(buf, "%s", desc);
205 69354a83 Hans de Goede
        for (j = 0; j < 8 && i + j < len; j++) {
206 69354a83 Hans de Goede
            n += sprintf(buf + n, " %02X", data[i + j]);
207 69354a83 Hans de Goede
        }
208 be62a2eb Markus Armbruster
        error_report("%s", buf);
209 69354a83 Hans de Goede
    }
210 69354a83 Hans de Goede
}
211 69354a83 Hans de Goede
212 69354a83 Hans de Goede
/*
213 69354a83 Hans de Goede
 * usbredirparser io functions
214 69354a83 Hans de Goede
 */
215 69354a83 Hans de Goede
216 69354a83 Hans de Goede
static int usbredir_read(void *priv, uint8_t *data, int count)
217 69354a83 Hans de Goede
{
218 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
219 69354a83 Hans de Goede
220 69354a83 Hans de Goede
    if (dev->read_buf_size < count) {
221 69354a83 Hans de Goede
        count = dev->read_buf_size;
222 69354a83 Hans de Goede
    }
223 69354a83 Hans de Goede
224 69354a83 Hans de Goede
    memcpy(data, dev->read_buf, count);
225 69354a83 Hans de Goede
226 69354a83 Hans de Goede
    dev->read_buf_size -= count;
227 69354a83 Hans de Goede
    if (dev->read_buf_size) {
228 69354a83 Hans de Goede
        dev->read_buf += count;
229 69354a83 Hans de Goede
    } else {
230 69354a83 Hans de Goede
        dev->read_buf = NULL;
231 69354a83 Hans de Goede
    }
232 69354a83 Hans de Goede
233 69354a83 Hans de Goede
    return count;
234 69354a83 Hans de Goede
}
235 69354a83 Hans de Goede
236 69354a83 Hans de Goede
static int usbredir_write(void *priv, uint8_t *data, int count)
237 69354a83 Hans de Goede
{
238 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
239 69354a83 Hans de Goede
240 c1b71a1d Hans de Goede
    if (!dev->cs->opened) {
241 c1b71a1d Hans de Goede
        return 0;
242 c1b71a1d Hans de Goede
    }
243 c1b71a1d Hans de Goede
244 2cc6e0a1 Anthony Liguori
    return qemu_chr_fe_write(dev->cs, data, count);
245 69354a83 Hans de Goede
}
246 69354a83 Hans de Goede
247 69354a83 Hans de Goede
/*
248 69354a83 Hans de Goede
 * Async and buffered packets helpers
249 69354a83 Hans de Goede
 */
250 69354a83 Hans de Goede
251 69354a83 Hans de Goede
static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p)
252 69354a83 Hans de Goede
{
253 7267c094 Anthony Liguori
    AsyncURB *aurb = (AsyncURB *) g_malloc0(sizeof(AsyncURB));
254 69354a83 Hans de Goede
    aurb->dev = dev;
255 69354a83 Hans de Goede
    aurb->packet = p;
256 69354a83 Hans de Goede
    aurb->packet_id = dev->packet_id;
257 69354a83 Hans de Goede
    QTAILQ_INSERT_TAIL(&dev->asyncq, aurb, next);
258 69354a83 Hans de Goede
    dev->packet_id++;
259 69354a83 Hans de Goede
260 69354a83 Hans de Goede
    return aurb;
261 69354a83 Hans de Goede
}
262 69354a83 Hans de Goede
263 69354a83 Hans de Goede
static void async_free(USBRedirDevice *dev, AsyncURB *aurb)
264 69354a83 Hans de Goede
{
265 69354a83 Hans de Goede
    QTAILQ_REMOVE(&dev->asyncq, aurb, next);
266 7267c094 Anthony Liguori
    g_free(aurb);
267 69354a83 Hans de Goede
}
268 69354a83 Hans de Goede
269 69354a83 Hans de Goede
static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id)
270 69354a83 Hans de Goede
{
271 69354a83 Hans de Goede
    AsyncURB *aurb;
272 69354a83 Hans de Goede
273 69354a83 Hans de Goede
    QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
274 69354a83 Hans de Goede
        if (aurb->packet_id == packet_id) {
275 69354a83 Hans de Goede
            return aurb;
276 69354a83 Hans de Goede
        }
277 69354a83 Hans de Goede
    }
278 69354a83 Hans de Goede
    ERROR("could not find async urb for packet_id %u\n", packet_id);
279 69354a83 Hans de Goede
    return NULL;
280 69354a83 Hans de Goede
}
281 69354a83 Hans de Goede
282 69354a83 Hans de Goede
static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
283 69354a83 Hans de Goede
{
284 69354a83 Hans de Goede
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
285 69354a83 Hans de Goede
    AsyncURB *aurb;
286 69354a83 Hans de Goede
287 69354a83 Hans de Goede
    QTAILQ_FOREACH(aurb, &dev->asyncq, next) {
288 69354a83 Hans de Goede
        if (p != aurb->packet) {
289 69354a83 Hans de Goede
            continue;
290 69354a83 Hans de Goede
        }
291 69354a83 Hans de Goede
292 69354a83 Hans de Goede
        DPRINTF("async cancel id %u\n", aurb->packet_id);
293 69354a83 Hans de Goede
        usbredirparser_send_cancel_data_packet(dev->parser, aurb->packet_id);
294 69354a83 Hans de Goede
        usbredirparser_do_write(dev->parser);
295 69354a83 Hans de Goede
296 69354a83 Hans de Goede
        /* Mark it as dead */
297 69354a83 Hans de Goede
        aurb->packet = NULL;
298 69354a83 Hans de Goede
        break;
299 69354a83 Hans de Goede
    }
300 69354a83 Hans de Goede
}
301 69354a83 Hans de Goede
302 81fd7b74 Hans de Goede
static void bufp_alloc(USBRedirDevice *dev,
303 69354a83 Hans de Goede
    uint8_t *data, int len, int status, uint8_t ep)
304 69354a83 Hans de Goede
{
305 81fd7b74 Hans de Goede
    struct buf_packet *bufp;
306 81fd7b74 Hans de Goede
307 81fd7b74 Hans de Goede
    if (!dev->endpoint[EP2I(ep)].bufpq_dropping_packets &&
308 81fd7b74 Hans de Goede
        dev->endpoint[EP2I(ep)].bufpq_size >
309 81fd7b74 Hans de Goede
            2 * dev->endpoint[EP2I(ep)].bufpq_target_size) {
310 81fd7b74 Hans de Goede
        DPRINTF("bufpq overflow, dropping packets ep %02X\n", ep);
311 81fd7b74 Hans de Goede
        dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 1;
312 81fd7b74 Hans de Goede
    }
313 81fd7b74 Hans de Goede
    /* Since we're interupting the stream anyways, drop enough packets to get
314 81fd7b74 Hans de Goede
       back to our target buffer size */
315 81fd7b74 Hans de Goede
    if (dev->endpoint[EP2I(ep)].bufpq_dropping_packets) {
316 81fd7b74 Hans de Goede
        if (dev->endpoint[EP2I(ep)].bufpq_size >
317 81fd7b74 Hans de Goede
                dev->endpoint[EP2I(ep)].bufpq_target_size) {
318 81fd7b74 Hans de Goede
            free(data);
319 81fd7b74 Hans de Goede
            return;
320 81fd7b74 Hans de Goede
        }
321 81fd7b74 Hans de Goede
        dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
322 81fd7b74 Hans de Goede
    }
323 81fd7b74 Hans de Goede
324 81fd7b74 Hans de Goede
    bufp = g_malloc(sizeof(struct buf_packet));
325 69354a83 Hans de Goede
    bufp->data   = data;
326 69354a83 Hans de Goede
    bufp->len    = len;
327 69354a83 Hans de Goede
    bufp->status = status;
328 69354a83 Hans de Goede
    QTAILQ_INSERT_TAIL(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
329 e1537884 Hans de Goede
    dev->endpoint[EP2I(ep)].bufpq_size++;
330 69354a83 Hans de Goede
}
331 69354a83 Hans de Goede
332 69354a83 Hans de Goede
static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp,
333 69354a83 Hans de Goede
    uint8_t ep)
334 69354a83 Hans de Goede
{
335 69354a83 Hans de Goede
    QTAILQ_REMOVE(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
336 e1537884 Hans de Goede
    dev->endpoint[EP2I(ep)].bufpq_size--;
337 69354a83 Hans de Goede
    free(bufp->data);
338 7267c094 Anthony Liguori
    g_free(bufp);
339 69354a83 Hans de Goede
}
340 69354a83 Hans de Goede
341 69354a83 Hans de Goede
static void usbredir_free_bufpq(USBRedirDevice *dev, uint8_t ep)
342 69354a83 Hans de Goede
{
343 69354a83 Hans de Goede
    struct buf_packet *buf, *buf_next;
344 69354a83 Hans de Goede
345 69354a83 Hans de Goede
    QTAILQ_FOREACH_SAFE(buf, &dev->endpoint[EP2I(ep)].bufpq, next, buf_next) {
346 69354a83 Hans de Goede
        bufp_free(dev, buf, ep);
347 69354a83 Hans de Goede
    }
348 69354a83 Hans de Goede
}
349 69354a83 Hans de Goede
350 69354a83 Hans de Goede
/*
351 69354a83 Hans de Goede
 * USBDevice callbacks
352 69354a83 Hans de Goede
 */
353 69354a83 Hans de Goede
354 69354a83 Hans de Goede
static void usbredir_handle_reset(USBDevice *udev)
355 69354a83 Hans de Goede
{
356 69354a83 Hans de Goede
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
357 69354a83 Hans de Goede
358 69354a83 Hans de Goede
    DPRINTF("reset device\n");
359 69354a83 Hans de Goede
    usbredirparser_send_reset(dev->parser);
360 69354a83 Hans de Goede
    usbredirparser_do_write(dev->parser);
361 69354a83 Hans de Goede
}
362 69354a83 Hans de Goede
363 69354a83 Hans de Goede
static int usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p,
364 69354a83 Hans de Goede
                                     uint8_t ep)
365 69354a83 Hans de Goede
{
366 69354a83 Hans de Goede
    int status, len;
367 69354a83 Hans de Goede
    if (!dev->endpoint[EP2I(ep)].iso_started &&
368 69354a83 Hans de Goede
            !dev->endpoint[EP2I(ep)].iso_error) {
369 69354a83 Hans de Goede
        struct usb_redir_start_iso_stream_header start_iso = {
370 69354a83 Hans de Goede
            .endpoint = ep,
371 69354a83 Hans de Goede
        };
372 e8a7dd29 Hans de Goede
        int pkts_per_sec;
373 e8a7dd29 Hans de Goede
374 e8a7dd29 Hans de Goede
        if (dev->dev.speed == USB_SPEED_HIGH) {
375 e8a7dd29 Hans de Goede
            pkts_per_sec = 8000 / dev->endpoint[EP2I(ep)].interval;
376 e8a7dd29 Hans de Goede
        } else {
377 e8a7dd29 Hans de Goede
            pkts_per_sec = 1000 / dev->endpoint[EP2I(ep)].interval;
378 e8a7dd29 Hans de Goede
        }
379 e8a7dd29 Hans de Goede
        /* Testing has shown that we need circa 60 ms buffer */
380 e8a7dd29 Hans de Goede
        dev->endpoint[EP2I(ep)].bufpq_target_size = (pkts_per_sec * 60) / 1000;
381 e8a7dd29 Hans de Goede
382 e8a7dd29 Hans de Goede
        /* Aim for approx 100 interrupts / second on the client to
383 e8a7dd29 Hans de Goede
           balance latency and interrupt load */
384 e8a7dd29 Hans de Goede
        start_iso.pkts_per_urb = pkts_per_sec / 100;
385 e8a7dd29 Hans de Goede
        if (start_iso.pkts_per_urb < 1) {
386 e8a7dd29 Hans de Goede
            start_iso.pkts_per_urb = 1;
387 e8a7dd29 Hans de Goede
        } else if (start_iso.pkts_per_urb > 32) {
388 e8a7dd29 Hans de Goede
            start_iso.pkts_per_urb = 32;
389 e8a7dd29 Hans de Goede
        }
390 e8a7dd29 Hans de Goede
391 e8a7dd29 Hans de Goede
        start_iso.no_urbs = (dev->endpoint[EP2I(ep)].bufpq_target_size +
392 e8a7dd29 Hans de Goede
                             start_iso.pkts_per_urb - 1) /
393 e8a7dd29 Hans de Goede
                            start_iso.pkts_per_urb;
394 e8a7dd29 Hans de Goede
        /* Output endpoints pre-fill only 1/2 of the packets, keeping the rest
395 e8a7dd29 Hans de Goede
           as overflow buffer. Also see the usbredir protocol documentation */
396 e8a7dd29 Hans de Goede
        if (!(ep & USB_DIR_IN)) {
397 e8a7dd29 Hans de Goede
            start_iso.no_urbs *= 2;
398 e8a7dd29 Hans de Goede
        }
399 e8a7dd29 Hans de Goede
        if (start_iso.no_urbs > 16) {
400 e8a7dd29 Hans de Goede
            start_iso.no_urbs = 16;
401 e8a7dd29 Hans de Goede
        }
402 e8a7dd29 Hans de Goede
403 69354a83 Hans de Goede
        /* No id, we look at the ep when receiving a status back */
404 69354a83 Hans de Goede
        usbredirparser_send_start_iso_stream(dev->parser, 0, &start_iso);
405 69354a83 Hans de Goede
        usbredirparser_do_write(dev->parser);
406 32213543 Hans de Goede
        DPRINTF("iso stream started pkts/sec %d pkts/urb %d urbs %d ep %02X\n",
407 32213543 Hans de Goede
                pkts_per_sec, start_iso.pkts_per_urb, start_iso.no_urbs, ep);
408 69354a83 Hans de Goede
        dev->endpoint[EP2I(ep)].iso_started = 1;
409 e1537884 Hans de Goede
        dev->endpoint[EP2I(ep)].bufpq_prefilled = 0;
410 81fd7b74 Hans de Goede
        dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
411 69354a83 Hans de Goede
    }
412 69354a83 Hans de Goede
413 69354a83 Hans de Goede
    if (ep & USB_DIR_IN) {
414 69354a83 Hans de Goede
        struct buf_packet *isop;
415 69354a83 Hans de Goede
416 e1537884 Hans de Goede
        if (dev->endpoint[EP2I(ep)].iso_started &&
417 e1537884 Hans de Goede
                !dev->endpoint[EP2I(ep)].bufpq_prefilled) {
418 e1537884 Hans de Goede
            if (dev->endpoint[EP2I(ep)].bufpq_size <
419 e1537884 Hans de Goede
                    dev->endpoint[EP2I(ep)].bufpq_target_size) {
420 e1537884 Hans de Goede
                return usbredir_handle_status(dev, 0, 0);
421 e1537884 Hans de Goede
            }
422 e1537884 Hans de Goede
            dev->endpoint[EP2I(ep)].bufpq_prefilled = 1;
423 e1537884 Hans de Goede
        }
424 e1537884 Hans de Goede
425 69354a83 Hans de Goede
        isop = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
426 69354a83 Hans de Goede
        if (isop == NULL) {
427 32213543 Hans de Goede
            DPRINTF("iso-token-in ep %02X, no isop, iso_error: %d\n",
428 32213543 Hans de Goede
                    ep, dev->endpoint[EP2I(ep)].iso_error);
429 e1537884 Hans de Goede
            /* Re-fill the buffer */
430 e1537884 Hans de Goede
            dev->endpoint[EP2I(ep)].bufpq_prefilled = 0;
431 69354a83 Hans de Goede
            /* Check iso_error for stream errors, otherwise its an underrun */
432 69354a83 Hans de Goede
            status = dev->endpoint[EP2I(ep)].iso_error;
433 69354a83 Hans de Goede
            dev->endpoint[EP2I(ep)].iso_error = 0;
434 d86b8853 Hans de Goede
            return status ? USB_RET_NAK : 0;
435 69354a83 Hans de Goede
        }
436 32213543 Hans de Goede
        DPRINTF2("iso-token-in ep %02X status %d len %d queue-size: %d\n", ep,
437 32213543 Hans de Goede
                 isop->status, isop->len, dev->endpoint[EP2I(ep)].bufpq_size);
438 69354a83 Hans de Goede
439 69354a83 Hans de Goede
        status = isop->status;
440 69354a83 Hans de Goede
        if (status != usb_redir_success) {
441 69354a83 Hans de Goede
            bufp_free(dev, isop, ep);
442 d86b8853 Hans de Goede
            return USB_RET_NAK;
443 69354a83 Hans de Goede
        }
444 69354a83 Hans de Goede
445 69354a83 Hans de Goede
        len = isop->len;
446 4f4321c1 Gerd Hoffmann
        if (len > p->iov.size) {
447 32213543 Hans de Goede
            ERROR("received iso data is larger then packet ep %02X (%d > %d)\n",
448 32213543 Hans de Goede
                  ep, len, (int)p->iov.size);
449 69354a83 Hans de Goede
            bufp_free(dev, isop, ep);
450 69354a83 Hans de Goede
            return USB_RET_NAK;
451 69354a83 Hans de Goede
        }
452 4f4321c1 Gerd Hoffmann
        usb_packet_copy(p, isop->data, len);
453 69354a83 Hans de Goede
        bufp_free(dev, isop, ep);
454 69354a83 Hans de Goede
        return len;
455 69354a83 Hans de Goede
    } else {
456 69354a83 Hans de Goede
        /* If the stream was not started because of a pending error don't
457 69354a83 Hans de Goede
           send the packet to the usb-host */
458 69354a83 Hans de Goede
        if (dev->endpoint[EP2I(ep)].iso_started) {
459 69354a83 Hans de Goede
            struct usb_redir_iso_packet_header iso_packet = {
460 69354a83 Hans de Goede
                .endpoint = ep,
461 4f4321c1 Gerd Hoffmann
                .length = p->iov.size
462 69354a83 Hans de Goede
            };
463 4f4321c1 Gerd Hoffmann
            uint8_t buf[p->iov.size];
464 69354a83 Hans de Goede
            /* No id, we look at the ep when receiving a status back */
465 4f4321c1 Gerd Hoffmann
            usb_packet_copy(p, buf, p->iov.size);
466 69354a83 Hans de Goede
            usbredirparser_send_iso_packet(dev->parser, 0, &iso_packet,
467 4f4321c1 Gerd Hoffmann
                                           buf, p->iov.size);
468 69354a83 Hans de Goede
            usbredirparser_do_write(dev->parser);
469 69354a83 Hans de Goede
        }
470 69354a83 Hans de Goede
        status = dev->endpoint[EP2I(ep)].iso_error;
471 69354a83 Hans de Goede
        dev->endpoint[EP2I(ep)].iso_error = 0;
472 4f4321c1 Gerd Hoffmann
        DPRINTF2("iso-token-out ep %02X status %d len %zd\n", ep, status,
473 4f4321c1 Gerd Hoffmann
                 p->iov.size);
474 4f4321c1 Gerd Hoffmann
        return usbredir_handle_status(dev, status, p->iov.size);
475 69354a83 Hans de Goede
    }
476 69354a83 Hans de Goede
}
477 69354a83 Hans de Goede
478 69354a83 Hans de Goede
static void usbredir_stop_iso_stream(USBRedirDevice *dev, uint8_t ep)
479 69354a83 Hans de Goede
{
480 69354a83 Hans de Goede
    struct usb_redir_stop_iso_stream_header stop_iso_stream = {
481 69354a83 Hans de Goede
        .endpoint = ep
482 69354a83 Hans de Goede
    };
483 69354a83 Hans de Goede
    if (dev->endpoint[EP2I(ep)].iso_started) {
484 69354a83 Hans de Goede
        usbredirparser_send_stop_iso_stream(dev->parser, 0, &stop_iso_stream);
485 69354a83 Hans de Goede
        DPRINTF("iso stream stopped ep %02X\n", ep);
486 69354a83 Hans de Goede
        dev->endpoint[EP2I(ep)].iso_started = 0;
487 69354a83 Hans de Goede
    }
488 2bd836e5 Hans de Goede
    dev->endpoint[EP2I(ep)].iso_error = 0;
489 69354a83 Hans de Goede
    usbredir_free_bufpq(dev, ep);
490 69354a83 Hans de Goede
}
491 69354a83 Hans de Goede
492 69354a83 Hans de Goede
static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
493 69354a83 Hans de Goede
                                      uint8_t ep)
494 69354a83 Hans de Goede
{
495 69354a83 Hans de Goede
    AsyncURB *aurb = async_alloc(dev, p);
496 69354a83 Hans de Goede
    struct usb_redir_bulk_packet_header bulk_packet;
497 69354a83 Hans de Goede
498 4f4321c1 Gerd Hoffmann
    DPRINTF("bulk-out ep %02X len %zd id %u\n", ep,
499 4f4321c1 Gerd Hoffmann
            p->iov.size, aurb->packet_id);
500 69354a83 Hans de Goede
501 69354a83 Hans de Goede
    bulk_packet.endpoint  = ep;
502 4f4321c1 Gerd Hoffmann
    bulk_packet.length    = p->iov.size;
503 69354a83 Hans de Goede
    bulk_packet.stream_id = 0;
504 69354a83 Hans de Goede
    aurb->bulk_packet = bulk_packet;
505 69354a83 Hans de Goede
506 69354a83 Hans de Goede
    if (ep & USB_DIR_IN) {
507 69354a83 Hans de Goede
        usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
508 69354a83 Hans de Goede
                                        &bulk_packet, NULL, 0);
509 69354a83 Hans de Goede
    } else {
510 4f4321c1 Gerd Hoffmann
        uint8_t buf[p->iov.size];
511 4f4321c1 Gerd Hoffmann
        usb_packet_copy(p, buf, p->iov.size);
512 4f4321c1 Gerd Hoffmann
        usbredir_log_data(dev, "bulk data out:", buf, p->iov.size);
513 69354a83 Hans de Goede
        usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
514 4f4321c1 Gerd Hoffmann
                                        &bulk_packet, buf, p->iov.size);
515 69354a83 Hans de Goede
    }
516 69354a83 Hans de Goede
    usbredirparser_do_write(dev->parser);
517 69354a83 Hans de Goede
    return USB_RET_ASYNC;
518 69354a83 Hans de Goede
}
519 69354a83 Hans de Goede
520 69354a83 Hans de Goede
static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
521 69354a83 Hans de Goede
                                           USBPacket *p, uint8_t ep)
522 69354a83 Hans de Goede
{
523 69354a83 Hans de Goede
    if (ep & USB_DIR_IN) {
524 69354a83 Hans de Goede
        /* Input interrupt endpoint, buffered packet input */
525 69354a83 Hans de Goede
        struct buf_packet *intp;
526 69354a83 Hans de Goede
        int status, len;
527 69354a83 Hans de Goede
528 69354a83 Hans de Goede
        if (!dev->endpoint[EP2I(ep)].interrupt_started &&
529 69354a83 Hans de Goede
                !dev->endpoint[EP2I(ep)].interrupt_error) {
530 69354a83 Hans de Goede
            struct usb_redir_start_interrupt_receiving_header start_int = {
531 69354a83 Hans de Goede
                .endpoint = ep,
532 69354a83 Hans de Goede
            };
533 69354a83 Hans de Goede
            /* No id, we look at the ep when receiving a status back */
534 69354a83 Hans de Goede
            usbredirparser_send_start_interrupt_receiving(dev->parser, 0,
535 69354a83 Hans de Goede
                                                          &start_int);
536 69354a83 Hans de Goede
            usbredirparser_do_write(dev->parser);
537 69354a83 Hans de Goede
            DPRINTF("interrupt recv started ep %02X\n", ep);
538 69354a83 Hans de Goede
            dev->endpoint[EP2I(ep)].interrupt_started = 1;
539 81fd7b74 Hans de Goede
            /* We don't really want to drop interrupt packets ever, but
540 81fd7b74 Hans de Goede
               having some upper limit to how much we buffer is good. */
541 81fd7b74 Hans de Goede
            dev->endpoint[EP2I(ep)].bufpq_target_size = 1000;
542 81fd7b74 Hans de Goede
            dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
543 69354a83 Hans de Goede
        }
544 69354a83 Hans de Goede
545 69354a83 Hans de Goede
        intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);
546 69354a83 Hans de Goede
        if (intp == NULL) {
547 69354a83 Hans de Goede
            DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep);
548 69354a83 Hans de Goede
            /* Check interrupt_error for stream errors */
549 69354a83 Hans de Goede
            status = dev->endpoint[EP2I(ep)].interrupt_error;
550 69354a83 Hans de Goede
            dev->endpoint[EP2I(ep)].interrupt_error = 0;
551 e6472210 Hans de Goede
            if (status) {
552 e6472210 Hans de Goede
                return usbredir_handle_status(dev, status, 0);
553 e6472210 Hans de Goede
            }
554 e6472210 Hans de Goede
            return USB_RET_NAK;
555 69354a83 Hans de Goede
        }
556 69354a83 Hans de Goede
        DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep,
557 69354a83 Hans de Goede
                intp->status, intp->len);
558 69354a83 Hans de Goede
559 69354a83 Hans de Goede
        status = intp->status;
560 69354a83 Hans de Goede
        if (status != usb_redir_success) {
561 69354a83 Hans de Goede
            bufp_free(dev, intp, ep);
562 69354a83 Hans de Goede
            return usbredir_handle_status(dev, status, 0);
563 69354a83 Hans de Goede
        }
564 69354a83 Hans de Goede
565 69354a83 Hans de Goede
        len = intp->len;
566 4f4321c1 Gerd Hoffmann
        if (len > p->iov.size) {
567 69354a83 Hans de Goede
            ERROR("received int data is larger then packet ep %02X\n", ep);
568 69354a83 Hans de Goede
            bufp_free(dev, intp, ep);
569 69354a83 Hans de Goede
            return USB_RET_NAK;
570 69354a83 Hans de Goede
        }
571 4f4321c1 Gerd Hoffmann
        usb_packet_copy(p, intp->data, len);
572 69354a83 Hans de Goede
        bufp_free(dev, intp, ep);
573 69354a83 Hans de Goede
        return len;
574 69354a83 Hans de Goede
    } else {
575 69354a83 Hans de Goede
        /* Output interrupt endpoint, normal async operation */
576 69354a83 Hans de Goede
        AsyncURB *aurb = async_alloc(dev, p);
577 69354a83 Hans de Goede
        struct usb_redir_interrupt_packet_header interrupt_packet;
578 4f4321c1 Gerd Hoffmann
        uint8_t buf[p->iov.size];
579 69354a83 Hans de Goede
580 4f4321c1 Gerd Hoffmann
        DPRINTF("interrupt-out ep %02X len %zd id %u\n", ep, p->iov.size,
581 69354a83 Hans de Goede
                aurb->packet_id);
582 69354a83 Hans de Goede
583 69354a83 Hans de Goede
        interrupt_packet.endpoint  = ep;
584 4f4321c1 Gerd Hoffmann
        interrupt_packet.length    = p->iov.size;
585 69354a83 Hans de Goede
        aurb->interrupt_packet     = interrupt_packet;
586 69354a83 Hans de Goede
587 4f4321c1 Gerd Hoffmann
        usb_packet_copy(p, buf, p->iov.size);
588 4f4321c1 Gerd Hoffmann
        usbredir_log_data(dev, "interrupt data out:", buf, p->iov.size);
589 69354a83 Hans de Goede
        usbredirparser_send_interrupt_packet(dev->parser, aurb->packet_id,
590 4f4321c1 Gerd Hoffmann
                                        &interrupt_packet, buf, p->iov.size);
591 69354a83 Hans de Goede
        usbredirparser_do_write(dev->parser);
592 69354a83 Hans de Goede
        return USB_RET_ASYNC;
593 69354a83 Hans de Goede
    }
594 69354a83 Hans de Goede
}
595 69354a83 Hans de Goede
596 69354a83 Hans de Goede
static void usbredir_stop_interrupt_receiving(USBRedirDevice *dev,
597 69354a83 Hans de Goede
    uint8_t ep)
598 69354a83 Hans de Goede
{
599 69354a83 Hans de Goede
    struct usb_redir_stop_interrupt_receiving_header stop_interrupt_recv = {
600 69354a83 Hans de Goede
        .endpoint = ep
601 69354a83 Hans de Goede
    };
602 69354a83 Hans de Goede
    if (dev->endpoint[EP2I(ep)].interrupt_started) {
603 69354a83 Hans de Goede
        usbredirparser_send_stop_interrupt_receiving(dev->parser, 0,
604 69354a83 Hans de Goede
                                                     &stop_interrupt_recv);
605 69354a83 Hans de Goede
        DPRINTF("interrupt recv stopped ep %02X\n", ep);
606 69354a83 Hans de Goede
        dev->endpoint[EP2I(ep)].interrupt_started = 0;
607 69354a83 Hans de Goede
    }
608 2bd836e5 Hans de Goede
    dev->endpoint[EP2I(ep)].interrupt_error = 0;
609 69354a83 Hans de Goede
    usbredir_free_bufpq(dev, ep);
610 69354a83 Hans de Goede
}
611 69354a83 Hans de Goede
612 69354a83 Hans de Goede
static int usbredir_handle_data(USBDevice *udev, USBPacket *p)
613 69354a83 Hans de Goede
{
614 69354a83 Hans de Goede
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
615 69354a83 Hans de Goede
    uint8_t ep;
616 69354a83 Hans de Goede
617 079d0b7f Gerd Hoffmann
    ep = p->ep->nr;
618 69354a83 Hans de Goede
    if (p->pid == USB_TOKEN_IN) {
619 69354a83 Hans de Goede
        ep |= USB_DIR_IN;
620 69354a83 Hans de Goede
    }
621 69354a83 Hans de Goede
622 69354a83 Hans de Goede
    switch (dev->endpoint[EP2I(ep)].type) {
623 69354a83 Hans de Goede
    case USB_ENDPOINT_XFER_CONTROL:
624 69354a83 Hans de Goede
        ERROR("handle_data called for control transfer on ep %02X\n", ep);
625 69354a83 Hans de Goede
        return USB_RET_NAK;
626 69354a83 Hans de Goede
    case USB_ENDPOINT_XFER_ISOC:
627 69354a83 Hans de Goede
        return usbredir_handle_iso_data(dev, p, ep);
628 69354a83 Hans de Goede
    case USB_ENDPOINT_XFER_BULK:
629 3a93113a Dong Xu Wang
        return usbredir_handle_bulk_data(dev, p, ep);
630 69354a83 Hans de Goede
    case USB_ENDPOINT_XFER_INT:
631 3a93113a Dong Xu Wang
        return usbredir_handle_interrupt_data(dev, p, ep);
632 69354a83 Hans de Goede
    default:
633 69354a83 Hans de Goede
        ERROR("handle_data ep %02X has unknown type %d\n", ep,
634 69354a83 Hans de Goede
              dev->endpoint[EP2I(ep)].type);
635 69354a83 Hans de Goede
        return USB_RET_NAK;
636 69354a83 Hans de Goede
    }
637 69354a83 Hans de Goede
}
638 69354a83 Hans de Goede
639 69354a83 Hans de Goede
static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
640 69354a83 Hans de Goede
                                int config)
641 69354a83 Hans de Goede
{
642 69354a83 Hans de Goede
    struct usb_redir_set_configuration_header set_config;
643 69354a83 Hans de Goede
    AsyncURB *aurb = async_alloc(dev, p);
644 69354a83 Hans de Goede
    int i;
645 69354a83 Hans de Goede
646 69354a83 Hans de Goede
    DPRINTF("set config %d id %u\n", config, aurb->packet_id);
647 69354a83 Hans de Goede
648 69354a83 Hans de Goede
    for (i = 0; i < MAX_ENDPOINTS; i++) {
649 69354a83 Hans de Goede
        switch (dev->endpoint[i].type) {
650 69354a83 Hans de Goede
        case USB_ENDPOINT_XFER_ISOC:
651 69354a83 Hans de Goede
            usbredir_stop_iso_stream(dev, I2EP(i));
652 69354a83 Hans de Goede
            break;
653 69354a83 Hans de Goede
        case USB_ENDPOINT_XFER_INT:
654 69354a83 Hans de Goede
            if (i & 0x10) {
655 69354a83 Hans de Goede
                usbredir_stop_interrupt_receiving(dev, I2EP(i));
656 69354a83 Hans de Goede
            }
657 69354a83 Hans de Goede
            break;
658 69354a83 Hans de Goede
        }
659 69354a83 Hans de Goede
        usbredir_free_bufpq(dev, I2EP(i));
660 69354a83 Hans de Goede
    }
661 69354a83 Hans de Goede
662 69354a83 Hans de Goede
    set_config.configuration = config;
663 69354a83 Hans de Goede
    usbredirparser_send_set_configuration(dev->parser, aurb->packet_id,
664 69354a83 Hans de Goede
                                          &set_config);
665 69354a83 Hans de Goede
    usbredirparser_do_write(dev->parser);
666 69354a83 Hans de Goede
    return USB_RET_ASYNC;
667 69354a83 Hans de Goede
}
668 69354a83 Hans de Goede
669 69354a83 Hans de Goede
static int usbredir_get_config(USBRedirDevice *dev, USBPacket *p)
670 69354a83 Hans de Goede
{
671 69354a83 Hans de Goede
    AsyncURB *aurb = async_alloc(dev, p);
672 69354a83 Hans de Goede
673 69354a83 Hans de Goede
    DPRINTF("get config id %u\n", aurb->packet_id);
674 69354a83 Hans de Goede
675 69354a83 Hans de Goede
    aurb->get = 1;
676 69354a83 Hans de Goede
    usbredirparser_send_get_configuration(dev->parser, aurb->packet_id);
677 69354a83 Hans de Goede
    usbredirparser_do_write(dev->parser);
678 69354a83 Hans de Goede
    return USB_RET_ASYNC;
679 69354a83 Hans de Goede
}
680 69354a83 Hans de Goede
681 69354a83 Hans de Goede
static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
682 69354a83 Hans de Goede
                                   int interface, int alt)
683 69354a83 Hans de Goede
{
684 69354a83 Hans de Goede
    struct usb_redir_set_alt_setting_header set_alt;
685 69354a83 Hans de Goede
    AsyncURB *aurb = async_alloc(dev, p);
686 69354a83 Hans de Goede
    int i;
687 69354a83 Hans de Goede
688 69354a83 Hans de Goede
    DPRINTF("set interface %d alt %d id %u\n", interface, alt,
689 69354a83 Hans de Goede
            aurb->packet_id);
690 69354a83 Hans de Goede
691 69354a83 Hans de Goede
    for (i = 0; i < MAX_ENDPOINTS; i++) {
692 69354a83 Hans de Goede
        if (dev->endpoint[i].interface == interface) {
693 69354a83 Hans de Goede
            switch (dev->endpoint[i].type) {
694 69354a83 Hans de Goede
            case USB_ENDPOINT_XFER_ISOC:
695 69354a83 Hans de Goede
                usbredir_stop_iso_stream(dev, I2EP(i));
696 69354a83 Hans de Goede
                break;
697 69354a83 Hans de Goede
            case USB_ENDPOINT_XFER_INT:
698 69354a83 Hans de Goede
                if (i & 0x10) {
699 69354a83 Hans de Goede
                    usbredir_stop_interrupt_receiving(dev, I2EP(i));
700 69354a83 Hans de Goede
                }
701 69354a83 Hans de Goede
                break;
702 69354a83 Hans de Goede
            }
703 69354a83 Hans de Goede
            usbredir_free_bufpq(dev, I2EP(i));
704 69354a83 Hans de Goede
        }
705 69354a83 Hans de Goede
    }
706 69354a83 Hans de Goede
707 69354a83 Hans de Goede
    set_alt.interface = interface;
708 69354a83 Hans de Goede
    set_alt.alt = alt;
709 69354a83 Hans de Goede
    usbredirparser_send_set_alt_setting(dev->parser, aurb->packet_id,
710 69354a83 Hans de Goede
                                        &set_alt);
711 69354a83 Hans de Goede
    usbredirparser_do_write(dev->parser);
712 69354a83 Hans de Goede
    return USB_RET_ASYNC;
713 69354a83 Hans de Goede
}
714 69354a83 Hans de Goede
715 69354a83 Hans de Goede
static int usbredir_get_interface(USBRedirDevice *dev, USBPacket *p,
716 69354a83 Hans de Goede
                                   int interface)
717 69354a83 Hans de Goede
{
718 69354a83 Hans de Goede
    struct usb_redir_get_alt_setting_header get_alt;
719 69354a83 Hans de Goede
    AsyncURB *aurb = async_alloc(dev, p);
720 69354a83 Hans de Goede
721 69354a83 Hans de Goede
    DPRINTF("get interface %d id %u\n", interface, aurb->packet_id);
722 69354a83 Hans de Goede
723 69354a83 Hans de Goede
    get_alt.interface = interface;
724 69354a83 Hans de Goede
    aurb->get = 1;
725 69354a83 Hans de Goede
    usbredirparser_send_get_alt_setting(dev->parser, aurb->packet_id,
726 69354a83 Hans de Goede
                                        &get_alt);
727 69354a83 Hans de Goede
    usbredirparser_do_write(dev->parser);
728 69354a83 Hans de Goede
    return USB_RET_ASYNC;
729 69354a83 Hans de Goede
}
730 69354a83 Hans de Goede
731 69354a83 Hans de Goede
static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
732 69354a83 Hans de Goede
        int request, int value, int index, int length, uint8_t *data)
733 69354a83 Hans de Goede
{
734 69354a83 Hans de Goede
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
735 69354a83 Hans de Goede
    struct usb_redir_control_packet_header control_packet;
736 69354a83 Hans de Goede
    AsyncURB *aurb;
737 69354a83 Hans de Goede
738 69354a83 Hans de Goede
    /* Special cases for certain standard device requests */
739 69354a83 Hans de Goede
    switch (request) {
740 69354a83 Hans de Goede
    case DeviceOutRequest | USB_REQ_SET_ADDRESS:
741 69354a83 Hans de Goede
        DPRINTF("set address %d\n", value);
742 69354a83 Hans de Goede
        dev->dev.addr = value;
743 69354a83 Hans de Goede
        return 0;
744 69354a83 Hans de Goede
    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
745 69354a83 Hans de Goede
        return usbredir_set_config(dev, p, value & 0xff);
746 69354a83 Hans de Goede
    case DeviceRequest | USB_REQ_GET_CONFIGURATION:
747 69354a83 Hans de Goede
        return usbredir_get_config(dev, p);
748 69354a83 Hans de Goede
    case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
749 69354a83 Hans de Goede
        return usbredir_set_interface(dev, p, index, value);
750 69354a83 Hans de Goede
    case InterfaceRequest | USB_REQ_GET_INTERFACE:
751 69354a83 Hans de Goede
        return usbredir_get_interface(dev, p, index);
752 69354a83 Hans de Goede
    }
753 69354a83 Hans de Goede
754 69354a83 Hans de Goede
    /* "Normal" ctrl requests */
755 69354a83 Hans de Goede
    aurb = async_alloc(dev, p);
756 69354a83 Hans de Goede
757 69354a83 Hans de Goede
    /* Note request is (bRequestType << 8) | bRequest */
758 69354a83 Hans de Goede
    DPRINTF("ctrl-out type 0x%x req 0x%x val 0x%x index %d len %d id %u\n",
759 69354a83 Hans de Goede
            request >> 8, request & 0xff, value, index, length,
760 69354a83 Hans de Goede
            aurb->packet_id);
761 69354a83 Hans de Goede
762 69354a83 Hans de Goede
    control_packet.request     = request & 0xFF;
763 69354a83 Hans de Goede
    control_packet.requesttype = request >> 8;
764 69354a83 Hans de Goede
    control_packet.endpoint    = control_packet.requesttype & USB_DIR_IN;
765 69354a83 Hans de Goede
    control_packet.value       = value;
766 69354a83 Hans de Goede
    control_packet.index       = index;
767 69354a83 Hans de Goede
    control_packet.length      = length;
768 69354a83 Hans de Goede
    aurb->control_packet       = control_packet;
769 69354a83 Hans de Goede
770 69354a83 Hans de Goede
    if (control_packet.requesttype & USB_DIR_IN) {
771 69354a83 Hans de Goede
        usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
772 69354a83 Hans de Goede
                                           &control_packet, NULL, 0);
773 69354a83 Hans de Goede
    } else {
774 69354a83 Hans de Goede
        usbredir_log_data(dev, "ctrl data out:", data, length);
775 69354a83 Hans de Goede
        usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
776 69354a83 Hans de Goede
                                           &control_packet, data, length);
777 69354a83 Hans de Goede
    }
778 69354a83 Hans de Goede
    usbredirparser_do_write(dev->parser);
779 69354a83 Hans de Goede
    return USB_RET_ASYNC;
780 69354a83 Hans de Goede
}
781 69354a83 Hans de Goede
782 69354a83 Hans de Goede
/*
783 69354a83 Hans de Goede
 * Close events can be triggered by usbredirparser_do_write which gets called
784 69354a83 Hans de Goede
 * from within the USBDevice data / control packet callbacks and doing a
785 69354a83 Hans de Goede
 * usb_detach from within these callbacks is not a good idea.
786 69354a83 Hans de Goede
 *
787 69354a83 Hans de Goede
 * So we use a bh handler to take care of close events. We also handle
788 69354a83 Hans de Goede
 * open events from this callback to make sure that a close directly followed
789 69354a83 Hans de Goede
 * by an open gets handled in the right order.
790 69354a83 Hans de Goede
 */
791 69354a83 Hans de Goede
static void usbredir_open_close_bh(void *opaque)
792 69354a83 Hans de Goede
{
793 69354a83 Hans de Goede
    USBRedirDevice *dev = opaque;
794 6af16589 Hans de Goede
    uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, };
795 69354a83 Hans de Goede
796 69354a83 Hans de Goede
    usbredir_device_disconnect(dev);
797 69354a83 Hans de Goede
798 69354a83 Hans de Goede
    if (dev->parser) {
799 69354a83 Hans de Goede
        usbredirparser_destroy(dev->parser);
800 69354a83 Hans de Goede
        dev->parser = NULL;
801 69354a83 Hans de Goede
    }
802 69354a83 Hans de Goede
803 69354a83 Hans de Goede
    if (dev->cs->opened) {
804 69354a83 Hans de Goede
        dev->parser = qemu_oom_check(usbredirparser_create());
805 69354a83 Hans de Goede
        dev->parser->priv = dev;
806 69354a83 Hans de Goede
        dev->parser->log_func = usbredir_log;
807 69354a83 Hans de Goede
        dev->parser->read_func = usbredir_read;
808 69354a83 Hans de Goede
        dev->parser->write_func = usbredir_write;
809 097a66ef Hans de Goede
        dev->parser->hello_func = usbredir_hello;
810 69354a83 Hans de Goede
        dev->parser->device_connect_func = usbredir_device_connect;
811 69354a83 Hans de Goede
        dev->parser->device_disconnect_func = usbredir_device_disconnect;
812 69354a83 Hans de Goede
        dev->parser->interface_info_func = usbredir_interface_info;
813 69354a83 Hans de Goede
        dev->parser->ep_info_func = usbredir_ep_info;
814 69354a83 Hans de Goede
        dev->parser->configuration_status_func = usbredir_configuration_status;
815 69354a83 Hans de Goede
        dev->parser->alt_setting_status_func = usbredir_alt_setting_status;
816 69354a83 Hans de Goede
        dev->parser->iso_stream_status_func = usbredir_iso_stream_status;
817 69354a83 Hans de Goede
        dev->parser->interrupt_receiving_status_func =
818 69354a83 Hans de Goede
            usbredir_interrupt_receiving_status;
819 69354a83 Hans de Goede
        dev->parser->bulk_streams_status_func = usbredir_bulk_streams_status;
820 69354a83 Hans de Goede
        dev->parser->control_packet_func = usbredir_control_packet;
821 69354a83 Hans de Goede
        dev->parser->bulk_packet_func = usbredir_bulk_packet;
822 69354a83 Hans de Goede
        dev->parser->iso_packet_func = usbredir_iso_packet;
823 69354a83 Hans de Goede
        dev->parser->interrupt_packet_func = usbredir_interrupt_packet;
824 69354a83 Hans de Goede
        dev->read_buf = NULL;
825 69354a83 Hans de Goede
        dev->read_buf_size = 0;
826 6af16589 Hans de Goede
827 6af16589 Hans de Goede
        usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version);
828 097a66ef Hans de Goede
        usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
829 6af16589 Hans de Goede
        usbredirparser_init(dev->parser, VERSION, caps, USB_REDIR_CAPS_SIZE, 0);
830 69354a83 Hans de Goede
        usbredirparser_do_write(dev->parser);
831 69354a83 Hans de Goede
    }
832 69354a83 Hans de Goede
}
833 69354a83 Hans de Goede
834 69354a83 Hans de Goede
static void usbredir_do_attach(void *opaque)
835 69354a83 Hans de Goede
{
836 69354a83 Hans de Goede
    USBRedirDevice *dev = opaque;
837 69354a83 Hans de Goede
838 69354a83 Hans de Goede
    usb_device_attach(&dev->dev);
839 69354a83 Hans de Goede
}
840 69354a83 Hans de Goede
841 69354a83 Hans de Goede
/*
842 69354a83 Hans de Goede
 * chardev callbacks
843 69354a83 Hans de Goede
 */
844 69354a83 Hans de Goede
845 69354a83 Hans de Goede
static int usbredir_chardev_can_read(void *opaque)
846 69354a83 Hans de Goede
{
847 69354a83 Hans de Goede
    USBRedirDevice *dev = opaque;
848 69354a83 Hans de Goede
849 69354a83 Hans de Goede
    if (dev->parser) {
850 69354a83 Hans de Goede
        /* usbredir_parser_do_read will consume *all* data we give it */
851 69354a83 Hans de Goede
        return 1024 * 1024;
852 69354a83 Hans de Goede
    } else {
853 69354a83 Hans de Goede
        /* usbredir_open_close_bh hasn't handled the open event yet */
854 69354a83 Hans de Goede
        return 0;
855 69354a83 Hans de Goede
    }
856 69354a83 Hans de Goede
}
857 69354a83 Hans de Goede
858 69354a83 Hans de Goede
static void usbredir_chardev_read(void *opaque, const uint8_t *buf, int size)
859 69354a83 Hans de Goede
{
860 69354a83 Hans de Goede
    USBRedirDevice *dev = opaque;
861 69354a83 Hans de Goede
862 69354a83 Hans de Goede
    /* No recursion allowed! */
863 69354a83 Hans de Goede
    assert(dev->read_buf == NULL);
864 69354a83 Hans de Goede
865 69354a83 Hans de Goede
    dev->read_buf = buf;
866 69354a83 Hans de Goede
    dev->read_buf_size = size;
867 69354a83 Hans de Goede
868 69354a83 Hans de Goede
    usbredirparser_do_read(dev->parser);
869 69354a83 Hans de Goede
    /* Send any acks, etc. which may be queued now */
870 69354a83 Hans de Goede
    usbredirparser_do_write(dev->parser);
871 69354a83 Hans de Goede
}
872 69354a83 Hans de Goede
873 69354a83 Hans de Goede
static void usbredir_chardev_event(void *opaque, int event)
874 69354a83 Hans de Goede
{
875 69354a83 Hans de Goede
    USBRedirDevice *dev = opaque;
876 69354a83 Hans de Goede
877 69354a83 Hans de Goede
    switch (event) {
878 69354a83 Hans de Goede
    case CHR_EVENT_OPENED:
879 69354a83 Hans de Goede
    case CHR_EVENT_CLOSED:
880 69354a83 Hans de Goede
        qemu_bh_schedule(dev->open_close_bh);
881 69354a83 Hans de Goede
        break;
882 69354a83 Hans de Goede
    }
883 69354a83 Hans de Goede
}
884 69354a83 Hans de Goede
885 69354a83 Hans de Goede
/*
886 69354a83 Hans de Goede
 * init + destroy
887 69354a83 Hans de Goede
 */
888 69354a83 Hans de Goede
889 69354a83 Hans de Goede
static int usbredir_initfn(USBDevice *udev)
890 69354a83 Hans de Goede
{
891 69354a83 Hans de Goede
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
892 69354a83 Hans de Goede
    int i;
893 69354a83 Hans de Goede
894 69354a83 Hans de Goede
    if (dev->cs == NULL) {
895 69354a83 Hans de Goede
        qerror_report(QERR_MISSING_PARAMETER, "chardev");
896 69354a83 Hans de Goede
        return -1;
897 69354a83 Hans de Goede
    }
898 69354a83 Hans de Goede
899 6af16589 Hans de Goede
    if (dev->filter_str) {
900 6af16589 Hans de Goede
        i = usbredirfilter_string_to_rules(dev->filter_str, ":", "|",
901 6af16589 Hans de Goede
                                           &dev->filter_rules,
902 6af16589 Hans de Goede
                                           &dev->filter_rules_count);
903 6af16589 Hans de Goede
        if (i) {
904 6af16589 Hans de Goede
            qerror_report(QERR_INVALID_PARAMETER_VALUE, "filter",
905 6af16589 Hans de Goede
                          "a usb device filter string");
906 6af16589 Hans de Goede
            return -1;
907 6af16589 Hans de Goede
        }
908 6af16589 Hans de Goede
    }
909 6af16589 Hans de Goede
910 69354a83 Hans de Goede
    dev->open_close_bh = qemu_bh_new(usbredir_open_close_bh, dev);
911 69354a83 Hans de Goede
    dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
912 69354a83 Hans de Goede
913 69354a83 Hans de Goede
    QTAILQ_INIT(&dev->asyncq);
914 69354a83 Hans de Goede
    for (i = 0; i < MAX_ENDPOINTS; i++) {
915 69354a83 Hans de Goede
        QTAILQ_INIT(&dev->endpoint[i].bufpq);
916 69354a83 Hans de Goede
    }
917 69354a83 Hans de Goede
918 69354a83 Hans de Goede
    /* We'll do the attach once we receive the speed from the usb-host */
919 69354a83 Hans de Goede
    udev->auto_attach = 0;
920 69354a83 Hans de Goede
921 65f9d986 Hans de Goede
    /* Let the backend know we are ready */
922 65f9d986 Hans de Goede
    qemu_chr_fe_open(dev->cs);
923 69354a83 Hans de Goede
    qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
924 69354a83 Hans de Goede
                          usbredir_chardev_read, usbredir_chardev_event, dev);
925 69354a83 Hans de Goede
926 69354a83 Hans de Goede
    return 0;
927 69354a83 Hans de Goede
}
928 69354a83 Hans de Goede
929 69354a83 Hans de Goede
static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
930 69354a83 Hans de Goede
{
931 69354a83 Hans de Goede
    AsyncURB *aurb, *next_aurb;
932 69354a83 Hans de Goede
    int i;
933 69354a83 Hans de Goede
934 69354a83 Hans de Goede
    QTAILQ_FOREACH_SAFE(aurb, &dev->asyncq, next, next_aurb) {
935 69354a83 Hans de Goede
        async_free(dev, aurb);
936 69354a83 Hans de Goede
    }
937 69354a83 Hans de Goede
    for (i = 0; i < MAX_ENDPOINTS; i++) {
938 69354a83 Hans de Goede
        usbredir_free_bufpq(dev, I2EP(i));
939 69354a83 Hans de Goede
    }
940 69354a83 Hans de Goede
}
941 69354a83 Hans de Goede
942 69354a83 Hans de Goede
static void usbredir_handle_destroy(USBDevice *udev)
943 69354a83 Hans de Goede
{
944 69354a83 Hans de Goede
    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
945 69354a83 Hans de Goede
946 65f9d986 Hans de Goede
    qemu_chr_fe_close(dev->cs);
947 70f24fb6 Anthony Liguori
    qemu_chr_delete(dev->cs);
948 69354a83 Hans de Goede
    /* Note must be done after qemu_chr_close, as that causes a close event */
949 69354a83 Hans de Goede
    qemu_bh_delete(dev->open_close_bh);
950 69354a83 Hans de Goede
951 69354a83 Hans de Goede
    qemu_del_timer(dev->attach_timer);
952 69354a83 Hans de Goede
    qemu_free_timer(dev->attach_timer);
953 69354a83 Hans de Goede
954 69354a83 Hans de Goede
    usbredir_cleanup_device_queues(dev);
955 69354a83 Hans de Goede
956 69354a83 Hans de Goede
    if (dev->parser) {
957 69354a83 Hans de Goede
        usbredirparser_destroy(dev->parser);
958 69354a83 Hans de Goede
    }
959 6af16589 Hans de Goede
960 6af16589 Hans de Goede
    free(dev->filter_rules);
961 6af16589 Hans de Goede
}
962 6af16589 Hans de Goede
963 6af16589 Hans de Goede
static int usbredir_check_filter(USBRedirDevice *dev)
964 6af16589 Hans de Goede
{
965 6af16589 Hans de Goede
    if (dev->interface_info.interface_count == 0) {
966 6af16589 Hans de Goede
        ERROR("No interface info for device\n");
967 5b3bd682 Hans de Goede
        goto error;
968 6af16589 Hans de Goede
    }
969 6af16589 Hans de Goede
970 6af16589 Hans de Goede
    if (dev->filter_rules) {
971 6af16589 Hans de Goede
        if (!usbredirparser_peer_has_cap(dev->parser,
972 6af16589 Hans de Goede
                                    usb_redir_cap_connect_device_version)) {
973 6af16589 Hans de Goede
            ERROR("Device filter specified and peer does not have the "
974 6af16589 Hans de Goede
                  "connect_device_version capability\n");
975 5b3bd682 Hans de Goede
            goto error;
976 6af16589 Hans de Goede
        }
977 6af16589 Hans de Goede
978 6af16589 Hans de Goede
        if (usbredirfilter_check(
979 6af16589 Hans de Goede
                dev->filter_rules,
980 6af16589 Hans de Goede
                dev->filter_rules_count,
981 6af16589 Hans de Goede
                dev->device_info.device_class,
982 6af16589 Hans de Goede
                dev->device_info.device_subclass,
983 6af16589 Hans de Goede
                dev->device_info.device_protocol,
984 6af16589 Hans de Goede
                dev->interface_info.interface_class,
985 6af16589 Hans de Goede
                dev->interface_info.interface_subclass,
986 6af16589 Hans de Goede
                dev->interface_info.interface_protocol,
987 6af16589 Hans de Goede
                dev->interface_info.interface_count,
988 6af16589 Hans de Goede
                dev->device_info.vendor_id,
989 6af16589 Hans de Goede
                dev->device_info.product_id,
990 6af16589 Hans de Goede
                dev->device_info.device_version_bcd,
991 6af16589 Hans de Goede
                0) != 0) {
992 5b3bd682 Hans de Goede
            goto error;
993 6af16589 Hans de Goede
        }
994 6af16589 Hans de Goede
    }
995 6af16589 Hans de Goede
996 6af16589 Hans de Goede
    return 0;
997 5b3bd682 Hans de Goede
998 5b3bd682 Hans de Goede
error:
999 5b3bd682 Hans de Goede
    usbredir_device_disconnect(dev);
1000 097a66ef Hans de Goede
    if (usbredirparser_peer_has_cap(dev->parser, usb_redir_cap_filter)) {
1001 097a66ef Hans de Goede
        usbredirparser_send_filter_reject(dev->parser);
1002 097a66ef Hans de Goede
        usbredirparser_do_write(dev->parser);
1003 097a66ef Hans de Goede
    }
1004 5b3bd682 Hans de Goede
    return -1;
1005 69354a83 Hans de Goede
}
1006 69354a83 Hans de Goede
1007 69354a83 Hans de Goede
/*
1008 69354a83 Hans de Goede
 * usbredirparser packet complete callbacks
1009 69354a83 Hans de Goede
 */
1010 69354a83 Hans de Goede
1011 69354a83 Hans de Goede
static int usbredir_handle_status(USBRedirDevice *dev,
1012 69354a83 Hans de Goede
                                       int status, int actual_len)
1013 69354a83 Hans de Goede
{
1014 69354a83 Hans de Goede
    switch (status) {
1015 69354a83 Hans de Goede
    case usb_redir_success:
1016 69354a83 Hans de Goede
        return actual_len;
1017 69354a83 Hans de Goede
    case usb_redir_stall:
1018 69354a83 Hans de Goede
        return USB_RET_STALL;
1019 69354a83 Hans de Goede
    case usb_redir_cancelled:
1020 69354a83 Hans de Goede
        WARNING("returning cancelled packet to HC?\n");
1021 69354a83 Hans de Goede
    case usb_redir_inval:
1022 69354a83 Hans de Goede
    case usb_redir_ioerror:
1023 69354a83 Hans de Goede
    case usb_redir_timeout:
1024 69354a83 Hans de Goede
    default:
1025 69354a83 Hans de Goede
        return USB_RET_NAK;
1026 69354a83 Hans de Goede
    }
1027 69354a83 Hans de Goede
}
1028 69354a83 Hans de Goede
1029 097a66ef Hans de Goede
static void usbredir_hello(void *priv, struct usb_redir_hello_header *h)
1030 097a66ef Hans de Goede
{
1031 097a66ef Hans de Goede
    USBRedirDevice *dev = priv;
1032 097a66ef Hans de Goede
1033 097a66ef Hans de Goede
    /* Try to send the filter info now that we've the usb-host's caps */
1034 097a66ef Hans de Goede
    if (usbredirparser_peer_has_cap(dev->parser, usb_redir_cap_filter) &&
1035 097a66ef Hans de Goede
            dev->filter_rules) {
1036 097a66ef Hans de Goede
        usbredirparser_send_filter_filter(dev->parser, dev->filter_rules,
1037 097a66ef Hans de Goede
                                          dev->filter_rules_count);
1038 097a66ef Hans de Goede
        usbredirparser_do_write(dev->parser);
1039 097a66ef Hans de Goede
    }
1040 097a66ef Hans de Goede
}
1041 097a66ef Hans de Goede
1042 69354a83 Hans de Goede
static void usbredir_device_connect(void *priv,
1043 69354a83 Hans de Goede
    struct usb_redir_device_connect_header *device_connect)
1044 69354a83 Hans de Goede
{
1045 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
1046 6af16589 Hans de Goede
    const char *speed;
1047 69354a83 Hans de Goede
1048 99f08100 Hans de Goede
    if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) {
1049 99f08100 Hans de Goede
        ERROR("Received device connect while already connected\n");
1050 99f08100 Hans de Goede
        return;
1051 99f08100 Hans de Goede
    }
1052 99f08100 Hans de Goede
1053 69354a83 Hans de Goede
    switch (device_connect->speed) {
1054 69354a83 Hans de Goede
    case usb_redir_speed_low:
1055 6af16589 Hans de Goede
        speed = "low speed";
1056 69354a83 Hans de Goede
        dev->dev.speed = USB_SPEED_LOW;
1057 69354a83 Hans de Goede
        break;
1058 69354a83 Hans de Goede
    case usb_redir_speed_full:
1059 6af16589 Hans de Goede
        speed = "full speed";
1060 69354a83 Hans de Goede
        dev->dev.speed = USB_SPEED_FULL;
1061 69354a83 Hans de Goede
        break;
1062 69354a83 Hans de Goede
    case usb_redir_speed_high:
1063 6af16589 Hans de Goede
        speed = "high speed";
1064 69354a83 Hans de Goede
        dev->dev.speed = USB_SPEED_HIGH;
1065 69354a83 Hans de Goede
        break;
1066 69354a83 Hans de Goede
    case usb_redir_speed_super:
1067 6af16589 Hans de Goede
        speed = "super speed";
1068 69354a83 Hans de Goede
        dev->dev.speed = USB_SPEED_SUPER;
1069 69354a83 Hans de Goede
        break;
1070 69354a83 Hans de Goede
    default:
1071 6af16589 Hans de Goede
        speed = "unknown speed";
1072 69354a83 Hans de Goede
        dev->dev.speed = USB_SPEED_FULL;
1073 69354a83 Hans de Goede
    }
1074 6af16589 Hans de Goede
1075 6af16589 Hans de Goede
    if (usbredirparser_peer_has_cap(dev->parser,
1076 6af16589 Hans de Goede
                                    usb_redir_cap_connect_device_version)) {
1077 6af16589 Hans de Goede
        INFO("attaching %s device %04x:%04x version %d.%d class %02x\n",
1078 6af16589 Hans de Goede
             speed, device_connect->vendor_id, device_connect->product_id,
1079 52234bc0 Hans de Goede
             ((device_connect->device_version_bcd & 0xf000) >> 12) * 10 +
1080 52234bc0 Hans de Goede
             ((device_connect->device_version_bcd & 0x0f00) >>  8),
1081 52234bc0 Hans de Goede
             ((device_connect->device_version_bcd & 0x00f0) >>  4) * 10 +
1082 52234bc0 Hans de Goede
             ((device_connect->device_version_bcd & 0x000f) >>  0),
1083 6af16589 Hans de Goede
             device_connect->device_class);
1084 6af16589 Hans de Goede
    } else {
1085 6af16589 Hans de Goede
        INFO("attaching %s device %04x:%04x class %02x\n", speed,
1086 6af16589 Hans de Goede
             device_connect->vendor_id, device_connect->product_id,
1087 6af16589 Hans de Goede
             device_connect->device_class);
1088 6af16589 Hans de Goede
    }
1089 6af16589 Hans de Goede
1090 69354a83 Hans de Goede
    dev->dev.speedmask = (1 << dev->dev.speed);
1091 6af16589 Hans de Goede
    dev->device_info = *device_connect;
1092 6af16589 Hans de Goede
1093 6af16589 Hans de Goede
    if (usbredir_check_filter(dev)) {
1094 6af16589 Hans de Goede
        WARNING("Device %04x:%04x rejected by device filter, not attaching\n",
1095 6af16589 Hans de Goede
                device_connect->vendor_id, device_connect->product_id);
1096 6af16589 Hans de Goede
        return;
1097 6af16589 Hans de Goede
    }
1098 6af16589 Hans de Goede
1099 69354a83 Hans de Goede
    qemu_mod_timer(dev->attach_timer, dev->next_attach_time);
1100 69354a83 Hans de Goede
}
1101 69354a83 Hans de Goede
1102 69354a83 Hans de Goede
static void usbredir_device_disconnect(void *priv)
1103 69354a83 Hans de Goede
{
1104 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
1105 99f08100 Hans de Goede
    int i;
1106 69354a83 Hans de Goede
1107 69354a83 Hans de Goede
    /* Stop any pending attaches */
1108 69354a83 Hans de Goede
    qemu_del_timer(dev->attach_timer);
1109 69354a83 Hans de Goede
1110 69354a83 Hans de Goede
    if (dev->dev.attached) {
1111 69354a83 Hans de Goede
        usb_device_detach(&dev->dev);
1112 69354a83 Hans de Goede
        /*
1113 69354a83 Hans de Goede
         * Delay next usb device attach to give the guest a chance to see
1114 69354a83 Hans de Goede
         * see the detach / attach in case of quick close / open succession
1115 69354a83 Hans de Goede
         */
1116 69354a83 Hans de Goede
        dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;
1117 69354a83 Hans de Goede
    }
1118 99f08100 Hans de Goede
1119 99f08100 Hans de Goede
    /* Reset state so that the next dev connected starts with a clean slate */
1120 99f08100 Hans de Goede
    usbredir_cleanup_device_queues(dev);
1121 99f08100 Hans de Goede
    memset(dev->endpoint, 0, sizeof(dev->endpoint));
1122 99f08100 Hans de Goede
    for (i = 0; i < MAX_ENDPOINTS; i++) {
1123 99f08100 Hans de Goede
        QTAILQ_INIT(&dev->endpoint[i].bufpq);
1124 99f08100 Hans de Goede
    }
1125 6af16589 Hans de Goede
    dev->interface_info.interface_count = 0;
1126 69354a83 Hans de Goede
}
1127 69354a83 Hans de Goede
1128 69354a83 Hans de Goede
static void usbredir_interface_info(void *priv,
1129 69354a83 Hans de Goede
    struct usb_redir_interface_info_header *interface_info)
1130 69354a83 Hans de Goede
{
1131 6af16589 Hans de Goede
    USBRedirDevice *dev = priv;
1132 6af16589 Hans de Goede
1133 6af16589 Hans de Goede
    dev->interface_info = *interface_info;
1134 6af16589 Hans de Goede
1135 6af16589 Hans de Goede
    /*
1136 6af16589 Hans de Goede
     * If we receive interface info after the device has already been
1137 6af16589 Hans de Goede
     * connected (ie on a set_config), re-check the filter.
1138 6af16589 Hans de Goede
     */
1139 6af16589 Hans de Goede
    if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) {
1140 6af16589 Hans de Goede
        if (usbredir_check_filter(dev)) {
1141 6af16589 Hans de Goede
            ERROR("Device no longer matches filter after interface info "
1142 6af16589 Hans de Goede
                  "change, disconnecting!\n");
1143 6af16589 Hans de Goede
        }
1144 6af16589 Hans de Goede
    }
1145 69354a83 Hans de Goede
}
1146 69354a83 Hans de Goede
1147 69354a83 Hans de Goede
static void usbredir_ep_info(void *priv,
1148 69354a83 Hans de Goede
    struct usb_redir_ep_info_header *ep_info)
1149 69354a83 Hans de Goede
{
1150 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
1151 69354a83 Hans de Goede
    int i;
1152 69354a83 Hans de Goede
1153 69354a83 Hans de Goede
    for (i = 0; i < MAX_ENDPOINTS; i++) {
1154 69354a83 Hans de Goede
        dev->endpoint[i].type = ep_info->type[i];
1155 69354a83 Hans de Goede
        dev->endpoint[i].interval = ep_info->interval[i];
1156 69354a83 Hans de Goede
        dev->endpoint[i].interface = ep_info->interface[i];
1157 e8a7dd29 Hans de Goede
        switch (dev->endpoint[i].type) {
1158 e8a7dd29 Hans de Goede
        case usb_redir_type_invalid:
1159 e8a7dd29 Hans de Goede
            break;
1160 e8a7dd29 Hans de Goede
        case usb_redir_type_iso:
1161 e8a7dd29 Hans de Goede
        case usb_redir_type_interrupt:
1162 e8a7dd29 Hans de Goede
            if (dev->endpoint[i].interval == 0) {
1163 e8a7dd29 Hans de Goede
                ERROR("Received 0 interval for isoc or irq endpoint\n");
1164 e8a7dd29 Hans de Goede
                usbredir_device_disconnect(dev);
1165 e8a7dd29 Hans de Goede
            }
1166 e8a7dd29 Hans de Goede
            /* Fall through */
1167 e8a7dd29 Hans de Goede
        case usb_redir_type_control:
1168 e8a7dd29 Hans de Goede
        case usb_redir_type_bulk:
1169 69354a83 Hans de Goede
            DPRINTF("ep: %02X type: %d interface: %d\n", I2EP(i),
1170 69354a83 Hans de Goede
                    dev->endpoint[i].type, dev->endpoint[i].interface);
1171 e8a7dd29 Hans de Goede
            break;
1172 e8a7dd29 Hans de Goede
        default:
1173 e8a7dd29 Hans de Goede
            ERROR("Received invalid endpoint type\n");
1174 e8a7dd29 Hans de Goede
            usbredir_device_disconnect(dev);
1175 69354a83 Hans de Goede
        }
1176 69354a83 Hans de Goede
    }
1177 69354a83 Hans de Goede
}
1178 69354a83 Hans de Goede
1179 69354a83 Hans de Goede
static void usbredir_configuration_status(void *priv, uint32_t id,
1180 69354a83 Hans de Goede
    struct usb_redir_configuration_status_header *config_status)
1181 69354a83 Hans de Goede
{
1182 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
1183 69354a83 Hans de Goede
    AsyncURB *aurb;
1184 69354a83 Hans de Goede
    int len = 0;
1185 69354a83 Hans de Goede
1186 69354a83 Hans de Goede
    DPRINTF("set config status %d config %d id %u\n", config_status->status,
1187 69354a83 Hans de Goede
            config_status->configuration, id);
1188 69354a83 Hans de Goede
1189 69354a83 Hans de Goede
    aurb = async_find(dev, id);
1190 69354a83 Hans de Goede
    if (!aurb) {
1191 69354a83 Hans de Goede
        return;
1192 69354a83 Hans de Goede
    }
1193 69354a83 Hans de Goede
    if (aurb->packet) {
1194 69354a83 Hans de Goede
        if (aurb->get) {
1195 69354a83 Hans de Goede
            dev->dev.data_buf[0] = config_status->configuration;
1196 69354a83 Hans de Goede
            len = 1;
1197 69354a83 Hans de Goede
        }
1198 4f4321c1 Gerd Hoffmann
        aurb->packet->result =
1199 69354a83 Hans de Goede
            usbredir_handle_status(dev, config_status->status, len);
1200 69354a83 Hans de Goede
        usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1201 69354a83 Hans de Goede
    }
1202 69354a83 Hans de Goede
    async_free(dev, aurb);
1203 69354a83 Hans de Goede
}
1204 69354a83 Hans de Goede
1205 69354a83 Hans de Goede
static void usbredir_alt_setting_status(void *priv, uint32_t id,
1206 69354a83 Hans de Goede
    struct usb_redir_alt_setting_status_header *alt_setting_status)
1207 69354a83 Hans de Goede
{
1208 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
1209 69354a83 Hans de Goede
    AsyncURB *aurb;
1210 69354a83 Hans de Goede
    int len = 0;
1211 69354a83 Hans de Goede
1212 69354a83 Hans de Goede
    DPRINTF("alt status %d intf %d alt %d id: %u\n",
1213 69354a83 Hans de Goede
            alt_setting_status->status,
1214 69354a83 Hans de Goede
            alt_setting_status->interface,
1215 69354a83 Hans de Goede
            alt_setting_status->alt, id);
1216 69354a83 Hans de Goede
1217 69354a83 Hans de Goede
    aurb = async_find(dev, id);
1218 69354a83 Hans de Goede
    if (!aurb) {
1219 69354a83 Hans de Goede
        return;
1220 69354a83 Hans de Goede
    }
1221 69354a83 Hans de Goede
    if (aurb->packet) {
1222 69354a83 Hans de Goede
        if (aurb->get) {
1223 69354a83 Hans de Goede
            dev->dev.data_buf[0] = alt_setting_status->alt;
1224 69354a83 Hans de Goede
            len = 1;
1225 69354a83 Hans de Goede
        }
1226 4f4321c1 Gerd Hoffmann
        aurb->packet->result =
1227 69354a83 Hans de Goede
            usbredir_handle_status(dev, alt_setting_status->status, len);
1228 69354a83 Hans de Goede
        usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1229 69354a83 Hans de Goede
    }
1230 69354a83 Hans de Goede
    async_free(dev, aurb);
1231 69354a83 Hans de Goede
}
1232 69354a83 Hans de Goede
1233 69354a83 Hans de Goede
static void usbredir_iso_stream_status(void *priv, uint32_t id,
1234 69354a83 Hans de Goede
    struct usb_redir_iso_stream_status_header *iso_stream_status)
1235 69354a83 Hans de Goede
{
1236 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
1237 69354a83 Hans de Goede
    uint8_t ep = iso_stream_status->endpoint;
1238 69354a83 Hans de Goede
1239 69354a83 Hans de Goede
    DPRINTF("iso status %d ep %02X id %u\n", iso_stream_status->status,
1240 69354a83 Hans de Goede
            ep, id);
1241 69354a83 Hans de Goede
1242 2bd836e5 Hans de Goede
    if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].iso_started) {
1243 99f08100 Hans de Goede
        return;
1244 99f08100 Hans de Goede
    }
1245 99f08100 Hans de Goede
1246 69354a83 Hans de Goede
    dev->endpoint[EP2I(ep)].iso_error = iso_stream_status->status;
1247 69354a83 Hans de Goede
    if (iso_stream_status->status == usb_redir_stall) {
1248 69354a83 Hans de Goede
        DPRINTF("iso stream stopped by peer ep %02X\n", ep);
1249 69354a83 Hans de Goede
        dev->endpoint[EP2I(ep)].iso_started = 0;
1250 69354a83 Hans de Goede
    }
1251 69354a83 Hans de Goede
}
1252 69354a83 Hans de Goede
1253 69354a83 Hans de Goede
static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
1254 69354a83 Hans de Goede
    struct usb_redir_interrupt_receiving_status_header
1255 69354a83 Hans de Goede
    *interrupt_receiving_status)
1256 69354a83 Hans de Goede
{
1257 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
1258 69354a83 Hans de Goede
    uint8_t ep = interrupt_receiving_status->endpoint;
1259 69354a83 Hans de Goede
1260 69354a83 Hans de Goede
    DPRINTF("interrupt recv status %d ep %02X id %u\n",
1261 69354a83 Hans de Goede
            interrupt_receiving_status->status, ep, id);
1262 69354a83 Hans de Goede
1263 2bd836e5 Hans de Goede
    if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].interrupt_started) {
1264 99f08100 Hans de Goede
        return;
1265 99f08100 Hans de Goede
    }
1266 99f08100 Hans de Goede
1267 69354a83 Hans de Goede
    dev->endpoint[EP2I(ep)].interrupt_error =
1268 69354a83 Hans de Goede
        interrupt_receiving_status->status;
1269 69354a83 Hans de Goede
    if (interrupt_receiving_status->status == usb_redir_stall) {
1270 69354a83 Hans de Goede
        DPRINTF("interrupt receiving stopped by peer ep %02X\n", ep);
1271 69354a83 Hans de Goede
        dev->endpoint[EP2I(ep)].interrupt_started = 0;
1272 69354a83 Hans de Goede
    }
1273 69354a83 Hans de Goede
}
1274 69354a83 Hans de Goede
1275 69354a83 Hans de Goede
static void usbredir_bulk_streams_status(void *priv, uint32_t id,
1276 69354a83 Hans de Goede
    struct usb_redir_bulk_streams_status_header *bulk_streams_status)
1277 69354a83 Hans de Goede
{
1278 69354a83 Hans de Goede
}
1279 69354a83 Hans de Goede
1280 69354a83 Hans de Goede
static void usbredir_control_packet(void *priv, uint32_t id,
1281 69354a83 Hans de Goede
    struct usb_redir_control_packet_header *control_packet,
1282 69354a83 Hans de Goede
    uint8_t *data, int data_len)
1283 69354a83 Hans de Goede
{
1284 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
1285 69354a83 Hans de Goede
    int len = control_packet->length;
1286 69354a83 Hans de Goede
    AsyncURB *aurb;
1287 69354a83 Hans de Goede
1288 69354a83 Hans de Goede
    DPRINTF("ctrl-in status %d len %d id %u\n", control_packet->status,
1289 69354a83 Hans de Goede
            len, id);
1290 69354a83 Hans de Goede
1291 69354a83 Hans de Goede
    aurb = async_find(dev, id);
1292 69354a83 Hans de Goede
    if (!aurb) {
1293 69354a83 Hans de Goede
        free(data);
1294 69354a83 Hans de Goede
        return;
1295 69354a83 Hans de Goede
    }
1296 69354a83 Hans de Goede
1297 69354a83 Hans de Goede
    aurb->control_packet.status = control_packet->status;
1298 69354a83 Hans de Goede
    aurb->control_packet.length = control_packet->length;
1299 69354a83 Hans de Goede
    if (memcmp(&aurb->control_packet, control_packet,
1300 69354a83 Hans de Goede
               sizeof(*control_packet))) {
1301 69354a83 Hans de Goede
        ERROR("return control packet mismatch, please report this!\n");
1302 69354a83 Hans de Goede
        len = USB_RET_NAK;
1303 69354a83 Hans de Goede
    }
1304 69354a83 Hans de Goede
1305 69354a83 Hans de Goede
    if (aurb->packet) {
1306 69354a83 Hans de Goede
        len = usbredir_handle_status(dev, control_packet->status, len);
1307 69354a83 Hans de Goede
        if (len > 0) {
1308 69354a83 Hans de Goede
            usbredir_log_data(dev, "ctrl data in:", data, data_len);
1309 69354a83 Hans de Goede
            if (data_len <= sizeof(dev->dev.data_buf)) {
1310 69354a83 Hans de Goede
                memcpy(dev->dev.data_buf, data, data_len);
1311 69354a83 Hans de Goede
            } else {
1312 69354a83 Hans de Goede
                ERROR("ctrl buffer too small (%d > %zu)\n",
1313 69354a83 Hans de Goede
                      data_len, sizeof(dev->dev.data_buf));
1314 69354a83 Hans de Goede
                len = USB_RET_STALL;
1315 69354a83 Hans de Goede
            }
1316 69354a83 Hans de Goede
        }
1317 4f4321c1 Gerd Hoffmann
        aurb->packet->result = len;
1318 69354a83 Hans de Goede
        usb_generic_async_ctrl_complete(&dev->dev, aurb->packet);
1319 69354a83 Hans de Goede
    }
1320 69354a83 Hans de Goede
    async_free(dev, aurb);
1321 69354a83 Hans de Goede
    free(data);
1322 69354a83 Hans de Goede
}
1323 69354a83 Hans de Goede
1324 69354a83 Hans de Goede
static void usbredir_bulk_packet(void *priv, uint32_t id,
1325 69354a83 Hans de Goede
    struct usb_redir_bulk_packet_header *bulk_packet,
1326 69354a83 Hans de Goede
    uint8_t *data, int data_len)
1327 69354a83 Hans de Goede
{
1328 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
1329 69354a83 Hans de Goede
    uint8_t ep = bulk_packet->endpoint;
1330 69354a83 Hans de Goede
    int len = bulk_packet->length;
1331 69354a83 Hans de Goede
    AsyncURB *aurb;
1332 69354a83 Hans de Goede
1333 69354a83 Hans de Goede
    DPRINTF("bulk-in status %d ep %02X len %d id %u\n", bulk_packet->status,
1334 69354a83 Hans de Goede
            ep, len, id);
1335 69354a83 Hans de Goede
1336 69354a83 Hans de Goede
    aurb = async_find(dev, id);
1337 69354a83 Hans de Goede
    if (!aurb) {
1338 69354a83 Hans de Goede
        free(data);
1339 69354a83 Hans de Goede
        return;
1340 69354a83 Hans de Goede
    }
1341 69354a83 Hans de Goede
1342 69354a83 Hans de Goede
    if (aurb->bulk_packet.endpoint != bulk_packet->endpoint ||
1343 69354a83 Hans de Goede
            aurb->bulk_packet.stream_id != bulk_packet->stream_id) {
1344 69354a83 Hans de Goede
        ERROR("return bulk packet mismatch, please report this!\n");
1345 69354a83 Hans de Goede
        len = USB_RET_NAK;
1346 69354a83 Hans de Goede
    }
1347 69354a83 Hans de Goede
1348 69354a83 Hans de Goede
    if (aurb->packet) {
1349 69354a83 Hans de Goede
        len = usbredir_handle_status(dev, bulk_packet->status, len);
1350 69354a83 Hans de Goede
        if (len > 0) {
1351 69354a83 Hans de Goede
            usbredir_log_data(dev, "bulk data in:", data, data_len);
1352 4f4321c1 Gerd Hoffmann
            if (data_len <= aurb->packet->iov.size) {
1353 4f4321c1 Gerd Hoffmann
                usb_packet_copy(aurb->packet, data, data_len);
1354 69354a83 Hans de Goede
            } else {
1355 4f4321c1 Gerd Hoffmann
                ERROR("bulk buffer too small (%d > %zd)\n", data_len,
1356 4f4321c1 Gerd Hoffmann
                      aurb->packet->iov.size);
1357 69354a83 Hans de Goede
                len = USB_RET_STALL;
1358 69354a83 Hans de Goede
            }
1359 69354a83 Hans de Goede
        }
1360 4f4321c1 Gerd Hoffmann
        aurb->packet->result = len;
1361 69354a83 Hans de Goede
        usb_packet_complete(&dev->dev, aurb->packet);
1362 69354a83 Hans de Goede
    }
1363 69354a83 Hans de Goede
    async_free(dev, aurb);
1364 69354a83 Hans de Goede
    free(data);
1365 69354a83 Hans de Goede
}
1366 69354a83 Hans de Goede
1367 69354a83 Hans de Goede
static void usbredir_iso_packet(void *priv, uint32_t id,
1368 69354a83 Hans de Goede
    struct usb_redir_iso_packet_header *iso_packet,
1369 69354a83 Hans de Goede
    uint8_t *data, int data_len)
1370 69354a83 Hans de Goede
{
1371 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
1372 69354a83 Hans de Goede
    uint8_t ep = iso_packet->endpoint;
1373 69354a83 Hans de Goede
1374 69354a83 Hans de Goede
    DPRINTF2("iso-in status %d ep %02X len %d id %u\n", iso_packet->status, ep,
1375 69354a83 Hans de Goede
             data_len, id);
1376 69354a83 Hans de Goede
1377 69354a83 Hans de Goede
    if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_ISOC) {
1378 69354a83 Hans de Goede
        ERROR("received iso packet for non iso endpoint %02X\n", ep);
1379 69354a83 Hans de Goede
        free(data);
1380 69354a83 Hans de Goede
        return;
1381 69354a83 Hans de Goede
    }
1382 69354a83 Hans de Goede
1383 69354a83 Hans de Goede
    if (dev->endpoint[EP2I(ep)].iso_started == 0) {
1384 69354a83 Hans de Goede
        DPRINTF("received iso packet for non started stream ep %02X\n", ep);
1385 69354a83 Hans de Goede
        free(data);
1386 69354a83 Hans de Goede
        return;
1387 69354a83 Hans de Goede
    }
1388 69354a83 Hans de Goede
1389 69354a83 Hans de Goede
    /* bufp_alloc also adds the packet to the ep queue */
1390 69354a83 Hans de Goede
    bufp_alloc(dev, data, data_len, iso_packet->status, ep);
1391 69354a83 Hans de Goede
}
1392 69354a83 Hans de Goede
1393 69354a83 Hans de Goede
static void usbredir_interrupt_packet(void *priv, uint32_t id,
1394 69354a83 Hans de Goede
    struct usb_redir_interrupt_packet_header *interrupt_packet,
1395 69354a83 Hans de Goede
    uint8_t *data, int data_len)
1396 69354a83 Hans de Goede
{
1397 69354a83 Hans de Goede
    USBRedirDevice *dev = priv;
1398 69354a83 Hans de Goede
    uint8_t ep = interrupt_packet->endpoint;
1399 69354a83 Hans de Goede
1400 69354a83 Hans de Goede
    DPRINTF("interrupt-in status %d ep %02X len %d id %u\n",
1401 69354a83 Hans de Goede
            interrupt_packet->status, ep, data_len, id);
1402 69354a83 Hans de Goede
1403 69354a83 Hans de Goede
    if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) {
1404 69354a83 Hans de Goede
        ERROR("received int packet for non interrupt endpoint %02X\n", ep);
1405 69354a83 Hans de Goede
        free(data);
1406 69354a83 Hans de Goede
        return;
1407 69354a83 Hans de Goede
    }
1408 69354a83 Hans de Goede
1409 69354a83 Hans de Goede
    if (ep & USB_DIR_IN) {
1410 69354a83 Hans de Goede
        if (dev->endpoint[EP2I(ep)].interrupt_started == 0) {
1411 69354a83 Hans de Goede
            DPRINTF("received int packet while not started ep %02X\n", ep);
1412 69354a83 Hans de Goede
            free(data);
1413 69354a83 Hans de Goede
            return;
1414 69354a83 Hans de Goede
        }
1415 69354a83 Hans de Goede
1416 69354a83 Hans de Goede
        /* bufp_alloc also adds the packet to the ep queue */
1417 69354a83 Hans de Goede
        bufp_alloc(dev, data, data_len, interrupt_packet->status, ep);
1418 69354a83 Hans de Goede
    } else {
1419 69354a83 Hans de Goede
        int len = interrupt_packet->length;
1420 69354a83 Hans de Goede
1421 69354a83 Hans de Goede
        AsyncURB *aurb = async_find(dev, id);
1422 69354a83 Hans de Goede
        if (!aurb) {
1423 69354a83 Hans de Goede
            return;
1424 69354a83 Hans de Goede
        }
1425 69354a83 Hans de Goede
1426 69354a83 Hans de Goede
        if (aurb->interrupt_packet.endpoint != interrupt_packet->endpoint) {
1427 69354a83 Hans de Goede
            ERROR("return int packet mismatch, please report this!\n");
1428 69354a83 Hans de Goede
            len = USB_RET_NAK;
1429 69354a83 Hans de Goede
        }
1430 69354a83 Hans de Goede
1431 69354a83 Hans de Goede
        if (aurb->packet) {
1432 4f4321c1 Gerd Hoffmann
            aurb->packet->result = usbredir_handle_status(dev,
1433 69354a83 Hans de Goede
                                               interrupt_packet->status, len);
1434 69354a83 Hans de Goede
            usb_packet_complete(&dev->dev, aurb->packet);
1435 69354a83 Hans de Goede
        }
1436 69354a83 Hans de Goede
        async_free(dev, aurb);
1437 69354a83 Hans de Goede
    }
1438 69354a83 Hans de Goede
}
1439 69354a83 Hans de Goede
1440 3bc36349 Anthony Liguori
static Property usbredir_properties[] = {
1441 3bc36349 Anthony Liguori
    DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
1442 3bc36349 Anthony Liguori
    DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0),
1443 6af16589 Hans de Goede
    DEFINE_PROP_STRING("filter", USBRedirDevice, filter_str),
1444 3bc36349 Anthony Liguori
    DEFINE_PROP_END_OF_LIST(),
1445 3bc36349 Anthony Liguori
};
1446 3bc36349 Anthony Liguori
1447 62aed765 Anthony Liguori
static void usbredir_class_initfn(ObjectClass *klass, void *data)
1448 62aed765 Anthony Liguori
{
1449 62aed765 Anthony Liguori
    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
1450 3bc36349 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
1451 62aed765 Anthony Liguori
1452 62aed765 Anthony Liguori
    uc->init           = usbredir_initfn;
1453 62aed765 Anthony Liguori
    uc->product_desc   = "USB Redirection Device";
1454 62aed765 Anthony Liguori
    uc->handle_destroy = usbredir_handle_destroy;
1455 62aed765 Anthony Liguori
    uc->cancel_packet  = usbredir_cancel_packet;
1456 62aed765 Anthony Liguori
    uc->handle_reset   = usbredir_handle_reset;
1457 62aed765 Anthony Liguori
    uc->handle_data    = usbredir_handle_data;
1458 62aed765 Anthony Liguori
    uc->handle_control = usbredir_handle_control;
1459 3bc36349 Anthony Liguori
    dc->props          = usbredir_properties;
1460 62aed765 Anthony Liguori
}
1461 62aed765 Anthony Liguori
1462 3bc36349 Anthony Liguori
static TypeInfo usbredir_dev_info = {
1463 3bc36349 Anthony Liguori
    .name          = "usb-redir",
1464 3bc36349 Anthony Liguori
    .parent        = TYPE_USB_DEVICE,
1465 3bc36349 Anthony Liguori
    .instance_size = sizeof(USBRedirDevice),
1466 3bc36349 Anthony Liguori
    .class_init    = usbredir_class_initfn,
1467 69354a83 Hans de Goede
};
1468 69354a83 Hans de Goede
1469 83f7d43a Andreas Färber
static void usbredir_register_types(void)
1470 69354a83 Hans de Goede
{
1471 3bc36349 Anthony Liguori
    type_register_static(&usbredir_dev_info);
1472 69354a83 Hans de Goede
}
1473 83f7d43a Andreas Färber
1474 83f7d43a Andreas Färber
type_init(usbredir_register_types)