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