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