Statistics
| Branch: | Revision:

root / usb-linux.c @ ebd669a1

History | View | Annotate | Download (50.2 kB)

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

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