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>
41 #include <linux/usbdevice_fs.h>
42 #include <linux/version.h>
45 /* We redefine it to avoid version problems */
46 struct usb_ctrltransfer
{
56 typedef int USBScanFunc(void *opaque
, int bus_num
, int addr
, char *port
,
57 int class_id
, int vendor_id
, int product_id
,
58 const char *product_name
, int speed
);
63 #define DPRINTF printf
68 #define USBDBG_DEVOPENED "husb: opened %s/devices\n"
70 #define USBPROCBUS_PATH "/proc/bus/usb"
71 #define PRODUCT_NAME_SZ 32
72 #define MAX_ENDPOINTS 15
73 #define MAX_PORTLEN 16
74 #define USBDEVBUS_PATH "/dev/bus/usb"
75 #define USBSYSBUS_PATH "/sys/bus/usb"
77 static char *usb_host_device_path
;
84 static int usb_fs_type
;
86 /* endpoint association data */
87 #define ISO_FRAME_DESC_PER_URB 32
88 #define ISO_URB_COUNT 3
89 #define INVALID_EP_TYPE 255
91 /* devio.c limits single requests to 16k */
92 #define MAX_USBFS_BUFFER_SIZE 16384
94 typedef struct AsyncURB AsyncURB
;
106 struct USBAutoFilter
{
114 typedef struct USBHostDevice
{
125 struct endp_data endp_table
[MAX_ENDPOINTS
];
126 QLIST_HEAD(, AsyncURB
) aurbs
;
128 /* Host side address */
131 char port
[MAX_PORTLEN
];
132 struct USBAutoFilter match
;
134 QTAILQ_ENTRY(USBHostDevice
) next
;
137 static QTAILQ_HEAD(, USBHostDevice
) hostdevs
= QTAILQ_HEAD_INITIALIZER(hostdevs
);
139 static int usb_host_close(USBHostDevice
*dev
);
140 static int parse_filter(const char *spec
, struct USBAutoFilter
*f
);
141 static void usb_host_auto_check(void *unused
);
142 static int usb_host_read_file(char *line
, size_t line_size
,
143 const char *device_file
, const char *device_name
);
145 static int is_isoc(USBHostDevice
*s
, int ep
)
147 return s
->endp_table
[ep
- 1].type
== USBDEVFS_URB_TYPE_ISO
;
150 static int is_valid(USBHostDevice
*s
, int ep
)
152 return s
->endp_table
[ep
- 1].type
!= INVALID_EP_TYPE
;
155 static int is_halted(USBHostDevice
*s
, int ep
)
157 return s
->endp_table
[ep
- 1].halted
;
160 static void clear_halt(USBHostDevice
*s
, int ep
)
162 s
->endp_table
[ep
- 1].halted
= 0;
165 static void set_halt(USBHostDevice
*s
, int ep
)
167 s
->endp_table
[ep
- 1].halted
= 1;
170 static int is_iso_started(USBHostDevice
*s
, int ep
)
172 return s
->endp_table
[ep
- 1].iso_started
;
175 static void clear_iso_started(USBHostDevice
*s
, int ep
)
177 s
->endp_table
[ep
- 1].iso_started
= 0;
180 static void set_iso_started(USBHostDevice
*s
, int ep
)
182 s
->endp_table
[ep
- 1].iso_started
= 1;
185 static void set_iso_urb(USBHostDevice
*s
, int ep
, AsyncURB
*iso_urb
)
187 s
->endp_table
[ep
- 1].iso_urb
= iso_urb
;
190 static AsyncURB
*get_iso_urb(USBHostDevice
*s
, int ep
)
192 return s
->endp_table
[ep
- 1].iso_urb
;
195 static void set_iso_urb_idx(USBHostDevice
*s
, int ep
, int i
)
197 s
->endp_table
[ep
- 1].iso_urb_idx
= i
;
200 static int get_iso_urb_idx(USBHostDevice
*s
, int ep
)
202 return s
->endp_table
[ep
- 1].iso_urb_idx
;
205 static void set_iso_buffer_used(USBHostDevice
*s
, int ep
, int i
)
207 s
->endp_table
[ep
- 1].iso_buffer_used
= i
;
210 static int get_iso_buffer_used(USBHostDevice
*s
, int ep
)
212 return s
->endp_table
[ep
- 1].iso_buffer_used
;
215 static void set_max_packet_size(USBHostDevice
*s
, int ep
, uint8_t *descriptor
)
217 int raw
= descriptor
[4] + (descriptor
[5] << 8);
218 int size
, microframes
;
221 switch ((raw
>> 11) & 3) {
222 case 1: microframes
= 2; break;
223 case 2: microframes
= 3; break;
224 default: microframes
= 1; break;
226 DPRINTF("husb: max packet size: 0x%x -> %d x %d\n",
227 raw
, microframes
, size
);
228 s
->endp_table
[ep
- 1].max_packet_size
= size
* microframes
;
231 static int get_max_packet_size(USBHostDevice
*s
, int ep
)
233 return s
->endp_table
[ep
- 1].max_packet_size
;
238 * We always allocate iso packet descriptors even for bulk transfers
239 * to simplify allocation and casts.
243 struct usbdevfs_urb urb
;
244 struct usbdevfs_iso_packet_desc isocpd
[ISO_FRAME_DESC_PER_URB
];
246 QLIST_ENTRY(AsyncURB
) next
;
248 /* For regular async urbs */
250 int more
; /* large transfer, more urbs follow */
252 /* For buffered iso handling */
253 int iso_frame_idx
; /* -1 means in flight */
256 static AsyncURB
*async_alloc(USBHostDevice
*s
)
258 AsyncURB
*aurb
= qemu_mallocz(sizeof(AsyncURB
));
260 QLIST_INSERT_HEAD(&s
->aurbs
, aurb
, next
);
264 static void async_free(AsyncURB
*aurb
)
266 QLIST_REMOVE(aurb
, next
);
270 static void async_complete(void *opaque
)
272 USBHostDevice
*s
= opaque
;
278 int r
= ioctl(s
->fd
, USBDEVFS_REAPURBNDELAY
, &aurb
);
280 if (errno
== EAGAIN
) {
283 if (errno
== ENODEV
&& !s
->closing
) {
284 printf("husb: device %d.%d disconnected\n",
285 s
->bus_num
, s
->addr
);
287 usb_host_auto_check(NULL
);
291 DPRINTF("husb: async. reap urb failed errno %d\n", errno
);
295 DPRINTF("husb: async completed. aurb %p status %d alen %d\n",
296 aurb
, aurb
->urb
.status
, aurb
->urb
.actual_length
);
298 /* If this is a buffered iso urb mark it as complete and don't do
299 anything else (it is handled further in usb_host_handle_iso_data) */
300 if (aurb
->iso_frame_idx
== -1) {
301 if (aurb
->urb
.status
== -EPIPE
) {
302 set_halt(s
, aurb
->urb
.endpoint
& 0xf);
304 aurb
->iso_frame_idx
= 0;
311 switch (aurb
->urb
.status
) {
313 p
->len
+= aurb
->urb
.actual_length
;
317 set_halt(s
, p
->devep
);
318 p
->len
= USB_RET_STALL
;
322 p
->len
= USB_RET_NAK
;
326 if (aurb
->urb
.type
== USBDEVFS_URB_TYPE_CONTROL
) {
327 usb_generic_async_ctrl_complete(&s
->dev
, p
);
328 } else if (!aurb
->more
) {
329 usb_packet_complete(&s
->dev
, p
);
337 static void usb_host_async_cancel(USBDevice
*dev
, USBPacket
*p
)
339 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
342 QLIST_FOREACH(aurb
, &s
->aurbs
, next
) {
343 if (p
!= aurb
->packet
) {
347 DPRINTF("husb: async cancel: packet %p, aurb %p\n", p
, aurb
);
349 /* Mark it as dead (see async_complete above) */
352 int r
= ioctl(s
->fd
, USBDEVFS_DISCARDURB
, aurb
);
354 DPRINTF("husb: async. discard urb failed errno %d\n", errno
);
359 static int usb_host_claim_interfaces(USBHostDevice
*dev
, int configuration
)
361 int dev_descr_len
, config_descr_len
;
362 int interface
, nb_interfaces
;
365 if (configuration
== 0) /* address state - ignore */
368 DPRINTF("husb: claiming interfaces. config %d\n", configuration
);
371 dev_descr_len
= dev
->descr
[0];
372 if (dev_descr_len
> dev
->descr_len
) {
377 while (i
< dev
->descr_len
) {
378 DPRINTF("husb: i is %d, descr_len is %d, dl %d, dt %d\n",
380 dev
->descr
[i
], dev
->descr
[i
+1]);
382 if (dev
->descr
[i
+1] != USB_DT_CONFIG
) {
386 config_descr_len
= dev
->descr
[i
];
388 printf("husb: config #%d need %d\n", dev
->descr
[i
+ 5], configuration
);
390 if (configuration
< 0 || configuration
== dev
->descr
[i
+ 5]) {
391 configuration
= dev
->descr
[i
+ 5];
395 i
+= config_descr_len
;
398 if (i
>= dev
->descr_len
) {
400 "husb: update iface failed. no matching configuration\n");
403 nb_interfaces
= dev
->descr
[i
+ 4];
405 #ifdef USBDEVFS_DISCONNECT
406 /* earlier Linux 2.4 do not support that */
408 struct usbdevfs_ioctl ctrl
;
409 for (interface
= 0; interface
< nb_interfaces
; interface
++) {
410 ctrl
.ioctl_code
= USBDEVFS_DISCONNECT
;
411 ctrl
.ifno
= interface
;
413 ret
= ioctl(dev
->fd
, USBDEVFS_IOCTL
, &ctrl
);
414 if (ret
< 0 && errno
!= ENODATA
) {
415 perror("USBDEVFS_DISCONNECT");
422 /* XXX: only grab if all interfaces are free */
423 for (interface
= 0; interface
< nb_interfaces
; interface
++) {
424 ret
= ioctl(dev
->fd
, USBDEVFS_CLAIMINTERFACE
, &interface
);
426 if (errno
== EBUSY
) {
427 printf("husb: update iface. device already grabbed\n");
429 perror("husb: failed to claim interface");
436 printf("husb: %d interfaces claimed for configuration %d\n",
437 nb_interfaces
, configuration
);
439 dev
->ninterfaces
= nb_interfaces
;
440 dev
->configuration
= configuration
;
444 static int usb_host_release_interfaces(USBHostDevice
*s
)
448 DPRINTF("husb: releasing interfaces\n");
450 for (i
= 0; i
< s
->ninterfaces
; i
++) {
451 ret
= ioctl(s
->fd
, USBDEVFS_RELEASEINTERFACE
, &i
);
453 perror("husb: failed to release interface");
461 static void usb_host_handle_reset(USBDevice
*dev
)
463 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
465 DPRINTF("husb: reset device %u.%u\n", s
->bus_num
, s
->addr
);
467 ioctl(s
->fd
, USBDEVFS_RESET
);
469 usb_host_claim_interfaces(s
, s
->configuration
);
472 static void usb_host_handle_destroy(USBDevice
*dev
)
474 USBHostDevice
*s
= (USBHostDevice
*)dev
;
477 QTAILQ_REMOVE(&hostdevs
, s
, next
);
478 qemu_remove_exit_notifier(&s
->exit
);
481 static int usb_linux_update_endp_table(USBHostDevice
*s
);
483 /* iso data is special, we need to keep enough urbs in flight to make sure
484 that the controller never runs out of them, otherwise the device will
485 likely suffer a buffer underrun / overrun. */
486 static AsyncURB
*usb_host_alloc_iso(USBHostDevice
*s
, uint8_t ep
, int in
)
489 int i
, j
, len
= get_max_packet_size(s
, ep
);
491 aurb
= qemu_mallocz(ISO_URB_COUNT
* sizeof(*aurb
));
492 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
493 aurb
[i
].urb
.endpoint
= ep
;
494 aurb
[i
].urb
.buffer_length
= ISO_FRAME_DESC_PER_URB
* len
;
495 aurb
[i
].urb
.buffer
= qemu_malloc(aurb
[i
].urb
.buffer_length
);
496 aurb
[i
].urb
.type
= USBDEVFS_URB_TYPE_ISO
;
497 aurb
[i
].urb
.flags
= USBDEVFS_URB_ISO_ASAP
;
498 aurb
[i
].urb
.number_of_packets
= ISO_FRAME_DESC_PER_URB
;
499 for (j
= 0 ; j
< ISO_FRAME_DESC_PER_URB
; j
++)
500 aurb
[i
].urb
.iso_frame_desc
[j
].length
= len
;
502 aurb
[i
].urb
.endpoint
|= 0x80;
503 /* Mark as fully consumed (idle) */
504 aurb
[i
].iso_frame_idx
= ISO_FRAME_DESC_PER_URB
;
507 set_iso_urb(s
, ep
, aurb
);
512 static void usb_host_stop_n_free_iso(USBHostDevice
*s
, uint8_t ep
)
515 int i
, ret
, killed
= 0, free
= 1;
517 aurb
= get_iso_urb(s
, ep
);
522 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
524 if (aurb
[i
].iso_frame_idx
== -1) {
525 ret
= ioctl(s
->fd
, USBDEVFS_DISCARDURB
, &aurb
[i
]);
527 printf("husb: discard isoc in urb failed errno %d\n", errno
);
535 /* Make sure any urbs we've killed are reaped before we free them */
540 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
541 qemu_free(aurb
[i
].urb
.buffer
);
547 printf("husb: leaking iso urbs because of discard failure\n");
548 set_iso_urb(s
, ep
, NULL
);
549 set_iso_urb_idx(s
, ep
, 0);
550 clear_iso_started(s
, ep
);
553 static int urb_status_to_usb_ret(int status
)
557 return USB_RET_STALL
;
563 static int usb_host_handle_iso_data(USBHostDevice
*s
, USBPacket
*p
, int in
)
566 int i
, j
, ret
, max_packet_size
, offset
, len
= 0;
568 max_packet_size
= get_max_packet_size(s
, p
->devep
);
569 if (max_packet_size
== 0)
572 aurb
= get_iso_urb(s
, p
->devep
);
574 aurb
= usb_host_alloc_iso(s
, p
->devep
, in
);
577 i
= get_iso_urb_idx(s
, p
->devep
);
578 j
= aurb
[i
].iso_frame_idx
;
579 if (j
>= 0 && j
< ISO_FRAME_DESC_PER_URB
) {
581 /* Check urb status */
582 if (aurb
[i
].urb
.status
) {
583 len
= urb_status_to_usb_ret(aurb
[i
].urb
.status
);
584 /* Move to the next urb */
585 aurb
[i
].iso_frame_idx
= ISO_FRAME_DESC_PER_URB
- 1;
586 /* Check frame status */
587 } else if (aurb
[i
].urb
.iso_frame_desc
[j
].status
) {
588 len
= urb_status_to_usb_ret(
589 aurb
[i
].urb
.iso_frame_desc
[j
].status
);
590 /* Check the frame fits */
591 } else if (aurb
[i
].urb
.iso_frame_desc
[j
].actual_length
> p
->len
) {
592 printf("husb: received iso data is larger then packet\n");
594 /* All good copy data over */
596 len
= aurb
[i
].urb
.iso_frame_desc
[j
].actual_length
;
599 j
* aurb
[i
].urb
.iso_frame_desc
[0].length
,
604 offset
= (j
== 0) ? 0 : get_iso_buffer_used(s
, p
->devep
);
606 /* Check the frame fits */
607 if (len
> max_packet_size
) {
608 printf("husb: send iso data is larger then max packet size\n");
612 /* All good copy data over */
613 memcpy(aurb
[i
].urb
.buffer
+ offset
, p
->data
, len
);
614 aurb
[i
].urb
.iso_frame_desc
[j
].length
= len
;
616 set_iso_buffer_used(s
, p
->devep
, offset
);
618 /* Start the stream once we have buffered enough data */
619 if (!is_iso_started(s
, p
->devep
) && i
== 1 && j
== 8) {
620 set_iso_started(s
, p
->devep
);
623 aurb
[i
].iso_frame_idx
++;
624 if (aurb
[i
].iso_frame_idx
== ISO_FRAME_DESC_PER_URB
) {
625 i
= (i
+ 1) % ISO_URB_COUNT
;
626 set_iso_urb_idx(s
, p
->devep
, i
);
630 set_iso_started(s
, p
->devep
);
632 DPRINTF("hubs: iso out error no free buffer, dropping packet\n");
636 if (is_iso_started(s
, p
->devep
)) {
637 /* (Re)-submit all fully consumed / filled urbs */
638 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
639 if (aurb
[i
].iso_frame_idx
== ISO_FRAME_DESC_PER_URB
) {
640 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, &aurb
[i
]);
642 printf("husb error submitting iso urb %d: %d\n", i
, errno
);
643 if (!in
|| len
== 0) {
655 aurb
[i
].iso_frame_idx
= -1;
663 static int usb_host_handle_data(USBDevice
*dev
, USBPacket
*p
)
665 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
666 struct usbdevfs_urb
*urb
;
672 if (!is_valid(s
, p
->devep
)) {
676 if (p
->pid
== USB_TOKEN_IN
) {
677 ep
= p
->devep
| 0x80;
682 if (is_halted(s
, p
->devep
)) {
683 ret
= ioctl(s
->fd
, USBDEVFS_CLEAR_HALT
, &ep
);
685 DPRINTF("husb: failed to clear halt. ep 0x%x errno %d\n",
689 clear_halt(s
, p
->devep
);
692 if (is_isoc(s
, p
->devep
)) {
693 return usb_host_handle_iso_data(s
, p
, p
->pid
== USB_TOKEN_IN
);
700 aurb
= async_alloc(s
);
705 urb
->type
= USBDEVFS_URB_TYPE_BULK
;
706 urb
->usercontext
= s
;
709 if (rem
> MAX_USBFS_BUFFER_SIZE
) {
710 urb
->buffer_length
= MAX_USBFS_BUFFER_SIZE
;
713 urb
->buffer_length
= rem
;
716 pbuf
+= urb
->buffer_length
;
717 rem
-= urb
->buffer_length
;
719 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
721 DPRINTF("husb: data submit: ep 0x%x, len %u, more %d, packet %p, aurb %p\n",
722 urb
->endpoint
, urb
->buffer_length
, aurb
->more
, p
, aurb
);
725 DPRINTF("husb: submit failed. errno %d\n", errno
);
733 return USB_RET_STALL
;
738 return USB_RET_ASYNC
;
741 static int ctrl_error(void)
743 if (errno
== ETIMEDOUT
) {
746 return USB_RET_STALL
;
750 static int usb_host_set_address(USBHostDevice
*s
, int addr
)
752 DPRINTF("husb: ctrl set addr %u\n", addr
);
757 static int usb_host_set_config(USBHostDevice
*s
, int config
)
759 usb_host_release_interfaces(s
);
761 int ret
= ioctl(s
->fd
, USBDEVFS_SETCONFIGURATION
, &config
);
763 DPRINTF("husb: ctrl set config %d ret %d errno %d\n", config
, ret
, errno
);
768 usb_host_claim_interfaces(s
, config
);
772 static int usb_host_set_interface(USBHostDevice
*s
, int iface
, int alt
)
774 struct usbdevfs_setinterface si
;
777 for (i
= 1; i
<= MAX_ENDPOINTS
; i
++) {
779 usb_host_stop_n_free_iso(s
, i
);
783 si
.interface
= iface
;
785 ret
= ioctl(s
->fd
, USBDEVFS_SETINTERFACE
, &si
);
787 DPRINTF("husb: ctrl set iface %d altset %d ret %d errno %d\n",
788 iface
, alt
, ret
, errno
);
793 usb_linux_update_endp_table(s
);
797 static int usb_host_handle_control(USBDevice
*dev
, USBPacket
*p
,
798 int request
, int value
, int index
, int length
, uint8_t *data
)
800 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
801 struct usbdevfs_urb
*urb
;
806 * Process certain standard device requests.
807 * These are infrequent and are processed synchronously.
810 /* Note request is (bRequestType << 8) | bRequest */
811 DPRINTF("husb: ctrl type 0x%x req 0x%x val 0x%x index %u len %u\n",
812 request
>> 8, request
& 0xff, value
, index
, length
);
815 case DeviceOutRequest
| USB_REQ_SET_ADDRESS
:
816 return usb_host_set_address(s
, value
);
818 case DeviceOutRequest
| USB_REQ_SET_CONFIGURATION
:
819 return usb_host_set_config(s
, value
& 0xff);
821 case InterfaceOutRequest
| USB_REQ_SET_INTERFACE
:
822 return usb_host_set_interface(s
, index
, value
);
825 /* The rest are asynchronous */
827 if (length
> sizeof(dev
->data_buf
)) {
828 fprintf(stderr
, "husb: ctrl buffer too small (%d > %zu)\n",
829 length
, sizeof(dev
->data_buf
));
830 return USB_RET_STALL
;
833 aurb
= async_alloc(s
);
837 * Setup ctrl transfer.
839 * s->ctrl is laid out such that data buffer immediately follows
840 * 'req' struct which is exactly what usbdevfs expects.
844 urb
->type
= USBDEVFS_URB_TYPE_CONTROL
;
845 urb
->endpoint
= p
->devep
;
847 urb
->buffer
= &dev
->setup_buf
;
848 urb
->buffer_length
= length
+ 8;
850 urb
->usercontext
= s
;
852 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
854 DPRINTF("husb: submit ctrl. len %u aurb %p\n", urb
->buffer_length
, aurb
);
857 DPRINTF("husb: submit failed. errno %d\n", errno
);
865 return USB_RET_STALL
;
869 return USB_RET_ASYNC
;
872 static int usb_linux_get_configuration(USBHostDevice
*s
)
874 uint8_t configuration
;
875 struct usb_ctrltransfer ct
;
878 if (usb_fs_type
== USB_FS_SYS
) {
879 char device_name
[32], line
[1024];
882 sprintf(device_name
, "%d-%s", s
->bus_num
, s
->port
);
884 if (!usb_host_read_file(line
, sizeof(line
), "bConfigurationValue",
888 if (sscanf(line
, "%d", &configuration
) != 1) {
891 return configuration
;
895 ct
.bRequestType
= USB_DIR_IN
;
896 ct
.bRequest
= USB_REQ_GET_CONFIGURATION
;
900 ct
.data
= &configuration
;
903 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
905 perror("usb_linux_get_configuration");
909 /* in address state */
910 if (configuration
== 0) {
914 return configuration
;
917 static uint8_t usb_linux_get_alt_setting(USBHostDevice
*s
,
918 uint8_t configuration
, uint8_t interface
)
921 struct usb_ctrltransfer ct
;
924 if (usb_fs_type
== USB_FS_SYS
) {
925 char device_name
[64], line
[1024];
928 sprintf(device_name
, "%d-%s:%d.%d", s
->bus_num
, s
->port
,
929 (int)configuration
, (int)interface
);
931 if (!usb_host_read_file(line
, sizeof(line
), "bAlternateSetting",
935 if (sscanf(line
, "%d", &alt_setting
) != 1) {
942 ct
.bRequestType
= USB_DIR_IN
| USB_RECIP_INTERFACE
;
943 ct
.bRequest
= USB_REQ_GET_INTERFACE
;
945 ct
.wIndex
= interface
;
947 ct
.data
= &alt_setting
;
949 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
951 /* Assume alt 0 on error */
958 /* returns 1 on problem encountered or 0 for success */
959 static int usb_linux_update_endp_table(USBHostDevice
*s
)
961 uint8_t *descriptors
;
962 uint8_t devep
, type
, configuration
, alt_interface
;
963 int interface
, length
, i
;
965 for (i
= 0; i
< MAX_ENDPOINTS
; i
++)
966 s
->endp_table
[i
].type
= INVALID_EP_TYPE
;
968 i
= usb_linux_get_configuration(s
);
973 /* get the desired configuration, interface, and endpoint descriptors
974 * from device description */
975 descriptors
= &s
->descr
[18];
976 length
= s
->descr_len
- 18;
979 if (descriptors
[i
+ 1] != USB_DT_CONFIG
||
980 descriptors
[i
+ 5] != configuration
) {
981 DPRINTF("invalid descriptor data - configuration\n");
987 if (descriptors
[i
+ 1] != USB_DT_INTERFACE
||
988 (descriptors
[i
+ 1] == USB_DT_INTERFACE
&&
989 descriptors
[i
+ 4] == 0)) {
994 interface
= descriptors
[i
+ 2];
995 alt_interface
= usb_linux_get_alt_setting(s
, configuration
, interface
);
997 /* the current interface descriptor is the active interface
998 * and has endpoints */
999 if (descriptors
[i
+ 3] != alt_interface
) {
1000 i
+= descriptors
[i
];
1004 /* advance to the endpoints */
1005 while (i
< length
&& descriptors
[i
+1] != USB_DT_ENDPOINT
) {
1006 i
+= descriptors
[i
];
1012 while (i
< length
) {
1013 if (descriptors
[i
+ 1] != USB_DT_ENDPOINT
) {
1017 devep
= descriptors
[i
+ 2];
1018 switch (descriptors
[i
+ 3] & 0x3) {
1020 type
= USBDEVFS_URB_TYPE_CONTROL
;
1023 type
= USBDEVFS_URB_TYPE_ISO
;
1024 set_max_packet_size(s
, (devep
& 0xf), descriptors
+ i
);
1027 type
= USBDEVFS_URB_TYPE_BULK
;
1030 type
= USBDEVFS_URB_TYPE_INTERRUPT
;
1033 DPRINTF("usb_host: malformed endpoint type\n");
1034 type
= USBDEVFS_URB_TYPE_BULK
;
1036 s
->endp_table
[(devep
& 0xf) - 1].type
= type
;
1037 s
->endp_table
[(devep
& 0xf) - 1].halted
= 0;
1039 i
+= descriptors
[i
];
1045 static int usb_host_open(USBHostDevice
*dev
, int bus_num
,
1046 int addr
, char *port
, const char *prod_name
)
1049 struct usbdevfs_connectinfo ci
;
1052 if (dev
->fd
!= -1) {
1055 printf("husb: open device %d.%d\n", bus_num
, addr
);
1057 if (!usb_host_device_path
) {
1058 perror("husb: USB Host Device Path not set");
1061 snprintf(buf
, sizeof(buf
), "%s/%03d/%03d", usb_host_device_path
,
1063 fd
= open(buf
, O_RDWR
| O_NONBLOCK
);
1068 DPRINTF("husb: opened %s\n", buf
);
1070 dev
->bus_num
= bus_num
;
1072 strcpy(dev
->port
, port
);
1075 /* read the device description */
1076 dev
->descr_len
= read(fd
, dev
->descr
, sizeof(dev
->descr
));
1077 if (dev
->descr_len
<= 0) {
1078 perror("husb: reading device data failed");
1085 printf("=== begin dumping device descriptor data ===\n");
1086 for (x
= 0; x
< dev
->descr_len
; x
++) {
1087 printf("%02x ", dev
->descr
[x
]);
1089 printf("\n=== end dumping device descriptor data ===\n");
1095 * Initial configuration is -1 which makes us claim first
1096 * available config. We used to start with 1, which does not
1097 * always work. I've seen devices where first config starts
1100 if (!usb_host_claim_interfaces(dev
, -1)) {
1104 ret
= ioctl(fd
, USBDEVFS_CONNECTINFO
, &ci
);
1106 perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
1110 printf("husb: grabbed usb device %d.%d\n", bus_num
, addr
);
1112 ret
= usb_linux_update_endp_table(dev
);
1118 dev
->dev
.speed
= USB_SPEED_LOW
;
1120 dev
->dev
.speed
= USB_SPEED_HIGH
;
1123 if (!prod_name
|| prod_name
[0] == '\0') {
1124 snprintf(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1125 "host:%d.%d", bus_num
, addr
);
1127 pstrcpy(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1131 /* USB devio uses 'write' flag to check for async completions */
1132 qemu_set_fd_handler(dev
->fd
, NULL
, async_complete
, dev
);
1134 usb_device_attach(&dev
->dev
);
1145 static int usb_host_close(USBHostDevice
*dev
)
1149 if (dev
->fd
== -1) {
1153 qemu_set_fd_handler(dev
->fd
, NULL
, NULL
, NULL
);
1155 for (i
= 1; i
<= MAX_ENDPOINTS
; i
++) {
1156 if (is_isoc(dev
, i
)) {
1157 usb_host_stop_n_free_iso(dev
, i
);
1160 async_complete(dev
);
1162 usb_device_detach(&dev
->dev
);
1163 ioctl(dev
->fd
, USBDEVFS_RESET
);
1169 static void usb_host_exit_notifier(struct Notifier
* n
)
1171 USBHostDevice
*s
= container_of(n
, USBHostDevice
, exit
);
1174 ioctl(s
->fd
, USBDEVFS_RESET
);
1178 static int usb_host_initfn(USBDevice
*dev
)
1180 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
1182 dev
->auto_attach
= 0;
1184 QTAILQ_INSERT_TAIL(&hostdevs
, s
, next
);
1185 s
->exit
.notify
= usb_host_exit_notifier
;
1186 qemu_add_exit_notifier(&s
->exit
);
1187 usb_host_auto_check(NULL
);
1191 static struct USBDeviceInfo usb_host_dev_info
= {
1192 .product_desc
= "USB Host Device",
1193 .qdev
.name
= "usb-host",
1194 .qdev
.size
= sizeof(USBHostDevice
),
1195 .init
= usb_host_initfn
,
1196 .handle_packet
= usb_generic_handle_packet
,
1197 .cancel_packet
= usb_host_async_cancel
,
1198 .handle_data
= usb_host_handle_data
,
1199 .handle_control
= usb_host_handle_control
,
1200 .handle_reset
= usb_host_handle_reset
,
1201 .handle_destroy
= usb_host_handle_destroy
,
1202 .usbdevice_name
= "host",
1203 .usbdevice_init
= usb_host_device_open
,
1204 .qdev
.props
= (Property
[]) {
1205 DEFINE_PROP_UINT32("hostbus", USBHostDevice
, match
.bus_num
, 0),
1206 DEFINE_PROP_UINT32("hostaddr", USBHostDevice
, match
.addr
, 0),
1207 DEFINE_PROP_STRING("hostport", USBHostDevice
, match
.port
),
1208 DEFINE_PROP_HEX32("vendorid", USBHostDevice
, match
.vendor_id
, 0),
1209 DEFINE_PROP_HEX32("productid", USBHostDevice
, match
.product_id
, 0),
1210 DEFINE_PROP_END_OF_LIST(),
1214 static void usb_host_register_devices(void)
1216 usb_qdev_register(&usb_host_dev_info
);
1218 device_init(usb_host_register_devices
)
1220 USBDevice
*usb_host_device_open(const char *devname
)
1222 struct USBAutoFilter filter
;
1226 dev
= usb_create(NULL
/* FIXME */, "usb-host");
1228 if (strstr(devname
, "auto:")) {
1229 if (parse_filter(devname
, &filter
) < 0) {
1233 if ((p
= strchr(devname
, '.'))) {
1234 filter
.bus_num
= strtoul(devname
, NULL
, 0);
1235 filter
.addr
= strtoul(p
+ 1, NULL
, 0);
1236 filter
.vendor_id
= 0;
1237 filter
.product_id
= 0;
1238 } else if ((p
= strchr(devname
, ':'))) {
1241 filter
.vendor_id
= strtoul(devname
, NULL
, 16);
1242 filter
.product_id
= strtoul(p
+ 1, NULL
, 16);
1248 qdev_prop_set_uint32(&dev
->qdev
, "hostbus", filter
.bus_num
);
1249 qdev_prop_set_uint32(&dev
->qdev
, "hostaddr", filter
.addr
);
1250 qdev_prop_set_uint32(&dev
->qdev
, "vendorid", filter
.vendor_id
);
1251 qdev_prop_set_uint32(&dev
->qdev
, "productid", filter
.product_id
);
1252 qdev_init_nofail(&dev
->qdev
);
1256 qdev_free(&dev
->qdev
);
1260 int usb_host_device_close(const char *devname
)
1263 char product_name
[PRODUCT_NAME_SZ
];
1267 if (strstr(devname
, "auto:")) {
1268 return usb_host_auto_del(devname
);
1270 if (usb_host_find_device(&bus_num
, &addr
, product_name
,
1271 sizeof(product_name
), devname
) < 0) {
1274 s
= hostdev_find(bus_num
, addr
);
1276 usb_device_delete_addr(s
->bus_num
, s
->dev
.addr
);
1284 static int get_tag_value(char *buf
, int buf_size
,
1285 const char *str
, const char *tag
,
1286 const char *stopchars
)
1290 p
= strstr(str
, tag
);
1295 while (qemu_isspace(*p
)) {
1299 while (*p
!= '\0' && !strchr(stopchars
, *p
)) {
1300 if ((q
- buf
) < (buf_size
- 1)) {
1310 * Use /proc/bus/usb/devices or /dev/bus/usb/devices file to determine
1311 * host's USB devices. This is legacy support since many distributions
1312 * are moving to /sys/bus/usb
1314 static int usb_host_scan_dev(void *opaque
, USBScanFunc
*func
)
1319 int bus_num
, addr
, speed
, device_count
, class_id
, product_id
, vendor_id
;
1320 char product_name
[512];
1323 if (!usb_host_device_path
) {
1324 perror("husb: USB Host Device Path not set");
1327 snprintf(line
, sizeof(line
), "%s/devices", usb_host_device_path
);
1328 f
= fopen(line
, "r");
1330 perror("husb: cannot open devices file");
1335 bus_num
= addr
= speed
= class_id
= product_id
= vendor_id
= 0;
1337 if (fgets(line
, sizeof(line
), f
) == NULL
) {
1340 if (strlen(line
) > 0) {
1341 line
[strlen(line
) - 1] = '\0';
1343 if (line
[0] == 'T' && line
[1] == ':') {
1344 if (device_count
&& (vendor_id
|| product_id
)) {
1345 /* New device. Add the previously discovered device. */
1346 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1347 product_id
, product_name
, speed
);
1352 if (get_tag_value(buf
, sizeof(buf
), line
, "Bus=", " ") < 0) {
1355 bus_num
= atoi(buf
);
1356 if (get_tag_value(buf
, sizeof(buf
), line
, "Dev#=", " ") < 0) {
1360 if (get_tag_value(buf
, sizeof(buf
), line
, "Spd=", " ") < 0) {
1363 if (!strcmp(buf
, "480")) {
1364 speed
= USB_SPEED_HIGH
;
1365 } else if (!strcmp(buf
, "1.5")) {
1366 speed
= USB_SPEED_LOW
;
1368 speed
= USB_SPEED_FULL
;
1370 product_name
[0] = '\0';
1375 } else if (line
[0] == 'P' && line
[1] == ':') {
1376 if (get_tag_value(buf
, sizeof(buf
), line
, "Vendor=", " ") < 0) {
1379 vendor_id
= strtoul(buf
, NULL
, 16);
1380 if (get_tag_value(buf
, sizeof(buf
), line
, "ProdID=", " ") < 0) {
1383 product_id
= strtoul(buf
, NULL
, 16);
1384 } else if (line
[0] == 'S' && line
[1] == ':') {
1385 if (get_tag_value(buf
, sizeof(buf
), line
, "Product=", "") < 0) {
1388 pstrcpy(product_name
, sizeof(product_name
), buf
);
1389 } else if (line
[0] == 'D' && line
[1] == ':') {
1390 if (get_tag_value(buf
, sizeof(buf
), line
, "Cls=", " (") < 0) {
1393 class_id
= strtoul(buf
, NULL
, 16);
1397 if (device_count
&& (vendor_id
|| product_id
)) {
1398 /* Add the last device. */
1399 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1400 product_id
, product_name
, speed
);
1410 * Read sys file-system device file
1412 * @line address of buffer to put file contents in
1413 * @line_size size of line
1414 * @device_file path to device file (printf format string)
1415 * @device_name device being opened (inserted into device_file)
1417 * @return 0 failed, 1 succeeded ('line' contains data)
1419 static int usb_host_read_file(char *line
, size_t line_size
,
1420 const char *device_file
, const char *device_name
)
1424 char filename
[PATH_MAX
];
1426 snprintf(filename
, PATH_MAX
, USBSYSBUS_PATH
"/devices/%s/%s", device_name
,
1428 f
= fopen(filename
, "r");
1430 ret
= fgets(line
, line_size
, f
) != NULL
;
1438 * Use /sys/bus/usb/devices/ directory to determine host's USB
1441 * This code is based on Robert Schiele's original patches posted to
1442 * the Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
1444 static int usb_host_scan_sys(void *opaque
, USBScanFunc
*func
)
1448 int bus_num
, addr
, speed
, class_id
, product_id
, vendor_id
;
1450 char port
[MAX_PORTLEN
];
1451 char product_name
[512];
1454 dir
= opendir(USBSYSBUS_PATH
"/devices");
1456 perror("husb: cannot open devices directory");
1460 while ((de
= readdir(dir
))) {
1461 if (de
->d_name
[0] != '.' && !strchr(de
->d_name
, ':')) {
1462 if (sscanf(de
->d_name
, "%d-%7[0-9.]", &bus_num
, port
) < 2) {
1466 if (!usb_host_read_file(line
, sizeof(line
), "devnum", de
->d_name
)) {
1469 if (sscanf(line
, "%d", &addr
) != 1) {
1472 if (!usb_host_read_file(line
, sizeof(line
), "bDeviceClass",
1476 if (sscanf(line
, "%x", &class_id
) != 1) {
1480 if (!usb_host_read_file(line
, sizeof(line
), "idVendor",
1484 if (sscanf(line
, "%x", &vendor_id
) != 1) {
1487 if (!usb_host_read_file(line
, sizeof(line
), "idProduct",
1491 if (sscanf(line
, "%x", &product_id
) != 1) {
1494 if (!usb_host_read_file(line
, sizeof(line
), "product",
1498 if (strlen(line
) > 0) {
1499 line
[strlen(line
) - 1] = '\0';
1501 pstrcpy(product_name
, sizeof(product_name
), line
);
1504 if (!usb_host_read_file(line
, sizeof(line
), "speed", de
->d_name
)) {
1507 if (!strcmp(line
, "480\n")) {
1508 speed
= USB_SPEED_HIGH
;
1509 } else if (!strcmp(line
, "1.5\n")) {
1510 speed
= USB_SPEED_LOW
;
1512 speed
= USB_SPEED_FULL
;
1515 ret
= func(opaque
, bus_num
, addr
, port
, class_id
, vendor_id
,
1516 product_id
, product_name
, speed
);
1530 * Determine how to access the host's USB devices and call the
1531 * specific support function.
1533 static int usb_host_scan(void *opaque
, USBScanFunc
*func
)
1535 Monitor
*mon
= cur_mon
;
1539 const char *fs_type
[] = {"unknown", "proc", "dev", "sys"};
1540 char devpath
[PATH_MAX
];
1542 /* only check the host once */
1544 dir
= opendir(USBSYSBUS_PATH
"/devices");
1546 /* devices found in /dev/bus/usb/ (yes - not a mistake!) */
1547 strcpy(devpath
, USBDEVBUS_PATH
);
1548 usb_fs_type
= USB_FS_SYS
;
1550 DPRINTF(USBDBG_DEVOPENED
, USBSYSBUS_PATH
);
1553 f
= fopen(USBPROCBUS_PATH
"/devices", "r");
1555 /* devices found in /proc/bus/usb/ */
1556 strcpy(devpath
, USBPROCBUS_PATH
);
1557 usb_fs_type
= USB_FS_PROC
;
1559 DPRINTF(USBDBG_DEVOPENED
, USBPROCBUS_PATH
);
1562 /* try additional methods if an access method hasn't been found yet */
1563 f
= fopen(USBDEVBUS_PATH
"/devices", "r");
1565 /* devices found in /dev/bus/usb/ */
1566 strcpy(devpath
, USBDEVBUS_PATH
);
1567 usb_fs_type
= USB_FS_DEV
;
1569 DPRINTF(USBDBG_DEVOPENED
, USBDEVBUS_PATH
);
1575 monitor_printf(mon
, "husb: unable to access USB devices\n");
1580 /* the module setting (used later for opening devices) */
1581 usb_host_device_path
= qemu_mallocz(strlen(devpath
)+1);
1582 strcpy(usb_host_device_path
, devpath
);
1584 monitor_printf(mon
, "husb: using %s file-system with %s\n",
1585 fs_type
[usb_fs_type
], usb_host_device_path
);
1589 switch (usb_fs_type
) {
1592 ret
= usb_host_scan_dev(opaque
, func
);
1595 ret
= usb_host_scan_sys(opaque
, func
);
1604 static QEMUTimer
*usb_auto_timer
;
1606 static int usb_host_auto_scan(void *opaque
, int bus_num
, int addr
, char *port
,
1607 int class_id
, int vendor_id
, int product_id
,
1608 const char *product_name
, int speed
)
1610 struct USBAutoFilter
*f
;
1611 struct USBHostDevice
*s
;
1617 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1620 if (f
->bus_num
> 0 && f
->bus_num
!= bus_num
) {
1623 if (f
->addr
> 0 && f
->addr
!= addr
) {
1626 if (f
->port
!= NULL
&& (port
== NULL
|| strcmp(f
->port
, port
) != 0)) {
1630 if (f
->vendor_id
> 0 && f
->vendor_id
!= vendor_id
) {
1634 if (f
->product_id
> 0 && f
->product_id
!= product_id
) {
1637 /* We got a match */
1639 /* Already attached ? */
1643 DPRINTF("husb: auto open: bus_num %d addr %d\n", bus_num
, addr
);
1645 usb_host_open(s
, bus_num
, addr
, port
, product_name
);
1651 static void usb_host_auto_check(void *unused
)
1653 struct USBHostDevice
*s
;
1654 int unconnected
= 0;
1656 usb_host_scan(NULL
, usb_host_auto_scan
);
1658 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1664 if (unconnected
== 0) {
1665 /* nothing to watch */
1666 if (usb_auto_timer
) {
1667 qemu_del_timer(usb_auto_timer
);
1672 if (!usb_auto_timer
) {
1673 usb_auto_timer
= qemu_new_timer_ms(rt_clock
, usb_host_auto_check
, NULL
);
1674 if (!usb_auto_timer
) {
1678 qemu_mod_timer(usb_auto_timer
, qemu_get_clock_ms(rt_clock
) + 2000);
1682 * Autoconnect filter
1684 * auto:bus:dev[:vid:pid]
1685 * auto:bus.dev[:vid:pid]
1687 * bus - bus number (dec, * means any)
1688 * dev - device number (dec, * means any)
1689 * vid - vendor id (hex, * means any)
1690 * pid - product id (hex, * means any)
1692 * See 'lsusb' output.
1694 static int parse_filter(const char *spec
, struct USBAutoFilter
*f
)
1696 enum { BUS
, DEV
, VID
, PID
, DONE
};
1697 const char *p
= spec
;
1705 for (i
= BUS
; i
< DONE
; i
++) {
1706 p
= strpbrk(p
, ":.");
1716 case BUS
: f
->bus_num
= strtol(p
, NULL
, 10); break;
1717 case DEV
: f
->addr
= strtol(p
, NULL
, 10); break;
1718 case VID
: f
->vendor_id
= strtol(p
, NULL
, 16); break;
1719 case PID
: f
->product_id
= strtol(p
, NULL
, 16); break;
1724 fprintf(stderr
, "husb: invalid auto filter spec %s\n", spec
);
1731 /**********************/
1732 /* USB host device info */
1734 struct usb_class_info
{
1736 const char *class_name
;
1739 static const struct usb_class_info usb_class_info
[] = {
1740 { USB_CLASS_AUDIO
, "Audio"},
1741 { USB_CLASS_COMM
, "Communication"},
1742 { USB_CLASS_HID
, "HID"},
1743 { USB_CLASS_HUB
, "Hub" },
1744 { USB_CLASS_PHYSICAL
, "Physical" },
1745 { USB_CLASS_PRINTER
, "Printer" },
1746 { USB_CLASS_MASS_STORAGE
, "Storage" },
1747 { USB_CLASS_CDC_DATA
, "Data" },
1748 { USB_CLASS_APP_SPEC
, "Application Specific" },
1749 { USB_CLASS_VENDOR_SPEC
, "Vendor Specific" },
1750 { USB_CLASS_STILL_IMAGE
, "Still Image" },
1751 { USB_CLASS_CSCID
, "Smart Card" },
1752 { USB_CLASS_CONTENT_SEC
, "Content Security" },
1756 static const char *usb_class_str(uint8_t class)
1758 const struct usb_class_info
*p
;
1759 for(p
= usb_class_info
; p
->class != -1; p
++) {
1760 if (p
->class == class) {
1764 return p
->class_name
;
1767 static void usb_info_device(Monitor
*mon
, int bus_num
, int addr
, char *port
,
1768 int class_id
, int vendor_id
, int product_id
,
1769 const char *product_name
,
1772 const char *class_str
, *speed_str
;
1778 case USB_SPEED_FULL
:
1781 case USB_SPEED_HIGH
:
1789 monitor_printf(mon
, " Bus %d, Addr %d, Port %s, Speed %s Mb/s\n",
1790 bus_num
, addr
, port
, speed_str
);
1791 class_str
= usb_class_str(class_id
);
1793 monitor_printf(mon
, " %s:", class_str
);
1795 monitor_printf(mon
, " Class %02x:", class_id
);
1797 monitor_printf(mon
, " USB device %04x:%04x", vendor_id
, product_id
);
1798 if (product_name
[0] != '\0') {
1799 monitor_printf(mon
, ", %s", product_name
);
1801 monitor_printf(mon
, "\n");
1804 static int usb_host_info_device(void *opaque
, int bus_num
, int addr
,
1805 char *path
, int class_id
,
1806 int vendor_id
, int product_id
,
1807 const char *product_name
,
1810 Monitor
*mon
= opaque
;
1812 usb_info_device(mon
, bus_num
, addr
, path
, class_id
, vendor_id
, product_id
,
1813 product_name
, speed
);
1817 static void dec2str(int val
, char *str
, size_t size
)
1820 snprintf(str
, size
, "*");
1822 snprintf(str
, size
, "%d", val
);
1826 static void hex2str(int val
, char *str
, size_t size
)
1829 snprintf(str
, size
, "*");
1831 snprintf(str
, size
, "%04x", val
);
1835 void usb_host_info(Monitor
*mon
)
1837 struct USBAutoFilter
*f
;
1838 struct USBHostDevice
*s
;
1840 usb_host_scan(mon
, usb_host_info_device
);
1842 if (QTAILQ_EMPTY(&hostdevs
)) {
1846 monitor_printf(mon
, " Auto filters:\n");
1847 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1848 char bus
[10], addr
[10], vid
[10], pid
[10];
1850 dec2str(f
->bus_num
, bus
, sizeof(bus
));
1851 dec2str(f
->addr
, addr
, sizeof(addr
));
1852 hex2str(f
->vendor_id
, vid
, sizeof(vid
));
1853 hex2str(f
->product_id
, pid
, sizeof(pid
));
1854 monitor_printf(mon
, " Bus %s, Addr %s, Port %s, ID %s:%s\n",
1855 bus
, addr
, f
->port
? f
->port
: "*", vid
, pid
);