]> git.proxmox.com Git - qemu.git/blame - usb-linux.c
usb-linux: We only need to keep track of 15 endpoints
[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;
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;
975f2998
HG
552 int i, j, ret, max_packet_size, len = 0;
553
554 max_packet_size = get_max_packet_size(s, p->devep);
555 if (max_packet_size == 0)
556 return USB_RET_NAK;
060dc841
HG
557
558 aurb = get_iso_urb(s, p->devep);
559 if (!aurb) {
560 aurb = usb_host_alloc_iso(s, p->devep, 1);
561 }
562
563 i = get_iso_urb_idx(s, p->devep);
564 j = aurb[i].iso_frame_idx;
565 if (j >= 0 && j < ISO_FRAME_DESC_PER_URB) {
566 /* Check urb status */
567 if (aurb[i].urb.status) {
568 len = urb_status_to_usb_ret(aurb[i].urb.status);
569 /* Move to the next urb */
570 aurb[i].iso_frame_idx = ISO_FRAME_DESC_PER_URB - 1;
571 /* Check frame status */
572 } else if (aurb[i].urb.iso_frame_desc[j].status) {
573 len = urb_status_to_usb_ret(aurb[i].urb.iso_frame_desc[j].status);
574 /* Check the frame fits */
575 } else if (aurb[i].urb.iso_frame_desc[j].actual_length > p->len) {
576 printf("husb: error received isoc data is larger then packet\n");
577 len = USB_RET_NAK;
578 /* All good copy data over */
579 } else {
580 len = aurb[i].urb.iso_frame_desc[j].actual_length;
581 memcpy(p->data,
582 aurb[i].urb.buffer +
583 j * aurb[i].urb.iso_frame_desc[0].length,
584 len);
585 }
586 aurb[i].iso_frame_idx++;
587 if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {
588 i = (i + 1) % ISO_URB_COUNT;
589 set_iso_urb_idx(s, p->devep, i);
590 }
591 }
592
593 /* (Re)-submit all fully consumed urbs */
594 for (i = 0; i < ISO_URB_COUNT; i++) {
595 if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {
596 ret = ioctl(s->fd, USBDEVFS_SUBMITURB, &aurb[i]);
597 if (ret < 0) {
598 printf("husb error submitting isoc urb %d: %d\n", i, errno);
599 if (len == 0) {
600 switch(errno) {
601 case ETIMEDOUT:
602 len = USB_RET_NAK;
603 case EPIPE:
604 default:
605 len = USB_RET_STALL;
606 }
607 }
608 break;
609 }
610 aurb[i].iso_frame_idx = -1;
611 }
612 }
613
614 return len;
615}
616
446ab128 617static int usb_host_handle_data(USBHostDevice *s, USBPacket *p)
bb36d470 618{
64838171 619 struct usbdevfs_urb *urb;
446ab128 620 AsyncURB *aurb;
bb36d470 621 int ret;
060dc841 622 uint8_t ep;
b9dc033c 623
a0b5fece
HG
624 if (!is_valid(s, p->devep)) {
625 return USB_RET_NAK;
626 }
627
2791104c 628 if (p->pid == USB_TOKEN_IN) {
060dc841 629 ep = p->devep | 0x80;
2791104c 630 } else {
060dc841 631 ep = p->devep;
2791104c 632 }
64838171
AL
633
634 if (is_halted(s, p->devep)) {
060dc841 635 ret = ioctl(s->fd, USBDEVFS_CLEAR_HALT, &ep);
64838171 636 if (ret < 0) {
2791104c 637 DPRINTF("husb: failed to clear halt. ep 0x%x errno %d\n",
060dc841 638 ep, errno);
bb36d470 639 return USB_RET_NAK;
bb36d470 640 }
64838171 641 clear_halt(s, p->devep);
4d043a09
AZ
642 }
643
060dc841
HG
644 if (is_isoc(s, p->devep) && p->pid == USB_TOKEN_IN)
645 return usb_host_handle_iso_data(s, p);
646
647 aurb = async_alloc();
648 aurb->hdev = s;
649 aurb->packet = p;
650
651 urb = &aurb->urb;
652
653 urb->endpoint = ep;
64838171
AL
654 urb->buffer = p->data;
655 urb->buffer_length = p->len;
b9dc033c 656
64838171
AL
657 if (is_isoc(s, p->devep)) {
658 /* Setup ISOC transfer */
659 urb->type = USBDEVFS_URB_TYPE_ISO;
660 urb->flags = USBDEVFS_URB_ISO_ASAP;
661 urb->number_of_packets = 1;
662 urb->iso_frame_desc[0].length = p->len;
663 } else {
664 /* Setup bulk transfer */
665 urb->type = USBDEVFS_URB_TYPE_BULK;
b9dc033c
AZ
666 }
667
64838171 668 urb->usercontext = s;
b9dc033c 669
64838171 670 ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
b9dc033c 671
2791104c
DA
672 DPRINTF("husb: data submit. ep 0x%x len %u aurb %p\n",
673 urb->endpoint, p->len, aurb);
b9dc033c 674
64838171 675 if (ret < 0) {
d0f2c4c6 676 DPRINTF("husb: submit failed. errno %d\n", errno);
64838171 677 async_free(aurb);
b9dc033c 678
b9dc033c
AZ
679 switch(errno) {
680 case ETIMEDOUT:
681 return USB_RET_NAK;
682 case EPIPE:
683 default:
684 return USB_RET_STALL;
685 }
686 }
64838171
AL
687
688 usb_defer_packet(p, async_cancel, aurb);
b9dc033c 689 return USB_RET_ASYNC;
b9dc033c
AZ
690}
691
446ab128
AL
692static int ctrl_error(void)
693{
2791104c 694 if (errno == ETIMEDOUT) {
446ab128 695 return USB_RET_NAK;
2791104c 696 } else {
446ab128 697 return USB_RET_STALL;
2791104c 698 }
446ab128
AL
699}
700
701static int usb_host_set_address(USBHostDevice *s, int addr)
702{
d0f2c4c6 703 DPRINTF("husb: ctrl set addr %u\n", addr);
446ab128
AL
704 s->dev.addr = addr;
705 return 0;
706}
707
708static int usb_host_set_config(USBHostDevice *s, int config)
709{
710 usb_host_release_interfaces(s);
711
712 int ret = ioctl(s->fd, USBDEVFS_SETCONFIGURATION, &config);
2791104c 713
d0f2c4c6 714 DPRINTF("husb: ctrl set config %d ret %d errno %d\n", config, ret, errno);
2791104c
DA
715
716 if (ret < 0) {
446ab128 717 return ctrl_error();
2791104c 718 }
446ab128
AL
719 usb_host_claim_interfaces(s, config);
720 return 0;
721}
722
723static int usb_host_set_interface(USBHostDevice *s, int iface, int alt)
724{
725 struct usbdevfs_setinterface si;
060dc841
HG
726 int i, ret;
727
3a4854b3 728 for (i = 1; i <= MAX_ENDPOINTS; i++) {
060dc841
HG
729 if (is_isoc(s, i)) {
730 usb_host_stop_n_free_iso(s, i);
731 }
732 }
446ab128
AL
733
734 si.interface = iface;
735 si.altsetting = alt;
736 ret = ioctl(s->fd, USBDEVFS_SETINTERFACE, &si);
446ab128 737
2791104c
DA
738 DPRINTF("husb: ctrl set iface %d altset %d ret %d errno %d\n",
739 iface, alt, ret, errno);
740
741 if (ret < 0) {
742 return ctrl_error();
743 }
446ab128
AL
744 usb_linux_update_endp_table(s);
745 return 0;
746}
747
748static int usb_host_handle_control(USBHostDevice *s, USBPacket *p)
749{
750 struct usbdevfs_urb *urb;
751 AsyncURB *aurb;
752 int ret, value, index;
c4c0e236 753 int buffer_len;
446ab128 754
2791104c 755 /*
446ab128
AL
756 * Process certain standard device requests.
757 * These are infrequent and are processed synchronously.
758 */
759 value = le16_to_cpu(s->ctrl.req.wValue);
760 index = le16_to_cpu(s->ctrl.req.wIndex);
761
d0f2c4c6 762 DPRINTF("husb: ctrl type 0x%x req 0x%x val 0x%x index %u len %u\n",
2791104c
DA
763 s->ctrl.req.bRequestType, s->ctrl.req.bRequest, value, index,
764 s->ctrl.len);
446ab128
AL
765
766 if (s->ctrl.req.bRequestType == 0) {
767 switch (s->ctrl.req.bRequest) {
768 case USB_REQ_SET_ADDRESS:
769 return usb_host_set_address(s, value);
770
771 case USB_REQ_SET_CONFIGURATION:
772 return usb_host_set_config(s, value & 0xff);
773 }
774 }
775
776 if (s->ctrl.req.bRequestType == 1 &&
2791104c 777 s->ctrl.req.bRequest == USB_REQ_SET_INTERFACE) {
446ab128 778 return usb_host_set_interface(s, index, value);
2791104c 779 }
446ab128
AL
780
781 /* The rest are asynchronous */
782
c4c0e236
JP
783 buffer_len = 8 + s->ctrl.len;
784 if (buffer_len > sizeof(s->ctrl.buffer)) {
b2e3b6e9 785 fprintf(stderr, "husb: ctrl buffer too small (%u > %zu)\n",
786 buffer_len, sizeof(s->ctrl.buffer));
787 return USB_RET_STALL;
c4c0e236
JP
788 }
789
446ab128 790 aurb = async_alloc();
446ab128
AL
791 aurb->hdev = s;
792 aurb->packet = p;
793
2791104c 794 /*
446ab128
AL
795 * Setup ctrl transfer.
796 *
a0102082 797 * s->ctrl is laid out such that data buffer immediately follows
446ab128 798 * 'req' struct which is exactly what usbdevfs expects.
2791104c 799 */
446ab128
AL
800 urb = &aurb->urb;
801
802 urb->type = USBDEVFS_URB_TYPE_CONTROL;
803 urb->endpoint = p->devep;
804
805 urb->buffer = &s->ctrl.req;
c4c0e236 806 urb->buffer_length = buffer_len;
446ab128
AL
807
808 urb->usercontext = s;
809
810 ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
811
d0f2c4c6 812 DPRINTF("husb: submit ctrl. len %u aurb %p\n", urb->buffer_length, aurb);
446ab128
AL
813
814 if (ret < 0) {
d0f2c4c6 815 DPRINTF("husb: submit failed. errno %d\n", errno);
446ab128
AL
816 async_free(aurb);
817
818 switch(errno) {
819 case ETIMEDOUT:
820 return USB_RET_NAK;
821 case EPIPE:
822 default:
823 return USB_RET_STALL;
824 }
825 }
826
827 usb_defer_packet(p, async_cancel, aurb);
828 return USB_RET_ASYNC;
829}
830
831static int do_token_setup(USBDevice *dev, USBPacket *p)
832{
833 USBHostDevice *s = (USBHostDevice *) dev;
834 int ret = 0;
835
2791104c 836 if (p->len != 8) {
446ab128 837 return USB_RET_STALL;
2791104c
DA
838 }
839
446ab128
AL
840 memcpy(&s->ctrl.req, p->data, 8);
841 s->ctrl.len = le16_to_cpu(s->ctrl.req.wLength);
842 s->ctrl.offset = 0;
843 s->ctrl.state = CTRL_STATE_SETUP;
844
845 if (s->ctrl.req.bRequestType & USB_DIR_IN) {
846 ret = usb_host_handle_control(s, p);
2791104c 847 if (ret < 0) {
446ab128 848 return ret;
2791104c 849 }
446ab128 850
2791104c 851 if (ret < s->ctrl.len) {
446ab128 852 s->ctrl.len = ret;
2791104c 853 }
446ab128
AL
854 s->ctrl.state = CTRL_STATE_DATA;
855 } else {
2791104c 856 if (s->ctrl.len == 0) {
446ab128 857 s->ctrl.state = CTRL_STATE_ACK;
2791104c 858 } else {
446ab128 859 s->ctrl.state = CTRL_STATE_DATA;
2791104c 860 }
446ab128
AL
861 }
862
863 return ret;
864}
865
866static int do_token_in(USBDevice *dev, USBPacket *p)
867{
868 USBHostDevice *s = (USBHostDevice *) dev;
869 int ret = 0;
870
2791104c 871 if (p->devep != 0) {
446ab128 872 return usb_host_handle_data(s, p);
2791104c 873 }
446ab128
AL
874
875 switch(s->ctrl.state) {
876 case CTRL_STATE_ACK:
877 if (!(s->ctrl.req.bRequestType & USB_DIR_IN)) {
878 ret = usb_host_handle_control(s, p);
2791104c 879 if (ret == USB_RET_ASYNC) {
446ab128 880 return USB_RET_ASYNC;
2791104c 881 }
446ab128
AL
882 s->ctrl.state = CTRL_STATE_IDLE;
883 return ret > 0 ? 0 : ret;
884 }
885
886 return 0;
887
888 case CTRL_STATE_DATA:
889 if (s->ctrl.req.bRequestType & USB_DIR_IN) {
890 int len = s->ctrl.len - s->ctrl.offset;
2791104c 891 if (len > p->len) {
446ab128 892 len = p->len;
2791104c 893 }
446ab128
AL
894 memcpy(p->data, s->ctrl.buffer + s->ctrl.offset, len);
895 s->ctrl.offset += len;
2791104c 896 if (s->ctrl.offset >= s->ctrl.len) {
446ab128 897 s->ctrl.state = CTRL_STATE_ACK;
2791104c 898 }
446ab128
AL
899 return len;
900 }
901
902 s->ctrl.state = CTRL_STATE_IDLE;
903 return USB_RET_STALL;
904
905 default:
906 return USB_RET_STALL;
907 }
908}
909
910static int do_token_out(USBDevice *dev, USBPacket *p)
911{
912 USBHostDevice *s = (USBHostDevice *) dev;
913
2791104c 914 if (p->devep != 0) {
446ab128 915 return usb_host_handle_data(s, p);
2791104c 916 }
446ab128
AL
917
918 switch(s->ctrl.state) {
919 case CTRL_STATE_ACK:
920 if (s->ctrl.req.bRequestType & USB_DIR_IN) {
921 s->ctrl.state = CTRL_STATE_IDLE;
922 /* transfer OK */
923 } else {
924 /* ignore additional output */
925 }
926 return 0;
927
928 case CTRL_STATE_DATA:
929 if (!(s->ctrl.req.bRequestType & USB_DIR_IN)) {
930 int len = s->ctrl.len - s->ctrl.offset;
2791104c 931 if (len > p->len) {
446ab128 932 len = p->len;
2791104c 933 }
446ab128
AL
934 memcpy(s->ctrl.buffer + s->ctrl.offset, p->data, len);
935 s->ctrl.offset += len;
2791104c 936 if (s->ctrl.offset >= s->ctrl.len) {
446ab128 937 s->ctrl.state = CTRL_STATE_ACK;
2791104c 938 }
446ab128
AL
939 return len;
940 }
941
942 s->ctrl.state = CTRL_STATE_IDLE;
943 return USB_RET_STALL;
944
945 default:
946 return USB_RET_STALL;
947 }
948}
949
950/*
951 * Packet handler.
952 * Called by the HC (host controller).
953 *
954 * Returns length of the transaction or one of the USB_RET_XXX codes.
955 */
d9cf1578 956static int usb_host_handle_packet(USBDevice *s, USBPacket *p)
446ab128
AL
957{
958 switch(p->pid) {
959 case USB_MSG_ATTACH:
960 s->state = USB_STATE_ATTACHED;
961 return 0;
962
963 case USB_MSG_DETACH:
964 s->state = USB_STATE_NOTATTACHED;
965 return 0;
966
967 case USB_MSG_RESET:
968 s->remote_wakeup = 0;
969 s->addr = 0;
970 s->state = USB_STATE_DEFAULT;
806b6024 971 s->info->handle_reset(s);
446ab128
AL
972 return 0;
973 }
974
975 /* Rest of the PIDs must match our address */
2791104c 976 if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr) {
446ab128 977 return USB_RET_NODEV;
2791104c 978 }
446ab128
AL
979
980 switch (p->pid) {
981 case USB_TOKEN_SETUP:
982 return do_token_setup(s, p);
983
984 case USB_TOKEN_IN:
985 return do_token_in(s, p);
986
987 case USB_TOKEN_OUT:
988 return do_token_out(s, p);
2791104c 989
446ab128
AL
990 default:
991 return USB_RET_STALL;
992 }
993}
994
71d71bbd 995static int usb_linux_get_configuration(USBHostDevice *s)
b9dc033c 996{
71d71bbd 997 uint8_t configuration;
e41b3910 998 struct usb_ctrltransfer ct;
71d71bbd 999 int ret;
b9dc033c 1000
2cc59d8c
HG
1001 if (usb_fs_type == USB_FS_SYS) {
1002 char device_name[32], line[1024];
1003 int configuration;
1004
1005 sprintf(device_name, "%d-%d", s->bus_num, s->devpath);
1006
1007 if (!usb_host_read_file(line, sizeof(line), "bConfigurationValue",
1008 device_name)) {
1009 goto usbdevfs;
1010 }
1011 if (sscanf(line, "%d", &configuration) != 1) {
1012 goto usbdevfs;
1013 }
1014 return configuration;
1015 }
1016
1017usbdevfs:
b9dc033c
AZ
1018 ct.bRequestType = USB_DIR_IN;
1019 ct.bRequest = USB_REQ_GET_CONFIGURATION;
1020 ct.wValue = 0;
1021 ct.wIndex = 0;
1022 ct.wLength = 1;
1023 ct.data = &configuration;
1024 ct.timeout = 50;
1025
1026 ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
1027 if (ret < 0) {
71d71bbd
HG
1028 perror("usb_linux_get_configuration");
1029 return -1;
b9dc033c
AZ
1030 }
1031
1032 /* in address state */
2791104c 1033 if (configuration == 0) {
71d71bbd 1034 return -1;
2791104c 1035 }
b9dc033c 1036
71d71bbd
HG
1037 return configuration;
1038}
1039
ed3a328d
HG
1040static uint8_t usb_linux_get_alt_setting(USBHostDevice *s,
1041 uint8_t configuration, uint8_t interface)
1042{
1043 uint8_t alt_setting;
1044 struct usb_ctrltransfer ct;
1045 int ret;
1046
c43831fb
HG
1047 if (usb_fs_type == USB_FS_SYS) {
1048 char device_name[64], line[1024];
1049 int alt_setting;
1050
1051 sprintf(device_name, "%d-%d:%d.%d", s->bus_num, s->devpath,
1052 (int)configuration, (int)interface);
1053
1054 if (!usb_host_read_file(line, sizeof(line), "bAlternateSetting",
1055 device_name)) {
1056 goto usbdevfs;
1057 }
1058 if (sscanf(line, "%d", &alt_setting) != 1) {
1059 goto usbdevfs;
1060 }
1061 return alt_setting;
1062 }
1063
1064usbdevfs:
ed3a328d
HG
1065 ct.bRequestType = USB_DIR_IN | USB_RECIP_INTERFACE;
1066 ct.bRequest = USB_REQ_GET_INTERFACE;
1067 ct.wValue = 0;
1068 ct.wIndex = interface;
1069 ct.wLength = 1;
1070 ct.data = &alt_setting;
1071 ct.timeout = 50;
1072 ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
1073 if (ret < 0) {
1074 /* Assume alt 0 on error */
1075 return 0;
1076 }
1077
1078 return alt_setting;
1079}
1080
71d71bbd
HG
1081/* returns 1 on problem encountered or 0 for success */
1082static int usb_linux_update_endp_table(USBHostDevice *s)
1083{
1084 uint8_t *descriptors;
1085 uint8_t devep, type, configuration, alt_interface;
ed3a328d 1086 int interface, length, i;
71d71bbd 1087
a0b5fece
HG
1088 for (i = 0; i < MAX_ENDPOINTS; i++)
1089 s->endp_table[i].type = INVALID_EP_TYPE;
1090
71d71bbd
HG
1091 i = usb_linux_get_configuration(s);
1092 if (i < 0)
1093 return 1;
1094 configuration = i;
1095
b9dc033c
AZ
1096 /* get the desired configuration, interface, and endpoint descriptors
1097 * from device description */
1098 descriptors = &s->descr[18];
1099 length = s->descr_len - 18;
1100 i = 0;
1101
1102 if (descriptors[i + 1] != USB_DT_CONFIG ||
1103 descriptors[i + 5] != configuration) {
d0f2c4c6 1104 DPRINTF("invalid descriptor data - configuration\n");
b9dc033c
AZ
1105 return 1;
1106 }
1107 i += descriptors[i];
1108
1109 while (i < length) {
1110 if (descriptors[i + 1] != USB_DT_INTERFACE ||
1111 (descriptors[i + 1] == USB_DT_INTERFACE &&
1112 descriptors[i + 4] == 0)) {
1113 i += descriptors[i];
1114 continue;
1115 }
1116
1117 interface = descriptors[i + 2];
ed3a328d 1118 alt_interface = usb_linux_get_alt_setting(s, configuration, interface);
b9dc033c
AZ
1119
1120 /* the current interface descriptor is the active interface
1121 * and has endpoints */
1122 if (descriptors[i + 3] != alt_interface) {
1123 i += descriptors[i];
1124 continue;
1125 }
1126
1127 /* advance to the endpoints */
2791104c 1128 while (i < length && descriptors[i +1] != USB_DT_ENDPOINT) {
b9dc033c 1129 i += descriptors[i];
2791104c 1130 }
b9dc033c
AZ
1131
1132 if (i >= length)
1133 break;
1134
1135 while (i < length) {
2791104c 1136 if (descriptors[i + 1] != USB_DT_ENDPOINT) {
b9dc033c 1137 break;
2791104c 1138 }
b9dc033c
AZ
1139
1140 devep = descriptors[i + 2];
1141 switch (descriptors[i + 3] & 0x3) {
1142 case 0x00:
1143 type = USBDEVFS_URB_TYPE_CONTROL;
1144 break;
1145 case 0x01:
1146 type = USBDEVFS_URB_TYPE_ISO;
060dc841
HG
1147 s->endp_table[(devep & 0xf) - 1].max_packet_size =
1148 descriptors[i + 4] + (descriptors[i + 5] << 8);
b9dc033c
AZ
1149 break;
1150 case 0x02:
1151 type = USBDEVFS_URB_TYPE_BULK;
1152 break;
1153 case 0x03:
1154 type = USBDEVFS_URB_TYPE_INTERRUPT;
1155 break;
ddbda432
AL
1156 default:
1157 DPRINTF("usb_host: malformed endpoint type\n");
1158 type = USBDEVFS_URB_TYPE_BULK;
b9dc033c
AZ
1159 }
1160 s->endp_table[(devep & 0xf) - 1].type = type;
64838171 1161 s->endp_table[(devep & 0xf) - 1].halted = 0;
b9dc033c
AZ
1162
1163 i += descriptors[i];
1164 }
1165 }
1166 return 0;
1167}
1168
26a9e82a 1169static int usb_host_open(USBHostDevice *dev, int bus_num,
0f5160d1 1170 int addr, int devpath, const char *prod_name)
bb36d470 1171{
b9dc033c 1172 int fd = -1, ret;
bb36d470 1173 struct usbdevfs_connectinfo ci;
a594cfbf 1174 char buf[1024];
1f3870ab 1175
2791104c 1176 if (dev->fd != -1) {
26a9e82a 1177 goto fail;
2791104c 1178 }
64838171 1179 printf("husb: open device %d.%d\n", bus_num, addr);
3b46e624 1180
0f431527
AL
1181 if (!usb_host_device_path) {
1182 perror("husb: USB Host Device Path not set");
1183 goto fail;
1184 }
1185 snprintf(buf, sizeof(buf), "%s/%03d/%03d", usb_host_device_path,
a594cfbf 1186 bus_num, addr);
b9dc033c 1187 fd = open(buf, O_RDWR | O_NONBLOCK);
bb36d470 1188 if (fd < 0) {
a594cfbf 1189 perror(buf);
1f3870ab 1190 goto fail;
bb36d470 1191 }
d0f2c4c6 1192 DPRINTF("husb: opened %s\n", buf);
bb36d470 1193
806b6024
GH
1194 dev->bus_num = bus_num;
1195 dev->addr = addr;
0f5160d1 1196 dev->devpath = devpath;
22f84e73 1197 dev->fd = fd;
806b6024 1198
b9dc033c
AZ
1199 /* read the device description */
1200 dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
1201 if (dev->descr_len <= 0) {
64838171 1202 perror("husb: reading device data failed");
bb36d470
FB
1203 goto fail;
1204 }
3b46e624 1205
b9dc033c 1206#ifdef DEBUG
868bfe2b 1207 {
b9dc033c
AZ
1208 int x;
1209 printf("=== begin dumping device descriptor data ===\n");
2791104c 1210 for (x = 0; x < dev->descr_len; x++) {
b9dc033c 1211 printf("%02x ", dev->descr[x]);
2791104c 1212 }
b9dc033c 1213 printf("\n=== end dumping device descriptor data ===\n");
bb36d470 1214 }
a594cfbf
FB
1215#endif
1216
b9dc033c 1217
2791104c
DA
1218 /*
1219 * Initial configuration is -1 which makes us claim first
446ab128 1220 * available config. We used to start with 1, which does not
2791104c 1221 * always work. I've seen devices where first config starts
446ab128
AL
1222 * with 2.
1223 */
2791104c 1224 if (!usb_host_claim_interfaces(dev, -1)) {
b9dc033c 1225 goto fail;
2791104c 1226 }
bb36d470
FB
1227
1228 ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
1229 if (ret < 0) {
046833ea 1230 perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
bb36d470
FB
1231 goto fail;
1232 }
1233
64838171 1234 printf("husb: grabbed usb device %d.%d\n", bus_num, addr);
bb36d470 1235
b9dc033c 1236 ret = usb_linux_update_endp_table(dev);
2791104c 1237 if (ret) {
bb36d470 1238 goto fail;
2791104c 1239 }
b9dc033c 1240
2791104c 1241 if (ci.slow) {
bb36d470 1242 dev->dev.speed = USB_SPEED_LOW;
2791104c 1243 } else {
bb36d470 1244 dev->dev.speed = USB_SPEED_HIGH;
2791104c 1245 }
bb36d470 1246
2791104c 1247 if (!prod_name || prod_name[0] == '\0') {
0fe6d12e 1248 snprintf(dev->dev.product_desc, sizeof(dev->dev.product_desc),
4b096fc9 1249 "host:%d.%d", bus_num, addr);
2791104c 1250 } else {
0fe6d12e 1251 pstrcpy(dev->dev.product_desc, sizeof(dev->dev.product_desc),
4b096fc9 1252 prod_name);
2791104c 1253 }
1f6e24e7 1254
64838171
AL
1255 /* USB devio uses 'write' flag to check for async completions */
1256 qemu_set_fd_handler(dev->fd, NULL, async_complete, dev);
1f3870ab 1257
26a9e82a
GH
1258 usb_device_attach(&dev->dev);
1259 return 0;
4b096fc9 1260
b9dc033c 1261fail:
26a9e82a 1262 dev->fd = -1;
2791104c 1263 if (fd != -1) {
806b6024 1264 close(fd);
2791104c 1265 }
26a9e82a
GH
1266 return -1;
1267}
1268
1269static int usb_host_close(USBHostDevice *dev)
1270{
060dc841
HG
1271 int i;
1272
2791104c 1273 if (dev->fd == -1) {
26a9e82a 1274 return -1;
2791104c 1275 }
26a9e82a
GH
1276
1277 qemu_set_fd_handler(dev->fd, NULL, NULL, NULL);
1278 dev->closing = 1;
3a4854b3 1279 for (i = 1; i <= MAX_ENDPOINTS; i++) {
060dc841
HG
1280 if (is_isoc(dev, i)) {
1281 usb_host_stop_n_free_iso(dev, i);
1282 }
1283 }
26a9e82a
GH
1284 async_complete(dev);
1285 dev->closing = 0;
1286 usb_device_detach(&dev->dev);
00ff227a 1287 ioctl(dev->fd, USBDEVFS_RESET);
26a9e82a
GH
1288 close(dev->fd);
1289 dev->fd = -1;
1290 return 0;
1291}
1292
b373a63a
SH
1293static void usb_host_exit_notifier(struct Notifier* n)
1294{
1295 USBHostDevice *s = container_of(n, USBHostDevice, exit);
1296
1297 if (s->fd != -1) {
1298 ioctl(s->fd, USBDEVFS_RESET);
1299 }
1300}
1301
26a9e82a
GH
1302static int usb_host_initfn(USBDevice *dev)
1303{
1304 USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
1305
1306 dev->auto_attach = 0;
1307 s->fd = -1;
1308 QTAILQ_INSERT_TAIL(&hostdevs, s, next);
b373a63a
SH
1309 s->exit.notify = usb_host_exit_notifier;
1310 qemu_add_exit_notifier(&s->exit);
26a9e82a
GH
1311 usb_host_auto_check(NULL);
1312 return 0;
a594cfbf 1313}
bb36d470 1314
806b6024 1315static struct USBDeviceInfo usb_host_dev_info = {
06384698 1316 .product_desc = "USB Host Device",
556cd098 1317 .qdev.name = "usb-host",
806b6024
GH
1318 .qdev.size = sizeof(USBHostDevice),
1319 .init = usb_host_initfn,
1320 .handle_packet = usb_host_handle_packet,
1321 .handle_reset = usb_host_handle_reset,
806b6024 1322 .handle_destroy = usb_host_handle_destroy,
26a9e82a
GH
1323 .usbdevice_name = "host",
1324 .usbdevice_init = usb_host_device_open,
1325 .qdev.props = (Property[]) {
1326 DEFINE_PROP_UINT32("hostbus", USBHostDevice, match.bus_num, 0),
1327 DEFINE_PROP_UINT32("hostaddr", USBHostDevice, match.addr, 0),
1328 DEFINE_PROP_HEX32("vendorid", USBHostDevice, match.vendor_id, 0),
1329 DEFINE_PROP_HEX32("productid", USBHostDevice, match.product_id, 0),
1330 DEFINE_PROP_END_OF_LIST(),
1331 },
806b6024
GH
1332};
1333
1334static void usb_host_register_devices(void)
1335{
1336 usb_qdev_register(&usb_host_dev_info);
1337}
1338device_init(usb_host_register_devices)
1339
4b096fc9
AL
1340USBDevice *usb_host_device_open(const char *devname)
1341{
0745eb1e 1342 struct USBAutoFilter filter;
26a9e82a 1343 USBDevice *dev;
26a9e82a
GH
1344 char *p;
1345
556cd098 1346 dev = usb_create(NULL /* FIXME */, "usb-host");
4b096fc9 1347
5d0c5750 1348 if (strstr(devname, "auto:")) {
2791104c 1349 if (parse_filter(devname, &filter) < 0) {
26a9e82a 1350 goto fail;
2791104c 1351 }
26a9e82a
GH
1352 } else {
1353 if ((p = strchr(devname, '.'))) {
0745eb1e
MA
1354 filter.bus_num = strtoul(devname, NULL, 0);
1355 filter.addr = strtoul(p + 1, NULL, 0);
1356 filter.vendor_id = 0;
1357 filter.product_id = 0;
26a9e82a 1358 } else if ((p = strchr(devname, ':'))) {
0745eb1e
MA
1359 filter.bus_num = 0;
1360 filter.addr = 0;
26a9e82a 1361 filter.vendor_id = strtoul(devname, NULL, 16);
0745eb1e 1362 filter.product_id = strtoul(p + 1, NULL, 16);
26a9e82a
GH
1363 } else {
1364 goto fail;
1365 }
5d0c5750 1366 }
4b096fc9 1367
0745eb1e
MA
1368 qdev_prop_set_uint32(&dev->qdev, "hostbus", filter.bus_num);
1369 qdev_prop_set_uint32(&dev->qdev, "hostaddr", filter.addr);
26a9e82a
GH
1370 qdev_prop_set_uint32(&dev->qdev, "vendorid", filter.vendor_id);
1371 qdev_prop_set_uint32(&dev->qdev, "productid", filter.product_id);
beb6f0de 1372 qdev_init_nofail(&dev->qdev);
26a9e82a 1373 return dev;
5d0c5750 1374
26a9e82a
GH
1375fail:
1376 qdev_free(&dev->qdev);
1377 return NULL;
4b096fc9 1378}
5d0c5750
AL
1379
1380int usb_host_device_close(const char *devname)
1381{
26a9e82a 1382#if 0
5d0c5750
AL
1383 char product_name[PRODUCT_NAME_SZ];
1384 int bus_num, addr;
1385 USBHostDevice *s;
1386
2791104c 1387 if (strstr(devname, "auto:")) {
5d0c5750 1388 return usb_host_auto_del(devname);
2791104c
DA
1389 }
1390 if (usb_host_find_device(&bus_num, &addr, product_name,
1391 sizeof(product_name), devname) < 0) {
5d0c5750 1392 return -1;
2791104c 1393 }
5d0c5750
AL
1394 s = hostdev_find(bus_num, addr);
1395 if (s) {
a5d2f727 1396 usb_device_delete_addr(s->bus_num, s->dev.addr);
5d0c5750
AL
1397 return 0;
1398 }
26a9e82a 1399#endif
5d0c5750
AL
1400
1401 return -1;
1402}
a5d2f727 1403
a594cfbf 1404static int get_tag_value(char *buf, int buf_size,
5fafdf24 1405 const char *str, const char *tag,
a594cfbf
FB
1406 const char *stopchars)
1407{
1408 const char *p;
1409 char *q;
1410 p = strstr(str, tag);
2791104c 1411 if (!p) {
a594cfbf 1412 return -1;
2791104c 1413 }
a594cfbf 1414 p += strlen(tag);
2791104c 1415 while (qemu_isspace(*p)) {
a594cfbf 1416 p++;
2791104c 1417 }
a594cfbf
FB
1418 q = buf;
1419 while (*p != '\0' && !strchr(stopchars, *p)) {
2791104c 1420 if ((q - buf) < (buf_size - 1)) {
a594cfbf 1421 *q++ = *p;
2791104c 1422 }
a594cfbf
FB
1423 p++;
1424 }
1425 *q = '\0';
1426 return q - buf;
bb36d470
FB
1427}
1428
0f431527
AL
1429/*
1430 * Use /proc/bus/usb/devices or /dev/bus/usb/devices file to determine
1431 * host's USB devices. This is legacy support since many distributions
1432 * are moving to /sys/bus/usb
1433 */
1434static int usb_host_scan_dev(void *opaque, USBScanFunc *func)
bb36d470 1435{
660f11be 1436 FILE *f = NULL;
a594cfbf 1437 char line[1024];
bb36d470 1438 char buf[1024];
a594cfbf 1439 int bus_num, addr, speed, device_count, class_id, product_id, vendor_id;
a594cfbf 1440 char product_name[512];
0f431527 1441 int ret = 0;
3b46e624 1442
0f431527
AL
1443 if (!usb_host_device_path) {
1444 perror("husb: USB Host Device Path not set");
1445 goto the_end;
1446 }
1447 snprintf(line, sizeof(line), "%s/devices", usb_host_device_path);
1448 f = fopen(line, "r");
a594cfbf 1449 if (!f) {
0f431527
AL
1450 perror("husb: cannot open devices file");
1451 goto the_end;
a594cfbf 1452 }
0f431527 1453
a594cfbf
FB
1454 device_count = 0;
1455 bus_num = addr = speed = class_id = product_id = vendor_id = 0;
bb36d470 1456 for(;;) {
2791104c 1457 if (fgets(line, sizeof(line), f) == NULL) {
bb36d470 1458 break;
2791104c
DA
1459 }
1460 if (strlen(line) > 0) {
a594cfbf 1461 line[strlen(line) - 1] = '\0';
2791104c 1462 }
a594cfbf 1463 if (line[0] == 'T' && line[1] == ':') {
38ca0f6d
PB
1464 if (device_count && (vendor_id || product_id)) {
1465 /* New device. Add the previously discovered device. */
0f5160d1 1466 ret = func(opaque, bus_num, addr, 0, class_id, vendor_id,
a594cfbf 1467 product_id, product_name, speed);
2791104c 1468 if (ret) {
a594cfbf 1469 goto the_end;
2791104c 1470 }
a594cfbf 1471 }
2791104c 1472 if (get_tag_value(buf, sizeof(buf), line, "Bus=", " ") < 0) {
a594cfbf 1473 goto fail;
2791104c 1474 }
a594cfbf 1475 bus_num = atoi(buf);
2791104c 1476 if (get_tag_value(buf, sizeof(buf), line, "Dev#=", " ") < 0) {
a594cfbf 1477 goto fail;
2791104c 1478 }
a594cfbf 1479 addr = atoi(buf);
2791104c 1480 if (get_tag_value(buf, sizeof(buf), line, "Spd=", " ") < 0) {
a594cfbf 1481 goto fail;
2791104c
DA
1482 }
1483 if (!strcmp(buf, "480")) {
a594cfbf 1484 speed = USB_SPEED_HIGH;
2791104c 1485 } else if (!strcmp(buf, "1.5")) {
a594cfbf 1486 speed = USB_SPEED_LOW;
2791104c 1487 } else {
a594cfbf 1488 speed = USB_SPEED_FULL;
2791104c 1489 }
a594cfbf
FB
1490 product_name[0] = '\0';
1491 class_id = 0xff;
1492 device_count++;
1493 product_id = 0;
1494 vendor_id = 0;
1495 } else if (line[0] == 'P' && line[1] == ':') {
2791104c 1496 if (get_tag_value(buf, sizeof(buf), line, "Vendor=", " ") < 0) {
a594cfbf 1497 goto fail;
2791104c 1498 }
a594cfbf 1499 vendor_id = strtoul(buf, NULL, 16);
2791104c 1500 if (get_tag_value(buf, sizeof(buf), line, "ProdID=", " ") < 0) {
a594cfbf 1501 goto fail;
2791104c 1502 }
a594cfbf
FB
1503 product_id = strtoul(buf, NULL, 16);
1504 } else if (line[0] == 'S' && line[1] == ':') {
2791104c 1505 if (get_tag_value(buf, sizeof(buf), line, "Product=", "") < 0) {
a594cfbf 1506 goto fail;
2791104c 1507 }
a594cfbf
FB
1508 pstrcpy(product_name, sizeof(product_name), buf);
1509 } else if (line[0] == 'D' && line[1] == ':') {
2791104c 1510 if (get_tag_value(buf, sizeof(buf), line, "Cls=", " (") < 0) {
a594cfbf 1511 goto fail;
2791104c 1512 }
a594cfbf 1513 class_id = strtoul(buf, NULL, 16);
bb36d470 1514 }
a594cfbf
FB
1515 fail: ;
1516 }
38ca0f6d
PB
1517 if (device_count && (vendor_id || product_id)) {
1518 /* Add the last device. */
0f5160d1 1519 ret = func(opaque, bus_num, addr, 0, class_id, vendor_id,
a594cfbf 1520 product_id, product_name, speed);
bb36d470 1521 }
a594cfbf 1522 the_end:
2791104c 1523 if (f) {
0f431527 1524 fclose(f);
2791104c 1525 }
0f431527
AL
1526 return ret;
1527}
1528
1529/*
1530 * Read sys file-system device file
1531 *
1532 * @line address of buffer to put file contents in
1533 * @line_size size of line
1534 * @device_file path to device file (printf format string)
1535 * @device_name device being opened (inserted into device_file)
1536 *
1537 * @return 0 failed, 1 succeeded ('line' contains data)
1538 */
2791104c
DA
1539static int usb_host_read_file(char *line, size_t line_size,
1540 const char *device_file, const char *device_name)
0f431527
AL
1541{
1542 FILE *f;
1543 int ret = 0;
1544 char filename[PATH_MAX];
1545
b4e237aa
BS
1546 snprintf(filename, PATH_MAX, USBSYSBUS_PATH "/devices/%s/%s", device_name,
1547 device_file);
0f431527
AL
1548 f = fopen(filename, "r");
1549 if (f) {
9f99cee7 1550 ret = fgets(line, line_size, f) != NULL;
0f431527 1551 fclose(f);
0f431527
AL
1552 }
1553
1554 return ret;
1555}
1556
1557/*
1558 * Use /sys/bus/usb/devices/ directory to determine host's USB
1559 * devices.
1560 *
1561 * This code is based on Robert Schiele's original patches posted to
1562 * the Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
1563 */
1564static int usb_host_scan_sys(void *opaque, USBScanFunc *func)
1565{
660f11be 1566 DIR *dir = NULL;
0f431527 1567 char line[1024];
0f5160d1 1568 int bus_num, addr, devpath, speed, class_id, product_id, vendor_id;
0f431527
AL
1569 int ret = 0;
1570 char product_name[512];
1571 struct dirent *de;
1572
1573 dir = opendir(USBSYSBUS_PATH "/devices");
1574 if (!dir) {
1575 perror("husb: cannot open devices directory");
1576 goto the_end;
1577 }
1578
1579 while ((de = readdir(dir))) {
1580 if (de->d_name[0] != '.' && !strchr(de->d_name, ':')) {
1581 char *tmpstr = de->d_name;
2791104c 1582 if (!strncmp(de->d_name, "usb", 3)) {
0f431527 1583 tmpstr += 3;
2791104c 1584 }
0f5160d1
HG
1585 if (sscanf(tmpstr, "%d-%d", &bus_num, &devpath) < 1) {
1586 goto the_end;
1587 }
0f431527 1588
2791104c 1589 if (!usb_host_read_file(line, sizeof(line), "devnum", de->d_name)) {
0f431527 1590 goto the_end;
2791104c
DA
1591 }
1592 if (sscanf(line, "%d", &addr) != 1) {
0f431527 1593 goto the_end;
2791104c 1594 }
b4e237aa 1595 if (!usb_host_read_file(line, sizeof(line), "bDeviceClass",
2791104c 1596 de->d_name)) {
0f431527 1597 goto the_end;
2791104c
DA
1598 }
1599 if (sscanf(line, "%x", &class_id) != 1) {
0f431527 1600 goto the_end;
2791104c 1601 }
0f431527 1602
2791104c
DA
1603 if (!usb_host_read_file(line, sizeof(line), "idVendor",
1604 de->d_name)) {
0f431527 1605 goto the_end;
2791104c
DA
1606 }
1607 if (sscanf(line, "%x", &vendor_id) != 1) {
0f431527 1608 goto the_end;
2791104c 1609 }
b4e237aa 1610 if (!usb_host_read_file(line, sizeof(line), "idProduct",
2791104c 1611 de->d_name)) {
0f431527 1612 goto the_end;
2791104c
DA
1613 }
1614 if (sscanf(line, "%x", &product_id) != 1) {
0f431527 1615 goto the_end;
2791104c 1616 }
b4e237aa
BS
1617 if (!usb_host_read_file(line, sizeof(line), "product",
1618 de->d_name)) {
0f431527
AL
1619 *product_name = 0;
1620 } else {
2791104c 1621 if (strlen(line) > 0) {
0f431527 1622 line[strlen(line) - 1] = '\0';
2791104c 1623 }
0f431527
AL
1624 pstrcpy(product_name, sizeof(product_name), line);
1625 }
1626
2791104c 1627 if (!usb_host_read_file(line, sizeof(line), "speed", de->d_name)) {
0f431527 1628 goto the_end;
2791104c
DA
1629 }
1630 if (!strcmp(line, "480\n")) {
0f431527 1631 speed = USB_SPEED_HIGH;
2791104c 1632 } else if (!strcmp(line, "1.5\n")) {
0f431527 1633 speed = USB_SPEED_LOW;
2791104c 1634 } else {
0f431527 1635 speed = USB_SPEED_FULL;
2791104c 1636 }
0f431527 1637
0f5160d1 1638 ret = func(opaque, bus_num, addr, devpath, class_id, vendor_id,
0f431527 1639 product_id, product_name, speed);
2791104c 1640 if (ret) {
0f431527 1641 goto the_end;
2791104c 1642 }
0f431527
AL
1643 }
1644 }
1645 the_end:
2791104c 1646 if (dir) {
0f431527 1647 closedir(dir);
2791104c 1648 }
0f431527
AL
1649 return ret;
1650}
1651
1652/*
1653 * Determine how to access the host's USB devices and call the
1654 * specific support function.
1655 */
1656static int usb_host_scan(void *opaque, USBScanFunc *func)
1657{
376253ec 1658 Monitor *mon = cur_mon;
660f11be
BS
1659 FILE *f = NULL;
1660 DIR *dir = NULL;
0f431527 1661 int ret = 0;
0f431527
AL
1662 const char *fs_type[] = {"unknown", "proc", "dev", "sys"};
1663 char devpath[PATH_MAX];
1664
1665 /* only check the host once */
1666 if (!usb_fs_type) {
55496240
MM
1667 dir = opendir(USBSYSBUS_PATH "/devices");
1668 if (dir) {
1669 /* devices found in /dev/bus/usb/ (yes - not a mistake!) */
1670 strcpy(devpath, USBDEVBUS_PATH);
1671 usb_fs_type = USB_FS_SYS;
1672 closedir(dir);
d0f2c4c6 1673 DPRINTF(USBDBG_DEVOPENED, USBSYSBUS_PATH);
55496240
MM
1674 goto found_devices;
1675 }
0f431527
AL
1676 f = fopen(USBPROCBUS_PATH "/devices", "r");
1677 if (f) {
1678 /* devices found in /proc/bus/usb/ */
1679 strcpy(devpath, USBPROCBUS_PATH);
1680 usb_fs_type = USB_FS_PROC;
1681 fclose(f);
d0f2c4c6 1682 DPRINTF(USBDBG_DEVOPENED, USBPROCBUS_PATH);
f16a0db3 1683 goto found_devices;
0f431527
AL
1684 }
1685 /* try additional methods if an access method hasn't been found yet */
1686 f = fopen(USBDEVBUS_PATH "/devices", "r");
f16a0db3 1687 if (f) {
0f431527
AL
1688 /* devices found in /dev/bus/usb/ */
1689 strcpy(devpath, USBDEVBUS_PATH);
1690 usb_fs_type = USB_FS_DEV;
1691 fclose(f);
d0f2c4c6 1692 DPRINTF(USBDBG_DEVOPENED, USBDEVBUS_PATH);
f16a0db3 1693 goto found_devices;
0f431527 1694 }
f16a0db3 1695 found_devices:
22babebb 1696 if (!usb_fs_type) {
2791104c 1697 if (mon) {
eba6fe87 1698 monitor_printf(mon, "husb: unable to access USB devices\n");
2791104c 1699 }
f16a0db3 1700 return -ENOENT;
0f431527
AL
1701 }
1702
1703 /* the module setting (used later for opening devices) */
1704 usb_host_device_path = qemu_mallocz(strlen(devpath)+1);
1eec614b 1705 strcpy(usb_host_device_path, devpath);
2791104c 1706 if (mon) {
eba6fe87
GH
1707 monitor_printf(mon, "husb: using %s file-system with %s\n",
1708 fs_type[usb_fs_type], usb_host_device_path);
2791104c 1709 }
0f431527
AL
1710 }
1711
1712 switch (usb_fs_type) {
1713 case USB_FS_PROC:
1714 case USB_FS_DEV:
1715 ret = usb_host_scan_dev(opaque, func);
1716 break;
1717 case USB_FS_SYS:
1718 ret = usb_host_scan_sys(opaque, func);
1719 break;
f16a0db3
AL
1720 default:
1721 ret = -EINVAL;
1722 break;
0f431527 1723 }
a594cfbf 1724 return ret;
bb36d470
FB
1725}
1726
4b096fc9 1727static QEMUTimer *usb_auto_timer;
4b096fc9 1728
0f5160d1 1729static int usb_host_auto_scan(void *opaque, int bus_num, int addr, int devpath,
26a9e82a
GH
1730 int class_id, int vendor_id, int product_id,
1731 const char *product_name, int speed)
4b096fc9
AL
1732{
1733 struct USBAutoFilter *f;
26a9e82a 1734 struct USBHostDevice *s;
4b096fc9
AL
1735
1736 /* Ignore hubs */
1737 if (class_id == 9)
1738 return 0;
1739
26a9e82a
GH
1740 QTAILQ_FOREACH(s, &hostdevs, next) {
1741 f = &s->match;
1742
2791104c 1743 if (f->bus_num > 0 && f->bus_num != bus_num) {
4b096fc9 1744 continue;
2791104c
DA
1745 }
1746 if (f->addr > 0 && f->addr != addr) {
4b096fc9 1747 continue;
2791104c 1748 }
4b096fc9 1749
2791104c 1750 if (f->vendor_id > 0 && f->vendor_id != vendor_id) {
4b096fc9 1751 continue;
2791104c 1752 }
4b096fc9 1753
2791104c 1754 if (f->product_id > 0 && f->product_id != product_id) {
4b096fc9 1755 continue;
2791104c 1756 }
4b096fc9
AL
1757 /* We got a match */
1758
33e66b86 1759 /* Already attached ? */
2791104c 1760 if (s->fd != -1) {
4b096fc9 1761 return 0;
2791104c 1762 }
d0f2c4c6 1763 DPRINTF("husb: auto open: bus_num %d addr %d\n", bus_num, addr);
4b096fc9 1764
0f5160d1 1765 usb_host_open(s, bus_num, addr, devpath, product_name);
4b096fc9
AL
1766 }
1767
1768 return 0;
1769}
1770
26a9e82a 1771static void usb_host_auto_check(void *unused)
4b096fc9 1772{
26a9e82a
GH
1773 struct USBHostDevice *s;
1774 int unconnected = 0;
1775
4b096fc9 1776 usb_host_scan(NULL, usb_host_auto_scan);
26a9e82a
GH
1777
1778 QTAILQ_FOREACH(s, &hostdevs, next) {
2791104c 1779 if (s->fd == -1) {
26a9e82a 1780 unconnected++;
2791104c 1781 }
26a9e82a
GH
1782 }
1783
1784 if (unconnected == 0) {
1785 /* nothing to watch */
2791104c 1786 if (usb_auto_timer) {
26a9e82a 1787 qemu_del_timer(usb_auto_timer);
2791104c 1788 }
26a9e82a
GH
1789 return;
1790 }
1791
1792 if (!usb_auto_timer) {
7bd427d8 1793 usb_auto_timer = qemu_new_timer_ms(rt_clock, usb_host_auto_check, NULL);
2791104c 1794 if (!usb_auto_timer) {
26a9e82a 1795 return;
2791104c 1796 }
26a9e82a 1797 }
7bd427d8 1798 qemu_mod_timer(usb_auto_timer, qemu_get_clock_ms(rt_clock) + 2000);
4b096fc9
AL
1799}
1800
1801/*
5d0c5750
AL
1802 * Autoconnect filter
1803 * Format:
1804 * auto:bus:dev[:vid:pid]
1805 * auto:bus.dev[:vid:pid]
1806 *
1807 * bus - bus number (dec, * means any)
1808 * dev - device number (dec, * means any)
1809 * vid - vendor id (hex, * means any)
1810 * pid - product id (hex, * means any)
1811 *
1812 * See 'lsusb' output.
4b096fc9 1813 */
5d0c5750 1814static int parse_filter(const char *spec, struct USBAutoFilter *f)
4b096fc9 1815{
5d0c5750
AL
1816 enum { BUS, DEV, VID, PID, DONE };
1817 const char *p = spec;
1818 int i;
1819
0745eb1e
MA
1820 f->bus_num = 0;
1821 f->addr = 0;
1822 f->vendor_id = 0;
1823 f->product_id = 0;
5d0c5750
AL
1824
1825 for (i = BUS; i < DONE; i++) {
2791104c
DA
1826 p = strpbrk(p, ":.");
1827 if (!p) {
1828 break;
1829 }
5d0c5750 1830 p++;
5d0c5750 1831
2791104c
DA
1832 if (*p == '*') {
1833 continue;
1834 }
5d0c5750
AL
1835 switch(i) {
1836 case BUS: f->bus_num = strtol(p, NULL, 10); break;
1837 case DEV: f->addr = strtol(p, NULL, 10); break;
1838 case VID: f->vendor_id = strtol(p, NULL, 16); break;
1839 case PID: f->product_id = strtol(p, NULL, 16); break;
1840 }
1841 }
1842
1843 if (i < DEV) {
1844 fprintf(stderr, "husb: invalid auto filter spec %s\n", spec);
1845 return -1;
1846 }
1847
1848 return 0;
1849}
1850
a594cfbf
FB
1851/**********************/
1852/* USB host device info */
1853
1854struct usb_class_info {
1855 int class;
1856 const char *class_name;
1857};
1858
1859static const struct usb_class_info usb_class_info[] = {
1860 { USB_CLASS_AUDIO, "Audio"},
1861 { USB_CLASS_COMM, "Communication"},
1862 { USB_CLASS_HID, "HID"},
1863 { USB_CLASS_HUB, "Hub" },
1864 { USB_CLASS_PHYSICAL, "Physical" },
1865 { USB_CLASS_PRINTER, "Printer" },
1866 { USB_CLASS_MASS_STORAGE, "Storage" },
1867 { USB_CLASS_CDC_DATA, "Data" },
1868 { USB_CLASS_APP_SPEC, "Application Specific" },
1869 { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
1870 { USB_CLASS_STILL_IMAGE, "Still Image" },
b9dc033c 1871 { USB_CLASS_CSCID, "Smart Card" },
a594cfbf
FB
1872 { USB_CLASS_CONTENT_SEC, "Content Security" },
1873 { -1, NULL }
1874};
1875
1876static const char *usb_class_str(uint8_t class)
bb36d470 1877{
a594cfbf
FB
1878 const struct usb_class_info *p;
1879 for(p = usb_class_info; p->class != -1; p++) {
2791104c 1880 if (p->class == class) {
a594cfbf 1881 break;
2791104c 1882 }
bb36d470 1883 }
a594cfbf
FB
1884 return p->class_name;
1885}
1886
179da8af 1887static void usb_info_device(Monitor *mon, int bus_num, int addr, int class_id,
9596ebb7
PB
1888 int vendor_id, int product_id,
1889 const char *product_name,
1890 int speed)
a594cfbf
FB
1891{
1892 const char *class_str, *speed_str;
1893
1894 switch(speed) {
5fafdf24
TS
1895 case USB_SPEED_LOW:
1896 speed_str = "1.5";
a594cfbf 1897 break;
5fafdf24
TS
1898 case USB_SPEED_FULL:
1899 speed_str = "12";
a594cfbf 1900 break;
5fafdf24
TS
1901 case USB_SPEED_HIGH:
1902 speed_str = "480";
a594cfbf
FB
1903 break;
1904 default:
5fafdf24 1905 speed_str = "?";
a594cfbf
FB
1906 break;
1907 }
1908
376253ec 1909 monitor_printf(mon, " Device %d.%d, speed %s Mb/s\n",
a594cfbf
FB
1910 bus_num, addr, speed_str);
1911 class_str = usb_class_str(class_id);
2791104c 1912 if (class_str) {
376253ec 1913 monitor_printf(mon, " %s:", class_str);
2791104c 1914 } else {
376253ec 1915 monitor_printf(mon, " Class %02x:", class_id);
2791104c 1916 }
376253ec 1917 monitor_printf(mon, " USB device %04x:%04x", vendor_id, product_id);
2791104c 1918 if (product_name[0] != '\0') {
376253ec 1919 monitor_printf(mon, ", %s", product_name);
2791104c 1920 }
376253ec 1921 monitor_printf(mon, "\n");
a594cfbf
FB
1922}
1923
5fafdf24 1924static int usb_host_info_device(void *opaque, int bus_num, int addr,
0f5160d1 1925 int devpath, int class_id,
5fafdf24 1926 int vendor_id, int product_id,
a594cfbf
FB
1927 const char *product_name,
1928 int speed)
1929{
179da8af
BS
1930 Monitor *mon = opaque;
1931
1932 usb_info_device(mon, bus_num, addr, class_id, vendor_id, product_id,
a594cfbf
FB
1933 product_name, speed);
1934 return 0;
1935}
1936
ac4ffb5a 1937static void dec2str(int val, char *str, size_t size)
5d0c5750 1938{
2791104c 1939 if (val == 0) {
ac4ffb5a 1940 snprintf(str, size, "*");
2791104c
DA
1941 } else {
1942 snprintf(str, size, "%d", val);
1943 }
5d0c5750
AL
1944}
1945
ac4ffb5a 1946static void hex2str(int val, char *str, size_t size)
5d0c5750 1947{
2791104c 1948 if (val == 0) {
ac4ffb5a 1949 snprintf(str, size, "*");
2791104c 1950 } else {
26a9e82a 1951 snprintf(str, size, "%04x", val);
2791104c 1952 }
5d0c5750
AL
1953}
1954
376253ec 1955void usb_host_info(Monitor *mon)
a594cfbf 1956{
5d0c5750 1957 struct USBAutoFilter *f;
26a9e82a 1958 struct USBHostDevice *s;
5d0c5750 1959
179da8af 1960 usb_host_scan(mon, usb_host_info_device);
5d0c5750 1961
2791104c 1962 if (QTAILQ_EMPTY(&hostdevs)) {
26a9e82a 1963 return;
2791104c
DA
1964 }
1965
26a9e82a
GH
1966 monitor_printf(mon, " Auto filters:\n");
1967 QTAILQ_FOREACH(s, &hostdevs, next) {
5d0c5750 1968 char bus[10], addr[10], vid[10], pid[10];
26a9e82a 1969 f = &s->match;
ac4ffb5a
AL
1970 dec2str(f->bus_num, bus, sizeof(bus));
1971 dec2str(f->addr, addr, sizeof(addr));
1972 hex2str(f->vendor_id, vid, sizeof(vid));
1973 hex2str(f->product_id, pid, sizeof(pid));
376253ec
AL
1974 monitor_printf(mon, " Device %s.%s ID %s:%s\n",
1975 bus, addr, vid, pid);
5d0c5750 1976 }
bb36d470 1977}