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