Statistics
| Branch: | Revision:

root / usb-linux.c @ 50b7963e

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

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