Statistics
| Branch: | Revision:

root / usb-linux.c @ bc59d9c9

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

1440 2791104c David Ahern
    if (strstr(devname, "auto:")) {
1441 5d0c5750 aliguori
        return usb_host_auto_del(devname);
1442 2791104c David Ahern
    }
1443 2791104c David Ahern
    if (usb_host_find_device(&bus_num, &addr, product_name,
1444 2791104c David Ahern
                                    sizeof(product_name), devname) < 0) {
1445 5d0c5750 aliguori
        return -1;
1446 2791104c David Ahern
    }
1447 5d0c5750 aliguori
    s = hostdev_find(bus_num, addr);
1448 5d0c5750 aliguori
    if (s) {
1449 a5d2f727 Gerd Hoffmann
        usb_device_delete_addr(s->bus_num, s->dev.addr);
1450 5d0c5750 aliguori
        return 0;
1451 5d0c5750 aliguori
    }
1452 26a9e82a Gerd Hoffmann
#endif
1453 5d0c5750 aliguori
1454 5d0c5750 aliguori
    return -1;
1455 5d0c5750 aliguori
}
1456 a5d2f727 Gerd Hoffmann
1457 a594cfbf bellard
static int get_tag_value(char *buf, int buf_size,
1458 5fafdf24 ths
                         const char *str, const char *tag,
1459 a594cfbf bellard
                         const char *stopchars)
1460 a594cfbf bellard
{
1461 a594cfbf bellard
    const char *p;
1462 a594cfbf bellard
    char *q;
1463 a594cfbf bellard
    p = strstr(str, tag);
1464 2791104c David Ahern
    if (!p) {
1465 a594cfbf bellard
        return -1;
1466 2791104c David Ahern
    }
1467 a594cfbf bellard
    p += strlen(tag);
1468 2791104c David Ahern
    while (qemu_isspace(*p)) {
1469 a594cfbf bellard
        p++;
1470 2791104c David Ahern
    }
1471 a594cfbf bellard
    q = buf;
1472 a594cfbf bellard
    while (*p != '\0' && !strchr(stopchars, *p)) {
1473 2791104c David Ahern
        if ((q - buf) < (buf_size - 1)) {
1474 a594cfbf bellard
            *q++ = *p;
1475 2791104c David Ahern
        }
1476 a594cfbf bellard
        p++;
1477 a594cfbf bellard
    }
1478 a594cfbf bellard
    *q = '\0';
1479 a594cfbf bellard
    return q - buf;
1480 bb36d470 bellard
}
1481 bb36d470 bellard
1482 0f431527 aliguori
/*
1483 0f431527 aliguori
 * Use /proc/bus/usb/devices or /dev/bus/usb/devices file to determine
1484 0f431527 aliguori
 * host's USB devices. This is legacy support since many distributions
1485 0f431527 aliguori
 * are moving to /sys/bus/usb
1486 0f431527 aliguori
 */
1487 0f431527 aliguori
static int usb_host_scan_dev(void *opaque, USBScanFunc *func)
1488 bb36d470 bellard
{
1489 660f11be Blue Swirl
    FILE *f = NULL;
1490 a594cfbf bellard
    char line[1024];
1491 bb36d470 bellard
    char buf[1024];
1492 0c402e5a Gerd Hoffmann
    int bus_num, addr, speed, device_count;
1493 0c402e5a Gerd Hoffmann
    int class_id, product_id, vendor_id, port;
1494 a594cfbf bellard
    char product_name[512];
1495 0f431527 aliguori
    int ret = 0;
1496 3b46e624 ths
1497 0f431527 aliguori
    if (!usb_host_device_path) {
1498 0f431527 aliguori
        perror("husb: USB Host Device Path not set");
1499 0f431527 aliguori
        goto the_end;
1500 0f431527 aliguori
    }
1501 0f431527 aliguori
    snprintf(line, sizeof(line), "%s/devices", usb_host_device_path);
1502 0f431527 aliguori
    f = fopen(line, "r");
1503 a594cfbf bellard
    if (!f) {
1504 0f431527 aliguori
        perror("husb: cannot open devices file");
1505 0f431527 aliguori
        goto the_end;
1506 a594cfbf bellard
    }
1507 0f431527 aliguori
1508 a594cfbf bellard
    device_count = 0;
1509 0c402e5a Gerd Hoffmann
    bus_num = addr = class_id = product_id = vendor_id = port = 0;
1510 3991c35e Hans de Goede
    speed = -1; /* Can't get the speed from /[proc|dev]/bus/usb/devices */
1511 bb36d470 bellard
    for(;;) {
1512 2791104c David Ahern
        if (fgets(line, sizeof(line), f) == NULL) {
1513 bb36d470 bellard
            break;
1514 2791104c David Ahern
        }
1515 2791104c David Ahern
        if (strlen(line) > 0) {
1516 a594cfbf bellard
            line[strlen(line) - 1] = '\0';
1517 2791104c David Ahern
        }
1518 a594cfbf bellard
        if (line[0] == 'T' && line[1] == ':') {
1519 38ca0f6d pbrook
            if (device_count && (vendor_id || product_id)) {
1520 38ca0f6d pbrook
                /* New device.  Add the previously discovered device.  */
1521 0f5160d1 Hans de Goede
                ret = func(opaque, bus_num, addr, 0, class_id, vendor_id,
1522 a594cfbf bellard
                           product_id, product_name, speed);
1523 2791104c David Ahern
                if (ret) {
1524 a594cfbf bellard
                    goto the_end;
1525 2791104c David Ahern
                }
1526 a594cfbf bellard
            }
1527 2791104c David Ahern
            if (get_tag_value(buf, sizeof(buf), line, "Bus=", " ") < 0) {
1528 a594cfbf bellard
                goto fail;
1529 2791104c David Ahern
            }
1530 a594cfbf bellard
            bus_num = atoi(buf);
1531 0c402e5a Gerd Hoffmann
            if (get_tag_value(buf, sizeof(buf), line, "Port=", " ") < 0) {
1532 0c402e5a Gerd Hoffmann
                goto fail;
1533 0c402e5a Gerd Hoffmann
            }
1534 0c402e5a Gerd Hoffmann
            port = atoi(buf);
1535 2791104c David Ahern
            if (get_tag_value(buf, sizeof(buf), line, "Dev#=", " ") < 0) {
1536 a594cfbf bellard
                goto fail;
1537 2791104c David Ahern
            }
1538 a594cfbf bellard
            addr = atoi(buf);
1539 2791104c David Ahern
            if (get_tag_value(buf, sizeof(buf), line, "Spd=", " ") < 0) {
1540 a594cfbf bellard
                goto fail;
1541 2791104c David Ahern
            }
1542 f264cfbf Hans de Goede
            if (!strcmp(buf, "5000")) {
1543 f264cfbf Hans de Goede
                speed = USB_SPEED_SUPER;
1544 f264cfbf Hans de Goede
            } else if (!strcmp(buf, "480")) {
1545 a594cfbf bellard
                speed = USB_SPEED_HIGH;
1546 2791104c David Ahern
            } else if (!strcmp(buf, "1.5")) {
1547 a594cfbf bellard
                speed = USB_SPEED_LOW;
1548 2791104c David Ahern
            } else {
1549 a594cfbf bellard
                speed = USB_SPEED_FULL;
1550 2791104c David Ahern
            }
1551 a594cfbf bellard
            product_name[0] = '\0';
1552 a594cfbf bellard
            class_id = 0xff;
1553 a594cfbf bellard
            device_count++;
1554 a594cfbf bellard
            product_id = 0;
1555 a594cfbf bellard
            vendor_id = 0;
1556 a594cfbf bellard
        } else if (line[0] == 'P' && line[1] == ':') {
1557 2791104c David Ahern
            if (get_tag_value(buf, sizeof(buf), line, "Vendor=", " ") < 0) {
1558 a594cfbf bellard
                goto fail;
1559 2791104c David Ahern
            }
1560 a594cfbf bellard
            vendor_id = strtoul(buf, NULL, 16);
1561 2791104c David Ahern
            if (get_tag_value(buf, sizeof(buf), line, "ProdID=", " ") < 0) {
1562 a594cfbf bellard
                goto fail;
1563 2791104c David Ahern
            }
1564 a594cfbf bellard
            product_id = strtoul(buf, NULL, 16);
1565 a594cfbf bellard
        } else if (line[0] == 'S' && line[1] == ':') {
1566 2791104c David Ahern
            if (get_tag_value(buf, sizeof(buf), line, "Product=", "") < 0) {
1567 a594cfbf bellard
                goto fail;
1568 2791104c David Ahern
            }
1569 a594cfbf bellard
            pstrcpy(product_name, sizeof(product_name), buf);
1570 a594cfbf bellard
        } else if (line[0] == 'D' && line[1] == ':') {
1571 2791104c David Ahern
            if (get_tag_value(buf, sizeof(buf), line, "Cls=", " (") < 0) {
1572 a594cfbf bellard
                goto fail;
1573 2791104c David Ahern
            }
1574 a594cfbf bellard
            class_id = strtoul(buf, NULL, 16);
1575 bb36d470 bellard
        }
1576 a594cfbf bellard
    fail: ;
1577 a594cfbf bellard
    }
1578 38ca0f6d pbrook
    if (device_count && (vendor_id || product_id)) {
1579 38ca0f6d pbrook
        /* Add the last device.  */
1580 0c402e5a Gerd Hoffmann
        if (port > 0) {
1581 0c402e5a Gerd Hoffmann
            snprintf(buf, sizeof(buf), "%d", port);
1582 0c402e5a Gerd Hoffmann
        } else {
1583 0c402e5a Gerd Hoffmann
            snprintf(buf, sizeof(buf), "?");
1584 0c402e5a Gerd Hoffmann
        }
1585 0c402e5a Gerd Hoffmann
        ret = func(opaque, bus_num, addr, buf, class_id, vendor_id,
1586 a594cfbf bellard
                   product_id, product_name, speed);
1587 bb36d470 bellard
    }
1588 a594cfbf bellard
 the_end:
1589 2791104c David Ahern
    if (f) {
1590 0f431527 aliguori
        fclose(f);
1591 2791104c David Ahern
    }
1592 0f431527 aliguori
    return ret;
1593 0f431527 aliguori
}
1594 0f431527 aliguori
1595 0f431527 aliguori
/*
1596 0f431527 aliguori
 * Read sys file-system device file
1597 0f431527 aliguori
 *
1598 0f431527 aliguori
 * @line address of buffer to put file contents in
1599 0f431527 aliguori
 * @line_size size of line
1600 0f431527 aliguori
 * @device_file path to device file (printf format string)
1601 0f431527 aliguori
 * @device_name device being opened (inserted into device_file)
1602 0f431527 aliguori
 *
1603 0f431527 aliguori
 * @return 0 failed, 1 succeeded ('line' contains data)
1604 0f431527 aliguori
 */
1605 2791104c David Ahern
static int usb_host_read_file(char *line, size_t line_size,
1606 2791104c David Ahern
                              const char *device_file, const char *device_name)
1607 0f431527 aliguori
{
1608 0f431527 aliguori
    FILE *f;
1609 0f431527 aliguori
    int ret = 0;
1610 0f431527 aliguori
    char filename[PATH_MAX];
1611 0f431527 aliguori
1612 b4e237aa blueswir1
    snprintf(filename, PATH_MAX, USBSYSBUS_PATH "/devices/%s/%s", device_name,
1613 b4e237aa blueswir1
             device_file);
1614 0f431527 aliguori
    f = fopen(filename, "r");
1615 0f431527 aliguori
    if (f) {
1616 9f99cee7 Kirill A. Shutemov
        ret = fgets(line, line_size, f) != NULL;
1617 0f431527 aliguori
        fclose(f);
1618 0f431527 aliguori
    }
1619 0f431527 aliguori
1620 0f431527 aliguori
    return ret;
1621 0f431527 aliguori
}
1622 0f431527 aliguori
1623 0f431527 aliguori
/*
1624 0f431527 aliguori
 * Use /sys/bus/usb/devices/ directory to determine host's USB
1625 0f431527 aliguori
 * devices.
1626 0f431527 aliguori
 *
1627 0f431527 aliguori
 * This code is based on Robert Schiele's original patches posted to
1628 0f431527 aliguori
 * the Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
1629 0f431527 aliguori
 */
1630 0f431527 aliguori
static int usb_host_scan_sys(void *opaque, USBScanFunc *func)
1631 0f431527 aliguori
{
1632 660f11be Blue Swirl
    DIR *dir = NULL;
1633 0f431527 aliguori
    char line[1024];
1634 5557d820 Gerd Hoffmann
    int bus_num, addr, speed, class_id, product_id, vendor_id;
1635 0f431527 aliguori
    int ret = 0;
1636 5557d820 Gerd Hoffmann
    char port[MAX_PORTLEN];
1637 0f431527 aliguori
    char product_name[512];
1638 0f431527 aliguori
    struct dirent *de;
1639 0f431527 aliguori
1640 0f431527 aliguori
    dir = opendir(USBSYSBUS_PATH "/devices");
1641 0f431527 aliguori
    if (!dir) {
1642 0f431527 aliguori
        perror("husb: cannot open devices directory");
1643 0f431527 aliguori
        goto the_end;
1644 0f431527 aliguori
    }
1645 0f431527 aliguori
1646 0f431527 aliguori
    while ((de = readdir(dir))) {
1647 0f431527 aliguori
        if (de->d_name[0] != '.' && !strchr(de->d_name, ':')) {
1648 5557d820 Gerd Hoffmann
            if (sscanf(de->d_name, "%d-%7[0-9.]", &bus_num, port) < 2) {
1649 5557d820 Gerd Hoffmann
                continue;
1650 0f5160d1 Hans de Goede
            }
1651 0f431527 aliguori
1652 2791104c David Ahern
            if (!usb_host_read_file(line, sizeof(line), "devnum", de->d_name)) {
1653 0f431527 aliguori
                goto the_end;
1654 2791104c David Ahern
            }
1655 2791104c David Ahern
            if (sscanf(line, "%d", &addr) != 1) {
1656 0f431527 aliguori
                goto the_end;
1657 2791104c David Ahern
            }
1658 b4e237aa blueswir1
            if (!usb_host_read_file(line, sizeof(line), "bDeviceClass",
1659 2791104c David Ahern
                                    de->d_name)) {
1660 0f431527 aliguori
                goto the_end;
1661 2791104c David Ahern
            }
1662 2791104c David Ahern
            if (sscanf(line, "%x", &class_id) != 1) {
1663 0f431527 aliguori
                goto the_end;
1664 2791104c David Ahern
            }
1665 0f431527 aliguori
1666 2791104c David Ahern
            if (!usb_host_read_file(line, sizeof(line), "idVendor",
1667 2791104c David Ahern
                                    de->d_name)) {
1668 0f431527 aliguori
                goto the_end;
1669 2791104c David Ahern
            }
1670 2791104c David Ahern
            if (sscanf(line, "%x", &vendor_id) != 1) {
1671 0f431527 aliguori
                goto the_end;
1672 2791104c David Ahern
            }
1673 b4e237aa blueswir1
            if (!usb_host_read_file(line, sizeof(line), "idProduct",
1674 2791104c David Ahern
                                    de->d_name)) {
1675 0f431527 aliguori
                goto the_end;
1676 2791104c David Ahern
            }
1677 2791104c David Ahern
            if (sscanf(line, "%x", &product_id) != 1) {
1678 0f431527 aliguori
                goto the_end;
1679 2791104c David Ahern
            }
1680 b4e237aa blueswir1
            if (!usb_host_read_file(line, sizeof(line), "product",
1681 b4e237aa blueswir1
                                    de->d_name)) {
1682 0f431527 aliguori
                *product_name = 0;
1683 0f431527 aliguori
            } else {
1684 2791104c David Ahern
                if (strlen(line) > 0) {
1685 0f431527 aliguori
                    line[strlen(line) - 1] = '\0';
1686 2791104c David Ahern
                }
1687 0f431527 aliguori
                pstrcpy(product_name, sizeof(product_name), line);
1688 0f431527 aliguori
            }
1689 0f431527 aliguori
1690 2791104c David Ahern
            if (!usb_host_read_file(line, sizeof(line), "speed", de->d_name)) {
1691 0f431527 aliguori
                goto the_end;
1692 2791104c David Ahern
            }
1693 f264cfbf Hans de Goede
            if (!strcmp(line, "5000\n")) {
1694 f264cfbf Hans de Goede
                speed = USB_SPEED_SUPER;
1695 f264cfbf Hans de Goede
            } else if (!strcmp(line, "480\n")) {
1696 0f431527 aliguori
                speed = USB_SPEED_HIGH;
1697 2791104c David Ahern
            } else if (!strcmp(line, "1.5\n")) {
1698 0f431527 aliguori
                speed = USB_SPEED_LOW;
1699 2791104c David Ahern
            } else {
1700 0f431527 aliguori
                speed = USB_SPEED_FULL;
1701 2791104c David Ahern
            }
1702 0f431527 aliguori
1703 5557d820 Gerd Hoffmann
            ret = func(opaque, bus_num, addr, port, class_id, vendor_id,
1704 0f431527 aliguori
                       product_id, product_name, speed);
1705 2791104c David Ahern
            if (ret) {
1706 0f431527 aliguori
                goto the_end;
1707 2791104c David Ahern
            }
1708 0f431527 aliguori
        }
1709 0f431527 aliguori
    }
1710 0f431527 aliguori
 the_end:
1711 2791104c David Ahern
    if (dir) {
1712 0f431527 aliguori
        closedir(dir);
1713 2791104c David Ahern
    }
1714 0f431527 aliguori
    return ret;
1715 0f431527 aliguori
}
1716 0f431527 aliguori
1717 0f431527 aliguori
/*
1718 0f431527 aliguori
 * Determine how to access the host's USB devices and call the
1719 0f431527 aliguori
 * specific support function.
1720 0f431527 aliguori
 */
1721 0f431527 aliguori
static int usb_host_scan(void *opaque, USBScanFunc *func)
1722 0f431527 aliguori
{
1723 376253ec aliguori
    Monitor *mon = cur_mon;
1724 660f11be Blue Swirl
    FILE *f = NULL;
1725 660f11be Blue Swirl
    DIR *dir = NULL;
1726 0f431527 aliguori
    int ret = 0;
1727 0f431527 aliguori
    const char *fs_type[] = {"unknown", "proc", "dev", "sys"};
1728 0f431527 aliguori
    char devpath[PATH_MAX];
1729 0f431527 aliguori
1730 0f431527 aliguori
    /* only check the host once */
1731 0f431527 aliguori
    if (!usb_fs_type) {
1732 55496240 Mark McLoughlin
        dir = opendir(USBSYSBUS_PATH "/devices");
1733 55496240 Mark McLoughlin
        if (dir) {
1734 55496240 Mark McLoughlin
            /* devices found in /dev/bus/usb/ (yes - not a mistake!) */
1735 55496240 Mark McLoughlin
            strcpy(devpath, USBDEVBUS_PATH);
1736 55496240 Mark McLoughlin
            usb_fs_type = USB_FS_SYS;
1737 55496240 Mark McLoughlin
            closedir(dir);
1738 d0f2c4c6 malc
            DPRINTF(USBDBG_DEVOPENED, USBSYSBUS_PATH);
1739 55496240 Mark McLoughlin
            goto found_devices;
1740 55496240 Mark McLoughlin
        }
1741 0f431527 aliguori
        f = fopen(USBPROCBUS_PATH "/devices", "r");
1742 0f431527 aliguori
        if (f) {
1743 0f431527 aliguori
            /* devices found in /proc/bus/usb/ */
1744 0f431527 aliguori
            strcpy(devpath, USBPROCBUS_PATH);
1745 0f431527 aliguori
            usb_fs_type = USB_FS_PROC;
1746 0f431527 aliguori
            fclose(f);
1747 d0f2c4c6 malc
            DPRINTF(USBDBG_DEVOPENED, USBPROCBUS_PATH);
1748 f16a0db3 aliguori
            goto found_devices;
1749 0f431527 aliguori
        }
1750 0f431527 aliguori
        /* try additional methods if an access method hasn't been found yet */
1751 0f431527 aliguori
        f = fopen(USBDEVBUS_PATH "/devices", "r");
1752 f16a0db3 aliguori
        if (f) {
1753 0f431527 aliguori
            /* devices found in /dev/bus/usb/ */
1754 0f431527 aliguori
            strcpy(devpath, USBDEVBUS_PATH);
1755 0f431527 aliguori
            usb_fs_type = USB_FS_DEV;
1756 0f431527 aliguori
            fclose(f);
1757 d0f2c4c6 malc
            DPRINTF(USBDBG_DEVOPENED, USBDEVBUS_PATH);
1758 f16a0db3 aliguori
            goto found_devices;
1759 0f431527 aliguori
        }
1760 f16a0db3 aliguori
    found_devices:
1761 22babebb aliguori
        if (!usb_fs_type) {
1762 2791104c David Ahern
            if (mon) {
1763 eba6fe87 Gerd Hoffmann
                monitor_printf(mon, "husb: unable to access USB devices\n");
1764 2791104c David Ahern
            }
1765 f16a0db3 aliguori
            return -ENOENT;
1766 0f431527 aliguori
        }
1767 0f431527 aliguori
1768 0f431527 aliguori
        /* the module setting (used later for opening devices) */
1769 7267c094 Anthony Liguori
        usb_host_device_path = g_malloc0(strlen(devpath)+1);
1770 1eec614b aliguori
        strcpy(usb_host_device_path, devpath);
1771 2791104c David Ahern
        if (mon) {
1772 eba6fe87 Gerd Hoffmann
            monitor_printf(mon, "husb: using %s file-system with %s\n",
1773 eba6fe87 Gerd Hoffmann
                           fs_type[usb_fs_type], usb_host_device_path);
1774 2791104c David Ahern
        }
1775 0f431527 aliguori
    }
1776 0f431527 aliguori
1777 0f431527 aliguori
    switch (usb_fs_type) {
1778 0f431527 aliguori
    case USB_FS_PROC:
1779 0f431527 aliguori
    case USB_FS_DEV:
1780 0f431527 aliguori
        ret = usb_host_scan_dev(opaque, func);
1781 0f431527 aliguori
        break;
1782 0f431527 aliguori
    case USB_FS_SYS:
1783 0f431527 aliguori
        ret = usb_host_scan_sys(opaque, func);
1784 0f431527 aliguori
        break;
1785 f16a0db3 aliguori
    default:
1786 f16a0db3 aliguori
        ret = -EINVAL;
1787 f16a0db3 aliguori
        break;
1788 0f431527 aliguori
    }
1789 a594cfbf bellard
    return ret;
1790 bb36d470 bellard
}
1791 bb36d470 bellard
1792 4b096fc9 aliguori
static QEMUTimer *usb_auto_timer;
1793 4b096fc9 aliguori
1794 ba9acab9 Gerd Hoffmann
static int usb_host_auto_scan(void *opaque, int bus_num,
1795 ba9acab9 Gerd Hoffmann
                              int addr, const char *port,
1796 26a9e82a Gerd Hoffmann
                              int class_id, int vendor_id, int product_id,
1797 26a9e82a Gerd Hoffmann
                              const char *product_name, int speed)
1798 4b096fc9 aliguori
{
1799 4b096fc9 aliguori
    struct USBAutoFilter *f;
1800 26a9e82a Gerd Hoffmann
    struct USBHostDevice *s;
1801 4b096fc9 aliguori
1802 4b096fc9 aliguori
    /* Ignore hubs */
1803 4b096fc9 aliguori
    if (class_id == 9)
1804 4b096fc9 aliguori
        return 0;
1805 4b096fc9 aliguori
1806 26a9e82a Gerd Hoffmann
    QTAILQ_FOREACH(s, &hostdevs, next) {
1807 26a9e82a Gerd Hoffmann
        f = &s->match;
1808 26a9e82a Gerd Hoffmann
1809 2791104c David Ahern
        if (f->bus_num > 0 && f->bus_num != bus_num) {
1810 4b096fc9 aliguori
            continue;
1811 2791104c David Ahern
        }
1812 2791104c David Ahern
        if (f->addr > 0 && f->addr != addr) {
1813 4b096fc9 aliguori
            continue;
1814 2791104c David Ahern
        }
1815 9056a297 Gerd Hoffmann
        if (f->port != NULL && (port == NULL || strcmp(f->port, port) != 0)) {
1816 9056a297 Gerd Hoffmann
            continue;
1817 9056a297 Gerd Hoffmann
        }
1818 4b096fc9 aliguori
1819 2791104c David Ahern
        if (f->vendor_id > 0 && f->vendor_id != vendor_id) {
1820 4b096fc9 aliguori
            continue;
1821 2791104c David Ahern
        }
1822 4b096fc9 aliguori
1823 2791104c David Ahern
        if (f->product_id > 0 && f->product_id != product_id) {
1824 4b096fc9 aliguori
            continue;
1825 2791104c David Ahern
        }
1826 4b096fc9 aliguori
        /* We got a match */
1827 3ee886c5 Gerd Hoffmann
        s->seen++;
1828 3ee886c5 Gerd Hoffmann
        if (s->errcount >= 3) {
1829 3ee886c5 Gerd Hoffmann
            return 0;
1830 3ee886c5 Gerd Hoffmann
        }
1831 4b096fc9 aliguori
1832 33e66b86 Markus Armbruster
        /* Already attached ? */
1833 2791104c David Ahern
        if (s->fd != -1) {
1834 4b096fc9 aliguori
            return 0;
1835 2791104c David Ahern
        }
1836 d0f2c4c6 malc
        DPRINTF("husb: auto open: bus_num %d addr %d\n", bus_num, addr);
1837 4b096fc9 aliguori
1838 3ee886c5 Gerd Hoffmann
        if (usb_host_open(s, bus_num, addr, port, product_name, speed) < 0) {
1839 3ee886c5 Gerd Hoffmann
            s->errcount++;
1840 3ee886c5 Gerd Hoffmann
        }
1841 97f86166 Hans de Goede
        break;
1842 4b096fc9 aliguori
    }
1843 4b096fc9 aliguori
1844 4b096fc9 aliguori
    return 0;
1845 4b096fc9 aliguori
}
1846 4b096fc9 aliguori
1847 26a9e82a Gerd Hoffmann
static void usb_host_auto_check(void *unused)
1848 4b096fc9 aliguori
{
1849 26a9e82a Gerd Hoffmann
    struct USBHostDevice *s;
1850 26a9e82a Gerd Hoffmann
    int unconnected = 0;
1851 26a9e82a Gerd Hoffmann
1852 4b096fc9 aliguori
    usb_host_scan(NULL, usb_host_auto_scan);
1853 26a9e82a Gerd Hoffmann
1854 26a9e82a Gerd Hoffmann
    QTAILQ_FOREACH(s, &hostdevs, next) {
1855 2791104c David Ahern
        if (s->fd == -1) {
1856 26a9e82a Gerd Hoffmann
            unconnected++;
1857 2791104c David Ahern
        }
1858 3ee886c5 Gerd Hoffmann
        if (s->seen == 0) {
1859 3ee886c5 Gerd Hoffmann
            s->errcount = 0;
1860 3ee886c5 Gerd Hoffmann
        }
1861 3ee886c5 Gerd Hoffmann
        s->seen = 0;
1862 26a9e82a Gerd Hoffmann
    }
1863 26a9e82a Gerd Hoffmann
1864 26a9e82a Gerd Hoffmann
    if (unconnected == 0) {
1865 26a9e82a Gerd Hoffmann
        /* nothing to watch */
1866 2791104c David Ahern
        if (usb_auto_timer) {
1867 26a9e82a Gerd Hoffmann
            qemu_del_timer(usb_auto_timer);
1868 e6a2f500 Gerd Hoffmann
            trace_usb_host_auto_scan_disabled();
1869 2791104c David Ahern
        }
1870 26a9e82a Gerd Hoffmann
        return;
1871 26a9e82a Gerd Hoffmann
    }
1872 26a9e82a Gerd Hoffmann
1873 26a9e82a Gerd Hoffmann
    if (!usb_auto_timer) {
1874 7bd427d8 Paolo Bonzini
        usb_auto_timer = qemu_new_timer_ms(rt_clock, usb_host_auto_check, NULL);
1875 2791104c David Ahern
        if (!usb_auto_timer) {
1876 26a9e82a Gerd Hoffmann
            return;
1877 2791104c David Ahern
        }
1878 e6a2f500 Gerd Hoffmann
        trace_usb_host_auto_scan_enabled();
1879 26a9e82a Gerd Hoffmann
    }
1880 7bd427d8 Paolo Bonzini
    qemu_mod_timer(usb_auto_timer, qemu_get_clock_ms(rt_clock) + 2000);
1881 4b096fc9 aliguori
}
1882 4b096fc9 aliguori
1883 4b096fc9 aliguori
/*
1884 5d0c5750 aliguori
 * Autoconnect filter
1885 5d0c5750 aliguori
 * Format:
1886 5d0c5750 aliguori
 *    auto:bus:dev[:vid:pid]
1887 5d0c5750 aliguori
 *    auto:bus.dev[:vid:pid]
1888 5d0c5750 aliguori
 *
1889 5d0c5750 aliguori
 *    bus  - bus number    (dec, * means any)
1890 5d0c5750 aliguori
 *    dev  - device number (dec, * means any)
1891 5d0c5750 aliguori
 *    vid  - vendor id     (hex, * means any)
1892 5d0c5750 aliguori
 *    pid  - product id    (hex, * means any)
1893 5d0c5750 aliguori
 *
1894 5d0c5750 aliguori
 *    See 'lsusb' output.
1895 4b096fc9 aliguori
 */
1896 5d0c5750 aliguori
static int parse_filter(const char *spec, struct USBAutoFilter *f)
1897 4b096fc9 aliguori
{
1898 5d0c5750 aliguori
    enum { BUS, DEV, VID, PID, DONE };
1899 5d0c5750 aliguori
    const char *p = spec;
1900 5d0c5750 aliguori
    int i;
1901 5d0c5750 aliguori
1902 0745eb1e Markus Armbruster
    f->bus_num    = 0;
1903 0745eb1e Markus Armbruster
    f->addr       = 0;
1904 0745eb1e Markus Armbruster
    f->vendor_id  = 0;
1905 0745eb1e Markus Armbruster
    f->product_id = 0;
1906 5d0c5750 aliguori
1907 5d0c5750 aliguori
    for (i = BUS; i < DONE; i++) {
1908 2791104c David Ahern
        p = strpbrk(p, ":.");
1909 2791104c David Ahern
        if (!p) {
1910 2791104c David Ahern
            break;
1911 2791104c David Ahern
        }
1912 5d0c5750 aliguori
        p++;
1913 5d0c5750 aliguori
1914 2791104c David Ahern
        if (*p == '*') {
1915 2791104c David Ahern
            continue;
1916 2791104c David Ahern
        }
1917 5d0c5750 aliguori
        switch(i) {
1918 5d0c5750 aliguori
        case BUS: f->bus_num = strtol(p, NULL, 10);    break;
1919 5d0c5750 aliguori
        case DEV: f->addr    = strtol(p, NULL, 10);    break;
1920 5d0c5750 aliguori
        case VID: f->vendor_id  = strtol(p, NULL, 16); break;
1921 5d0c5750 aliguori
        case PID: f->product_id = strtol(p, NULL, 16); break;
1922 5d0c5750 aliguori
        }
1923 5d0c5750 aliguori
    }
1924 5d0c5750 aliguori
1925 5d0c5750 aliguori
    if (i < DEV) {
1926 5d0c5750 aliguori
        fprintf(stderr, "husb: invalid auto filter spec %s\n", spec);
1927 5d0c5750 aliguori
        return -1;
1928 5d0c5750 aliguori
    }
1929 5d0c5750 aliguori
1930 5d0c5750 aliguori
    return 0;
1931 5d0c5750 aliguori
}
1932 5d0c5750 aliguori
1933 a594cfbf bellard
/**********************/
1934 a594cfbf bellard
/* USB host device info */
1935 a594cfbf bellard
1936 a594cfbf bellard
struct usb_class_info {
1937 a594cfbf bellard
    int class;
1938 a594cfbf bellard
    const char *class_name;
1939 a594cfbf bellard
};
1940 a594cfbf bellard
1941 a594cfbf bellard
static const struct usb_class_info usb_class_info[] = {
1942 a594cfbf bellard
    { USB_CLASS_AUDIO, "Audio"},
1943 a594cfbf bellard
    { USB_CLASS_COMM, "Communication"},
1944 a594cfbf bellard
    { USB_CLASS_HID, "HID"},
1945 a594cfbf bellard
    { USB_CLASS_HUB, "Hub" },
1946 a594cfbf bellard
    { USB_CLASS_PHYSICAL, "Physical" },
1947 a594cfbf bellard
    { USB_CLASS_PRINTER, "Printer" },
1948 a594cfbf bellard
    { USB_CLASS_MASS_STORAGE, "Storage" },
1949 a594cfbf bellard
    { USB_CLASS_CDC_DATA, "Data" },
1950 a594cfbf bellard
    { USB_CLASS_APP_SPEC, "Application Specific" },
1951 a594cfbf bellard
    { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
1952 a594cfbf bellard
    { USB_CLASS_STILL_IMAGE, "Still Image" },
1953 b9dc033c balrog
    { USB_CLASS_CSCID, "Smart Card" },
1954 a594cfbf bellard
    { USB_CLASS_CONTENT_SEC, "Content Security" },
1955 a594cfbf bellard
    { -1, NULL }
1956 a594cfbf bellard
};
1957 a594cfbf bellard
1958 a594cfbf bellard
static const char *usb_class_str(uint8_t class)
1959 bb36d470 bellard
{
1960 a594cfbf bellard
    const struct usb_class_info *p;
1961 a594cfbf bellard
    for(p = usb_class_info; p->class != -1; p++) {
1962 2791104c David Ahern
        if (p->class == class) {
1963 a594cfbf bellard
            break;
1964 2791104c David Ahern
        }
1965 bb36d470 bellard
    }
1966 a594cfbf bellard
    return p->class_name;
1967 a594cfbf bellard
}
1968 a594cfbf bellard
1969 ba9acab9 Gerd Hoffmann
static void usb_info_device(Monitor *mon, int bus_num,
1970 ba9acab9 Gerd Hoffmann
                            int addr, const char *port,
1971 5557d820 Gerd Hoffmann
                            int class_id, int vendor_id, int product_id,
1972 9596ebb7 pbrook
                            const char *product_name,
1973 9596ebb7 pbrook
                            int speed)
1974 a594cfbf bellard
{
1975 a594cfbf bellard
    const char *class_str, *speed_str;
1976 a594cfbf bellard
1977 a594cfbf bellard
    switch(speed) {
1978 5fafdf24 ths
    case USB_SPEED_LOW:
1979 5fafdf24 ths
        speed_str = "1.5";
1980 a594cfbf bellard
        break;
1981 5fafdf24 ths
    case USB_SPEED_FULL:
1982 5fafdf24 ths
        speed_str = "12";
1983 a594cfbf bellard
        break;
1984 5fafdf24 ths
    case USB_SPEED_HIGH:
1985 5fafdf24 ths
        speed_str = "480";
1986 a594cfbf bellard
        break;
1987 f264cfbf Hans de Goede
    case USB_SPEED_SUPER:
1988 f264cfbf Hans de Goede
        speed_str = "5000";
1989 f264cfbf Hans de Goede
        break;
1990 a594cfbf bellard
    default:
1991 5fafdf24 ths
        speed_str = "?";
1992 a594cfbf bellard
        break;
1993 a594cfbf bellard
    }
1994 a594cfbf bellard
1995 5557d820 Gerd Hoffmann
    monitor_printf(mon, "  Bus %d, Addr %d, Port %s, Speed %s Mb/s\n",
1996 5557d820 Gerd Hoffmann
                   bus_num, addr, port, speed_str);
1997 a594cfbf bellard
    class_str = usb_class_str(class_id);
1998 2791104c David Ahern
    if (class_str) {
1999 376253ec aliguori
        monitor_printf(mon, "    %s:", class_str);
2000 2791104c David Ahern
    } else {
2001 376253ec aliguori
        monitor_printf(mon, "    Class %02x:", class_id);
2002 2791104c David Ahern
    }
2003 376253ec aliguori
    monitor_printf(mon, " USB device %04x:%04x", vendor_id, product_id);
2004 2791104c David Ahern
    if (product_name[0] != '\0') {
2005 376253ec aliguori
        monitor_printf(mon, ", %s", product_name);
2006 2791104c David Ahern
    }
2007 376253ec aliguori
    monitor_printf(mon, "\n");
2008 a594cfbf bellard
}
2009 a594cfbf bellard
2010 5fafdf24 ths
static int usb_host_info_device(void *opaque, int bus_num, int addr,
2011 ba9acab9 Gerd Hoffmann
                                const char *path, int class_id,
2012 5fafdf24 ths
                                int vendor_id, int product_id,
2013 a594cfbf bellard
                                const char *product_name,
2014 a594cfbf bellard
                                int speed)
2015 a594cfbf bellard
{
2016 179da8af Blue Swirl
    Monitor *mon = opaque;
2017 179da8af Blue Swirl
2018 5557d820 Gerd Hoffmann
    usb_info_device(mon, bus_num, addr, path, class_id, vendor_id, product_id,
2019 a594cfbf bellard
                    product_name, speed);
2020 a594cfbf bellard
    return 0;
2021 a594cfbf bellard
}
2022 a594cfbf bellard
2023 ac4ffb5a aliguori
static void dec2str(int val, char *str, size_t size)
2024 5d0c5750 aliguori
{
2025 2791104c David Ahern
    if (val == 0) {
2026 ac4ffb5a aliguori
        snprintf(str, size, "*");
2027 2791104c David Ahern
    } else {
2028 2791104c David Ahern
        snprintf(str, size, "%d", val);
2029 2791104c David Ahern
    }
2030 5d0c5750 aliguori
}
2031 5d0c5750 aliguori
2032 ac4ffb5a aliguori
static void hex2str(int val, char *str, size_t size)
2033 5d0c5750 aliguori
{
2034 2791104c David Ahern
    if (val == 0) {
2035 ac4ffb5a aliguori
        snprintf(str, size, "*");
2036 2791104c David Ahern
    } else {
2037 26a9e82a Gerd Hoffmann
        snprintf(str, size, "%04x", val);
2038 2791104c David Ahern
    }
2039 5d0c5750 aliguori
}
2040 5d0c5750 aliguori
2041 376253ec aliguori
void usb_host_info(Monitor *mon)
2042 a594cfbf bellard
{
2043 5d0c5750 aliguori
    struct USBAutoFilter *f;
2044 26a9e82a Gerd Hoffmann
    struct USBHostDevice *s;
2045 5d0c5750 aliguori
2046 179da8af Blue Swirl
    usb_host_scan(mon, usb_host_info_device);
2047 5d0c5750 aliguori
2048 2791104c David Ahern
    if (QTAILQ_EMPTY(&hostdevs)) {
2049 26a9e82a Gerd Hoffmann
        return;
2050 2791104c David Ahern
    }
2051 2791104c David Ahern
2052 26a9e82a Gerd Hoffmann
    monitor_printf(mon, "  Auto filters:\n");
2053 26a9e82a Gerd Hoffmann
    QTAILQ_FOREACH(s, &hostdevs, next) {
2054 5d0c5750 aliguori
        char bus[10], addr[10], vid[10], pid[10];
2055 26a9e82a Gerd Hoffmann
        f = &s->match;
2056 ac4ffb5a aliguori
        dec2str(f->bus_num, bus, sizeof(bus));
2057 ac4ffb5a aliguori
        dec2str(f->addr, addr, sizeof(addr));
2058 ac4ffb5a aliguori
        hex2str(f->vendor_id, vid, sizeof(vid));
2059 ac4ffb5a aliguori
        hex2str(f->product_id, pid, sizeof(pid));
2060 9056a297 Gerd Hoffmann
        monitor_printf(mon, "    Bus %s, Addr %s, Port %s, ID %s:%s\n",
2061 9056a297 Gerd Hoffmann
                       bus, addr, f->port ? f->port : "*", vid, pid);
2062 5d0c5750 aliguori
    }
2063 bb36d470 bellard
}