Statistics
| Branch: | Revision:

root / usb-redir.c @ 079d0b7f

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