]> git.proxmox.com Git - qemu.git/blame - usb-linux.c
qapi: modify visitor code generation for list iteration
[qemu.git] / usb-linux.c
CommitLineData
bb36d470
FB
1/*
2 * Linux host USB redirector
3 *
4 * Copyright (c) 2005 Fabrice Bellard
5fafdf24 5 *
64838171
AL
6 * Copyright (c) 2008 Max Krasnyansky
7 * Support for host device auto connect & disconnect
5d0c5750 8 * Major rewrite to support fully async operation
4b096fc9 9 *
0f431527
AL
10 * Copyright 2008 TJ <linux@tjworld.net>
11 * Added flexible support for /dev/bus/usb /sys/bus/usb/devices in addition
12 * to the legacy /proc/bus/usb USB device discovery and handling
13 *
bb36d470
FB
14 * Permission is hereby granted, free of charge, to any person obtaining a copy
15 * of this software and associated documentation files (the "Software"), to deal
16 * in the Software without restriction, including without limitation the rights
17 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18 * copies of the Software, and to permit persons to whom the Software is
19 * furnished to do so, subject to the following conditions:
20 *
21 * The above copyright notice and this permission notice shall be included in
22 * all copies or substantial portions of the Software.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30 * THE SOFTWARE.
31 */
446ab128 32
87ecb68b 33#include "qemu-common.h"
1f3870ab 34#include "qemu-timer.h"
376253ec 35#include "monitor.h"
b373a63a 36#include "sysemu.h"
e6a2f500 37#include "trace.h"
bb36d470 38
bb36d470
FB
39#include <dirent.h>
40#include <sys/ioctl.h>
bb36d470 41
446ab128
AL
42#include <linux/usbdevice_fs.h>
43#include <linux/version.h>
44#include "hw/usb.h"
bb36d470 45
d9cf1578
BS
46/* We redefine it to avoid version problems */
47struct usb_ctrltransfer {
48 uint8_t bRequestType;
49 uint8_t bRequest;
50 uint16_t wValue;
51 uint16_t wIndex;
52 uint16_t wLength;
53 uint32_t timeout;
54 void *data;
55};
56
ba9acab9 57typedef int USBScanFunc(void *opaque, int bus_num, int addr, const char *port,
0f5160d1 58 int class_id, int vendor_id, int product_id,
a594cfbf 59 const char *product_name, int speed);
26a9e82a 60
0745eb1e 61//#define DEBUG
64838171
AL
62
63#ifdef DEBUG
d0f2c4c6 64#define DPRINTF printf
64838171 65#else
d0f2c4c6 66#define DPRINTF(...)
64838171 67#endif
bb36d470 68
5be8e1f2
BS
69#define USBDBG_DEVOPENED "husb: opened %s/devices\n"
70
0f431527 71#define USBPROCBUS_PATH "/proc/bus/usb"
1f6e24e7 72#define PRODUCT_NAME_SZ 32
3a4854b3 73#define MAX_ENDPOINTS 15
5557d820 74#define MAX_PORTLEN 16
0f431527
AL
75#define USBDEVBUS_PATH "/dev/bus/usb"
76#define USBSYSBUS_PATH "/sys/bus/usb"
77
78static char *usb_host_device_path;
79
80#define USB_FS_NONE 0
81#define USB_FS_PROC 1
82#define USB_FS_DEV 2
83#define USB_FS_SYS 3
84
85static int usb_fs_type;
bb36d470 86
b9dc033c 87/* endpoint association data */
060dc841 88#define ISO_FRAME_DESC_PER_URB 32
a0b5fece 89#define INVALID_EP_TYPE 255
060dc841 90
71138531
GH
91/* devio.c limits single requests to 16k */
92#define MAX_USBFS_BUFFER_SIZE 16384
93
060dc841
HG
94typedef struct AsyncURB AsyncURB;
95
b9dc033c
AZ
96struct endp_data {
97 uint8_t type;
64838171 98 uint8_t halted;
bb6d5498 99 uint8_t iso_started;
060dc841
HG
100 AsyncURB *iso_urb;
101 int iso_urb_idx;
bb6d5498 102 int iso_buffer_used;
060dc841 103 int max_packet_size;
82887262 104 int inflight;
b9dc033c
AZ
105};
106
26a9e82a
GH
107struct USBAutoFilter {
108 uint32_t bus_num;
109 uint32_t addr;
9056a297 110 char *port;
26a9e82a
GH
111 uint32_t vendor_id;
112 uint32_t product_id;
113};
114
bb36d470
FB
115typedef struct USBHostDevice {
116 USBDevice dev;
64838171 117 int fd;
9516bb47 118 int hub_fd;
64838171 119
f8ddbfbc 120 uint8_t descr[8192];
64838171
AL
121 int descr_len;
122 int configuration;
446ab128 123 int ninterfaces;
24772c1e 124 int closing;
b81bcd8a 125 uint32_t iso_urb_count;
b373a63a 126 Notifier exit;
64838171 127
c0e5750b
GH
128 struct endp_data ep_in[MAX_ENDPOINTS];
129 struct endp_data ep_out[MAX_ENDPOINTS];
7a8fc83f 130 QLIST_HEAD(, AsyncURB) aurbs;
4b096fc9 131
4b096fc9
AL
132 /* Host side address */
133 int bus_num;
134 int addr;
5557d820 135 char port[MAX_PORTLEN];
26a9e82a 136 struct USBAutoFilter match;
3ee886c5 137 int seen, errcount;
4b096fc9 138
26a9e82a 139 QTAILQ_ENTRY(USBHostDevice) next;
bb36d470
FB
140} USBHostDevice;
141
26a9e82a
GH
142static QTAILQ_HEAD(, USBHostDevice) hostdevs = QTAILQ_HEAD_INITIALIZER(hostdevs);
143
144static int usb_host_close(USBHostDevice *dev);
145static int parse_filter(const char *spec, struct USBAutoFilter *f);
146static void usb_host_auto_check(void *unused);
2cc59d8c
HG
147static int usb_host_read_file(char *line, size_t line_size,
148 const char *device_file, const char *device_name);
9b87e19b 149static int usb_linux_update_endp_table(USBHostDevice *s);
26a9e82a 150
c0e5750b 151static struct endp_data *get_endp(USBHostDevice *s, int pid, int ep)
ca3a36cf 152{
c0e5750b
GH
153 struct endp_data *eps = pid == USB_TOKEN_IN ? s->ep_in : s->ep_out;
154 assert(pid == USB_TOKEN_IN || pid == USB_TOKEN_OUT);
155 assert(ep > 0 && ep <= MAX_ENDPOINTS);
156 return eps + ep - 1;
ca3a36cf
GH
157}
158
c0e5750b 159static int is_isoc(USBHostDevice *s, int pid, int ep)
64838171 160{
c0e5750b 161 return get_endp(s, pid, ep)->type == USBDEVFS_URB_TYPE_ISO;
64838171
AL
162}
163
c0e5750b 164static int is_valid(USBHostDevice *s, int pid, int ep)
a0b5fece 165{
c0e5750b 166 return get_endp(s, pid, ep)->type != INVALID_EP_TYPE;
a0b5fece
HG
167}
168
c0e5750b 169static int is_halted(USBHostDevice *s, int pid, int ep)
64838171 170{
c0e5750b 171 return get_endp(s, pid, ep)->halted;
64838171
AL
172}
173
c0e5750b 174static void clear_halt(USBHostDevice *s, int pid, int ep)
64838171 175{
e6a2f500 176 trace_usb_host_ep_clear_halt(s->bus_num, s->addr, ep);
c0e5750b 177 get_endp(s, pid, ep)->halted = 0;
64838171
AL
178}
179
c0e5750b 180static void set_halt(USBHostDevice *s, int pid, int ep)
64838171 181{
c0e5750b
GH
182 if (ep != 0) {
183 trace_usb_host_ep_set_halt(s->bus_num, s->addr, ep);
184 get_endp(s, pid, ep)->halted = 1;
185 }
64838171
AL
186}
187
c0e5750b 188static int is_iso_started(USBHostDevice *s, int pid, int ep)
bb6d5498 189{
c0e5750b 190 return get_endp(s, pid, ep)->iso_started;
bb6d5498
HG
191}
192
c0e5750b 193static void clear_iso_started(USBHostDevice *s, int pid, int ep)
bb6d5498 194{
e6a2f500 195 trace_usb_host_ep_stop_iso(s->bus_num, s->addr, ep);
c0e5750b 196 get_endp(s, pid, ep)->iso_started = 0;
bb6d5498
HG
197}
198
c0e5750b 199static void set_iso_started(USBHostDevice *s, int pid, int ep)
bb6d5498 200{
c0e5750b 201 struct endp_data *e = get_endp(s, pid, ep);
e6a2f500
GH
202
203 trace_usb_host_ep_start_iso(s->bus_num, s->addr, ep);
82887262
GH
204 if (!e->iso_started) {
205 e->iso_started = 1;
206 e->inflight = 0;
207 }
208}
209
c0e5750b 210static int change_iso_inflight(USBHostDevice *s, int pid, int ep, int value)
82887262 211{
c0e5750b 212 struct endp_data *e = get_endp(s, pid, ep);
82887262
GH
213
214 e->inflight += value;
215 return e->inflight;
bb6d5498
HG
216}
217
c0e5750b 218static void set_iso_urb(USBHostDevice *s, int pid, int ep, AsyncURB *iso_urb)
060dc841 219{
c0e5750b 220 get_endp(s, pid, ep)->iso_urb = iso_urb;
060dc841
HG
221}
222
c0e5750b 223static AsyncURB *get_iso_urb(USBHostDevice *s, int pid, int ep)
060dc841 224{
c0e5750b 225 return get_endp(s, pid, ep)->iso_urb;
060dc841
HG
226}
227
c0e5750b 228static void set_iso_urb_idx(USBHostDevice *s, int pid, int ep, int i)
060dc841 229{
c0e5750b 230 get_endp(s, pid, ep)->iso_urb_idx = i;
060dc841
HG
231}
232
c0e5750b 233static int get_iso_urb_idx(USBHostDevice *s, int pid, int ep)
060dc841 234{
c0e5750b 235 return get_endp(s, pid, ep)->iso_urb_idx;
060dc841
HG
236}
237
c0e5750b 238static void set_iso_buffer_used(USBHostDevice *s, int pid, int ep, int i)
bb6d5498 239{
c0e5750b 240 get_endp(s, pid, ep)->iso_buffer_used = i;
bb6d5498
HG
241}
242
c0e5750b 243static int get_iso_buffer_used(USBHostDevice *s, int pid, int ep)
bb6d5498 244{
c0e5750b 245 return get_endp(s, pid, ep)->iso_buffer_used;
bb6d5498
HG
246}
247
c0e5750b
GH
248static void set_max_packet_size(USBHostDevice *s, int pid, int ep,
249 uint8_t *descriptor)
6dfcdccb
GH
250{
251 int raw = descriptor[4] + (descriptor[5] << 8);
252 int size, microframes;
253
254 size = raw & 0x7ff;
255 switch ((raw >> 11) & 3) {
256 case 1: microframes = 2; break;
257 case 2: microframes = 3; break;
258 default: microframes = 1; break;
259 }
c0e5750b 260 get_endp(s, pid, ep)->max_packet_size = size * microframes;
6dfcdccb
GH
261}
262
c0e5750b 263static int get_max_packet_size(USBHostDevice *s, int pid, int ep)
060dc841 264{
c0e5750b 265 return get_endp(s, pid, ep)->max_packet_size;
060dc841
HG
266}
267
2791104c 268/*
64838171 269 * Async URB state.
060dc841 270 * We always allocate iso packet descriptors even for bulk transfers
2791104c 271 * to simplify allocation and casts.
64838171 272 */
060dc841 273struct AsyncURB
64838171
AL
274{
275 struct usbdevfs_urb urb;
060dc841 276 struct usbdevfs_iso_packet_desc isocpd[ISO_FRAME_DESC_PER_URB];
7a8fc83f
GH
277 USBHostDevice *hdev;
278 QLIST_ENTRY(AsyncURB) next;
b9dc033c 279
060dc841 280 /* For regular async urbs */
64838171 281 USBPacket *packet;
71138531 282 int more; /* large transfer, more urbs follow */
060dc841
HG
283
284 /* For buffered iso handling */
285 int iso_frame_idx; /* -1 means in flight */
286};
b9dc033c 287
7a8fc83f 288static AsyncURB *async_alloc(USBHostDevice *s)
b9dc033c 289{
7267c094 290 AsyncURB *aurb = g_malloc0(sizeof(AsyncURB));
7a8fc83f
GH
291 aurb->hdev = s;
292 QLIST_INSERT_HEAD(&s->aurbs, aurb, next);
293 return aurb;
b9dc033c
AZ
294}
295
64838171 296static void async_free(AsyncURB *aurb)
b9dc033c 297{
7a8fc83f 298 QLIST_REMOVE(aurb, next);
7267c094 299 g_free(aurb);
64838171 300}
b9dc033c 301
41c01ee7
GH
302static void do_disconnect(USBHostDevice *s)
303{
41c01ee7
GH
304 usb_host_close(s);
305 usb_host_auto_check(NULL);
306}
307
64838171
AL
308static void async_complete(void *opaque)
309{
310 USBHostDevice *s = opaque;
311 AsyncURB *aurb;
82887262 312 int urbs = 0;
64838171
AL
313
314 while (1) {
2791104c 315 USBPacket *p;
b9dc033c 316
2791104c 317 int r = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &aurb);
64838171 318 if (r < 0) {
2791104c 319 if (errno == EAGAIN) {
82887262
GH
320 if (urbs > 2) {
321 fprintf(stderr, "husb: %d iso urbs finished at once\n", urbs);
322 }
64838171 323 return;
2791104c 324 }
40197c35
GH
325 if (errno == ENODEV) {
326 if (!s->closing) {
327 trace_usb_host_disconnect(s->bus_num, s->addr);
328 do_disconnect(s);
329 }
64838171
AL
330 return;
331 }
332
e6a2f500 333 perror("USBDEVFS_REAPURBNDELAY");
64838171 334 return;
b9dc033c 335 }
64838171 336
2791104c 337 DPRINTF("husb: async completed. aurb %p status %d alen %d\n",
64838171
AL
338 aurb, aurb->urb.status, aurb->urb.actual_length);
339
060dc841
HG
340 /* If this is a buffered iso urb mark it as complete and don't do
341 anything else (it is handled further in usb_host_handle_iso_data) */
342 if (aurb->iso_frame_idx == -1) {
82887262 343 int inflight;
c0e5750b
GH
344 int pid = (aurb->urb.endpoint & USB_DIR_IN) ?
345 USB_TOKEN_IN : USB_TOKEN_OUT;
346 int ep = aurb->urb.endpoint & 0xf;
060dc841 347 if (aurb->urb.status == -EPIPE) {
c0e5750b 348 set_halt(s, pid, ep);
060dc841
HG
349 }
350 aurb->iso_frame_idx = 0;
82887262 351 urbs++;
c0e5750b
GH
352 inflight = change_iso_inflight(s, pid, ep, -1);
353 if (inflight == 0 && is_iso_started(s, pid, ep)) {
82887262
GH
354 fprintf(stderr, "husb: out of buffers for iso stream\n");
355 }
060dc841
HG
356 continue;
357 }
358
359 p = aurb->packet;
e6a2f500
GH
360 trace_usb_host_urb_complete(s->bus_num, s->addr, aurb, aurb->urb.status,
361 aurb->urb.actual_length, aurb->more);
060dc841 362
2791104c 363 if (p) {
64838171
AL
364 switch (aurb->urb.status) {
365 case 0:
4f4321c1 366 p->result += aurb->urb.actual_length;
64838171
AL
367 break;
368
369 case -EPIPE:
c0e5750b 370 set_halt(s, p->pid, p->devep);
4f4321c1 371 p->result = USB_RET_STALL;
2791104c 372 break;
dcc7e25f 373
64838171 374 default:
4f4321c1 375 p->result = USB_RET_NAK;
64838171
AL
376 break;
377 }
378
50b7963e 379 if (aurb->urb.type == USBDEVFS_URB_TYPE_CONTROL) {
e6a2f500 380 trace_usb_host_req_complete(s->bus_num, s->addr, p->result);
50b7963e 381 usb_generic_async_ctrl_complete(&s->dev, p);
71138531 382 } else if (!aurb->more) {
e6a2f500 383 trace_usb_host_req_complete(s->bus_num, s->addr, p->result);
50b7963e
HG
384 usb_packet_complete(&s->dev, p);
385 }
2791104c 386 }
64838171
AL
387
388 async_free(aurb);
b9dc033c 389 }
b9dc033c
AZ
390}
391
eb5e680a 392static void usb_host_async_cancel(USBDevice *dev, USBPacket *p)
b9dc033c 393{
eb5e680a 394 USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
227ebeb5 395 AsyncURB *aurb;
b9dc033c 396
227ebeb5
GH
397 QLIST_FOREACH(aurb, &s->aurbs, next) {
398 if (p != aurb->packet) {
399 continue;
400 }
64838171 401
227ebeb5 402 DPRINTF("husb: async cancel: packet %p, aurb %p\n", p, aurb);
b9dc033c 403
227ebeb5
GH
404 /* Mark it as dead (see async_complete above) */
405 aurb->packet = NULL;
406
407 int r = ioctl(s->fd, USBDEVFS_DISCARDURB, aurb);
408 if (r < 0) {
409 DPRINTF("husb: async. discard urb failed errno %d\n", errno);
410 }
b9dc033c 411 }
b9dc033c
AZ
412}
413
446ab128 414static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
b9dc033c 415{
41c01ee7 416 const char *op = NULL;
b9dc033c 417 int dev_descr_len, config_descr_len;
d4c4e6fd 418 int interface, nb_interfaces;
b9dc033c
AZ
419 int ret, i;
420
eb7700bb
GH
421 if (configuration == 0) { /* address state - ignore */
422 dev->ninterfaces = 0;
423 dev->configuration = 0;
b9dc033c 424 return 1;
eb7700bb 425 }
b9dc033c 426
d0f2c4c6 427 DPRINTF("husb: claiming interfaces. config %d\n", configuration);
446ab128 428
b9dc033c
AZ
429 i = 0;
430 dev_descr_len = dev->descr[0];
2791104c 431 if (dev_descr_len > dev->descr_len) {
61c1117f
HG
432 fprintf(stderr, "husb: update iface failed. descr too short\n");
433 return 0;
2791104c 434 }
b9dc033c
AZ
435
436 i += dev_descr_len;
437 while (i < dev->descr_len) {
2791104c
DA
438 DPRINTF("husb: i is %d, descr_len is %d, dl %d, dt %d\n",
439 i, dev->descr_len,
b9dc033c 440 dev->descr[i], dev->descr[i+1]);
64838171 441
b9dc033c
AZ
442 if (dev->descr[i+1] != USB_DT_CONFIG) {
443 i += dev->descr[i];
444 continue;
445 }
446 config_descr_len = dev->descr[i];
447
e6a2f500 448 DPRINTF("husb: config #%d need %d\n", dev->descr[i + 5], configuration);
1f3870ab 449
eb7700bb 450 if (configuration == dev->descr[i + 5]) {
446ab128 451 configuration = dev->descr[i + 5];
b9dc033c 452 break;
446ab128 453 }
b9dc033c
AZ
454
455 i += config_descr_len;
456 }
457
458 if (i >= dev->descr_len) {
2791104c
DA
459 fprintf(stderr,
460 "husb: update iface failed. no matching configuration\n");
61c1117f 461 return 0;
b9dc033c
AZ
462 }
463 nb_interfaces = dev->descr[i + 4];
464
465#ifdef USBDEVFS_DISCONNECT
466 /* earlier Linux 2.4 do not support that */
467 {
468 struct usbdevfs_ioctl ctrl;
469 for (interface = 0; interface < nb_interfaces; interface++) {
470 ctrl.ioctl_code = USBDEVFS_DISCONNECT;
471 ctrl.ifno = interface;
021730f7 472 ctrl.data = 0;
41c01ee7 473 op = "USBDEVFS_DISCONNECT";
b9dc033c
AZ
474 ret = ioctl(dev->fd, USBDEVFS_IOCTL, &ctrl);
475 if (ret < 0 && errno != ENODATA) {
b9dc033c
AZ
476 goto fail;
477 }
478 }
479 }
480#endif
481
482 /* XXX: only grab if all interfaces are free */
483 for (interface = 0; interface < nb_interfaces; interface++) {
41c01ee7 484 op = "USBDEVFS_CLAIMINTERFACE";
b9dc033c
AZ
485 ret = ioctl(dev->fd, USBDEVFS_CLAIMINTERFACE, &interface);
486 if (ret < 0) {
41c01ee7 487 goto fail;
b9dc033c
AZ
488 }
489 }
490
e6a2f500
GH
491 trace_usb_host_claim_interfaces(dev->bus_num, dev->addr,
492 nb_interfaces, configuration);
b9dc033c 493
446ab128
AL
494 dev->ninterfaces = nb_interfaces;
495 dev->configuration = configuration;
496 return 1;
41c01ee7
GH
497
498fail:
499 if (errno == ENODEV) {
500 do_disconnect(dev);
501 }
502 perror(op);
503 return 0;
446ab128
AL
504}
505
506static int usb_host_release_interfaces(USBHostDevice *s)
507{
508 int ret, i;
509
e6a2f500 510 trace_usb_host_release_interfaces(s->bus_num, s->addr);
446ab128
AL
511
512 for (i = 0; i < s->ninterfaces; i++) {
513 ret = ioctl(s->fd, USBDEVFS_RELEASEINTERFACE, &i);
514 if (ret < 0) {
e6a2f500 515 perror("USBDEVFS_RELEASEINTERFACE");
446ab128
AL
516 return 0;
517 }
518 }
b9dc033c
AZ
519 return 1;
520}
521
059809e4 522static void usb_host_handle_reset(USBDevice *dev)
bb36d470 523{
26a9e82a 524 USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
64838171 525
e6a2f500 526 trace_usb_host_reset(s->bus_num, s->addr);
64838171 527
bb36d470 528 ioctl(s->fd, USBDEVFS_RESET);
446ab128 529
eb7700bb 530 usb_host_claim_interfaces(s, 0);
9b87e19b 531 usb_linux_update_endp_table(s);
5fafdf24 532}
bb36d470 533
059809e4
FB
534static void usb_host_handle_destroy(USBDevice *dev)
535{
536 USBHostDevice *s = (USBHostDevice *)dev;
537
26a9e82a 538 usb_host_close(s);
9516bb47
GH
539 if (s->hub_fd != -1) {
540 close(s->hub_fd);
541 }
26a9e82a 542 QTAILQ_REMOVE(&hostdevs, s, next);
b373a63a 543 qemu_remove_exit_notifier(&s->exit);
059809e4
FB
544}
545
060dc841
HG
546/* iso data is special, we need to keep enough urbs in flight to make sure
547 that the controller never runs out of them, otherwise the device will
548 likely suffer a buffer underrun / overrun. */
c0e5750b 549static AsyncURB *usb_host_alloc_iso(USBHostDevice *s, int pid, uint8_t ep)
060dc841
HG
550{
551 AsyncURB *aurb;
c0e5750b 552 int i, j, len = get_max_packet_size(s, pid, ep);
060dc841 553
7267c094 554 aurb = g_malloc0(s->iso_urb_count * sizeof(*aurb));
b81bcd8a 555 for (i = 0; i < s->iso_urb_count; i++) {
060dc841
HG
556 aurb[i].urb.endpoint = ep;
557 aurb[i].urb.buffer_length = ISO_FRAME_DESC_PER_URB * len;
7267c094 558 aurb[i].urb.buffer = g_malloc(aurb[i].urb.buffer_length);
060dc841
HG
559 aurb[i].urb.type = USBDEVFS_URB_TYPE_ISO;
560 aurb[i].urb.flags = USBDEVFS_URB_ISO_ASAP;
561 aurb[i].urb.number_of_packets = ISO_FRAME_DESC_PER_URB;
562 for (j = 0 ; j < ISO_FRAME_DESC_PER_URB; j++)
563 aurb[i].urb.iso_frame_desc[j].length = len;
c0e5750b 564 if (pid == USB_TOKEN_IN) {
060dc841
HG
565 aurb[i].urb.endpoint |= 0x80;
566 /* Mark as fully consumed (idle) */
567 aurb[i].iso_frame_idx = ISO_FRAME_DESC_PER_URB;
568 }
569 }
c0e5750b 570 set_iso_urb(s, pid, ep, aurb);
060dc841
HG
571
572 return aurb;
573}
574
c0e5750b 575static void usb_host_stop_n_free_iso(USBHostDevice *s, int pid, uint8_t ep)
060dc841
HG
576{
577 AsyncURB *aurb;
578 int i, ret, killed = 0, free = 1;
579
c0e5750b 580 aurb = get_iso_urb(s, pid, ep);
060dc841
HG
581 if (!aurb) {
582 return;
583 }
584
b81bcd8a 585 for (i = 0; i < s->iso_urb_count; i++) {
060dc841
HG
586 /* in flight? */
587 if (aurb[i].iso_frame_idx == -1) {
588 ret = ioctl(s->fd, USBDEVFS_DISCARDURB, &aurb[i]);
589 if (ret < 0) {
e6a2f500 590 perror("USBDEVFS_DISCARDURB");
060dc841
HG
591 free = 0;
592 continue;
593 }
594 killed++;
595 }
596 }
597
598 /* Make sure any urbs we've killed are reaped before we free them */
599 if (killed) {
600 async_complete(s);
601 }
602
b81bcd8a 603 for (i = 0; i < s->iso_urb_count; i++) {
7267c094 604 g_free(aurb[i].urb.buffer);
060dc841
HG
605 }
606
607 if (free)
7267c094 608 g_free(aurb);
060dc841
HG
609 else
610 printf("husb: leaking iso urbs because of discard failure\n");
c0e5750b
GH
611 set_iso_urb(s, pid, ep, NULL);
612 set_iso_urb_idx(s, pid, ep, 0);
613 clear_iso_started(s, pid, ep);
060dc841
HG
614}
615
616static int urb_status_to_usb_ret(int status)
617{
618 switch (status) {
619 case -EPIPE:
620 return USB_RET_STALL;
621 default:
622 return USB_RET_NAK;
623 }
624}
625
bb6d5498 626static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in)
060dc841
HG
627{
628 AsyncURB *aurb;
bb6d5498 629 int i, j, ret, max_packet_size, offset, len = 0;
4f4321c1 630 uint8_t *buf;
975f2998 631
c0e5750b 632 max_packet_size = get_max_packet_size(s, p->pid, p->devep);
975f2998
HG
633 if (max_packet_size == 0)
634 return USB_RET_NAK;
060dc841 635
c0e5750b 636 aurb = get_iso_urb(s, p->pid, p->devep);
060dc841 637 if (!aurb) {
c0e5750b 638 aurb = usb_host_alloc_iso(s, p->pid, p->devep);
060dc841
HG
639 }
640
c0e5750b 641 i = get_iso_urb_idx(s, p->pid, p->devep);
060dc841
HG
642 j = aurb[i].iso_frame_idx;
643 if (j >= 0 && j < ISO_FRAME_DESC_PER_URB) {
bb6d5498
HG
644 if (in) {
645 /* Check urb status */
646 if (aurb[i].urb.status) {
647 len = urb_status_to_usb_ret(aurb[i].urb.status);
648 /* Move to the next urb */
649 aurb[i].iso_frame_idx = ISO_FRAME_DESC_PER_URB - 1;
650 /* Check frame status */
651 } else if (aurb[i].urb.iso_frame_desc[j].status) {
652 len = urb_status_to_usb_ret(
653 aurb[i].urb.iso_frame_desc[j].status);
654 /* Check the frame fits */
4f4321c1
GH
655 } else if (aurb[i].urb.iso_frame_desc[j].actual_length
656 > p->iov.size) {
bb6d5498
HG
657 printf("husb: received iso data is larger then packet\n");
658 len = USB_RET_NAK;
659 /* All good copy data over */
660 } else {
661 len = aurb[i].urb.iso_frame_desc[j].actual_length;
4f4321c1
GH
662 buf = aurb[i].urb.buffer +
663 j * aurb[i].urb.iso_frame_desc[0].length;
664 usb_packet_copy(p, buf, len);
bb6d5498 665 }
060dc841 666 } else {
4f4321c1 667 len = p->iov.size;
c0e5750b 668 offset = (j == 0) ? 0 : get_iso_buffer_used(s, p->pid, p->devep);
bb6d5498
HG
669
670 /* Check the frame fits */
671 if (len > max_packet_size) {
672 printf("husb: send iso data is larger then max packet size\n");
673 return USB_RET_NAK;
674 }
675
676 /* All good copy data over */
4f4321c1 677 usb_packet_copy(p, aurb[i].urb.buffer + offset, len);
bb6d5498
HG
678 aurb[i].urb.iso_frame_desc[j].length = len;
679 offset += len;
c0e5750b 680 set_iso_buffer_used(s, p->pid, p->devep, offset);
bb6d5498
HG
681
682 /* Start the stream once we have buffered enough data */
c0e5750b
GH
683 if (!is_iso_started(s, p->pid, p->devep) && i == 1 && j == 8) {
684 set_iso_started(s, p->pid, p->devep);
bb6d5498 685 }
060dc841
HG
686 }
687 aurb[i].iso_frame_idx++;
688 if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {
b81bcd8a 689 i = (i + 1) % s->iso_urb_count;
c0e5750b 690 set_iso_urb_idx(s, p->pid, p->devep, i);
060dc841 691 }
bb6d5498
HG
692 } else {
693 if (in) {
c0e5750b 694 set_iso_started(s, p->pid, p->devep);
bb6d5498
HG
695 } else {
696 DPRINTF("hubs: iso out error no free buffer, dropping packet\n");
697 }
060dc841
HG
698 }
699
c0e5750b 700 if (is_iso_started(s, p->pid, p->devep)) {
bb6d5498 701 /* (Re)-submit all fully consumed / filled urbs */
b81bcd8a 702 for (i = 0; i < s->iso_urb_count; i++) {
bb6d5498
HG
703 if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {
704 ret = ioctl(s->fd, USBDEVFS_SUBMITURB, &aurb[i]);
705 if (ret < 0) {
e6a2f500 706 perror("USBDEVFS_SUBMITURB");
bb6d5498
HG
707 if (!in || len == 0) {
708 switch(errno) {
709 case ETIMEDOUT:
710 len = USB_RET_NAK;
0225e254 711 break;
bb6d5498
HG
712 case EPIPE:
713 default:
714 len = USB_RET_STALL;
715 }
060dc841 716 }
bb6d5498 717 break;
060dc841 718 }
bb6d5498 719 aurb[i].iso_frame_idx = -1;
c0e5750b 720 change_iso_inflight(s, p->pid, p->devep, 1);
060dc841 721 }
060dc841
HG
722 }
723 }
724
725 return len;
726}
727
50b7963e 728static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
bb36d470 729{
50b7963e 730 USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
64838171 731 struct usbdevfs_urb *urb;
446ab128 732 AsyncURB *aurb;
b621bab4 733 int ret, rem, prem, v;
71138531 734 uint8_t *pbuf;
060dc841 735 uint8_t ep;
b9dc033c 736
e6a2f500
GH
737 trace_usb_host_req_data(s->bus_num, s->addr,
738 p->pid == USB_TOKEN_IN,
739 p->devep, p->iov.size);
740
c0e5750b 741 if (!is_valid(s, p->pid, p->devep)) {
e6a2f500 742 trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_NAK);
a0b5fece
HG
743 return USB_RET_NAK;
744 }
745
2791104c 746 if (p->pid == USB_TOKEN_IN) {
060dc841 747 ep = p->devep | 0x80;
2791104c 748 } else {
060dc841 749 ep = p->devep;
2791104c 750 }
64838171 751
c0e5750b 752 if (is_halted(s, p->pid, p->devep)) {
9b87e19b
GH
753 unsigned int arg = ep;
754 ret = ioctl(s->fd, USBDEVFS_CLEAR_HALT, &arg);
64838171 755 if (ret < 0) {
e6a2f500
GH
756 perror("USBDEVFS_CLEAR_HALT");
757 trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_NAK);
bb36d470 758 return USB_RET_NAK;
bb36d470 759 }
c0e5750b 760 clear_halt(s, p->pid, p->devep);
4d043a09
AZ
761 }
762
c0e5750b 763 if (is_isoc(s, p->pid, p->devep)) {
bb6d5498
HG
764 return usb_host_handle_iso_data(s, p, p->pid == USB_TOKEN_IN);
765 }
060dc841 766
b621bab4
GH
767 v = 0;
768 prem = p->iov.iov[v].iov_len;
769 pbuf = p->iov.iov[v].iov_base;
770 rem = p->iov.size;
71138531 771 while (rem) {
b621bab4
GH
772 if (prem == 0) {
773 v++;
774 assert(v < p->iov.niov);
775 prem = p->iov.iov[v].iov_len;
776 pbuf = p->iov.iov[v].iov_base;
777 assert(prem <= rem);
778 }
71138531
GH
779 aurb = async_alloc(s);
780 aurb->packet = p;
781
782 urb = &aurb->urb;
783 urb->endpoint = ep;
784 urb->type = USBDEVFS_URB_TYPE_BULK;
785 urb->usercontext = s;
786 urb->buffer = pbuf;
b621bab4 787 urb->buffer_length = prem;
71138531 788
b621bab4 789 if (urb->buffer_length > MAX_USBFS_BUFFER_SIZE) {
71138531 790 urb->buffer_length = MAX_USBFS_BUFFER_SIZE;
71138531
GH
791 }
792 pbuf += urb->buffer_length;
b621bab4 793 prem -= urb->buffer_length;
71138531 794 rem -= urb->buffer_length;
b621bab4
GH
795 if (rem) {
796 aurb->more = 1;
797 }
b9dc033c 798
e6a2f500
GH
799 trace_usb_host_urb_submit(s->bus_num, s->addr, aurb,
800 urb->buffer_length, aurb->more);
71138531 801 ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
b9dc033c 802
71138531
GH
803 DPRINTF("husb: data submit: ep 0x%x, len %u, more %d, packet %p, aurb %p\n",
804 urb->endpoint, urb->buffer_length, aurb->more, p, aurb);
b9dc033c 805
71138531 806 if (ret < 0) {
e6a2f500 807 perror("USBDEVFS_SUBMITURB");
71138531 808 async_free(aurb);
b9dc033c 809
71138531
GH
810 switch(errno) {
811 case ETIMEDOUT:
e6a2f500 812 trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_NAK);
71138531
GH
813 return USB_RET_NAK;
814 case EPIPE:
815 default:
e6a2f500 816 trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_STALL);
71138531
GH
817 return USB_RET_STALL;
818 }
b9dc033c
AZ
819 }
820 }
64838171 821
b9dc033c 822 return USB_RET_ASYNC;
b9dc033c
AZ
823}
824
446ab128
AL
825static int ctrl_error(void)
826{
2791104c 827 if (errno == ETIMEDOUT) {
446ab128 828 return USB_RET_NAK;
2791104c 829 } else {
446ab128 830 return USB_RET_STALL;
2791104c 831 }
446ab128
AL
832}
833
834static int usb_host_set_address(USBHostDevice *s, int addr)
835{
e6a2f500 836 trace_usb_host_set_address(s->bus_num, s->addr, addr);
446ab128
AL
837 s->dev.addr = addr;
838 return 0;
839}
840
841static int usb_host_set_config(USBHostDevice *s, int config)
842{
e6a2f500
GH
843 trace_usb_host_set_config(s->bus_num, s->addr, config);
844
446ab128
AL
845 usb_host_release_interfaces(s);
846
847 int ret = ioctl(s->fd, USBDEVFS_SETCONFIGURATION, &config);
2791104c 848
d0f2c4c6 849 DPRINTF("husb: ctrl set config %d ret %d errno %d\n", config, ret, errno);
2791104c
DA
850
851 if (ret < 0) {
446ab128 852 return ctrl_error();
2791104c 853 }
446ab128 854 usb_host_claim_interfaces(s, config);
eb7700bb 855 usb_linux_update_endp_table(s);
446ab128
AL
856 return 0;
857}
858
859static int usb_host_set_interface(USBHostDevice *s, int iface, int alt)
860{
861 struct usbdevfs_setinterface si;
060dc841
HG
862 int i, ret;
863
e6a2f500
GH
864 trace_usb_host_set_interface(s->bus_num, s->addr, iface, alt);
865
3a4854b3 866 for (i = 1; i <= MAX_ENDPOINTS; i++) {
c0e5750b
GH
867 if (is_isoc(s, USB_TOKEN_IN, i)) {
868 usb_host_stop_n_free_iso(s, USB_TOKEN_IN, i);
869 }
870 if (is_isoc(s, USB_TOKEN_OUT, i)) {
871 usb_host_stop_n_free_iso(s, USB_TOKEN_OUT, i);
060dc841
HG
872 }
873 }
446ab128
AL
874
875 si.interface = iface;
876 si.altsetting = alt;
877 ret = ioctl(s->fd, USBDEVFS_SETINTERFACE, &si);
446ab128 878
2791104c
DA
879 DPRINTF("husb: ctrl set iface %d altset %d ret %d errno %d\n",
880 iface, alt, ret, errno);
881
882 if (ret < 0) {
883 return ctrl_error();
884 }
446ab128
AL
885 usb_linux_update_endp_table(s);
886 return 0;
887}
888
50b7963e
HG
889static int usb_host_handle_control(USBDevice *dev, USBPacket *p,
890 int request, int value, int index, int length, uint8_t *data)
446ab128 891{
50b7963e 892 USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
446ab128
AL
893 struct usbdevfs_urb *urb;
894 AsyncURB *aurb;
50b7963e 895 int ret;
446ab128 896
2791104c 897 /*
446ab128
AL
898 * Process certain standard device requests.
899 * These are infrequent and are processed synchronously.
900 */
446ab128 901
50b7963e 902 /* Note request is (bRequestType << 8) | bRequest */
e6a2f500 903 trace_usb_host_req_control(s->bus_num, s->addr, request, value, index);
446ab128 904
50b7963e
HG
905 switch (request) {
906 case DeviceOutRequest | USB_REQ_SET_ADDRESS:
907 return usb_host_set_address(s, value);
446ab128 908
50b7963e
HG
909 case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
910 return usb_host_set_config(s, value & 0xff);
446ab128 911
50b7963e 912 case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
446ab128 913 return usb_host_set_interface(s, index, value);
2791104c 914 }
446ab128
AL
915
916 /* The rest are asynchronous */
917
50b7963e
HG
918 if (length > sizeof(dev->data_buf)) {
919 fprintf(stderr, "husb: ctrl buffer too small (%d > %zu)\n",
920 length, sizeof(dev->data_buf));
b2e3b6e9 921 return USB_RET_STALL;
c4c0e236
JP
922 }
923
7a8fc83f 924 aurb = async_alloc(s);
446ab128
AL
925 aurb->packet = p;
926
2791104c 927 /*
446ab128
AL
928 * Setup ctrl transfer.
929 *
a0102082 930 * s->ctrl is laid out such that data buffer immediately follows
446ab128 931 * 'req' struct which is exactly what usbdevfs expects.
2791104c 932 */
446ab128
AL
933 urb = &aurb->urb;
934
935 urb->type = USBDEVFS_URB_TYPE_CONTROL;
936 urb->endpoint = p->devep;
937
50b7963e
HG
938 urb->buffer = &dev->setup_buf;
939 urb->buffer_length = length + 8;
446ab128
AL
940
941 urb->usercontext = s;
942
e6a2f500
GH
943 trace_usb_host_urb_submit(s->bus_num, s->addr, aurb,
944 urb->buffer_length, aurb->more);
446ab128
AL
945 ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
946
d0f2c4c6 947 DPRINTF("husb: submit ctrl. len %u aurb %p\n", urb->buffer_length, aurb);
446ab128
AL
948
949 if (ret < 0) {
d0f2c4c6 950 DPRINTF("husb: submit failed. errno %d\n", errno);
446ab128
AL
951 async_free(aurb);
952
953 switch(errno) {
954 case ETIMEDOUT:
955 return USB_RET_NAK;
956 case EPIPE:
957 default:
958 return USB_RET_STALL;
959 }
960 }
961
446ab128
AL
962 return USB_RET_ASYNC;
963}
964
ed3a328d
HG
965static uint8_t usb_linux_get_alt_setting(USBHostDevice *s,
966 uint8_t configuration, uint8_t interface)
967{
968 uint8_t alt_setting;
969 struct usb_ctrltransfer ct;
970 int ret;
971
c43831fb
HG
972 if (usb_fs_type == USB_FS_SYS) {
973 char device_name[64], line[1024];
974 int alt_setting;
975
5557d820 976 sprintf(device_name, "%d-%s:%d.%d", s->bus_num, s->port,
c43831fb
HG
977 (int)configuration, (int)interface);
978
979 if (!usb_host_read_file(line, sizeof(line), "bAlternateSetting",
980 device_name)) {
981 goto usbdevfs;
982 }
983 if (sscanf(line, "%d", &alt_setting) != 1) {
984 goto usbdevfs;
985 }
986 return alt_setting;
987 }
988
989usbdevfs:
ed3a328d
HG
990 ct.bRequestType = USB_DIR_IN | USB_RECIP_INTERFACE;
991 ct.bRequest = USB_REQ_GET_INTERFACE;
992 ct.wValue = 0;
993 ct.wIndex = interface;
994 ct.wLength = 1;
995 ct.data = &alt_setting;
996 ct.timeout = 50;
997 ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
998 if (ret < 0) {
999 /* Assume alt 0 on error */
1000 return 0;
1001 }
1002
1003 return alt_setting;
1004}
1005
71d71bbd
HG
1006/* returns 1 on problem encountered or 0 for success */
1007static int usb_linux_update_endp_table(USBHostDevice *s)
1008{
1009 uint8_t *descriptors;
eb7700bb 1010 uint8_t devep, type, alt_interface;
c0e5750b
GH
1011 int interface, length, i, ep, pid;
1012 struct endp_data *epd;
71d71bbd 1013
c0e5750b
GH
1014 for (i = 0; i < MAX_ENDPOINTS; i++) {
1015 s->ep_in[i].type = INVALID_EP_TYPE;
1016 s->ep_out[i].type = INVALID_EP_TYPE;
1017 }
a0b5fece 1018
eb7700bb
GH
1019 if (s->configuration == 0) {
1020 /* not configured yet -- leave all endpoints disabled */
1021 return 0;
1022 }
71d71bbd 1023
b9dc033c
AZ
1024 /* get the desired configuration, interface, and endpoint descriptors
1025 * from device description */
1026 descriptors = &s->descr[18];
1027 length = s->descr_len - 18;
1028 i = 0;
1029
1030 if (descriptors[i + 1] != USB_DT_CONFIG ||
eb7700bb
GH
1031 descriptors[i + 5] != s->configuration) {
1032 fprintf(stderr, "invalid descriptor data - configuration %d\n",
1033 s->configuration);
b9dc033c
AZ
1034 return 1;
1035 }
1036 i += descriptors[i];
1037
1038 while (i < length) {
1039 if (descriptors[i + 1] != USB_DT_INTERFACE ||
1040 (descriptors[i + 1] == USB_DT_INTERFACE &&
1041 descriptors[i + 4] == 0)) {
1042 i += descriptors[i];
1043 continue;
1044 }
1045
1046 interface = descriptors[i + 2];
eb7700bb
GH
1047 alt_interface = usb_linux_get_alt_setting(s, s->configuration,
1048 interface);
b9dc033c
AZ
1049
1050 /* the current interface descriptor is the active interface
1051 * and has endpoints */
1052 if (descriptors[i + 3] != alt_interface) {
1053 i += descriptors[i];
1054 continue;
1055 }
1056
1057 /* advance to the endpoints */
2791104c 1058 while (i < length && descriptors[i +1] != USB_DT_ENDPOINT) {
b9dc033c 1059 i += descriptors[i];
2791104c 1060 }
b9dc033c
AZ
1061
1062 if (i >= length)
1063 break;
1064
1065 while (i < length) {
2791104c 1066 if (descriptors[i + 1] != USB_DT_ENDPOINT) {
b9dc033c 1067 break;
2791104c 1068 }
b9dc033c
AZ
1069
1070 devep = descriptors[i + 2];
c0e5750b
GH
1071 pid = (devep & USB_DIR_IN) ? USB_TOKEN_IN : USB_TOKEN_OUT;
1072 ep = devep & 0xf;
1073 if (ep == 0) {
130314f8
HG
1074 fprintf(stderr, "usb-linux: invalid ep descriptor, ep == 0\n");
1075 return 1;
1076 }
1077
b9dc033c
AZ
1078 switch (descriptors[i + 3] & 0x3) {
1079 case 0x00:
1080 type = USBDEVFS_URB_TYPE_CONTROL;
1081 break;
1082 case 0x01:
1083 type = USBDEVFS_URB_TYPE_ISO;
c0e5750b 1084 set_max_packet_size(s, pid, ep, descriptors + i);
b9dc033c
AZ
1085 break;
1086 case 0x02:
1087 type = USBDEVFS_URB_TYPE_BULK;
1088 break;
1089 case 0x03:
1090 type = USBDEVFS_URB_TYPE_INTERRUPT;
1091 break;
ddbda432
AL
1092 default:
1093 DPRINTF("usb_host: malformed endpoint type\n");
1094 type = USBDEVFS_URB_TYPE_BULK;
b9dc033c 1095 }
c0e5750b
GH
1096 epd = get_endp(s, pid, ep);
1097 assert(epd->type == INVALID_EP_TYPE);
1098 epd->type = type;
1099 epd->halted = 0;
b9dc033c
AZ
1100
1101 i += descriptors[i];
1102 }
1103 }
1104 return 0;
1105}
1106
e4b17767
HG
1107/*
1108 * Check if we can safely redirect a usb2 device to a usb1 virtual controller,
1109 * this function assumes this is safe, if:
1110 * 1) There are no isoc endpoints
1111 * 2) There are no interrupt endpoints with a max_packet_size > 64
1112 * Note bulk endpoints with a max_packet_size > 64 in theory also are not
1113 * usb1 compatible, but in practice this seems to work fine.
1114 */
1115static int usb_linux_full_speed_compat(USBHostDevice *dev)
1116{
1117 int i, packet_size;
1118
1119 /*
1120 * usb_linux_update_endp_table only registers info about ep in the current
1121 * interface altsettings, so we need to parse the descriptors again.
1122 */
1123 for (i = 0; (i + 5) < dev->descr_len; i += dev->descr[i]) {
1124 if (dev->descr[i + 1] == USB_DT_ENDPOINT) {
1125 switch (dev->descr[i + 3] & 0x3) {
1126 case 0x00: /* CONTROL */
1127 break;
1128 case 0x01: /* ISO */
1129 return 0;
1130 case 0x02: /* BULK */
1131 break;
1132 case 0x03: /* INTERRUPT */
1133 packet_size = dev->descr[i + 4] + (dev->descr[i + 5] << 8);
1134 if (packet_size > 64)
1135 return 0;
1136 break;
1137 }
1138 }
1139 }
1140 return 1;
1141}
1142
26a9e82a 1143static int usb_host_open(USBHostDevice *dev, int bus_num,
ba9acab9
GH
1144 int addr, const char *port,
1145 const char *prod_name, int speed)
bb36d470 1146{
b9dc033c 1147 int fd = -1, ret;
a594cfbf 1148 char buf[1024];
1f3870ab 1149
e6a2f500
GH
1150 trace_usb_host_open_started(bus_num, addr);
1151
2791104c 1152 if (dev->fd != -1) {
26a9e82a 1153 goto fail;
2791104c 1154 }
3b46e624 1155
0f431527
AL
1156 if (!usb_host_device_path) {
1157 perror("husb: USB Host Device Path not set");
1158 goto fail;
1159 }
1160 snprintf(buf, sizeof(buf), "%s/%03d/%03d", usb_host_device_path,
a594cfbf 1161 bus_num, addr);
b9dc033c 1162 fd = open(buf, O_RDWR | O_NONBLOCK);
bb36d470 1163 if (fd < 0) {
a594cfbf 1164 perror(buf);
1f3870ab 1165 goto fail;
bb36d470 1166 }
d0f2c4c6 1167 DPRINTF("husb: opened %s\n", buf);
bb36d470 1168
806b6024
GH
1169 dev->bus_num = bus_num;
1170 dev->addr = addr;
5557d820 1171 strcpy(dev->port, port);
22f84e73 1172 dev->fd = fd;
806b6024 1173
b9dc033c
AZ
1174 /* read the device description */
1175 dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
1176 if (dev->descr_len <= 0) {
64838171 1177 perror("husb: reading device data failed");
bb36d470
FB
1178 goto fail;
1179 }
3b46e624 1180
b9dc033c 1181#ifdef DEBUG
868bfe2b 1182 {
b9dc033c
AZ
1183 int x;
1184 printf("=== begin dumping device descriptor data ===\n");
2791104c 1185 for (x = 0; x < dev->descr_len; x++) {
b9dc033c 1186 printf("%02x ", dev->descr[x]);
2791104c 1187 }
b9dc033c 1188 printf("\n=== end dumping device descriptor data ===\n");
bb36d470 1189 }
a594cfbf
FB
1190#endif
1191
b9dc033c 1192
eb7700bb
GH
1193 /* start unconfigured -- we'll wait for the guest to set a configuration */
1194 if (!usb_host_claim_interfaces(dev, 0)) {
b9dc033c 1195 goto fail;
2791104c 1196 }
bb36d470 1197
b9dc033c 1198 ret = usb_linux_update_endp_table(dev);
2791104c 1199 if (ret) {
bb36d470 1200 goto fail;
2791104c 1201 }
b9dc033c 1202
3991c35e
HG
1203 if (speed == -1) {
1204 struct usbdevfs_connectinfo ci;
1205
1206 ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
1207 if (ret < 0) {
1208 perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
1209 goto fail;
1210 }
1211
1212 if (ci.slow) {
1213 speed = USB_SPEED_LOW;
1214 } else {
1215 speed = USB_SPEED_HIGH;
1216 }
2791104c 1217 }
3991c35e 1218 dev->dev.speed = speed;
ba3f9bfb 1219 dev->dev.speedmask = (1 << speed);
e4b17767
HG
1220 if (dev->dev.speed == USB_SPEED_HIGH && usb_linux_full_speed_compat(dev)) {
1221 dev->dev.speedmask |= USB_SPEED_MASK_FULL;
1222 }
3991c35e 1223
e6a2f500 1224 trace_usb_host_open_success(bus_num, addr);
bb36d470 1225
2791104c 1226 if (!prod_name || prod_name[0] == '\0') {
0fe6d12e 1227 snprintf(dev->dev.product_desc, sizeof(dev->dev.product_desc),
4b096fc9 1228 "host:%d.%d", bus_num, addr);
2791104c 1229 } else {
0fe6d12e 1230 pstrcpy(dev->dev.product_desc, sizeof(dev->dev.product_desc),
4b096fc9 1231 prod_name);
2791104c 1232 }
1f6e24e7 1233
fa19bf83
HG
1234 ret = usb_device_attach(&dev->dev);
1235 if (ret) {
1236 goto fail;
1237 }
1238
64838171
AL
1239 /* USB devio uses 'write' flag to check for async completions */
1240 qemu_set_fd_handler(dev->fd, NULL, async_complete, dev);
1f3870ab 1241
26a9e82a 1242 return 0;
4b096fc9 1243
b9dc033c 1244fail:
e6a2f500 1245 trace_usb_host_open_failure(bus_num, addr);
1f45a81b
GH
1246 if (dev->fd != -1) {
1247 close(dev->fd);
1248 dev->fd = -1;
2791104c 1249 }
26a9e82a
GH
1250 return -1;
1251}
1252
1253static int usb_host_close(USBHostDevice *dev)
1254{
060dc841
HG
1255 int i;
1256
1f45a81b 1257 if (dev->fd == -1 || !dev->dev.attached) {
26a9e82a 1258 return -1;
2791104c 1259 }
26a9e82a 1260
e6a2f500
GH
1261 trace_usb_host_close(dev->bus_num, dev->addr);
1262
26a9e82a
GH
1263 qemu_set_fd_handler(dev->fd, NULL, NULL, NULL);
1264 dev->closing = 1;
3a4854b3 1265 for (i = 1; i <= MAX_ENDPOINTS; i++) {
c0e5750b
GH
1266 if (is_isoc(dev, USB_TOKEN_IN, i)) {
1267 usb_host_stop_n_free_iso(dev, USB_TOKEN_IN, i);
1268 }
1269 if (is_isoc(dev, USB_TOKEN_OUT, i)) {
1270 usb_host_stop_n_free_iso(dev, USB_TOKEN_OUT, i);
060dc841
HG
1271 }
1272 }
26a9e82a
GH
1273 async_complete(dev);
1274 dev->closing = 0;
1275 usb_device_detach(&dev->dev);
00ff227a 1276 ioctl(dev->fd, USBDEVFS_RESET);
26a9e82a
GH
1277 close(dev->fd);
1278 dev->fd = -1;
1279 return 0;
1280}
1281
9e8dd451 1282static void usb_host_exit_notifier(struct Notifier *n, void *data)
b373a63a
SH
1283{
1284 USBHostDevice *s = container_of(n, USBHostDevice, exit);
1285
1286 if (s->fd != -1) {
1287 ioctl(s->fd, USBDEVFS_RESET);
1288 }
1289}
1290
26a9e82a
GH
1291static int usb_host_initfn(USBDevice *dev)
1292{
1293 USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
1294
1295 dev->auto_attach = 0;
1296 s->fd = -1;
9516bb47
GH
1297 s->hub_fd = -1;
1298
26a9e82a 1299 QTAILQ_INSERT_TAIL(&hostdevs, s, next);
b373a63a
SH
1300 s->exit.notify = usb_host_exit_notifier;
1301 qemu_add_exit_notifier(&s->exit);
26a9e82a 1302 usb_host_auto_check(NULL);
9516bb47
GH
1303
1304#ifdef USBDEVFS_CLAIM_PORT
1305 if (s->match.bus_num != 0 && s->match.port != NULL) {
1306 char *h, hub_name[64], line[1024];
1307 int hub_addr, portnr, ret;
1308
1309 snprintf(hub_name, sizeof(hub_name), "%d-%s",
1310 s->match.bus_num, s->match.port);
1311
1312 /* try strip off last ".$portnr" to get hub */
1313 h = strrchr(hub_name, '.');
1314 if (h != NULL) {
1315 portnr = atoi(h+1);
1316 *h = '\0';
1317 } else {
1318 /* no dot in there -> it is the root hub */
1319 snprintf(hub_name, sizeof(hub_name), "usb%d",
1320 s->match.bus_num);
1321 portnr = atoi(s->match.port);
1322 }
1323
1324 if (!usb_host_read_file(line, sizeof(line), "devnum",
1325 hub_name)) {
1326 goto out;
1327 }
1328 if (sscanf(line, "%d", &hub_addr) != 1) {
1329 goto out;
1330 }
1331
1332 if (!usb_host_device_path) {
1333 goto out;
1334 }
1335 snprintf(line, sizeof(line), "%s/%03d/%03d",
1336 usb_host_device_path, s->match.bus_num, hub_addr);
1337 s->hub_fd = open(line, O_RDWR | O_NONBLOCK);
1338 if (s->hub_fd < 0) {
1339 goto out;
1340 }
1341
1342 ret = ioctl(s->hub_fd, USBDEVFS_CLAIM_PORT, &portnr);
1343 if (ret < 0) {
1344 close(s->hub_fd);
1345 s->hub_fd = -1;
1346 goto out;
1347 }
1348
1349 trace_usb_host_claim_port(s->match.bus_num, hub_addr, portnr);
1350 }
1351out:
1352#endif
1353
26a9e82a 1354 return 0;
a594cfbf 1355}
bb36d470 1356
d6791578
GH
1357static const VMStateDescription vmstate_usb_host = {
1358 .name = "usb-host",
1359 .unmigratable = 1,
1360};
1361
806b6024 1362static struct USBDeviceInfo usb_host_dev_info = {
06384698 1363 .product_desc = "USB Host Device",
556cd098 1364 .qdev.name = "usb-host",
806b6024 1365 .qdev.size = sizeof(USBHostDevice),
d6791578 1366 .qdev.vmsd = &vmstate_usb_host,
806b6024 1367 .init = usb_host_initfn,
50b7963e 1368 .handle_packet = usb_generic_handle_packet,
eb5e680a 1369 .cancel_packet = usb_host_async_cancel,
50b7963e
HG
1370 .handle_data = usb_host_handle_data,
1371 .handle_control = usb_host_handle_control,
806b6024 1372 .handle_reset = usb_host_handle_reset,
806b6024 1373 .handle_destroy = usb_host_handle_destroy,
26a9e82a
GH
1374 .usbdevice_name = "host",
1375 .usbdevice_init = usb_host_device_open,
1376 .qdev.props = (Property[]) {
1377 DEFINE_PROP_UINT32("hostbus", USBHostDevice, match.bus_num, 0),
1378 DEFINE_PROP_UINT32("hostaddr", USBHostDevice, match.addr, 0),
9056a297 1379 DEFINE_PROP_STRING("hostport", USBHostDevice, match.port),
26a9e82a
GH
1380 DEFINE_PROP_HEX32("vendorid", USBHostDevice, match.vendor_id, 0),
1381 DEFINE_PROP_HEX32("productid", USBHostDevice, match.product_id, 0),
b81bcd8a 1382 DEFINE_PROP_UINT32("isobufs", USBHostDevice, iso_urb_count, 4),
26a9e82a
GH
1383 DEFINE_PROP_END_OF_LIST(),
1384 },
806b6024
GH
1385};
1386
1387static void usb_host_register_devices(void)
1388{
1389 usb_qdev_register(&usb_host_dev_info);
1390}
1391device_init(usb_host_register_devices)
1392
4b096fc9
AL
1393USBDevice *usb_host_device_open(const char *devname)
1394{
0745eb1e 1395 struct USBAutoFilter filter;
26a9e82a 1396 USBDevice *dev;
26a9e82a
GH
1397 char *p;
1398
556cd098 1399 dev = usb_create(NULL /* FIXME */, "usb-host");
4b096fc9 1400
5d0c5750 1401 if (strstr(devname, "auto:")) {
2791104c 1402 if (parse_filter(devname, &filter) < 0) {
26a9e82a 1403 goto fail;
2791104c 1404 }
26a9e82a
GH
1405 } else {
1406 if ((p = strchr(devname, '.'))) {
0745eb1e
MA
1407 filter.bus_num = strtoul(devname, NULL, 0);
1408 filter.addr = strtoul(p + 1, NULL, 0);
1409 filter.vendor_id = 0;
1410 filter.product_id = 0;
26a9e82a 1411 } else if ((p = strchr(devname, ':'))) {
0745eb1e
MA
1412 filter.bus_num = 0;
1413 filter.addr = 0;
26a9e82a 1414 filter.vendor_id = strtoul(devname, NULL, 16);
0745eb1e 1415 filter.product_id = strtoul(p + 1, NULL, 16);
26a9e82a
GH
1416 } else {
1417 goto fail;
1418 }
5d0c5750 1419 }
4b096fc9 1420
0745eb1e
MA
1421 qdev_prop_set_uint32(&dev->qdev, "hostbus", filter.bus_num);
1422 qdev_prop_set_uint32(&dev->qdev, "hostaddr", filter.addr);
26a9e82a
GH
1423 qdev_prop_set_uint32(&dev->qdev, "vendorid", filter.vendor_id);
1424 qdev_prop_set_uint32(&dev->qdev, "productid", filter.product_id);
beb6f0de 1425 qdev_init_nofail(&dev->qdev);
26a9e82a 1426 return dev;
5d0c5750 1427
26a9e82a
GH
1428fail:
1429 qdev_free(&dev->qdev);
1430 return NULL;
4b096fc9 1431}
5d0c5750
AL
1432
1433int usb_host_device_close(const char *devname)
1434{
26a9e82a 1435#if 0
5d0c5750
AL
1436 char product_name[PRODUCT_NAME_SZ];
1437 int bus_num, addr;
1438 USBHostDevice *s;
1439
2791104c 1440 if (strstr(devname, "auto:")) {
5d0c5750 1441 return usb_host_auto_del(devname);
2791104c
DA
1442 }
1443 if (usb_host_find_device(&bus_num, &addr, product_name,
1444 sizeof(product_name), devname) < 0) {
5d0c5750 1445 return -1;
2791104c 1446 }
5d0c5750
AL
1447 s = hostdev_find(bus_num, addr);
1448 if (s) {
a5d2f727 1449 usb_device_delete_addr(s->bus_num, s->dev.addr);
5d0c5750
AL
1450 return 0;
1451 }
26a9e82a 1452#endif
5d0c5750
AL
1453
1454 return -1;
1455}
a5d2f727 1456
a594cfbf 1457static int get_tag_value(char *buf, int buf_size,
5fafdf24 1458 const char *str, const char *tag,
a594cfbf
FB
1459 const char *stopchars)
1460{
1461 const char *p;
1462 char *q;
1463 p = strstr(str, tag);
2791104c 1464 if (!p) {
a594cfbf 1465 return -1;
2791104c 1466 }
a594cfbf 1467 p += strlen(tag);
2791104c 1468 while (qemu_isspace(*p)) {
a594cfbf 1469 p++;
2791104c 1470 }
a594cfbf
FB
1471 q = buf;
1472 while (*p != '\0' && !strchr(stopchars, *p)) {
2791104c 1473 if ((q - buf) < (buf_size - 1)) {
a594cfbf 1474 *q++ = *p;
2791104c 1475 }
a594cfbf
FB
1476 p++;
1477 }
1478 *q = '\0';
1479 return q - buf;
bb36d470
FB
1480}
1481
0f431527
AL
1482/*
1483 * Use /proc/bus/usb/devices or /dev/bus/usb/devices file to determine
1484 * host's USB devices. This is legacy support since many distributions
1485 * are moving to /sys/bus/usb
1486 */
1487static int usb_host_scan_dev(void *opaque, USBScanFunc *func)
bb36d470 1488{
660f11be 1489 FILE *f = NULL;
a594cfbf 1490 char line[1024];
bb36d470 1491 char buf[1024];
0c402e5a
GH
1492 int bus_num, addr, speed, device_count;
1493 int class_id, product_id, vendor_id, port;
a594cfbf 1494 char product_name[512];
0f431527 1495 int ret = 0;
3b46e624 1496
0f431527
AL
1497 if (!usb_host_device_path) {
1498 perror("husb: USB Host Device Path not set");
1499 goto the_end;
1500 }
1501 snprintf(line, sizeof(line), "%s/devices", usb_host_device_path);
1502 f = fopen(line, "r");
a594cfbf 1503 if (!f) {
0f431527
AL
1504 perror("husb: cannot open devices file");
1505 goto the_end;
a594cfbf 1506 }
0f431527 1507
a594cfbf 1508 device_count = 0;
0c402e5a 1509 bus_num = addr = class_id = product_id = vendor_id = port = 0;
3991c35e 1510 speed = -1; /* Can't get the speed from /[proc|dev]/bus/usb/devices */
bb36d470 1511 for(;;) {
2791104c 1512 if (fgets(line, sizeof(line), f) == NULL) {
bb36d470 1513 break;
2791104c
DA
1514 }
1515 if (strlen(line) > 0) {
a594cfbf 1516 line[strlen(line) - 1] = '\0';
2791104c 1517 }
a594cfbf 1518 if (line[0] == 'T' && line[1] == ':') {
38ca0f6d
PB
1519 if (device_count && (vendor_id || product_id)) {
1520 /* New device. Add the previously discovered device. */
0f5160d1 1521 ret = func(opaque, bus_num, addr, 0, class_id, vendor_id,
a594cfbf 1522 product_id, product_name, speed);
2791104c 1523 if (ret) {
a594cfbf 1524 goto the_end;
2791104c 1525 }
a594cfbf 1526 }
2791104c 1527 if (get_tag_value(buf, sizeof(buf), line, "Bus=", " ") < 0) {
a594cfbf 1528 goto fail;
2791104c 1529 }
a594cfbf 1530 bus_num = atoi(buf);
0c402e5a
GH
1531 if (get_tag_value(buf, sizeof(buf), line, "Port=", " ") < 0) {
1532 goto fail;
1533 }
1534 port = atoi(buf);
2791104c 1535 if (get_tag_value(buf, sizeof(buf), line, "Dev#=", " ") < 0) {
a594cfbf 1536 goto fail;
2791104c 1537 }
a594cfbf 1538 addr = atoi(buf);
2791104c 1539 if (get_tag_value(buf, sizeof(buf), line, "Spd=", " ") < 0) {
a594cfbf 1540 goto fail;
2791104c 1541 }
f264cfbf
HG
1542 if (!strcmp(buf, "5000")) {
1543 speed = USB_SPEED_SUPER;
1544 } else if (!strcmp(buf, "480")) {
a594cfbf 1545 speed = USB_SPEED_HIGH;
2791104c 1546 } else if (!strcmp(buf, "1.5")) {
a594cfbf 1547 speed = USB_SPEED_LOW;
2791104c 1548 } else {
a594cfbf 1549 speed = USB_SPEED_FULL;
2791104c 1550 }
a594cfbf
FB
1551 product_name[0] = '\0';
1552 class_id = 0xff;
1553 device_count++;
1554 product_id = 0;
1555 vendor_id = 0;
1556 } else if (line[0] == 'P' && line[1] == ':') {
2791104c 1557 if (get_tag_value(buf, sizeof(buf), line, "Vendor=", " ") < 0) {
a594cfbf 1558 goto fail;
2791104c 1559 }
a594cfbf 1560 vendor_id = strtoul(buf, NULL, 16);
2791104c 1561 if (get_tag_value(buf, sizeof(buf), line, "ProdID=", " ") < 0) {
a594cfbf 1562 goto fail;
2791104c 1563 }
a594cfbf
FB
1564 product_id = strtoul(buf, NULL, 16);
1565 } else if (line[0] == 'S' && line[1] == ':') {
2791104c 1566 if (get_tag_value(buf, sizeof(buf), line, "Product=", "") < 0) {
a594cfbf 1567 goto fail;
2791104c 1568 }
a594cfbf
FB
1569 pstrcpy(product_name, sizeof(product_name), buf);
1570 } else if (line[0] == 'D' && line[1] == ':') {
2791104c 1571 if (get_tag_value(buf, sizeof(buf), line, "Cls=", " (") < 0) {
a594cfbf 1572 goto fail;
2791104c 1573 }
a594cfbf 1574 class_id = strtoul(buf, NULL, 16);
bb36d470 1575 }
a594cfbf
FB
1576 fail: ;
1577 }
38ca0f6d
PB
1578 if (device_count && (vendor_id || product_id)) {
1579 /* Add the last device. */
0c402e5a
GH
1580 if (port > 0) {
1581 snprintf(buf, sizeof(buf), "%d", port);
1582 } else {
1583 snprintf(buf, sizeof(buf), "?");
1584 }
1585 ret = func(opaque, bus_num, addr, buf, class_id, vendor_id,
a594cfbf 1586 product_id, product_name, speed);
bb36d470 1587 }
a594cfbf 1588 the_end:
2791104c 1589 if (f) {
0f431527 1590 fclose(f);
2791104c 1591 }
0f431527
AL
1592 return ret;
1593}
1594
1595/*
1596 * Read sys file-system device file
1597 *
1598 * @line address of buffer to put file contents in
1599 * @line_size size of line
1600 * @device_file path to device file (printf format string)
1601 * @device_name device being opened (inserted into device_file)
1602 *
1603 * @return 0 failed, 1 succeeded ('line' contains data)
1604 */
2791104c
DA
1605static int usb_host_read_file(char *line, size_t line_size,
1606 const char *device_file, const char *device_name)
0f431527
AL
1607{
1608 FILE *f;
1609 int ret = 0;
1610 char filename[PATH_MAX];
1611
b4e237aa
BS
1612 snprintf(filename, PATH_MAX, USBSYSBUS_PATH "/devices/%s/%s", device_name,
1613 device_file);
0f431527
AL
1614 f = fopen(filename, "r");
1615 if (f) {
9f99cee7 1616 ret = fgets(line, line_size, f) != NULL;
0f431527 1617 fclose(f);
0f431527
AL
1618 }
1619
1620 return ret;
1621}
1622
1623/*
1624 * Use /sys/bus/usb/devices/ directory to determine host's USB
1625 * devices.
1626 *
1627 * This code is based on Robert Schiele's original patches posted to
1628 * the Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
1629 */
1630static int usb_host_scan_sys(void *opaque, USBScanFunc *func)
1631{
660f11be 1632 DIR *dir = NULL;
0f431527 1633 char line[1024];
5557d820 1634 int bus_num, addr, speed, class_id, product_id, vendor_id;
0f431527 1635 int ret = 0;
5557d820 1636 char port[MAX_PORTLEN];
0f431527
AL
1637 char product_name[512];
1638 struct dirent *de;
1639
1640 dir = opendir(USBSYSBUS_PATH "/devices");
1641 if (!dir) {
1642 perror("husb: cannot open devices directory");
1643 goto the_end;
1644 }
1645
1646 while ((de = readdir(dir))) {
1647 if (de->d_name[0] != '.' && !strchr(de->d_name, ':')) {
5557d820
GH
1648 if (sscanf(de->d_name, "%d-%7[0-9.]", &bus_num, port) < 2) {
1649 continue;
0f5160d1 1650 }
0f431527 1651
2791104c 1652 if (!usb_host_read_file(line, sizeof(line), "devnum", de->d_name)) {
0f431527 1653 goto the_end;
2791104c
DA
1654 }
1655 if (sscanf(line, "%d", &addr) != 1) {
0f431527 1656 goto the_end;
2791104c 1657 }
b4e237aa 1658 if (!usb_host_read_file(line, sizeof(line), "bDeviceClass",
2791104c 1659 de->d_name)) {
0f431527 1660 goto the_end;
2791104c
DA
1661 }
1662 if (sscanf(line, "%x", &class_id) != 1) {
0f431527 1663 goto the_end;
2791104c 1664 }
0f431527 1665
2791104c
DA
1666 if (!usb_host_read_file(line, sizeof(line), "idVendor",
1667 de->d_name)) {
0f431527 1668 goto the_end;
2791104c
DA
1669 }
1670 if (sscanf(line, "%x", &vendor_id) != 1) {
0f431527 1671 goto the_end;
2791104c 1672 }
b4e237aa 1673 if (!usb_host_read_file(line, sizeof(line), "idProduct",
2791104c 1674 de->d_name)) {
0f431527 1675 goto the_end;
2791104c
DA
1676 }
1677 if (sscanf(line, "%x", &product_id) != 1) {
0f431527 1678 goto the_end;
2791104c 1679 }
b4e237aa
BS
1680 if (!usb_host_read_file(line, sizeof(line), "product",
1681 de->d_name)) {
0f431527
AL
1682 *product_name = 0;
1683 } else {
2791104c 1684 if (strlen(line) > 0) {
0f431527 1685 line[strlen(line) - 1] = '\0';
2791104c 1686 }
0f431527
AL
1687 pstrcpy(product_name, sizeof(product_name), line);
1688 }
1689
2791104c 1690 if (!usb_host_read_file(line, sizeof(line), "speed", de->d_name)) {
0f431527 1691 goto the_end;
2791104c 1692 }
f264cfbf
HG
1693 if (!strcmp(line, "5000\n")) {
1694 speed = USB_SPEED_SUPER;
1695 } else if (!strcmp(line, "480\n")) {
0f431527 1696 speed = USB_SPEED_HIGH;
2791104c 1697 } else if (!strcmp(line, "1.5\n")) {
0f431527 1698 speed = USB_SPEED_LOW;
2791104c 1699 } else {
0f431527 1700 speed = USB_SPEED_FULL;
2791104c 1701 }
0f431527 1702
5557d820 1703 ret = func(opaque, bus_num, addr, port, class_id, vendor_id,
0f431527 1704 product_id, product_name, speed);
2791104c 1705 if (ret) {
0f431527 1706 goto the_end;
2791104c 1707 }
0f431527
AL
1708 }
1709 }
1710 the_end:
2791104c 1711 if (dir) {
0f431527 1712 closedir(dir);
2791104c 1713 }
0f431527
AL
1714 return ret;
1715}
1716
1717/*
1718 * Determine how to access the host's USB devices and call the
1719 * specific support function.
1720 */
1721static int usb_host_scan(void *opaque, USBScanFunc *func)
1722{
376253ec 1723 Monitor *mon = cur_mon;
660f11be
BS
1724 FILE *f = NULL;
1725 DIR *dir = NULL;
0f431527 1726 int ret = 0;
0f431527
AL
1727 const char *fs_type[] = {"unknown", "proc", "dev", "sys"};
1728 char devpath[PATH_MAX];
1729
1730 /* only check the host once */
1731 if (!usb_fs_type) {
55496240
MM
1732 dir = opendir(USBSYSBUS_PATH "/devices");
1733 if (dir) {
1734 /* devices found in /dev/bus/usb/ (yes - not a mistake!) */
1735 strcpy(devpath, USBDEVBUS_PATH);
1736 usb_fs_type = USB_FS_SYS;
1737 closedir(dir);
d0f2c4c6 1738 DPRINTF(USBDBG_DEVOPENED, USBSYSBUS_PATH);
55496240
MM
1739 goto found_devices;
1740 }
0f431527
AL
1741 f = fopen(USBPROCBUS_PATH "/devices", "r");
1742 if (f) {
1743 /* devices found in /proc/bus/usb/ */
1744 strcpy(devpath, USBPROCBUS_PATH);
1745 usb_fs_type = USB_FS_PROC;
1746 fclose(f);
d0f2c4c6 1747 DPRINTF(USBDBG_DEVOPENED, USBPROCBUS_PATH);
f16a0db3 1748 goto found_devices;
0f431527
AL
1749 }
1750 /* try additional methods if an access method hasn't been found yet */
1751 f = fopen(USBDEVBUS_PATH "/devices", "r");
f16a0db3 1752 if (f) {
0f431527
AL
1753 /* devices found in /dev/bus/usb/ */
1754 strcpy(devpath, USBDEVBUS_PATH);
1755 usb_fs_type = USB_FS_DEV;
1756 fclose(f);
d0f2c4c6 1757 DPRINTF(USBDBG_DEVOPENED, USBDEVBUS_PATH);
f16a0db3 1758 goto found_devices;
0f431527 1759 }
f16a0db3 1760 found_devices:
22babebb 1761 if (!usb_fs_type) {
2791104c 1762 if (mon) {
eba6fe87 1763 monitor_printf(mon, "husb: unable to access USB devices\n");
2791104c 1764 }
f16a0db3 1765 return -ENOENT;
0f431527
AL
1766 }
1767
1768 /* the module setting (used later for opening devices) */
7267c094 1769 usb_host_device_path = g_malloc0(strlen(devpath)+1);
1eec614b 1770 strcpy(usb_host_device_path, devpath);
2791104c 1771 if (mon) {
eba6fe87
GH
1772 monitor_printf(mon, "husb: using %s file-system with %s\n",
1773 fs_type[usb_fs_type], usb_host_device_path);
2791104c 1774 }
0f431527
AL
1775 }
1776
1777 switch (usb_fs_type) {
1778 case USB_FS_PROC:
1779 case USB_FS_DEV:
1780 ret = usb_host_scan_dev(opaque, func);
1781 break;
1782 case USB_FS_SYS:
1783 ret = usb_host_scan_sys(opaque, func);
1784 break;
f16a0db3
AL
1785 default:
1786 ret = -EINVAL;
1787 break;
0f431527 1788 }
a594cfbf 1789 return ret;
bb36d470
FB
1790}
1791
4b096fc9 1792static QEMUTimer *usb_auto_timer;
4b096fc9 1793
ba9acab9
GH
1794static int usb_host_auto_scan(void *opaque, int bus_num,
1795 int addr, const char *port,
26a9e82a
GH
1796 int class_id, int vendor_id, int product_id,
1797 const char *product_name, int speed)
4b096fc9
AL
1798{
1799 struct USBAutoFilter *f;
26a9e82a 1800 struct USBHostDevice *s;
4b096fc9
AL
1801
1802 /* Ignore hubs */
1803 if (class_id == 9)
1804 return 0;
1805
26a9e82a
GH
1806 QTAILQ_FOREACH(s, &hostdevs, next) {
1807 f = &s->match;
1808
2791104c 1809 if (f->bus_num > 0 && f->bus_num != bus_num) {
4b096fc9 1810 continue;
2791104c
DA
1811 }
1812 if (f->addr > 0 && f->addr != addr) {
4b096fc9 1813 continue;
2791104c 1814 }
9056a297
GH
1815 if (f->port != NULL && (port == NULL || strcmp(f->port, port) != 0)) {
1816 continue;
1817 }
4b096fc9 1818
2791104c 1819 if (f->vendor_id > 0 && f->vendor_id != vendor_id) {
4b096fc9 1820 continue;
2791104c 1821 }
4b096fc9 1822
2791104c 1823 if (f->product_id > 0 && f->product_id != product_id) {
4b096fc9 1824 continue;
2791104c 1825 }
4b096fc9 1826 /* We got a match */
3ee886c5
GH
1827 s->seen++;
1828 if (s->errcount >= 3) {
1829 return 0;
1830 }
4b096fc9 1831
33e66b86 1832 /* Already attached ? */
2791104c 1833 if (s->fd != -1) {
4b096fc9 1834 return 0;
2791104c 1835 }
d0f2c4c6 1836 DPRINTF("husb: auto open: bus_num %d addr %d\n", bus_num, addr);
4b096fc9 1837
3ee886c5
GH
1838 if (usb_host_open(s, bus_num, addr, port, product_name, speed) < 0) {
1839 s->errcount++;
1840 }
97f86166 1841 break;
4b096fc9
AL
1842 }
1843
1844 return 0;
1845}
1846
26a9e82a 1847static void usb_host_auto_check(void *unused)
4b096fc9 1848{
26a9e82a
GH
1849 struct USBHostDevice *s;
1850 int unconnected = 0;
1851
4b096fc9 1852 usb_host_scan(NULL, usb_host_auto_scan);
26a9e82a
GH
1853
1854 QTAILQ_FOREACH(s, &hostdevs, next) {
2791104c 1855 if (s->fd == -1) {
26a9e82a 1856 unconnected++;
2791104c 1857 }
3ee886c5
GH
1858 if (s->seen == 0) {
1859 s->errcount = 0;
1860 }
1861 s->seen = 0;
26a9e82a
GH
1862 }
1863
1864 if (unconnected == 0) {
1865 /* nothing to watch */
2791104c 1866 if (usb_auto_timer) {
26a9e82a 1867 qemu_del_timer(usb_auto_timer);
e6a2f500 1868 trace_usb_host_auto_scan_disabled();
2791104c 1869 }
26a9e82a
GH
1870 return;
1871 }
1872
1873 if (!usb_auto_timer) {
7bd427d8 1874 usb_auto_timer = qemu_new_timer_ms(rt_clock, usb_host_auto_check, NULL);
2791104c 1875 if (!usb_auto_timer) {
26a9e82a 1876 return;
2791104c 1877 }
e6a2f500 1878 trace_usb_host_auto_scan_enabled();
26a9e82a 1879 }
7bd427d8 1880 qemu_mod_timer(usb_auto_timer, qemu_get_clock_ms(rt_clock) + 2000);
4b096fc9
AL
1881}
1882
1883/*
5d0c5750
AL
1884 * Autoconnect filter
1885 * Format:
1886 * auto:bus:dev[:vid:pid]
1887 * auto:bus.dev[:vid:pid]
1888 *
1889 * bus - bus number (dec, * means any)
1890 * dev - device number (dec, * means any)
1891 * vid - vendor id (hex, * means any)
1892 * pid - product id (hex, * means any)
1893 *
1894 * See 'lsusb' output.
4b096fc9 1895 */
5d0c5750 1896static int parse_filter(const char *spec, struct USBAutoFilter *f)
4b096fc9 1897{
5d0c5750
AL
1898 enum { BUS, DEV, VID, PID, DONE };
1899 const char *p = spec;
1900 int i;
1901
0745eb1e
MA
1902 f->bus_num = 0;
1903 f->addr = 0;
1904 f->vendor_id = 0;
1905 f->product_id = 0;
5d0c5750
AL
1906
1907 for (i = BUS; i < DONE; i++) {
2791104c
DA
1908 p = strpbrk(p, ":.");
1909 if (!p) {
1910 break;
1911 }
5d0c5750 1912 p++;
5d0c5750 1913
2791104c
DA
1914 if (*p == '*') {
1915 continue;
1916 }
5d0c5750
AL
1917 switch(i) {
1918 case BUS: f->bus_num = strtol(p, NULL, 10); break;
1919 case DEV: f->addr = strtol(p, NULL, 10); break;
1920 case VID: f->vendor_id = strtol(p, NULL, 16); break;
1921 case PID: f->product_id = strtol(p, NULL, 16); break;
1922 }
1923 }
1924
1925 if (i < DEV) {
1926 fprintf(stderr, "husb: invalid auto filter spec %s\n", spec);
1927 return -1;
1928 }
1929
1930 return 0;
1931}
1932
a594cfbf
FB
1933/**********************/
1934/* USB host device info */
1935
1936struct usb_class_info {
1937 int class;
1938 const char *class_name;
1939};
1940
1941static const struct usb_class_info usb_class_info[] = {
1942 { USB_CLASS_AUDIO, "Audio"},
1943 { USB_CLASS_COMM, "Communication"},
1944 { USB_CLASS_HID, "HID"},
1945 { USB_CLASS_HUB, "Hub" },
1946 { USB_CLASS_PHYSICAL, "Physical" },
1947 { USB_CLASS_PRINTER, "Printer" },
1948 { USB_CLASS_MASS_STORAGE, "Storage" },
1949 { USB_CLASS_CDC_DATA, "Data" },
1950 { USB_CLASS_APP_SPEC, "Application Specific" },
1951 { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
1952 { USB_CLASS_STILL_IMAGE, "Still Image" },
b9dc033c 1953 { USB_CLASS_CSCID, "Smart Card" },
a594cfbf
FB
1954 { USB_CLASS_CONTENT_SEC, "Content Security" },
1955 { -1, NULL }
1956};
1957
1958static const char *usb_class_str(uint8_t class)
bb36d470 1959{
a594cfbf
FB
1960 const struct usb_class_info *p;
1961 for(p = usb_class_info; p->class != -1; p++) {
2791104c 1962 if (p->class == class) {
a594cfbf 1963 break;
2791104c 1964 }
bb36d470 1965 }
a594cfbf
FB
1966 return p->class_name;
1967}
1968
ba9acab9
GH
1969static void usb_info_device(Monitor *mon, int bus_num,
1970 int addr, const char *port,
5557d820 1971 int class_id, int vendor_id, int product_id,
9596ebb7
PB
1972 const char *product_name,
1973 int speed)
a594cfbf
FB
1974{
1975 const char *class_str, *speed_str;
1976
1977 switch(speed) {
5fafdf24
TS
1978 case USB_SPEED_LOW:
1979 speed_str = "1.5";
a594cfbf 1980 break;
5fafdf24
TS
1981 case USB_SPEED_FULL:
1982 speed_str = "12";
a594cfbf 1983 break;
5fafdf24
TS
1984 case USB_SPEED_HIGH:
1985 speed_str = "480";
a594cfbf 1986 break;
f264cfbf
HG
1987 case USB_SPEED_SUPER:
1988 speed_str = "5000";
1989 break;
a594cfbf 1990 default:
5fafdf24 1991 speed_str = "?";
a594cfbf
FB
1992 break;
1993 }
1994
5557d820
GH
1995 monitor_printf(mon, " Bus %d, Addr %d, Port %s, Speed %s Mb/s\n",
1996 bus_num, addr, port, speed_str);
a594cfbf 1997 class_str = usb_class_str(class_id);
2791104c 1998 if (class_str) {
376253ec 1999 monitor_printf(mon, " %s:", class_str);
2791104c 2000 } else {
376253ec 2001 monitor_printf(mon, " Class %02x:", class_id);
2791104c 2002 }
376253ec 2003 monitor_printf(mon, " USB device %04x:%04x", vendor_id, product_id);
2791104c 2004 if (product_name[0] != '\0') {
376253ec 2005 monitor_printf(mon, ", %s", product_name);
2791104c 2006 }
376253ec 2007 monitor_printf(mon, "\n");
a594cfbf
FB
2008}
2009
5fafdf24 2010static int usb_host_info_device(void *opaque, int bus_num, int addr,
ba9acab9 2011 const char *path, int class_id,
5fafdf24 2012 int vendor_id, int product_id,
a594cfbf
FB
2013 const char *product_name,
2014 int speed)
2015{
179da8af
BS
2016 Monitor *mon = opaque;
2017
5557d820 2018 usb_info_device(mon, bus_num, addr, path, class_id, vendor_id, product_id,
a594cfbf
FB
2019 product_name, speed);
2020 return 0;
2021}
2022
ac4ffb5a 2023static void dec2str(int val, char *str, size_t size)
5d0c5750 2024{
2791104c 2025 if (val == 0) {
ac4ffb5a 2026 snprintf(str, size, "*");
2791104c
DA
2027 } else {
2028 snprintf(str, size, "%d", val);
2029 }
5d0c5750
AL
2030}
2031
ac4ffb5a 2032static void hex2str(int val, char *str, size_t size)
5d0c5750 2033{
2791104c 2034 if (val == 0) {
ac4ffb5a 2035 snprintf(str, size, "*");
2791104c 2036 } else {
26a9e82a 2037 snprintf(str, size, "%04x", val);
2791104c 2038 }
5d0c5750
AL
2039}
2040
376253ec 2041void usb_host_info(Monitor *mon)
a594cfbf 2042{
5d0c5750 2043 struct USBAutoFilter *f;
26a9e82a 2044 struct USBHostDevice *s;
5d0c5750 2045
179da8af 2046 usb_host_scan(mon, usb_host_info_device);
5d0c5750 2047
2791104c 2048 if (QTAILQ_EMPTY(&hostdevs)) {
26a9e82a 2049 return;
2791104c
DA
2050 }
2051
26a9e82a
GH
2052 monitor_printf(mon, " Auto filters:\n");
2053 QTAILQ_FOREACH(s, &hostdevs, next) {
5d0c5750 2054 char bus[10], addr[10], vid[10], pid[10];
26a9e82a 2055 f = &s->match;
ac4ffb5a
AL
2056 dec2str(f->bus_num, bus, sizeof(bus));
2057 dec2str(f->addr, addr, sizeof(addr));
2058 hex2str(f->vendor_id, vid, sizeof(vid));
2059 hex2str(f->product_id, pid, sizeof(pid));
9056a297
GH
2060 monitor_printf(mon, " Bus %s, Addr %s, Port %s, ID %s:%s\n",
2061 bus, addr, f->port ? f->port : "*", vid, pid);
5d0c5750 2062 }
bb36d470 2063}