Statistics
| Branch: | Revision:

root / usb-linux.c @ 3991c35e

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

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