2 * Linux host USB redirector
4 * Copyright (c) 2005 Fabrice Bellard
6 * Copyright (c) 2008 Max Krasnyansky
7 * Support for host device auto connect & disconnect
8 * Major rewrite to support fully async operation
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
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:
21 * The above copyright notice and this permission notice shall be included in
22 * all copies or substantial portions of the Software.
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
33 #include "qemu-common.h"
34 #include "qemu-timer.h"
39 #include <sys/ioctl.h>
42 #include <linux/usbdevice_fs.h>
43 #include <linux/version.h>
46 /* We redefine it to avoid version problems */
47 struct usb_ctrltransfer
{
57 typedef int USBScanFunc(void *opaque
, int bus_num
, int addr
, char *port
,
58 int class_id
, int vendor_id
, int product_id
,
59 const char *product_name
, int speed
);
64 #define DPRINTF printf
69 #define USBDBG_DEVOPENED "husb: opened %s/devices\n"
71 #define USBPROCBUS_PATH "/proc/bus/usb"
72 #define PRODUCT_NAME_SZ 32
73 #define MAX_ENDPOINTS 15
74 #define MAX_PORTLEN 16
75 #define USBDEVBUS_PATH "/dev/bus/usb"
76 #define USBSYSBUS_PATH "/sys/bus/usb"
78 static char *usb_host_device_path
;
85 static int usb_fs_type
;
87 /* endpoint association data */
88 #define ISO_FRAME_DESC_PER_URB 32
89 #define ISO_URB_COUNT 3
90 #define INVALID_EP_TYPE 255
92 /* devio.c limits single requests to 16k */
93 #define MAX_USBFS_BUFFER_SIZE 16384
95 typedef struct AsyncURB AsyncURB
;
107 struct USBAutoFilter
{
115 typedef struct USBHostDevice
{
126 struct endp_data endp_table
[MAX_ENDPOINTS
];
127 QLIST_HEAD(, AsyncURB
) aurbs
;
129 /* Host side address */
132 char port
[MAX_PORTLEN
];
133 struct USBAutoFilter match
;
135 QTAILQ_ENTRY(USBHostDevice
) next
;
138 static QTAILQ_HEAD(, USBHostDevice
) hostdevs
= QTAILQ_HEAD_INITIALIZER(hostdevs
);
140 static int usb_host_close(USBHostDevice
*dev
);
141 static int parse_filter(const char *spec
, struct USBAutoFilter
*f
);
142 static void usb_host_auto_check(void *unused
);
143 static int usb_host_read_file(char *line
, size_t line_size
,
144 const char *device_file
, const char *device_name
);
146 static int is_isoc(USBHostDevice
*s
, int ep
)
148 return s
->endp_table
[ep
- 1].type
== USBDEVFS_URB_TYPE_ISO
;
151 static int is_valid(USBHostDevice
*s
, int ep
)
153 return s
->endp_table
[ep
- 1].type
!= INVALID_EP_TYPE
;
156 static int is_halted(USBHostDevice
*s
, int ep
)
158 return s
->endp_table
[ep
- 1].halted
;
161 static void clear_halt(USBHostDevice
*s
, int ep
)
163 s
->endp_table
[ep
- 1].halted
= 0;
166 static void set_halt(USBHostDevice
*s
, int ep
)
168 s
->endp_table
[ep
- 1].halted
= 1;
171 static int is_iso_started(USBHostDevice
*s
, int ep
)
173 return s
->endp_table
[ep
- 1].iso_started
;
176 static void clear_iso_started(USBHostDevice
*s
, int ep
)
178 s
->endp_table
[ep
- 1].iso_started
= 0;
181 static void set_iso_started(USBHostDevice
*s
, int ep
)
183 s
->endp_table
[ep
- 1].iso_started
= 1;
186 static void set_iso_urb(USBHostDevice
*s
, int ep
, AsyncURB
*iso_urb
)
188 s
->endp_table
[ep
- 1].iso_urb
= iso_urb
;
191 static AsyncURB
*get_iso_urb(USBHostDevice
*s
, int ep
)
193 return s
->endp_table
[ep
- 1].iso_urb
;
196 static void set_iso_urb_idx(USBHostDevice
*s
, int ep
, int i
)
198 s
->endp_table
[ep
- 1].iso_urb_idx
= i
;
201 static int get_iso_urb_idx(USBHostDevice
*s
, int ep
)
203 return s
->endp_table
[ep
- 1].iso_urb_idx
;
206 static void set_iso_buffer_used(USBHostDevice
*s
, int ep
, int i
)
208 s
->endp_table
[ep
- 1].iso_buffer_used
= i
;
211 static int get_iso_buffer_used(USBHostDevice
*s
, int ep
)
213 return s
->endp_table
[ep
- 1].iso_buffer_used
;
216 static void set_max_packet_size(USBHostDevice
*s
, int ep
, uint8_t *descriptor
)
218 int raw
= descriptor
[4] + (descriptor
[5] << 8);
219 int size
, microframes
;
222 switch ((raw
>> 11) & 3) {
223 case 1: microframes
= 2; break;
224 case 2: microframes
= 3; break;
225 default: microframes
= 1; break;
227 DPRINTF("husb: max packet size: 0x%x -> %d x %d\n",
228 raw
, microframes
, size
);
229 s
->endp_table
[ep
- 1].max_packet_size
= size
* microframes
;
232 static int get_max_packet_size(USBHostDevice
*s
, int ep
)
234 return s
->endp_table
[ep
- 1].max_packet_size
;
239 * We always allocate iso packet descriptors even for bulk transfers
240 * to simplify allocation and casts.
244 struct usbdevfs_urb urb
;
245 struct usbdevfs_iso_packet_desc isocpd
[ISO_FRAME_DESC_PER_URB
];
247 QLIST_ENTRY(AsyncURB
) next
;
249 /* For regular async urbs */
251 int more
; /* large transfer, more urbs follow */
253 /* For buffered iso handling */
254 int iso_frame_idx
; /* -1 means in flight */
257 static AsyncURB
*async_alloc(USBHostDevice
*s
)
259 AsyncURB
*aurb
= qemu_mallocz(sizeof(AsyncURB
));
261 QLIST_INSERT_HEAD(&s
->aurbs
, aurb
, next
);
265 static void async_free(AsyncURB
*aurb
)
267 QLIST_REMOVE(aurb
, next
);
271 static void async_complete(void *opaque
)
273 USBHostDevice
*s
= opaque
;
279 int r
= ioctl(s
->fd
, USBDEVFS_REAPURBNDELAY
, &aurb
);
281 if (errno
== EAGAIN
) {
284 if (errno
== ENODEV
&& !s
->closing
) {
285 printf("husb: device %d.%d disconnected\n",
286 s
->bus_num
, s
->addr
);
288 usb_host_auto_check(NULL
);
292 DPRINTF("husb: async. reap urb failed errno %d\n", errno
);
296 DPRINTF("husb: async completed. aurb %p status %d alen %d\n",
297 aurb
, aurb
->urb
.status
, aurb
->urb
.actual_length
);
299 /* If this is a buffered iso urb mark it as complete and don't do
300 anything else (it is handled further in usb_host_handle_iso_data) */
301 if (aurb
->iso_frame_idx
== -1) {
302 if (aurb
->urb
.status
== -EPIPE
) {
303 set_halt(s
, aurb
->urb
.endpoint
& 0xf);
305 aurb
->iso_frame_idx
= 0;
312 switch (aurb
->urb
.status
) {
314 p
->len
+= aurb
->urb
.actual_length
;
318 set_halt(s
, p
->devep
);
319 p
->len
= USB_RET_STALL
;
323 p
->len
= USB_RET_NAK
;
327 if (aurb
->urb
.type
== USBDEVFS_URB_TYPE_CONTROL
) {
328 usb_generic_async_ctrl_complete(&s
->dev
, p
);
329 } else if (!aurb
->more
) {
330 usb_packet_complete(&s
->dev
, p
);
338 static void async_cancel(USBPacket
*p
, void *opaque
)
340 USBHostDevice
*s
= opaque
;
343 QLIST_FOREACH(aurb
, &s
->aurbs
, next
) {
344 if (p
!= aurb
->packet
) {
348 DPRINTF("husb: async cancel: packet %p, aurb %p\n", p
, aurb
);
350 /* Mark it as dead (see async_complete above) */
353 int r
= ioctl(s
->fd
, USBDEVFS_DISCARDURB
, aurb
);
355 DPRINTF("husb: async. discard urb failed errno %d\n", errno
);
360 static int usb_host_claim_interfaces(USBHostDevice
*dev
, int configuration
)
362 int dev_descr_len
, config_descr_len
;
363 int interface
, nb_interfaces
;
366 if (configuration
== 0) /* address state - ignore */
369 DPRINTF("husb: claiming interfaces. config %d\n", configuration
);
372 dev_descr_len
= dev
->descr
[0];
373 if (dev_descr_len
> dev
->descr_len
) {
378 while (i
< dev
->descr_len
) {
379 DPRINTF("husb: i is %d, descr_len is %d, dl %d, dt %d\n",
381 dev
->descr
[i
], dev
->descr
[i
+1]);
383 if (dev
->descr
[i
+1] != USB_DT_CONFIG
) {
387 config_descr_len
= dev
->descr
[i
];
389 printf("husb: config #%d need %d\n", dev
->descr
[i
+ 5], configuration
);
391 if (configuration
< 0 || configuration
== dev
->descr
[i
+ 5]) {
392 configuration
= dev
->descr
[i
+ 5];
396 i
+= config_descr_len
;
399 if (i
>= dev
->descr_len
) {
401 "husb: update iface failed. no matching configuration\n");
404 nb_interfaces
= dev
->descr
[i
+ 4];
406 #ifdef USBDEVFS_DISCONNECT
407 /* earlier Linux 2.4 do not support that */
409 struct usbdevfs_ioctl ctrl
;
410 for (interface
= 0; interface
< nb_interfaces
; interface
++) {
411 ctrl
.ioctl_code
= USBDEVFS_DISCONNECT
;
412 ctrl
.ifno
= interface
;
414 ret
= ioctl(dev
->fd
, USBDEVFS_IOCTL
, &ctrl
);
415 if (ret
< 0 && errno
!= ENODATA
) {
416 perror("USBDEVFS_DISCONNECT");
423 /* XXX: only grab if all interfaces are free */
424 for (interface
= 0; interface
< nb_interfaces
; interface
++) {
425 ret
= ioctl(dev
->fd
, USBDEVFS_CLAIMINTERFACE
, &interface
);
427 if (errno
== EBUSY
) {
428 printf("husb: update iface. device already grabbed\n");
430 perror("husb: failed to claim interface");
437 printf("husb: %d interfaces claimed for configuration %d\n",
438 nb_interfaces
, configuration
);
440 dev
->ninterfaces
= nb_interfaces
;
441 dev
->configuration
= configuration
;
445 static int usb_host_release_interfaces(USBHostDevice
*s
)
449 DPRINTF("husb: releasing interfaces\n");
451 for (i
= 0; i
< s
->ninterfaces
; i
++) {
452 ret
= ioctl(s
->fd
, USBDEVFS_RELEASEINTERFACE
, &i
);
454 perror("husb: failed to release interface");
462 static void usb_host_handle_reset(USBDevice
*dev
)
464 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
466 DPRINTF("husb: reset device %u.%u\n", s
->bus_num
, s
->addr
);
468 ioctl(s
->fd
, USBDEVFS_RESET
);
470 usb_host_claim_interfaces(s
, s
->configuration
);
473 static void usb_host_handle_destroy(USBDevice
*dev
)
475 USBHostDevice
*s
= (USBHostDevice
*)dev
;
478 QTAILQ_REMOVE(&hostdevs
, s
, next
);
479 qemu_remove_exit_notifier(&s
->exit
);
482 static int usb_linux_update_endp_table(USBHostDevice
*s
);
484 /* iso data is special, we need to keep enough urbs in flight to make sure
485 that the controller never runs out of them, otherwise the device will
486 likely suffer a buffer underrun / overrun. */
487 static AsyncURB
*usb_host_alloc_iso(USBHostDevice
*s
, uint8_t ep
, int in
)
490 int i
, j
, len
= get_max_packet_size(s
, ep
);
492 aurb
= qemu_mallocz(ISO_URB_COUNT
* sizeof(*aurb
));
493 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
494 aurb
[i
].urb
.endpoint
= ep
;
495 aurb
[i
].urb
.buffer_length
= ISO_FRAME_DESC_PER_URB
* len
;
496 aurb
[i
].urb
.buffer
= qemu_malloc(aurb
[i
].urb
.buffer_length
);
497 aurb
[i
].urb
.type
= USBDEVFS_URB_TYPE_ISO
;
498 aurb
[i
].urb
.flags
= USBDEVFS_URB_ISO_ASAP
;
499 aurb
[i
].urb
.number_of_packets
= ISO_FRAME_DESC_PER_URB
;
500 for (j
= 0 ; j
< ISO_FRAME_DESC_PER_URB
; j
++)
501 aurb
[i
].urb
.iso_frame_desc
[j
].length
= len
;
503 aurb
[i
].urb
.endpoint
|= 0x80;
504 /* Mark as fully consumed (idle) */
505 aurb
[i
].iso_frame_idx
= ISO_FRAME_DESC_PER_URB
;
508 set_iso_urb(s
, ep
, aurb
);
513 static void usb_host_stop_n_free_iso(USBHostDevice
*s
, uint8_t ep
)
516 int i
, ret
, killed
= 0, free
= 1;
518 aurb
= get_iso_urb(s
, ep
);
523 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
525 if (aurb
[i
].iso_frame_idx
== -1) {
526 ret
= ioctl(s
->fd
, USBDEVFS_DISCARDURB
, &aurb
[i
]);
528 printf("husb: discard isoc in urb failed errno %d\n", errno
);
536 /* Make sure any urbs we've killed are reaped before we free them */
541 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
542 qemu_free(aurb
[i
].urb
.buffer
);
548 printf("husb: leaking iso urbs because of discard failure\n");
549 set_iso_urb(s
, ep
, NULL
);
550 set_iso_urb_idx(s
, ep
, 0);
551 clear_iso_started(s
, ep
);
554 static int urb_status_to_usb_ret(int status
)
558 return USB_RET_STALL
;
564 static int usb_host_handle_iso_data(USBHostDevice
*s
, USBPacket
*p
, int in
)
567 int i
, j
, ret
, max_packet_size
, offset
, len
= 0;
569 max_packet_size
= get_max_packet_size(s
, p
->devep
);
570 if (max_packet_size
== 0)
573 aurb
= get_iso_urb(s
, p
->devep
);
575 aurb
= usb_host_alloc_iso(s
, p
->devep
, in
);
578 i
= get_iso_urb_idx(s
, p
->devep
);
579 j
= aurb
[i
].iso_frame_idx
;
580 if (j
>= 0 && j
< ISO_FRAME_DESC_PER_URB
) {
582 /* Check urb status */
583 if (aurb
[i
].urb
.status
) {
584 len
= urb_status_to_usb_ret(aurb
[i
].urb
.status
);
585 /* Move to the next urb */
586 aurb
[i
].iso_frame_idx
= ISO_FRAME_DESC_PER_URB
- 1;
587 /* Check frame status */
588 } else if (aurb
[i
].urb
.iso_frame_desc
[j
].status
) {
589 len
= urb_status_to_usb_ret(
590 aurb
[i
].urb
.iso_frame_desc
[j
].status
);
591 /* Check the frame fits */
592 } else if (aurb
[i
].urb
.iso_frame_desc
[j
].actual_length
> p
->len
) {
593 printf("husb: received iso data is larger then packet\n");
595 /* All good copy data over */
597 len
= aurb
[i
].urb
.iso_frame_desc
[j
].actual_length
;
600 j
* aurb
[i
].urb
.iso_frame_desc
[0].length
,
605 offset
= (j
== 0) ? 0 : get_iso_buffer_used(s
, p
->devep
);
607 /* Check the frame fits */
608 if (len
> max_packet_size
) {
609 printf("husb: send iso data is larger then max packet size\n");
613 /* All good copy data over */
614 memcpy(aurb
[i
].urb
.buffer
+ offset
, p
->data
, len
);
615 aurb
[i
].urb
.iso_frame_desc
[j
].length
= len
;
617 set_iso_buffer_used(s
, p
->devep
, offset
);
619 /* Start the stream once we have buffered enough data */
620 if (!is_iso_started(s
, p
->devep
) && i
== 1 && j
== 8) {
621 set_iso_started(s
, p
->devep
);
624 aurb
[i
].iso_frame_idx
++;
625 if (aurb
[i
].iso_frame_idx
== ISO_FRAME_DESC_PER_URB
) {
626 i
= (i
+ 1) % ISO_URB_COUNT
;
627 set_iso_urb_idx(s
, p
->devep
, i
);
631 set_iso_started(s
, p
->devep
);
633 DPRINTF("hubs: iso out error no free buffer, dropping packet\n");
637 if (is_iso_started(s
, p
->devep
)) {
638 /* (Re)-submit all fully consumed / filled urbs */
639 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
640 if (aurb
[i
].iso_frame_idx
== ISO_FRAME_DESC_PER_URB
) {
641 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, &aurb
[i
]);
643 printf("husb error submitting iso urb %d: %d\n", i
, errno
);
644 if (!in
|| len
== 0) {
656 aurb
[i
].iso_frame_idx
= -1;
664 static int usb_host_handle_data(USBDevice
*dev
, USBPacket
*p
)
666 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
667 struct usbdevfs_urb
*urb
;
673 if (!is_valid(s
, p
->devep
)) {
677 if (p
->pid
== USB_TOKEN_IN
) {
678 ep
= p
->devep
| 0x80;
683 if (is_halted(s
, p
->devep
)) {
684 ret
= ioctl(s
->fd
, USBDEVFS_CLEAR_HALT
, &ep
);
686 DPRINTF("husb: failed to clear halt. ep 0x%x errno %d\n",
690 clear_halt(s
, p
->devep
);
693 if (is_isoc(s
, p
->devep
)) {
694 return usb_host_handle_iso_data(s
, p
, p
->pid
== USB_TOKEN_IN
);
701 aurb
= async_alloc(s
);
706 urb
->type
= USBDEVFS_URB_TYPE_BULK
;
707 urb
->usercontext
= s
;
710 if (rem
> MAX_USBFS_BUFFER_SIZE
) {
711 urb
->buffer_length
= MAX_USBFS_BUFFER_SIZE
;
714 urb
->buffer_length
= rem
;
717 pbuf
+= urb
->buffer_length
;
718 rem
-= urb
->buffer_length
;
720 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
722 DPRINTF("husb: data submit: ep 0x%x, len %u, more %d, packet %p, aurb %p\n",
723 urb
->endpoint
, urb
->buffer_length
, aurb
->more
, p
, aurb
);
726 DPRINTF("husb: submit failed. errno %d\n", errno
);
734 return USB_RET_STALL
;
739 usb_defer_packet(p
, async_cancel
, s
);
740 return USB_RET_ASYNC
;
743 static int ctrl_error(void)
745 if (errno
== ETIMEDOUT
) {
748 return USB_RET_STALL
;
752 static int usb_host_set_address(USBHostDevice
*s
, int addr
)
754 DPRINTF("husb: ctrl set addr %u\n", addr
);
759 static int usb_host_set_config(USBHostDevice
*s
, int config
)
761 usb_host_release_interfaces(s
);
763 int ret
= ioctl(s
->fd
, USBDEVFS_SETCONFIGURATION
, &config
);
765 DPRINTF("husb: ctrl set config %d ret %d errno %d\n", config
, ret
, errno
);
770 usb_host_claim_interfaces(s
, config
);
774 static int usb_host_set_interface(USBHostDevice
*s
, int iface
, int alt
)
776 struct usbdevfs_setinterface si
;
779 for (i
= 1; i
<= MAX_ENDPOINTS
; i
++) {
781 usb_host_stop_n_free_iso(s
, i
);
785 si
.interface
= iface
;
787 ret
= ioctl(s
->fd
, USBDEVFS_SETINTERFACE
, &si
);
789 DPRINTF("husb: ctrl set iface %d altset %d ret %d errno %d\n",
790 iface
, alt
, ret
, errno
);
795 usb_linux_update_endp_table(s
);
799 static int usb_host_handle_control(USBDevice
*dev
, USBPacket
*p
,
800 int request
, int value
, int index
, int length
, uint8_t *data
)
802 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
803 struct usbdevfs_urb
*urb
;
808 * Process certain standard device requests.
809 * These are infrequent and are processed synchronously.
812 /* Note request is (bRequestType << 8) | bRequest */
813 DPRINTF("husb: ctrl type 0x%x req 0x%x val 0x%x index %u len %u\n",
814 request
>> 8, request
& 0xff, value
, index
, length
);
817 case DeviceOutRequest
| USB_REQ_SET_ADDRESS
:
818 return usb_host_set_address(s
, value
);
820 case DeviceOutRequest
| USB_REQ_SET_CONFIGURATION
:
821 return usb_host_set_config(s
, value
& 0xff);
823 case InterfaceOutRequest
| USB_REQ_SET_INTERFACE
:
824 return usb_host_set_interface(s
, index
, value
);
827 /* The rest are asynchronous */
829 if (length
> sizeof(dev
->data_buf
)) {
830 fprintf(stderr
, "husb: ctrl buffer too small (%d > %zu)\n",
831 length
, sizeof(dev
->data_buf
));
832 return USB_RET_STALL
;
835 aurb
= async_alloc(s
);
839 * Setup ctrl transfer.
841 * s->ctrl is laid out such that data buffer immediately follows
842 * 'req' struct which is exactly what usbdevfs expects.
846 urb
->type
= USBDEVFS_URB_TYPE_CONTROL
;
847 urb
->endpoint
= p
->devep
;
849 urb
->buffer
= &dev
->setup_buf
;
850 urb
->buffer_length
= length
+ 8;
852 urb
->usercontext
= s
;
854 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
856 DPRINTF("husb: submit ctrl. len %u aurb %p\n", urb
->buffer_length
, aurb
);
859 DPRINTF("husb: submit failed. errno %d\n", errno
);
867 return USB_RET_STALL
;
871 usb_defer_packet(p
, async_cancel
, s
);
872 return USB_RET_ASYNC
;
875 static int usb_linux_get_configuration(USBHostDevice
*s
)
877 uint8_t configuration
;
878 struct usb_ctrltransfer ct
;
881 if (usb_fs_type
== USB_FS_SYS
) {
882 char device_name
[32], line
[1024];
885 sprintf(device_name
, "%d-%s", s
->bus_num
, s
->port
);
887 if (!usb_host_read_file(line
, sizeof(line
), "bConfigurationValue",
891 if (sscanf(line
, "%d", &configuration
) != 1) {
894 return configuration
;
898 ct
.bRequestType
= USB_DIR_IN
;
899 ct
.bRequest
= USB_REQ_GET_CONFIGURATION
;
903 ct
.data
= &configuration
;
906 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
908 perror("usb_linux_get_configuration");
912 /* in address state */
913 if (configuration
== 0) {
917 return configuration
;
920 static uint8_t usb_linux_get_alt_setting(USBHostDevice
*s
,
921 uint8_t configuration
, uint8_t interface
)
924 struct usb_ctrltransfer ct
;
927 if (usb_fs_type
== USB_FS_SYS
) {
928 char device_name
[64], line
[1024];
931 sprintf(device_name
, "%d-%s:%d.%d", s
->bus_num
, s
->port
,
932 (int)configuration
, (int)interface
);
934 if (!usb_host_read_file(line
, sizeof(line
), "bAlternateSetting",
938 if (sscanf(line
, "%d", &alt_setting
) != 1) {
945 ct
.bRequestType
= USB_DIR_IN
| USB_RECIP_INTERFACE
;
946 ct
.bRequest
= USB_REQ_GET_INTERFACE
;
948 ct
.wIndex
= interface
;
950 ct
.data
= &alt_setting
;
952 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
954 /* Assume alt 0 on error */
961 /* returns 1 on problem encountered or 0 for success */
962 static int usb_linux_update_endp_table(USBHostDevice
*s
)
964 uint8_t *descriptors
;
965 uint8_t devep
, type
, configuration
, alt_interface
;
966 int interface
, length
, i
;
968 for (i
= 0; i
< MAX_ENDPOINTS
; i
++)
969 s
->endp_table
[i
].type
= INVALID_EP_TYPE
;
971 i
= usb_linux_get_configuration(s
);
976 /* get the desired configuration, interface, and endpoint descriptors
977 * from device description */
978 descriptors
= &s
->descr
[18];
979 length
= s
->descr_len
- 18;
982 if (descriptors
[i
+ 1] != USB_DT_CONFIG
||
983 descriptors
[i
+ 5] != configuration
) {
984 DPRINTF("invalid descriptor data - configuration\n");
990 if (descriptors
[i
+ 1] != USB_DT_INTERFACE
||
991 (descriptors
[i
+ 1] == USB_DT_INTERFACE
&&
992 descriptors
[i
+ 4] == 0)) {
997 interface
= descriptors
[i
+ 2];
998 alt_interface
= usb_linux_get_alt_setting(s
, configuration
, interface
);
1000 /* the current interface descriptor is the active interface
1001 * and has endpoints */
1002 if (descriptors
[i
+ 3] != alt_interface
) {
1003 i
+= descriptors
[i
];
1007 /* advance to the endpoints */
1008 while (i
< length
&& descriptors
[i
+1] != USB_DT_ENDPOINT
) {
1009 i
+= descriptors
[i
];
1015 while (i
< length
) {
1016 if (descriptors
[i
+ 1] != USB_DT_ENDPOINT
) {
1020 devep
= descriptors
[i
+ 2];
1021 switch (descriptors
[i
+ 3] & 0x3) {
1023 type
= USBDEVFS_URB_TYPE_CONTROL
;
1026 type
= USBDEVFS_URB_TYPE_ISO
;
1027 set_max_packet_size(s
, (devep
& 0xf), descriptors
+ i
);
1030 type
= USBDEVFS_URB_TYPE_BULK
;
1033 type
= USBDEVFS_URB_TYPE_INTERRUPT
;
1036 DPRINTF("usb_host: malformed endpoint type\n");
1037 type
= USBDEVFS_URB_TYPE_BULK
;
1039 s
->endp_table
[(devep
& 0xf) - 1].type
= type
;
1040 s
->endp_table
[(devep
& 0xf) - 1].halted
= 0;
1042 i
+= descriptors
[i
];
1048 static int usb_host_open(USBHostDevice
*dev
, int bus_num
,
1049 int addr
, char *port
, const char *prod_name
)
1052 struct usbdevfs_connectinfo ci
;
1055 if (dev
->fd
!= -1) {
1058 printf("husb: open device %d.%d\n", bus_num
, addr
);
1060 if (!usb_host_device_path
) {
1061 perror("husb: USB Host Device Path not set");
1064 snprintf(buf
, sizeof(buf
), "%s/%03d/%03d", usb_host_device_path
,
1066 fd
= open(buf
, O_RDWR
| O_NONBLOCK
);
1071 DPRINTF("husb: opened %s\n", buf
);
1073 dev
->bus_num
= bus_num
;
1075 strcpy(dev
->port
, port
);
1078 /* read the device description */
1079 dev
->descr_len
= read(fd
, dev
->descr
, sizeof(dev
->descr
));
1080 if (dev
->descr_len
<= 0) {
1081 perror("husb: reading device data failed");
1088 printf("=== begin dumping device descriptor data ===\n");
1089 for (x
= 0; x
< dev
->descr_len
; x
++) {
1090 printf("%02x ", dev
->descr
[x
]);
1092 printf("\n=== end dumping device descriptor data ===\n");
1098 * Initial configuration is -1 which makes us claim first
1099 * available config. We used to start with 1, which does not
1100 * always work. I've seen devices where first config starts
1103 if (!usb_host_claim_interfaces(dev
, -1)) {
1107 ret
= ioctl(fd
, USBDEVFS_CONNECTINFO
, &ci
);
1109 perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
1113 printf("husb: grabbed usb device %d.%d\n", bus_num
, addr
);
1115 ret
= usb_linux_update_endp_table(dev
);
1121 dev
->dev
.speed
= USB_SPEED_LOW
;
1123 dev
->dev
.speed
= USB_SPEED_HIGH
;
1126 if (!prod_name
|| prod_name
[0] == '\0') {
1127 snprintf(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1128 "host:%d.%d", bus_num
, addr
);
1130 pstrcpy(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1134 /* USB devio uses 'write' flag to check for async completions */
1135 qemu_set_fd_handler(dev
->fd
, NULL
, async_complete
, dev
);
1137 usb_device_attach(&dev
->dev
);
1148 static int usb_host_close(USBHostDevice
*dev
)
1152 if (dev
->fd
== -1) {
1156 qemu_set_fd_handler(dev
->fd
, NULL
, NULL
, NULL
);
1158 for (i
= 1; i
<= MAX_ENDPOINTS
; i
++) {
1159 if (is_isoc(dev
, i
)) {
1160 usb_host_stop_n_free_iso(dev
, i
);
1163 async_complete(dev
);
1165 usb_device_detach(&dev
->dev
);
1166 ioctl(dev
->fd
, USBDEVFS_RESET
);
1172 static void usb_host_exit_notifier(struct Notifier
* n
)
1174 USBHostDevice
*s
= container_of(n
, USBHostDevice
, exit
);
1177 ioctl(s
->fd
, USBDEVFS_RESET
);
1181 static int usb_host_initfn(USBDevice
*dev
)
1183 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
1185 dev
->auto_attach
= 0;
1187 QTAILQ_INSERT_TAIL(&hostdevs
, s
, next
);
1188 s
->exit
.notify
= usb_host_exit_notifier
;
1189 qemu_add_exit_notifier(&s
->exit
);
1190 usb_host_auto_check(NULL
);
1194 static struct USBDeviceInfo usb_host_dev_info
= {
1195 .product_desc
= "USB Host Device",
1196 .qdev
.name
= "usb-host",
1197 .qdev
.size
= sizeof(USBHostDevice
),
1198 .init
= usb_host_initfn
,
1199 .handle_packet
= usb_generic_handle_packet
,
1200 .handle_data
= usb_host_handle_data
,
1201 .handle_control
= usb_host_handle_control
,
1202 .handle_reset
= usb_host_handle_reset
,
1203 .handle_destroy
= usb_host_handle_destroy
,
1204 .usbdevice_name
= "host",
1205 .usbdevice_init
= usb_host_device_open
,
1206 .qdev
.props
= (Property
[]) {
1207 DEFINE_PROP_UINT32("hostbus", USBHostDevice
, match
.bus_num
, 0),
1208 DEFINE_PROP_UINT32("hostaddr", USBHostDevice
, match
.addr
, 0),
1209 DEFINE_PROP_STRING("hostport", USBHostDevice
, match
.port
),
1210 DEFINE_PROP_HEX32("vendorid", USBHostDevice
, match
.vendor_id
, 0),
1211 DEFINE_PROP_HEX32("productid", USBHostDevice
, match
.product_id
, 0),
1212 DEFINE_PROP_END_OF_LIST(),
1216 static void usb_host_register_devices(void)
1218 usb_qdev_register(&usb_host_dev_info
);
1220 device_init(usb_host_register_devices
)
1222 USBDevice
*usb_host_device_open(const char *devname
)
1224 struct USBAutoFilter filter
;
1228 dev
= usb_create(NULL
/* FIXME */, "usb-host");
1230 if (strstr(devname
, "auto:")) {
1231 if (parse_filter(devname
, &filter
) < 0) {
1235 if ((p
= strchr(devname
, '.'))) {
1236 filter
.bus_num
= strtoul(devname
, NULL
, 0);
1237 filter
.addr
= strtoul(p
+ 1, NULL
, 0);
1238 filter
.vendor_id
= 0;
1239 filter
.product_id
= 0;
1240 } else if ((p
= strchr(devname
, ':'))) {
1243 filter
.vendor_id
= strtoul(devname
, NULL
, 16);
1244 filter
.product_id
= strtoul(p
+ 1, NULL
, 16);
1250 qdev_prop_set_uint32(&dev
->qdev
, "hostbus", filter
.bus_num
);
1251 qdev_prop_set_uint32(&dev
->qdev
, "hostaddr", filter
.addr
);
1252 qdev_prop_set_uint32(&dev
->qdev
, "vendorid", filter
.vendor_id
);
1253 qdev_prop_set_uint32(&dev
->qdev
, "productid", filter
.product_id
);
1254 qdev_init_nofail(&dev
->qdev
);
1258 qdev_free(&dev
->qdev
);
1262 int usb_host_device_close(const char *devname
)
1265 char product_name
[PRODUCT_NAME_SZ
];
1269 if (strstr(devname
, "auto:")) {
1270 return usb_host_auto_del(devname
);
1272 if (usb_host_find_device(&bus_num
, &addr
, product_name
,
1273 sizeof(product_name
), devname
) < 0) {
1276 s
= hostdev_find(bus_num
, addr
);
1278 usb_device_delete_addr(s
->bus_num
, s
->dev
.addr
);
1286 static int get_tag_value(char *buf
, int buf_size
,
1287 const char *str
, const char *tag
,
1288 const char *stopchars
)
1292 p
= strstr(str
, tag
);
1297 while (qemu_isspace(*p
)) {
1301 while (*p
!= '\0' && !strchr(stopchars
, *p
)) {
1302 if ((q
- buf
) < (buf_size
- 1)) {
1312 * Use /proc/bus/usb/devices or /dev/bus/usb/devices file to determine
1313 * host's USB devices. This is legacy support since many distributions
1314 * are moving to /sys/bus/usb
1316 static int usb_host_scan_dev(void *opaque
, USBScanFunc
*func
)
1321 int bus_num
, addr
, speed
, device_count
, class_id
, product_id
, vendor_id
;
1322 char product_name
[512];
1325 if (!usb_host_device_path
) {
1326 perror("husb: USB Host Device Path not set");
1329 snprintf(line
, sizeof(line
), "%s/devices", usb_host_device_path
);
1330 f
= fopen(line
, "r");
1332 perror("husb: cannot open devices file");
1337 bus_num
= addr
= speed
= class_id
= product_id
= vendor_id
= 0;
1339 if (fgets(line
, sizeof(line
), f
) == NULL
) {
1342 if (strlen(line
) > 0) {
1343 line
[strlen(line
) - 1] = '\0';
1345 if (line
[0] == 'T' && line
[1] == ':') {
1346 if (device_count
&& (vendor_id
|| product_id
)) {
1347 /* New device. Add the previously discovered device. */
1348 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1349 product_id
, product_name
, speed
);
1354 if (get_tag_value(buf
, sizeof(buf
), line
, "Bus=", " ") < 0) {
1357 bus_num
= atoi(buf
);
1358 if (get_tag_value(buf
, sizeof(buf
), line
, "Dev#=", " ") < 0) {
1362 if (get_tag_value(buf
, sizeof(buf
), line
, "Spd=", " ") < 0) {
1365 if (!strcmp(buf
, "480")) {
1366 speed
= USB_SPEED_HIGH
;
1367 } else if (!strcmp(buf
, "1.5")) {
1368 speed
= USB_SPEED_LOW
;
1370 speed
= USB_SPEED_FULL
;
1372 product_name
[0] = '\0';
1377 } else if (line
[0] == 'P' && line
[1] == ':') {
1378 if (get_tag_value(buf
, sizeof(buf
), line
, "Vendor=", " ") < 0) {
1381 vendor_id
= strtoul(buf
, NULL
, 16);
1382 if (get_tag_value(buf
, sizeof(buf
), line
, "ProdID=", " ") < 0) {
1385 product_id
= strtoul(buf
, NULL
, 16);
1386 } else if (line
[0] == 'S' && line
[1] == ':') {
1387 if (get_tag_value(buf
, sizeof(buf
), line
, "Product=", "") < 0) {
1390 pstrcpy(product_name
, sizeof(product_name
), buf
);
1391 } else if (line
[0] == 'D' && line
[1] == ':') {
1392 if (get_tag_value(buf
, sizeof(buf
), line
, "Cls=", " (") < 0) {
1395 class_id
= strtoul(buf
, NULL
, 16);
1399 if (device_count
&& (vendor_id
|| product_id
)) {
1400 /* Add the last device. */
1401 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1402 product_id
, product_name
, speed
);
1412 * Read sys file-system device file
1414 * @line address of buffer to put file contents in
1415 * @line_size size of line
1416 * @device_file path to device file (printf format string)
1417 * @device_name device being opened (inserted into device_file)
1419 * @return 0 failed, 1 succeeded ('line' contains data)
1421 static int usb_host_read_file(char *line
, size_t line_size
,
1422 const char *device_file
, const char *device_name
)
1426 char filename
[PATH_MAX
];
1428 snprintf(filename
, PATH_MAX
, USBSYSBUS_PATH
"/devices/%s/%s", device_name
,
1430 f
= fopen(filename
, "r");
1432 ret
= fgets(line
, line_size
, f
) != NULL
;
1440 * Use /sys/bus/usb/devices/ directory to determine host's USB
1443 * This code is based on Robert Schiele's original patches posted to
1444 * the Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
1446 static int usb_host_scan_sys(void *opaque
, USBScanFunc
*func
)
1450 int bus_num
, addr
, speed
, class_id
, product_id
, vendor_id
;
1452 char port
[MAX_PORTLEN
];
1453 char product_name
[512];
1456 dir
= opendir(USBSYSBUS_PATH
"/devices");
1458 perror("husb: cannot open devices directory");
1462 while ((de
= readdir(dir
))) {
1463 if (de
->d_name
[0] != '.' && !strchr(de
->d_name
, ':')) {
1464 if (sscanf(de
->d_name
, "%d-%7[0-9.]", &bus_num
, port
) < 2) {
1468 if (!usb_host_read_file(line
, sizeof(line
), "devnum", de
->d_name
)) {
1471 if (sscanf(line
, "%d", &addr
) != 1) {
1474 if (!usb_host_read_file(line
, sizeof(line
), "bDeviceClass",
1478 if (sscanf(line
, "%x", &class_id
) != 1) {
1482 if (!usb_host_read_file(line
, sizeof(line
), "idVendor",
1486 if (sscanf(line
, "%x", &vendor_id
) != 1) {
1489 if (!usb_host_read_file(line
, sizeof(line
), "idProduct",
1493 if (sscanf(line
, "%x", &product_id
) != 1) {
1496 if (!usb_host_read_file(line
, sizeof(line
), "product",
1500 if (strlen(line
) > 0) {
1501 line
[strlen(line
) - 1] = '\0';
1503 pstrcpy(product_name
, sizeof(product_name
), line
);
1506 if (!usb_host_read_file(line
, sizeof(line
), "speed", de
->d_name
)) {
1509 if (!strcmp(line
, "480\n")) {
1510 speed
= USB_SPEED_HIGH
;
1511 } else if (!strcmp(line
, "1.5\n")) {
1512 speed
= USB_SPEED_LOW
;
1514 speed
= USB_SPEED_FULL
;
1517 ret
= func(opaque
, bus_num
, addr
, port
, class_id
, vendor_id
,
1518 product_id
, product_name
, speed
);
1532 * Determine how to access the host's USB devices and call the
1533 * specific support function.
1535 static int usb_host_scan(void *opaque
, USBScanFunc
*func
)
1537 Monitor
*mon
= cur_mon
;
1541 const char *fs_type
[] = {"unknown", "proc", "dev", "sys"};
1542 char devpath
[PATH_MAX
];
1544 /* only check the host once */
1546 dir
= opendir(USBSYSBUS_PATH
"/devices");
1548 /* devices found in /dev/bus/usb/ (yes - not a mistake!) */
1549 strcpy(devpath
, USBDEVBUS_PATH
);
1550 usb_fs_type
= USB_FS_SYS
;
1552 DPRINTF(USBDBG_DEVOPENED
, USBSYSBUS_PATH
);
1555 f
= fopen(USBPROCBUS_PATH
"/devices", "r");
1557 /* devices found in /proc/bus/usb/ */
1558 strcpy(devpath
, USBPROCBUS_PATH
);
1559 usb_fs_type
= USB_FS_PROC
;
1561 DPRINTF(USBDBG_DEVOPENED
, USBPROCBUS_PATH
);
1564 /* try additional methods if an access method hasn't been found yet */
1565 f
= fopen(USBDEVBUS_PATH
"/devices", "r");
1567 /* devices found in /dev/bus/usb/ */
1568 strcpy(devpath
, USBDEVBUS_PATH
);
1569 usb_fs_type
= USB_FS_DEV
;
1571 DPRINTF(USBDBG_DEVOPENED
, USBDEVBUS_PATH
);
1577 monitor_printf(mon
, "husb: unable to access USB devices\n");
1582 /* the module setting (used later for opening devices) */
1583 usb_host_device_path
= qemu_mallocz(strlen(devpath
)+1);
1584 strcpy(usb_host_device_path
, devpath
);
1586 monitor_printf(mon
, "husb: using %s file-system with %s\n",
1587 fs_type
[usb_fs_type
], usb_host_device_path
);
1591 switch (usb_fs_type
) {
1594 ret
= usb_host_scan_dev(opaque
, func
);
1597 ret
= usb_host_scan_sys(opaque
, func
);
1606 static QEMUTimer
*usb_auto_timer
;
1608 static int usb_host_auto_scan(void *opaque
, int bus_num
, int addr
, char *port
,
1609 int class_id
, int vendor_id
, int product_id
,
1610 const char *product_name
, int speed
)
1612 struct USBAutoFilter
*f
;
1613 struct USBHostDevice
*s
;
1619 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1622 if (f
->bus_num
> 0 && f
->bus_num
!= bus_num
) {
1625 if (f
->addr
> 0 && f
->addr
!= addr
) {
1628 if (f
->port
!= NULL
&& (port
== NULL
|| strcmp(f
->port
, port
) != 0)) {
1632 if (f
->vendor_id
> 0 && f
->vendor_id
!= vendor_id
) {
1636 if (f
->product_id
> 0 && f
->product_id
!= product_id
) {
1639 /* We got a match */
1641 /* Already attached ? */
1645 DPRINTF("husb: auto open: bus_num %d addr %d\n", bus_num
, addr
);
1647 usb_host_open(s
, bus_num
, addr
, port
, product_name
);
1653 static void usb_host_auto_check(void *unused
)
1655 struct USBHostDevice
*s
;
1656 int unconnected
= 0;
1658 usb_host_scan(NULL
, usb_host_auto_scan
);
1660 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1666 if (unconnected
== 0) {
1667 /* nothing to watch */
1668 if (usb_auto_timer
) {
1669 qemu_del_timer(usb_auto_timer
);
1674 if (!usb_auto_timer
) {
1675 usb_auto_timer
= qemu_new_timer_ms(rt_clock
, usb_host_auto_check
, NULL
);
1676 if (!usb_auto_timer
) {
1680 qemu_mod_timer(usb_auto_timer
, qemu_get_clock_ms(rt_clock
) + 2000);
1684 * Autoconnect filter
1686 * auto:bus:dev[:vid:pid]
1687 * auto:bus.dev[:vid:pid]
1689 * bus - bus number (dec, * means any)
1690 * dev - device number (dec, * means any)
1691 * vid - vendor id (hex, * means any)
1692 * pid - product id (hex, * means any)
1694 * See 'lsusb' output.
1696 static int parse_filter(const char *spec
, struct USBAutoFilter
*f
)
1698 enum { BUS
, DEV
, VID
, PID
, DONE
};
1699 const char *p
= spec
;
1707 for (i
= BUS
; i
< DONE
; i
++) {
1708 p
= strpbrk(p
, ":.");
1718 case BUS
: f
->bus_num
= strtol(p
, NULL
, 10); break;
1719 case DEV
: f
->addr
= strtol(p
, NULL
, 10); break;
1720 case VID
: f
->vendor_id
= strtol(p
, NULL
, 16); break;
1721 case PID
: f
->product_id
= strtol(p
, NULL
, 16); break;
1726 fprintf(stderr
, "husb: invalid auto filter spec %s\n", spec
);
1733 /**********************/
1734 /* USB host device info */
1736 struct usb_class_info
{
1738 const char *class_name
;
1741 static const struct usb_class_info usb_class_info
[] = {
1742 { USB_CLASS_AUDIO
, "Audio"},
1743 { USB_CLASS_COMM
, "Communication"},
1744 { USB_CLASS_HID
, "HID"},
1745 { USB_CLASS_HUB
, "Hub" },
1746 { USB_CLASS_PHYSICAL
, "Physical" },
1747 { USB_CLASS_PRINTER
, "Printer" },
1748 { USB_CLASS_MASS_STORAGE
, "Storage" },
1749 { USB_CLASS_CDC_DATA
, "Data" },
1750 { USB_CLASS_APP_SPEC
, "Application Specific" },
1751 { USB_CLASS_VENDOR_SPEC
, "Vendor Specific" },
1752 { USB_CLASS_STILL_IMAGE
, "Still Image" },
1753 { USB_CLASS_CSCID
, "Smart Card" },
1754 { USB_CLASS_CONTENT_SEC
, "Content Security" },
1758 static const char *usb_class_str(uint8_t class)
1760 const struct usb_class_info
*p
;
1761 for(p
= usb_class_info
; p
->class != -1; p
++) {
1762 if (p
->class == class) {
1766 return p
->class_name
;
1769 static void usb_info_device(Monitor
*mon
, int bus_num
, int addr
, char *port
,
1770 int class_id
, int vendor_id
, int product_id
,
1771 const char *product_name
,
1774 const char *class_str
, *speed_str
;
1780 case USB_SPEED_FULL
:
1783 case USB_SPEED_HIGH
:
1791 monitor_printf(mon
, " Bus %d, Addr %d, Port %s, Speed %s Mb/s\n",
1792 bus_num
, addr
, port
, speed_str
);
1793 class_str
= usb_class_str(class_id
);
1795 monitor_printf(mon
, " %s:", class_str
);
1797 monitor_printf(mon
, " Class %02x:", class_id
);
1799 monitor_printf(mon
, " USB device %04x:%04x", vendor_id
, product_id
);
1800 if (product_name
[0] != '\0') {
1801 monitor_printf(mon
, ", %s", product_name
);
1803 monitor_printf(mon
, "\n");
1806 static int usb_host_info_device(void *opaque
, int bus_num
, int addr
,
1807 char *path
, int class_id
,
1808 int vendor_id
, int product_id
,
1809 const char *product_name
,
1812 Monitor
*mon
= opaque
;
1814 usb_info_device(mon
, bus_num
, addr
, path
, class_id
, vendor_id
, product_id
,
1815 product_name
, speed
);
1819 static void dec2str(int val
, char *str
, size_t size
)
1822 snprintf(str
, size
, "*");
1824 snprintf(str
, size
, "%d", val
);
1828 static void hex2str(int val
, char *str
, size_t size
)
1831 snprintf(str
, size
, "*");
1833 snprintf(str
, size
, "%04x", val
);
1837 void usb_host_info(Monitor
*mon
)
1839 struct USBAutoFilter
*f
;
1840 struct USBHostDevice
*s
;
1842 usb_host_scan(mon
, usb_host_info_device
);
1844 if (QTAILQ_EMPTY(&hostdevs
)) {
1848 monitor_printf(mon
, " Auto filters:\n");
1849 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1850 char bus
[10], addr
[10], vid
[10], pid
[10];
1852 dec2str(f
->bus_num
, bus
, sizeof(bus
));
1853 dec2str(f
->addr
, addr
, sizeof(addr
));
1854 hex2str(f
->vendor_id
, vid
, sizeof(vid
));
1855 hex2str(f
->product_id
, pid
, sizeof(pid
));
1856 monitor_printf(mon
, " Bus %s, Addr %s, Port %s, ID %s:%s\n",
1857 bus
, addr
, f
->port
? f
->port
: "*", vid
, pid
);