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