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