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