Statistics
| Branch: | Revision:

root / hw / usb / host-linux.c @ 873123fe

History | View | Annotate | Download (56.4 kB)

1 bb36d470 bellard
/*
2 bb36d470 bellard
 * Linux host USB redirector
3 bb36d470 bellard
 *
4 bb36d470 bellard
 * Copyright (c) 2005 Fabrice Bellard
5 5fafdf24 ths
 *
6 64838171 aliguori
 * Copyright (c) 2008 Max Krasnyansky
7 64838171 aliguori
 *      Support for host device auto connect & disconnect
8 5d0c5750 aliguori
 *      Major rewrite to support fully async operation
9 4b096fc9 aliguori
 *
10 0f431527 aliguori
 * Copyright 2008 TJ <linux@tjworld.net>
11 0f431527 aliguori
 *      Added flexible support for /dev/bus/usb /sys/bus/usb/devices in addition
12 0f431527 aliguori
 *      to the legacy /proc/bus/usb USB device discovery and handling
13 0f431527 aliguori
 *
14 bb36d470 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
15 bb36d470 bellard
 * of this software and associated documentation files (the "Software"), to deal
16 bb36d470 bellard
 * in the Software without restriction, including without limitation the rights
17 bb36d470 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18 bb36d470 bellard
 * copies of the Software, and to permit persons to whom the Software is
19 bb36d470 bellard
 * furnished to do so, subject to the following conditions:
20 bb36d470 bellard
 *
21 bb36d470 bellard
 * The above copyright notice and this permission notice shall be included in
22 bb36d470 bellard
 * all copies or substantial portions of the Software.
23 bb36d470 bellard
 *
24 bb36d470 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 bb36d470 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 bb36d470 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 bb36d470 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 bb36d470 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 bb36d470 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30 bb36d470 bellard
 * THE SOFTWARE.
31 bb36d470 bellard
 */
32 446ab128 aliguori
33 87ecb68b pbrook
#include "qemu-common.h"
34 1f3870ab aliguori
#include "qemu-timer.h"
35 376253ec aliguori
#include "monitor.h"
36 b373a63a Shahar Havivi
#include "sysemu.h"
37 e6a2f500 Gerd Hoffmann
#include "trace.h"
38 bb36d470 bellard
39 bb36d470 bellard
#include <dirent.h>
40 bb36d470 bellard
#include <sys/ioctl.h>
41 bb36d470 bellard
42 446ab128 aliguori
#include <linux/usbdevice_fs.h>
43 446ab128 aliguori
#include <linux/version.h>
44 446ab128 aliguori
#include "hw/usb.h"
45 96dd9aac Gerd Hoffmann
#include "hw/usb/desc.h"
46 bb36d470 bellard
47 d9cf1578 blueswir1
/* We redefine it to avoid version problems */
48 d9cf1578 blueswir1
struct usb_ctrltransfer {
49 d9cf1578 blueswir1
    uint8_t  bRequestType;
50 d9cf1578 blueswir1
    uint8_t  bRequest;
51 d9cf1578 blueswir1
    uint16_t wValue;
52 d9cf1578 blueswir1
    uint16_t wIndex;
53 d9cf1578 blueswir1
    uint16_t wLength;
54 d9cf1578 blueswir1
    uint32_t timeout;
55 d9cf1578 blueswir1
    void *data;
56 d9cf1578 blueswir1
};
57 d9cf1578 blueswir1
58 ba9acab9 Gerd Hoffmann
typedef int USBScanFunc(void *opaque, int bus_num, int addr, const char *port,
59 0f5160d1 Hans de Goede
                        int class_id, int vendor_id, int product_id,
60 a594cfbf bellard
                        const char *product_name, int speed);
61 26a9e82a Gerd Hoffmann
62 0745eb1e Markus Armbruster
//#define DEBUG
63 64838171 aliguori
64 64838171 aliguori
#ifdef DEBUG
65 d0f2c4c6 malc
#define DPRINTF printf
66 64838171 aliguori
#else
67 d0f2c4c6 malc
#define DPRINTF(...)
68 64838171 aliguori
#endif
69 bb36d470 bellard
70 1f6e24e7 bellard
#define PRODUCT_NAME_SZ 32
71 5557d820 Gerd Hoffmann
#define MAX_PORTLEN 16
72 bb36d470 bellard
73 b9dc033c balrog
/* endpoint association data */
74 060dc841 Hans de Goede
#define ISO_FRAME_DESC_PER_URB 32
75 060dc841 Hans de Goede
76 71138531 Gerd Hoffmann
/* devio.c limits single requests to 16k */
77 71138531 Gerd Hoffmann
#define MAX_USBFS_BUFFER_SIZE 16384
78 71138531 Gerd Hoffmann
79 060dc841 Hans de Goede
typedef struct AsyncURB AsyncURB;
80 060dc841 Hans de Goede
81 b9dc033c balrog
struct endp_data {
82 64838171 aliguori
    uint8_t halted;
83 bb6d5498 Hans de Goede
    uint8_t iso_started;
84 060dc841 Hans de Goede
    AsyncURB *iso_urb;
85 060dc841 Hans de Goede
    int iso_urb_idx;
86 bb6d5498 Hans de Goede
    int iso_buffer_used;
87 82887262 Gerd Hoffmann
    int inflight;
88 b9dc033c balrog
};
89 b9dc033c balrog
90 26a9e82a Gerd Hoffmann
struct USBAutoFilter {
91 26a9e82a Gerd Hoffmann
    uint32_t bus_num;
92 26a9e82a Gerd Hoffmann
    uint32_t addr;
93 9056a297 Gerd Hoffmann
    char     *port;
94 26a9e82a Gerd Hoffmann
    uint32_t vendor_id;
95 26a9e82a Gerd Hoffmann
    uint32_t product_id;
96 26a9e82a Gerd Hoffmann
};
97 26a9e82a Gerd Hoffmann
98 39c20577 Gerd Hoffmann
enum USBHostDeviceOptions {
99 39c20577 Gerd Hoffmann
    USB_HOST_OPT_PIPELINE,
100 39c20577 Gerd Hoffmann
};
101 39c20577 Gerd Hoffmann
102 bb36d470 bellard
typedef struct USBHostDevice {
103 bb36d470 bellard
    USBDevice dev;
104 64838171 aliguori
    int       fd;
105 9516bb47 Gerd Hoffmann
    int       hub_fd;
106 c75fead6 Gerd Hoffmann
    int       hub_port;
107 64838171 aliguori
108 f8ddbfbc Hans de Goede
    uint8_t   descr[8192];
109 64838171 aliguori
    int       descr_len;
110 24772c1e aliguori
    int       closing;
111 b81bcd8a Gerd Hoffmann
    uint32_t  iso_urb_count;
112 39c20577 Gerd Hoffmann
    uint32_t  options;
113 b373a63a Shahar Havivi
    Notifier  exit;
114 a229c053 Gerd Hoffmann
    QEMUBH    *bh;
115 64838171 aliguori
116 d8e17efd Gerd Hoffmann
    struct endp_data ep_in[USB_MAX_ENDPOINTS];
117 d8e17efd Gerd Hoffmann
    struct endp_data ep_out[USB_MAX_ENDPOINTS];
118 7a8fc83f Gerd Hoffmann
    QLIST_HEAD(, AsyncURB) aurbs;
119 4b096fc9 aliguori
120 4b096fc9 aliguori
    /* Host side address */
121 4b096fc9 aliguori
    int bus_num;
122 4b096fc9 aliguori
    int addr;
123 5557d820 Gerd Hoffmann
    char port[MAX_PORTLEN];
124 26a9e82a Gerd Hoffmann
    struct USBAutoFilter match;
125 65bb3a5c Gerd Hoffmann
    int32_t bootindex;
126 3ee886c5 Gerd Hoffmann
    int seen, errcount;
127 4b096fc9 aliguori
128 26a9e82a Gerd Hoffmann
    QTAILQ_ENTRY(USBHostDevice) next;
129 bb36d470 bellard
} USBHostDevice;
130 bb36d470 bellard
131 26a9e82a Gerd Hoffmann
static QTAILQ_HEAD(, USBHostDevice) hostdevs = QTAILQ_HEAD_INITIALIZER(hostdevs);
132 26a9e82a Gerd Hoffmann
133 26a9e82a Gerd Hoffmann
static int usb_host_close(USBHostDevice *dev);
134 26a9e82a Gerd Hoffmann
static int parse_filter(const char *spec, struct USBAutoFilter *f);
135 26a9e82a Gerd Hoffmann
static void usb_host_auto_check(void *unused);
136 2cc59d8c Hans de Goede
static int usb_host_read_file(char *line, size_t line_size,
137 2cc59d8c Hans de Goede
                            const char *device_file, const char *device_name);
138 9b87e19b Gerd Hoffmann
static int usb_linux_update_endp_table(USBHostDevice *s);
139 26a9e82a Gerd Hoffmann
140 d8e17efd Gerd Hoffmann
static int usb_host_usbfs_type(USBHostDevice *s, USBPacket *p)
141 d8e17efd Gerd Hoffmann
{
142 d8e17efd Gerd Hoffmann
    static const int usbfs[] = {
143 d8e17efd Gerd Hoffmann
        [USB_ENDPOINT_XFER_CONTROL] = USBDEVFS_URB_TYPE_CONTROL,
144 d8e17efd Gerd Hoffmann
        [USB_ENDPOINT_XFER_ISOC]    = USBDEVFS_URB_TYPE_ISO,
145 d8e17efd Gerd Hoffmann
        [USB_ENDPOINT_XFER_BULK]    = USBDEVFS_URB_TYPE_BULK,
146 d8e17efd Gerd Hoffmann
        [USB_ENDPOINT_XFER_INT]     = USBDEVFS_URB_TYPE_INTERRUPT,
147 d8e17efd Gerd Hoffmann
    };
148 079d0b7f Gerd Hoffmann
    uint8_t type = p->ep->type;
149 d8e17efd Gerd Hoffmann
    assert(type < ARRAY_SIZE(usbfs));
150 d8e17efd Gerd Hoffmann
    return usbfs[type];
151 d8e17efd Gerd Hoffmann
}
152 d8e17efd Gerd Hoffmann
153 c7662daa Gerd Hoffmann
static int usb_host_do_reset(USBHostDevice *dev)
154 c7662daa Gerd Hoffmann
{
155 c7662daa Gerd Hoffmann
    struct timeval s, e;
156 c7662daa Gerd Hoffmann
    uint32_t usecs;
157 c7662daa Gerd Hoffmann
    int ret;
158 c7662daa Gerd Hoffmann
159 c7662daa Gerd Hoffmann
    gettimeofday(&s, NULL);
160 c7662daa Gerd Hoffmann
    ret = ioctl(dev->fd, USBDEVFS_RESET);
161 c7662daa Gerd Hoffmann
    gettimeofday(&e, NULL);
162 c7662daa Gerd Hoffmann
    usecs = (e.tv_sec  - s.tv_sec) * 1000000;
163 c7662daa Gerd Hoffmann
    usecs += e.tv_usec - s.tv_usec;
164 c7662daa Gerd Hoffmann
    if (usecs > 1000000) {
165 c7662daa Gerd Hoffmann
        /* more than a second, something is fishy, broken usb device? */
166 c7662daa Gerd Hoffmann
        fprintf(stderr, "husb: device %d:%d reset took %d.%06d seconds\n",
167 c7662daa Gerd Hoffmann
                dev->bus_num, dev->addr, usecs / 1000000, usecs % 1000000);
168 c7662daa Gerd Hoffmann
    }
169 c7662daa Gerd Hoffmann
    return ret;
170 c7662daa Gerd Hoffmann
}
171 c7662daa Gerd Hoffmann
172 c0e5750b Gerd Hoffmann
static struct endp_data *get_endp(USBHostDevice *s, int pid, int ep)
173 ca3a36cf Gerd Hoffmann
{
174 c0e5750b Gerd Hoffmann
    struct endp_data *eps = pid == USB_TOKEN_IN ? s->ep_in : s->ep_out;
175 c0e5750b Gerd Hoffmann
    assert(pid == USB_TOKEN_IN || pid == USB_TOKEN_OUT);
176 d8e17efd Gerd Hoffmann
    assert(ep > 0 && ep <= USB_MAX_ENDPOINTS);
177 c0e5750b Gerd Hoffmann
    return eps + ep - 1;
178 ca3a36cf Gerd Hoffmann
}
179 ca3a36cf Gerd Hoffmann
180 c0e5750b Gerd Hoffmann
static int is_isoc(USBHostDevice *s, int pid, int ep)
181 64838171 aliguori
{
182 d8e17efd Gerd Hoffmann
    return usb_ep_get_type(&s->dev, pid, ep) == USB_ENDPOINT_XFER_ISOC;
183 64838171 aliguori
}
184 64838171 aliguori
185 c0e5750b Gerd Hoffmann
static int is_valid(USBHostDevice *s, int pid, int ep)
186 a0b5fece Hans de Goede
{
187 d8e17efd Gerd Hoffmann
    return usb_ep_get_type(&s->dev, pid, ep) != USB_ENDPOINT_XFER_INVALID;
188 a0b5fece Hans de Goede
}
189 a0b5fece Hans de Goede
190 c0e5750b Gerd Hoffmann
static int is_halted(USBHostDevice *s, int pid, int ep)
191 64838171 aliguori
{
192 c0e5750b Gerd Hoffmann
    return get_endp(s, pid, ep)->halted;
193 64838171 aliguori
}
194 64838171 aliguori
195 c0e5750b Gerd Hoffmann
static void clear_halt(USBHostDevice *s, int pid, int ep)
196 64838171 aliguori
{
197 e6a2f500 Gerd Hoffmann
    trace_usb_host_ep_clear_halt(s->bus_num, s->addr, ep);
198 c0e5750b Gerd Hoffmann
    get_endp(s, pid, ep)->halted = 0;
199 64838171 aliguori
}
200 64838171 aliguori
201 c0e5750b Gerd Hoffmann
static void set_halt(USBHostDevice *s, int pid, int ep)
202 64838171 aliguori
{
203 c0e5750b Gerd Hoffmann
    if (ep != 0) {
204 c0e5750b Gerd Hoffmann
        trace_usb_host_ep_set_halt(s->bus_num, s->addr, ep);
205 c0e5750b Gerd Hoffmann
        get_endp(s, pid, ep)->halted = 1;
206 c0e5750b Gerd Hoffmann
    }
207 64838171 aliguori
}
208 64838171 aliguori
209 c0e5750b Gerd Hoffmann
static int is_iso_started(USBHostDevice *s, int pid, int ep)
210 bb6d5498 Hans de Goede
{
211 c0e5750b Gerd Hoffmann
    return get_endp(s, pid, ep)->iso_started;
212 bb6d5498 Hans de Goede
}
213 bb6d5498 Hans de Goede
214 c0e5750b Gerd Hoffmann
static void clear_iso_started(USBHostDevice *s, int pid, int ep)
215 bb6d5498 Hans de Goede
{
216 c32da151 Gerd Hoffmann
    trace_usb_host_iso_stop(s->bus_num, s->addr, ep);
217 c0e5750b Gerd Hoffmann
    get_endp(s, pid, ep)->iso_started = 0;
218 bb6d5498 Hans de Goede
}
219 bb6d5498 Hans de Goede
220 c0e5750b Gerd Hoffmann
static void set_iso_started(USBHostDevice *s, int pid, int ep)
221 bb6d5498 Hans de Goede
{
222 c0e5750b Gerd Hoffmann
    struct endp_data *e = get_endp(s, pid, ep);
223 e6a2f500 Gerd Hoffmann
224 c32da151 Gerd Hoffmann
    trace_usb_host_iso_start(s->bus_num, s->addr, ep);
225 82887262 Gerd Hoffmann
    if (!e->iso_started) {
226 82887262 Gerd Hoffmann
        e->iso_started = 1;
227 82887262 Gerd Hoffmann
        e->inflight = 0;
228 82887262 Gerd Hoffmann
    }
229 82887262 Gerd Hoffmann
}
230 82887262 Gerd Hoffmann
231 c0e5750b Gerd Hoffmann
static int change_iso_inflight(USBHostDevice *s, int pid, int ep, int value)
232 82887262 Gerd Hoffmann
{
233 c0e5750b Gerd Hoffmann
    struct endp_data *e = get_endp(s, pid, ep);
234 82887262 Gerd Hoffmann
235 82887262 Gerd Hoffmann
    e->inflight += value;
236 82887262 Gerd Hoffmann
    return e->inflight;
237 bb6d5498 Hans de Goede
}
238 bb6d5498 Hans de Goede
239 c0e5750b Gerd Hoffmann
static void set_iso_urb(USBHostDevice *s, int pid, int ep, AsyncURB *iso_urb)
240 060dc841 Hans de Goede
{
241 c0e5750b Gerd Hoffmann
    get_endp(s, pid, ep)->iso_urb = iso_urb;
242 060dc841 Hans de Goede
}
243 060dc841 Hans de Goede
244 c0e5750b Gerd Hoffmann
static AsyncURB *get_iso_urb(USBHostDevice *s, int pid, int ep)
245 060dc841 Hans de Goede
{
246 c0e5750b Gerd Hoffmann
    return get_endp(s, pid, ep)->iso_urb;
247 060dc841 Hans de Goede
}
248 060dc841 Hans de Goede
249 c0e5750b Gerd Hoffmann
static void set_iso_urb_idx(USBHostDevice *s, int pid, int ep, int i)
250 060dc841 Hans de Goede
{
251 c0e5750b Gerd Hoffmann
    get_endp(s, pid, ep)->iso_urb_idx = i;
252 060dc841 Hans de Goede
}
253 060dc841 Hans de Goede
254 c0e5750b Gerd Hoffmann
static int get_iso_urb_idx(USBHostDevice *s, int pid, int ep)
255 060dc841 Hans de Goede
{
256 c0e5750b Gerd Hoffmann
    return get_endp(s, pid, ep)->iso_urb_idx;
257 060dc841 Hans de Goede
}
258 060dc841 Hans de Goede
259 c0e5750b Gerd Hoffmann
static void set_iso_buffer_used(USBHostDevice *s, int pid, int ep, int i)
260 bb6d5498 Hans de Goede
{
261 c0e5750b Gerd Hoffmann
    get_endp(s, pid, ep)->iso_buffer_used = i;
262 bb6d5498 Hans de Goede
}
263 bb6d5498 Hans de Goede
264 c0e5750b Gerd Hoffmann
static int get_iso_buffer_used(USBHostDevice *s, int pid, int ep)
265 bb6d5498 Hans de Goede
{
266 c0e5750b Gerd Hoffmann
    return get_endp(s, pid, ep)->iso_buffer_used;
267 bb6d5498 Hans de Goede
}
268 bb6d5498 Hans de Goede
269 2791104c David Ahern
/*
270 64838171 aliguori
 * Async URB state.
271 060dc841 Hans de Goede
 * We always allocate iso packet descriptors even for bulk transfers
272 2791104c David Ahern
 * to simplify allocation and casts.
273 64838171 aliguori
 */
274 060dc841 Hans de Goede
struct AsyncURB
275 64838171 aliguori
{
276 64838171 aliguori
    struct usbdevfs_urb urb;
277 060dc841 Hans de Goede
    struct usbdevfs_iso_packet_desc isocpd[ISO_FRAME_DESC_PER_URB];
278 7a8fc83f Gerd Hoffmann
    USBHostDevice *hdev;
279 7a8fc83f Gerd Hoffmann
    QLIST_ENTRY(AsyncURB) next;
280 b9dc033c balrog
281 060dc841 Hans de Goede
    /* For regular async urbs */
282 64838171 aliguori
    USBPacket     *packet;
283 71138531 Gerd Hoffmann
    int more; /* large transfer, more urbs follow */
284 060dc841 Hans de Goede
285 060dc841 Hans de Goede
    /* For buffered iso handling */
286 060dc841 Hans de Goede
    int iso_frame_idx; /* -1 means in flight */
287 060dc841 Hans de Goede
};
288 b9dc033c balrog
289 7a8fc83f Gerd Hoffmann
static AsyncURB *async_alloc(USBHostDevice *s)
290 b9dc033c balrog
{
291 7267c094 Anthony Liguori
    AsyncURB *aurb = g_malloc0(sizeof(AsyncURB));
292 7a8fc83f Gerd Hoffmann
    aurb->hdev = s;
293 7a8fc83f Gerd Hoffmann
    QLIST_INSERT_HEAD(&s->aurbs, aurb, next);
294 7a8fc83f Gerd Hoffmann
    return aurb;
295 b9dc033c balrog
}
296 b9dc033c balrog
297 64838171 aliguori
static void async_free(AsyncURB *aurb)
298 b9dc033c balrog
{
299 7a8fc83f Gerd Hoffmann
    QLIST_REMOVE(aurb, next);
300 7267c094 Anthony Liguori
    g_free(aurb);
301 64838171 aliguori
}
302 b9dc033c balrog
303 41c01ee7 Gerd Hoffmann
static void do_disconnect(USBHostDevice *s)
304 41c01ee7 Gerd Hoffmann
{
305 41c01ee7 Gerd Hoffmann
    usb_host_close(s);
306 41c01ee7 Gerd Hoffmann
    usb_host_auto_check(NULL);
307 41c01ee7 Gerd Hoffmann
}
308 41c01ee7 Gerd Hoffmann
309 64838171 aliguori
static void async_complete(void *opaque)
310 64838171 aliguori
{
311 64838171 aliguori
    USBHostDevice *s = opaque;
312 64838171 aliguori
    AsyncURB *aurb;
313 82887262 Gerd Hoffmann
    int urbs = 0;
314 64838171 aliguori
315 64838171 aliguori
    while (1) {
316 2791104c David Ahern
        USBPacket *p;
317 b9dc033c balrog
318 2791104c David Ahern
        int r = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &aurb);
319 64838171 aliguori
        if (r < 0) {
320 2791104c David Ahern
            if (errno == EAGAIN) {
321 82887262 Gerd Hoffmann
                if (urbs > 2) {
322 c32da151 Gerd Hoffmann
                    /* indicates possible latency issues */
323 c32da151 Gerd Hoffmann
                    trace_usb_host_iso_many_urbs(s->bus_num, s->addr, urbs);
324 82887262 Gerd Hoffmann
                }
325 64838171 aliguori
                return;
326 2791104c David Ahern
            }
327 40197c35 Gerd Hoffmann
            if (errno == ENODEV) {
328 40197c35 Gerd Hoffmann
                if (!s->closing) {
329 40197c35 Gerd Hoffmann
                    trace_usb_host_disconnect(s->bus_num, s->addr);
330 40197c35 Gerd Hoffmann
                    do_disconnect(s);
331 40197c35 Gerd Hoffmann
                }
332 64838171 aliguori
                return;
333 64838171 aliguori
            }
334 64838171 aliguori
335 e6a2f500 Gerd Hoffmann
            perror("USBDEVFS_REAPURBNDELAY");
336 64838171 aliguori
            return;
337 b9dc033c balrog
        }
338 64838171 aliguori
339 2791104c David Ahern
        DPRINTF("husb: async completed. aurb %p status %d alen %d\n",
340 64838171 aliguori
                aurb, aurb->urb.status, aurb->urb.actual_length);
341 64838171 aliguori
342 060dc841 Hans de Goede
        /* If this is a buffered iso urb mark it as complete and don't do
343 060dc841 Hans de Goede
           anything else (it is handled further in usb_host_handle_iso_data) */
344 060dc841 Hans de Goede
        if (aurb->iso_frame_idx == -1) {
345 82887262 Gerd Hoffmann
            int inflight;
346 c0e5750b Gerd Hoffmann
            int pid = (aurb->urb.endpoint & USB_DIR_IN) ?
347 c0e5750b Gerd Hoffmann
                USB_TOKEN_IN : USB_TOKEN_OUT;
348 c0e5750b Gerd Hoffmann
            int ep = aurb->urb.endpoint & 0xf;
349 060dc841 Hans de Goede
            if (aurb->urb.status == -EPIPE) {
350 c0e5750b Gerd Hoffmann
                set_halt(s, pid, ep);
351 060dc841 Hans de Goede
            }
352 060dc841 Hans de Goede
            aurb->iso_frame_idx = 0;
353 82887262 Gerd Hoffmann
            urbs++;
354 c0e5750b Gerd Hoffmann
            inflight = change_iso_inflight(s, pid, ep, -1);
355 c0e5750b Gerd Hoffmann
            if (inflight == 0 && is_iso_started(s, pid, ep)) {
356 c32da151 Gerd Hoffmann
                /* can be latency issues, or simply end of stream */
357 c32da151 Gerd Hoffmann
                trace_usb_host_iso_out_of_bufs(s->bus_num, s->addr, ep);
358 82887262 Gerd Hoffmann
            }
359 060dc841 Hans de Goede
            continue;
360 060dc841 Hans de Goede
        }
361 060dc841 Hans de Goede
362 060dc841 Hans de Goede
        p = aurb->packet;
363 e6a2f500 Gerd Hoffmann
        trace_usb_host_urb_complete(s->bus_num, s->addr, aurb, aurb->urb.status,
364 e6a2f500 Gerd Hoffmann
                                    aurb->urb.actual_length, aurb->more);
365 060dc841 Hans de Goede
366 2791104c David Ahern
        if (p) {
367 64838171 aliguori
            switch (aurb->urb.status) {
368 64838171 aliguori
            case 0:
369 4f4321c1 Gerd Hoffmann
                p->result += aurb->urb.actual_length;
370 64838171 aliguori
                break;
371 64838171 aliguori
372 64838171 aliguori
            case -EPIPE:
373 079d0b7f Gerd Hoffmann
                set_halt(s, p->pid, p->ep->nr);
374 4f4321c1 Gerd Hoffmann
                p->result = USB_RET_STALL;
375 2791104c David Ahern
                break;
376 dcc7e25f Paul Bolle
377 4d819a9b Hans de Goede
            case -EOVERFLOW:
378 4d819a9b Hans de Goede
                p->result = USB_RET_BABBLE;
379 4d819a9b Hans de Goede
                break;
380 4d819a9b Hans de Goede
381 64838171 aliguori
            default:
382 d61000a8 Hans de Goede
                p->result = USB_RET_IOERROR;
383 64838171 aliguori
                break;
384 64838171 aliguori
            }
385 64838171 aliguori
386 50b7963e Hans de Goede
            if (aurb->urb.type == USBDEVFS_URB_TYPE_CONTROL) {
387 19b89252 Gerd Hoffmann
                trace_usb_host_req_complete(s->bus_num, s->addr, p, p->result);
388 50b7963e Hans de Goede
                usb_generic_async_ctrl_complete(&s->dev, p);
389 71138531 Gerd Hoffmann
            } else if (!aurb->more) {
390 19b89252 Gerd Hoffmann
                trace_usb_host_req_complete(s->bus_num, s->addr, p, p->result);
391 50b7963e Hans de Goede
                usb_packet_complete(&s->dev, p);
392 50b7963e Hans de Goede
            }
393 2791104c David Ahern
        }
394 64838171 aliguori
395 64838171 aliguori
        async_free(aurb);
396 b9dc033c balrog
    }
397 b9dc033c balrog
}
398 b9dc033c balrog
399 eb5e680a Gerd Hoffmann
static void usb_host_async_cancel(USBDevice *dev, USBPacket *p)
400 b9dc033c balrog
{
401 eb5e680a Gerd Hoffmann
    USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
402 227ebeb5 Gerd Hoffmann
    AsyncURB *aurb;
403 b9dc033c balrog
404 19b89252 Gerd Hoffmann
    trace_usb_host_req_canceled(s->bus_num, s->addr, p);
405 6aebe407 Gerd Hoffmann
406 227ebeb5 Gerd Hoffmann
    QLIST_FOREACH(aurb, &s->aurbs, next) {
407 227ebeb5 Gerd Hoffmann
        if (p != aurb->packet) {
408 227ebeb5 Gerd Hoffmann
            continue;
409 227ebeb5 Gerd Hoffmann
        }
410 64838171 aliguori
411 6aebe407 Gerd Hoffmann
        trace_usb_host_urb_canceled(s->bus_num, s->addr, aurb);
412 b9dc033c balrog
413 227ebeb5 Gerd Hoffmann
        /* Mark it as dead (see async_complete above) */
414 227ebeb5 Gerd Hoffmann
        aurb->packet = NULL;
415 227ebeb5 Gerd Hoffmann
416 227ebeb5 Gerd Hoffmann
        int r = ioctl(s->fd, USBDEVFS_DISCARDURB, aurb);
417 227ebeb5 Gerd Hoffmann
        if (r < 0) {
418 227ebeb5 Gerd Hoffmann
            DPRINTF("husb: async. discard urb failed errno %d\n", errno);
419 227ebeb5 Gerd Hoffmann
        }
420 b9dc033c balrog
    }
421 b9dc033c balrog
}
422 b9dc033c balrog
423 097db438 Gerd Hoffmann
static int usb_host_open_device(int bus, int addr)
424 097db438 Gerd Hoffmann
{
425 097db438 Gerd Hoffmann
    const char *usbfs = NULL;
426 097db438 Gerd Hoffmann
    char filename[32];
427 097db438 Gerd Hoffmann
    struct stat st;
428 097db438 Gerd Hoffmann
    int fd, rc;
429 097db438 Gerd Hoffmann
430 097db438 Gerd Hoffmann
    rc = stat("/dev/bus/usb", &st);
431 097db438 Gerd Hoffmann
    if (rc == 0 && S_ISDIR(st.st_mode)) {
432 097db438 Gerd Hoffmann
        /* udev-created device nodes available */
433 097db438 Gerd Hoffmann
        usbfs = "/dev/bus/usb";
434 097db438 Gerd Hoffmann
    } else {
435 097db438 Gerd Hoffmann
        /* fallback: usbfs mounted below /proc */
436 097db438 Gerd Hoffmann
        usbfs = "/proc/bus/usb";
437 097db438 Gerd Hoffmann
    }
438 097db438 Gerd Hoffmann
439 097db438 Gerd Hoffmann
    snprintf(filename, sizeof(filename), "%s/%03d/%03d",
440 097db438 Gerd Hoffmann
             usbfs, bus, addr);
441 097db438 Gerd Hoffmann
    fd = open(filename, O_RDWR | O_NONBLOCK);
442 097db438 Gerd Hoffmann
    if (fd < 0) {
443 097db438 Gerd Hoffmann
        fprintf(stderr, "husb: open %s: %s\n", filename, strerror(errno));
444 097db438 Gerd Hoffmann
    }
445 097db438 Gerd Hoffmann
    return fd;
446 097db438 Gerd Hoffmann
}
447 097db438 Gerd Hoffmann
448 e6274727 Gerd Hoffmann
static int usb_host_claim_port(USBHostDevice *s)
449 e6274727 Gerd Hoffmann
{
450 e6274727 Gerd Hoffmann
#ifdef USBDEVFS_CLAIM_PORT
451 e6274727 Gerd Hoffmann
    char *h, hub_name[64], line[1024];
452 c75fead6 Gerd Hoffmann
    int hub_addr, ret;
453 e6274727 Gerd Hoffmann
454 e6274727 Gerd Hoffmann
    snprintf(hub_name, sizeof(hub_name), "%d-%s",
455 e6274727 Gerd Hoffmann
             s->match.bus_num, s->match.port);
456 e6274727 Gerd Hoffmann
457 e6274727 Gerd Hoffmann
    /* try strip off last ".$portnr" to get hub */
458 e6274727 Gerd Hoffmann
    h = strrchr(hub_name, '.');
459 e6274727 Gerd Hoffmann
    if (h != NULL) {
460 c75fead6 Gerd Hoffmann
        s->hub_port = atoi(h+1);
461 e6274727 Gerd Hoffmann
        *h = '\0';
462 e6274727 Gerd Hoffmann
    } else {
463 e6274727 Gerd Hoffmann
        /* no dot in there -> it is the root hub */
464 e6274727 Gerd Hoffmann
        snprintf(hub_name, sizeof(hub_name), "usb%d",
465 e6274727 Gerd Hoffmann
                 s->match.bus_num);
466 c75fead6 Gerd Hoffmann
        s->hub_port = atoi(s->match.port);
467 e6274727 Gerd Hoffmann
    }
468 e6274727 Gerd Hoffmann
469 e6274727 Gerd Hoffmann
    if (!usb_host_read_file(line, sizeof(line), "devnum",
470 e6274727 Gerd Hoffmann
                            hub_name)) {
471 e6274727 Gerd Hoffmann
        return -1;
472 e6274727 Gerd Hoffmann
    }
473 e6274727 Gerd Hoffmann
    if (sscanf(line, "%d", &hub_addr) != 1) {
474 e6274727 Gerd Hoffmann
        return -1;
475 e6274727 Gerd Hoffmann
    }
476 e6274727 Gerd Hoffmann
477 097db438 Gerd Hoffmann
    s->hub_fd = usb_host_open_device(s->match.bus_num, hub_addr);
478 e6274727 Gerd Hoffmann
    if (s->hub_fd < 0) {
479 e6274727 Gerd Hoffmann
        return -1;
480 e6274727 Gerd Hoffmann
    }
481 e6274727 Gerd Hoffmann
482 c75fead6 Gerd Hoffmann
    ret = ioctl(s->hub_fd, USBDEVFS_CLAIM_PORT, &s->hub_port);
483 e6274727 Gerd Hoffmann
    if (ret < 0) {
484 e6274727 Gerd Hoffmann
        close(s->hub_fd);
485 e6274727 Gerd Hoffmann
        s->hub_fd = -1;
486 e6274727 Gerd Hoffmann
        return -1;
487 e6274727 Gerd Hoffmann
    }
488 e6274727 Gerd Hoffmann
489 c75fead6 Gerd Hoffmann
    trace_usb_host_claim_port(s->match.bus_num, hub_addr, s->hub_port);
490 e6274727 Gerd Hoffmann
    return 0;
491 e6274727 Gerd Hoffmann
#else
492 e6274727 Gerd Hoffmann
    return -1;
493 e6274727 Gerd Hoffmann
#endif
494 e6274727 Gerd Hoffmann
}
495 e6274727 Gerd Hoffmann
496 c75fead6 Gerd Hoffmann
static void usb_host_release_port(USBHostDevice *s)
497 c75fead6 Gerd Hoffmann
{
498 c75fead6 Gerd Hoffmann
    if (s->hub_fd == -1) {
499 c75fead6 Gerd Hoffmann
        return;
500 c75fead6 Gerd Hoffmann
    }
501 c75fead6 Gerd Hoffmann
#ifdef USBDEVFS_RELEASE_PORT
502 c75fead6 Gerd Hoffmann
    ioctl(s->hub_fd, USBDEVFS_RELEASE_PORT, &s->hub_port);
503 c75fead6 Gerd Hoffmann
#endif
504 c75fead6 Gerd Hoffmann
    close(s->hub_fd);
505 c75fead6 Gerd Hoffmann
    s->hub_fd = -1;
506 c75fead6 Gerd Hoffmann
}
507 c75fead6 Gerd Hoffmann
508 e6274727 Gerd Hoffmann
static int usb_host_disconnect_ifaces(USBHostDevice *dev, int nb_interfaces)
509 e6274727 Gerd Hoffmann
{
510 e6274727 Gerd Hoffmann
    /* earlier Linux 2.4 do not support that */
511 e6274727 Gerd Hoffmann
#ifdef USBDEVFS_DISCONNECT
512 e6274727 Gerd Hoffmann
    struct usbdevfs_ioctl ctrl;
513 e6274727 Gerd Hoffmann
    int ret, interface;
514 e6274727 Gerd Hoffmann
515 e6274727 Gerd Hoffmann
    for (interface = 0; interface < nb_interfaces; interface++) {
516 e6274727 Gerd Hoffmann
        ctrl.ioctl_code = USBDEVFS_DISCONNECT;
517 e6274727 Gerd Hoffmann
        ctrl.ifno = interface;
518 e6274727 Gerd Hoffmann
        ctrl.data = 0;
519 e6274727 Gerd Hoffmann
        ret = ioctl(dev->fd, USBDEVFS_IOCTL, &ctrl);
520 e6274727 Gerd Hoffmann
        if (ret < 0 && errno != ENODATA) {
521 e6274727 Gerd Hoffmann
            perror("USBDEVFS_DISCONNECT");
522 e6274727 Gerd Hoffmann
            return -1;
523 e6274727 Gerd Hoffmann
        }
524 e6274727 Gerd Hoffmann
    }
525 e6274727 Gerd Hoffmann
#endif
526 e6274727 Gerd Hoffmann
    return 0;
527 e6274727 Gerd Hoffmann
}
528 e6274727 Gerd Hoffmann
529 0fcc3bfc Gerd Hoffmann
static int usb_linux_get_num_interfaces(USBHostDevice *s)
530 0fcc3bfc Gerd Hoffmann
{
531 0fcc3bfc Gerd Hoffmann
    char device_name[64], line[1024];
532 0fcc3bfc Gerd Hoffmann
    int num_interfaces = 0;
533 0fcc3bfc Gerd Hoffmann
534 0fcc3bfc Gerd Hoffmann
    sprintf(device_name, "%d-%s", s->bus_num, s->port);
535 0fcc3bfc Gerd Hoffmann
    if (!usb_host_read_file(line, sizeof(line), "bNumInterfaces",
536 0fcc3bfc Gerd Hoffmann
                            device_name)) {
537 0fcc3bfc Gerd Hoffmann
        return -1;
538 0fcc3bfc Gerd Hoffmann
    }
539 0fcc3bfc Gerd Hoffmann
    if (sscanf(line, "%d", &num_interfaces) != 1) {
540 0fcc3bfc Gerd Hoffmann
        return -1;
541 0fcc3bfc Gerd Hoffmann
    }
542 0fcc3bfc Gerd Hoffmann
    return num_interfaces;
543 0fcc3bfc Gerd Hoffmann
}
544 0fcc3bfc Gerd Hoffmann
545 446ab128 aliguori
static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
546 b9dc033c balrog
{
547 41c01ee7 Gerd Hoffmann
    const char *op = NULL;
548 b9dc033c balrog
    int dev_descr_len, config_descr_len;
549 d4c4e6fd Blue Swirl
    int interface, nb_interfaces;
550 b9dc033c balrog
    int ret, i;
551 b9dc033c balrog
552 1de14d43 Gerd Hoffmann
    for (i = 0; i < USB_MAX_INTERFACES; i++) {
553 1de14d43 Gerd Hoffmann
        dev->dev.altsetting[i] = 0;
554 1de14d43 Gerd Hoffmann
    }
555 1de14d43 Gerd Hoffmann
556 eb7700bb Gerd Hoffmann
    if (configuration == 0) { /* address state - ignore */
557 65360511 Gerd Hoffmann
        dev->dev.ninterfaces   = 0;
558 65360511 Gerd Hoffmann
        dev->dev.configuration = 0;
559 b9dc033c balrog
        return 1;
560 eb7700bb Gerd Hoffmann
    }
561 b9dc033c balrog
562 d0f2c4c6 malc
    DPRINTF("husb: claiming interfaces. config %d\n", configuration);
563 446ab128 aliguori
564 b9dc033c balrog
    i = 0;
565 b9dc033c balrog
    dev_descr_len = dev->descr[0];
566 2791104c David Ahern
    if (dev_descr_len > dev->descr_len) {
567 61c1117f Hans de Goede
        fprintf(stderr, "husb: update iface failed. descr too short\n");
568 61c1117f Hans de Goede
        return 0;
569 2791104c David Ahern
    }
570 b9dc033c balrog
571 b9dc033c balrog
    i += dev_descr_len;
572 b9dc033c balrog
    while (i < dev->descr_len) {
573 2791104c David Ahern
        DPRINTF("husb: i is %d, descr_len is %d, dl %d, dt %d\n",
574 2791104c David Ahern
                i, dev->descr_len,
575 b9dc033c balrog
               dev->descr[i], dev->descr[i+1]);
576 64838171 aliguori
577 b9dc033c balrog
        if (dev->descr[i+1] != USB_DT_CONFIG) {
578 b9dc033c balrog
            i += dev->descr[i];
579 b9dc033c balrog
            continue;
580 b9dc033c balrog
        }
581 b9dc033c balrog
        config_descr_len = dev->descr[i];
582 b9dc033c balrog
583 e6a2f500 Gerd Hoffmann
        DPRINTF("husb: config #%d need %d\n", dev->descr[i + 5], configuration);
584 1f3870ab aliguori
585 eb7700bb Gerd Hoffmann
        if (configuration == dev->descr[i + 5]) {
586 446ab128 aliguori
            configuration = dev->descr[i + 5];
587 b9dc033c balrog
            break;
588 446ab128 aliguori
        }
589 b9dc033c balrog
590 b9dc033c balrog
        i += config_descr_len;
591 b9dc033c balrog
    }
592 b9dc033c balrog
593 b9dc033c balrog
    if (i >= dev->descr_len) {
594 2791104c David Ahern
        fprintf(stderr,
595 2791104c David Ahern
                "husb: update iface failed. no matching configuration\n");
596 61c1117f Hans de Goede
        return 0;
597 b9dc033c balrog
    }
598 b9dc033c balrog
    nb_interfaces = dev->descr[i + 4];
599 b9dc033c balrog
600 e6274727 Gerd Hoffmann
    if (usb_host_disconnect_ifaces(dev, nb_interfaces) < 0) {
601 e6274727 Gerd Hoffmann
        goto fail;
602 b9dc033c balrog
    }
603 b9dc033c balrog
604 b9dc033c balrog
    /* XXX: only grab if all interfaces are free */
605 b9dc033c balrog
    for (interface = 0; interface < nb_interfaces; interface++) {
606 41c01ee7 Gerd Hoffmann
        op = "USBDEVFS_CLAIMINTERFACE";
607 b9dc033c balrog
        ret = ioctl(dev->fd, USBDEVFS_CLAIMINTERFACE, &interface);
608 b9dc033c balrog
        if (ret < 0) {
609 41c01ee7 Gerd Hoffmann
            goto fail;
610 b9dc033c balrog
        }
611 b9dc033c balrog
    }
612 b9dc033c balrog
613 e6a2f500 Gerd Hoffmann
    trace_usb_host_claim_interfaces(dev->bus_num, dev->addr,
614 e6a2f500 Gerd Hoffmann
                                    nb_interfaces, configuration);
615 b9dc033c balrog
616 65360511 Gerd Hoffmann
    dev->dev.ninterfaces   = nb_interfaces;
617 65360511 Gerd Hoffmann
    dev->dev.configuration = configuration;
618 446ab128 aliguori
    return 1;
619 41c01ee7 Gerd Hoffmann
620 41c01ee7 Gerd Hoffmann
fail:
621 41c01ee7 Gerd Hoffmann
    if (errno == ENODEV) {
622 41c01ee7 Gerd Hoffmann
        do_disconnect(dev);
623 41c01ee7 Gerd Hoffmann
    }
624 41c01ee7 Gerd Hoffmann
    perror(op);
625 41c01ee7 Gerd Hoffmann
    return 0;
626 446ab128 aliguori
}
627 446ab128 aliguori
628 446ab128 aliguori
static int usb_host_release_interfaces(USBHostDevice *s)
629 446ab128 aliguori
{
630 446ab128 aliguori
    int ret, i;
631 446ab128 aliguori
632 e6a2f500 Gerd Hoffmann
    trace_usb_host_release_interfaces(s->bus_num, s->addr);
633 446ab128 aliguori
634 65360511 Gerd Hoffmann
    for (i = 0; i < s->dev.ninterfaces; i++) {
635 446ab128 aliguori
        ret = ioctl(s->fd, USBDEVFS_RELEASEINTERFACE, &i);
636 446ab128 aliguori
        if (ret < 0) {
637 e6a2f500 Gerd Hoffmann
            perror("USBDEVFS_RELEASEINTERFACE");
638 446ab128 aliguori
            return 0;
639 446ab128 aliguori
        }
640 446ab128 aliguori
    }
641 b9dc033c balrog
    return 1;
642 b9dc033c balrog
}
643 b9dc033c balrog
644 059809e4 bellard
static void usb_host_handle_reset(USBDevice *dev)
645 bb36d470 bellard
{
646 26a9e82a Gerd Hoffmann
    USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
647 64838171 aliguori
648 e6a2f500 Gerd Hoffmann
    trace_usb_host_reset(s->bus_num, s->addr);
649 64838171 aliguori
650 c7662daa Gerd Hoffmann
    usb_host_do_reset(s);;
651 446ab128 aliguori
652 eb7700bb Gerd Hoffmann
    usb_host_claim_interfaces(s, 0);
653 9b87e19b Gerd Hoffmann
    usb_linux_update_endp_table(s);
654 5fafdf24 ths
}
655 bb36d470 bellard
656 059809e4 bellard
static void usb_host_handle_destroy(USBDevice *dev)
657 059809e4 bellard
{
658 059809e4 bellard
    USBHostDevice *s = (USBHostDevice *)dev;
659 059809e4 bellard
660 c75fead6 Gerd Hoffmann
    usb_host_release_port(s);
661 26a9e82a Gerd Hoffmann
    usb_host_close(s);
662 26a9e82a Gerd Hoffmann
    QTAILQ_REMOVE(&hostdevs, s, next);
663 b373a63a Shahar Havivi
    qemu_remove_exit_notifier(&s->exit);
664 059809e4 bellard
}
665 059809e4 bellard
666 060dc841 Hans de Goede
/* iso data is special, we need to keep enough urbs in flight to make sure
667 060dc841 Hans de Goede
   that the controller never runs out of them, otherwise the device will
668 060dc841 Hans de Goede
   likely suffer a buffer underrun / overrun. */
669 c0e5750b Gerd Hoffmann
static AsyncURB *usb_host_alloc_iso(USBHostDevice *s, int pid, uint8_t ep)
670 060dc841 Hans de Goede
{
671 060dc841 Hans de Goede
    AsyncURB *aurb;
672 f003397c Gerd Hoffmann
    int i, j, len = usb_ep_get_max_packet_size(&s->dev, pid, ep);
673 060dc841 Hans de Goede
674 7267c094 Anthony Liguori
    aurb = g_malloc0(s->iso_urb_count * sizeof(*aurb));
675 b81bcd8a Gerd Hoffmann
    for (i = 0; i < s->iso_urb_count; i++) {
676 060dc841 Hans de Goede
        aurb[i].urb.endpoint      = ep;
677 060dc841 Hans de Goede
        aurb[i].urb.buffer_length = ISO_FRAME_DESC_PER_URB * len;
678 7267c094 Anthony Liguori
        aurb[i].urb.buffer        = g_malloc(aurb[i].urb.buffer_length);
679 060dc841 Hans de Goede
        aurb[i].urb.type          = USBDEVFS_URB_TYPE_ISO;
680 060dc841 Hans de Goede
        aurb[i].urb.flags         = USBDEVFS_URB_ISO_ASAP;
681 060dc841 Hans de Goede
        aurb[i].urb.number_of_packets = ISO_FRAME_DESC_PER_URB;
682 060dc841 Hans de Goede
        for (j = 0 ; j < ISO_FRAME_DESC_PER_URB; j++)
683 060dc841 Hans de Goede
            aurb[i].urb.iso_frame_desc[j].length = len;
684 c0e5750b Gerd Hoffmann
        if (pid == USB_TOKEN_IN) {
685 060dc841 Hans de Goede
            aurb[i].urb.endpoint |= 0x80;
686 060dc841 Hans de Goede
            /* Mark as fully consumed (idle) */
687 060dc841 Hans de Goede
            aurb[i].iso_frame_idx = ISO_FRAME_DESC_PER_URB;
688 060dc841 Hans de Goede
        }
689 060dc841 Hans de Goede
    }
690 c0e5750b Gerd Hoffmann
    set_iso_urb(s, pid, ep, aurb);
691 060dc841 Hans de Goede
692 060dc841 Hans de Goede
    return aurb;
693 060dc841 Hans de Goede
}
694 060dc841 Hans de Goede
695 c0e5750b Gerd Hoffmann
static void usb_host_stop_n_free_iso(USBHostDevice *s, int pid, uint8_t ep)
696 060dc841 Hans de Goede
{
697 060dc841 Hans de Goede
    AsyncURB *aurb;
698 060dc841 Hans de Goede
    int i, ret, killed = 0, free = 1;
699 060dc841 Hans de Goede
700 c0e5750b Gerd Hoffmann
    aurb = get_iso_urb(s, pid, ep);
701 060dc841 Hans de Goede
    if (!aurb) {
702 060dc841 Hans de Goede
        return;
703 060dc841 Hans de Goede
    }
704 060dc841 Hans de Goede
705 b81bcd8a Gerd Hoffmann
    for (i = 0; i < s->iso_urb_count; i++) {
706 060dc841 Hans de Goede
        /* in flight? */
707 060dc841 Hans de Goede
        if (aurb[i].iso_frame_idx == -1) {
708 060dc841 Hans de Goede
            ret = ioctl(s->fd, USBDEVFS_DISCARDURB, &aurb[i]);
709 060dc841 Hans de Goede
            if (ret < 0) {
710 e6a2f500 Gerd Hoffmann
                perror("USBDEVFS_DISCARDURB");
711 060dc841 Hans de Goede
                free = 0;
712 060dc841 Hans de Goede
                continue;
713 060dc841 Hans de Goede
            }
714 060dc841 Hans de Goede
            killed++;
715 060dc841 Hans de Goede
        }
716 060dc841 Hans de Goede
    }
717 060dc841 Hans de Goede
718 060dc841 Hans de Goede
    /* Make sure any urbs we've killed are reaped before we free them */
719 060dc841 Hans de Goede
    if (killed) {
720 060dc841 Hans de Goede
        async_complete(s);
721 060dc841 Hans de Goede
    }
722 060dc841 Hans de Goede
723 b81bcd8a Gerd Hoffmann
    for (i = 0; i < s->iso_urb_count; i++) {
724 7267c094 Anthony Liguori
        g_free(aurb[i].urb.buffer);
725 060dc841 Hans de Goede
    }
726 060dc841 Hans de Goede
727 060dc841 Hans de Goede
    if (free)
728 7267c094 Anthony Liguori
        g_free(aurb);
729 060dc841 Hans de Goede
    else
730 060dc841 Hans de Goede
        printf("husb: leaking iso urbs because of discard failure\n");
731 c0e5750b Gerd Hoffmann
    set_iso_urb(s, pid, ep, NULL);
732 c0e5750b Gerd Hoffmann
    set_iso_urb_idx(s, pid, ep, 0);
733 c0e5750b Gerd Hoffmann
    clear_iso_started(s, pid, ep);
734 060dc841 Hans de Goede
}
735 060dc841 Hans de Goede
736 060dc841 Hans de Goede
static int urb_status_to_usb_ret(int status)
737 060dc841 Hans de Goede
{
738 060dc841 Hans de Goede
    switch (status) {
739 060dc841 Hans de Goede
    case -EPIPE:
740 060dc841 Hans de Goede
        return USB_RET_STALL;
741 4d819a9b Hans de Goede
    case -EOVERFLOW:
742 4d819a9b Hans de Goede
        return USB_RET_BABBLE;
743 060dc841 Hans de Goede
    default:
744 d61000a8 Hans de Goede
        return USB_RET_IOERROR;
745 060dc841 Hans de Goede
    }
746 060dc841 Hans de Goede
}
747 060dc841 Hans de Goede
748 bb6d5498 Hans de Goede
static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in)
749 060dc841 Hans de Goede
{
750 060dc841 Hans de Goede
    AsyncURB *aurb;
751 bb6d5498 Hans de Goede
    int i, j, ret, max_packet_size, offset, len = 0;
752 4f4321c1 Gerd Hoffmann
    uint8_t *buf;
753 975f2998 Hans de Goede
754 079d0b7f Gerd Hoffmann
    max_packet_size = p->ep->max_packet_size;
755 975f2998 Hans de Goede
    if (max_packet_size == 0)
756 975f2998 Hans de Goede
        return USB_RET_NAK;
757 060dc841 Hans de Goede
758 079d0b7f Gerd Hoffmann
    aurb = get_iso_urb(s, p->pid, p->ep->nr);
759 060dc841 Hans de Goede
    if (!aurb) {
760 079d0b7f Gerd Hoffmann
        aurb = usb_host_alloc_iso(s, p->pid, p->ep->nr);
761 060dc841 Hans de Goede
    }
762 060dc841 Hans de Goede
763 079d0b7f Gerd Hoffmann
    i = get_iso_urb_idx(s, p->pid, p->ep->nr);
764 060dc841 Hans de Goede
    j = aurb[i].iso_frame_idx;
765 060dc841 Hans de Goede
    if (j >= 0 && j < ISO_FRAME_DESC_PER_URB) {
766 bb6d5498 Hans de Goede
        if (in) {
767 bb6d5498 Hans de Goede
            /* Check urb status  */
768 bb6d5498 Hans de Goede
            if (aurb[i].urb.status) {
769 bb6d5498 Hans de Goede
                len = urb_status_to_usb_ret(aurb[i].urb.status);
770 bb6d5498 Hans de Goede
                /* Move to the next urb */
771 bb6d5498 Hans de Goede
                aurb[i].iso_frame_idx = ISO_FRAME_DESC_PER_URB - 1;
772 bb6d5498 Hans de Goede
            /* Check frame status */
773 bb6d5498 Hans de Goede
            } else if (aurb[i].urb.iso_frame_desc[j].status) {
774 bb6d5498 Hans de Goede
                len = urb_status_to_usb_ret(
775 bb6d5498 Hans de Goede
                                        aurb[i].urb.iso_frame_desc[j].status);
776 bb6d5498 Hans de Goede
            /* Check the frame fits */
777 4f4321c1 Gerd Hoffmann
            } else if (aurb[i].urb.iso_frame_desc[j].actual_length
778 4f4321c1 Gerd Hoffmann
                       > p->iov.size) {
779 bb6d5498 Hans de Goede
                printf("husb: received iso data is larger then packet\n");
780 4d819a9b Hans de Goede
                len = USB_RET_BABBLE;
781 bb6d5498 Hans de Goede
            /* All good copy data over */
782 bb6d5498 Hans de Goede
            } else {
783 bb6d5498 Hans de Goede
                len = aurb[i].urb.iso_frame_desc[j].actual_length;
784 4f4321c1 Gerd Hoffmann
                buf  = aurb[i].urb.buffer +
785 4f4321c1 Gerd Hoffmann
                    j * aurb[i].urb.iso_frame_desc[0].length;
786 4f4321c1 Gerd Hoffmann
                usb_packet_copy(p, buf, len);
787 bb6d5498 Hans de Goede
            }
788 060dc841 Hans de Goede
        } else {
789 4f4321c1 Gerd Hoffmann
            len = p->iov.size;
790 079d0b7f Gerd Hoffmann
            offset = (j == 0) ? 0 : get_iso_buffer_used(s, p->pid, p->ep->nr);
791 bb6d5498 Hans de Goede
792 bb6d5498 Hans de Goede
            /* Check the frame fits */
793 bb6d5498 Hans de Goede
            if (len > max_packet_size) {
794 bb6d5498 Hans de Goede
                printf("husb: send iso data is larger then max packet size\n");
795 bb6d5498 Hans de Goede
                return USB_RET_NAK;
796 bb6d5498 Hans de Goede
            }
797 bb6d5498 Hans de Goede
798 bb6d5498 Hans de Goede
            /* All good copy data over */
799 4f4321c1 Gerd Hoffmann
            usb_packet_copy(p, aurb[i].urb.buffer + offset, len);
800 bb6d5498 Hans de Goede
            aurb[i].urb.iso_frame_desc[j].length = len;
801 bb6d5498 Hans de Goede
            offset += len;
802 079d0b7f Gerd Hoffmann
            set_iso_buffer_used(s, p->pid, p->ep->nr, offset);
803 bb6d5498 Hans de Goede
804 bb6d5498 Hans de Goede
            /* Start the stream once we have buffered enough data */
805 079d0b7f Gerd Hoffmann
            if (!is_iso_started(s, p->pid, p->ep->nr) && i == 1 && j == 8) {
806 079d0b7f Gerd Hoffmann
                set_iso_started(s, p->pid, p->ep->nr);
807 bb6d5498 Hans de Goede
            }
808 060dc841 Hans de Goede
        }
809 060dc841 Hans de Goede
        aurb[i].iso_frame_idx++;
810 060dc841 Hans de Goede
        if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {
811 b81bcd8a Gerd Hoffmann
            i = (i + 1) % s->iso_urb_count;
812 079d0b7f Gerd Hoffmann
            set_iso_urb_idx(s, p->pid, p->ep->nr, i);
813 060dc841 Hans de Goede
        }
814 bb6d5498 Hans de Goede
    } else {
815 bb6d5498 Hans de Goede
        if (in) {
816 079d0b7f Gerd Hoffmann
            set_iso_started(s, p->pid, p->ep->nr);
817 bb6d5498 Hans de Goede
        } else {
818 bb6d5498 Hans de Goede
            DPRINTF("hubs: iso out error no free buffer, dropping packet\n");
819 bb6d5498 Hans de Goede
        }
820 060dc841 Hans de Goede
    }
821 060dc841 Hans de Goede
822 079d0b7f Gerd Hoffmann
    if (is_iso_started(s, p->pid, p->ep->nr)) {
823 bb6d5498 Hans de Goede
        /* (Re)-submit all fully consumed / filled urbs */
824 b81bcd8a Gerd Hoffmann
        for (i = 0; i < s->iso_urb_count; i++) {
825 bb6d5498 Hans de Goede
            if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {
826 bb6d5498 Hans de Goede
                ret = ioctl(s->fd, USBDEVFS_SUBMITURB, &aurb[i]);
827 bb6d5498 Hans de Goede
                if (ret < 0) {
828 e6a2f500 Gerd Hoffmann
                    perror("USBDEVFS_SUBMITURB");
829 bb6d5498 Hans de Goede
                    if (!in || len == 0) {
830 bb6d5498 Hans de Goede
                        switch(errno) {
831 bb6d5498 Hans de Goede
                        case ETIMEDOUT:
832 bb6d5498 Hans de Goede
                            len = USB_RET_NAK;
833 0225e254 Stefan Weil
                            break;
834 bb6d5498 Hans de Goede
                        case EPIPE:
835 bb6d5498 Hans de Goede
                        default:
836 bb6d5498 Hans de Goede
                            len = USB_RET_STALL;
837 bb6d5498 Hans de Goede
                        }
838 060dc841 Hans de Goede
                    }
839 bb6d5498 Hans de Goede
                    break;
840 060dc841 Hans de Goede
                }
841 bb6d5498 Hans de Goede
                aurb[i].iso_frame_idx = -1;
842 079d0b7f Gerd Hoffmann
                change_iso_inflight(s, p->pid, p->ep->nr, 1);
843 060dc841 Hans de Goede
            }
844 060dc841 Hans de Goede
        }
845 060dc841 Hans de Goede
    }
846 060dc841 Hans de Goede
847 060dc841 Hans de Goede
    return len;
848 060dc841 Hans de Goede
}
849 060dc841 Hans de Goede
850 50b7963e Hans de Goede
static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
851 bb36d470 bellard
{
852 50b7963e Hans de Goede
    USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
853 64838171 aliguori
    struct usbdevfs_urb *urb;
854 446ab128 aliguori
    AsyncURB *aurb;
855 b621bab4 Gerd Hoffmann
    int ret, rem, prem, v;
856 71138531 Gerd Hoffmann
    uint8_t *pbuf;
857 060dc841 Hans de Goede
    uint8_t ep;
858 b9dc033c balrog
859 19b89252 Gerd Hoffmann
    trace_usb_host_req_data(s->bus_num, s->addr, p,
860 e6a2f500 Gerd Hoffmann
                            p->pid == USB_TOKEN_IN,
861 079d0b7f Gerd Hoffmann
                            p->ep->nr, p->iov.size);
862 e6a2f500 Gerd Hoffmann
863 079d0b7f Gerd Hoffmann
    if (!is_valid(s, p->pid, p->ep->nr)) {
864 19b89252 Gerd Hoffmann
        trace_usb_host_req_complete(s->bus_num, s->addr, p, USB_RET_NAK);
865 a0b5fece Hans de Goede
        return USB_RET_NAK;
866 a0b5fece Hans de Goede
    }
867 a0b5fece Hans de Goede
868 2791104c David Ahern
    if (p->pid == USB_TOKEN_IN) {
869 079d0b7f Gerd Hoffmann
        ep = p->ep->nr | 0x80;
870 2791104c David Ahern
    } else {
871 079d0b7f Gerd Hoffmann
        ep = p->ep->nr;
872 2791104c David Ahern
    }
873 64838171 aliguori
874 079d0b7f Gerd Hoffmann
    if (is_halted(s, p->pid, p->ep->nr)) {
875 9b87e19b Gerd Hoffmann
        unsigned int arg = ep;
876 9b87e19b Gerd Hoffmann
        ret = ioctl(s->fd, USBDEVFS_CLEAR_HALT, &arg);
877 64838171 aliguori
        if (ret < 0) {
878 e6a2f500 Gerd Hoffmann
            perror("USBDEVFS_CLEAR_HALT");
879 19b89252 Gerd Hoffmann
            trace_usb_host_req_complete(s->bus_num, s->addr, p, USB_RET_NAK);
880 bb36d470 bellard
            return USB_RET_NAK;
881 bb36d470 bellard
        }
882 079d0b7f Gerd Hoffmann
        clear_halt(s, p->pid, p->ep->nr);
883 4d043a09 balrog
    }
884 4d043a09 balrog
885 079d0b7f Gerd Hoffmann
    if (is_isoc(s, p->pid, p->ep->nr)) {
886 bb6d5498 Hans de Goede
        return usb_host_handle_iso_data(s, p, p->pid == USB_TOKEN_IN);
887 bb6d5498 Hans de Goede
    }
888 060dc841 Hans de Goede
889 b621bab4 Gerd Hoffmann
    v = 0;
890 818d59dc Gerd Hoffmann
    prem = 0;
891 818d59dc Gerd Hoffmann
    pbuf = NULL;
892 b621bab4 Gerd Hoffmann
    rem = p->iov.size;
893 0b377169 Gerd Hoffmann
    do {
894 0b377169 Gerd Hoffmann
        if (prem == 0 && rem > 0) {
895 b621bab4 Gerd Hoffmann
            assert(v < p->iov.niov);
896 b621bab4 Gerd Hoffmann
            prem = p->iov.iov[v].iov_len;
897 b621bab4 Gerd Hoffmann
            pbuf = p->iov.iov[v].iov_base;
898 b621bab4 Gerd Hoffmann
            assert(prem <= rem);
899 818d59dc Gerd Hoffmann
            v++;
900 b621bab4 Gerd Hoffmann
        }
901 71138531 Gerd Hoffmann
        aurb = async_alloc(s);
902 71138531 Gerd Hoffmann
        aurb->packet = p;
903 71138531 Gerd Hoffmann
904 71138531 Gerd Hoffmann
        urb = &aurb->urb;
905 71138531 Gerd Hoffmann
        urb->endpoint      = ep;
906 d8e17efd Gerd Hoffmann
        urb->type          = usb_host_usbfs_type(s, p);
907 71138531 Gerd Hoffmann
        urb->usercontext   = s;
908 71138531 Gerd Hoffmann
        urb->buffer        = pbuf;
909 b621bab4 Gerd Hoffmann
        urb->buffer_length = prem;
910 71138531 Gerd Hoffmann
911 b621bab4 Gerd Hoffmann
        if (urb->buffer_length > MAX_USBFS_BUFFER_SIZE) {
912 71138531 Gerd Hoffmann
            urb->buffer_length = MAX_USBFS_BUFFER_SIZE;
913 71138531 Gerd Hoffmann
        }
914 71138531 Gerd Hoffmann
        pbuf += urb->buffer_length;
915 b621bab4 Gerd Hoffmann
        prem -= urb->buffer_length;
916 71138531 Gerd Hoffmann
        rem  -= urb->buffer_length;
917 b621bab4 Gerd Hoffmann
        if (rem) {
918 b621bab4 Gerd Hoffmann
            aurb->more         = 1;
919 b621bab4 Gerd Hoffmann
        }
920 b9dc033c balrog
921 e6a2f500 Gerd Hoffmann
        trace_usb_host_urb_submit(s->bus_num, s->addr, aurb,
922 e6a2f500 Gerd Hoffmann
                                  urb->buffer_length, aurb->more);
923 71138531 Gerd Hoffmann
        ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
924 b9dc033c balrog
925 71138531 Gerd Hoffmann
        DPRINTF("husb: data submit: ep 0x%x, len %u, more %d, packet %p, aurb %p\n",
926 71138531 Gerd Hoffmann
                urb->endpoint, urb->buffer_length, aurb->more, p, aurb);
927 b9dc033c balrog
928 71138531 Gerd Hoffmann
        if (ret < 0) {
929 e6a2f500 Gerd Hoffmann
            perror("USBDEVFS_SUBMITURB");
930 71138531 Gerd Hoffmann
            async_free(aurb);
931 b9dc033c balrog
932 71138531 Gerd Hoffmann
            switch(errno) {
933 71138531 Gerd Hoffmann
            case ETIMEDOUT:
934 19b89252 Gerd Hoffmann
                trace_usb_host_req_complete(s->bus_num, s->addr, p,
935 19b89252 Gerd Hoffmann
                                            USB_RET_NAK);
936 71138531 Gerd Hoffmann
                return USB_RET_NAK;
937 71138531 Gerd Hoffmann
            case EPIPE:
938 71138531 Gerd Hoffmann
            default:
939 19b89252 Gerd Hoffmann
                trace_usb_host_req_complete(s->bus_num, s->addr, p,
940 19b89252 Gerd Hoffmann
                                            USB_RET_STALL);
941 71138531 Gerd Hoffmann
                return USB_RET_STALL;
942 71138531 Gerd Hoffmann
            }
943 b9dc033c balrog
        }
944 0b377169 Gerd Hoffmann
    } while (rem > 0);
945 64838171 aliguori
946 b9dc033c balrog
    return USB_RET_ASYNC;
947 b9dc033c balrog
}
948 b9dc033c balrog
949 446ab128 aliguori
static int ctrl_error(void)
950 446ab128 aliguori
{
951 2791104c David Ahern
    if (errno == ETIMEDOUT) {
952 446ab128 aliguori
        return USB_RET_NAK;
953 2791104c David Ahern
    } else {
954 446ab128 aliguori
        return USB_RET_STALL;
955 2791104c David Ahern
    }
956 446ab128 aliguori
}
957 446ab128 aliguori
958 446ab128 aliguori
static int usb_host_set_address(USBHostDevice *s, int addr)
959 446ab128 aliguori
{
960 e6a2f500 Gerd Hoffmann
    trace_usb_host_set_address(s->bus_num, s->addr, addr);
961 446ab128 aliguori
    s->dev.addr = addr;
962 446ab128 aliguori
    return 0;
963 446ab128 aliguori
}
964 446ab128 aliguori
965 446ab128 aliguori
static int usb_host_set_config(USBHostDevice *s, int config)
966 446ab128 aliguori
{
967 0fcc3bfc Gerd Hoffmann
    int ret, first = 1;
968 0fcc3bfc Gerd Hoffmann
969 e6a2f500 Gerd Hoffmann
    trace_usb_host_set_config(s->bus_num, s->addr, config);
970 e6a2f500 Gerd Hoffmann
971 446ab128 aliguori
    usb_host_release_interfaces(s);
972 446ab128 aliguori
973 0fcc3bfc Gerd Hoffmann
again:
974 0fcc3bfc Gerd Hoffmann
    ret = ioctl(s->fd, USBDEVFS_SETCONFIGURATION, &config);
975 2791104c David Ahern
976 d0f2c4c6 malc
    DPRINTF("husb: ctrl set config %d ret %d errno %d\n", config, ret, errno);
977 2791104c David Ahern
978 0fcc3bfc Gerd Hoffmann
    if (ret < 0 && errno == EBUSY && first) {
979 0fcc3bfc Gerd Hoffmann
        /* happens if usb device is in use by host drivers */
980 0fcc3bfc Gerd Hoffmann
        int count = usb_linux_get_num_interfaces(s);
981 0fcc3bfc Gerd Hoffmann
        if (count > 0) {
982 0fcc3bfc Gerd Hoffmann
            DPRINTF("husb: busy -> disconnecting %d interfaces\n", count);
983 0fcc3bfc Gerd Hoffmann
            usb_host_disconnect_ifaces(s, count);
984 0fcc3bfc Gerd Hoffmann
            first = 0;
985 0fcc3bfc Gerd Hoffmann
            goto again;
986 0fcc3bfc Gerd Hoffmann
        }
987 0fcc3bfc Gerd Hoffmann
    }
988 0fcc3bfc Gerd Hoffmann
989 2791104c David Ahern
    if (ret < 0) {
990 446ab128 aliguori
        return ctrl_error();
991 2791104c David Ahern
    }
992 446ab128 aliguori
    usb_host_claim_interfaces(s, config);
993 eb7700bb Gerd Hoffmann
    usb_linux_update_endp_table(s);
994 446ab128 aliguori
    return 0;
995 446ab128 aliguori
}
996 446ab128 aliguori
997 446ab128 aliguori
static int usb_host_set_interface(USBHostDevice *s, int iface, int alt)
998 446ab128 aliguori
{
999 446ab128 aliguori
    struct usbdevfs_setinterface si;
1000 060dc841 Hans de Goede
    int i, ret;
1001 060dc841 Hans de Goede
1002 e6a2f500 Gerd Hoffmann
    trace_usb_host_set_interface(s->bus_num, s->addr, iface, alt);
1003 e6a2f500 Gerd Hoffmann
1004 d8e17efd Gerd Hoffmann
    for (i = 1; i <= USB_MAX_ENDPOINTS; i++) {
1005 c0e5750b Gerd Hoffmann
        if (is_isoc(s, USB_TOKEN_IN, i)) {
1006 c0e5750b Gerd Hoffmann
            usb_host_stop_n_free_iso(s, USB_TOKEN_IN, i);
1007 c0e5750b Gerd Hoffmann
        }
1008 c0e5750b Gerd Hoffmann
        if (is_isoc(s, USB_TOKEN_OUT, i)) {
1009 c0e5750b Gerd Hoffmann
            usb_host_stop_n_free_iso(s, USB_TOKEN_OUT, i);
1010 060dc841 Hans de Goede
        }
1011 060dc841 Hans de Goede
    }
1012 446ab128 aliguori
1013 1de14d43 Gerd Hoffmann
    if (iface >= USB_MAX_INTERFACES) {
1014 1de14d43 Gerd Hoffmann
        return USB_RET_STALL;
1015 1de14d43 Gerd Hoffmann
    }
1016 1de14d43 Gerd Hoffmann
1017 446ab128 aliguori
    si.interface  = iface;
1018 446ab128 aliguori
    si.altsetting = alt;
1019 446ab128 aliguori
    ret = ioctl(s->fd, USBDEVFS_SETINTERFACE, &si);
1020 446ab128 aliguori
1021 2791104c David Ahern
    DPRINTF("husb: ctrl set iface %d altset %d ret %d errno %d\n",
1022 2791104c David Ahern
            iface, alt, ret, errno);
1023 2791104c David Ahern
1024 2791104c David Ahern
    if (ret < 0) {
1025 2791104c David Ahern
        return ctrl_error();
1026 2791104c David Ahern
    }
1027 1de14d43 Gerd Hoffmann
1028 1de14d43 Gerd Hoffmann
    s->dev.altsetting[iface] = alt;
1029 446ab128 aliguori
    usb_linux_update_endp_table(s);
1030 446ab128 aliguori
    return 0;
1031 446ab128 aliguori
}
1032 446ab128 aliguori
1033 50b7963e Hans de Goede
static int usb_host_handle_control(USBDevice *dev, USBPacket *p,
1034 50b7963e Hans de Goede
               int request, int value, int index, int length, uint8_t *data)
1035 446ab128 aliguori
{
1036 50b7963e Hans de Goede
    USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
1037 446ab128 aliguori
    struct usbdevfs_urb *urb;
1038 446ab128 aliguori
    AsyncURB *aurb;
1039 50b7963e Hans de Goede
    int ret;
1040 446ab128 aliguori
1041 2791104c David Ahern
    /*
1042 446ab128 aliguori
     * Process certain standard device requests.
1043 446ab128 aliguori
     * These are infrequent and are processed synchronously.
1044 446ab128 aliguori
     */
1045 446ab128 aliguori
1046 50b7963e Hans de Goede
    /* Note request is (bRequestType << 8) | bRequest */
1047 19b89252 Gerd Hoffmann
    trace_usb_host_req_control(s->bus_num, s->addr, p, request, value, index);
1048 c19537a1 Gerd Hoffmann
    assert(p->result == 0);
1049 446ab128 aliguori
1050 50b7963e Hans de Goede
    switch (request) {
1051 50b7963e Hans de Goede
    case DeviceOutRequest | USB_REQ_SET_ADDRESS:
1052 e382e751 Gerd Hoffmann
        ret = usb_host_set_address(s, value);
1053 19b89252 Gerd Hoffmann
        trace_usb_host_req_emulated(s->bus_num, s->addr, p, ret);
1054 e382e751 Gerd Hoffmann
        return ret;
1055 446ab128 aliguori
1056 50b7963e Hans de Goede
    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
1057 e382e751 Gerd Hoffmann
        ret = usb_host_set_config(s, value & 0xff);
1058 19b89252 Gerd Hoffmann
        trace_usb_host_req_emulated(s->bus_num, s->addr, p, ret);
1059 e382e751 Gerd Hoffmann
        return ret;
1060 446ab128 aliguori
1061 50b7963e Hans de Goede
    case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
1062 e382e751 Gerd Hoffmann
        ret = usb_host_set_interface(s, index, value);
1063 19b89252 Gerd Hoffmann
        trace_usb_host_req_emulated(s->bus_num, s->addr, p, ret);
1064 e382e751 Gerd Hoffmann
        return ret;
1065 a2498f76 Gerd Hoffmann
1066 a2498f76 Gerd Hoffmann
    case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:
1067 a2498f76 Gerd Hoffmann
        if (value == 0) { /* clear halt */
1068 a2498f76 Gerd Hoffmann
            int pid = (index & USB_DIR_IN) ? USB_TOKEN_IN : USB_TOKEN_OUT;
1069 a2498f76 Gerd Hoffmann
            ioctl(s->fd, USBDEVFS_CLEAR_HALT, &index);
1070 a2498f76 Gerd Hoffmann
            clear_halt(s, pid, index & 0x0f);
1071 a2498f76 Gerd Hoffmann
            trace_usb_host_req_emulated(s->bus_num, s->addr, p, 0);
1072 a2498f76 Gerd Hoffmann
            return 0;
1073 a2498f76 Gerd Hoffmann
        }
1074 2791104c David Ahern
    }
1075 446ab128 aliguori
1076 446ab128 aliguori
    /* The rest are asynchronous */
1077 446ab128 aliguori
1078 50b7963e Hans de Goede
    if (length > sizeof(dev->data_buf)) {
1079 50b7963e Hans de Goede
        fprintf(stderr, "husb: ctrl buffer too small (%d > %zu)\n",
1080 50b7963e Hans de Goede
                length, sizeof(dev->data_buf));
1081 b2e3b6e9 malc
        return USB_RET_STALL;
1082 c4c0e236 Jim Paris
    }
1083 c4c0e236 Jim Paris
1084 7a8fc83f Gerd Hoffmann
    aurb = async_alloc(s);
1085 446ab128 aliguori
    aurb->packet = p;
1086 446ab128 aliguori
1087 2791104c David Ahern
    /*
1088 446ab128 aliguori
     * Setup ctrl transfer.
1089 446ab128 aliguori
     *
1090 a0102082 Brad Hards
     * s->ctrl is laid out such that data buffer immediately follows
1091 446ab128 aliguori
     * 'req' struct which is exactly what usbdevfs expects.
1092 2791104c David Ahern
     */
1093 446ab128 aliguori
    urb = &aurb->urb;
1094 446ab128 aliguori
1095 446ab128 aliguori
    urb->type     = USBDEVFS_URB_TYPE_CONTROL;
1096 079d0b7f Gerd Hoffmann
    urb->endpoint = p->ep->nr;
1097 446ab128 aliguori
1098 50b7963e Hans de Goede
    urb->buffer        = &dev->setup_buf;
1099 50b7963e Hans de Goede
    urb->buffer_length = length + 8;
1100 446ab128 aliguori
1101 446ab128 aliguori
    urb->usercontext = s;
1102 446ab128 aliguori
1103 e6a2f500 Gerd Hoffmann
    trace_usb_host_urb_submit(s->bus_num, s->addr, aurb,
1104 e6a2f500 Gerd Hoffmann
                              urb->buffer_length, aurb->more);
1105 446ab128 aliguori
    ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
1106 446ab128 aliguori
1107 d0f2c4c6 malc
    DPRINTF("husb: submit ctrl. len %u aurb %p\n", urb->buffer_length, aurb);
1108 446ab128 aliguori
1109 446ab128 aliguori
    if (ret < 0) {
1110 d0f2c4c6 malc
        DPRINTF("husb: submit failed. errno %d\n", errno);
1111 446ab128 aliguori
        async_free(aurb);
1112 446ab128 aliguori
1113 446ab128 aliguori
        switch(errno) {
1114 446ab128 aliguori
        case ETIMEDOUT:
1115 446ab128 aliguori
            return USB_RET_NAK;
1116 446ab128 aliguori
        case EPIPE:
1117 446ab128 aliguori
        default:
1118 446ab128 aliguori
            return USB_RET_STALL;
1119 446ab128 aliguori
        }
1120 446ab128 aliguori
    }
1121 446ab128 aliguori
1122 446ab128 aliguori
    return USB_RET_ASYNC;
1123 446ab128 aliguori
}
1124 446ab128 aliguori
1125 71d71bbd Hans de Goede
/* returns 1 on problem encountered or 0 for success */
1126 71d71bbd Hans de Goede
static int usb_linux_update_endp_table(USBHostDevice *s)
1127 71d71bbd Hans de Goede
{
1128 96dd9aac Gerd Hoffmann
    static const char *tname[] = {
1129 96dd9aac Gerd Hoffmann
        [USB_ENDPOINT_XFER_CONTROL] = "control",
1130 96dd9aac Gerd Hoffmann
        [USB_ENDPOINT_XFER_ISOC]    = "isoc",
1131 96dd9aac Gerd Hoffmann
        [USB_ENDPOINT_XFER_BULK]    = "bulk",
1132 96dd9aac Gerd Hoffmann
        [USB_ENDPOINT_XFER_INT]     = "int",
1133 96dd9aac Gerd Hoffmann
    };
1134 96dd9aac Gerd Hoffmann
    uint8_t devep, type;
1135 96dd9aac Gerd Hoffmann
    uint16_t mps, v, p;
1136 96dd9aac Gerd Hoffmann
    int ep, pid;
1137 96dd9aac Gerd Hoffmann
    unsigned int i, configuration = -1, interface = -1, altsetting = -1;
1138 c0e5750b Gerd Hoffmann
    struct endp_data *epd;
1139 96dd9aac Gerd Hoffmann
    USBDescriptor *d;
1140 96dd9aac Gerd Hoffmann
    bool active = false;
1141 71d71bbd Hans de Goede
1142 19deaa08 Gerd Hoffmann
    usb_ep_reset(&s->dev);
1143 a0b5fece Hans de Goede
1144 96dd9aac Gerd Hoffmann
    for (i = 0;; i += d->bLength) {
1145 96dd9aac Gerd Hoffmann
        if (i+2 >= s->descr_len) {
1146 96dd9aac Gerd Hoffmann
            break;
1147 b9dc033c balrog
        }
1148 96dd9aac Gerd Hoffmann
        d = (void *)(s->descr + i);
1149 96dd9aac Gerd Hoffmann
        if (d->bLength < 2) {
1150 96dd9aac Gerd Hoffmann
            trace_usb_host_parse_error(s->bus_num, s->addr,
1151 96dd9aac Gerd Hoffmann
                                       "descriptor too short");
1152 96dd9aac Gerd Hoffmann
            goto error;
1153 b9dc033c balrog
        }
1154 96dd9aac Gerd Hoffmann
        if (i + d->bLength > s->descr_len) {
1155 96dd9aac Gerd Hoffmann
            trace_usb_host_parse_error(s->bus_num, s->addr,
1156 96dd9aac Gerd Hoffmann
                                       "descriptor too long");
1157 96dd9aac Gerd Hoffmann
            goto error;
1158 2791104c David Ahern
        }
1159 96dd9aac Gerd Hoffmann
        switch (d->bDescriptorType) {
1160 96dd9aac Gerd Hoffmann
        case 0:
1161 96dd9aac Gerd Hoffmann
            trace_usb_host_parse_error(s->bus_num, s->addr,
1162 96dd9aac Gerd Hoffmann
                                       "invalid descriptor type");
1163 96dd9aac Gerd Hoffmann
            goto error;
1164 96dd9aac Gerd Hoffmann
        case USB_DT_DEVICE:
1165 96dd9aac Gerd Hoffmann
            if (d->bLength < 0x12) {
1166 96dd9aac Gerd Hoffmann
                trace_usb_host_parse_error(s->bus_num, s->addr,
1167 96dd9aac Gerd Hoffmann
                                           "device descriptor too short");
1168 96dd9aac Gerd Hoffmann
                goto error;
1169 96dd9aac Gerd Hoffmann
            }
1170 96dd9aac Gerd Hoffmann
            v = (d->u.device.idVendor_hi << 8) | d->u.device.idVendor_lo;
1171 96dd9aac Gerd Hoffmann
            p = (d->u.device.idProduct_hi << 8) | d->u.device.idProduct_lo;
1172 96dd9aac Gerd Hoffmann
            trace_usb_host_parse_device(s->bus_num, s->addr, v, p);
1173 b9dc033c balrog
            break;
1174 96dd9aac Gerd Hoffmann
        case USB_DT_CONFIG:
1175 96dd9aac Gerd Hoffmann
            if (d->bLength < 0x09) {
1176 96dd9aac Gerd Hoffmann
                trace_usb_host_parse_error(s->bus_num, s->addr,
1177 96dd9aac Gerd Hoffmann
                                           "config descriptor too short");
1178 96dd9aac Gerd Hoffmann
                goto error;
1179 2791104c David Ahern
            }
1180 96dd9aac Gerd Hoffmann
            configuration = d->u.config.bConfigurationValue;
1181 96dd9aac Gerd Hoffmann
            active = (configuration == s->dev.configuration);
1182 96dd9aac Gerd Hoffmann
            trace_usb_host_parse_config(s->bus_num, s->addr,
1183 96dd9aac Gerd Hoffmann
                                        configuration, active);
1184 96dd9aac Gerd Hoffmann
            break;
1185 96dd9aac Gerd Hoffmann
        case USB_DT_INTERFACE:
1186 96dd9aac Gerd Hoffmann
            if (d->bLength < 0x09) {
1187 96dd9aac Gerd Hoffmann
                trace_usb_host_parse_error(s->bus_num, s->addr,
1188 96dd9aac Gerd Hoffmann
                                           "interface descriptor too short");
1189 96dd9aac Gerd Hoffmann
                goto error;
1190 96dd9aac Gerd Hoffmann
            }
1191 96dd9aac Gerd Hoffmann
            interface = d->u.interface.bInterfaceNumber;
1192 96dd9aac Gerd Hoffmann
            altsetting = d->u.interface.bAlternateSetting;
1193 96dd9aac Gerd Hoffmann
            active = (configuration == s->dev.configuration) &&
1194 96dd9aac Gerd Hoffmann
                (altsetting == s->dev.altsetting[interface]);
1195 96dd9aac Gerd Hoffmann
            trace_usb_host_parse_interface(s->bus_num, s->addr,
1196 96dd9aac Gerd Hoffmann
                                           interface, altsetting, active);
1197 96dd9aac Gerd Hoffmann
            break;
1198 96dd9aac Gerd Hoffmann
        case USB_DT_ENDPOINT:
1199 96dd9aac Gerd Hoffmann
            if (d->bLength < 0x07) {
1200 96dd9aac Gerd Hoffmann
                trace_usb_host_parse_error(s->bus_num, s->addr,
1201 96dd9aac Gerd Hoffmann
                                           "endpoint descriptor too short");
1202 96dd9aac Gerd Hoffmann
                goto error;
1203 96dd9aac Gerd Hoffmann
            }
1204 96dd9aac Gerd Hoffmann
            devep = d->u.endpoint.bEndpointAddress;
1205 c0e5750b Gerd Hoffmann
            pid = (devep & USB_DIR_IN) ? USB_TOKEN_IN : USB_TOKEN_OUT;
1206 c0e5750b Gerd Hoffmann
            ep = devep & 0xf;
1207 c0e5750b Gerd Hoffmann
            if (ep == 0) {
1208 96dd9aac Gerd Hoffmann
                trace_usb_host_parse_error(s->bus_num, s->addr,
1209 96dd9aac Gerd Hoffmann
                                           "invalid endpoint address");
1210 96dd9aac Gerd Hoffmann
                goto error;
1211 130314f8 Hans de Goede
            }
1212 130314f8 Hans de Goede
1213 96dd9aac Gerd Hoffmann
            type = d->u.endpoint.bmAttributes & 0x3;
1214 96dd9aac Gerd Hoffmann
            mps = d->u.endpoint.wMaxPacketSize_lo |
1215 96dd9aac Gerd Hoffmann
                (d->u.endpoint.wMaxPacketSize_hi << 8);
1216 96dd9aac Gerd Hoffmann
            trace_usb_host_parse_endpoint(s->bus_num, s->addr, ep,
1217 96dd9aac Gerd Hoffmann
                                          (devep & USB_DIR_IN) ? "in" : "out",
1218 96dd9aac Gerd Hoffmann
                                          tname[type], active);
1219 96dd9aac Gerd Hoffmann
1220 96dd9aac Gerd Hoffmann
            if (active) {
1221 96dd9aac Gerd Hoffmann
                usb_ep_set_max_packet_size(&s->dev, pid, ep, mps);
1222 96dd9aac Gerd Hoffmann
                assert(usb_ep_get_type(&s->dev, pid, ep) ==
1223 96dd9aac Gerd Hoffmann
                       USB_ENDPOINT_XFER_INVALID);
1224 96dd9aac Gerd Hoffmann
                usb_ep_set_type(&s->dev, pid, ep, type);
1225 96dd9aac Gerd Hoffmann
                usb_ep_set_ifnum(&s->dev, pid, ep, interface);
1226 96dd9aac Gerd Hoffmann
                if ((s->options & (1 << USB_HOST_OPT_PIPELINE)) &&
1227 96dd9aac Gerd Hoffmann
                    (type == USB_ENDPOINT_XFER_BULK)) {
1228 96dd9aac Gerd Hoffmann
                    usb_ep_set_pipeline(&s->dev, pid, ep, true);
1229 96dd9aac Gerd Hoffmann
                }
1230 d8e17efd Gerd Hoffmann
1231 96dd9aac Gerd Hoffmann
                epd = get_endp(s, pid, ep);
1232 96dd9aac Gerd Hoffmann
                epd->halted = 0;
1233 96dd9aac Gerd Hoffmann
            }
1234 b9dc033c balrog
1235 96dd9aac Gerd Hoffmann
            break;
1236 96dd9aac Gerd Hoffmann
        default:
1237 96dd9aac Gerd Hoffmann
            trace_usb_host_parse_unknown(s->bus_num, s->addr,
1238 96dd9aac Gerd Hoffmann
                                         d->bLength, d->bDescriptorType);
1239 96dd9aac Gerd Hoffmann
            break;
1240 b9dc033c balrog
        }
1241 b9dc033c balrog
    }
1242 b9dc033c balrog
    return 0;
1243 96dd9aac Gerd Hoffmann
1244 96dd9aac Gerd Hoffmann
error:
1245 19deaa08 Gerd Hoffmann
    usb_ep_reset(&s->dev);
1246 96dd9aac Gerd Hoffmann
    return 1;
1247 b9dc033c balrog
}
1248 b9dc033c balrog
1249 e4b17767 Hans de Goede
/*
1250 e4b17767 Hans de Goede
 * Check if we can safely redirect a usb2 device to a usb1 virtual controller,
1251 e4b17767 Hans de Goede
 * this function assumes this is safe, if:
1252 e4b17767 Hans de Goede
 * 1) There are no isoc endpoints
1253 e4b17767 Hans de Goede
 * 2) There are no interrupt endpoints with a max_packet_size > 64
1254 e4b17767 Hans de Goede
 * Note bulk endpoints with a max_packet_size > 64 in theory also are not
1255 e4b17767 Hans de Goede
 * usb1 compatible, but in practice this seems to work fine.
1256 e4b17767 Hans de Goede
 */
1257 e4b17767 Hans de Goede
static int usb_linux_full_speed_compat(USBHostDevice *dev)
1258 e4b17767 Hans de Goede
{
1259 e4b17767 Hans de Goede
    int i, packet_size;
1260 e4b17767 Hans de Goede
1261 e4b17767 Hans de Goede
    /*
1262 e4b17767 Hans de Goede
     * usb_linux_update_endp_table only registers info about ep in the current
1263 e4b17767 Hans de Goede
     * interface altsettings, so we need to parse the descriptors again.
1264 e4b17767 Hans de Goede
     */
1265 e4b17767 Hans de Goede
    for (i = 0; (i + 5) < dev->descr_len; i += dev->descr[i]) {
1266 e4b17767 Hans de Goede
        if (dev->descr[i + 1] == USB_DT_ENDPOINT) {
1267 e4b17767 Hans de Goede
            switch (dev->descr[i + 3] & 0x3) {
1268 e4b17767 Hans de Goede
            case 0x00: /* CONTROL */
1269 e4b17767 Hans de Goede
                break;
1270 e4b17767 Hans de Goede
            case 0x01: /* ISO */
1271 e4b17767 Hans de Goede
                return 0;
1272 e4b17767 Hans de Goede
            case 0x02: /* BULK */
1273 e4b17767 Hans de Goede
                break;
1274 e4b17767 Hans de Goede
            case 0x03: /* INTERRUPT */
1275 e4b17767 Hans de Goede
                packet_size = dev->descr[i + 4] + (dev->descr[i + 5] << 8);
1276 e4b17767 Hans de Goede
                if (packet_size > 64)
1277 e4b17767 Hans de Goede
                    return 0;
1278 e4b17767 Hans de Goede
                break;
1279 e4b17767 Hans de Goede
            }
1280 e4b17767 Hans de Goede
        }
1281 e4b17767 Hans de Goede
    }
1282 e4b17767 Hans de Goede
    return 1;
1283 e4b17767 Hans de Goede
}
1284 e4b17767 Hans de Goede
1285 26a9e82a Gerd Hoffmann
static int usb_host_open(USBHostDevice *dev, int bus_num,
1286 ba9acab9 Gerd Hoffmann
                         int addr, const char *port,
1287 ba9acab9 Gerd Hoffmann
                         const char *prod_name, int speed)
1288 bb36d470 bellard
{
1289 b9dc033c balrog
    int fd = -1, ret;
1290 1f3870ab aliguori
1291 e6a2f500 Gerd Hoffmann
    trace_usb_host_open_started(bus_num, addr);
1292 e6a2f500 Gerd Hoffmann
1293 2791104c David Ahern
    if (dev->fd != -1) {
1294 26a9e82a Gerd Hoffmann
        goto fail;
1295 2791104c David Ahern
    }
1296 3b46e624 ths
1297 097db438 Gerd Hoffmann
    fd = usb_host_open_device(bus_num, addr);
1298 bb36d470 bellard
    if (fd < 0) {
1299 1f3870ab aliguori
        goto fail;
1300 bb36d470 bellard
    }
1301 d0f2c4c6 malc
    DPRINTF("husb: opened %s\n", buf);
1302 bb36d470 bellard
1303 806b6024 Gerd Hoffmann
    dev->bus_num = bus_num;
1304 806b6024 Gerd Hoffmann
    dev->addr = addr;
1305 5557d820 Gerd Hoffmann
    strcpy(dev->port, port);
1306 22f84e73 Gerd Hoffmann
    dev->fd = fd;
1307 806b6024 Gerd Hoffmann
1308 b9dc033c balrog
    /* read the device description */
1309 b9dc033c balrog
    dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
1310 b9dc033c balrog
    if (dev->descr_len <= 0) {
1311 64838171 aliguori
        perror("husb: reading device data failed");
1312 bb36d470 bellard
        goto fail;
1313 bb36d470 bellard
    }
1314 3b46e624 ths
1315 b9dc033c balrog
#ifdef DEBUG
1316 868bfe2b bellard
    {
1317 b9dc033c balrog
        int x;
1318 b9dc033c balrog
        printf("=== begin dumping device descriptor data ===\n");
1319 2791104c David Ahern
        for (x = 0; x < dev->descr_len; x++) {
1320 b9dc033c balrog
            printf("%02x ", dev->descr[x]);
1321 2791104c David Ahern
        }
1322 b9dc033c balrog
        printf("\n=== end dumping device descriptor data ===\n");
1323 bb36d470 bellard
    }
1324 a594cfbf bellard
#endif
1325 a594cfbf bellard
1326 b9dc033c balrog
1327 eb7700bb Gerd Hoffmann
    /* start unconfigured -- we'll wait for the guest to set a configuration */
1328 eb7700bb Gerd Hoffmann
    if (!usb_host_claim_interfaces(dev, 0)) {
1329 b9dc033c balrog
        goto fail;
1330 2791104c David Ahern
    }
1331 bb36d470 bellard
1332 19deaa08 Gerd Hoffmann
    usb_ep_init(&dev->dev);
1333 b9dc033c balrog
    ret = usb_linux_update_endp_table(dev);
1334 2791104c David Ahern
    if (ret) {
1335 bb36d470 bellard
        goto fail;
1336 2791104c David Ahern
    }
1337 b9dc033c balrog
1338 3991c35e Hans de Goede
    if (speed == -1) {
1339 3991c35e Hans de Goede
        struct usbdevfs_connectinfo ci;
1340 3991c35e Hans de Goede
1341 3991c35e Hans de Goede
        ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
1342 3991c35e Hans de Goede
        if (ret < 0) {
1343 3991c35e Hans de Goede
            perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
1344 3991c35e Hans de Goede
            goto fail;
1345 3991c35e Hans de Goede
        }
1346 3991c35e Hans de Goede
1347 3991c35e Hans de Goede
        if (ci.slow) {
1348 3991c35e Hans de Goede
            speed = USB_SPEED_LOW;
1349 3991c35e Hans de Goede
        } else {
1350 3991c35e Hans de Goede
            speed = USB_SPEED_HIGH;
1351 3991c35e Hans de Goede
        }
1352 2791104c David Ahern
    }
1353 3991c35e Hans de Goede
    dev->dev.speed = speed;
1354 ba3f9bfb Hans de Goede
    dev->dev.speedmask = (1 << speed);
1355 e4b17767 Hans de Goede
    if (dev->dev.speed == USB_SPEED_HIGH && usb_linux_full_speed_compat(dev)) {
1356 e4b17767 Hans de Goede
        dev->dev.speedmask |= USB_SPEED_MASK_FULL;
1357 e4b17767 Hans de Goede
    }
1358 3991c35e Hans de Goede
1359 e6a2f500 Gerd Hoffmann
    trace_usb_host_open_success(bus_num, addr);
1360 bb36d470 bellard
1361 2791104c David Ahern
    if (!prod_name || prod_name[0] == '\0') {
1362 0fe6d12e Markus Armbruster
        snprintf(dev->dev.product_desc, sizeof(dev->dev.product_desc),
1363 4b096fc9 aliguori
                 "host:%d.%d", bus_num, addr);
1364 2791104c David Ahern
    } else {
1365 0fe6d12e Markus Armbruster
        pstrcpy(dev->dev.product_desc, sizeof(dev->dev.product_desc),
1366 4b096fc9 aliguori
                prod_name);
1367 2791104c David Ahern
    }
1368 1f6e24e7 bellard
1369 fa19bf83 Hans de Goede
    ret = usb_device_attach(&dev->dev);
1370 fa19bf83 Hans de Goede
    if (ret) {
1371 fa19bf83 Hans de Goede
        goto fail;
1372 fa19bf83 Hans de Goede
    }
1373 fa19bf83 Hans de Goede
1374 64838171 aliguori
    /* USB devio uses 'write' flag to check for async completions */
1375 64838171 aliguori
    qemu_set_fd_handler(dev->fd, NULL, async_complete, dev);
1376 1f3870ab aliguori
1377 26a9e82a Gerd Hoffmann
    return 0;
1378 4b096fc9 aliguori
1379 b9dc033c balrog
fail:
1380 e6a2f500 Gerd Hoffmann
    trace_usb_host_open_failure(bus_num, addr);
1381 1f45a81b Gerd Hoffmann
    if (dev->fd != -1) {
1382 1f45a81b Gerd Hoffmann
        close(dev->fd);
1383 1f45a81b Gerd Hoffmann
        dev->fd = -1;
1384 2791104c David Ahern
    }
1385 26a9e82a Gerd Hoffmann
    return -1;
1386 26a9e82a Gerd Hoffmann
}
1387 26a9e82a Gerd Hoffmann
1388 26a9e82a Gerd Hoffmann
static int usb_host_close(USBHostDevice *dev)
1389 26a9e82a Gerd Hoffmann
{
1390 060dc841 Hans de Goede
    int i;
1391 060dc841 Hans de Goede
1392 39fba3ad Gerd Hoffmann
    if (dev->fd == -1) {
1393 26a9e82a Gerd Hoffmann
        return -1;
1394 2791104c David Ahern
    }
1395 26a9e82a Gerd Hoffmann
1396 e6a2f500 Gerd Hoffmann
    trace_usb_host_close(dev->bus_num, dev->addr);
1397 e6a2f500 Gerd Hoffmann
1398 26a9e82a Gerd Hoffmann
    qemu_set_fd_handler(dev->fd, NULL, NULL, NULL);
1399 26a9e82a Gerd Hoffmann
    dev->closing = 1;
1400 d8e17efd Gerd Hoffmann
    for (i = 1; i <= USB_MAX_ENDPOINTS; i++) {
1401 c0e5750b Gerd Hoffmann
        if (is_isoc(dev, USB_TOKEN_IN, i)) {
1402 c0e5750b Gerd Hoffmann
            usb_host_stop_n_free_iso(dev, USB_TOKEN_IN, i);
1403 c0e5750b Gerd Hoffmann
        }
1404 c0e5750b Gerd Hoffmann
        if (is_isoc(dev, USB_TOKEN_OUT, i)) {
1405 c0e5750b Gerd Hoffmann
            usb_host_stop_n_free_iso(dev, USB_TOKEN_OUT, i);
1406 060dc841 Hans de Goede
        }
1407 060dc841 Hans de Goede
    }
1408 26a9e82a Gerd Hoffmann
    async_complete(dev);
1409 26a9e82a Gerd Hoffmann
    dev->closing = 0;
1410 39fba3ad Gerd Hoffmann
    if (dev->dev.attached) {
1411 39fba3ad Gerd Hoffmann
        usb_device_detach(&dev->dev);
1412 39fba3ad Gerd Hoffmann
    }
1413 c7662daa Gerd Hoffmann
    usb_host_do_reset(dev);
1414 26a9e82a Gerd Hoffmann
    close(dev->fd);
1415 26a9e82a Gerd Hoffmann
    dev->fd = -1;
1416 26a9e82a Gerd Hoffmann
    return 0;
1417 26a9e82a Gerd Hoffmann
}
1418 26a9e82a Gerd Hoffmann
1419 9e8dd451 Jan Kiszka
static void usb_host_exit_notifier(struct Notifier *n, void *data)
1420 b373a63a Shahar Havivi
{
1421 b373a63a Shahar Havivi
    USBHostDevice *s = container_of(n, USBHostDevice, exit);
1422 b373a63a Shahar Havivi
1423 c75fead6 Gerd Hoffmann
    usb_host_release_port(s);
1424 b373a63a Shahar Havivi
    if (s->fd != -1) {
1425 c7662daa Gerd Hoffmann
        usb_host_do_reset(s);;
1426 b373a63a Shahar Havivi
    }
1427 b373a63a Shahar Havivi
}
1428 b373a63a Shahar Havivi
1429 a229c053 Gerd Hoffmann
/*
1430 a229c053 Gerd Hoffmann
 * This is *NOT* about restoring state.  We have absolutely no idea
1431 a229c053 Gerd Hoffmann
 * what state the host device is in at the moment and whenever it is
1432 a229c053 Gerd Hoffmann
 * still present in the first place.  Attemping to contine where we
1433 a229c053 Gerd Hoffmann
 * left off is impossible.
1434 a229c053 Gerd Hoffmann
 *
1435 a229c053 Gerd Hoffmann
 * What we are going to to to here is emulate a surprise removal of
1436 a229c053 Gerd Hoffmann
 * the usb device passed through, then kick host scan so the device
1437 a229c053 Gerd Hoffmann
 * will get re-attached (and re-initialized by the guest) in case it
1438 a229c053 Gerd Hoffmann
 * is still present.
1439 a229c053 Gerd Hoffmann
 *
1440 a229c053 Gerd Hoffmann
 * As the device removal will change the state of other devices (usb
1441 a229c053 Gerd Hoffmann
 * host controller, most likely interrupt controller too) we have to
1442 a229c053 Gerd Hoffmann
 * wait with it until *all* vmstate is loaded.  Thus post_load just
1443 a229c053 Gerd Hoffmann
 * kicks a bottom half which then does the actual work.
1444 a229c053 Gerd Hoffmann
 */
1445 a229c053 Gerd Hoffmann
static void usb_host_post_load_bh(void *opaque)
1446 a229c053 Gerd Hoffmann
{
1447 a229c053 Gerd Hoffmann
    USBHostDevice *dev = opaque;
1448 a229c053 Gerd Hoffmann
1449 a229c053 Gerd Hoffmann
    if (dev->fd != -1) {
1450 a229c053 Gerd Hoffmann
        usb_host_close(dev);
1451 a229c053 Gerd Hoffmann
    }
1452 a229c053 Gerd Hoffmann
    if (dev->dev.attached) {
1453 a229c053 Gerd Hoffmann
        usb_device_detach(&dev->dev);
1454 a229c053 Gerd Hoffmann
    }
1455 a229c053 Gerd Hoffmann
    usb_host_auto_check(NULL);
1456 a229c053 Gerd Hoffmann
}
1457 a229c053 Gerd Hoffmann
1458 a229c053 Gerd Hoffmann
static int usb_host_post_load(void *opaque, int version_id)
1459 a229c053 Gerd Hoffmann
{
1460 a229c053 Gerd Hoffmann
    USBHostDevice *dev = opaque;
1461 a229c053 Gerd Hoffmann
1462 a229c053 Gerd Hoffmann
    qemu_bh_schedule(dev->bh);
1463 a229c053 Gerd Hoffmann
    return 0;
1464 a229c053 Gerd Hoffmann
}
1465 a229c053 Gerd Hoffmann
1466 26a9e82a Gerd Hoffmann
static int usb_host_initfn(USBDevice *dev)
1467 26a9e82a Gerd Hoffmann
{
1468 26a9e82a Gerd Hoffmann
    USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
1469 26a9e82a Gerd Hoffmann
1470 26a9e82a Gerd Hoffmann
    dev->auto_attach = 0;
1471 26a9e82a Gerd Hoffmann
    s->fd = -1;
1472 9516bb47 Gerd Hoffmann
    s->hub_fd = -1;
1473 9516bb47 Gerd Hoffmann
1474 26a9e82a Gerd Hoffmann
    QTAILQ_INSERT_TAIL(&hostdevs, s, next);
1475 b373a63a Shahar Havivi
    s->exit.notify = usb_host_exit_notifier;
1476 b373a63a Shahar Havivi
    qemu_add_exit_notifier(&s->exit);
1477 a229c053 Gerd Hoffmann
    s->bh = qemu_bh_new(usb_host_post_load_bh, s);
1478 26a9e82a Gerd Hoffmann
    usb_host_auto_check(NULL);
1479 9516bb47 Gerd Hoffmann
1480 9516bb47 Gerd Hoffmann
    if (s->match.bus_num != 0 && s->match.port != NULL) {
1481 e6274727 Gerd Hoffmann
        usb_host_claim_port(s);
1482 9516bb47 Gerd Hoffmann
    }
1483 65bb3a5c Gerd Hoffmann
    add_boot_device_path(s->bootindex, &dev->qdev, NULL);
1484 26a9e82a Gerd Hoffmann
    return 0;
1485 a594cfbf bellard
}
1486 bb36d470 bellard
1487 d6791578 Gerd Hoffmann
static const VMStateDescription vmstate_usb_host = {
1488 d6791578 Gerd Hoffmann
    .name = "usb-host",
1489 a229c053 Gerd Hoffmann
    .version_id = 1,
1490 a229c053 Gerd Hoffmann
    .minimum_version_id = 1,
1491 a229c053 Gerd Hoffmann
    .post_load = usb_host_post_load,
1492 a229c053 Gerd Hoffmann
    .fields = (VMStateField[]) {
1493 a229c053 Gerd Hoffmann
        VMSTATE_USB_DEVICE(dev, USBHostDevice),
1494 a229c053 Gerd Hoffmann
        VMSTATE_END_OF_LIST()
1495 a229c053 Gerd Hoffmann
    }
1496 d6791578 Gerd Hoffmann
};
1497 d6791578 Gerd Hoffmann
1498 39bffca2 Anthony Liguori
static Property usb_host_dev_properties[] = {
1499 39bffca2 Anthony Liguori
    DEFINE_PROP_UINT32("hostbus",  USBHostDevice, match.bus_num,    0),
1500 39bffca2 Anthony Liguori
    DEFINE_PROP_UINT32("hostaddr", USBHostDevice, match.addr,       0),
1501 39bffca2 Anthony Liguori
    DEFINE_PROP_STRING("hostport", USBHostDevice, match.port),
1502 39bffca2 Anthony Liguori
    DEFINE_PROP_HEX32("vendorid",  USBHostDevice, match.vendor_id,  0),
1503 39bffca2 Anthony Liguori
    DEFINE_PROP_HEX32("productid", USBHostDevice, match.product_id, 0),
1504 39bffca2 Anthony Liguori
    DEFINE_PROP_UINT32("isobufs",  USBHostDevice, iso_urb_count,    4),
1505 65bb3a5c Gerd Hoffmann
    DEFINE_PROP_INT32("bootindex", USBHostDevice, bootindex,        -1),
1506 39c20577 Gerd Hoffmann
    DEFINE_PROP_BIT("pipeline",    USBHostDevice, options,
1507 39c20577 Gerd Hoffmann
                    USB_HOST_OPT_PIPELINE, true),
1508 39bffca2 Anthony Liguori
    DEFINE_PROP_END_OF_LIST(),
1509 39bffca2 Anthony Liguori
};
1510 39bffca2 Anthony Liguori
1511 62aed765 Anthony Liguori
static void usb_host_class_initfn(ObjectClass *klass, void *data)
1512 62aed765 Anthony Liguori
{
1513 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
1514 62aed765 Anthony Liguori
    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
1515 62aed765 Anthony Liguori
1516 62aed765 Anthony Liguori
    uc->init           = usb_host_initfn;
1517 62aed765 Anthony Liguori
    uc->product_desc   = "USB Host Device";
1518 62aed765 Anthony Liguori
    uc->cancel_packet  = usb_host_async_cancel;
1519 62aed765 Anthony Liguori
    uc->handle_data    = usb_host_handle_data;
1520 62aed765 Anthony Liguori
    uc->handle_control = usb_host_handle_control;
1521 62aed765 Anthony Liguori
    uc->handle_reset   = usb_host_handle_reset;
1522 62aed765 Anthony Liguori
    uc->handle_destroy = usb_host_handle_destroy;
1523 39bffca2 Anthony Liguori
    dc->vmsd = &vmstate_usb_host;
1524 39bffca2 Anthony Liguori
    dc->props = usb_host_dev_properties;
1525 62aed765 Anthony Liguori
}
1526 62aed765 Anthony Liguori
1527 39bffca2 Anthony Liguori
static TypeInfo usb_host_dev_info = {
1528 39bffca2 Anthony Liguori
    .name          = "usb-host",
1529 39bffca2 Anthony Liguori
    .parent        = TYPE_USB_DEVICE,
1530 39bffca2 Anthony Liguori
    .instance_size = sizeof(USBHostDevice),
1531 39bffca2 Anthony Liguori
    .class_init    = usb_host_class_initfn,
1532 806b6024 Gerd Hoffmann
};
1533 806b6024 Gerd Hoffmann
1534 83f7d43a Andreas Fรคrber
static void usb_host_register_types(void)
1535 806b6024 Gerd Hoffmann
{
1536 39bffca2 Anthony Liguori
    type_register_static(&usb_host_dev_info);
1537 ba02430f Anthony Liguori
    usb_legacy_register("usb-host", "host", usb_host_device_open);
1538 806b6024 Gerd Hoffmann
}
1539 83f7d43a Andreas Fรคrber
1540 83f7d43a Andreas Fรคrber
type_init(usb_host_register_types)
1541 806b6024 Gerd Hoffmann
1542 3741715c Jan Kiszka
USBDevice *usb_host_device_open(USBBus *bus, const char *devname)
1543 4b096fc9 aliguori
{
1544 0745eb1e Markus Armbruster
    struct USBAutoFilter filter;
1545 26a9e82a Gerd Hoffmann
    USBDevice *dev;
1546 26a9e82a Gerd Hoffmann
    char *p;
1547 26a9e82a Gerd Hoffmann
1548 3741715c Jan Kiszka
    dev = usb_create(bus, "usb-host");
1549 4b096fc9 aliguori
1550 5d0c5750 aliguori
    if (strstr(devname, "auto:")) {
1551 2791104c David Ahern
        if (parse_filter(devname, &filter) < 0) {
1552 26a9e82a Gerd Hoffmann
            goto fail;
1553 2791104c David Ahern
        }
1554 26a9e82a Gerd Hoffmann
    } else {
1555 26a9e82a Gerd Hoffmann
        if ((p = strchr(devname, '.'))) {
1556 0745eb1e Markus Armbruster
            filter.bus_num    = strtoul(devname, NULL, 0);
1557 0745eb1e Markus Armbruster
            filter.addr       = strtoul(p + 1, NULL, 0);
1558 0745eb1e Markus Armbruster
            filter.vendor_id  = 0;
1559 0745eb1e Markus Armbruster
            filter.product_id = 0;
1560 26a9e82a Gerd Hoffmann
        } else if ((p = strchr(devname, ':'))) {
1561 0745eb1e Markus Armbruster
            filter.bus_num    = 0;
1562 0745eb1e Markus Armbruster
            filter.addr       = 0;
1563 26a9e82a Gerd Hoffmann
            filter.vendor_id  = strtoul(devname, NULL, 16);
1564 0745eb1e Markus Armbruster
            filter.product_id = strtoul(p + 1, NULL, 16);
1565 26a9e82a Gerd Hoffmann
        } else {
1566 26a9e82a Gerd Hoffmann
            goto fail;
1567 26a9e82a Gerd Hoffmann
        }
1568 5d0c5750 aliguori
    }
1569 4b096fc9 aliguori
1570 0745eb1e Markus Armbruster
    qdev_prop_set_uint32(&dev->qdev, "hostbus",   filter.bus_num);
1571 0745eb1e Markus Armbruster
    qdev_prop_set_uint32(&dev->qdev, "hostaddr",  filter.addr);
1572 26a9e82a Gerd Hoffmann
    qdev_prop_set_uint32(&dev->qdev, "vendorid",  filter.vendor_id);
1573 26a9e82a Gerd Hoffmann
    qdev_prop_set_uint32(&dev->qdev, "productid", filter.product_id);
1574 beb6f0de Kevin Wolf
    qdev_init_nofail(&dev->qdev);
1575 26a9e82a Gerd Hoffmann
    return dev;
1576 5d0c5750 aliguori
1577 26a9e82a Gerd Hoffmann
fail:
1578 26a9e82a Gerd Hoffmann
    qdev_free(&dev->qdev);
1579 26a9e82a Gerd Hoffmann
    return NULL;
1580 4b096fc9 aliguori
}
1581 5d0c5750 aliguori
1582 5d0c5750 aliguori
int usb_host_device_close(const char *devname)
1583 5d0c5750 aliguori
{
1584 26a9e82a Gerd Hoffmann
#if 0
1585 5d0c5750 aliguori
    char product_name[PRODUCT_NAME_SZ];
1586 5d0c5750 aliguori
    int bus_num, addr;
1587 5d0c5750 aliguori
    USBHostDevice *s;
1588 5d0c5750 aliguori

1589 2791104c David Ahern
    if (strstr(devname, "auto:")) {
1590 5d0c5750 aliguori
        return usb_host_auto_del(devname);
1591 2791104c David Ahern
    }
1592 2791104c David Ahern
    if (usb_host_find_device(&bus_num, &addr, product_name,
1593 2791104c David Ahern
                                    sizeof(product_name), devname) < 0) {
1594 5d0c5750 aliguori
        return -1;
1595 2791104c David Ahern
    }
1596 5d0c5750 aliguori
    s = hostdev_find(bus_num, addr);
1597 5d0c5750 aliguori
    if (s) {
1598 a5d2f727 Gerd Hoffmann
        usb_device_delete_addr(s->bus_num, s->dev.addr);
1599 5d0c5750 aliguori
        return 0;
1600 5d0c5750 aliguori
    }
1601 26a9e82a Gerd Hoffmann
#endif
1602 5d0c5750 aliguori
1603 5d0c5750 aliguori
    return -1;
1604 5d0c5750 aliguori
}
1605 a5d2f727 Gerd Hoffmann
1606 0f431527 aliguori
/*
1607 0f431527 aliguori
 * Read sys file-system device file
1608 0f431527 aliguori
 *
1609 0f431527 aliguori
 * @line address of buffer to put file contents in
1610 0f431527 aliguori
 * @line_size size of line
1611 0f431527 aliguori
 * @device_file path to device file (printf format string)
1612 0f431527 aliguori
 * @device_name device being opened (inserted into device_file)
1613 0f431527 aliguori
 *
1614 0f431527 aliguori
 * @return 0 failed, 1 succeeded ('line' contains data)
1615 0f431527 aliguori
 */
1616 2791104c David Ahern
static int usb_host_read_file(char *line, size_t line_size,
1617 2791104c David Ahern
                              const char *device_file, const char *device_name)
1618 0f431527 aliguori
{
1619 0f431527 aliguori
    FILE *f;
1620 0f431527 aliguori
    int ret = 0;
1621 0f431527 aliguori
    char filename[PATH_MAX];
1622 0f431527 aliguori
1623 097db438 Gerd Hoffmann
    snprintf(filename, PATH_MAX, "/sys/bus/usb/devices/%s/%s", device_name,
1624 b4e237aa blueswir1
             device_file);
1625 0f431527 aliguori
    f = fopen(filename, "r");
1626 0f431527 aliguori
    if (f) {
1627 9f99cee7 Kirill A. Shutemov
        ret = fgets(line, line_size, f) != NULL;
1628 0f431527 aliguori
        fclose(f);
1629 0f431527 aliguori
    }
1630 0f431527 aliguori
1631 0f431527 aliguori
    return ret;
1632 0f431527 aliguori
}
1633 0f431527 aliguori
1634 0f431527 aliguori
/*
1635 0f431527 aliguori
 * Use /sys/bus/usb/devices/ directory to determine host's USB
1636 0f431527 aliguori
 * devices.
1637 0f431527 aliguori
 *
1638 0f431527 aliguori
 * This code is based on Robert Schiele's original patches posted to
1639 0f431527 aliguori
 * the Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
1640 0f431527 aliguori
 */
1641 097db438 Gerd Hoffmann
static int usb_host_scan(void *opaque, USBScanFunc *func)
1642 0f431527 aliguori
{
1643 660f11be Blue Swirl
    DIR *dir = NULL;
1644 0f431527 aliguori
    char line[1024];
1645 5557d820 Gerd Hoffmann
    int bus_num, addr, speed, class_id, product_id, vendor_id;
1646 0f431527 aliguori
    int ret = 0;
1647 5557d820 Gerd Hoffmann
    char port[MAX_PORTLEN];
1648 0f431527 aliguori
    char product_name[512];
1649 0f431527 aliguori
    struct dirent *de;
1650 0f431527 aliguori
1651 097db438 Gerd Hoffmann
    dir = opendir("/sys/bus/usb/devices");
1652 0f431527 aliguori
    if (!dir) {
1653 097db438 Gerd Hoffmann
        perror("husb: opendir /sys/bus/usb/devices");
1654 097db438 Gerd Hoffmann
        fprintf(stderr, "husb: please make sure sysfs is mounted at /sys\n");
1655 0f431527 aliguori
        goto the_end;
1656 0f431527 aliguori
    }
1657 0f431527 aliguori
1658 0f431527 aliguori
    while ((de = readdir(dir))) {
1659 0f431527 aliguori
        if (de->d_name[0] != '.' && !strchr(de->d_name, ':')) {
1660 5557d820 Gerd Hoffmann
            if (sscanf(de->d_name, "%d-%7[0-9.]", &bus_num, port) < 2) {
1661 5557d820 Gerd Hoffmann
                continue;
1662 0f5160d1 Hans de Goede
            }
1663 0f431527 aliguori
1664 2791104c David Ahern
            if (!usb_host_read_file(line, sizeof(line), "devnum", de->d_name)) {
1665 0f431527 aliguori
                goto the_end;
1666 2791104c David Ahern
            }
1667 2791104c David Ahern
            if (sscanf(line, "%d", &addr) != 1) {
1668 0f431527 aliguori
                goto the_end;
1669 2791104c David Ahern
            }
1670 b4e237aa blueswir1
            if (!usb_host_read_file(line, sizeof(line), "bDeviceClass",
1671 2791104c David Ahern
                                    de->d_name)) {
1672 0f431527 aliguori
                goto the_end;
1673 2791104c David Ahern
            }
1674 2791104c David Ahern
            if (sscanf(line, "%x", &class_id) != 1) {
1675 0f431527 aliguori
                goto the_end;
1676 2791104c David Ahern
            }
1677 0f431527 aliguori
1678 2791104c David Ahern
            if (!usb_host_read_file(line, sizeof(line), "idVendor",
1679 2791104c David Ahern
                                    de->d_name)) {
1680 0f431527 aliguori
                goto the_end;
1681 2791104c David Ahern
            }
1682 2791104c David Ahern
            if (sscanf(line, "%x", &vendor_id) != 1) {
1683 0f431527 aliguori
                goto the_end;
1684 2791104c David Ahern
            }
1685 b4e237aa blueswir1
            if (!usb_host_read_file(line, sizeof(line), "idProduct",
1686 2791104c David Ahern
                                    de->d_name)) {
1687 0f431527 aliguori
                goto the_end;
1688 2791104c David Ahern
            }
1689 2791104c David Ahern
            if (sscanf(line, "%x", &product_id) != 1) {
1690 0f431527 aliguori
                goto the_end;
1691 2791104c David Ahern
            }
1692 b4e237aa blueswir1
            if (!usb_host_read_file(line, sizeof(line), "product",
1693 b4e237aa blueswir1
                                    de->d_name)) {
1694 0f431527 aliguori
                *product_name = 0;
1695 0f431527 aliguori
            } else {
1696 2791104c David Ahern
                if (strlen(line) > 0) {
1697 0f431527 aliguori
                    line[strlen(line) - 1] = '\0';
1698 2791104c David Ahern
                }
1699 0f431527 aliguori
                pstrcpy(product_name, sizeof(product_name), line);
1700 0f431527 aliguori
            }
1701 0f431527 aliguori
1702 2791104c David Ahern
            if (!usb_host_read_file(line, sizeof(line), "speed", de->d_name)) {
1703 0f431527 aliguori
                goto the_end;
1704 2791104c David Ahern
            }
1705 f264cfbf Hans de Goede
            if (!strcmp(line, "5000\n")) {
1706 f264cfbf Hans de Goede
                speed = USB_SPEED_SUPER;
1707 f264cfbf Hans de Goede
            } else if (!strcmp(line, "480\n")) {
1708 0f431527 aliguori
                speed = USB_SPEED_HIGH;
1709 2791104c David Ahern
            } else if (!strcmp(line, "1.5\n")) {
1710 0f431527 aliguori
                speed = USB_SPEED_LOW;
1711 2791104c David Ahern
            } else {
1712 0f431527 aliguori
                speed = USB_SPEED_FULL;
1713 2791104c David Ahern
            }
1714 0f431527 aliguori
1715 5557d820 Gerd Hoffmann
            ret = func(opaque, bus_num, addr, port, class_id, vendor_id,
1716 0f431527 aliguori
                       product_id, product_name, speed);
1717 2791104c David Ahern
            if (ret) {
1718 0f431527 aliguori
                goto the_end;
1719 2791104c David Ahern
            }
1720 0f431527 aliguori
        }
1721 0f431527 aliguori
    }
1722 0f431527 aliguori
 the_end:
1723 2791104c David Ahern
    if (dir) {
1724 0f431527 aliguori
        closedir(dir);
1725 2791104c David Ahern
    }
1726 0f431527 aliguori
    return ret;
1727 0f431527 aliguori
}
1728 0f431527 aliguori
1729 4b096fc9 aliguori
static QEMUTimer *usb_auto_timer;
1730 4b096fc9 aliguori
1731 ba9acab9 Gerd Hoffmann
static int usb_host_auto_scan(void *opaque, int bus_num,
1732 ba9acab9 Gerd Hoffmann
                              int addr, const char *port,
1733 26a9e82a Gerd Hoffmann
                              int class_id, int vendor_id, int product_id,
1734 26a9e82a Gerd Hoffmann
                              const char *product_name, int speed)
1735 4b096fc9 aliguori
{
1736 4b096fc9 aliguori
    struct USBAutoFilter *f;
1737 26a9e82a Gerd Hoffmann
    struct USBHostDevice *s;
1738 4b096fc9 aliguori
1739 4b096fc9 aliguori
    /* Ignore hubs */
1740 4b096fc9 aliguori
    if (class_id == 9)
1741 4b096fc9 aliguori
        return 0;
1742 4b096fc9 aliguori
1743 26a9e82a Gerd Hoffmann
    QTAILQ_FOREACH(s, &hostdevs, next) {
1744 26a9e82a Gerd Hoffmann
        f = &s->match;
1745 26a9e82a Gerd Hoffmann
1746 2791104c David Ahern
        if (f->bus_num > 0 && f->bus_num != bus_num) {
1747 4b096fc9 aliguori
            continue;
1748 2791104c David Ahern
        }
1749 2791104c David Ahern
        if (f->addr > 0 && f->addr != addr) {
1750 4b096fc9 aliguori
            continue;
1751 2791104c David Ahern
        }
1752 9056a297 Gerd Hoffmann
        if (f->port != NULL && (port == NULL || strcmp(f->port, port) != 0)) {
1753 9056a297 Gerd Hoffmann
            continue;
1754 9056a297 Gerd Hoffmann
        }
1755 4b096fc9 aliguori
1756 2791104c David Ahern
        if (f->vendor_id > 0 && f->vendor_id != vendor_id) {
1757 4b096fc9 aliguori
            continue;
1758 2791104c David Ahern
        }
1759 4b096fc9 aliguori
1760 2791104c David Ahern
        if (f->product_id > 0 && f->product_id != product_id) {
1761 4b096fc9 aliguori
            continue;
1762 2791104c David Ahern
        }
1763 4b096fc9 aliguori
        /* We got a match */
1764 3ee886c5 Gerd Hoffmann
        s->seen++;
1765 3ee886c5 Gerd Hoffmann
        if (s->errcount >= 3) {
1766 3ee886c5 Gerd Hoffmann
            return 0;
1767 3ee886c5 Gerd Hoffmann
        }
1768 4b096fc9 aliguori
1769 33e66b86 Markus Armbruster
        /* Already attached ? */
1770 2791104c David Ahern
        if (s->fd != -1) {
1771 4b096fc9 aliguori
            return 0;
1772 2791104c David Ahern
        }
1773 d0f2c4c6 malc
        DPRINTF("husb: auto open: bus_num %d addr %d\n", bus_num, addr);
1774 4b096fc9 aliguori
1775 3ee886c5 Gerd Hoffmann
        if (usb_host_open(s, bus_num, addr, port, product_name, speed) < 0) {
1776 3ee886c5 Gerd Hoffmann
            s->errcount++;
1777 3ee886c5 Gerd Hoffmann
        }
1778 97f86166 Hans de Goede
        break;
1779 4b096fc9 aliguori
    }
1780 4b096fc9 aliguori
1781 4b096fc9 aliguori
    return 0;
1782 4b096fc9 aliguori
}
1783 4b096fc9 aliguori
1784 26a9e82a Gerd Hoffmann
static void usb_host_auto_check(void *unused)
1785 4b096fc9 aliguori
{
1786 26a9e82a Gerd Hoffmann
    struct USBHostDevice *s;
1787 26a9e82a Gerd Hoffmann
    int unconnected = 0;
1788 26a9e82a Gerd Hoffmann
1789 a844ed84 Gerd Hoffmann
    if (runstate_is_running()) {
1790 a844ed84 Gerd Hoffmann
        usb_host_scan(NULL, usb_host_auto_scan);
1791 26a9e82a Gerd Hoffmann
1792 a844ed84 Gerd Hoffmann
        QTAILQ_FOREACH(s, &hostdevs, next) {
1793 a844ed84 Gerd Hoffmann
            if (s->fd == -1) {
1794 a844ed84 Gerd Hoffmann
                unconnected++;
1795 a844ed84 Gerd Hoffmann
            }
1796 a844ed84 Gerd Hoffmann
            if (s->seen == 0) {
1797 a844ed84 Gerd Hoffmann
                s->errcount = 0;
1798 a844ed84 Gerd Hoffmann
            }
1799 a844ed84 Gerd Hoffmann
            s->seen = 0;
1800 3ee886c5 Gerd Hoffmann
        }
1801 26a9e82a Gerd Hoffmann
1802 a844ed84 Gerd Hoffmann
        if (unconnected == 0) {
1803 a844ed84 Gerd Hoffmann
            /* nothing to watch */
1804 a844ed84 Gerd Hoffmann
            if (usb_auto_timer) {
1805 a844ed84 Gerd Hoffmann
                qemu_del_timer(usb_auto_timer);
1806 a844ed84 Gerd Hoffmann
                trace_usb_host_auto_scan_disabled();
1807 a844ed84 Gerd Hoffmann
            }
1808 a844ed84 Gerd Hoffmann
            return;
1809 2791104c David Ahern
        }
1810 26a9e82a Gerd Hoffmann
    }
1811 26a9e82a Gerd Hoffmann
1812 26a9e82a Gerd Hoffmann
    if (!usb_auto_timer) {
1813 7bd427d8 Paolo Bonzini
        usb_auto_timer = qemu_new_timer_ms(rt_clock, usb_host_auto_check, NULL);
1814 2791104c David Ahern
        if (!usb_auto_timer) {
1815 26a9e82a Gerd Hoffmann
            return;
1816 2791104c David Ahern
        }
1817 e6a2f500 Gerd Hoffmann
        trace_usb_host_auto_scan_enabled();
1818 26a9e82a Gerd Hoffmann
    }
1819 7bd427d8 Paolo Bonzini
    qemu_mod_timer(usb_auto_timer, qemu_get_clock_ms(rt_clock) + 2000);
1820 4b096fc9 aliguori
}
1821 4b096fc9 aliguori
1822 4b096fc9 aliguori
/*
1823 5d0c5750 aliguori
 * Autoconnect filter
1824 5d0c5750 aliguori
 * Format:
1825 5d0c5750 aliguori
 *    auto:bus:dev[:vid:pid]
1826 5d0c5750 aliguori
 *    auto:bus.dev[:vid:pid]
1827 5d0c5750 aliguori
 *
1828 5d0c5750 aliguori
 *    bus  - bus number    (dec, * means any)
1829 5d0c5750 aliguori
 *    dev  - device number (dec, * means any)
1830 5d0c5750 aliguori
 *    vid  - vendor id     (hex, * means any)
1831 5d0c5750 aliguori
 *    pid  - product id    (hex, * means any)
1832 5d0c5750 aliguori
 *
1833 5d0c5750 aliguori
 *    See 'lsusb' output.
1834 4b096fc9 aliguori
 */
1835 5d0c5750 aliguori
static int parse_filter(const char *spec, struct USBAutoFilter *f)
1836 4b096fc9 aliguori
{
1837 5d0c5750 aliguori
    enum { BUS, DEV, VID, PID, DONE };
1838 5d0c5750 aliguori
    const char *p = spec;
1839 5d0c5750 aliguori
    int i;
1840 5d0c5750 aliguori
1841 0745eb1e Markus Armbruster
    f->bus_num    = 0;
1842 0745eb1e Markus Armbruster
    f->addr       = 0;
1843 0745eb1e Markus Armbruster
    f->vendor_id  = 0;
1844 0745eb1e Markus Armbruster
    f->product_id = 0;
1845 5d0c5750 aliguori
1846 5d0c5750 aliguori
    for (i = BUS; i < DONE; i++) {
1847 2791104c David Ahern
        p = strpbrk(p, ":.");
1848 2791104c David Ahern
        if (!p) {
1849 2791104c David Ahern
            break;
1850 2791104c David Ahern
        }
1851 5d0c5750 aliguori
        p++;
1852 5d0c5750 aliguori
1853 2791104c David Ahern
        if (*p == '*') {
1854 2791104c David Ahern
            continue;
1855 2791104c David Ahern
        }
1856 5d0c5750 aliguori
        switch(i) {
1857 5d0c5750 aliguori
        case BUS: f->bus_num = strtol(p, NULL, 10);    break;
1858 5d0c5750 aliguori
        case DEV: f->addr    = strtol(p, NULL, 10);    break;
1859 5d0c5750 aliguori
        case VID: f->vendor_id  = strtol(p, NULL, 16); break;
1860 5d0c5750 aliguori
        case PID: f->product_id = strtol(p, NULL, 16); break;
1861 5d0c5750 aliguori
        }
1862 5d0c5750 aliguori
    }
1863 5d0c5750 aliguori
1864 5d0c5750 aliguori
    if (i < DEV) {
1865 5d0c5750 aliguori
        fprintf(stderr, "husb: invalid auto filter spec %s\n", spec);
1866 5d0c5750 aliguori
        return -1;
1867 5d0c5750 aliguori
    }
1868 5d0c5750 aliguori
1869 5d0c5750 aliguori
    return 0;
1870 5d0c5750 aliguori
}
1871 5d0c5750 aliguori
1872 a594cfbf bellard
/**********************/
1873 a594cfbf bellard
/* USB host device info */
1874 a594cfbf bellard
1875 a594cfbf bellard
struct usb_class_info {
1876 a594cfbf bellard
    int class;
1877 a594cfbf bellard
    const char *class_name;
1878 a594cfbf bellard
};
1879 a594cfbf bellard
1880 a594cfbf bellard
static const struct usb_class_info usb_class_info[] = {
1881 a594cfbf bellard
    { USB_CLASS_AUDIO, "Audio"},
1882 a594cfbf bellard
    { USB_CLASS_COMM, "Communication"},
1883 a594cfbf bellard
    { USB_CLASS_HID, "HID"},
1884 a594cfbf bellard
    { USB_CLASS_HUB, "Hub" },
1885 a594cfbf bellard
    { USB_CLASS_PHYSICAL, "Physical" },
1886 a594cfbf bellard
    { USB_CLASS_PRINTER, "Printer" },
1887 a594cfbf bellard
    { USB_CLASS_MASS_STORAGE, "Storage" },
1888 a594cfbf bellard
    { USB_CLASS_CDC_DATA, "Data" },
1889 a594cfbf bellard
    { USB_CLASS_APP_SPEC, "Application Specific" },
1890 a594cfbf bellard
    { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
1891 a594cfbf bellard
    { USB_CLASS_STILL_IMAGE, "Still Image" },
1892 b9dc033c balrog
    { USB_CLASS_CSCID, "Smart Card" },
1893 a594cfbf bellard
    { USB_CLASS_CONTENT_SEC, "Content Security" },
1894 a594cfbf bellard
    { -1, NULL }
1895 a594cfbf bellard
};
1896 a594cfbf bellard
1897 a594cfbf bellard
static const char *usb_class_str(uint8_t class)
1898 bb36d470 bellard
{
1899 a594cfbf bellard
    const struct usb_class_info *p;
1900 a594cfbf bellard
    for(p = usb_class_info; p->class != -1; p++) {
1901 2791104c David Ahern
        if (p->class == class) {
1902 a594cfbf bellard
            break;
1903 2791104c David Ahern
        }
1904 bb36d470 bellard
    }
1905 a594cfbf bellard
    return p->class_name;
1906 a594cfbf bellard
}
1907 a594cfbf bellard
1908 ba9acab9 Gerd Hoffmann
static void usb_info_device(Monitor *mon, int bus_num,
1909 ba9acab9 Gerd Hoffmann
                            int addr, const char *port,
1910 5557d820 Gerd Hoffmann
                            int class_id, int vendor_id, int product_id,
1911 9596ebb7 pbrook
                            const char *product_name,
1912 9596ebb7 pbrook
                            int speed)
1913 a594cfbf bellard
{
1914 a594cfbf bellard
    const char *class_str, *speed_str;
1915 a594cfbf bellard
1916 a594cfbf bellard
    switch(speed) {
1917 5fafdf24 ths
    case USB_SPEED_LOW:
1918 5fafdf24 ths
        speed_str = "1.5";
1919 a594cfbf bellard
        break;
1920 5fafdf24 ths
    case USB_SPEED_FULL:
1921 5fafdf24 ths
        speed_str = "12";
1922 a594cfbf bellard
        break;
1923 5fafdf24 ths
    case USB_SPEED_HIGH:
1924 5fafdf24 ths
        speed_str = "480";
1925 a594cfbf bellard
        break;
1926 f264cfbf Hans de Goede
    case USB_SPEED_SUPER:
1927 f264cfbf Hans de Goede
        speed_str = "5000";
1928 f264cfbf Hans de Goede
        break;
1929 a594cfbf bellard
    default:
1930 5fafdf24 ths
        speed_str = "?";
1931 a594cfbf bellard
        break;
1932 a594cfbf bellard
    }
1933 a594cfbf bellard
1934 5557d820 Gerd Hoffmann
    monitor_printf(mon, "  Bus %d, Addr %d, Port %s, Speed %s Mb/s\n",
1935 5557d820 Gerd Hoffmann
                   bus_num, addr, port, speed_str);
1936 a594cfbf bellard
    class_str = usb_class_str(class_id);
1937 2791104c David Ahern
    if (class_str) {
1938 376253ec aliguori
        monitor_printf(mon, "    %s:", class_str);
1939 2791104c David Ahern
    } else {
1940 376253ec aliguori
        monitor_printf(mon, "    Class %02x:", class_id);
1941 2791104c David Ahern
    }
1942 376253ec aliguori
    monitor_printf(mon, " USB device %04x:%04x", vendor_id, product_id);
1943 2791104c David Ahern
    if (product_name[0] != '\0') {
1944 376253ec aliguori
        monitor_printf(mon, ", %s", product_name);
1945 2791104c David Ahern
    }
1946 376253ec aliguori
    monitor_printf(mon, "\n");
1947 a594cfbf bellard
}
1948 a594cfbf bellard
1949 5fafdf24 ths
static int usb_host_info_device(void *opaque, int bus_num, int addr,
1950 ba9acab9 Gerd Hoffmann
                                const char *path, int class_id,
1951 5fafdf24 ths
                                int vendor_id, int product_id,
1952 a594cfbf bellard
                                const char *product_name,
1953 a594cfbf bellard
                                int speed)
1954 a594cfbf bellard
{
1955 179da8af Blue Swirl
    Monitor *mon = opaque;
1956 179da8af Blue Swirl
1957 5557d820 Gerd Hoffmann
    usb_info_device(mon, bus_num, addr, path, class_id, vendor_id, product_id,
1958 a594cfbf bellard
                    product_name, speed);
1959 a594cfbf bellard
    return 0;
1960 a594cfbf bellard
}
1961 a594cfbf bellard
1962 ac4ffb5a aliguori
static void dec2str(int val, char *str, size_t size)
1963 5d0c5750 aliguori
{
1964 2791104c David Ahern
    if (val == 0) {
1965 ac4ffb5a aliguori
        snprintf(str, size, "*");
1966 2791104c David Ahern
    } else {
1967 2791104c David Ahern
        snprintf(str, size, "%d", val);
1968 2791104c David Ahern
    }
1969 5d0c5750 aliguori
}
1970 5d0c5750 aliguori
1971 ac4ffb5a aliguori
static void hex2str(int val, char *str, size_t size)
1972 5d0c5750 aliguori
{
1973 2791104c David Ahern
    if (val == 0) {
1974 ac4ffb5a aliguori
        snprintf(str, size, "*");
1975 2791104c David Ahern
    } else {
1976 26a9e82a Gerd Hoffmann
        snprintf(str, size, "%04x", val);
1977 2791104c David Ahern
    }
1978 5d0c5750 aliguori
}
1979 5d0c5750 aliguori
1980 376253ec aliguori
void usb_host_info(Monitor *mon)
1981 a594cfbf bellard
{
1982 5d0c5750 aliguori
    struct USBAutoFilter *f;
1983 26a9e82a Gerd Hoffmann
    struct USBHostDevice *s;
1984 5d0c5750 aliguori
1985 179da8af Blue Swirl
    usb_host_scan(mon, usb_host_info_device);
1986 5d0c5750 aliguori
1987 2791104c David Ahern
    if (QTAILQ_EMPTY(&hostdevs)) {
1988 26a9e82a Gerd Hoffmann
        return;
1989 2791104c David Ahern
    }
1990 2791104c David Ahern
1991 26a9e82a Gerd Hoffmann
    monitor_printf(mon, "  Auto filters:\n");
1992 26a9e82a Gerd Hoffmann
    QTAILQ_FOREACH(s, &hostdevs, next) {
1993 5d0c5750 aliguori
        char bus[10], addr[10], vid[10], pid[10];
1994 26a9e82a Gerd Hoffmann
        f = &s->match;
1995 ac4ffb5a aliguori
        dec2str(f->bus_num, bus, sizeof(bus));
1996 ac4ffb5a aliguori
        dec2str(f->addr, addr, sizeof(addr));
1997 ac4ffb5a aliguori
        hex2str(f->vendor_id, vid, sizeof(vid));
1998 ac4ffb5a aliguori
        hex2str(f->product_id, pid, sizeof(pid));
1999 9056a297 Gerd Hoffmann
        monitor_printf(mon, "    Bus %s, Addr %s, Port %s, ID %s:%s\n",
2000 9056a297 Gerd Hoffmann
                       bus, addr, f->port ? f->port : "*", vid, pid);
2001 5d0c5750 aliguori
    }
2002 bb36d470 bellard
}