Statistics
| Branch: | Revision:

root / usb-linux.c @ eb5e680a

History | View | Annotate | Download (50.2 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 bb36d470 bellard
38 bb36d470 bellard
#include <dirent.h>
39 bb36d470 bellard
#include <sys/ioctl.h>
40 b9dc033c balrog
#include <signal.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 bb36d470 bellard
46 d9cf1578 blueswir1
/* We redefine it to avoid version problems */
47 d9cf1578 blueswir1
struct usb_ctrltransfer {
48 d9cf1578 blueswir1
    uint8_t  bRequestType;
49 d9cf1578 blueswir1
    uint8_t  bRequest;
50 d9cf1578 blueswir1
    uint16_t wValue;
51 d9cf1578 blueswir1
    uint16_t wIndex;
52 d9cf1578 blueswir1
    uint16_t wLength;
53 d9cf1578 blueswir1
    uint32_t timeout;
54 d9cf1578 blueswir1
    void *data;
55 d9cf1578 blueswir1
};
56 d9cf1578 blueswir1
57 5557d820 Gerd Hoffmann
typedef int USBScanFunc(void *opaque, int bus_num, int addr, char *port,
58 0f5160d1 Hans de Goede
                        int class_id, int vendor_id, int product_id,
59 a594cfbf bellard
                        const char *product_name, int speed);
60 26a9e82a Gerd Hoffmann
61 0745eb1e Markus Armbruster
//#define DEBUG
62 64838171 aliguori
63 64838171 aliguori
#ifdef DEBUG
64 d0f2c4c6 malc
#define DPRINTF printf
65 64838171 aliguori
#else
66 d0f2c4c6 malc
#define DPRINTF(...)
67 64838171 aliguori
#endif
68 bb36d470 bellard
69 5be8e1f2 blueswir1
#define USBDBG_DEVOPENED "husb: opened %s/devices\n"
70 5be8e1f2 blueswir1
71 0f431527 aliguori
#define USBPROCBUS_PATH "/proc/bus/usb"
72 1f6e24e7 bellard
#define PRODUCT_NAME_SZ 32
73 3a4854b3 Hans de Goede
#define MAX_ENDPOINTS 15
74 5557d820 Gerd Hoffmann
#define MAX_PORTLEN 16
75 0f431527 aliguori
#define USBDEVBUS_PATH "/dev/bus/usb"
76 0f431527 aliguori
#define USBSYSBUS_PATH "/sys/bus/usb"
77 0f431527 aliguori
78 0f431527 aliguori
static char *usb_host_device_path;
79 0f431527 aliguori
80 0f431527 aliguori
#define USB_FS_NONE 0
81 0f431527 aliguori
#define USB_FS_PROC 1
82 0f431527 aliguori
#define USB_FS_DEV 2
83 0f431527 aliguori
#define USB_FS_SYS 3
84 0f431527 aliguori
85 0f431527 aliguori
static int usb_fs_type;
86 bb36d470 bellard
87 b9dc033c balrog
/* endpoint association data */
88 060dc841 Hans de Goede
#define ISO_FRAME_DESC_PER_URB 32
89 060dc841 Hans de Goede
#define ISO_URB_COUNT 3
90 a0b5fece Hans de Goede
#define INVALID_EP_TYPE 255
91 060dc841 Hans de Goede
92 71138531 Gerd Hoffmann
/* devio.c limits single requests to 16k */
93 71138531 Gerd Hoffmann
#define MAX_USBFS_BUFFER_SIZE 16384
94 71138531 Gerd Hoffmann
95 060dc841 Hans de Goede
typedef struct AsyncURB AsyncURB;
96 060dc841 Hans de Goede
97 b9dc033c balrog
struct endp_data {
98 b9dc033c balrog
    uint8_t type;
99 64838171 aliguori
    uint8_t halted;
100 bb6d5498 Hans de Goede
    uint8_t iso_started;
101 060dc841 Hans de Goede
    AsyncURB *iso_urb;
102 060dc841 Hans de Goede
    int iso_urb_idx;
103 bb6d5498 Hans de Goede
    int iso_buffer_used;
104 060dc841 Hans de Goede
    int max_packet_size;
105 b9dc033c balrog
};
106 b9dc033c balrog
107 26a9e82a Gerd Hoffmann
struct USBAutoFilter {
108 26a9e82a Gerd Hoffmann
    uint32_t bus_num;
109 26a9e82a Gerd Hoffmann
    uint32_t addr;
110 9056a297 Gerd Hoffmann
    char     *port;
111 26a9e82a Gerd Hoffmann
    uint32_t vendor_id;
112 26a9e82a Gerd Hoffmann
    uint32_t product_id;
113 26a9e82a Gerd Hoffmann
};
114 26a9e82a Gerd Hoffmann
115 bb36d470 bellard
typedef struct USBHostDevice {
116 bb36d470 bellard
    USBDevice dev;
117 64838171 aliguori
    int       fd;
118 64838171 aliguori
119 64838171 aliguori
    uint8_t   descr[1024];
120 64838171 aliguori
    int       descr_len;
121 64838171 aliguori
    int       configuration;
122 446ab128 aliguori
    int       ninterfaces;
123 24772c1e aliguori
    int       closing;
124 b373a63a Shahar Havivi
    Notifier  exit;
125 64838171 aliguori
126 b9dc033c balrog
    struct endp_data endp_table[MAX_ENDPOINTS];
127 7a8fc83f Gerd Hoffmann
    QLIST_HEAD(, AsyncURB) aurbs;
128 4b096fc9 aliguori
129 4b096fc9 aliguori
    /* Host side address */
130 4b096fc9 aliguori
    int bus_num;
131 4b096fc9 aliguori
    int addr;
132 5557d820 Gerd Hoffmann
    char port[MAX_PORTLEN];
133 26a9e82a Gerd Hoffmann
    struct USBAutoFilter match;
134 4b096fc9 aliguori
135 26a9e82a Gerd Hoffmann
    QTAILQ_ENTRY(USBHostDevice) next;
136 bb36d470 bellard
} USBHostDevice;
137 bb36d470 bellard
138 26a9e82a Gerd Hoffmann
static QTAILQ_HEAD(, USBHostDevice) hostdevs = QTAILQ_HEAD_INITIALIZER(hostdevs);
139 26a9e82a Gerd Hoffmann
140 26a9e82a Gerd Hoffmann
static int usb_host_close(USBHostDevice *dev);
141 26a9e82a Gerd Hoffmann
static int parse_filter(const char *spec, struct USBAutoFilter *f);
142 26a9e82a Gerd Hoffmann
static void usb_host_auto_check(void *unused);
143 2cc59d8c Hans de Goede
static int usb_host_read_file(char *line, size_t line_size,
144 2cc59d8c Hans de Goede
                            const char *device_file, const char *device_name);
145 26a9e82a Gerd Hoffmann
146 64838171 aliguori
static int is_isoc(USBHostDevice *s, int ep)
147 64838171 aliguori
{
148 64838171 aliguori
    return s->endp_table[ep - 1].type == USBDEVFS_URB_TYPE_ISO;
149 64838171 aliguori
}
150 64838171 aliguori
151 a0b5fece Hans de Goede
static int is_valid(USBHostDevice *s, int ep)
152 a0b5fece Hans de Goede
{
153 a0b5fece Hans de Goede
    return s->endp_table[ep - 1].type != INVALID_EP_TYPE;
154 a0b5fece Hans de Goede
}
155 a0b5fece Hans de Goede
156 64838171 aliguori
static int is_halted(USBHostDevice *s, int ep)
157 64838171 aliguori
{
158 64838171 aliguori
    return s->endp_table[ep - 1].halted;
159 64838171 aliguori
}
160 64838171 aliguori
161 64838171 aliguori
static void clear_halt(USBHostDevice *s, int ep)
162 64838171 aliguori
{
163 64838171 aliguori
    s->endp_table[ep - 1].halted = 0;
164 64838171 aliguori
}
165 64838171 aliguori
166 64838171 aliguori
static void set_halt(USBHostDevice *s, int ep)
167 64838171 aliguori
{
168 64838171 aliguori
    s->endp_table[ep - 1].halted = 1;
169 64838171 aliguori
}
170 64838171 aliguori
171 bb6d5498 Hans de Goede
static int is_iso_started(USBHostDevice *s, int ep)
172 bb6d5498 Hans de Goede
{
173 bb6d5498 Hans de Goede
    return s->endp_table[ep - 1].iso_started;
174 bb6d5498 Hans de Goede
}
175 bb6d5498 Hans de Goede
176 bb6d5498 Hans de Goede
static void clear_iso_started(USBHostDevice *s, int ep)
177 bb6d5498 Hans de Goede
{
178 bb6d5498 Hans de Goede
    s->endp_table[ep - 1].iso_started = 0;
179 bb6d5498 Hans de Goede
}
180 bb6d5498 Hans de Goede
181 bb6d5498 Hans de Goede
static void set_iso_started(USBHostDevice *s, int ep)
182 bb6d5498 Hans de Goede
{
183 bb6d5498 Hans de Goede
    s->endp_table[ep - 1].iso_started = 1;
184 bb6d5498 Hans de Goede
}
185 bb6d5498 Hans de Goede
186 060dc841 Hans de Goede
static void set_iso_urb(USBHostDevice *s, int ep, AsyncURB *iso_urb)
187 060dc841 Hans de Goede
{
188 060dc841 Hans de Goede
    s->endp_table[ep - 1].iso_urb = iso_urb;
189 060dc841 Hans de Goede
}
190 060dc841 Hans de Goede
191 060dc841 Hans de Goede
static AsyncURB *get_iso_urb(USBHostDevice *s, int ep)
192 060dc841 Hans de Goede
{
193 060dc841 Hans de Goede
    return s->endp_table[ep - 1].iso_urb;
194 060dc841 Hans de Goede
}
195 060dc841 Hans de Goede
196 060dc841 Hans de Goede
static void set_iso_urb_idx(USBHostDevice *s, int ep, int i)
197 060dc841 Hans de Goede
{
198 060dc841 Hans de Goede
    s->endp_table[ep - 1].iso_urb_idx = i;
199 060dc841 Hans de Goede
}
200 060dc841 Hans de Goede
201 060dc841 Hans de Goede
static int get_iso_urb_idx(USBHostDevice *s, int ep)
202 060dc841 Hans de Goede
{
203 060dc841 Hans de Goede
    return s->endp_table[ep - 1].iso_urb_idx;
204 060dc841 Hans de Goede
}
205 060dc841 Hans de Goede
206 bb6d5498 Hans de Goede
static void set_iso_buffer_used(USBHostDevice *s, int ep, int i)
207 bb6d5498 Hans de Goede
{
208 bb6d5498 Hans de Goede
    s->endp_table[ep - 1].iso_buffer_used = i;
209 bb6d5498 Hans de Goede
}
210 bb6d5498 Hans de Goede
211 bb6d5498 Hans de Goede
static int get_iso_buffer_used(USBHostDevice *s, int ep)
212 bb6d5498 Hans de Goede
{
213 bb6d5498 Hans de Goede
    return s->endp_table[ep - 1].iso_buffer_used;
214 bb6d5498 Hans de Goede
}
215 bb6d5498 Hans de Goede
216 6dfcdccb Gerd Hoffmann
static void set_max_packet_size(USBHostDevice *s, int ep, uint8_t *descriptor)
217 6dfcdccb Gerd Hoffmann
{
218 6dfcdccb Gerd Hoffmann
    int raw = descriptor[4] + (descriptor[5] << 8);
219 6dfcdccb Gerd Hoffmann
    int size, microframes;
220 6dfcdccb Gerd Hoffmann
221 6dfcdccb Gerd Hoffmann
    size = raw & 0x7ff;
222 6dfcdccb Gerd Hoffmann
    switch ((raw >> 11) & 3) {
223 6dfcdccb Gerd Hoffmann
    case 1:  microframes = 2; break;
224 6dfcdccb Gerd Hoffmann
    case 2:  microframes = 3; break;
225 6dfcdccb Gerd Hoffmann
    default: microframes = 1; break;
226 6dfcdccb Gerd Hoffmann
    }
227 6dfcdccb Gerd Hoffmann
    DPRINTF("husb: max packet size: 0x%x -> %d x %d\n",
228 6dfcdccb Gerd Hoffmann
            raw, microframes, size);
229 6dfcdccb Gerd Hoffmann
    s->endp_table[ep - 1].max_packet_size = size * microframes;
230 6dfcdccb Gerd Hoffmann
}
231 6dfcdccb Gerd Hoffmann
232 060dc841 Hans de Goede
static int get_max_packet_size(USBHostDevice *s, int ep)
233 060dc841 Hans de Goede
{
234 060dc841 Hans de Goede
    return s->endp_table[ep - 1].max_packet_size;
235 060dc841 Hans de Goede
}
236 060dc841 Hans de Goede
237 2791104c David Ahern
/*
238 64838171 aliguori
 * Async URB state.
239 060dc841 Hans de Goede
 * We always allocate iso packet descriptors even for bulk transfers
240 2791104c David Ahern
 * to simplify allocation and casts.
241 64838171 aliguori
 */
242 060dc841 Hans de Goede
struct AsyncURB
243 64838171 aliguori
{
244 64838171 aliguori
    struct usbdevfs_urb urb;
245 060dc841 Hans de Goede
    struct usbdevfs_iso_packet_desc isocpd[ISO_FRAME_DESC_PER_URB];
246 7a8fc83f Gerd Hoffmann
    USBHostDevice *hdev;
247 7a8fc83f Gerd Hoffmann
    QLIST_ENTRY(AsyncURB) next;
248 b9dc033c balrog
249 060dc841 Hans de Goede
    /* For regular async urbs */
250 64838171 aliguori
    USBPacket     *packet;
251 71138531 Gerd Hoffmann
    int more; /* large transfer, more urbs follow */
252 060dc841 Hans de Goede
253 060dc841 Hans de Goede
    /* For buffered iso handling */
254 060dc841 Hans de Goede
    int iso_frame_idx; /* -1 means in flight */
255 060dc841 Hans de Goede
};
256 b9dc033c balrog
257 7a8fc83f Gerd Hoffmann
static AsyncURB *async_alloc(USBHostDevice *s)
258 b9dc033c balrog
{
259 7a8fc83f Gerd Hoffmann
    AsyncURB *aurb = qemu_mallocz(sizeof(AsyncURB));
260 7a8fc83f Gerd Hoffmann
    aurb->hdev = s;
261 7a8fc83f Gerd Hoffmann
    QLIST_INSERT_HEAD(&s->aurbs, aurb, next);
262 7a8fc83f Gerd Hoffmann
    return aurb;
263 b9dc033c balrog
}
264 b9dc033c balrog
265 64838171 aliguori
static void async_free(AsyncURB *aurb)
266 b9dc033c balrog
{
267 7a8fc83f Gerd Hoffmann
    QLIST_REMOVE(aurb, next);
268 64838171 aliguori
    qemu_free(aurb);
269 64838171 aliguori
}
270 b9dc033c balrog
271 64838171 aliguori
static void async_complete(void *opaque)
272 64838171 aliguori
{
273 64838171 aliguori
    USBHostDevice *s = opaque;
274 64838171 aliguori
    AsyncURB *aurb;
275 64838171 aliguori
276 64838171 aliguori
    while (1) {
277 2791104c David Ahern
        USBPacket *p;
278 b9dc033c balrog
279 2791104c David Ahern
        int r = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &aurb);
280 64838171 aliguori
        if (r < 0) {
281 2791104c David Ahern
            if (errno == EAGAIN) {
282 64838171 aliguori
                return;
283 2791104c David Ahern
            }
284 24772c1e aliguori
            if (errno == ENODEV && !s->closing) {
285 2791104c David Ahern
                printf("husb: device %d.%d disconnected\n",
286 2791104c David Ahern
                       s->bus_num, s->addr);
287 26a9e82a Gerd Hoffmann
                usb_host_close(s);
288 26a9e82a Gerd Hoffmann
                usb_host_auto_check(NULL);
289 64838171 aliguori
                return;
290 64838171 aliguori
            }
291 64838171 aliguori
292 d0f2c4c6 malc
            DPRINTF("husb: async. reap urb failed errno %d\n", errno);
293 64838171 aliguori
            return;
294 b9dc033c balrog
        }
295 64838171 aliguori
296 2791104c David Ahern
        DPRINTF("husb: async completed. aurb %p status %d alen %d\n",
297 64838171 aliguori
                aurb, aurb->urb.status, aurb->urb.actual_length);
298 64838171 aliguori
299 060dc841 Hans de Goede
        /* If this is a buffered iso urb mark it as complete and don't do
300 060dc841 Hans de Goede
           anything else (it is handled further in usb_host_handle_iso_data) */
301 060dc841 Hans de Goede
        if (aurb->iso_frame_idx == -1) {
302 060dc841 Hans de Goede
            if (aurb->urb.status == -EPIPE) {
303 060dc841 Hans de Goede
                set_halt(s, aurb->urb.endpoint & 0xf);
304 060dc841 Hans de Goede
            }
305 060dc841 Hans de Goede
            aurb->iso_frame_idx = 0;
306 060dc841 Hans de Goede
            continue;
307 060dc841 Hans de Goede
        }
308 060dc841 Hans de Goede
309 060dc841 Hans de Goede
        p = aurb->packet;
310 060dc841 Hans de Goede
311 2791104c David Ahern
        if (p) {
312 64838171 aliguori
            switch (aurb->urb.status) {
313 64838171 aliguori
            case 0:
314 71138531 Gerd Hoffmann
                p->len += aurb->urb.actual_length;
315 64838171 aliguori
                break;
316 64838171 aliguori
317 64838171 aliguori
            case -EPIPE:
318 64838171 aliguori
                set_halt(s, p->devep);
319 2791104c David Ahern
                p->len = USB_RET_STALL;
320 2791104c David Ahern
                break;
321 dcc7e25f Paul Bolle
322 64838171 aliguori
            default:
323 64838171 aliguori
                p->len = USB_RET_NAK;
324 64838171 aliguori
                break;
325 64838171 aliguori
            }
326 64838171 aliguori
327 50b7963e Hans de Goede
            if (aurb->urb.type == USBDEVFS_URB_TYPE_CONTROL) {
328 50b7963e Hans de Goede
                usb_generic_async_ctrl_complete(&s->dev, p);
329 71138531 Gerd Hoffmann
            } else if (!aurb->more) {
330 50b7963e Hans de Goede
                usb_packet_complete(&s->dev, p);
331 50b7963e Hans de Goede
            }
332 2791104c David Ahern
        }
333 64838171 aliguori
334 64838171 aliguori
        async_free(aurb);
335 b9dc033c balrog
    }
336 b9dc033c balrog
}
337 b9dc033c balrog
338 eb5e680a Gerd Hoffmann
static void usb_host_async_cancel(USBDevice *dev, USBPacket *p)
339 b9dc033c balrog
{
340 eb5e680a Gerd Hoffmann
    USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
341 227ebeb5 Gerd Hoffmann
    AsyncURB *aurb;
342 b9dc033c balrog
343 227ebeb5 Gerd Hoffmann
    QLIST_FOREACH(aurb, &s->aurbs, next) {
344 227ebeb5 Gerd Hoffmann
        if (p != aurb->packet) {
345 227ebeb5 Gerd Hoffmann
            continue;
346 227ebeb5 Gerd Hoffmann
        }
347 64838171 aliguori
348 227ebeb5 Gerd Hoffmann
        DPRINTF("husb: async cancel: packet %p, aurb %p\n", p, aurb);
349 b9dc033c balrog
350 227ebeb5 Gerd Hoffmann
        /* Mark it as dead (see async_complete above) */
351 227ebeb5 Gerd Hoffmann
        aurb->packet = NULL;
352 227ebeb5 Gerd Hoffmann
353 227ebeb5 Gerd Hoffmann
        int r = ioctl(s->fd, USBDEVFS_DISCARDURB, aurb);
354 227ebeb5 Gerd Hoffmann
        if (r < 0) {
355 227ebeb5 Gerd Hoffmann
            DPRINTF("husb: async. discard urb failed errno %d\n", errno);
356 227ebeb5 Gerd Hoffmann
        }
357 b9dc033c balrog
    }
358 b9dc033c balrog
}
359 b9dc033c balrog
360 446ab128 aliguori
static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
361 b9dc033c balrog
{
362 b9dc033c balrog
    int dev_descr_len, config_descr_len;
363 d4c4e6fd Blue Swirl
    int interface, nb_interfaces;
364 b9dc033c balrog
    int ret, i;
365 b9dc033c balrog
366 b9dc033c balrog
    if (configuration == 0) /* address state - ignore */
367 b9dc033c balrog
        return 1;
368 b9dc033c balrog
369 d0f2c4c6 malc
    DPRINTF("husb: claiming interfaces. config %d\n", configuration);
370 446ab128 aliguori
371 b9dc033c balrog
    i = 0;
372 b9dc033c balrog
    dev_descr_len = dev->descr[0];
373 2791104c David Ahern
    if (dev_descr_len > dev->descr_len) {
374 b9dc033c balrog
        goto fail;
375 2791104c David Ahern
    }
376 b9dc033c balrog
377 b9dc033c balrog
    i += dev_descr_len;
378 b9dc033c balrog
    while (i < dev->descr_len) {
379 2791104c David Ahern
        DPRINTF("husb: i is %d, descr_len is %d, dl %d, dt %d\n",
380 2791104c David Ahern
                i, dev->descr_len,
381 b9dc033c balrog
               dev->descr[i], dev->descr[i+1]);
382 64838171 aliguori
383 b9dc033c balrog
        if (dev->descr[i+1] != USB_DT_CONFIG) {
384 b9dc033c balrog
            i += dev->descr[i];
385 b9dc033c balrog
            continue;
386 b9dc033c balrog
        }
387 b9dc033c balrog
        config_descr_len = dev->descr[i];
388 b9dc033c balrog
389 2791104c David Ahern
        printf("husb: config #%d need %d\n", dev->descr[i + 5], configuration);
390 1f3870ab aliguori
391 446ab128 aliguori
        if (configuration < 0 || configuration == dev->descr[i + 5]) {
392 446ab128 aliguori
            configuration = dev->descr[i + 5];
393 b9dc033c balrog
            break;
394 446ab128 aliguori
        }
395 b9dc033c balrog
396 b9dc033c balrog
        i += config_descr_len;
397 b9dc033c balrog
    }
398 b9dc033c balrog
399 b9dc033c balrog
    if (i >= dev->descr_len) {
400 2791104c David Ahern
        fprintf(stderr,
401 2791104c David Ahern
                "husb: update iface failed. no matching configuration\n");
402 b9dc033c balrog
        goto fail;
403 b9dc033c balrog
    }
404 b9dc033c balrog
    nb_interfaces = dev->descr[i + 4];
405 b9dc033c balrog
406 b9dc033c balrog
#ifdef USBDEVFS_DISCONNECT
407 b9dc033c balrog
    /* earlier Linux 2.4 do not support that */
408 b9dc033c balrog
    {
409 b9dc033c balrog
        struct usbdevfs_ioctl ctrl;
410 b9dc033c balrog
        for (interface = 0; interface < nb_interfaces; interface++) {
411 b9dc033c balrog
            ctrl.ioctl_code = USBDEVFS_DISCONNECT;
412 b9dc033c balrog
            ctrl.ifno = interface;
413 021730f7 Brad Hards
            ctrl.data = 0;
414 b9dc033c balrog
            ret = ioctl(dev->fd, USBDEVFS_IOCTL, &ctrl);
415 b9dc033c balrog
            if (ret < 0 && errno != ENODATA) {
416 b9dc033c balrog
                perror("USBDEVFS_DISCONNECT");
417 b9dc033c balrog
                goto fail;
418 b9dc033c balrog
            }
419 b9dc033c balrog
        }
420 b9dc033c balrog
    }
421 b9dc033c balrog
#endif
422 b9dc033c balrog
423 b9dc033c balrog
    /* XXX: only grab if all interfaces are free */
424 b9dc033c balrog
    for (interface = 0; interface < nb_interfaces; interface++) {
425 b9dc033c balrog
        ret = ioctl(dev->fd, USBDEVFS_CLAIMINTERFACE, &interface);
426 b9dc033c balrog
        if (ret < 0) {
427 b9dc033c balrog
            if (errno == EBUSY) {
428 64838171 aliguori
                printf("husb: update iface. device already grabbed\n");
429 b9dc033c balrog
            } else {
430 64838171 aliguori
                perror("husb: failed to claim interface");
431 b9dc033c balrog
            }
432 b9dc033c balrog
        fail:
433 b9dc033c balrog
            return 0;
434 b9dc033c balrog
        }
435 b9dc033c balrog
    }
436 b9dc033c balrog
437 64838171 aliguori
    printf("husb: %d interfaces claimed for configuration %d\n",
438 b9dc033c balrog
           nb_interfaces, configuration);
439 b9dc033c balrog
440 446ab128 aliguori
    dev->ninterfaces   = nb_interfaces;
441 446ab128 aliguori
    dev->configuration = configuration;
442 446ab128 aliguori
    return 1;
443 446ab128 aliguori
}
444 446ab128 aliguori
445 446ab128 aliguori
static int usb_host_release_interfaces(USBHostDevice *s)
446 446ab128 aliguori
{
447 446ab128 aliguori
    int ret, i;
448 446ab128 aliguori
449 d0f2c4c6 malc
    DPRINTF("husb: releasing interfaces\n");
450 446ab128 aliguori
451 446ab128 aliguori
    for (i = 0; i < s->ninterfaces; i++) {
452 446ab128 aliguori
        ret = ioctl(s->fd, USBDEVFS_RELEASEINTERFACE, &i);
453 446ab128 aliguori
        if (ret < 0) {
454 446ab128 aliguori
            perror("husb: failed to release interface");
455 446ab128 aliguori
            return 0;
456 446ab128 aliguori
        }
457 446ab128 aliguori
    }
458 446ab128 aliguori
459 b9dc033c balrog
    return 1;
460 b9dc033c balrog
}
461 b9dc033c balrog
462 059809e4 bellard
static void usb_host_handle_reset(USBDevice *dev)
463 bb36d470 bellard
{
464 26a9e82a Gerd Hoffmann
    USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
465 64838171 aliguori
466 d0f2c4c6 malc
    DPRINTF("husb: reset device %u.%u\n", s->bus_num, s->addr);
467 64838171 aliguori
468 bb36d470 bellard
    ioctl(s->fd, USBDEVFS_RESET);
469 446ab128 aliguori
470 446ab128 aliguori
    usb_host_claim_interfaces(s, s->configuration);
471 5fafdf24 ths
}
472 bb36d470 bellard
473 059809e4 bellard
static void usb_host_handle_destroy(USBDevice *dev)
474 059809e4 bellard
{
475 059809e4 bellard
    USBHostDevice *s = (USBHostDevice *)dev;
476 059809e4 bellard
477 26a9e82a Gerd Hoffmann
    usb_host_close(s);
478 26a9e82a Gerd Hoffmann
    QTAILQ_REMOVE(&hostdevs, s, next);
479 b373a63a Shahar Havivi
    qemu_remove_exit_notifier(&s->exit);
480 059809e4 bellard
}
481 059809e4 bellard
482 b9dc033c balrog
static int usb_linux_update_endp_table(USBHostDevice *s);
483 b9dc033c balrog
484 060dc841 Hans de Goede
/* iso data is special, we need to keep enough urbs in flight to make sure
485 060dc841 Hans de Goede
   that the controller never runs out of them, otherwise the device will
486 060dc841 Hans de Goede
   likely suffer a buffer underrun / overrun. */
487 060dc841 Hans de Goede
static AsyncURB *usb_host_alloc_iso(USBHostDevice *s, uint8_t ep, int in)
488 060dc841 Hans de Goede
{
489 060dc841 Hans de Goede
    AsyncURB *aurb;
490 060dc841 Hans de Goede
    int i, j, len = get_max_packet_size(s, ep);
491 060dc841 Hans de Goede
492 060dc841 Hans de Goede
    aurb = qemu_mallocz(ISO_URB_COUNT * sizeof(*aurb));
493 060dc841 Hans de Goede
    for (i = 0; i < ISO_URB_COUNT; i++) {
494 060dc841 Hans de Goede
        aurb[i].urb.endpoint      = ep;
495 060dc841 Hans de Goede
        aurb[i].urb.buffer_length = ISO_FRAME_DESC_PER_URB * len;
496 060dc841 Hans de Goede
        aurb[i].urb.buffer        = qemu_malloc(aurb[i].urb.buffer_length);
497 060dc841 Hans de Goede
        aurb[i].urb.type          = USBDEVFS_URB_TYPE_ISO;
498 060dc841 Hans de Goede
        aurb[i].urb.flags         = USBDEVFS_URB_ISO_ASAP;
499 060dc841 Hans de Goede
        aurb[i].urb.number_of_packets = ISO_FRAME_DESC_PER_URB;
500 060dc841 Hans de Goede
        for (j = 0 ; j < ISO_FRAME_DESC_PER_URB; j++)
501 060dc841 Hans de Goede
            aurb[i].urb.iso_frame_desc[j].length = len;
502 060dc841 Hans de Goede
        if (in) {
503 060dc841 Hans de Goede
            aurb[i].urb.endpoint |= 0x80;
504 060dc841 Hans de Goede
            /* Mark as fully consumed (idle) */
505 060dc841 Hans de Goede
            aurb[i].iso_frame_idx = ISO_FRAME_DESC_PER_URB;
506 060dc841 Hans de Goede
        }
507 060dc841 Hans de Goede
    }
508 060dc841 Hans de Goede
    set_iso_urb(s, ep, aurb);
509 060dc841 Hans de Goede
510 060dc841 Hans de Goede
    return aurb;
511 060dc841 Hans de Goede
}
512 060dc841 Hans de Goede
513 060dc841 Hans de Goede
static void usb_host_stop_n_free_iso(USBHostDevice *s, uint8_t ep)
514 060dc841 Hans de Goede
{
515 060dc841 Hans de Goede
    AsyncURB *aurb;
516 060dc841 Hans de Goede
    int i, ret, killed = 0, free = 1;
517 060dc841 Hans de Goede
518 060dc841 Hans de Goede
    aurb = get_iso_urb(s, ep);
519 060dc841 Hans de Goede
    if (!aurb) {
520 060dc841 Hans de Goede
        return;
521 060dc841 Hans de Goede
    }
522 060dc841 Hans de Goede
523 060dc841 Hans de Goede
    for (i = 0; i < ISO_URB_COUNT; i++) {
524 060dc841 Hans de Goede
        /* in flight? */
525 060dc841 Hans de Goede
        if (aurb[i].iso_frame_idx == -1) {
526 060dc841 Hans de Goede
            ret = ioctl(s->fd, USBDEVFS_DISCARDURB, &aurb[i]);
527 060dc841 Hans de Goede
            if (ret < 0) {
528 060dc841 Hans de Goede
                printf("husb: discard isoc in urb failed errno %d\n", errno);
529 060dc841 Hans de Goede
                free = 0;
530 060dc841 Hans de Goede
                continue;
531 060dc841 Hans de Goede
            }
532 060dc841 Hans de Goede
            killed++;
533 060dc841 Hans de Goede
        }
534 060dc841 Hans de Goede
    }
535 060dc841 Hans de Goede
536 060dc841 Hans de Goede
    /* Make sure any urbs we've killed are reaped before we free them */
537 060dc841 Hans de Goede
    if (killed) {
538 060dc841 Hans de Goede
        async_complete(s);
539 060dc841 Hans de Goede
    }
540 060dc841 Hans de Goede
541 060dc841 Hans de Goede
    for (i = 0; i < ISO_URB_COUNT; i++) {
542 060dc841 Hans de Goede
        qemu_free(aurb[i].urb.buffer);
543 060dc841 Hans de Goede
    }
544 060dc841 Hans de Goede
545 060dc841 Hans de Goede
    if (free)
546 060dc841 Hans de Goede
        qemu_free(aurb);
547 060dc841 Hans de Goede
    else
548 060dc841 Hans de Goede
        printf("husb: leaking iso urbs because of discard failure\n");
549 060dc841 Hans de Goede
    set_iso_urb(s, ep, NULL);
550 bb6d5498 Hans de Goede
    set_iso_urb_idx(s, ep, 0);
551 bb6d5498 Hans de Goede
    clear_iso_started(s, ep);
552 060dc841 Hans de Goede
}
553 060dc841 Hans de Goede
554 060dc841 Hans de Goede
static int urb_status_to_usb_ret(int status)
555 060dc841 Hans de Goede
{
556 060dc841 Hans de Goede
    switch (status) {
557 060dc841 Hans de Goede
    case -EPIPE:
558 060dc841 Hans de Goede
        return USB_RET_STALL;
559 060dc841 Hans de Goede
    default:
560 060dc841 Hans de Goede
        return USB_RET_NAK;
561 060dc841 Hans de Goede
    }
562 060dc841 Hans de Goede
}
563 060dc841 Hans de Goede
564 bb6d5498 Hans de Goede
static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in)
565 060dc841 Hans de Goede
{
566 060dc841 Hans de Goede
    AsyncURB *aurb;
567 bb6d5498 Hans de Goede
    int i, j, ret, max_packet_size, offset, len = 0;
568 975f2998 Hans de Goede
569 975f2998 Hans de Goede
    max_packet_size = get_max_packet_size(s, p->devep);
570 975f2998 Hans de Goede
    if (max_packet_size == 0)
571 975f2998 Hans de Goede
        return USB_RET_NAK;
572 060dc841 Hans de Goede
573 060dc841 Hans de Goede
    aurb = get_iso_urb(s, p->devep);
574 060dc841 Hans de Goede
    if (!aurb) {
575 bb6d5498 Hans de Goede
        aurb = usb_host_alloc_iso(s, p->devep, in);
576 060dc841 Hans de Goede
    }
577 060dc841 Hans de Goede
578 060dc841 Hans de Goede
    i = get_iso_urb_idx(s, p->devep);
579 060dc841 Hans de Goede
    j = aurb[i].iso_frame_idx;
580 060dc841 Hans de Goede
    if (j >= 0 && j < ISO_FRAME_DESC_PER_URB) {
581 bb6d5498 Hans de Goede
        if (in) {
582 bb6d5498 Hans de Goede
            /* Check urb status  */
583 bb6d5498 Hans de Goede
            if (aurb[i].urb.status) {
584 bb6d5498 Hans de Goede
                len = urb_status_to_usb_ret(aurb[i].urb.status);
585 bb6d5498 Hans de Goede
                /* Move to the next urb */
586 bb6d5498 Hans de Goede
                aurb[i].iso_frame_idx = ISO_FRAME_DESC_PER_URB - 1;
587 bb6d5498 Hans de Goede
            /* Check frame status */
588 bb6d5498 Hans de Goede
            } else if (aurb[i].urb.iso_frame_desc[j].status) {
589 bb6d5498 Hans de Goede
                len = urb_status_to_usb_ret(
590 bb6d5498 Hans de Goede
                                        aurb[i].urb.iso_frame_desc[j].status);
591 bb6d5498 Hans de Goede
            /* Check the frame fits */
592 bb6d5498 Hans de Goede
            } else if (aurb[i].urb.iso_frame_desc[j].actual_length > p->len) {
593 bb6d5498 Hans de Goede
                printf("husb: received iso data is larger then packet\n");
594 bb6d5498 Hans de Goede
                len = USB_RET_NAK;
595 bb6d5498 Hans de Goede
            /* All good copy data over */
596 bb6d5498 Hans de Goede
            } else {
597 bb6d5498 Hans de Goede
                len = aurb[i].urb.iso_frame_desc[j].actual_length;
598 bb6d5498 Hans de Goede
                memcpy(p->data,
599 bb6d5498 Hans de Goede
                       aurb[i].urb.buffer +
600 bb6d5498 Hans de Goede
                           j * aurb[i].urb.iso_frame_desc[0].length,
601 bb6d5498 Hans de Goede
                       len);
602 bb6d5498 Hans de Goede
            }
603 060dc841 Hans de Goede
        } else {
604 bb6d5498 Hans de Goede
            len = p->len;
605 bb6d5498 Hans de Goede
            offset = (j == 0) ? 0 : get_iso_buffer_used(s, p->devep);
606 bb6d5498 Hans de Goede
607 bb6d5498 Hans de Goede
            /* Check the frame fits */
608 bb6d5498 Hans de Goede
            if (len > max_packet_size) {
609 bb6d5498 Hans de Goede
                printf("husb: send iso data is larger then max packet size\n");
610 bb6d5498 Hans de Goede
                return USB_RET_NAK;
611 bb6d5498 Hans de Goede
            }
612 bb6d5498 Hans de Goede
613 bb6d5498 Hans de Goede
            /* All good copy data over */
614 bb6d5498 Hans de Goede
            memcpy(aurb[i].urb.buffer + offset, p->data, len);
615 bb6d5498 Hans de Goede
            aurb[i].urb.iso_frame_desc[j].length = len;
616 bb6d5498 Hans de Goede
            offset += len;
617 bb6d5498 Hans de Goede
            set_iso_buffer_used(s, p->devep, offset);
618 bb6d5498 Hans de Goede
619 bb6d5498 Hans de Goede
            /* Start the stream once we have buffered enough data */
620 bb6d5498 Hans de Goede
            if (!is_iso_started(s, p->devep) && i == 1 && j == 8) {
621 bb6d5498 Hans de Goede
                set_iso_started(s, p->devep);
622 bb6d5498 Hans de Goede
            }
623 060dc841 Hans de Goede
        }
624 060dc841 Hans de Goede
        aurb[i].iso_frame_idx++;
625 060dc841 Hans de Goede
        if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {
626 060dc841 Hans de Goede
            i = (i + 1) % ISO_URB_COUNT;
627 060dc841 Hans de Goede
            set_iso_urb_idx(s, p->devep, i);
628 060dc841 Hans de Goede
        }
629 bb6d5498 Hans de Goede
    } else {
630 bb6d5498 Hans de Goede
        if (in) {
631 bb6d5498 Hans de Goede
            set_iso_started(s, p->devep);
632 bb6d5498 Hans de Goede
        } else {
633 bb6d5498 Hans de Goede
            DPRINTF("hubs: iso out error no free buffer, dropping packet\n");
634 bb6d5498 Hans de Goede
        }
635 060dc841 Hans de Goede
    }
636 060dc841 Hans de Goede
637 bb6d5498 Hans de Goede
    if (is_iso_started(s, p->devep)) {
638 bb6d5498 Hans de Goede
        /* (Re)-submit all fully consumed / filled urbs */
639 bb6d5498 Hans de Goede
        for (i = 0; i < ISO_URB_COUNT; i++) {
640 bb6d5498 Hans de Goede
            if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {
641 bb6d5498 Hans de Goede
                ret = ioctl(s->fd, USBDEVFS_SUBMITURB, &aurb[i]);
642 bb6d5498 Hans de Goede
                if (ret < 0) {
643 bb6d5498 Hans de Goede
                    printf("husb error submitting iso urb %d: %d\n", i, errno);
644 bb6d5498 Hans de Goede
                    if (!in || len == 0) {
645 bb6d5498 Hans de Goede
                        switch(errno) {
646 bb6d5498 Hans de Goede
                        case ETIMEDOUT:
647 bb6d5498 Hans de Goede
                            len = USB_RET_NAK;
648 0225e254 Stefan Weil
                            break;
649 bb6d5498 Hans de Goede
                        case EPIPE:
650 bb6d5498 Hans de Goede
                        default:
651 bb6d5498 Hans de Goede
                            len = USB_RET_STALL;
652 bb6d5498 Hans de Goede
                        }
653 060dc841 Hans de Goede
                    }
654 bb6d5498 Hans de Goede
                    break;
655 060dc841 Hans de Goede
                }
656 bb6d5498 Hans de Goede
                aurb[i].iso_frame_idx = -1;
657 060dc841 Hans de Goede
            }
658 060dc841 Hans de Goede
        }
659 060dc841 Hans de Goede
    }
660 060dc841 Hans de Goede
661 060dc841 Hans de Goede
    return len;
662 060dc841 Hans de Goede
}
663 060dc841 Hans de Goede
664 50b7963e Hans de Goede
static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
665 bb36d470 bellard
{
666 50b7963e Hans de Goede
    USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
667 64838171 aliguori
    struct usbdevfs_urb *urb;
668 446ab128 aliguori
    AsyncURB *aurb;
669 71138531 Gerd Hoffmann
    int ret, rem;
670 71138531 Gerd Hoffmann
    uint8_t *pbuf;
671 060dc841 Hans de Goede
    uint8_t ep;
672 b9dc033c balrog
673 a0b5fece Hans de Goede
    if (!is_valid(s, p->devep)) {
674 a0b5fece Hans de Goede
        return USB_RET_NAK;
675 a0b5fece Hans de Goede
    }
676 a0b5fece Hans de Goede
677 2791104c David Ahern
    if (p->pid == USB_TOKEN_IN) {
678 060dc841 Hans de Goede
        ep = p->devep | 0x80;
679 2791104c David Ahern
    } else {
680 060dc841 Hans de Goede
        ep = p->devep;
681 2791104c David Ahern
    }
682 64838171 aliguori
683 64838171 aliguori
    if (is_halted(s, p->devep)) {
684 060dc841 Hans de Goede
        ret = ioctl(s->fd, USBDEVFS_CLEAR_HALT, &ep);
685 64838171 aliguori
        if (ret < 0) {
686 2791104c David Ahern
            DPRINTF("husb: failed to clear halt. ep 0x%x errno %d\n",
687 060dc841 Hans de Goede
                   ep, errno);
688 bb36d470 bellard
            return USB_RET_NAK;
689 bb36d470 bellard
        }
690 64838171 aliguori
        clear_halt(s, p->devep);
691 4d043a09 balrog
    }
692 4d043a09 balrog
693 bb6d5498 Hans de Goede
    if (is_isoc(s, p->devep)) {
694 bb6d5498 Hans de Goede
        return usb_host_handle_iso_data(s, p, p->pid == USB_TOKEN_IN);
695 bb6d5498 Hans de Goede
    }
696 060dc841 Hans de Goede
697 71138531 Gerd Hoffmann
    rem = p->len;
698 71138531 Gerd Hoffmann
    pbuf = p->data;
699 71138531 Gerd Hoffmann
    p->len = 0;
700 71138531 Gerd Hoffmann
    while (rem) {
701 71138531 Gerd Hoffmann
        aurb = async_alloc(s);
702 71138531 Gerd Hoffmann
        aurb->packet = p;
703 71138531 Gerd Hoffmann
704 71138531 Gerd Hoffmann
        urb = &aurb->urb;
705 71138531 Gerd Hoffmann
        urb->endpoint      = ep;
706 71138531 Gerd Hoffmann
        urb->type          = USBDEVFS_URB_TYPE_BULK;
707 71138531 Gerd Hoffmann
        urb->usercontext   = s;
708 71138531 Gerd Hoffmann
        urb->buffer        = pbuf;
709 71138531 Gerd Hoffmann
710 71138531 Gerd Hoffmann
        if (rem > MAX_USBFS_BUFFER_SIZE) {
711 71138531 Gerd Hoffmann
            urb->buffer_length = MAX_USBFS_BUFFER_SIZE;
712 71138531 Gerd Hoffmann
            aurb->more         = 1;
713 71138531 Gerd Hoffmann
        } else {
714 71138531 Gerd Hoffmann
            urb->buffer_length = rem;
715 71138531 Gerd Hoffmann
            aurb->more         = 0;
716 71138531 Gerd Hoffmann
        }
717 71138531 Gerd Hoffmann
        pbuf += urb->buffer_length;
718 71138531 Gerd Hoffmann
        rem  -= urb->buffer_length;
719 b9dc033c balrog
720 71138531 Gerd Hoffmann
        ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
721 b9dc033c balrog
722 71138531 Gerd Hoffmann
        DPRINTF("husb: data submit: ep 0x%x, len %u, more %d, packet %p, aurb %p\n",
723 71138531 Gerd Hoffmann
                urb->endpoint, urb->buffer_length, aurb->more, p, aurb);
724 b9dc033c balrog
725 71138531 Gerd Hoffmann
        if (ret < 0) {
726 71138531 Gerd Hoffmann
            DPRINTF("husb: submit failed. errno %d\n", errno);
727 71138531 Gerd Hoffmann
            async_free(aurb);
728 b9dc033c balrog
729 71138531 Gerd Hoffmann
            switch(errno) {
730 71138531 Gerd Hoffmann
            case ETIMEDOUT:
731 71138531 Gerd Hoffmann
                return USB_RET_NAK;
732 71138531 Gerd Hoffmann
            case EPIPE:
733 71138531 Gerd Hoffmann
            default:
734 71138531 Gerd Hoffmann
                return USB_RET_STALL;
735 71138531 Gerd Hoffmann
            }
736 b9dc033c balrog
        }
737 b9dc033c balrog
    }
738 64838171 aliguori
739 b9dc033c balrog
    return USB_RET_ASYNC;
740 b9dc033c balrog
}
741 b9dc033c balrog
742 446ab128 aliguori
static int ctrl_error(void)
743 446ab128 aliguori
{
744 2791104c David Ahern
    if (errno == ETIMEDOUT) {
745 446ab128 aliguori
        return USB_RET_NAK;
746 2791104c David Ahern
    } else {
747 446ab128 aliguori
        return USB_RET_STALL;
748 2791104c David Ahern
    }
749 446ab128 aliguori
}
750 446ab128 aliguori
751 446ab128 aliguori
static int usb_host_set_address(USBHostDevice *s, int addr)
752 446ab128 aliguori
{
753 d0f2c4c6 malc
    DPRINTF("husb: ctrl set addr %u\n", addr);
754 446ab128 aliguori
    s->dev.addr = addr;
755 446ab128 aliguori
    return 0;
756 446ab128 aliguori
}
757 446ab128 aliguori
758 446ab128 aliguori
static int usb_host_set_config(USBHostDevice *s, int config)
759 446ab128 aliguori
{
760 446ab128 aliguori
    usb_host_release_interfaces(s);
761 446ab128 aliguori
762 446ab128 aliguori
    int ret = ioctl(s->fd, USBDEVFS_SETCONFIGURATION, &config);
763 2791104c David Ahern
764 d0f2c4c6 malc
    DPRINTF("husb: ctrl set config %d ret %d errno %d\n", config, ret, errno);
765 2791104c David Ahern
766 2791104c David Ahern
    if (ret < 0) {
767 446ab128 aliguori
        return ctrl_error();
768 2791104c David Ahern
    }
769 446ab128 aliguori
    usb_host_claim_interfaces(s, config);
770 446ab128 aliguori
    return 0;
771 446ab128 aliguori
}
772 446ab128 aliguori
773 446ab128 aliguori
static int usb_host_set_interface(USBHostDevice *s, int iface, int alt)
774 446ab128 aliguori
{
775 446ab128 aliguori
    struct usbdevfs_setinterface si;
776 060dc841 Hans de Goede
    int i, ret;
777 060dc841 Hans de Goede
778 3a4854b3 Hans de Goede
    for (i = 1; i <= MAX_ENDPOINTS; i++) {
779 060dc841 Hans de Goede
        if (is_isoc(s, i)) {
780 060dc841 Hans de Goede
            usb_host_stop_n_free_iso(s, i);
781 060dc841 Hans de Goede
        }
782 060dc841 Hans de Goede
    }
783 446ab128 aliguori
784 446ab128 aliguori
    si.interface  = iface;
785 446ab128 aliguori
    si.altsetting = alt;
786 446ab128 aliguori
    ret = ioctl(s->fd, USBDEVFS_SETINTERFACE, &si);
787 446ab128 aliguori
788 2791104c David Ahern
    DPRINTF("husb: ctrl set iface %d altset %d ret %d errno %d\n",
789 2791104c David Ahern
            iface, alt, ret, errno);
790 2791104c David Ahern
791 2791104c David Ahern
    if (ret < 0) {
792 2791104c David Ahern
        return ctrl_error();
793 2791104c David Ahern
    }
794 446ab128 aliguori
    usb_linux_update_endp_table(s);
795 446ab128 aliguori
    return 0;
796 446ab128 aliguori
}
797 446ab128 aliguori
798 50b7963e Hans de Goede
static int usb_host_handle_control(USBDevice *dev, USBPacket *p,
799 50b7963e Hans de Goede
               int request, int value, int index, int length, uint8_t *data)
800 446ab128 aliguori
{
801 50b7963e Hans de Goede
    USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
802 446ab128 aliguori
    struct usbdevfs_urb *urb;
803 446ab128 aliguori
    AsyncURB *aurb;
804 50b7963e Hans de Goede
    int ret;
805 446ab128 aliguori
806 2791104c David Ahern
    /*
807 446ab128 aliguori
     * Process certain standard device requests.
808 446ab128 aliguori
     * These are infrequent and are processed synchronously.
809 446ab128 aliguori
     */
810 446ab128 aliguori
811 50b7963e Hans de Goede
    /* Note request is (bRequestType << 8) | bRequest */
812 d0f2c4c6 malc
    DPRINTF("husb: ctrl type 0x%x req 0x%x val 0x%x index %u len %u\n",
813 50b7963e Hans de Goede
            request >> 8, request & 0xff, value, index, length);
814 446ab128 aliguori
815 50b7963e Hans de Goede
    switch (request) {
816 50b7963e Hans de Goede
    case DeviceOutRequest | USB_REQ_SET_ADDRESS:
817 50b7963e Hans de Goede
        return usb_host_set_address(s, value);
818 446ab128 aliguori
819 50b7963e Hans de Goede
    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
820 50b7963e Hans de Goede
        return usb_host_set_config(s, value & 0xff);
821 446ab128 aliguori
822 50b7963e Hans de Goede
    case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
823 446ab128 aliguori
        return usb_host_set_interface(s, index, value);
824 2791104c David Ahern
    }
825 446ab128 aliguori
826 446ab128 aliguori
    /* The rest are asynchronous */
827 446ab128 aliguori
828 50b7963e Hans de Goede
    if (length > sizeof(dev->data_buf)) {
829 50b7963e Hans de Goede
        fprintf(stderr, "husb: ctrl buffer too small (%d > %zu)\n",
830 50b7963e Hans de Goede
                length, sizeof(dev->data_buf));
831 b2e3b6e9 malc
        return USB_RET_STALL;
832 c4c0e236 Jim Paris
    }
833 c4c0e236 Jim Paris
834 7a8fc83f Gerd Hoffmann
    aurb = async_alloc(s);
835 446ab128 aliguori
    aurb->packet = p;
836 446ab128 aliguori
837 2791104c David Ahern
    /*
838 446ab128 aliguori
     * Setup ctrl transfer.
839 446ab128 aliguori
     *
840 a0102082 Brad Hards
     * s->ctrl is laid out such that data buffer immediately follows
841 446ab128 aliguori
     * 'req' struct which is exactly what usbdevfs expects.
842 2791104c David Ahern
     */
843 446ab128 aliguori
    urb = &aurb->urb;
844 446ab128 aliguori
845 446ab128 aliguori
    urb->type     = USBDEVFS_URB_TYPE_CONTROL;
846 446ab128 aliguori
    urb->endpoint = p->devep;
847 446ab128 aliguori
848 50b7963e Hans de Goede
    urb->buffer        = &dev->setup_buf;
849 50b7963e Hans de Goede
    urb->buffer_length = length + 8;
850 446ab128 aliguori
851 446ab128 aliguori
    urb->usercontext = s;
852 446ab128 aliguori
853 446ab128 aliguori
    ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
854 446ab128 aliguori
855 d0f2c4c6 malc
    DPRINTF("husb: submit ctrl. len %u aurb %p\n", urb->buffer_length, aurb);
856 446ab128 aliguori
857 446ab128 aliguori
    if (ret < 0) {
858 d0f2c4c6 malc
        DPRINTF("husb: submit failed. errno %d\n", errno);
859 446ab128 aliguori
        async_free(aurb);
860 446ab128 aliguori
861 446ab128 aliguori
        switch(errno) {
862 446ab128 aliguori
        case ETIMEDOUT:
863 446ab128 aliguori
            return USB_RET_NAK;
864 446ab128 aliguori
        case EPIPE:
865 446ab128 aliguori
        default:
866 446ab128 aliguori
            return USB_RET_STALL;
867 446ab128 aliguori
        }
868 446ab128 aliguori
    }
869 446ab128 aliguori
870 446ab128 aliguori
    return USB_RET_ASYNC;
871 446ab128 aliguori
}
872 446ab128 aliguori
873 71d71bbd Hans de Goede
static int usb_linux_get_configuration(USBHostDevice *s)
874 b9dc033c balrog
{
875 71d71bbd Hans de Goede
    uint8_t configuration;
876 e41b3910 pbrook
    struct usb_ctrltransfer ct;
877 71d71bbd Hans de Goede
    int ret;
878 b9dc033c balrog
879 2cc59d8c Hans de Goede
    if (usb_fs_type == USB_FS_SYS) {
880 2cc59d8c Hans de Goede
        char device_name[32], line[1024];
881 2cc59d8c Hans de Goede
        int configuration;
882 2cc59d8c Hans de Goede
883 5557d820 Gerd Hoffmann
        sprintf(device_name, "%d-%s", s->bus_num, s->port);
884 2cc59d8c Hans de Goede
885 2cc59d8c Hans de Goede
        if (!usb_host_read_file(line, sizeof(line), "bConfigurationValue",
886 2cc59d8c Hans de Goede
                                device_name)) {
887 2cc59d8c Hans de Goede
            goto usbdevfs;
888 2cc59d8c Hans de Goede
        }
889 2cc59d8c Hans de Goede
        if (sscanf(line, "%d", &configuration) != 1) {
890 2cc59d8c Hans de Goede
            goto usbdevfs;
891 2cc59d8c Hans de Goede
        }
892 2cc59d8c Hans de Goede
        return configuration;
893 2cc59d8c Hans de Goede
    }
894 2cc59d8c Hans de Goede
895 2cc59d8c Hans de Goede
usbdevfs:
896 b9dc033c balrog
    ct.bRequestType = USB_DIR_IN;
897 b9dc033c balrog
    ct.bRequest = USB_REQ_GET_CONFIGURATION;
898 b9dc033c balrog
    ct.wValue = 0;
899 b9dc033c balrog
    ct.wIndex = 0;
900 b9dc033c balrog
    ct.wLength = 1;
901 b9dc033c balrog
    ct.data = &configuration;
902 b9dc033c balrog
    ct.timeout = 50;
903 b9dc033c balrog
904 b9dc033c balrog
    ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
905 b9dc033c balrog
    if (ret < 0) {
906 71d71bbd Hans de Goede
        perror("usb_linux_get_configuration");
907 71d71bbd Hans de Goede
        return -1;
908 b9dc033c balrog
    }
909 b9dc033c balrog
910 b9dc033c balrog
    /* in address state */
911 2791104c David Ahern
    if (configuration == 0) {
912 71d71bbd Hans de Goede
        return -1;
913 2791104c David Ahern
    }
914 b9dc033c balrog
915 71d71bbd Hans de Goede
    return configuration;
916 71d71bbd Hans de Goede
}
917 71d71bbd Hans de Goede
918 ed3a328d Hans de Goede
static uint8_t usb_linux_get_alt_setting(USBHostDevice *s,
919 ed3a328d Hans de Goede
    uint8_t configuration, uint8_t interface)
920 ed3a328d Hans de Goede
{
921 ed3a328d Hans de Goede
    uint8_t alt_setting;
922 ed3a328d Hans de Goede
    struct usb_ctrltransfer ct;
923 ed3a328d Hans de Goede
    int ret;
924 ed3a328d Hans de Goede
925 c43831fb Hans de Goede
    if (usb_fs_type == USB_FS_SYS) {
926 c43831fb Hans de Goede
        char device_name[64], line[1024];
927 c43831fb Hans de Goede
        int alt_setting;
928 c43831fb Hans de Goede
929 5557d820 Gerd Hoffmann
        sprintf(device_name, "%d-%s:%d.%d", s->bus_num, s->port,
930 c43831fb Hans de Goede
                (int)configuration, (int)interface);
931 c43831fb Hans de Goede
932 c43831fb Hans de Goede
        if (!usb_host_read_file(line, sizeof(line), "bAlternateSetting",
933 c43831fb Hans de Goede
                                device_name)) {
934 c43831fb Hans de Goede
            goto usbdevfs;
935 c43831fb Hans de Goede
        }
936 c43831fb Hans de Goede
        if (sscanf(line, "%d", &alt_setting) != 1) {
937 c43831fb Hans de Goede
            goto usbdevfs;
938 c43831fb Hans de Goede
        }
939 c43831fb Hans de Goede
        return alt_setting;
940 c43831fb Hans de Goede
    }
941 c43831fb Hans de Goede
942 c43831fb Hans de Goede
usbdevfs:
943 ed3a328d Hans de Goede
    ct.bRequestType = USB_DIR_IN | USB_RECIP_INTERFACE;
944 ed3a328d Hans de Goede
    ct.bRequest = USB_REQ_GET_INTERFACE;
945 ed3a328d Hans de Goede
    ct.wValue = 0;
946 ed3a328d Hans de Goede
    ct.wIndex = interface;
947 ed3a328d Hans de Goede
    ct.wLength = 1;
948 ed3a328d Hans de Goede
    ct.data = &alt_setting;
949 ed3a328d Hans de Goede
    ct.timeout = 50;
950 ed3a328d Hans de Goede
    ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
951 ed3a328d Hans de Goede
    if (ret < 0) {
952 ed3a328d Hans de Goede
        /* Assume alt 0 on error */
953 ed3a328d Hans de Goede
        return 0;
954 ed3a328d Hans de Goede
    }
955 ed3a328d Hans de Goede
956 ed3a328d Hans de Goede
    return alt_setting;
957 ed3a328d Hans de Goede
}
958 ed3a328d Hans de Goede
959 71d71bbd Hans de Goede
/* returns 1 on problem encountered or 0 for success */
960 71d71bbd Hans de Goede
static int usb_linux_update_endp_table(USBHostDevice *s)
961 71d71bbd Hans de Goede
{
962 71d71bbd Hans de Goede
    uint8_t *descriptors;
963 71d71bbd Hans de Goede
    uint8_t devep, type, configuration, alt_interface;
964 ed3a328d Hans de Goede
    int interface, length, i;
965 71d71bbd Hans de Goede
966 a0b5fece Hans de Goede
    for (i = 0; i < MAX_ENDPOINTS; i++)
967 a0b5fece Hans de Goede
        s->endp_table[i].type = INVALID_EP_TYPE;
968 a0b5fece Hans de Goede
969 71d71bbd Hans de Goede
    i = usb_linux_get_configuration(s);
970 71d71bbd Hans de Goede
    if (i < 0)
971 71d71bbd Hans de Goede
        return 1;
972 71d71bbd Hans de Goede
    configuration = i;
973 71d71bbd Hans de Goede
974 b9dc033c balrog
    /* get the desired configuration, interface, and endpoint descriptors
975 b9dc033c balrog
     * from device description */
976 b9dc033c balrog
    descriptors = &s->descr[18];
977 b9dc033c balrog
    length = s->descr_len - 18;
978 b9dc033c balrog
    i = 0;
979 b9dc033c balrog
980 b9dc033c balrog
    if (descriptors[i + 1] != USB_DT_CONFIG ||
981 b9dc033c balrog
        descriptors[i + 5] != configuration) {
982 d0f2c4c6 malc
        DPRINTF("invalid descriptor data - configuration\n");
983 b9dc033c balrog
        return 1;
984 b9dc033c balrog
    }
985 b9dc033c balrog
    i += descriptors[i];
986 b9dc033c balrog
987 b9dc033c balrog
    while (i < length) {
988 b9dc033c balrog
        if (descriptors[i + 1] != USB_DT_INTERFACE ||
989 b9dc033c balrog
            (descriptors[i + 1] == USB_DT_INTERFACE &&
990 b9dc033c balrog
             descriptors[i + 4] == 0)) {
991 b9dc033c balrog
            i += descriptors[i];
992 b9dc033c balrog
            continue;
993 b9dc033c balrog
        }
994 b9dc033c balrog
995 b9dc033c balrog
        interface = descriptors[i + 2];
996 ed3a328d Hans de Goede
        alt_interface = usb_linux_get_alt_setting(s, configuration, interface);
997 b9dc033c balrog
998 b9dc033c balrog
        /* the current interface descriptor is the active interface
999 b9dc033c balrog
         * and has endpoints */
1000 b9dc033c balrog
        if (descriptors[i + 3] != alt_interface) {
1001 b9dc033c balrog
            i += descriptors[i];
1002 b9dc033c balrog
            continue;
1003 b9dc033c balrog
        }
1004 b9dc033c balrog
1005 b9dc033c balrog
        /* advance to the endpoints */
1006 2791104c David Ahern
        while (i < length && descriptors[i +1] != USB_DT_ENDPOINT) {
1007 b9dc033c balrog
            i += descriptors[i];
1008 2791104c David Ahern
        }
1009 b9dc033c balrog
1010 b9dc033c balrog
        if (i >= length)
1011 b9dc033c balrog
            break;
1012 b9dc033c balrog
1013 b9dc033c balrog
        while (i < length) {
1014 2791104c David Ahern
            if (descriptors[i + 1] != USB_DT_ENDPOINT) {
1015 b9dc033c balrog
                break;
1016 2791104c David Ahern
            }
1017 b9dc033c balrog
1018 b9dc033c balrog
            devep = descriptors[i + 2];
1019 b9dc033c balrog
            switch (descriptors[i + 3] & 0x3) {
1020 b9dc033c balrog
            case 0x00:
1021 b9dc033c balrog
                type = USBDEVFS_URB_TYPE_CONTROL;
1022 b9dc033c balrog
                break;
1023 b9dc033c balrog
            case 0x01:
1024 b9dc033c balrog
                type = USBDEVFS_URB_TYPE_ISO;
1025 6dfcdccb Gerd Hoffmann
                set_max_packet_size(s, (devep & 0xf), descriptors + i);
1026 b9dc033c balrog
                break;
1027 b9dc033c balrog
            case 0x02:
1028 b9dc033c balrog
                type = USBDEVFS_URB_TYPE_BULK;
1029 b9dc033c balrog
                break;
1030 b9dc033c balrog
            case 0x03:
1031 b9dc033c balrog
                type = USBDEVFS_URB_TYPE_INTERRUPT;
1032 b9dc033c balrog
                break;
1033 ddbda432 Anthony Liguori
            default:
1034 ddbda432 Anthony Liguori
                DPRINTF("usb_host: malformed endpoint type\n");
1035 ddbda432 Anthony Liguori
                type = USBDEVFS_URB_TYPE_BULK;
1036 b9dc033c balrog
            }
1037 b9dc033c balrog
            s->endp_table[(devep & 0xf) - 1].type = type;
1038 64838171 aliguori
            s->endp_table[(devep & 0xf) - 1].halted = 0;
1039 b9dc033c balrog
1040 b9dc033c balrog
            i += descriptors[i];
1041 b9dc033c balrog
        }
1042 b9dc033c balrog
    }
1043 b9dc033c balrog
    return 0;
1044 b9dc033c balrog
}
1045 b9dc033c balrog
1046 26a9e82a Gerd Hoffmann
static int usb_host_open(USBHostDevice *dev, int bus_num,
1047 5557d820 Gerd Hoffmann
                         int addr, char *port, const char *prod_name)
1048 bb36d470 bellard
{
1049 b9dc033c balrog
    int fd = -1, ret;
1050 bb36d470 bellard
    struct usbdevfs_connectinfo ci;
1051 a594cfbf bellard
    char buf[1024];
1052 1f3870ab aliguori
1053 2791104c David Ahern
    if (dev->fd != -1) {
1054 26a9e82a Gerd Hoffmann
        goto fail;
1055 2791104c David Ahern
    }
1056 64838171 aliguori
    printf("husb: open device %d.%d\n", bus_num, addr);
1057 3b46e624 ths
1058 0f431527 aliguori
    if (!usb_host_device_path) {
1059 0f431527 aliguori
        perror("husb: USB Host Device Path not set");
1060 0f431527 aliguori
        goto fail;
1061 0f431527 aliguori
    }
1062 0f431527 aliguori
    snprintf(buf, sizeof(buf), "%s/%03d/%03d", usb_host_device_path,
1063 a594cfbf bellard
             bus_num, addr);
1064 b9dc033c balrog
    fd = open(buf, O_RDWR | O_NONBLOCK);
1065 bb36d470 bellard
    if (fd < 0) {
1066 a594cfbf bellard
        perror(buf);
1067 1f3870ab aliguori
        goto fail;
1068 bb36d470 bellard
    }
1069 d0f2c4c6 malc
    DPRINTF("husb: opened %s\n", buf);
1070 bb36d470 bellard
1071 806b6024 Gerd Hoffmann
    dev->bus_num = bus_num;
1072 806b6024 Gerd Hoffmann
    dev->addr = addr;
1073 5557d820 Gerd Hoffmann
    strcpy(dev->port, port);
1074 22f84e73 Gerd Hoffmann
    dev->fd = fd;
1075 806b6024 Gerd Hoffmann
1076 b9dc033c balrog
    /* read the device description */
1077 b9dc033c balrog
    dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
1078 b9dc033c balrog
    if (dev->descr_len <= 0) {
1079 64838171 aliguori
        perror("husb: reading device data failed");
1080 bb36d470 bellard
        goto fail;
1081 bb36d470 bellard
    }
1082 3b46e624 ths
1083 b9dc033c balrog
#ifdef DEBUG
1084 868bfe2b bellard
    {
1085 b9dc033c balrog
        int x;
1086 b9dc033c balrog
        printf("=== begin dumping device descriptor data ===\n");
1087 2791104c David Ahern
        for (x = 0; x < dev->descr_len; x++) {
1088 b9dc033c balrog
            printf("%02x ", dev->descr[x]);
1089 2791104c David Ahern
        }
1090 b9dc033c balrog
        printf("\n=== end dumping device descriptor data ===\n");
1091 bb36d470 bellard
    }
1092 a594cfbf bellard
#endif
1093 a594cfbf bellard
1094 b9dc033c balrog
1095 2791104c David Ahern
    /*
1096 2791104c David Ahern
     * Initial configuration is -1 which makes us claim first
1097 446ab128 aliguori
     * available config. We used to start with 1, which does not
1098 2791104c David Ahern
     * always work. I've seen devices where first config starts
1099 446ab128 aliguori
     * with 2.
1100 446ab128 aliguori
     */
1101 2791104c David Ahern
    if (!usb_host_claim_interfaces(dev, -1)) {
1102 b9dc033c balrog
        goto fail;
1103 2791104c David Ahern
    }
1104 bb36d470 bellard
1105 bb36d470 bellard
    ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
1106 bb36d470 bellard
    if (ret < 0) {
1107 046833ea balrog
        perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
1108 bb36d470 bellard
        goto fail;
1109 bb36d470 bellard
    }
1110 bb36d470 bellard
1111 64838171 aliguori
    printf("husb: grabbed usb device %d.%d\n", bus_num, addr);
1112 bb36d470 bellard
1113 b9dc033c balrog
    ret = usb_linux_update_endp_table(dev);
1114 2791104c David Ahern
    if (ret) {
1115 bb36d470 bellard
        goto fail;
1116 2791104c David Ahern
    }
1117 b9dc033c balrog
1118 2791104c David Ahern
    if (ci.slow) {
1119 bb36d470 bellard
        dev->dev.speed = USB_SPEED_LOW;
1120 2791104c David Ahern
    } else {
1121 bb36d470 bellard
        dev->dev.speed = USB_SPEED_HIGH;
1122 2791104c David Ahern
    }
1123 bb36d470 bellard
1124 2791104c David Ahern
    if (!prod_name || prod_name[0] == '\0') {
1125 0fe6d12e Markus Armbruster
        snprintf(dev->dev.product_desc, sizeof(dev->dev.product_desc),
1126 4b096fc9 aliguori
                 "host:%d.%d", bus_num, addr);
1127 2791104c David Ahern
    } else {
1128 0fe6d12e Markus Armbruster
        pstrcpy(dev->dev.product_desc, sizeof(dev->dev.product_desc),
1129 4b096fc9 aliguori
                prod_name);
1130 2791104c David Ahern
    }
1131 1f6e24e7 bellard
1132 64838171 aliguori
    /* USB devio uses 'write' flag to check for async completions */
1133 64838171 aliguori
    qemu_set_fd_handler(dev->fd, NULL, async_complete, dev);
1134 1f3870ab aliguori
1135 26a9e82a Gerd Hoffmann
    usb_device_attach(&dev->dev);
1136 26a9e82a Gerd Hoffmann
    return 0;
1137 4b096fc9 aliguori
1138 b9dc033c balrog
fail:
1139 26a9e82a Gerd Hoffmann
    dev->fd = -1;
1140 2791104c David Ahern
    if (fd != -1) {
1141 806b6024 Gerd Hoffmann
        close(fd);
1142 2791104c David Ahern
    }
1143 26a9e82a Gerd Hoffmann
    return -1;
1144 26a9e82a Gerd Hoffmann
}
1145 26a9e82a Gerd Hoffmann
1146 26a9e82a Gerd Hoffmann
static int usb_host_close(USBHostDevice *dev)
1147 26a9e82a Gerd Hoffmann
{
1148 060dc841 Hans de Goede
    int i;
1149 060dc841 Hans de Goede
1150 2791104c David Ahern
    if (dev->fd == -1) {
1151 26a9e82a Gerd Hoffmann
        return -1;
1152 2791104c David Ahern
    }
1153 26a9e82a Gerd Hoffmann
1154 26a9e82a Gerd Hoffmann
    qemu_set_fd_handler(dev->fd, NULL, NULL, NULL);
1155 26a9e82a Gerd Hoffmann
    dev->closing = 1;
1156 3a4854b3 Hans de Goede
    for (i = 1; i <= MAX_ENDPOINTS; i++) {
1157 060dc841 Hans de Goede
        if (is_isoc(dev, i)) {
1158 060dc841 Hans de Goede
            usb_host_stop_n_free_iso(dev, i);
1159 060dc841 Hans de Goede
        }
1160 060dc841 Hans de Goede
    }
1161 26a9e82a Gerd Hoffmann
    async_complete(dev);
1162 26a9e82a Gerd Hoffmann
    dev->closing = 0;
1163 26a9e82a Gerd Hoffmann
    usb_device_detach(&dev->dev);
1164 00ff227a Shahar Havivi
    ioctl(dev->fd, USBDEVFS_RESET);
1165 26a9e82a Gerd Hoffmann
    close(dev->fd);
1166 26a9e82a Gerd Hoffmann
    dev->fd = -1;
1167 26a9e82a Gerd Hoffmann
    return 0;
1168 26a9e82a Gerd Hoffmann
}
1169 26a9e82a Gerd Hoffmann
1170 b373a63a Shahar Havivi
static void usb_host_exit_notifier(struct Notifier* n)
1171 b373a63a Shahar Havivi
{
1172 b373a63a Shahar Havivi
    USBHostDevice *s = container_of(n, USBHostDevice, exit);
1173 b373a63a Shahar Havivi
1174 b373a63a Shahar Havivi
    if (s->fd != -1) {
1175 b373a63a Shahar Havivi
        ioctl(s->fd, USBDEVFS_RESET);
1176 b373a63a Shahar Havivi
    }
1177 b373a63a Shahar Havivi
}
1178 b373a63a Shahar Havivi
1179 26a9e82a Gerd Hoffmann
static int usb_host_initfn(USBDevice *dev)
1180 26a9e82a Gerd Hoffmann
{
1181 26a9e82a Gerd Hoffmann
    USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
1182 26a9e82a Gerd Hoffmann
1183 26a9e82a Gerd Hoffmann
    dev->auto_attach = 0;
1184 26a9e82a Gerd Hoffmann
    s->fd = -1;
1185 26a9e82a Gerd Hoffmann
    QTAILQ_INSERT_TAIL(&hostdevs, s, next);
1186 b373a63a Shahar Havivi
    s->exit.notify = usb_host_exit_notifier;
1187 b373a63a Shahar Havivi
    qemu_add_exit_notifier(&s->exit);
1188 26a9e82a Gerd Hoffmann
    usb_host_auto_check(NULL);
1189 26a9e82a Gerd Hoffmann
    return 0;
1190 a594cfbf bellard
}
1191 bb36d470 bellard
1192 806b6024 Gerd Hoffmann
static struct USBDeviceInfo usb_host_dev_info = {
1193 06384698 Markus Armbruster
    .product_desc   = "USB Host Device",
1194 556cd098 Markus Armbruster
    .qdev.name      = "usb-host",
1195 806b6024 Gerd Hoffmann
    .qdev.size      = sizeof(USBHostDevice),
1196 806b6024 Gerd Hoffmann
    .init           = usb_host_initfn,
1197 50b7963e Hans de Goede
    .handle_packet  = usb_generic_handle_packet,
1198 eb5e680a Gerd Hoffmann
    .cancel_packet  = usb_host_async_cancel,
1199 50b7963e Hans de Goede
    .handle_data    = usb_host_handle_data,
1200 50b7963e Hans de Goede
    .handle_control = usb_host_handle_control,
1201 806b6024 Gerd Hoffmann
    .handle_reset   = usb_host_handle_reset,
1202 806b6024 Gerd Hoffmann
    .handle_destroy = usb_host_handle_destroy,
1203 26a9e82a Gerd Hoffmann
    .usbdevice_name = "host",
1204 26a9e82a Gerd Hoffmann
    .usbdevice_init = usb_host_device_open,
1205 26a9e82a Gerd Hoffmann
    .qdev.props     = (Property[]) {
1206 26a9e82a Gerd Hoffmann
        DEFINE_PROP_UINT32("hostbus",  USBHostDevice, match.bus_num,    0),
1207 26a9e82a Gerd Hoffmann
        DEFINE_PROP_UINT32("hostaddr", USBHostDevice, match.addr,       0),
1208 9056a297 Gerd Hoffmann
        DEFINE_PROP_STRING("hostport", USBHostDevice, match.port),
1209 26a9e82a Gerd Hoffmann
        DEFINE_PROP_HEX32("vendorid",  USBHostDevice, match.vendor_id,  0),
1210 26a9e82a Gerd Hoffmann
        DEFINE_PROP_HEX32("productid", USBHostDevice, match.product_id, 0),
1211 26a9e82a Gerd Hoffmann
        DEFINE_PROP_END_OF_LIST(),
1212 26a9e82a Gerd Hoffmann
    },
1213 806b6024 Gerd Hoffmann
};
1214 806b6024 Gerd Hoffmann
1215 806b6024 Gerd Hoffmann
static void usb_host_register_devices(void)
1216 806b6024 Gerd Hoffmann
{
1217 806b6024 Gerd Hoffmann
    usb_qdev_register(&usb_host_dev_info);
1218 806b6024 Gerd Hoffmann
}
1219 806b6024 Gerd Hoffmann
device_init(usb_host_register_devices)
1220 806b6024 Gerd Hoffmann
1221 4b096fc9 aliguori
USBDevice *usb_host_device_open(const char *devname)
1222 4b096fc9 aliguori
{
1223 0745eb1e Markus Armbruster
    struct USBAutoFilter filter;
1224 26a9e82a Gerd Hoffmann
    USBDevice *dev;
1225 26a9e82a Gerd Hoffmann
    char *p;
1226 26a9e82a Gerd Hoffmann
1227 556cd098 Markus Armbruster
    dev = usb_create(NULL /* FIXME */, "usb-host");
1228 4b096fc9 aliguori
1229 5d0c5750 aliguori
    if (strstr(devname, "auto:")) {
1230 2791104c David Ahern
        if (parse_filter(devname, &filter) < 0) {
1231 26a9e82a Gerd Hoffmann
            goto fail;
1232 2791104c David Ahern
        }
1233 26a9e82a Gerd Hoffmann
    } else {
1234 26a9e82a Gerd Hoffmann
        if ((p = strchr(devname, '.'))) {
1235 0745eb1e Markus Armbruster
            filter.bus_num    = strtoul(devname, NULL, 0);
1236 0745eb1e Markus Armbruster
            filter.addr       = strtoul(p + 1, NULL, 0);
1237 0745eb1e Markus Armbruster
            filter.vendor_id  = 0;
1238 0745eb1e Markus Armbruster
            filter.product_id = 0;
1239 26a9e82a Gerd Hoffmann
        } else if ((p = strchr(devname, ':'))) {
1240 0745eb1e Markus Armbruster
            filter.bus_num    = 0;
1241 0745eb1e Markus Armbruster
            filter.addr       = 0;
1242 26a9e82a Gerd Hoffmann
            filter.vendor_id  = strtoul(devname, NULL, 16);
1243 0745eb1e Markus Armbruster
            filter.product_id = strtoul(p + 1, NULL, 16);
1244 26a9e82a Gerd Hoffmann
        } else {
1245 26a9e82a Gerd Hoffmann
            goto fail;
1246 26a9e82a Gerd Hoffmann
        }
1247 5d0c5750 aliguori
    }
1248 4b096fc9 aliguori
1249 0745eb1e Markus Armbruster
    qdev_prop_set_uint32(&dev->qdev, "hostbus",   filter.bus_num);
1250 0745eb1e Markus Armbruster
    qdev_prop_set_uint32(&dev->qdev, "hostaddr",  filter.addr);
1251 26a9e82a Gerd Hoffmann
    qdev_prop_set_uint32(&dev->qdev, "vendorid",  filter.vendor_id);
1252 26a9e82a Gerd Hoffmann
    qdev_prop_set_uint32(&dev->qdev, "productid", filter.product_id);
1253 beb6f0de Kevin Wolf
    qdev_init_nofail(&dev->qdev);
1254 26a9e82a Gerd Hoffmann
    return dev;
1255 5d0c5750 aliguori
1256 26a9e82a Gerd Hoffmann
fail:
1257 26a9e82a Gerd Hoffmann
    qdev_free(&dev->qdev);
1258 26a9e82a Gerd Hoffmann
    return NULL;
1259 4b096fc9 aliguori
}
1260 5d0c5750 aliguori
1261 5d0c5750 aliguori
int usb_host_device_close(const char *devname)
1262 5d0c5750 aliguori
{
1263 26a9e82a Gerd Hoffmann
#if 0
1264 5d0c5750 aliguori
    char product_name[PRODUCT_NAME_SZ];
1265 5d0c5750 aliguori
    int bus_num, addr;
1266 5d0c5750 aliguori
    USBHostDevice *s;
1267 5d0c5750 aliguori

1268 2791104c David Ahern
    if (strstr(devname, "auto:")) {
1269 5d0c5750 aliguori
        return usb_host_auto_del(devname);
1270 2791104c David Ahern
    }
1271 2791104c David Ahern
    if (usb_host_find_device(&bus_num, &addr, product_name,
1272 2791104c David Ahern
                                    sizeof(product_name), devname) < 0) {
1273 5d0c5750 aliguori
        return -1;
1274 2791104c David Ahern
    }
1275 5d0c5750 aliguori
    s = hostdev_find(bus_num, addr);
1276 5d0c5750 aliguori
    if (s) {
1277 a5d2f727 Gerd Hoffmann
        usb_device_delete_addr(s->bus_num, s->dev.addr);
1278 5d0c5750 aliguori
        return 0;
1279 5d0c5750 aliguori
    }
1280 26a9e82a Gerd Hoffmann
#endif
1281 5d0c5750 aliguori
1282 5d0c5750 aliguori
    return -1;
1283 5d0c5750 aliguori
}
1284 a5d2f727 Gerd Hoffmann
1285 a594cfbf bellard
static int get_tag_value(char *buf, int buf_size,
1286 5fafdf24 ths
                         const char *str, const char *tag,
1287 a594cfbf bellard
                         const char *stopchars)
1288 a594cfbf bellard
{
1289 a594cfbf bellard
    const char *p;
1290 a594cfbf bellard
    char *q;
1291 a594cfbf bellard
    p = strstr(str, tag);
1292 2791104c David Ahern
    if (!p) {
1293 a594cfbf bellard
        return -1;
1294 2791104c David Ahern
    }
1295 a594cfbf bellard
    p += strlen(tag);
1296 2791104c David Ahern
    while (qemu_isspace(*p)) {
1297 a594cfbf bellard
        p++;
1298 2791104c David Ahern
    }
1299 a594cfbf bellard
    q = buf;
1300 a594cfbf bellard
    while (*p != '\0' && !strchr(stopchars, *p)) {
1301 2791104c David Ahern
        if ((q - buf) < (buf_size - 1)) {
1302 a594cfbf bellard
            *q++ = *p;
1303 2791104c David Ahern
        }
1304 a594cfbf bellard
        p++;
1305 a594cfbf bellard
    }
1306 a594cfbf bellard
    *q = '\0';
1307 a594cfbf bellard
    return q - buf;
1308 bb36d470 bellard
}
1309 bb36d470 bellard
1310 0f431527 aliguori
/*
1311 0f431527 aliguori
 * Use /proc/bus/usb/devices or /dev/bus/usb/devices file to determine
1312 0f431527 aliguori
 * host's USB devices. This is legacy support since many distributions
1313 0f431527 aliguori
 * are moving to /sys/bus/usb
1314 0f431527 aliguori
 */
1315 0f431527 aliguori
static int usb_host_scan_dev(void *opaque, USBScanFunc *func)
1316 bb36d470 bellard
{
1317 660f11be Blue Swirl
    FILE *f = NULL;
1318 a594cfbf bellard
    char line[1024];
1319 bb36d470 bellard
    char buf[1024];
1320 a594cfbf bellard
    int bus_num, addr, speed, device_count, class_id, product_id, vendor_id;
1321 a594cfbf bellard
    char product_name[512];
1322 0f431527 aliguori
    int ret = 0;
1323 3b46e624 ths
1324 0f431527 aliguori
    if (!usb_host_device_path) {
1325 0f431527 aliguori
        perror("husb: USB Host Device Path not set");
1326 0f431527 aliguori
        goto the_end;
1327 0f431527 aliguori
    }
1328 0f431527 aliguori
    snprintf(line, sizeof(line), "%s/devices", usb_host_device_path);
1329 0f431527 aliguori
    f = fopen(line, "r");
1330 a594cfbf bellard
    if (!f) {
1331 0f431527 aliguori
        perror("husb: cannot open devices file");
1332 0f431527 aliguori
        goto the_end;
1333 a594cfbf bellard
    }
1334 0f431527 aliguori
1335 a594cfbf bellard
    device_count = 0;
1336 a594cfbf bellard
    bus_num = addr = speed = class_id = product_id = vendor_id = 0;
1337 bb36d470 bellard
    for(;;) {
1338 2791104c David Ahern
        if (fgets(line, sizeof(line), f) == NULL) {
1339 bb36d470 bellard
            break;
1340 2791104c David Ahern
        }
1341 2791104c David Ahern
        if (strlen(line) > 0) {
1342 a594cfbf bellard
            line[strlen(line) - 1] = '\0';
1343 2791104c David Ahern
        }
1344 a594cfbf bellard
        if (line[0] == 'T' && line[1] == ':') {
1345 38ca0f6d pbrook
            if (device_count && (vendor_id || product_id)) {
1346 38ca0f6d pbrook
                /* New device.  Add the previously discovered device.  */
1347 0f5160d1 Hans de Goede
                ret = func(opaque, bus_num, addr, 0, class_id, vendor_id,
1348 a594cfbf bellard
                           product_id, product_name, speed);
1349 2791104c David Ahern
                if (ret) {
1350 a594cfbf bellard
                    goto the_end;
1351 2791104c David Ahern
                }
1352 a594cfbf bellard
            }
1353 2791104c David Ahern
            if (get_tag_value(buf, sizeof(buf), line, "Bus=", " ") < 0) {
1354 a594cfbf bellard
                goto fail;
1355 2791104c David Ahern
            }
1356 a594cfbf bellard
            bus_num = atoi(buf);
1357 2791104c David Ahern
            if (get_tag_value(buf, sizeof(buf), line, "Dev#=", " ") < 0) {
1358 a594cfbf bellard
                goto fail;
1359 2791104c David Ahern
            }
1360 a594cfbf bellard
            addr = atoi(buf);
1361 2791104c David Ahern
            if (get_tag_value(buf, sizeof(buf), line, "Spd=", " ") < 0) {
1362 a594cfbf bellard
                goto fail;
1363 2791104c David Ahern
            }
1364 2791104c David Ahern
            if (!strcmp(buf, "480")) {
1365 a594cfbf bellard
                speed = USB_SPEED_HIGH;
1366 2791104c David Ahern
            } else if (!strcmp(buf, "1.5")) {
1367 a594cfbf bellard
                speed = USB_SPEED_LOW;
1368 2791104c David Ahern
            } else {
1369 a594cfbf bellard
                speed = USB_SPEED_FULL;
1370 2791104c David Ahern
            }
1371 a594cfbf bellard
            product_name[0] = '\0';
1372 a594cfbf bellard
            class_id = 0xff;
1373 a594cfbf bellard
            device_count++;
1374 a594cfbf bellard
            product_id = 0;
1375 a594cfbf bellard
            vendor_id = 0;
1376 a594cfbf bellard
        } else if (line[0] == 'P' && line[1] == ':') {
1377 2791104c David Ahern
            if (get_tag_value(buf, sizeof(buf), line, "Vendor=", " ") < 0) {
1378 a594cfbf bellard
                goto fail;
1379 2791104c David Ahern
            }
1380 a594cfbf bellard
            vendor_id = strtoul(buf, NULL, 16);
1381 2791104c David Ahern
            if (get_tag_value(buf, sizeof(buf), line, "ProdID=", " ") < 0) {
1382 a594cfbf bellard
                goto fail;
1383 2791104c David Ahern
            }
1384 a594cfbf bellard
            product_id = strtoul(buf, NULL, 16);
1385 a594cfbf bellard
        } else if (line[0] == 'S' && line[1] == ':') {
1386 2791104c David Ahern
            if (get_tag_value(buf, sizeof(buf), line, "Product=", "") < 0) {
1387 a594cfbf bellard
                goto fail;
1388 2791104c David Ahern
            }
1389 a594cfbf bellard
            pstrcpy(product_name, sizeof(product_name), buf);
1390 a594cfbf bellard
        } else if (line[0] == 'D' && line[1] == ':') {
1391 2791104c David Ahern
            if (get_tag_value(buf, sizeof(buf), line, "Cls=", " (") < 0) {
1392 a594cfbf bellard
                goto fail;
1393 2791104c David Ahern
            }
1394 a594cfbf bellard
            class_id = strtoul(buf, NULL, 16);
1395 bb36d470 bellard
        }
1396 a594cfbf bellard
    fail: ;
1397 a594cfbf bellard
    }
1398 38ca0f6d pbrook
    if (device_count && (vendor_id || product_id)) {
1399 38ca0f6d pbrook
        /* Add the last device.  */
1400 0f5160d1 Hans de Goede
        ret = func(opaque, bus_num, addr, 0, class_id, vendor_id,
1401 a594cfbf bellard
                   product_id, product_name, speed);
1402 bb36d470 bellard
    }
1403 a594cfbf bellard
 the_end:
1404 2791104c David Ahern
    if (f) {
1405 0f431527 aliguori
        fclose(f);
1406 2791104c David Ahern
    }
1407 0f431527 aliguori
    return ret;
1408 0f431527 aliguori
}
1409 0f431527 aliguori
1410 0f431527 aliguori
/*
1411 0f431527 aliguori
 * Read sys file-system device file
1412 0f431527 aliguori
 *
1413 0f431527 aliguori
 * @line address of buffer to put file contents in
1414 0f431527 aliguori
 * @line_size size of line
1415 0f431527 aliguori
 * @device_file path to device file (printf format string)
1416 0f431527 aliguori
 * @device_name device being opened (inserted into device_file)
1417 0f431527 aliguori
 *
1418 0f431527 aliguori
 * @return 0 failed, 1 succeeded ('line' contains data)
1419 0f431527 aliguori
 */
1420 2791104c David Ahern
static int usb_host_read_file(char *line, size_t line_size,
1421 2791104c David Ahern
                              const char *device_file, const char *device_name)
1422 0f431527 aliguori
{
1423 0f431527 aliguori
    FILE *f;
1424 0f431527 aliguori
    int ret = 0;
1425 0f431527 aliguori
    char filename[PATH_MAX];
1426 0f431527 aliguori
1427 b4e237aa blueswir1
    snprintf(filename, PATH_MAX, USBSYSBUS_PATH "/devices/%s/%s", device_name,
1428 b4e237aa blueswir1
             device_file);
1429 0f431527 aliguori
    f = fopen(filename, "r");
1430 0f431527 aliguori
    if (f) {
1431 9f99cee7 Kirill A. Shutemov
        ret = fgets(line, line_size, f) != NULL;
1432 0f431527 aliguori
        fclose(f);
1433 0f431527 aliguori
    }
1434 0f431527 aliguori
1435 0f431527 aliguori
    return ret;
1436 0f431527 aliguori
}
1437 0f431527 aliguori
1438 0f431527 aliguori
/*
1439 0f431527 aliguori
 * Use /sys/bus/usb/devices/ directory to determine host's USB
1440 0f431527 aliguori
 * devices.
1441 0f431527 aliguori
 *
1442 0f431527 aliguori
 * This code is based on Robert Schiele's original patches posted to
1443 0f431527 aliguori
 * the Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
1444 0f431527 aliguori
 */
1445 0f431527 aliguori
static int usb_host_scan_sys(void *opaque, USBScanFunc *func)
1446 0f431527 aliguori
{
1447 660f11be Blue Swirl
    DIR *dir = NULL;
1448 0f431527 aliguori
    char line[1024];
1449 5557d820 Gerd Hoffmann
    int bus_num, addr, speed, class_id, product_id, vendor_id;
1450 0f431527 aliguori
    int ret = 0;
1451 5557d820 Gerd Hoffmann
    char port[MAX_PORTLEN];
1452 0f431527 aliguori
    char product_name[512];
1453 0f431527 aliguori
    struct dirent *de;
1454 0f431527 aliguori
1455 0f431527 aliguori
    dir = opendir(USBSYSBUS_PATH "/devices");
1456 0f431527 aliguori
    if (!dir) {
1457 0f431527 aliguori
        perror("husb: cannot open devices directory");
1458 0f431527 aliguori
        goto the_end;
1459 0f431527 aliguori
    }
1460 0f431527 aliguori
1461 0f431527 aliguori
    while ((de = readdir(dir))) {
1462 0f431527 aliguori
        if (de->d_name[0] != '.' && !strchr(de->d_name, ':')) {
1463 5557d820 Gerd Hoffmann
            if (sscanf(de->d_name, "%d-%7[0-9.]", &bus_num, port) < 2) {
1464 5557d820 Gerd Hoffmann
                continue;
1465 0f5160d1 Hans de Goede
            }
1466 0f431527 aliguori
1467 2791104c David Ahern
            if (!usb_host_read_file(line, sizeof(line), "devnum", de->d_name)) {
1468 0f431527 aliguori
                goto the_end;
1469 2791104c David Ahern
            }
1470 2791104c David Ahern
            if (sscanf(line, "%d", &addr) != 1) {
1471 0f431527 aliguori
                goto the_end;
1472 2791104c David Ahern
            }
1473 b4e237aa blueswir1
            if (!usb_host_read_file(line, sizeof(line), "bDeviceClass",
1474 2791104c David Ahern
                                    de->d_name)) {
1475 0f431527 aliguori
                goto the_end;
1476 2791104c David Ahern
            }
1477 2791104c David Ahern
            if (sscanf(line, "%x", &class_id) != 1) {
1478 0f431527 aliguori
                goto the_end;
1479 2791104c David Ahern
            }
1480 0f431527 aliguori
1481 2791104c David Ahern
            if (!usb_host_read_file(line, sizeof(line), "idVendor",
1482 2791104c David Ahern
                                    de->d_name)) {
1483 0f431527 aliguori
                goto the_end;
1484 2791104c David Ahern
            }
1485 2791104c David Ahern
            if (sscanf(line, "%x", &vendor_id) != 1) {
1486 0f431527 aliguori
                goto the_end;
1487 2791104c David Ahern
            }
1488 b4e237aa blueswir1
            if (!usb_host_read_file(line, sizeof(line), "idProduct",
1489 2791104c David Ahern
                                    de->d_name)) {
1490 0f431527 aliguori
                goto the_end;
1491 2791104c David Ahern
            }
1492 2791104c David Ahern
            if (sscanf(line, "%x", &product_id) != 1) {
1493 0f431527 aliguori
                goto the_end;
1494 2791104c David Ahern
            }
1495 b4e237aa blueswir1
            if (!usb_host_read_file(line, sizeof(line), "product",
1496 b4e237aa blueswir1
                                    de->d_name)) {
1497 0f431527 aliguori
                *product_name = 0;
1498 0f431527 aliguori
            } else {
1499 2791104c David Ahern
                if (strlen(line) > 0) {
1500 0f431527 aliguori
                    line[strlen(line) - 1] = '\0';
1501 2791104c David Ahern
                }
1502 0f431527 aliguori
                pstrcpy(product_name, sizeof(product_name), line);
1503 0f431527 aliguori
            }
1504 0f431527 aliguori
1505 2791104c David Ahern
            if (!usb_host_read_file(line, sizeof(line), "speed", de->d_name)) {
1506 0f431527 aliguori
                goto the_end;
1507 2791104c David Ahern
            }
1508 2791104c David Ahern
            if (!strcmp(line, "480\n")) {
1509 0f431527 aliguori
                speed = USB_SPEED_HIGH;
1510 2791104c David Ahern
            } else if (!strcmp(line, "1.5\n")) {
1511 0f431527 aliguori
                speed = USB_SPEED_LOW;
1512 2791104c David Ahern
            } else {
1513 0f431527 aliguori
                speed = USB_SPEED_FULL;
1514 2791104c David Ahern
            }
1515 0f431527 aliguori
1516 5557d820 Gerd Hoffmann
            ret = func(opaque, bus_num, addr, port, class_id, vendor_id,
1517 0f431527 aliguori
                       product_id, product_name, speed);
1518 2791104c David Ahern
            if (ret) {
1519 0f431527 aliguori
                goto the_end;
1520 2791104c David Ahern
            }
1521 0f431527 aliguori
        }
1522 0f431527 aliguori
    }
1523 0f431527 aliguori
 the_end:
1524 2791104c David Ahern
    if (dir) {
1525 0f431527 aliguori
        closedir(dir);
1526 2791104c David Ahern
    }
1527 0f431527 aliguori
    return ret;
1528 0f431527 aliguori
}
1529 0f431527 aliguori
1530 0f431527 aliguori
/*
1531 0f431527 aliguori
 * Determine how to access the host's USB devices and call the
1532 0f431527 aliguori
 * specific support function.
1533 0f431527 aliguori
 */
1534 0f431527 aliguori
static int usb_host_scan(void *opaque, USBScanFunc *func)
1535 0f431527 aliguori
{
1536 376253ec aliguori
    Monitor *mon = cur_mon;
1537 660f11be Blue Swirl
    FILE *f = NULL;
1538 660f11be Blue Swirl
    DIR *dir = NULL;
1539 0f431527 aliguori
    int ret = 0;
1540 0f431527 aliguori
    const char *fs_type[] = {"unknown", "proc", "dev", "sys"};
1541 0f431527 aliguori
    char devpath[PATH_MAX];
1542 0f431527 aliguori
1543 0f431527 aliguori
    /* only check the host once */
1544 0f431527 aliguori
    if (!usb_fs_type) {
1545 55496240 Mark McLoughlin
        dir = opendir(USBSYSBUS_PATH "/devices");
1546 55496240 Mark McLoughlin
        if (dir) {
1547 55496240 Mark McLoughlin
            /* devices found in /dev/bus/usb/ (yes - not a mistake!) */
1548 55496240 Mark McLoughlin
            strcpy(devpath, USBDEVBUS_PATH);
1549 55496240 Mark McLoughlin
            usb_fs_type = USB_FS_SYS;
1550 55496240 Mark McLoughlin
            closedir(dir);
1551 d0f2c4c6 malc
            DPRINTF(USBDBG_DEVOPENED, USBSYSBUS_PATH);
1552 55496240 Mark McLoughlin
            goto found_devices;
1553 55496240 Mark McLoughlin
        }
1554 0f431527 aliguori
        f = fopen(USBPROCBUS_PATH "/devices", "r");
1555 0f431527 aliguori
        if (f) {
1556 0f431527 aliguori
            /* devices found in /proc/bus/usb/ */
1557 0f431527 aliguori
            strcpy(devpath, USBPROCBUS_PATH);
1558 0f431527 aliguori
            usb_fs_type = USB_FS_PROC;
1559 0f431527 aliguori
            fclose(f);
1560 d0f2c4c6 malc
            DPRINTF(USBDBG_DEVOPENED, USBPROCBUS_PATH);
1561 f16a0db3 aliguori
            goto found_devices;
1562 0f431527 aliguori
        }
1563 0f431527 aliguori
        /* try additional methods if an access method hasn't been found yet */
1564 0f431527 aliguori
        f = fopen(USBDEVBUS_PATH "/devices", "r");
1565 f16a0db3 aliguori
        if (f) {
1566 0f431527 aliguori
            /* devices found in /dev/bus/usb/ */
1567 0f431527 aliguori
            strcpy(devpath, USBDEVBUS_PATH);
1568 0f431527 aliguori
            usb_fs_type = USB_FS_DEV;
1569 0f431527 aliguori
            fclose(f);
1570 d0f2c4c6 malc
            DPRINTF(USBDBG_DEVOPENED, USBDEVBUS_PATH);
1571 f16a0db3 aliguori
            goto found_devices;
1572 0f431527 aliguori
        }
1573 f16a0db3 aliguori
    found_devices:
1574 22babebb aliguori
        if (!usb_fs_type) {
1575 2791104c David Ahern
            if (mon) {
1576 eba6fe87 Gerd Hoffmann
                monitor_printf(mon, "husb: unable to access USB devices\n");
1577 2791104c David Ahern
            }
1578 f16a0db3 aliguori
            return -ENOENT;
1579 0f431527 aliguori
        }
1580 0f431527 aliguori
1581 0f431527 aliguori
        /* the module setting (used later for opening devices) */
1582 0f431527 aliguori
        usb_host_device_path = qemu_mallocz(strlen(devpath)+1);
1583 1eec614b aliguori
        strcpy(usb_host_device_path, devpath);
1584 2791104c David Ahern
        if (mon) {
1585 eba6fe87 Gerd Hoffmann
            monitor_printf(mon, "husb: using %s file-system with %s\n",
1586 eba6fe87 Gerd Hoffmann
                           fs_type[usb_fs_type], usb_host_device_path);
1587 2791104c David Ahern
        }
1588 0f431527 aliguori
    }
1589 0f431527 aliguori
1590 0f431527 aliguori
    switch (usb_fs_type) {
1591 0f431527 aliguori
    case USB_FS_PROC:
1592 0f431527 aliguori
    case USB_FS_DEV:
1593 0f431527 aliguori
        ret = usb_host_scan_dev(opaque, func);
1594 0f431527 aliguori
        break;
1595 0f431527 aliguori
    case USB_FS_SYS:
1596 0f431527 aliguori
        ret = usb_host_scan_sys(opaque, func);
1597 0f431527 aliguori
        break;
1598 f16a0db3 aliguori
    default:
1599 f16a0db3 aliguori
        ret = -EINVAL;
1600 f16a0db3 aliguori
        break;
1601 0f431527 aliguori
    }
1602 a594cfbf bellard
    return ret;
1603 bb36d470 bellard
}
1604 bb36d470 bellard
1605 4b096fc9 aliguori
static QEMUTimer *usb_auto_timer;
1606 4b096fc9 aliguori
1607 5557d820 Gerd Hoffmann
static int usb_host_auto_scan(void *opaque, int bus_num, int addr, char *port,
1608 26a9e82a Gerd Hoffmann
                              int class_id, int vendor_id, int product_id,
1609 26a9e82a Gerd Hoffmann
                              const char *product_name, int speed)
1610 4b096fc9 aliguori
{
1611 4b096fc9 aliguori
    struct USBAutoFilter *f;
1612 26a9e82a Gerd Hoffmann
    struct USBHostDevice *s;
1613 4b096fc9 aliguori
1614 4b096fc9 aliguori
    /* Ignore hubs */
1615 4b096fc9 aliguori
    if (class_id == 9)
1616 4b096fc9 aliguori
        return 0;
1617 4b096fc9 aliguori
1618 26a9e82a Gerd Hoffmann
    QTAILQ_FOREACH(s, &hostdevs, next) {
1619 26a9e82a Gerd Hoffmann
        f = &s->match;
1620 26a9e82a Gerd Hoffmann
1621 2791104c David Ahern
        if (f->bus_num > 0 && f->bus_num != bus_num) {
1622 4b096fc9 aliguori
            continue;
1623 2791104c David Ahern
        }
1624 2791104c David Ahern
        if (f->addr > 0 && f->addr != addr) {
1625 4b096fc9 aliguori
            continue;
1626 2791104c David Ahern
        }
1627 9056a297 Gerd Hoffmann
        if (f->port != NULL && (port == NULL || strcmp(f->port, port) != 0)) {
1628 9056a297 Gerd Hoffmann
            continue;
1629 9056a297 Gerd Hoffmann
        }
1630 4b096fc9 aliguori
1631 2791104c David Ahern
        if (f->vendor_id > 0 && f->vendor_id != vendor_id) {
1632 4b096fc9 aliguori
            continue;
1633 2791104c David Ahern
        }
1634 4b096fc9 aliguori
1635 2791104c David Ahern
        if (f->product_id > 0 && f->product_id != product_id) {
1636 4b096fc9 aliguori
            continue;
1637 2791104c David Ahern
        }
1638 4b096fc9 aliguori
        /* We got a match */
1639 4b096fc9 aliguori
1640 33e66b86 Markus Armbruster
        /* Already attached ? */
1641 2791104c David Ahern
        if (s->fd != -1) {
1642 4b096fc9 aliguori
            return 0;
1643 2791104c David Ahern
        }
1644 d0f2c4c6 malc
        DPRINTF("husb: auto open: bus_num %d addr %d\n", bus_num, addr);
1645 4b096fc9 aliguori
1646 5557d820 Gerd Hoffmann
        usb_host_open(s, bus_num, addr, port, product_name);
1647 4b096fc9 aliguori
    }
1648 4b096fc9 aliguori
1649 4b096fc9 aliguori
    return 0;
1650 4b096fc9 aliguori
}
1651 4b096fc9 aliguori
1652 26a9e82a Gerd Hoffmann
static void usb_host_auto_check(void *unused)
1653 4b096fc9 aliguori
{
1654 26a9e82a Gerd Hoffmann
    struct USBHostDevice *s;
1655 26a9e82a Gerd Hoffmann
    int unconnected = 0;
1656 26a9e82a Gerd Hoffmann
1657 4b096fc9 aliguori
    usb_host_scan(NULL, usb_host_auto_scan);
1658 26a9e82a Gerd Hoffmann
1659 26a9e82a Gerd Hoffmann
    QTAILQ_FOREACH(s, &hostdevs, next) {
1660 2791104c David Ahern
        if (s->fd == -1) {
1661 26a9e82a Gerd Hoffmann
            unconnected++;
1662 2791104c David Ahern
        }
1663 26a9e82a Gerd Hoffmann
    }
1664 26a9e82a Gerd Hoffmann
1665 26a9e82a Gerd Hoffmann
    if (unconnected == 0) {
1666 26a9e82a Gerd Hoffmann
        /* nothing to watch */
1667 2791104c David Ahern
        if (usb_auto_timer) {
1668 26a9e82a Gerd Hoffmann
            qemu_del_timer(usb_auto_timer);
1669 2791104c David Ahern
        }
1670 26a9e82a Gerd Hoffmann
        return;
1671 26a9e82a Gerd Hoffmann
    }
1672 26a9e82a Gerd Hoffmann
1673 26a9e82a Gerd Hoffmann
    if (!usb_auto_timer) {
1674 7bd427d8 Paolo Bonzini
        usb_auto_timer = qemu_new_timer_ms(rt_clock, usb_host_auto_check, NULL);
1675 2791104c David Ahern
        if (!usb_auto_timer) {
1676 26a9e82a Gerd Hoffmann
            return;
1677 2791104c David Ahern
        }
1678 26a9e82a Gerd Hoffmann
    }
1679 7bd427d8 Paolo Bonzini
    qemu_mod_timer(usb_auto_timer, qemu_get_clock_ms(rt_clock) + 2000);
1680 4b096fc9 aliguori
}
1681 4b096fc9 aliguori
1682 4b096fc9 aliguori
/*
1683 5d0c5750 aliguori
 * Autoconnect filter
1684 5d0c5750 aliguori
 * Format:
1685 5d0c5750 aliguori
 *    auto:bus:dev[:vid:pid]
1686 5d0c5750 aliguori
 *    auto:bus.dev[:vid:pid]
1687 5d0c5750 aliguori
 *
1688 5d0c5750 aliguori
 *    bus  - bus number    (dec, * means any)
1689 5d0c5750 aliguori
 *    dev  - device number (dec, * means any)
1690 5d0c5750 aliguori
 *    vid  - vendor id     (hex, * means any)
1691 5d0c5750 aliguori
 *    pid  - product id    (hex, * means any)
1692 5d0c5750 aliguori
 *
1693 5d0c5750 aliguori
 *    See 'lsusb' output.
1694 4b096fc9 aliguori
 */
1695 5d0c5750 aliguori
static int parse_filter(const char *spec, struct USBAutoFilter *f)
1696 4b096fc9 aliguori
{
1697 5d0c5750 aliguori
    enum { BUS, DEV, VID, PID, DONE };
1698 5d0c5750 aliguori
    const char *p = spec;
1699 5d0c5750 aliguori
    int i;
1700 5d0c5750 aliguori
1701 0745eb1e Markus Armbruster
    f->bus_num    = 0;
1702 0745eb1e Markus Armbruster
    f->addr       = 0;
1703 0745eb1e Markus Armbruster
    f->vendor_id  = 0;
1704 0745eb1e Markus Armbruster
    f->product_id = 0;
1705 5d0c5750 aliguori
1706 5d0c5750 aliguori
    for (i = BUS; i < DONE; i++) {
1707 2791104c David Ahern
        p = strpbrk(p, ":.");
1708 2791104c David Ahern
        if (!p) {
1709 2791104c David Ahern
            break;
1710 2791104c David Ahern
        }
1711 5d0c5750 aliguori
        p++;
1712 5d0c5750 aliguori
1713 2791104c David Ahern
        if (*p == '*') {
1714 2791104c David Ahern
            continue;
1715 2791104c David Ahern
        }
1716 5d0c5750 aliguori
        switch(i) {
1717 5d0c5750 aliguori
        case BUS: f->bus_num = strtol(p, NULL, 10);    break;
1718 5d0c5750 aliguori
        case DEV: f->addr    = strtol(p, NULL, 10);    break;
1719 5d0c5750 aliguori
        case VID: f->vendor_id  = strtol(p, NULL, 16); break;
1720 5d0c5750 aliguori
        case PID: f->product_id = strtol(p, NULL, 16); break;
1721 5d0c5750 aliguori
        }
1722 5d0c5750 aliguori
    }
1723 5d0c5750 aliguori
1724 5d0c5750 aliguori
    if (i < DEV) {
1725 5d0c5750 aliguori
        fprintf(stderr, "husb: invalid auto filter spec %s\n", spec);
1726 5d0c5750 aliguori
        return -1;
1727 5d0c5750 aliguori
    }
1728 5d0c5750 aliguori
1729 5d0c5750 aliguori
    return 0;
1730 5d0c5750 aliguori
}
1731 5d0c5750 aliguori
1732 a594cfbf bellard
/**********************/
1733 a594cfbf bellard
/* USB host device info */
1734 a594cfbf bellard
1735 a594cfbf bellard
struct usb_class_info {
1736 a594cfbf bellard
    int class;
1737 a594cfbf bellard
    const char *class_name;
1738 a594cfbf bellard
};
1739 a594cfbf bellard
1740 a594cfbf bellard
static const struct usb_class_info usb_class_info[] = {
1741 a594cfbf bellard
    { USB_CLASS_AUDIO, "Audio"},
1742 a594cfbf bellard
    { USB_CLASS_COMM, "Communication"},
1743 a594cfbf bellard
    { USB_CLASS_HID, "HID"},
1744 a594cfbf bellard
    { USB_CLASS_HUB, "Hub" },
1745 a594cfbf bellard
    { USB_CLASS_PHYSICAL, "Physical" },
1746 a594cfbf bellard
    { USB_CLASS_PRINTER, "Printer" },
1747 a594cfbf bellard
    { USB_CLASS_MASS_STORAGE, "Storage" },
1748 a594cfbf bellard
    { USB_CLASS_CDC_DATA, "Data" },
1749 a594cfbf bellard
    { USB_CLASS_APP_SPEC, "Application Specific" },
1750 a594cfbf bellard
    { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
1751 a594cfbf bellard
    { USB_CLASS_STILL_IMAGE, "Still Image" },
1752 b9dc033c balrog
    { USB_CLASS_CSCID, "Smart Card" },
1753 a594cfbf bellard
    { USB_CLASS_CONTENT_SEC, "Content Security" },
1754 a594cfbf bellard
    { -1, NULL }
1755 a594cfbf bellard
};
1756 a594cfbf bellard
1757 a594cfbf bellard
static const char *usb_class_str(uint8_t class)
1758 bb36d470 bellard
{
1759 a594cfbf bellard
    const struct usb_class_info *p;
1760 a594cfbf bellard
    for(p = usb_class_info; p->class != -1; p++) {
1761 2791104c David Ahern
        if (p->class == class) {
1762 a594cfbf bellard
            break;
1763 2791104c David Ahern
        }
1764 bb36d470 bellard
    }
1765 a594cfbf bellard
    return p->class_name;
1766 a594cfbf bellard
}
1767 a594cfbf bellard
1768 5557d820 Gerd Hoffmann
static void usb_info_device(Monitor *mon, int bus_num, int addr, char *port,
1769 5557d820 Gerd Hoffmann
                            int class_id, int vendor_id, int product_id,
1770 9596ebb7 pbrook
                            const char *product_name,
1771 9596ebb7 pbrook
                            int speed)
1772 a594cfbf bellard
{
1773 a594cfbf bellard
    const char *class_str, *speed_str;
1774 a594cfbf bellard
1775 a594cfbf bellard
    switch(speed) {
1776 5fafdf24 ths
    case USB_SPEED_LOW:
1777 5fafdf24 ths
        speed_str = "1.5";
1778 a594cfbf bellard
        break;
1779 5fafdf24 ths
    case USB_SPEED_FULL:
1780 5fafdf24 ths
        speed_str = "12";
1781 a594cfbf bellard
        break;
1782 5fafdf24 ths
    case USB_SPEED_HIGH:
1783 5fafdf24 ths
        speed_str = "480";
1784 a594cfbf bellard
        break;
1785 a594cfbf bellard
    default:
1786 5fafdf24 ths
        speed_str = "?";
1787 a594cfbf bellard
        break;
1788 a594cfbf bellard
    }
1789 a594cfbf bellard
1790 5557d820 Gerd Hoffmann
    monitor_printf(mon, "  Bus %d, Addr %d, Port %s, Speed %s Mb/s\n",
1791 5557d820 Gerd Hoffmann
                   bus_num, addr, port, speed_str);
1792 a594cfbf bellard
    class_str = usb_class_str(class_id);
1793 2791104c David Ahern
    if (class_str) {
1794 376253ec aliguori
        monitor_printf(mon, "    %s:", class_str);
1795 2791104c David Ahern
    } else {
1796 376253ec aliguori
        monitor_printf(mon, "    Class %02x:", class_id);
1797 2791104c David Ahern
    }
1798 376253ec aliguori
    monitor_printf(mon, " USB device %04x:%04x", vendor_id, product_id);
1799 2791104c David Ahern
    if (product_name[0] != '\0') {
1800 376253ec aliguori
        monitor_printf(mon, ", %s", product_name);
1801 2791104c David Ahern
    }
1802 376253ec aliguori
    monitor_printf(mon, "\n");
1803 a594cfbf bellard
}
1804 a594cfbf bellard
1805 5fafdf24 ths
static int usb_host_info_device(void *opaque, int bus_num, int addr,
1806 5557d820 Gerd Hoffmann
                                char *path, int class_id,
1807 5fafdf24 ths
                                int vendor_id, int product_id,
1808 a594cfbf bellard
                                const char *product_name,
1809 a594cfbf bellard
                                int speed)
1810 a594cfbf bellard
{
1811 179da8af Blue Swirl
    Monitor *mon = opaque;
1812 179da8af Blue Swirl
1813 5557d820 Gerd Hoffmann
    usb_info_device(mon, bus_num, addr, path, class_id, vendor_id, product_id,
1814 a594cfbf bellard
                    product_name, speed);
1815 a594cfbf bellard
    return 0;
1816 a594cfbf bellard
}
1817 a594cfbf bellard
1818 ac4ffb5a aliguori
static void dec2str(int val, char *str, size_t size)
1819 5d0c5750 aliguori
{
1820 2791104c David Ahern
    if (val == 0) {
1821 ac4ffb5a aliguori
        snprintf(str, size, "*");
1822 2791104c David Ahern
    } else {
1823 2791104c David Ahern
        snprintf(str, size, "%d", val);
1824 2791104c David Ahern
    }
1825 5d0c5750 aliguori
}
1826 5d0c5750 aliguori
1827 ac4ffb5a aliguori
static void hex2str(int val, char *str, size_t size)
1828 5d0c5750 aliguori
{
1829 2791104c David Ahern
    if (val == 0) {
1830 ac4ffb5a aliguori
        snprintf(str, size, "*");
1831 2791104c David Ahern
    } else {
1832 26a9e82a Gerd Hoffmann
        snprintf(str, size, "%04x", val);
1833 2791104c David Ahern
    }
1834 5d0c5750 aliguori
}
1835 5d0c5750 aliguori
1836 376253ec aliguori
void usb_host_info(Monitor *mon)
1837 a594cfbf bellard
{
1838 5d0c5750 aliguori
    struct USBAutoFilter *f;
1839 26a9e82a Gerd Hoffmann
    struct USBHostDevice *s;
1840 5d0c5750 aliguori
1841 179da8af Blue Swirl
    usb_host_scan(mon, usb_host_info_device);
1842 5d0c5750 aliguori
1843 2791104c David Ahern
    if (QTAILQ_EMPTY(&hostdevs)) {
1844 26a9e82a Gerd Hoffmann
        return;
1845 2791104c David Ahern
    }
1846 2791104c David Ahern
1847 26a9e82a Gerd Hoffmann
    monitor_printf(mon, "  Auto filters:\n");
1848 26a9e82a Gerd Hoffmann
    QTAILQ_FOREACH(s, &hostdevs, next) {
1849 5d0c5750 aliguori
        char bus[10], addr[10], vid[10], pid[10];
1850 26a9e82a Gerd Hoffmann
        f = &s->match;
1851 ac4ffb5a aliguori
        dec2str(f->bus_num, bus, sizeof(bus));
1852 ac4ffb5a aliguori
        dec2str(f->addr, addr, sizeof(addr));
1853 ac4ffb5a aliguori
        hex2str(f->vendor_id, vid, sizeof(vid));
1854 ac4ffb5a aliguori
        hex2str(f->product_id, pid, sizeof(pid));
1855 9056a297 Gerd Hoffmann
        monitor_printf(mon, "    Bus %s, Addr %s, Port %s, ID %s:%s\n",
1856 9056a297 Gerd Hoffmann
                       bus, addr, f->port ? f->port : "*", vid, pid);
1857 5d0c5750 aliguori
    }
1858 bb36d470 bellard
}