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