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 INVALID_EP_TYPE 255
90 /* devio.c limits single requests to 16k */
91 #define MAX_USBFS_BUFFER_SIZE 16384
93 typedef struct AsyncURB AsyncURB
;
105 struct USBAutoFilter
{
113 typedef struct USBHostDevice
{
122 uint32_t iso_urb_count
;
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 struct endp_data
*get_endp(USBHostDevice
*s
, int ep
)
147 return s
->endp_table
+ ep
- 1;
150 static int is_isoc(USBHostDevice
*s
, int ep
)
152 return get_endp(s
, ep
)->type
== USBDEVFS_URB_TYPE_ISO
;
155 static int is_valid(USBHostDevice
*s
, int ep
)
157 return get_endp(s
, ep
)->type
!= INVALID_EP_TYPE
;
160 static int is_halted(USBHostDevice
*s
, int ep
)
162 return get_endp(s
, ep
)->halted
;
165 static void clear_halt(USBHostDevice
*s
, int ep
)
167 get_endp(s
, ep
)->halted
= 0;
170 static void set_halt(USBHostDevice
*s
, int ep
)
172 get_endp(s
, ep
)->halted
= 1;
175 static int is_iso_started(USBHostDevice
*s
, int ep
)
177 return get_endp(s
, ep
)->iso_started
;
180 static void clear_iso_started(USBHostDevice
*s
, int ep
)
182 get_endp(s
, ep
)->iso_started
= 0;
185 static void set_iso_started(USBHostDevice
*s
, int ep
)
187 get_endp(s
, ep
)->iso_started
= 1;
190 static void set_iso_urb(USBHostDevice
*s
, int ep
, AsyncURB
*iso_urb
)
192 get_endp(s
, ep
)->iso_urb
= iso_urb
;
195 static AsyncURB
*get_iso_urb(USBHostDevice
*s
, int ep
)
197 return get_endp(s
, ep
)->iso_urb
;
200 static void set_iso_urb_idx(USBHostDevice
*s
, int ep
, int i
)
202 get_endp(s
, ep
)->iso_urb_idx
= i
;
205 static int get_iso_urb_idx(USBHostDevice
*s
, int ep
)
207 return get_endp(s
, ep
)->iso_urb_idx
;
210 static void set_iso_buffer_used(USBHostDevice
*s
, int ep
, int i
)
212 get_endp(s
, ep
)->iso_buffer_used
= i
;
215 static int get_iso_buffer_used(USBHostDevice
*s
, int ep
)
217 return get_endp(s
, ep
)->iso_buffer_used
;
220 static void set_max_packet_size(USBHostDevice
*s
, int ep
, uint8_t *descriptor
)
222 int raw
= descriptor
[4] + (descriptor
[5] << 8);
223 int size
, microframes
;
226 switch ((raw
>> 11) & 3) {
227 case 1: microframes
= 2; break;
228 case 2: microframes
= 3; break;
229 default: microframes
= 1; break;
231 get_endp(s
, ep
)->max_packet_size
= size
* microframes
;
234 static int get_max_packet_size(USBHostDevice
*s
, int ep
)
236 return get_endp(s
, ep
)->max_packet_size
;
241 * We always allocate iso packet descriptors even for bulk transfers
242 * to simplify allocation and casts.
246 struct usbdevfs_urb urb
;
247 struct usbdevfs_iso_packet_desc isocpd
[ISO_FRAME_DESC_PER_URB
];
249 QLIST_ENTRY(AsyncURB
) next
;
251 /* For regular async urbs */
253 int more
; /* large transfer, more urbs follow */
255 /* For buffered iso handling */
256 int iso_frame_idx
; /* -1 means in flight */
259 static AsyncURB
*async_alloc(USBHostDevice
*s
)
261 AsyncURB
*aurb
= qemu_mallocz(sizeof(AsyncURB
));
263 QLIST_INSERT_HEAD(&s
->aurbs
, aurb
, next
);
267 static void async_free(AsyncURB
*aurb
)
269 QLIST_REMOVE(aurb
, next
);
273 static void do_disconnect(USBHostDevice
*s
)
275 printf("husb: device %d.%d disconnected\n",
276 s
->bus_num
, s
->addr
);
278 usb_host_auto_check(NULL
);
281 static void async_complete(void *opaque
)
283 USBHostDevice
*s
= opaque
;
289 int r
= ioctl(s
->fd
, USBDEVFS_REAPURBNDELAY
, &aurb
);
291 if (errno
== EAGAIN
) {
294 if (errno
== ENODEV
&& !s
->closing
) {
299 DPRINTF("husb: async. reap urb failed errno %d\n", errno
);
303 DPRINTF("husb: async completed. aurb %p status %d alen %d\n",
304 aurb
, aurb
->urb
.status
, aurb
->urb
.actual_length
);
306 /* If this is a buffered iso urb mark it as complete and don't do
307 anything else (it is handled further in usb_host_handle_iso_data) */
308 if (aurb
->iso_frame_idx
== -1) {
309 if (aurb
->urb
.status
== -EPIPE
) {
310 set_halt(s
, aurb
->urb
.endpoint
& 0xf);
312 aurb
->iso_frame_idx
= 0;
319 switch (aurb
->urb
.status
) {
321 p
->len
+= aurb
->urb
.actual_length
;
325 set_halt(s
, p
->devep
);
326 p
->len
= USB_RET_STALL
;
330 p
->len
= USB_RET_NAK
;
334 if (aurb
->urb
.type
== USBDEVFS_URB_TYPE_CONTROL
) {
335 usb_generic_async_ctrl_complete(&s
->dev
, p
);
336 } else if (!aurb
->more
) {
337 usb_packet_complete(&s
->dev
, p
);
345 static void usb_host_async_cancel(USBDevice
*dev
, USBPacket
*p
)
347 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
350 QLIST_FOREACH(aurb
, &s
->aurbs
, next
) {
351 if (p
!= aurb
->packet
) {
355 DPRINTF("husb: async cancel: packet %p, aurb %p\n", p
, aurb
);
357 /* Mark it as dead (see async_complete above) */
360 int r
= ioctl(s
->fd
, USBDEVFS_DISCARDURB
, aurb
);
362 DPRINTF("husb: async. discard urb failed errno %d\n", errno
);
367 static int usb_host_claim_interfaces(USBHostDevice
*dev
, int configuration
)
369 const char *op
= NULL
;
370 int dev_descr_len
, config_descr_len
;
371 int interface
, nb_interfaces
;
374 if (configuration
== 0) /* address state - ignore */
377 DPRINTF("husb: claiming interfaces. config %d\n", configuration
);
380 dev_descr_len
= dev
->descr
[0];
381 if (dev_descr_len
> dev
->descr_len
) {
382 fprintf(stderr
, "husb: update iface failed. descr too short\n");
387 while (i
< dev
->descr_len
) {
388 DPRINTF("husb: i is %d, descr_len is %d, dl %d, dt %d\n",
390 dev
->descr
[i
], dev
->descr
[i
+1]);
392 if (dev
->descr
[i
+1] != USB_DT_CONFIG
) {
396 config_descr_len
= dev
->descr
[i
];
398 printf("husb: config #%d need %d\n", dev
->descr
[i
+ 5], configuration
);
400 if (configuration
< 0 || configuration
== dev
->descr
[i
+ 5]) {
401 configuration
= dev
->descr
[i
+ 5];
405 i
+= config_descr_len
;
408 if (i
>= dev
->descr_len
) {
410 "husb: update iface failed. no matching configuration\n");
413 nb_interfaces
= dev
->descr
[i
+ 4];
415 #ifdef USBDEVFS_DISCONNECT
416 /* earlier Linux 2.4 do not support that */
418 struct usbdevfs_ioctl ctrl
;
419 for (interface
= 0; interface
< nb_interfaces
; interface
++) {
420 ctrl
.ioctl_code
= USBDEVFS_DISCONNECT
;
421 ctrl
.ifno
= interface
;
423 op
= "USBDEVFS_DISCONNECT";
424 ret
= ioctl(dev
->fd
, USBDEVFS_IOCTL
, &ctrl
);
425 if (ret
< 0 && errno
!= ENODATA
) {
432 /* XXX: only grab if all interfaces are free */
433 for (interface
= 0; interface
< nb_interfaces
; interface
++) {
434 op
= "USBDEVFS_CLAIMINTERFACE";
435 ret
= ioctl(dev
->fd
, USBDEVFS_CLAIMINTERFACE
, &interface
);
437 if (errno
== EBUSY
) {
438 printf("husb: update iface. device already grabbed\n");
440 perror("husb: failed to claim interface");
446 printf("husb: %d interfaces claimed for configuration %d\n",
447 nb_interfaces
, configuration
);
449 dev
->ninterfaces
= nb_interfaces
;
450 dev
->configuration
= configuration
;
454 if (errno
== ENODEV
) {
461 static int usb_host_release_interfaces(USBHostDevice
*s
)
465 DPRINTF("husb: releasing interfaces\n");
467 for (i
= 0; i
< s
->ninterfaces
; i
++) {
468 ret
= ioctl(s
->fd
, USBDEVFS_RELEASEINTERFACE
, &i
);
470 perror("husb: failed to release interface");
478 static void usb_host_handle_reset(USBDevice
*dev
)
480 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
482 DPRINTF("husb: reset device %u.%u\n", s
->bus_num
, s
->addr
);
484 ioctl(s
->fd
, USBDEVFS_RESET
);
486 usb_host_claim_interfaces(s
, s
->configuration
);
489 static void usb_host_handle_destroy(USBDevice
*dev
)
491 USBHostDevice
*s
= (USBHostDevice
*)dev
;
494 QTAILQ_REMOVE(&hostdevs
, s
, next
);
495 qemu_remove_exit_notifier(&s
->exit
);
498 static int usb_linux_update_endp_table(USBHostDevice
*s
);
500 /* iso data is special, we need to keep enough urbs in flight to make sure
501 that the controller never runs out of them, otherwise the device will
502 likely suffer a buffer underrun / overrun. */
503 static AsyncURB
*usb_host_alloc_iso(USBHostDevice
*s
, uint8_t ep
, int in
)
506 int i
, j
, len
= get_max_packet_size(s
, ep
);
508 aurb
= qemu_mallocz(s
->iso_urb_count
* sizeof(*aurb
));
509 for (i
= 0; i
< s
->iso_urb_count
; i
++) {
510 aurb
[i
].urb
.endpoint
= ep
;
511 aurb
[i
].urb
.buffer_length
= ISO_FRAME_DESC_PER_URB
* len
;
512 aurb
[i
].urb
.buffer
= qemu_malloc(aurb
[i
].urb
.buffer_length
);
513 aurb
[i
].urb
.type
= USBDEVFS_URB_TYPE_ISO
;
514 aurb
[i
].urb
.flags
= USBDEVFS_URB_ISO_ASAP
;
515 aurb
[i
].urb
.number_of_packets
= ISO_FRAME_DESC_PER_URB
;
516 for (j
= 0 ; j
< ISO_FRAME_DESC_PER_URB
; j
++)
517 aurb
[i
].urb
.iso_frame_desc
[j
].length
= len
;
519 aurb
[i
].urb
.endpoint
|= 0x80;
520 /* Mark as fully consumed (idle) */
521 aurb
[i
].iso_frame_idx
= ISO_FRAME_DESC_PER_URB
;
524 set_iso_urb(s
, ep
, aurb
);
529 static void usb_host_stop_n_free_iso(USBHostDevice
*s
, uint8_t ep
)
532 int i
, ret
, killed
= 0, free
= 1;
534 aurb
= get_iso_urb(s
, ep
);
539 for (i
= 0; i
< s
->iso_urb_count
; i
++) {
541 if (aurb
[i
].iso_frame_idx
== -1) {
542 ret
= ioctl(s
->fd
, USBDEVFS_DISCARDURB
, &aurb
[i
]);
544 printf("husb: discard isoc in urb failed errno %d\n", errno
);
552 /* Make sure any urbs we've killed are reaped before we free them */
557 for (i
= 0; i
< s
->iso_urb_count
; i
++) {
558 qemu_free(aurb
[i
].urb
.buffer
);
564 printf("husb: leaking iso urbs because of discard failure\n");
565 set_iso_urb(s
, ep
, NULL
);
566 set_iso_urb_idx(s
, ep
, 0);
567 clear_iso_started(s
, ep
);
570 static int urb_status_to_usb_ret(int status
)
574 return USB_RET_STALL
;
580 static int usb_host_handle_iso_data(USBHostDevice
*s
, USBPacket
*p
, int in
)
583 int i
, j
, ret
, max_packet_size
, offset
, len
= 0;
585 max_packet_size
= get_max_packet_size(s
, p
->devep
);
586 if (max_packet_size
== 0)
589 aurb
= get_iso_urb(s
, p
->devep
);
591 aurb
= usb_host_alloc_iso(s
, p
->devep
, in
);
594 i
= get_iso_urb_idx(s
, p
->devep
);
595 j
= aurb
[i
].iso_frame_idx
;
596 if (j
>= 0 && j
< ISO_FRAME_DESC_PER_URB
) {
598 /* Check urb status */
599 if (aurb
[i
].urb
.status
) {
600 len
= urb_status_to_usb_ret(aurb
[i
].urb
.status
);
601 /* Move to the next urb */
602 aurb
[i
].iso_frame_idx
= ISO_FRAME_DESC_PER_URB
- 1;
603 /* Check frame status */
604 } else if (aurb
[i
].urb
.iso_frame_desc
[j
].status
) {
605 len
= urb_status_to_usb_ret(
606 aurb
[i
].urb
.iso_frame_desc
[j
].status
);
607 /* Check the frame fits */
608 } else if (aurb
[i
].urb
.iso_frame_desc
[j
].actual_length
> p
->len
) {
609 printf("husb: received iso data is larger then packet\n");
611 /* All good copy data over */
613 len
= aurb
[i
].urb
.iso_frame_desc
[j
].actual_length
;
616 j
* aurb
[i
].urb
.iso_frame_desc
[0].length
,
621 offset
= (j
== 0) ? 0 : get_iso_buffer_used(s
, p
->devep
);
623 /* Check the frame fits */
624 if (len
> max_packet_size
) {
625 printf("husb: send iso data is larger then max packet size\n");
629 /* All good copy data over */
630 memcpy(aurb
[i
].urb
.buffer
+ offset
, p
->data
, len
);
631 aurb
[i
].urb
.iso_frame_desc
[j
].length
= len
;
633 set_iso_buffer_used(s
, p
->devep
, offset
);
635 /* Start the stream once we have buffered enough data */
636 if (!is_iso_started(s
, p
->devep
) && i
== 1 && j
== 8) {
637 set_iso_started(s
, p
->devep
);
640 aurb
[i
].iso_frame_idx
++;
641 if (aurb
[i
].iso_frame_idx
== ISO_FRAME_DESC_PER_URB
) {
642 i
= (i
+ 1) % s
->iso_urb_count
;
643 set_iso_urb_idx(s
, p
->devep
, i
);
647 set_iso_started(s
, p
->devep
);
649 DPRINTF("hubs: iso out error no free buffer, dropping packet\n");
653 if (is_iso_started(s
, p
->devep
)) {
654 /* (Re)-submit all fully consumed / filled urbs */
655 for (i
= 0; i
< s
->iso_urb_count
; i
++) {
656 if (aurb
[i
].iso_frame_idx
== ISO_FRAME_DESC_PER_URB
) {
657 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, &aurb
[i
]);
659 printf("husb error submitting iso urb %d: %d\n", i
, errno
);
660 if (!in
|| len
== 0) {
672 aurb
[i
].iso_frame_idx
= -1;
680 static int usb_host_handle_data(USBDevice
*dev
, USBPacket
*p
)
682 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
683 struct usbdevfs_urb
*urb
;
689 if (!is_valid(s
, p
->devep
)) {
693 if (p
->pid
== USB_TOKEN_IN
) {
694 ep
= p
->devep
| 0x80;
699 if (is_halted(s
, p
->devep
)) {
700 ret
= ioctl(s
->fd
, USBDEVFS_CLEAR_HALT
, &ep
);
702 DPRINTF("husb: failed to clear halt. ep 0x%x errno %d\n",
706 clear_halt(s
, p
->devep
);
709 if (is_isoc(s
, p
->devep
)) {
710 return usb_host_handle_iso_data(s
, p
, p
->pid
== USB_TOKEN_IN
);
717 aurb
= async_alloc(s
);
722 urb
->type
= USBDEVFS_URB_TYPE_BULK
;
723 urb
->usercontext
= s
;
726 if (rem
> MAX_USBFS_BUFFER_SIZE
) {
727 urb
->buffer_length
= MAX_USBFS_BUFFER_SIZE
;
730 urb
->buffer_length
= rem
;
733 pbuf
+= urb
->buffer_length
;
734 rem
-= urb
->buffer_length
;
736 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
738 DPRINTF("husb: data submit: ep 0x%x, len %u, more %d, packet %p, aurb %p\n",
739 urb
->endpoint
, urb
->buffer_length
, aurb
->more
, p
, aurb
);
742 DPRINTF("husb: submit failed. errno %d\n", errno
);
750 return USB_RET_STALL
;
755 return USB_RET_ASYNC
;
758 static int ctrl_error(void)
760 if (errno
== ETIMEDOUT
) {
763 return USB_RET_STALL
;
767 static int usb_host_set_address(USBHostDevice
*s
, int addr
)
769 DPRINTF("husb: ctrl set addr %u\n", addr
);
774 static int usb_host_set_config(USBHostDevice
*s
, int config
)
776 usb_host_release_interfaces(s
);
778 int ret
= ioctl(s
->fd
, USBDEVFS_SETCONFIGURATION
, &config
);
780 DPRINTF("husb: ctrl set config %d ret %d errno %d\n", config
, ret
, errno
);
785 usb_host_claim_interfaces(s
, config
);
789 static int usb_host_set_interface(USBHostDevice
*s
, int iface
, int alt
)
791 struct usbdevfs_setinterface si
;
794 for (i
= 1; i
<= MAX_ENDPOINTS
; i
++) {
796 usb_host_stop_n_free_iso(s
, i
);
800 si
.interface
= iface
;
802 ret
= ioctl(s
->fd
, USBDEVFS_SETINTERFACE
, &si
);
804 DPRINTF("husb: ctrl set iface %d altset %d ret %d errno %d\n",
805 iface
, alt
, ret
, errno
);
810 usb_linux_update_endp_table(s
);
814 static int usb_host_handle_control(USBDevice
*dev
, USBPacket
*p
,
815 int request
, int value
, int index
, int length
, uint8_t *data
)
817 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
818 struct usbdevfs_urb
*urb
;
823 * Process certain standard device requests.
824 * These are infrequent and are processed synchronously.
827 /* Note request is (bRequestType << 8) | bRequest */
828 DPRINTF("husb: ctrl type 0x%x req 0x%x val 0x%x index %u len %u\n",
829 request
>> 8, request
& 0xff, value
, index
, length
);
832 case DeviceOutRequest
| USB_REQ_SET_ADDRESS
:
833 return usb_host_set_address(s
, value
);
835 case DeviceOutRequest
| USB_REQ_SET_CONFIGURATION
:
836 return usb_host_set_config(s
, value
& 0xff);
838 case InterfaceOutRequest
| USB_REQ_SET_INTERFACE
:
839 return usb_host_set_interface(s
, index
, value
);
842 /* The rest are asynchronous */
844 if (length
> sizeof(dev
->data_buf
)) {
845 fprintf(stderr
, "husb: ctrl buffer too small (%d > %zu)\n",
846 length
, sizeof(dev
->data_buf
));
847 return USB_RET_STALL
;
850 aurb
= async_alloc(s
);
854 * Setup ctrl transfer.
856 * s->ctrl is laid out such that data buffer immediately follows
857 * 'req' struct which is exactly what usbdevfs expects.
861 urb
->type
= USBDEVFS_URB_TYPE_CONTROL
;
862 urb
->endpoint
= p
->devep
;
864 urb
->buffer
= &dev
->setup_buf
;
865 urb
->buffer_length
= length
+ 8;
867 urb
->usercontext
= s
;
869 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
871 DPRINTF("husb: submit ctrl. len %u aurb %p\n", urb
->buffer_length
, aurb
);
874 DPRINTF("husb: submit failed. errno %d\n", errno
);
882 return USB_RET_STALL
;
886 return USB_RET_ASYNC
;
889 static int usb_linux_get_configuration(USBHostDevice
*s
)
891 uint8_t configuration
;
892 struct usb_ctrltransfer ct
;
895 if (usb_fs_type
== USB_FS_SYS
) {
896 char device_name
[32], line
[1024];
899 sprintf(device_name
, "%d-%s", s
->bus_num
, s
->port
);
901 if (!usb_host_read_file(line
, sizeof(line
), "bConfigurationValue",
905 if (sscanf(line
, "%d", &configuration
) != 1) {
908 return configuration
;
912 ct
.bRequestType
= USB_DIR_IN
;
913 ct
.bRequest
= USB_REQ_GET_CONFIGURATION
;
917 ct
.data
= &configuration
;
920 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
922 perror("usb_linux_get_configuration");
926 /* in address state */
927 if (configuration
== 0) {
931 return configuration
;
934 static uint8_t usb_linux_get_alt_setting(USBHostDevice
*s
,
935 uint8_t configuration
, uint8_t interface
)
938 struct usb_ctrltransfer ct
;
941 if (usb_fs_type
== USB_FS_SYS
) {
942 char device_name
[64], line
[1024];
945 sprintf(device_name
, "%d-%s:%d.%d", s
->bus_num
, s
->port
,
946 (int)configuration
, (int)interface
);
948 if (!usb_host_read_file(line
, sizeof(line
), "bAlternateSetting",
952 if (sscanf(line
, "%d", &alt_setting
) != 1) {
959 ct
.bRequestType
= USB_DIR_IN
| USB_RECIP_INTERFACE
;
960 ct
.bRequest
= USB_REQ_GET_INTERFACE
;
962 ct
.wIndex
= interface
;
964 ct
.data
= &alt_setting
;
966 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
968 /* Assume alt 0 on error */
975 /* returns 1 on problem encountered or 0 for success */
976 static int usb_linux_update_endp_table(USBHostDevice
*s
)
978 uint8_t *descriptors
;
979 uint8_t devep
, type
, configuration
, alt_interface
;
980 int interface
, length
, i
;
982 for (i
= 0; i
< MAX_ENDPOINTS
; i
++)
983 s
->endp_table
[i
].type
= INVALID_EP_TYPE
;
985 i
= usb_linux_get_configuration(s
);
990 /* get the desired configuration, interface, and endpoint descriptors
991 * from device description */
992 descriptors
= &s
->descr
[18];
993 length
= s
->descr_len
- 18;
996 if (descriptors
[i
+ 1] != USB_DT_CONFIG
||
997 descriptors
[i
+ 5] != configuration
) {
998 DPRINTF("invalid descriptor data - configuration\n");
1001 i
+= descriptors
[i
];
1003 while (i
< length
) {
1004 if (descriptors
[i
+ 1] != USB_DT_INTERFACE
||
1005 (descriptors
[i
+ 1] == USB_DT_INTERFACE
&&
1006 descriptors
[i
+ 4] == 0)) {
1007 i
+= descriptors
[i
];
1011 interface
= descriptors
[i
+ 2];
1012 alt_interface
= usb_linux_get_alt_setting(s
, configuration
, interface
);
1014 /* the current interface descriptor is the active interface
1015 * and has endpoints */
1016 if (descriptors
[i
+ 3] != alt_interface
) {
1017 i
+= descriptors
[i
];
1021 /* advance to the endpoints */
1022 while (i
< length
&& descriptors
[i
+1] != USB_DT_ENDPOINT
) {
1023 i
+= descriptors
[i
];
1029 while (i
< length
) {
1030 if (descriptors
[i
+ 1] != USB_DT_ENDPOINT
) {
1034 devep
= descriptors
[i
+ 2];
1035 if ((devep
& 0x0f) == 0) {
1036 fprintf(stderr
, "usb-linux: invalid ep descriptor, ep == 0\n");
1040 switch (descriptors
[i
+ 3] & 0x3) {
1042 type
= USBDEVFS_URB_TYPE_CONTROL
;
1045 type
= USBDEVFS_URB_TYPE_ISO
;
1046 set_max_packet_size(s
, (devep
& 0xf), descriptors
+ i
);
1049 type
= USBDEVFS_URB_TYPE_BULK
;
1052 type
= USBDEVFS_URB_TYPE_INTERRUPT
;
1055 DPRINTF("usb_host: malformed endpoint type\n");
1056 type
= USBDEVFS_URB_TYPE_BULK
;
1058 s
->endp_table
[(devep
& 0xf) - 1].type
= type
;
1059 s
->endp_table
[(devep
& 0xf) - 1].halted
= 0;
1061 i
+= descriptors
[i
];
1067 static int usb_host_open(USBHostDevice
*dev
, int bus_num
,
1068 int addr
, char *port
, const char *prod_name
, int speed
)
1073 if (dev
->fd
!= -1) {
1076 printf("husb: open device %d.%d\n", bus_num
, addr
);
1078 if (!usb_host_device_path
) {
1079 perror("husb: USB Host Device Path not set");
1082 snprintf(buf
, sizeof(buf
), "%s/%03d/%03d", usb_host_device_path
,
1084 fd
= open(buf
, O_RDWR
| O_NONBLOCK
);
1089 DPRINTF("husb: opened %s\n", buf
);
1091 dev
->bus_num
= bus_num
;
1093 strcpy(dev
->port
, port
);
1096 /* read the device description */
1097 dev
->descr_len
= read(fd
, dev
->descr
, sizeof(dev
->descr
));
1098 if (dev
->descr_len
<= 0) {
1099 perror("husb: reading device data failed");
1106 printf("=== begin dumping device descriptor data ===\n");
1107 for (x
= 0; x
< dev
->descr_len
; x
++) {
1108 printf("%02x ", dev
->descr
[x
]);
1110 printf("\n=== end dumping device descriptor data ===\n");
1116 * Initial configuration is -1 which makes us claim first
1117 * available config. We used to start with 1, which does not
1118 * always work. I've seen devices where first config starts
1121 if (!usb_host_claim_interfaces(dev
, -1)) {
1125 ret
= usb_linux_update_endp_table(dev
);
1131 struct usbdevfs_connectinfo ci
;
1133 ret
= ioctl(fd
, USBDEVFS_CONNECTINFO
, &ci
);
1135 perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
1140 speed
= USB_SPEED_LOW
;
1142 speed
= USB_SPEED_HIGH
;
1145 dev
->dev
.speed
= speed
;
1147 printf("husb: grabbed usb device %d.%d\n", bus_num
, addr
);
1149 if (!prod_name
|| prod_name
[0] == '\0') {
1150 snprintf(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1151 "host:%d.%d", bus_num
, addr
);
1153 pstrcpy(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1157 /* USB devio uses 'write' flag to check for async completions */
1158 qemu_set_fd_handler(dev
->fd
, NULL
, async_complete
, dev
);
1160 usb_device_attach(&dev
->dev
);
1164 if (dev
->fd
!= -1) {
1171 static int usb_host_close(USBHostDevice
*dev
)
1175 if (dev
->fd
== -1 || !dev
->dev
.attached
) {
1179 qemu_set_fd_handler(dev
->fd
, NULL
, NULL
, NULL
);
1181 for (i
= 1; i
<= MAX_ENDPOINTS
; i
++) {
1182 if (is_isoc(dev
, i
)) {
1183 usb_host_stop_n_free_iso(dev
, i
);
1186 async_complete(dev
);
1188 usb_device_detach(&dev
->dev
);
1189 ioctl(dev
->fd
, USBDEVFS_RESET
);
1195 static void usb_host_exit_notifier(struct Notifier
* n
)
1197 USBHostDevice
*s
= container_of(n
, USBHostDevice
, exit
);
1200 ioctl(s
->fd
, USBDEVFS_RESET
);
1204 static int usb_host_initfn(USBDevice
*dev
)
1206 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
1208 dev
->auto_attach
= 0;
1210 QTAILQ_INSERT_TAIL(&hostdevs
, s
, next
);
1211 s
->exit
.notify
= usb_host_exit_notifier
;
1212 qemu_add_exit_notifier(&s
->exit
);
1213 usb_host_auto_check(NULL
);
1217 static struct USBDeviceInfo usb_host_dev_info
= {
1218 .product_desc
= "USB Host Device",
1219 .qdev
.name
= "usb-host",
1220 .qdev
.size
= sizeof(USBHostDevice
),
1221 .init
= usb_host_initfn
,
1222 .handle_packet
= usb_generic_handle_packet
,
1223 .cancel_packet
= usb_host_async_cancel
,
1224 .handle_data
= usb_host_handle_data
,
1225 .handle_control
= usb_host_handle_control
,
1226 .handle_reset
= usb_host_handle_reset
,
1227 .handle_destroy
= usb_host_handle_destroy
,
1228 .usbdevice_name
= "host",
1229 .usbdevice_init
= usb_host_device_open
,
1230 .qdev
.props
= (Property
[]) {
1231 DEFINE_PROP_UINT32("hostbus", USBHostDevice
, match
.bus_num
, 0),
1232 DEFINE_PROP_UINT32("hostaddr", USBHostDevice
, match
.addr
, 0),
1233 DEFINE_PROP_STRING("hostport", USBHostDevice
, match
.port
),
1234 DEFINE_PROP_HEX32("vendorid", USBHostDevice
, match
.vendor_id
, 0),
1235 DEFINE_PROP_HEX32("productid", USBHostDevice
, match
.product_id
, 0),
1236 DEFINE_PROP_UINT32("isobufs", USBHostDevice
, iso_urb_count
, 4),
1237 DEFINE_PROP_END_OF_LIST(),
1241 static void usb_host_register_devices(void)
1243 usb_qdev_register(&usb_host_dev_info
);
1245 device_init(usb_host_register_devices
)
1247 USBDevice
*usb_host_device_open(const char *devname
)
1249 struct USBAutoFilter filter
;
1253 dev
= usb_create(NULL
/* FIXME */, "usb-host");
1255 if (strstr(devname
, "auto:")) {
1256 if (parse_filter(devname
, &filter
) < 0) {
1260 if ((p
= strchr(devname
, '.'))) {
1261 filter
.bus_num
= strtoul(devname
, NULL
, 0);
1262 filter
.addr
= strtoul(p
+ 1, NULL
, 0);
1263 filter
.vendor_id
= 0;
1264 filter
.product_id
= 0;
1265 } else if ((p
= strchr(devname
, ':'))) {
1268 filter
.vendor_id
= strtoul(devname
, NULL
, 16);
1269 filter
.product_id
= strtoul(p
+ 1, NULL
, 16);
1275 qdev_prop_set_uint32(&dev
->qdev
, "hostbus", filter
.bus_num
);
1276 qdev_prop_set_uint32(&dev
->qdev
, "hostaddr", filter
.addr
);
1277 qdev_prop_set_uint32(&dev
->qdev
, "vendorid", filter
.vendor_id
);
1278 qdev_prop_set_uint32(&dev
->qdev
, "productid", filter
.product_id
);
1279 qdev_init_nofail(&dev
->qdev
);
1283 qdev_free(&dev
->qdev
);
1287 int usb_host_device_close(const char *devname
)
1290 char product_name
[PRODUCT_NAME_SZ
];
1294 if (strstr(devname
, "auto:")) {
1295 return usb_host_auto_del(devname
);
1297 if (usb_host_find_device(&bus_num
, &addr
, product_name
,
1298 sizeof(product_name
), devname
) < 0) {
1301 s
= hostdev_find(bus_num
, addr
);
1303 usb_device_delete_addr(s
->bus_num
, s
->dev
.addr
);
1311 static int get_tag_value(char *buf
, int buf_size
,
1312 const char *str
, const char *tag
,
1313 const char *stopchars
)
1317 p
= strstr(str
, tag
);
1322 while (qemu_isspace(*p
)) {
1326 while (*p
!= '\0' && !strchr(stopchars
, *p
)) {
1327 if ((q
- buf
) < (buf_size
- 1)) {
1337 * Use /proc/bus/usb/devices or /dev/bus/usb/devices file to determine
1338 * host's USB devices. This is legacy support since many distributions
1339 * are moving to /sys/bus/usb
1341 static int usb_host_scan_dev(void *opaque
, USBScanFunc
*func
)
1346 int bus_num
, addr
, speed
, device_count
, class_id
, product_id
, vendor_id
;
1347 char product_name
[512];
1350 if (!usb_host_device_path
) {
1351 perror("husb: USB Host Device Path not set");
1354 snprintf(line
, sizeof(line
), "%s/devices", usb_host_device_path
);
1355 f
= fopen(line
, "r");
1357 perror("husb: cannot open devices file");
1362 bus_num
= addr
= class_id
= product_id
= vendor_id
= 0;
1363 speed
= -1; /* Can't get the speed from /[proc|dev]/bus/usb/devices */
1365 if (fgets(line
, sizeof(line
), f
) == NULL
) {
1368 if (strlen(line
) > 0) {
1369 line
[strlen(line
) - 1] = '\0';
1371 if (line
[0] == 'T' && line
[1] == ':') {
1372 if (device_count
&& (vendor_id
|| product_id
)) {
1373 /* New device. Add the previously discovered device. */
1374 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1375 product_id
, product_name
, speed
);
1380 if (get_tag_value(buf
, sizeof(buf
), line
, "Bus=", " ") < 0) {
1383 bus_num
= atoi(buf
);
1384 if (get_tag_value(buf
, sizeof(buf
), line
, "Dev#=", " ") < 0) {
1388 if (get_tag_value(buf
, sizeof(buf
), line
, "Spd=", " ") < 0) {
1391 if (!strcmp(buf
, "5000")) {
1392 speed
= USB_SPEED_SUPER
;
1393 } else if (!strcmp(buf
, "480")) {
1394 speed
= USB_SPEED_HIGH
;
1395 } else if (!strcmp(buf
, "1.5")) {
1396 speed
= USB_SPEED_LOW
;
1398 speed
= USB_SPEED_FULL
;
1400 product_name
[0] = '\0';
1405 } else if (line
[0] == 'P' && line
[1] == ':') {
1406 if (get_tag_value(buf
, sizeof(buf
), line
, "Vendor=", " ") < 0) {
1409 vendor_id
= strtoul(buf
, NULL
, 16);
1410 if (get_tag_value(buf
, sizeof(buf
), line
, "ProdID=", " ") < 0) {
1413 product_id
= strtoul(buf
, NULL
, 16);
1414 } else if (line
[0] == 'S' && line
[1] == ':') {
1415 if (get_tag_value(buf
, sizeof(buf
), line
, "Product=", "") < 0) {
1418 pstrcpy(product_name
, sizeof(product_name
), buf
);
1419 } else if (line
[0] == 'D' && line
[1] == ':') {
1420 if (get_tag_value(buf
, sizeof(buf
), line
, "Cls=", " (") < 0) {
1423 class_id
= strtoul(buf
, NULL
, 16);
1427 if (device_count
&& (vendor_id
|| product_id
)) {
1428 /* Add the last device. */
1429 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1430 product_id
, product_name
, speed
);
1440 * Read sys file-system device file
1442 * @line address of buffer to put file contents in
1443 * @line_size size of line
1444 * @device_file path to device file (printf format string)
1445 * @device_name device being opened (inserted into device_file)
1447 * @return 0 failed, 1 succeeded ('line' contains data)
1449 static int usb_host_read_file(char *line
, size_t line_size
,
1450 const char *device_file
, const char *device_name
)
1454 char filename
[PATH_MAX
];
1456 snprintf(filename
, PATH_MAX
, USBSYSBUS_PATH
"/devices/%s/%s", device_name
,
1458 f
= fopen(filename
, "r");
1460 ret
= fgets(line
, line_size
, f
) != NULL
;
1468 * Use /sys/bus/usb/devices/ directory to determine host's USB
1471 * This code is based on Robert Schiele's original patches posted to
1472 * the Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
1474 static int usb_host_scan_sys(void *opaque
, USBScanFunc
*func
)
1478 int bus_num
, addr
, speed
, class_id
, product_id
, vendor_id
;
1480 char port
[MAX_PORTLEN
];
1481 char product_name
[512];
1484 dir
= opendir(USBSYSBUS_PATH
"/devices");
1486 perror("husb: cannot open devices directory");
1490 while ((de
= readdir(dir
))) {
1491 if (de
->d_name
[0] != '.' && !strchr(de
->d_name
, ':')) {
1492 if (sscanf(de
->d_name
, "%d-%7[0-9.]", &bus_num
, port
) < 2) {
1496 if (!usb_host_read_file(line
, sizeof(line
), "devnum", de
->d_name
)) {
1499 if (sscanf(line
, "%d", &addr
) != 1) {
1502 if (!usb_host_read_file(line
, sizeof(line
), "bDeviceClass",
1506 if (sscanf(line
, "%x", &class_id
) != 1) {
1510 if (!usb_host_read_file(line
, sizeof(line
), "idVendor",
1514 if (sscanf(line
, "%x", &vendor_id
) != 1) {
1517 if (!usb_host_read_file(line
, sizeof(line
), "idProduct",
1521 if (sscanf(line
, "%x", &product_id
) != 1) {
1524 if (!usb_host_read_file(line
, sizeof(line
), "product",
1528 if (strlen(line
) > 0) {
1529 line
[strlen(line
) - 1] = '\0';
1531 pstrcpy(product_name
, sizeof(product_name
), line
);
1534 if (!usb_host_read_file(line
, sizeof(line
), "speed", de
->d_name
)) {
1537 if (!strcmp(line
, "5000\n")) {
1538 speed
= USB_SPEED_SUPER
;
1539 } else if (!strcmp(line
, "480\n")) {
1540 speed
= USB_SPEED_HIGH
;
1541 } else if (!strcmp(line
, "1.5\n")) {
1542 speed
= USB_SPEED_LOW
;
1544 speed
= USB_SPEED_FULL
;
1547 ret
= func(opaque
, bus_num
, addr
, port
, class_id
, vendor_id
,
1548 product_id
, product_name
, speed
);
1562 * Determine how to access the host's USB devices and call the
1563 * specific support function.
1565 static int usb_host_scan(void *opaque
, USBScanFunc
*func
)
1567 Monitor
*mon
= cur_mon
;
1571 const char *fs_type
[] = {"unknown", "proc", "dev", "sys"};
1572 char devpath
[PATH_MAX
];
1574 /* only check the host once */
1576 dir
= opendir(USBSYSBUS_PATH
"/devices");
1578 /* devices found in /dev/bus/usb/ (yes - not a mistake!) */
1579 strcpy(devpath
, USBDEVBUS_PATH
);
1580 usb_fs_type
= USB_FS_SYS
;
1582 DPRINTF(USBDBG_DEVOPENED
, USBSYSBUS_PATH
);
1585 f
= fopen(USBPROCBUS_PATH
"/devices", "r");
1587 /* devices found in /proc/bus/usb/ */
1588 strcpy(devpath
, USBPROCBUS_PATH
);
1589 usb_fs_type
= USB_FS_PROC
;
1591 DPRINTF(USBDBG_DEVOPENED
, USBPROCBUS_PATH
);
1594 /* try additional methods if an access method hasn't been found yet */
1595 f
= fopen(USBDEVBUS_PATH
"/devices", "r");
1597 /* devices found in /dev/bus/usb/ */
1598 strcpy(devpath
, USBDEVBUS_PATH
);
1599 usb_fs_type
= USB_FS_DEV
;
1601 DPRINTF(USBDBG_DEVOPENED
, USBDEVBUS_PATH
);
1607 monitor_printf(mon
, "husb: unable to access USB devices\n");
1612 /* the module setting (used later for opening devices) */
1613 usb_host_device_path
= qemu_mallocz(strlen(devpath
)+1);
1614 strcpy(usb_host_device_path
, devpath
);
1616 monitor_printf(mon
, "husb: using %s file-system with %s\n",
1617 fs_type
[usb_fs_type
], usb_host_device_path
);
1621 switch (usb_fs_type
) {
1624 ret
= usb_host_scan_dev(opaque
, func
);
1627 ret
= usb_host_scan_sys(opaque
, func
);
1636 static QEMUTimer
*usb_auto_timer
;
1638 static int usb_host_auto_scan(void *opaque
, int bus_num
, int addr
, char *port
,
1639 int class_id
, int vendor_id
, int product_id
,
1640 const char *product_name
, int speed
)
1642 struct USBAutoFilter
*f
;
1643 struct USBHostDevice
*s
;
1649 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1652 if (f
->bus_num
> 0 && f
->bus_num
!= bus_num
) {
1655 if (f
->addr
> 0 && f
->addr
!= addr
) {
1658 if (f
->port
!= NULL
&& (port
== NULL
|| strcmp(f
->port
, port
) != 0)) {
1662 if (f
->vendor_id
> 0 && f
->vendor_id
!= vendor_id
) {
1666 if (f
->product_id
> 0 && f
->product_id
!= product_id
) {
1669 /* We got a match */
1671 /* Already attached ? */
1675 DPRINTF("husb: auto open: bus_num %d addr %d\n", bus_num
, addr
);
1677 usb_host_open(s
, bus_num
, addr
, port
, product_name
, speed
);
1684 static void usb_host_auto_check(void *unused
)
1686 struct USBHostDevice
*s
;
1687 int unconnected
= 0;
1689 usb_host_scan(NULL
, usb_host_auto_scan
);
1691 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1697 if (unconnected
== 0) {
1698 /* nothing to watch */
1699 if (usb_auto_timer
) {
1700 qemu_del_timer(usb_auto_timer
);
1705 if (!usb_auto_timer
) {
1706 usb_auto_timer
= qemu_new_timer_ms(rt_clock
, usb_host_auto_check
, NULL
);
1707 if (!usb_auto_timer
) {
1711 qemu_mod_timer(usb_auto_timer
, qemu_get_clock_ms(rt_clock
) + 2000);
1715 * Autoconnect filter
1717 * auto:bus:dev[:vid:pid]
1718 * auto:bus.dev[:vid:pid]
1720 * bus - bus number (dec, * means any)
1721 * dev - device number (dec, * means any)
1722 * vid - vendor id (hex, * means any)
1723 * pid - product id (hex, * means any)
1725 * See 'lsusb' output.
1727 static int parse_filter(const char *spec
, struct USBAutoFilter
*f
)
1729 enum { BUS
, DEV
, VID
, PID
, DONE
};
1730 const char *p
= spec
;
1738 for (i
= BUS
; i
< DONE
; i
++) {
1739 p
= strpbrk(p
, ":.");
1749 case BUS
: f
->bus_num
= strtol(p
, NULL
, 10); break;
1750 case DEV
: f
->addr
= strtol(p
, NULL
, 10); break;
1751 case VID
: f
->vendor_id
= strtol(p
, NULL
, 16); break;
1752 case PID
: f
->product_id
= strtol(p
, NULL
, 16); break;
1757 fprintf(stderr
, "husb: invalid auto filter spec %s\n", spec
);
1764 /**********************/
1765 /* USB host device info */
1767 struct usb_class_info
{
1769 const char *class_name
;
1772 static const struct usb_class_info usb_class_info
[] = {
1773 { USB_CLASS_AUDIO
, "Audio"},
1774 { USB_CLASS_COMM
, "Communication"},
1775 { USB_CLASS_HID
, "HID"},
1776 { USB_CLASS_HUB
, "Hub" },
1777 { USB_CLASS_PHYSICAL
, "Physical" },
1778 { USB_CLASS_PRINTER
, "Printer" },
1779 { USB_CLASS_MASS_STORAGE
, "Storage" },
1780 { USB_CLASS_CDC_DATA
, "Data" },
1781 { USB_CLASS_APP_SPEC
, "Application Specific" },
1782 { USB_CLASS_VENDOR_SPEC
, "Vendor Specific" },
1783 { USB_CLASS_STILL_IMAGE
, "Still Image" },
1784 { USB_CLASS_CSCID
, "Smart Card" },
1785 { USB_CLASS_CONTENT_SEC
, "Content Security" },
1789 static const char *usb_class_str(uint8_t class)
1791 const struct usb_class_info
*p
;
1792 for(p
= usb_class_info
; p
->class != -1; p
++) {
1793 if (p
->class == class) {
1797 return p
->class_name
;
1800 static void usb_info_device(Monitor
*mon
, int bus_num
, int addr
, char *port
,
1801 int class_id
, int vendor_id
, int product_id
,
1802 const char *product_name
,
1805 const char *class_str
, *speed_str
;
1811 case USB_SPEED_FULL
:
1814 case USB_SPEED_HIGH
:
1817 case USB_SPEED_SUPER
:
1825 monitor_printf(mon
, " Bus %d, Addr %d, Port %s, Speed %s Mb/s\n",
1826 bus_num
, addr
, port
, speed_str
);
1827 class_str
= usb_class_str(class_id
);
1829 monitor_printf(mon
, " %s:", class_str
);
1831 monitor_printf(mon
, " Class %02x:", class_id
);
1833 monitor_printf(mon
, " USB device %04x:%04x", vendor_id
, product_id
);
1834 if (product_name
[0] != '\0') {
1835 monitor_printf(mon
, ", %s", product_name
);
1837 monitor_printf(mon
, "\n");
1840 static int usb_host_info_device(void *opaque
, int bus_num
, int addr
,
1841 char *path
, int class_id
,
1842 int vendor_id
, int product_id
,
1843 const char *product_name
,
1846 Monitor
*mon
= opaque
;
1848 usb_info_device(mon
, bus_num
, addr
, path
, class_id
, vendor_id
, product_id
,
1849 product_name
, speed
);
1853 static void dec2str(int val
, char *str
, size_t size
)
1856 snprintf(str
, size
, "*");
1858 snprintf(str
, size
, "%d", val
);
1862 static void hex2str(int val
, char *str
, size_t size
)
1865 snprintf(str
, size
, "*");
1867 snprintf(str
, size
, "%04x", val
);
1871 void usb_host_info(Monitor
*mon
)
1873 struct USBAutoFilter
*f
;
1874 struct USBHostDevice
*s
;
1876 usb_host_scan(mon
, usb_host_info_device
);
1878 if (QTAILQ_EMPTY(&hostdevs
)) {
1882 monitor_printf(mon
, " Auto filters:\n");
1883 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1884 char bus
[10], addr
[10], vid
[10], pid
[10];
1886 dec2str(f
->bus_num
, bus
, sizeof(bus
));
1887 dec2str(f
->addr
, addr
, sizeof(addr
));
1888 hex2str(f
->vendor_id
, vid
, sizeof(vid
));
1889 hex2str(f
->product_id
, pid
, sizeof(pid
));
1890 monitor_printf(mon
, " Bus %s, Addr %s, Port %s, ID %s:%s\n",
1891 bus
, addr
, f
->port
? f
->port
: "*", vid
, pid
);