Statistics
| Branch: | Revision:

root / usb-linux.c @ 1f45a81b

History | View | Annotate | Download (51 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 61c1117f Hans de Goede
        fprintf(stderr, "husb: update iface failed. descr too short\n");
380 61c1117f Hans de Goede
        return 0;
381 2791104c David Ahern
    }
382 b9dc033c balrog
383 b9dc033c balrog
    i += dev_descr_len;
384 b9dc033c balrog
    while (i < dev->descr_len) {
385 2791104c David Ahern
        DPRINTF("husb: i is %d, descr_len is %d, dl %d, dt %d\n",
386 2791104c David Ahern
                i, dev->descr_len,
387 b9dc033c balrog
               dev->descr[i], dev->descr[i+1]);
388 64838171 aliguori
389 b9dc033c balrog
        if (dev->descr[i+1] != USB_DT_CONFIG) {
390 b9dc033c balrog
            i += dev->descr[i];
391 b9dc033c balrog
            continue;
392 b9dc033c balrog
        }
393 b9dc033c balrog
        config_descr_len = dev->descr[i];
394 b9dc033c balrog
395 2791104c David Ahern
        printf("husb: config #%d need %d\n", dev->descr[i + 5], configuration);
396 1f3870ab aliguori
397 446ab128 aliguori
        if (configuration < 0 || configuration == dev->descr[i + 5]) {
398 446ab128 aliguori
            configuration = dev->descr[i + 5];
399 b9dc033c balrog
            break;
400 446ab128 aliguori
        }
401 b9dc033c balrog
402 b9dc033c balrog
        i += config_descr_len;
403 b9dc033c balrog
    }
404 b9dc033c balrog
405 b9dc033c balrog
    if (i >= dev->descr_len) {
406 2791104c David Ahern
        fprintf(stderr,
407 2791104c David Ahern
                "husb: update iface failed. no matching configuration\n");
408 61c1117f Hans de Goede
        return 0;
409 b9dc033c balrog
    }
410 b9dc033c balrog
    nb_interfaces = dev->descr[i + 4];
411 b9dc033c balrog
412 b9dc033c balrog
#ifdef USBDEVFS_DISCONNECT
413 b9dc033c balrog
    /* earlier Linux 2.4 do not support that */
414 b9dc033c balrog
    {
415 b9dc033c balrog
        struct usbdevfs_ioctl ctrl;
416 b9dc033c balrog
        for (interface = 0; interface < nb_interfaces; interface++) {
417 b9dc033c balrog
            ctrl.ioctl_code = USBDEVFS_DISCONNECT;
418 b9dc033c balrog
            ctrl.ifno = interface;
419 021730f7 Brad Hards
            ctrl.data = 0;
420 41c01ee7 Gerd Hoffmann
            op = "USBDEVFS_DISCONNECT";
421 b9dc033c balrog
            ret = ioctl(dev->fd, USBDEVFS_IOCTL, &ctrl);
422 b9dc033c balrog
            if (ret < 0 && errno != ENODATA) {
423 b9dc033c balrog
                goto fail;
424 b9dc033c balrog
            }
425 b9dc033c balrog
        }
426 b9dc033c balrog
    }
427 b9dc033c balrog
#endif
428 b9dc033c balrog
429 b9dc033c balrog
    /* XXX: only grab if all interfaces are free */
430 b9dc033c balrog
    for (interface = 0; interface < nb_interfaces; interface++) {
431 41c01ee7 Gerd Hoffmann
        op = "USBDEVFS_CLAIMINTERFACE";
432 b9dc033c balrog
        ret = ioctl(dev->fd, USBDEVFS_CLAIMINTERFACE, &interface);
433 b9dc033c balrog
        if (ret < 0) {
434 b9dc033c balrog
            if (errno == EBUSY) {
435 64838171 aliguori
                printf("husb: update iface. device already grabbed\n");
436 b9dc033c balrog
            } else {
437 64838171 aliguori
                perror("husb: failed to claim interface");
438 b9dc033c balrog
            }
439 41c01ee7 Gerd Hoffmann
            goto fail;
440 b9dc033c balrog
        }
441 b9dc033c balrog
    }
442 b9dc033c balrog
443 64838171 aliguori
    printf("husb: %d interfaces claimed for configuration %d\n",
444 b9dc033c balrog
           nb_interfaces, configuration);
445 b9dc033c balrog
446 446ab128 aliguori
    dev->ninterfaces   = nb_interfaces;
447 446ab128 aliguori
    dev->configuration = configuration;
448 446ab128 aliguori
    return 1;
449 41c01ee7 Gerd Hoffmann
450 41c01ee7 Gerd Hoffmann
fail:
451 41c01ee7 Gerd Hoffmann
    if (errno == ENODEV) {
452 41c01ee7 Gerd Hoffmann
        do_disconnect(dev);
453 41c01ee7 Gerd Hoffmann
    }
454 41c01ee7 Gerd Hoffmann
    perror(op);
455 41c01ee7 Gerd Hoffmann
    return 0;
456 446ab128 aliguori
}
457 446ab128 aliguori
458 446ab128 aliguori
static int usb_host_release_interfaces(USBHostDevice *s)
459 446ab128 aliguori
{
460 446ab128 aliguori
    int ret, i;
461 446ab128 aliguori
462 d0f2c4c6 malc
    DPRINTF("husb: releasing interfaces\n");
463 446ab128 aliguori
464 446ab128 aliguori
    for (i = 0; i < s->ninterfaces; i++) {
465 446ab128 aliguori
        ret = ioctl(s->fd, USBDEVFS_RELEASEINTERFACE, &i);
466 446ab128 aliguori
        if (ret < 0) {
467 446ab128 aliguori
            perror("husb: failed to release interface");
468 446ab128 aliguori
            return 0;
469 446ab128 aliguori
        }
470 446ab128 aliguori
    }
471 446ab128 aliguori
472 b9dc033c balrog
    return 1;
473 b9dc033c balrog
}
474 b9dc033c balrog
475 059809e4 bellard
static void usb_host_handle_reset(USBDevice *dev)
476 bb36d470 bellard
{
477 26a9e82a Gerd Hoffmann
    USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
478 64838171 aliguori
479 d0f2c4c6 malc
    DPRINTF("husb: reset device %u.%u\n", s->bus_num, s->addr);
480 64838171 aliguori
481 bb36d470 bellard
    ioctl(s->fd, USBDEVFS_RESET);
482 446ab128 aliguori
483 446ab128 aliguori
    usb_host_claim_interfaces(s, s->configuration);
484 5fafdf24 ths
}
485 bb36d470 bellard
486 059809e4 bellard
static void usb_host_handle_destroy(USBDevice *dev)
487 059809e4 bellard
{
488 059809e4 bellard
    USBHostDevice *s = (USBHostDevice *)dev;
489 059809e4 bellard
490 26a9e82a Gerd Hoffmann
    usb_host_close(s);
491 26a9e82a Gerd Hoffmann
    QTAILQ_REMOVE(&hostdevs, s, next);
492 b373a63a Shahar Havivi
    qemu_remove_exit_notifier(&s->exit);
493 059809e4 bellard
}
494 059809e4 bellard
495 b9dc033c balrog
static int usb_linux_update_endp_table(USBHostDevice *s);
496 b9dc033c balrog
497 060dc841 Hans de Goede
/* iso data is special, we need to keep enough urbs in flight to make sure
498 060dc841 Hans de Goede
   that the controller never runs out of them, otherwise the device will
499 060dc841 Hans de Goede
   likely suffer a buffer underrun / overrun. */
500 060dc841 Hans de Goede
static AsyncURB *usb_host_alloc_iso(USBHostDevice *s, uint8_t ep, int in)
501 060dc841 Hans de Goede
{
502 060dc841 Hans de Goede
    AsyncURB *aurb;
503 060dc841 Hans de Goede
    int i, j, len = get_max_packet_size(s, ep);
504 060dc841 Hans de Goede
505 060dc841 Hans de Goede
    aurb = qemu_mallocz(ISO_URB_COUNT * sizeof(*aurb));
506 060dc841 Hans de Goede
    for (i = 0; i < ISO_URB_COUNT; i++) {
507 060dc841 Hans de Goede
        aurb[i].urb.endpoint      = ep;
508 060dc841 Hans de Goede
        aurb[i].urb.buffer_length = ISO_FRAME_DESC_PER_URB * len;
509 060dc841 Hans de Goede
        aurb[i].urb.buffer        = qemu_malloc(aurb[i].urb.buffer_length);
510 060dc841 Hans de Goede
        aurb[i].urb.type          = USBDEVFS_URB_TYPE_ISO;
511 060dc841 Hans de Goede
        aurb[i].urb.flags         = USBDEVFS_URB_ISO_ASAP;
512 060dc841 Hans de Goede
        aurb[i].urb.number_of_packets = ISO_FRAME_DESC_PER_URB;
513 060dc841 Hans de Goede
        for (j = 0 ; j < ISO_FRAME_DESC_PER_URB; j++)
514 060dc841 Hans de Goede
            aurb[i].urb.iso_frame_desc[j].length = len;
515 060dc841 Hans de Goede
        if (in) {
516 060dc841 Hans de Goede
            aurb[i].urb.endpoint |= 0x80;
517 060dc841 Hans de Goede
            /* Mark as fully consumed (idle) */
518 060dc841 Hans de Goede
            aurb[i].iso_frame_idx = ISO_FRAME_DESC_PER_URB;
519 060dc841 Hans de Goede
        }
520 060dc841 Hans de Goede
    }
521 060dc841 Hans de Goede
    set_iso_urb(s, ep, aurb);
522 060dc841 Hans de Goede
523 060dc841 Hans de Goede
    return aurb;
524 060dc841 Hans de Goede
}
525 060dc841 Hans de Goede
526 060dc841 Hans de Goede
static void usb_host_stop_n_free_iso(USBHostDevice *s, uint8_t ep)
527 060dc841 Hans de Goede
{
528 060dc841 Hans de Goede
    AsyncURB *aurb;
529 060dc841 Hans de Goede
    int i, ret, killed = 0, free = 1;
530 060dc841 Hans de Goede
531 060dc841 Hans de Goede
    aurb = get_iso_urb(s, ep);
532 060dc841 Hans de Goede
    if (!aurb) {
533 060dc841 Hans de Goede
        return;
534 060dc841 Hans de Goede
    }
535 060dc841 Hans de Goede
536 060dc841 Hans de Goede
    for (i = 0; i < ISO_URB_COUNT; i++) {
537 060dc841 Hans de Goede
        /* in flight? */
538 060dc841 Hans de Goede
        if (aurb[i].iso_frame_idx == -1) {
539 060dc841 Hans de Goede
            ret = ioctl(s->fd, USBDEVFS_DISCARDURB, &aurb[i]);
540 060dc841 Hans de Goede
            if (ret < 0) {
541 060dc841 Hans de Goede
                printf("husb: discard isoc in urb failed errno %d\n", errno);
542 060dc841 Hans de Goede
                free = 0;
543 060dc841 Hans de Goede
                continue;
544 060dc841 Hans de Goede
            }
545 060dc841 Hans de Goede
            killed++;
546 060dc841 Hans de Goede
        }
547 060dc841 Hans de Goede
    }
548 060dc841 Hans de Goede
549 060dc841 Hans de Goede
    /* Make sure any urbs we've killed are reaped before we free them */
550 060dc841 Hans de Goede
    if (killed) {
551 060dc841 Hans de Goede
        async_complete(s);
552 060dc841 Hans de Goede
    }
553 060dc841 Hans de Goede
554 060dc841 Hans de Goede
    for (i = 0; i < ISO_URB_COUNT; i++) {
555 060dc841 Hans de Goede
        qemu_free(aurb[i].urb.buffer);
556 060dc841 Hans de Goede
    }
557 060dc841 Hans de Goede
558 060dc841 Hans de Goede
    if (free)
559 060dc841 Hans de Goede
        qemu_free(aurb);
560 060dc841 Hans de Goede
    else
561 060dc841 Hans de Goede
        printf("husb: leaking iso urbs because of discard failure\n");
562 060dc841 Hans de Goede
    set_iso_urb(s, ep, NULL);
563 bb6d5498 Hans de Goede
    set_iso_urb_idx(s, ep, 0);
564 bb6d5498 Hans de Goede
    clear_iso_started(s, ep);
565 060dc841 Hans de Goede
}
566 060dc841 Hans de Goede
567 060dc841 Hans de Goede
static int urb_status_to_usb_ret(int status)
568 060dc841 Hans de Goede
{
569 060dc841 Hans de Goede
    switch (status) {
570 060dc841 Hans de Goede
    case -EPIPE:
571 060dc841 Hans de Goede
        return USB_RET_STALL;
572 060dc841 Hans de Goede
    default:
573 060dc841 Hans de Goede
        return USB_RET_NAK;
574 060dc841 Hans de Goede
    }
575 060dc841 Hans de Goede
}
576 060dc841 Hans de Goede
577 bb6d5498 Hans de Goede
static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in)
578 060dc841 Hans de Goede
{
579 060dc841 Hans de Goede
    AsyncURB *aurb;
580 bb6d5498 Hans de Goede
    int i, j, ret, max_packet_size, offset, len = 0;
581 975f2998 Hans de Goede
582 975f2998 Hans de Goede
    max_packet_size = get_max_packet_size(s, p->devep);
583 975f2998 Hans de Goede
    if (max_packet_size == 0)
584 975f2998 Hans de Goede
        return USB_RET_NAK;
585 060dc841 Hans de Goede
586 060dc841 Hans de Goede
    aurb = get_iso_urb(s, p->devep);
587 060dc841 Hans de Goede
    if (!aurb) {
588 bb6d5498 Hans de Goede
        aurb = usb_host_alloc_iso(s, p->devep, in);
589 060dc841 Hans de Goede
    }
590 060dc841 Hans de Goede
591 060dc841 Hans de Goede
    i = get_iso_urb_idx(s, p->devep);
592 060dc841 Hans de Goede
    j = aurb[i].iso_frame_idx;
593 060dc841 Hans de Goede
    if (j >= 0 && j < ISO_FRAME_DESC_PER_URB) {
594 bb6d5498 Hans de Goede
        if (in) {
595 bb6d5498 Hans de Goede
            /* Check urb status  */
596 bb6d5498 Hans de Goede
            if (aurb[i].urb.status) {
597 bb6d5498 Hans de Goede
                len = urb_status_to_usb_ret(aurb[i].urb.status);
598 bb6d5498 Hans de Goede
                /* Move to the next urb */
599 bb6d5498 Hans de Goede
                aurb[i].iso_frame_idx = ISO_FRAME_DESC_PER_URB - 1;
600 bb6d5498 Hans de Goede
            /* Check frame status */
601 bb6d5498 Hans de Goede
            } else if (aurb[i].urb.iso_frame_desc[j].status) {
602 bb6d5498 Hans de Goede
                len = urb_status_to_usb_ret(
603 bb6d5498 Hans de Goede
                                        aurb[i].urb.iso_frame_desc[j].status);
604 bb6d5498 Hans de Goede
            /* Check the frame fits */
605 bb6d5498 Hans de Goede
            } else if (aurb[i].urb.iso_frame_desc[j].actual_length > p->len) {
606 bb6d5498 Hans de Goede
                printf("husb: received iso data is larger then packet\n");
607 bb6d5498 Hans de Goede
                len = USB_RET_NAK;
608 bb6d5498 Hans de Goede
            /* All good copy data over */
609 bb6d5498 Hans de Goede
            } else {
610 bb6d5498 Hans de Goede
                len = aurb[i].urb.iso_frame_desc[j].actual_length;
611 bb6d5498 Hans de Goede
                memcpy(p->data,
612 bb6d5498 Hans de Goede
                       aurb[i].urb.buffer +
613 bb6d5498 Hans de Goede
                           j * aurb[i].urb.iso_frame_desc[0].length,
614 bb6d5498 Hans de Goede
                       len);
615 bb6d5498 Hans de Goede
            }
616 060dc841 Hans de Goede
        } else {
617 bb6d5498 Hans de Goede
            len = p->len;
618 bb6d5498 Hans de Goede
            offset = (j == 0) ? 0 : get_iso_buffer_used(s, p->devep);
619 bb6d5498 Hans de Goede
620 bb6d5498 Hans de Goede
            /* Check the frame fits */
621 bb6d5498 Hans de Goede
            if (len > max_packet_size) {
622 bb6d5498 Hans de Goede
                printf("husb: send iso data is larger then max packet size\n");
623 bb6d5498 Hans de Goede
                return USB_RET_NAK;
624 bb6d5498 Hans de Goede
            }
625 bb6d5498 Hans de Goede
626 bb6d5498 Hans de Goede
            /* All good copy data over */
627 bb6d5498 Hans de Goede
            memcpy(aurb[i].urb.buffer + offset, p->data, len);
628 bb6d5498 Hans de Goede
            aurb[i].urb.iso_frame_desc[j].length = len;
629 bb6d5498 Hans de Goede
            offset += len;
630 bb6d5498 Hans de Goede
            set_iso_buffer_used(s, p->devep, offset);
631 bb6d5498 Hans de Goede
632 bb6d5498 Hans de Goede
            /* Start the stream once we have buffered enough data */
633 bb6d5498 Hans de Goede
            if (!is_iso_started(s, p->devep) && i == 1 && j == 8) {
634 bb6d5498 Hans de Goede
                set_iso_started(s, p->devep);
635 bb6d5498 Hans de Goede
            }
636 060dc841 Hans de Goede
        }
637 060dc841 Hans de Goede
        aurb[i].iso_frame_idx++;
638 060dc841 Hans de Goede
        if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {
639 060dc841 Hans de Goede
            i = (i + 1) % ISO_URB_COUNT;
640 060dc841 Hans de Goede
            set_iso_urb_idx(s, p->devep, i);
641 060dc841 Hans de Goede
        }
642 bb6d5498 Hans de Goede
    } else {
643 bb6d5498 Hans de Goede
        if (in) {
644 bb6d5498 Hans de Goede
            set_iso_started(s, p->devep);
645 bb6d5498 Hans de Goede
        } else {
646 bb6d5498 Hans de Goede
            DPRINTF("hubs: iso out error no free buffer, dropping packet\n");
647 bb6d5498 Hans de Goede
        }
648 060dc841 Hans de Goede
    }
649 060dc841 Hans de Goede
650 bb6d5498 Hans de Goede
    if (is_iso_started(s, p->devep)) {
651 bb6d5498 Hans de Goede
        /* (Re)-submit all fully consumed / filled urbs */
652 bb6d5498 Hans de Goede
        for (i = 0; i < ISO_URB_COUNT; i++) {
653 bb6d5498 Hans de Goede
            if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {
654 bb6d5498 Hans de Goede
                ret = ioctl(s->fd, USBDEVFS_SUBMITURB, &aurb[i]);
655 bb6d5498 Hans de Goede
                if (ret < 0) {
656 bb6d5498 Hans de Goede
                    printf("husb error submitting iso urb %d: %d\n", i, errno);
657 bb6d5498 Hans de Goede
                    if (!in || len == 0) {
658 bb6d5498 Hans de Goede
                        switch(errno) {
659 bb6d5498 Hans de Goede
                        case ETIMEDOUT:
660 bb6d5498 Hans de Goede
                            len = USB_RET_NAK;
661 0225e254 Stefan Weil
                            break;
662 bb6d5498 Hans de Goede
                        case EPIPE:
663 bb6d5498 Hans de Goede
                        default:
664 bb6d5498 Hans de Goede
                            len = USB_RET_STALL;
665 bb6d5498 Hans de Goede
                        }
666 060dc841 Hans de Goede
                    }
667 bb6d5498 Hans de Goede
                    break;
668 060dc841 Hans de Goede
                }
669 bb6d5498 Hans de Goede
                aurb[i].iso_frame_idx = -1;
670 060dc841 Hans de Goede
            }
671 060dc841 Hans de Goede
        }
672 060dc841 Hans de Goede
    }
673 060dc841 Hans de Goede
674 060dc841 Hans de Goede
    return len;
675 060dc841 Hans de Goede
}
676 060dc841 Hans de Goede
677 50b7963e Hans de Goede
static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
678 bb36d470 bellard
{
679 50b7963e Hans de Goede
    USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
680 64838171 aliguori
    struct usbdevfs_urb *urb;
681 446ab128 aliguori
    AsyncURB *aurb;
682 71138531 Gerd Hoffmann
    int ret, rem;
683 71138531 Gerd Hoffmann
    uint8_t *pbuf;
684 060dc841 Hans de Goede
    uint8_t ep;
685 b9dc033c balrog
686 a0b5fece Hans de Goede
    if (!is_valid(s, p->devep)) {
687 a0b5fece Hans de Goede
        return USB_RET_NAK;
688 a0b5fece Hans de Goede
    }
689 a0b5fece Hans de Goede
690 2791104c David Ahern
    if (p->pid == USB_TOKEN_IN) {
691 060dc841 Hans de Goede
        ep = p->devep | 0x80;
692 2791104c David Ahern
    } else {
693 060dc841 Hans de Goede
        ep = p->devep;
694 2791104c David Ahern
    }
695 64838171 aliguori
696 64838171 aliguori
    if (is_halted(s, p->devep)) {
697 060dc841 Hans de Goede
        ret = ioctl(s->fd, USBDEVFS_CLEAR_HALT, &ep);
698 64838171 aliguori
        if (ret < 0) {
699 2791104c David Ahern
            DPRINTF("husb: failed to clear halt. ep 0x%x errno %d\n",
700 060dc841 Hans de Goede
                   ep, errno);
701 bb36d470 bellard
            return USB_RET_NAK;
702 bb36d470 bellard
        }
703 64838171 aliguori
        clear_halt(s, p->devep);
704 4d043a09 balrog
    }
705 4d043a09 balrog
706 bb6d5498 Hans de Goede
    if (is_isoc(s, p->devep)) {
707 bb6d5498 Hans de Goede
        return usb_host_handle_iso_data(s, p, p->pid == USB_TOKEN_IN);
708 bb6d5498 Hans de Goede
    }
709 060dc841 Hans de Goede
710 71138531 Gerd Hoffmann
    rem = p->len;
711 71138531 Gerd Hoffmann
    pbuf = p->data;
712 71138531 Gerd Hoffmann
    p->len = 0;
713 71138531 Gerd Hoffmann
    while (rem) {
714 71138531 Gerd Hoffmann
        aurb = async_alloc(s);
715 71138531 Gerd Hoffmann
        aurb->packet = p;
716 71138531 Gerd Hoffmann
717 71138531 Gerd Hoffmann
        urb = &aurb->urb;
718 71138531 Gerd Hoffmann
        urb->endpoint      = ep;
719 71138531 Gerd Hoffmann
        urb->type          = USBDEVFS_URB_TYPE_BULK;
720 71138531 Gerd Hoffmann
        urb->usercontext   = s;
721 71138531 Gerd Hoffmann
        urb->buffer        = pbuf;
722 71138531 Gerd Hoffmann
723 71138531 Gerd Hoffmann
        if (rem > MAX_USBFS_BUFFER_SIZE) {
724 71138531 Gerd Hoffmann
            urb->buffer_length = MAX_USBFS_BUFFER_SIZE;
725 71138531 Gerd Hoffmann
            aurb->more         = 1;
726 71138531 Gerd Hoffmann
        } else {
727 71138531 Gerd Hoffmann
            urb->buffer_length = rem;
728 71138531 Gerd Hoffmann
            aurb->more         = 0;
729 71138531 Gerd Hoffmann
        }
730 71138531 Gerd Hoffmann
        pbuf += urb->buffer_length;
731 71138531 Gerd Hoffmann
        rem  -= urb->buffer_length;
732 b9dc033c balrog
733 71138531 Gerd Hoffmann
        ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
734 b9dc033c balrog
735 71138531 Gerd Hoffmann
        DPRINTF("husb: data submit: ep 0x%x, len %u, more %d, packet %p, aurb %p\n",
736 71138531 Gerd Hoffmann
                urb->endpoint, urb->buffer_length, aurb->more, p, aurb);
737 b9dc033c balrog
738 71138531 Gerd Hoffmann
        if (ret < 0) {
739 71138531 Gerd Hoffmann
            DPRINTF("husb: submit failed. errno %d\n", errno);
740 71138531 Gerd Hoffmann
            async_free(aurb);
741 b9dc033c balrog
742 71138531 Gerd Hoffmann
            switch(errno) {
743 71138531 Gerd Hoffmann
            case ETIMEDOUT:
744 71138531 Gerd Hoffmann
                return USB_RET_NAK;
745 71138531 Gerd Hoffmann
            case EPIPE:
746 71138531 Gerd Hoffmann
            default:
747 71138531 Gerd Hoffmann
                return USB_RET_STALL;
748 71138531 Gerd Hoffmann
            }
749 b9dc033c balrog
        }
750 b9dc033c balrog
    }
751 64838171 aliguori
752 b9dc033c balrog
    return USB_RET_ASYNC;
753 b9dc033c balrog
}
754 b9dc033c balrog
755 446ab128 aliguori
static int ctrl_error(void)
756 446ab128 aliguori
{
757 2791104c David Ahern
    if (errno == ETIMEDOUT) {
758 446ab128 aliguori
        return USB_RET_NAK;
759 2791104c David Ahern
    } else {
760 446ab128 aliguori
        return USB_RET_STALL;
761 2791104c David Ahern
    }
762 446ab128 aliguori
}
763 446ab128 aliguori
764 446ab128 aliguori
static int usb_host_set_address(USBHostDevice *s, int addr)
765 446ab128 aliguori
{
766 d0f2c4c6 malc
    DPRINTF("husb: ctrl set addr %u\n", addr);
767 446ab128 aliguori
    s->dev.addr = addr;
768 446ab128 aliguori
    return 0;
769 446ab128 aliguori
}
770 446ab128 aliguori
771 446ab128 aliguori
static int usb_host_set_config(USBHostDevice *s, int config)
772 446ab128 aliguori
{
773 446ab128 aliguori
    usb_host_release_interfaces(s);
774 446ab128 aliguori
775 446ab128 aliguori
    int ret = ioctl(s->fd, USBDEVFS_SETCONFIGURATION, &config);
776 2791104c David Ahern
777 d0f2c4c6 malc
    DPRINTF("husb: ctrl set config %d ret %d errno %d\n", config, ret, errno);
778 2791104c David Ahern
779 2791104c David Ahern
    if (ret < 0) {
780 446ab128 aliguori
        return ctrl_error();
781 2791104c David Ahern
    }
782 446ab128 aliguori
    usb_host_claim_interfaces(s, config);
783 446ab128 aliguori
    return 0;
784 446ab128 aliguori
}
785 446ab128 aliguori
786 446ab128 aliguori
static int usb_host_set_interface(USBHostDevice *s, int iface, int alt)
787 446ab128 aliguori
{
788 446ab128 aliguori
    struct usbdevfs_setinterface si;
789 060dc841 Hans de Goede
    int i, ret;
790 060dc841 Hans de Goede
791 3a4854b3 Hans de Goede
    for (i = 1; i <= MAX_ENDPOINTS; i++) {
792 060dc841 Hans de Goede
        if (is_isoc(s, i)) {
793 060dc841 Hans de Goede
            usb_host_stop_n_free_iso(s, i);
794 060dc841 Hans de Goede
        }
795 060dc841 Hans de Goede
    }
796 446ab128 aliguori
797 446ab128 aliguori
    si.interface  = iface;
798 446ab128 aliguori
    si.altsetting = alt;
799 446ab128 aliguori
    ret = ioctl(s->fd, USBDEVFS_SETINTERFACE, &si);
800 446ab128 aliguori
801 2791104c David Ahern
    DPRINTF("husb: ctrl set iface %d altset %d ret %d errno %d\n",
802 2791104c David Ahern
            iface, alt, ret, errno);
803 2791104c David Ahern
804 2791104c David Ahern
    if (ret < 0) {
805 2791104c David Ahern
        return ctrl_error();
806 2791104c David Ahern
    }
807 446ab128 aliguori
    usb_linux_update_endp_table(s);
808 446ab128 aliguori
    return 0;
809 446ab128 aliguori
}
810 446ab128 aliguori
811 50b7963e Hans de Goede
static int usb_host_handle_control(USBDevice *dev, USBPacket *p,
812 50b7963e Hans de Goede
               int request, int value, int index, int length, uint8_t *data)
813 446ab128 aliguori
{
814 50b7963e Hans de Goede
    USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
815 446ab128 aliguori
    struct usbdevfs_urb *urb;
816 446ab128 aliguori
    AsyncURB *aurb;
817 50b7963e Hans de Goede
    int ret;
818 446ab128 aliguori
819 2791104c David Ahern
    /*
820 446ab128 aliguori
     * Process certain standard device requests.
821 446ab128 aliguori
     * These are infrequent and are processed synchronously.
822 446ab128 aliguori
     */
823 446ab128 aliguori
824 50b7963e Hans de Goede
    /* Note request is (bRequestType << 8) | bRequest */
825 d0f2c4c6 malc
    DPRINTF("husb: ctrl type 0x%x req 0x%x val 0x%x index %u len %u\n",
826 50b7963e Hans de Goede
            request >> 8, request & 0xff, value, index, length);
827 446ab128 aliguori
828 50b7963e Hans de Goede
    switch (request) {
829 50b7963e Hans de Goede
    case DeviceOutRequest | USB_REQ_SET_ADDRESS:
830 50b7963e Hans de Goede
        return usb_host_set_address(s, value);
831 446ab128 aliguori
832 50b7963e Hans de Goede
    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
833 50b7963e Hans de Goede
        return usb_host_set_config(s, value & 0xff);
834 446ab128 aliguori
835 50b7963e Hans de Goede
    case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
836 446ab128 aliguori
        return usb_host_set_interface(s, index, value);
837 2791104c David Ahern
    }
838 446ab128 aliguori
839 446ab128 aliguori
    /* The rest are asynchronous */
840 446ab128 aliguori
841 50b7963e Hans de Goede
    if (length > sizeof(dev->data_buf)) {
842 50b7963e Hans de Goede
        fprintf(stderr, "husb: ctrl buffer too small (%d > %zu)\n",
843 50b7963e Hans de Goede
                length, sizeof(dev->data_buf));
844 b2e3b6e9 malc
        return USB_RET_STALL;
845 c4c0e236 Jim Paris
    }
846 c4c0e236 Jim Paris
847 7a8fc83f Gerd Hoffmann
    aurb = async_alloc(s);
848 446ab128 aliguori
    aurb->packet = p;
849 446ab128 aliguori
850 2791104c David Ahern
    /*
851 446ab128 aliguori
     * Setup ctrl transfer.
852 446ab128 aliguori
     *
853 a0102082 Brad Hards
     * s->ctrl is laid out such that data buffer immediately follows
854 446ab128 aliguori
     * 'req' struct which is exactly what usbdevfs expects.
855 2791104c David Ahern
     */
856 446ab128 aliguori
    urb = &aurb->urb;
857 446ab128 aliguori
858 446ab128 aliguori
    urb->type     = USBDEVFS_URB_TYPE_CONTROL;
859 446ab128 aliguori
    urb->endpoint = p->devep;
860 446ab128 aliguori
861 50b7963e Hans de Goede
    urb->buffer        = &dev->setup_buf;
862 50b7963e Hans de Goede
    urb->buffer_length = length + 8;
863 446ab128 aliguori
864 446ab128 aliguori
    urb->usercontext = s;
865 446ab128 aliguori
866 446ab128 aliguori
    ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
867 446ab128 aliguori
868 d0f2c4c6 malc
    DPRINTF("husb: submit ctrl. len %u aurb %p\n", urb->buffer_length, aurb);
869 446ab128 aliguori
870 446ab128 aliguori
    if (ret < 0) {
871 d0f2c4c6 malc
        DPRINTF("husb: submit failed. errno %d\n", errno);
872 446ab128 aliguori
        async_free(aurb);
873 446ab128 aliguori
874 446ab128 aliguori
        switch(errno) {
875 446ab128 aliguori
        case ETIMEDOUT:
876 446ab128 aliguori
            return USB_RET_NAK;
877 446ab128 aliguori
        case EPIPE:
878 446ab128 aliguori
        default:
879 446ab128 aliguori
            return USB_RET_STALL;
880 446ab128 aliguori
        }
881 446ab128 aliguori
    }
882 446ab128 aliguori
883 446ab128 aliguori
    return USB_RET_ASYNC;
884 446ab128 aliguori
}
885 446ab128 aliguori
886 71d71bbd Hans de Goede
static int usb_linux_get_configuration(USBHostDevice *s)
887 b9dc033c balrog
{
888 71d71bbd Hans de Goede
    uint8_t configuration;
889 e41b3910 pbrook
    struct usb_ctrltransfer ct;
890 71d71bbd Hans de Goede
    int ret;
891 b9dc033c balrog
892 2cc59d8c Hans de Goede
    if (usb_fs_type == USB_FS_SYS) {
893 2cc59d8c Hans de Goede
        char device_name[32], line[1024];
894 2cc59d8c Hans de Goede
        int configuration;
895 2cc59d8c Hans de Goede
896 5557d820 Gerd Hoffmann
        sprintf(device_name, "%d-%s", s->bus_num, s->port);
897 2cc59d8c Hans de Goede
898 2cc59d8c Hans de Goede
        if (!usb_host_read_file(line, sizeof(line), "bConfigurationValue",
899 2cc59d8c Hans de Goede
                                device_name)) {
900 2cc59d8c Hans de Goede
            goto usbdevfs;
901 2cc59d8c Hans de Goede
        }
902 2cc59d8c Hans de Goede
        if (sscanf(line, "%d", &configuration) != 1) {
903 2cc59d8c Hans de Goede
            goto usbdevfs;
904 2cc59d8c Hans de Goede
        }
905 2cc59d8c Hans de Goede
        return configuration;
906 2cc59d8c Hans de Goede
    }
907 2cc59d8c Hans de Goede
908 2cc59d8c Hans de Goede
usbdevfs:
909 b9dc033c balrog
    ct.bRequestType = USB_DIR_IN;
910 b9dc033c balrog
    ct.bRequest = USB_REQ_GET_CONFIGURATION;
911 b9dc033c balrog
    ct.wValue = 0;
912 b9dc033c balrog
    ct.wIndex = 0;
913 b9dc033c balrog
    ct.wLength = 1;
914 b9dc033c balrog
    ct.data = &configuration;
915 b9dc033c balrog
    ct.timeout = 50;
916 b9dc033c balrog
917 b9dc033c balrog
    ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
918 b9dc033c balrog
    if (ret < 0) {
919 71d71bbd Hans de Goede
        perror("usb_linux_get_configuration");
920 71d71bbd Hans de Goede
        return -1;
921 b9dc033c balrog
    }
922 b9dc033c balrog
923 b9dc033c balrog
    /* in address state */
924 2791104c David Ahern
    if (configuration == 0) {
925 71d71bbd Hans de Goede
        return -1;
926 2791104c David Ahern
    }
927 b9dc033c balrog
928 71d71bbd Hans de Goede
    return configuration;
929 71d71bbd Hans de Goede
}
930 71d71bbd Hans de Goede
931 ed3a328d Hans de Goede
static uint8_t usb_linux_get_alt_setting(USBHostDevice *s,
932 ed3a328d Hans de Goede
    uint8_t configuration, uint8_t interface)
933 ed3a328d Hans de Goede
{
934 ed3a328d Hans de Goede
    uint8_t alt_setting;
935 ed3a328d Hans de Goede
    struct usb_ctrltransfer ct;
936 ed3a328d Hans de Goede
    int ret;
937 ed3a328d Hans de Goede
938 c43831fb Hans de Goede
    if (usb_fs_type == USB_FS_SYS) {
939 c43831fb Hans de Goede
        char device_name[64], line[1024];
940 c43831fb Hans de Goede
        int alt_setting;
941 c43831fb Hans de Goede
942 5557d820 Gerd Hoffmann
        sprintf(device_name, "%d-%s:%d.%d", s->bus_num, s->port,
943 c43831fb Hans de Goede
                (int)configuration, (int)interface);
944 c43831fb Hans de Goede
945 c43831fb Hans de Goede
        if (!usb_host_read_file(line, sizeof(line), "bAlternateSetting",
946 c43831fb Hans de Goede
                                device_name)) {
947 c43831fb Hans de Goede
            goto usbdevfs;
948 c43831fb Hans de Goede
        }
949 c43831fb Hans de Goede
        if (sscanf(line, "%d", &alt_setting) != 1) {
950 c43831fb Hans de Goede
            goto usbdevfs;
951 c43831fb Hans de Goede
        }
952 c43831fb Hans de Goede
        return alt_setting;
953 c43831fb Hans de Goede
    }
954 c43831fb Hans de Goede
955 c43831fb Hans de Goede
usbdevfs:
956 ed3a328d Hans de Goede
    ct.bRequestType = USB_DIR_IN | USB_RECIP_INTERFACE;
957 ed3a328d Hans de Goede
    ct.bRequest = USB_REQ_GET_INTERFACE;
958 ed3a328d Hans de Goede
    ct.wValue = 0;
959 ed3a328d Hans de Goede
    ct.wIndex = interface;
960 ed3a328d Hans de Goede
    ct.wLength = 1;
961 ed3a328d Hans de Goede
    ct.data = &alt_setting;
962 ed3a328d Hans de Goede
    ct.timeout = 50;
963 ed3a328d Hans de Goede
    ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
964 ed3a328d Hans de Goede
    if (ret < 0) {
965 ed3a328d Hans de Goede
        /* Assume alt 0 on error */
966 ed3a328d Hans de Goede
        return 0;
967 ed3a328d Hans de Goede
    }
968 ed3a328d Hans de Goede
969 ed3a328d Hans de Goede
    return alt_setting;
970 ed3a328d Hans de Goede
}
971 ed3a328d Hans de Goede
972 71d71bbd Hans de Goede
/* returns 1 on problem encountered or 0 for success */
973 71d71bbd Hans de Goede
static int usb_linux_update_endp_table(USBHostDevice *s)
974 71d71bbd Hans de Goede
{
975 71d71bbd Hans de Goede
    uint8_t *descriptors;
976 71d71bbd Hans de Goede
    uint8_t devep, type, configuration, alt_interface;
977 ed3a328d Hans de Goede
    int interface, length, i;
978 71d71bbd Hans de Goede
979 a0b5fece Hans de Goede
    for (i = 0; i < MAX_ENDPOINTS; i++)
980 a0b5fece Hans de Goede
        s->endp_table[i].type = INVALID_EP_TYPE;
981 a0b5fece Hans de Goede
982 71d71bbd Hans de Goede
    i = usb_linux_get_configuration(s);
983 71d71bbd Hans de Goede
    if (i < 0)
984 71d71bbd Hans de Goede
        return 1;
985 71d71bbd Hans de Goede
    configuration = i;
986 71d71bbd Hans de Goede
987 b9dc033c balrog
    /* get the desired configuration, interface, and endpoint descriptors
988 b9dc033c balrog
     * from device description */
989 b9dc033c balrog
    descriptors = &s->descr[18];
990 b9dc033c balrog
    length = s->descr_len - 18;
991 b9dc033c balrog
    i = 0;
992 b9dc033c balrog
993 b9dc033c balrog
    if (descriptors[i + 1] != USB_DT_CONFIG ||
994 b9dc033c balrog
        descriptors[i + 5] != configuration) {
995 d0f2c4c6 malc
        DPRINTF("invalid descriptor data - configuration\n");
996 b9dc033c balrog
        return 1;
997 b9dc033c balrog
    }
998 b9dc033c balrog
    i += descriptors[i];
999 b9dc033c balrog
1000 b9dc033c balrog
    while (i < length) {
1001 b9dc033c balrog
        if (descriptors[i + 1] != USB_DT_INTERFACE ||
1002 b9dc033c balrog
            (descriptors[i + 1] == USB_DT_INTERFACE &&
1003 b9dc033c balrog
             descriptors[i + 4] == 0)) {
1004 b9dc033c balrog
            i += descriptors[i];
1005 b9dc033c balrog
            continue;
1006 b9dc033c balrog
        }
1007 b9dc033c balrog
1008 b9dc033c balrog
        interface = descriptors[i + 2];
1009 ed3a328d Hans de Goede
        alt_interface = usb_linux_get_alt_setting(s, configuration, interface);
1010 b9dc033c balrog
1011 b9dc033c balrog
        /* the current interface descriptor is the active interface
1012 b9dc033c balrog
         * and has endpoints */
1013 b9dc033c balrog
        if (descriptors[i + 3] != alt_interface) {
1014 b9dc033c balrog
            i += descriptors[i];
1015 b9dc033c balrog
            continue;
1016 b9dc033c balrog
        }
1017 b9dc033c balrog
1018 b9dc033c balrog
        /* advance to the endpoints */
1019 2791104c David Ahern
        while (i < length && descriptors[i +1] != USB_DT_ENDPOINT) {
1020 b9dc033c balrog
            i += descriptors[i];
1021 2791104c David Ahern
        }
1022 b9dc033c balrog
1023 b9dc033c balrog
        if (i >= length)
1024 b9dc033c balrog
            break;
1025 b9dc033c balrog
1026 b9dc033c balrog
        while (i < length) {
1027 2791104c David Ahern
            if (descriptors[i + 1] != USB_DT_ENDPOINT) {
1028 b9dc033c balrog
                break;
1029 2791104c David Ahern
            }
1030 b9dc033c balrog
1031 b9dc033c balrog
            devep = descriptors[i + 2];
1032 130314f8 Hans de Goede
            if ((devep & 0x0f) == 0) {
1033 130314f8 Hans de Goede
                fprintf(stderr, "usb-linux: invalid ep descriptor, ep == 0\n");
1034 130314f8 Hans de Goede
                return 1;
1035 130314f8 Hans de Goede
            }
1036 130314f8 Hans de Goede
1037 b9dc033c balrog
            switch (descriptors[i + 3] & 0x3) {
1038 b9dc033c balrog
            case 0x00:
1039 b9dc033c balrog
                type = USBDEVFS_URB_TYPE_CONTROL;
1040 b9dc033c balrog
                break;
1041 b9dc033c balrog
            case 0x01:
1042 b9dc033c balrog
                type = USBDEVFS_URB_TYPE_ISO;
1043 6dfcdccb Gerd Hoffmann
                set_max_packet_size(s, (devep & 0xf), descriptors + i);
1044 b9dc033c balrog
                break;
1045 b9dc033c balrog
            case 0x02:
1046 b9dc033c balrog
                type = USBDEVFS_URB_TYPE_BULK;
1047 b9dc033c balrog
                break;
1048 b9dc033c balrog
            case 0x03:
1049 b9dc033c balrog
                type = USBDEVFS_URB_TYPE_INTERRUPT;
1050 b9dc033c balrog
                break;
1051 ddbda432 Anthony Liguori
            default:
1052 ddbda432 Anthony Liguori
                DPRINTF("usb_host: malformed endpoint type\n");
1053 ddbda432 Anthony Liguori
                type = USBDEVFS_URB_TYPE_BULK;
1054 b9dc033c balrog
            }
1055 b9dc033c balrog
            s->endp_table[(devep & 0xf) - 1].type = type;
1056 64838171 aliguori
            s->endp_table[(devep & 0xf) - 1].halted = 0;
1057 b9dc033c balrog
1058 b9dc033c balrog
            i += descriptors[i];
1059 b9dc033c balrog
        }
1060 b9dc033c balrog
    }
1061 b9dc033c balrog
    return 0;
1062 b9dc033c balrog
}
1063 b9dc033c balrog
1064 26a9e82a Gerd Hoffmann
static int usb_host_open(USBHostDevice *dev, int bus_num,
1065 3991c35e Hans de Goede
                        int addr, char *port, const char *prod_name, int speed)
1066 bb36d470 bellard
{
1067 b9dc033c balrog
    int fd = -1, ret;
1068 a594cfbf bellard
    char buf[1024];
1069 1f3870ab aliguori
1070 2791104c David Ahern
    if (dev->fd != -1) {
1071 26a9e82a Gerd Hoffmann
        goto fail;
1072 2791104c David Ahern
    }
1073 64838171 aliguori
    printf("husb: open device %d.%d\n", bus_num, addr);
1074 3b46e624 ths
1075 0f431527 aliguori
    if (!usb_host_device_path) {
1076 0f431527 aliguori
        perror("husb: USB Host Device Path not set");
1077 0f431527 aliguori
        goto fail;
1078 0f431527 aliguori
    }
1079 0f431527 aliguori
    snprintf(buf, sizeof(buf), "%s/%03d/%03d", usb_host_device_path,
1080 a594cfbf bellard
             bus_num, addr);
1081 b9dc033c balrog
    fd = open(buf, O_RDWR | O_NONBLOCK);
1082 bb36d470 bellard
    if (fd < 0) {
1083 a594cfbf bellard
        perror(buf);
1084 1f3870ab aliguori
        goto fail;
1085 bb36d470 bellard
    }
1086 d0f2c4c6 malc
    DPRINTF("husb: opened %s\n", buf);
1087 bb36d470 bellard
1088 806b6024 Gerd Hoffmann
    dev->bus_num = bus_num;
1089 806b6024 Gerd Hoffmann
    dev->addr = addr;
1090 5557d820 Gerd Hoffmann
    strcpy(dev->port, port);
1091 22f84e73 Gerd Hoffmann
    dev->fd = fd;
1092 806b6024 Gerd Hoffmann
1093 b9dc033c balrog
    /* read the device description */
1094 b9dc033c balrog
    dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
1095 b9dc033c balrog
    if (dev->descr_len <= 0) {
1096 64838171 aliguori
        perror("husb: reading device data failed");
1097 bb36d470 bellard
        goto fail;
1098 bb36d470 bellard
    }
1099 3b46e624 ths
1100 b9dc033c balrog
#ifdef DEBUG
1101 868bfe2b bellard
    {
1102 b9dc033c balrog
        int x;
1103 b9dc033c balrog
        printf("=== begin dumping device descriptor data ===\n");
1104 2791104c David Ahern
        for (x = 0; x < dev->descr_len; x++) {
1105 b9dc033c balrog
            printf("%02x ", dev->descr[x]);
1106 2791104c David Ahern
        }
1107 b9dc033c balrog
        printf("\n=== end dumping device descriptor data ===\n");
1108 bb36d470 bellard
    }
1109 a594cfbf bellard
#endif
1110 a594cfbf bellard
1111 b9dc033c balrog
1112 2791104c David Ahern
    /*
1113 2791104c David Ahern
     * Initial configuration is -1 which makes us claim first
1114 446ab128 aliguori
     * available config. We used to start with 1, which does not
1115 2791104c David Ahern
     * always work. I've seen devices where first config starts
1116 446ab128 aliguori
     * with 2.
1117 446ab128 aliguori
     */
1118 2791104c David Ahern
    if (!usb_host_claim_interfaces(dev, -1)) {
1119 b9dc033c balrog
        goto fail;
1120 2791104c David Ahern
    }
1121 bb36d470 bellard
1122 b9dc033c balrog
    ret = usb_linux_update_endp_table(dev);
1123 2791104c David Ahern
    if (ret) {
1124 bb36d470 bellard
        goto fail;
1125 2791104c David Ahern
    }
1126 b9dc033c balrog
1127 3991c35e Hans de Goede
    if (speed == -1) {
1128 3991c35e Hans de Goede
        struct usbdevfs_connectinfo ci;
1129 3991c35e Hans de Goede
1130 3991c35e Hans de Goede
        ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
1131 3991c35e Hans de Goede
        if (ret < 0) {
1132 3991c35e Hans de Goede
            perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
1133 3991c35e Hans de Goede
            goto fail;
1134 3991c35e Hans de Goede
        }
1135 3991c35e Hans de Goede
1136 3991c35e Hans de Goede
        if (ci.slow) {
1137 3991c35e Hans de Goede
            speed = USB_SPEED_LOW;
1138 3991c35e Hans de Goede
        } else {
1139 3991c35e Hans de Goede
            speed = USB_SPEED_HIGH;
1140 3991c35e Hans de Goede
        }
1141 2791104c David Ahern
    }
1142 3991c35e Hans de Goede
    dev->dev.speed = speed;
1143 3991c35e Hans de Goede
1144 3991c35e Hans de Goede
    printf("husb: grabbed usb device %d.%d\n", bus_num, addr);
1145 bb36d470 bellard
1146 2791104c David Ahern
    if (!prod_name || prod_name[0] == '\0') {
1147 0fe6d12e Markus Armbruster
        snprintf(dev->dev.product_desc, sizeof(dev->dev.product_desc),
1148 4b096fc9 aliguori
                 "host:%d.%d", bus_num, addr);
1149 2791104c David Ahern
    } else {
1150 0fe6d12e Markus Armbruster
        pstrcpy(dev->dev.product_desc, sizeof(dev->dev.product_desc),
1151 4b096fc9 aliguori
                prod_name);
1152 2791104c David Ahern
    }
1153 1f6e24e7 bellard
1154 64838171 aliguori
    /* USB devio uses 'write' flag to check for async completions */
1155 64838171 aliguori
    qemu_set_fd_handler(dev->fd, NULL, async_complete, dev);
1156 1f3870ab aliguori
1157 26a9e82a Gerd Hoffmann
    usb_device_attach(&dev->dev);
1158 26a9e82a Gerd Hoffmann
    return 0;
1159 4b096fc9 aliguori
1160 b9dc033c balrog
fail:
1161 1f45a81b Gerd Hoffmann
    if (dev->fd != -1) {
1162 1f45a81b Gerd Hoffmann
        close(dev->fd);
1163 1f45a81b Gerd Hoffmann
        dev->fd = -1;
1164 2791104c David Ahern
    }
1165 26a9e82a Gerd Hoffmann
    return -1;
1166 26a9e82a Gerd Hoffmann
}
1167 26a9e82a Gerd Hoffmann
1168 26a9e82a Gerd Hoffmann
static int usb_host_close(USBHostDevice *dev)
1169 26a9e82a Gerd Hoffmann
{
1170 060dc841 Hans de Goede
    int i;
1171 060dc841 Hans de Goede
1172 1f45a81b Gerd Hoffmann
    if (dev->fd == -1 || !dev->dev.attached) {
1173 26a9e82a Gerd Hoffmann
        return -1;
1174 2791104c David Ahern
    }
1175 26a9e82a Gerd Hoffmann
1176 26a9e82a Gerd Hoffmann
    qemu_set_fd_handler(dev->fd, NULL, NULL, NULL);
1177 26a9e82a Gerd Hoffmann
    dev->closing = 1;
1178 3a4854b3 Hans de Goede
    for (i = 1; i <= MAX_ENDPOINTS; i++) {
1179 060dc841 Hans de Goede
        if (is_isoc(dev, i)) {
1180 060dc841 Hans de Goede
            usb_host_stop_n_free_iso(dev, i);
1181 060dc841 Hans de Goede
        }
1182 060dc841 Hans de Goede
    }
1183 26a9e82a Gerd Hoffmann
    async_complete(dev);
1184 26a9e82a Gerd Hoffmann
    dev->closing = 0;
1185 26a9e82a Gerd Hoffmann
    usb_device_detach(&dev->dev);
1186 00ff227a Shahar Havivi
    ioctl(dev->fd, USBDEVFS_RESET);
1187 26a9e82a Gerd Hoffmann
    close(dev->fd);
1188 26a9e82a Gerd Hoffmann
    dev->fd = -1;
1189 26a9e82a Gerd Hoffmann
    return 0;
1190 26a9e82a Gerd Hoffmann
}
1191 26a9e82a Gerd Hoffmann
1192 b373a63a Shahar Havivi
static void usb_host_exit_notifier(struct Notifier* n)
1193 b373a63a Shahar Havivi
{
1194 b373a63a Shahar Havivi
    USBHostDevice *s = container_of(n, USBHostDevice, exit);
1195 b373a63a Shahar Havivi
1196 b373a63a Shahar Havivi
    if (s->fd != -1) {
1197 b373a63a Shahar Havivi
        ioctl(s->fd, USBDEVFS_RESET);
1198 b373a63a Shahar Havivi
    }
1199 b373a63a Shahar Havivi
}
1200 b373a63a Shahar Havivi
1201 26a9e82a Gerd Hoffmann
static int usb_host_initfn(USBDevice *dev)
1202 26a9e82a Gerd Hoffmann
{
1203 26a9e82a Gerd Hoffmann
    USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
1204 26a9e82a Gerd Hoffmann
1205 26a9e82a Gerd Hoffmann
    dev->auto_attach = 0;
1206 26a9e82a Gerd Hoffmann
    s->fd = -1;
1207 26a9e82a Gerd Hoffmann
    QTAILQ_INSERT_TAIL(&hostdevs, s, next);
1208 b373a63a Shahar Havivi
    s->exit.notify = usb_host_exit_notifier;
1209 b373a63a Shahar Havivi
    qemu_add_exit_notifier(&s->exit);
1210 26a9e82a Gerd Hoffmann
    usb_host_auto_check(NULL);
1211 26a9e82a Gerd Hoffmann
    return 0;
1212 a594cfbf bellard
}
1213 bb36d470 bellard
1214 806b6024 Gerd Hoffmann
static struct USBDeviceInfo usb_host_dev_info = {
1215 06384698 Markus Armbruster
    .product_desc   = "USB Host Device",
1216 556cd098 Markus Armbruster
    .qdev.name      = "usb-host",
1217 806b6024 Gerd Hoffmann
    .qdev.size      = sizeof(USBHostDevice),
1218 806b6024 Gerd Hoffmann
    .init           = usb_host_initfn,
1219 50b7963e Hans de Goede
    .handle_packet  = usb_generic_handle_packet,
1220 eb5e680a Gerd Hoffmann
    .cancel_packet  = usb_host_async_cancel,
1221 50b7963e Hans de Goede
    .handle_data    = usb_host_handle_data,
1222 50b7963e Hans de Goede
    .handle_control = usb_host_handle_control,
1223 806b6024 Gerd Hoffmann
    .handle_reset   = usb_host_handle_reset,
1224 806b6024 Gerd Hoffmann
    .handle_destroy = usb_host_handle_destroy,
1225 26a9e82a Gerd Hoffmann
    .usbdevice_name = "host",
1226 26a9e82a Gerd Hoffmann
    .usbdevice_init = usb_host_device_open,
1227 26a9e82a Gerd Hoffmann
    .qdev.props     = (Property[]) {
1228 26a9e82a Gerd Hoffmann
        DEFINE_PROP_UINT32("hostbus",  USBHostDevice, match.bus_num,    0),
1229 26a9e82a Gerd Hoffmann
        DEFINE_PROP_UINT32("hostaddr", USBHostDevice, match.addr,       0),
1230 9056a297 Gerd Hoffmann
        DEFINE_PROP_STRING("hostport", USBHostDevice, match.port),
1231 26a9e82a Gerd Hoffmann
        DEFINE_PROP_HEX32("vendorid",  USBHostDevice, match.vendor_id,  0),
1232 26a9e82a Gerd Hoffmann
        DEFINE_PROP_HEX32("productid", USBHostDevice, match.product_id, 0),
1233 26a9e82a Gerd Hoffmann
        DEFINE_PROP_END_OF_LIST(),
1234 26a9e82a Gerd Hoffmann
    },
1235 806b6024 Gerd Hoffmann
};
1236 806b6024 Gerd Hoffmann
1237 806b6024 Gerd Hoffmann
static void usb_host_register_devices(void)
1238 806b6024 Gerd Hoffmann
{
1239 806b6024 Gerd Hoffmann
    usb_qdev_register(&usb_host_dev_info);
1240 806b6024 Gerd Hoffmann
}
1241 806b6024 Gerd Hoffmann
device_init(usb_host_register_devices)
1242 806b6024 Gerd Hoffmann
1243 4b096fc9 aliguori
USBDevice *usb_host_device_open(const char *devname)
1244 4b096fc9 aliguori
{
1245 0745eb1e Markus Armbruster
    struct USBAutoFilter filter;
1246 26a9e82a Gerd Hoffmann
    USBDevice *dev;
1247 26a9e82a Gerd Hoffmann
    char *p;
1248 26a9e82a Gerd Hoffmann
1249 556cd098 Markus Armbruster
    dev = usb_create(NULL /* FIXME */, "usb-host");
1250 4b096fc9 aliguori
1251 5d0c5750 aliguori
    if (strstr(devname, "auto:")) {
1252 2791104c David Ahern
        if (parse_filter(devname, &filter) < 0) {
1253 26a9e82a Gerd Hoffmann
            goto fail;
1254 2791104c David Ahern
        }
1255 26a9e82a Gerd Hoffmann
    } else {
1256 26a9e82a Gerd Hoffmann
        if ((p = strchr(devname, '.'))) {
1257 0745eb1e Markus Armbruster
            filter.bus_num    = strtoul(devname, NULL, 0);
1258 0745eb1e Markus Armbruster
            filter.addr       = strtoul(p + 1, NULL, 0);
1259 0745eb1e Markus Armbruster
            filter.vendor_id  = 0;
1260 0745eb1e Markus Armbruster
            filter.product_id = 0;
1261 26a9e82a Gerd Hoffmann
        } else if ((p = strchr(devname, ':'))) {
1262 0745eb1e Markus Armbruster
            filter.bus_num    = 0;
1263 0745eb1e Markus Armbruster
            filter.addr       = 0;
1264 26a9e82a Gerd Hoffmann
            filter.vendor_id  = strtoul(devname, NULL, 16);
1265 0745eb1e Markus Armbruster
            filter.product_id = strtoul(p + 1, NULL, 16);
1266 26a9e82a Gerd Hoffmann
        } else {
1267 26a9e82a Gerd Hoffmann
            goto fail;
1268 26a9e82a Gerd Hoffmann
        }
1269 5d0c5750 aliguori
    }
1270 4b096fc9 aliguori
1271 0745eb1e Markus Armbruster
    qdev_prop_set_uint32(&dev->qdev, "hostbus",   filter.bus_num);
1272 0745eb1e Markus Armbruster
    qdev_prop_set_uint32(&dev->qdev, "hostaddr",  filter.addr);
1273 26a9e82a Gerd Hoffmann
    qdev_prop_set_uint32(&dev->qdev, "vendorid",  filter.vendor_id);
1274 26a9e82a Gerd Hoffmann
    qdev_prop_set_uint32(&dev->qdev, "productid", filter.product_id);
1275 beb6f0de Kevin Wolf
    qdev_init_nofail(&dev->qdev);
1276 26a9e82a Gerd Hoffmann
    return dev;
1277 5d0c5750 aliguori
1278 26a9e82a Gerd Hoffmann
fail:
1279 26a9e82a Gerd Hoffmann
    qdev_free(&dev->qdev);
1280 26a9e82a Gerd Hoffmann
    return NULL;
1281 4b096fc9 aliguori
}
1282 5d0c5750 aliguori
1283 5d0c5750 aliguori
int usb_host_device_close(const char *devname)
1284 5d0c5750 aliguori
{
1285 26a9e82a Gerd Hoffmann
#if 0
1286 5d0c5750 aliguori
    char product_name[PRODUCT_NAME_SZ];
1287 5d0c5750 aliguori
    int bus_num, addr;
1288 5d0c5750 aliguori
    USBHostDevice *s;
1289 5d0c5750 aliguori

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