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 int get_max_packet_size(USBHostDevice
*s
, int ep
)
218 return s
->endp_table
[ep
- 1].max_packet_size
;
223 * We always allocate iso packet descriptors even for bulk transfers
224 * to simplify allocation and casts.
228 struct usbdevfs_urb urb
;
229 struct usbdevfs_iso_packet_desc isocpd
[ISO_FRAME_DESC_PER_URB
];
231 QLIST_ENTRY(AsyncURB
) next
;
233 /* For regular async urbs */
235 int more
; /* large transfer, more urbs follow */
237 /* For buffered iso handling */
238 int iso_frame_idx
; /* -1 means in flight */
241 static AsyncURB
*async_alloc(USBHostDevice
*s
)
243 AsyncURB
*aurb
= qemu_mallocz(sizeof(AsyncURB
));
245 QLIST_INSERT_HEAD(&s
->aurbs
, aurb
, next
);
249 static void async_free(AsyncURB
*aurb
)
251 QLIST_REMOVE(aurb
, next
);
255 static void async_complete(void *opaque
)
257 USBHostDevice
*s
= opaque
;
263 int r
= ioctl(s
->fd
, USBDEVFS_REAPURBNDELAY
, &aurb
);
265 if (errno
== EAGAIN
) {
268 if (errno
== ENODEV
&& !s
->closing
) {
269 printf("husb: device %d.%d disconnected\n",
270 s
->bus_num
, s
->addr
);
272 usb_host_auto_check(NULL
);
276 DPRINTF("husb: async. reap urb failed errno %d\n", errno
);
280 DPRINTF("husb: async completed. aurb %p status %d alen %d\n",
281 aurb
, aurb
->urb
.status
, aurb
->urb
.actual_length
);
283 /* If this is a buffered iso urb mark it as complete and don't do
284 anything else (it is handled further in usb_host_handle_iso_data) */
285 if (aurb
->iso_frame_idx
== -1) {
286 if (aurb
->urb
.status
== -EPIPE
) {
287 set_halt(s
, aurb
->urb
.endpoint
& 0xf);
289 aurb
->iso_frame_idx
= 0;
296 switch (aurb
->urb
.status
) {
298 p
->len
+= aurb
->urb
.actual_length
;
302 set_halt(s
, p
->devep
);
303 p
->len
= USB_RET_STALL
;
307 p
->len
= USB_RET_NAK
;
311 if (aurb
->urb
.type
== USBDEVFS_URB_TYPE_CONTROL
) {
312 usb_generic_async_ctrl_complete(&s
->dev
, p
);
313 } else if (!aurb
->more
) {
314 usb_packet_complete(&s
->dev
, p
);
322 static void async_cancel(USBPacket
*p
, void *opaque
)
324 USBHostDevice
*s
= opaque
;
327 QLIST_FOREACH(aurb
, &s
->aurbs
, next
) {
328 if (p
!= aurb
->packet
) {
332 DPRINTF("husb: async cancel: packet %p, aurb %p\n", p
, aurb
);
334 /* Mark it as dead (see async_complete above) */
337 int r
= ioctl(s
->fd
, USBDEVFS_DISCARDURB
, aurb
);
339 DPRINTF("husb: async. discard urb failed errno %d\n", errno
);
344 static int usb_host_claim_interfaces(USBHostDevice
*dev
, int configuration
)
346 int dev_descr_len
, config_descr_len
;
347 int interface
, nb_interfaces
;
350 if (configuration
== 0) /* address state - ignore */
353 DPRINTF("husb: claiming interfaces. config %d\n", configuration
);
356 dev_descr_len
= dev
->descr
[0];
357 if (dev_descr_len
> dev
->descr_len
) {
362 while (i
< dev
->descr_len
) {
363 DPRINTF("husb: i is %d, descr_len is %d, dl %d, dt %d\n",
365 dev
->descr
[i
], dev
->descr
[i
+1]);
367 if (dev
->descr
[i
+1] != USB_DT_CONFIG
) {
371 config_descr_len
= dev
->descr
[i
];
373 printf("husb: config #%d need %d\n", dev
->descr
[i
+ 5], configuration
);
375 if (configuration
< 0 || configuration
== dev
->descr
[i
+ 5]) {
376 configuration
= dev
->descr
[i
+ 5];
380 i
+= config_descr_len
;
383 if (i
>= dev
->descr_len
) {
385 "husb: update iface failed. no matching configuration\n");
388 nb_interfaces
= dev
->descr
[i
+ 4];
390 #ifdef USBDEVFS_DISCONNECT
391 /* earlier Linux 2.4 do not support that */
393 struct usbdevfs_ioctl ctrl
;
394 for (interface
= 0; interface
< nb_interfaces
; interface
++) {
395 ctrl
.ioctl_code
= USBDEVFS_DISCONNECT
;
396 ctrl
.ifno
= interface
;
398 ret
= ioctl(dev
->fd
, USBDEVFS_IOCTL
, &ctrl
);
399 if (ret
< 0 && errno
!= ENODATA
) {
400 perror("USBDEVFS_DISCONNECT");
407 /* XXX: only grab if all interfaces are free */
408 for (interface
= 0; interface
< nb_interfaces
; interface
++) {
409 ret
= ioctl(dev
->fd
, USBDEVFS_CLAIMINTERFACE
, &interface
);
411 if (errno
== EBUSY
) {
412 printf("husb: update iface. device already grabbed\n");
414 perror("husb: failed to claim interface");
421 printf("husb: %d interfaces claimed for configuration %d\n",
422 nb_interfaces
, configuration
);
424 dev
->ninterfaces
= nb_interfaces
;
425 dev
->configuration
= configuration
;
429 static int usb_host_release_interfaces(USBHostDevice
*s
)
433 DPRINTF("husb: releasing interfaces\n");
435 for (i
= 0; i
< s
->ninterfaces
; i
++) {
436 ret
= ioctl(s
->fd
, USBDEVFS_RELEASEINTERFACE
, &i
);
438 perror("husb: failed to release interface");
446 static void usb_host_handle_reset(USBDevice
*dev
)
448 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
450 DPRINTF("husb: reset device %u.%u\n", s
->bus_num
, s
->addr
);
452 ioctl(s
->fd
, USBDEVFS_RESET
);
454 usb_host_claim_interfaces(s
, s
->configuration
);
457 static void usb_host_handle_destroy(USBDevice
*dev
)
459 USBHostDevice
*s
= (USBHostDevice
*)dev
;
462 QTAILQ_REMOVE(&hostdevs
, s
, next
);
463 qemu_remove_exit_notifier(&s
->exit
);
466 static int usb_linux_update_endp_table(USBHostDevice
*s
);
468 /* iso data is special, we need to keep enough urbs in flight to make sure
469 that the controller never runs out of them, otherwise the device will
470 likely suffer a buffer underrun / overrun. */
471 static AsyncURB
*usb_host_alloc_iso(USBHostDevice
*s
, uint8_t ep
, int in
)
474 int i
, j
, len
= get_max_packet_size(s
, ep
);
476 aurb
= qemu_mallocz(ISO_URB_COUNT
* sizeof(*aurb
));
477 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
478 aurb
[i
].urb
.endpoint
= ep
;
479 aurb
[i
].urb
.buffer_length
= ISO_FRAME_DESC_PER_URB
* len
;
480 aurb
[i
].urb
.buffer
= qemu_malloc(aurb
[i
].urb
.buffer_length
);
481 aurb
[i
].urb
.type
= USBDEVFS_URB_TYPE_ISO
;
482 aurb
[i
].urb
.flags
= USBDEVFS_URB_ISO_ASAP
;
483 aurb
[i
].urb
.number_of_packets
= ISO_FRAME_DESC_PER_URB
;
484 for (j
= 0 ; j
< ISO_FRAME_DESC_PER_URB
; j
++)
485 aurb
[i
].urb
.iso_frame_desc
[j
].length
= len
;
487 aurb
[i
].urb
.endpoint
|= 0x80;
488 /* Mark as fully consumed (idle) */
489 aurb
[i
].iso_frame_idx
= ISO_FRAME_DESC_PER_URB
;
492 set_iso_urb(s
, ep
, aurb
);
497 static void usb_host_stop_n_free_iso(USBHostDevice
*s
, uint8_t ep
)
500 int i
, ret
, killed
= 0, free
= 1;
502 aurb
= get_iso_urb(s
, ep
);
507 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
509 if (aurb
[i
].iso_frame_idx
== -1) {
510 ret
= ioctl(s
->fd
, USBDEVFS_DISCARDURB
, &aurb
[i
]);
512 printf("husb: discard isoc in urb failed errno %d\n", errno
);
520 /* Make sure any urbs we've killed are reaped before we free them */
525 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
526 qemu_free(aurb
[i
].urb
.buffer
);
532 printf("husb: leaking iso urbs because of discard failure\n");
533 set_iso_urb(s
, ep
, NULL
);
534 set_iso_urb_idx(s
, ep
, 0);
535 clear_iso_started(s
, ep
);
538 static int urb_status_to_usb_ret(int status
)
542 return USB_RET_STALL
;
548 static int usb_host_handle_iso_data(USBHostDevice
*s
, USBPacket
*p
, int in
)
551 int i
, j
, ret
, max_packet_size
, offset
, len
= 0;
553 max_packet_size
= get_max_packet_size(s
, p
->devep
);
554 if (max_packet_size
== 0)
557 aurb
= get_iso_urb(s
, p
->devep
);
559 aurb
= usb_host_alloc_iso(s
, p
->devep
, in
);
562 i
= get_iso_urb_idx(s
, p
->devep
);
563 j
= aurb
[i
].iso_frame_idx
;
564 if (j
>= 0 && j
< ISO_FRAME_DESC_PER_URB
) {
566 /* Check urb status */
567 if (aurb
[i
].urb
.status
) {
568 len
= urb_status_to_usb_ret(aurb
[i
].urb
.status
);
569 /* Move to the next urb */
570 aurb
[i
].iso_frame_idx
= ISO_FRAME_DESC_PER_URB
- 1;
571 /* Check frame status */
572 } else if (aurb
[i
].urb
.iso_frame_desc
[j
].status
) {
573 len
= urb_status_to_usb_ret(
574 aurb
[i
].urb
.iso_frame_desc
[j
].status
);
575 /* Check the frame fits */
576 } else if (aurb
[i
].urb
.iso_frame_desc
[j
].actual_length
> p
->len
) {
577 printf("husb: received iso data is larger then packet\n");
579 /* All good copy data over */
581 len
= aurb
[i
].urb
.iso_frame_desc
[j
].actual_length
;
584 j
* aurb
[i
].urb
.iso_frame_desc
[0].length
,
589 offset
= (j
== 0) ? 0 : get_iso_buffer_used(s
, p
->devep
);
591 /* Check the frame fits */
592 if (len
> max_packet_size
) {
593 printf("husb: send iso data is larger then max packet size\n");
597 /* All good copy data over */
598 memcpy(aurb
[i
].urb
.buffer
+ offset
, p
->data
, len
);
599 aurb
[i
].urb
.iso_frame_desc
[j
].length
= len
;
601 set_iso_buffer_used(s
, p
->devep
, offset
);
603 /* Start the stream once we have buffered enough data */
604 if (!is_iso_started(s
, p
->devep
) && i
== 1 && j
== 8) {
605 set_iso_started(s
, p
->devep
);
608 aurb
[i
].iso_frame_idx
++;
609 if (aurb
[i
].iso_frame_idx
== ISO_FRAME_DESC_PER_URB
) {
610 i
= (i
+ 1) % ISO_URB_COUNT
;
611 set_iso_urb_idx(s
, p
->devep
, i
);
615 set_iso_started(s
, p
->devep
);
617 DPRINTF("hubs: iso out error no free buffer, dropping packet\n");
621 if (is_iso_started(s
, p
->devep
)) {
622 /* (Re)-submit all fully consumed / filled urbs */
623 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
624 if (aurb
[i
].iso_frame_idx
== ISO_FRAME_DESC_PER_URB
) {
625 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, &aurb
[i
]);
627 printf("husb error submitting iso urb %d: %d\n", i
, errno
);
628 if (!in
|| len
== 0) {
640 aurb
[i
].iso_frame_idx
= -1;
648 static int usb_host_handle_data(USBDevice
*dev
, USBPacket
*p
)
650 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
651 struct usbdevfs_urb
*urb
;
657 if (!is_valid(s
, p
->devep
)) {
661 if (p
->pid
== USB_TOKEN_IN
) {
662 ep
= p
->devep
| 0x80;
667 if (is_halted(s
, p
->devep
)) {
668 ret
= ioctl(s
->fd
, USBDEVFS_CLEAR_HALT
, &ep
);
670 DPRINTF("husb: failed to clear halt. ep 0x%x errno %d\n",
674 clear_halt(s
, p
->devep
);
677 if (is_isoc(s
, p
->devep
)) {
678 return usb_host_handle_iso_data(s
, p
, p
->pid
== USB_TOKEN_IN
);
685 aurb
= async_alloc(s
);
690 urb
->type
= USBDEVFS_URB_TYPE_BULK
;
691 urb
->usercontext
= s
;
694 if (rem
> MAX_USBFS_BUFFER_SIZE
) {
695 urb
->buffer_length
= MAX_USBFS_BUFFER_SIZE
;
698 urb
->buffer_length
= rem
;
701 pbuf
+= urb
->buffer_length
;
702 rem
-= urb
->buffer_length
;
704 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
706 DPRINTF("husb: data submit: ep 0x%x, len %u, more %d, packet %p, aurb %p\n",
707 urb
->endpoint
, urb
->buffer_length
, aurb
->more
, p
, aurb
);
710 DPRINTF("husb: submit failed. errno %d\n", errno
);
718 return USB_RET_STALL
;
723 usb_defer_packet(p
, async_cancel
, s
);
724 return USB_RET_ASYNC
;
727 static int ctrl_error(void)
729 if (errno
== ETIMEDOUT
) {
732 return USB_RET_STALL
;
736 static int usb_host_set_address(USBHostDevice
*s
, int addr
)
738 DPRINTF("husb: ctrl set addr %u\n", addr
);
743 static int usb_host_set_config(USBHostDevice
*s
, int config
)
745 usb_host_release_interfaces(s
);
747 int ret
= ioctl(s
->fd
, USBDEVFS_SETCONFIGURATION
, &config
);
749 DPRINTF("husb: ctrl set config %d ret %d errno %d\n", config
, ret
, errno
);
754 usb_host_claim_interfaces(s
, config
);
758 static int usb_host_set_interface(USBHostDevice
*s
, int iface
, int alt
)
760 struct usbdevfs_setinterface si
;
763 for (i
= 1; i
<= MAX_ENDPOINTS
; i
++) {
765 usb_host_stop_n_free_iso(s
, i
);
769 si
.interface
= iface
;
771 ret
= ioctl(s
->fd
, USBDEVFS_SETINTERFACE
, &si
);
773 DPRINTF("husb: ctrl set iface %d altset %d ret %d errno %d\n",
774 iface
, alt
, ret
, errno
);
779 usb_linux_update_endp_table(s
);
783 static int usb_host_handle_control(USBDevice
*dev
, USBPacket
*p
,
784 int request
, int value
, int index
, int length
, uint8_t *data
)
786 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
787 struct usbdevfs_urb
*urb
;
792 * Process certain standard device requests.
793 * These are infrequent and are processed synchronously.
796 /* Note request is (bRequestType << 8) | bRequest */
797 DPRINTF("husb: ctrl type 0x%x req 0x%x val 0x%x index %u len %u\n",
798 request
>> 8, request
& 0xff, value
, index
, length
);
801 case DeviceOutRequest
| USB_REQ_SET_ADDRESS
:
802 return usb_host_set_address(s
, value
);
804 case DeviceOutRequest
| USB_REQ_SET_CONFIGURATION
:
805 return usb_host_set_config(s
, value
& 0xff);
807 case InterfaceOutRequest
| USB_REQ_SET_INTERFACE
:
808 return usb_host_set_interface(s
, index
, value
);
811 /* The rest are asynchronous */
813 if (length
> sizeof(dev
->data_buf
)) {
814 fprintf(stderr
, "husb: ctrl buffer too small (%d > %zu)\n",
815 length
, sizeof(dev
->data_buf
));
816 return USB_RET_STALL
;
819 aurb
= async_alloc(s
);
823 * Setup ctrl transfer.
825 * s->ctrl is laid out such that data buffer immediately follows
826 * 'req' struct which is exactly what usbdevfs expects.
830 urb
->type
= USBDEVFS_URB_TYPE_CONTROL
;
831 urb
->endpoint
= p
->devep
;
833 urb
->buffer
= &dev
->setup_buf
;
834 urb
->buffer_length
= length
+ 8;
836 urb
->usercontext
= s
;
838 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
840 DPRINTF("husb: submit ctrl. len %u aurb %p\n", urb
->buffer_length
, aurb
);
843 DPRINTF("husb: submit failed. errno %d\n", errno
);
851 return USB_RET_STALL
;
855 usb_defer_packet(p
, async_cancel
, s
);
856 return USB_RET_ASYNC
;
859 static int usb_linux_get_configuration(USBHostDevice
*s
)
861 uint8_t configuration
;
862 struct usb_ctrltransfer ct
;
865 if (usb_fs_type
== USB_FS_SYS
) {
866 char device_name
[32], line
[1024];
869 sprintf(device_name
, "%d-%s", s
->bus_num
, s
->port
);
871 if (!usb_host_read_file(line
, sizeof(line
), "bConfigurationValue",
875 if (sscanf(line
, "%d", &configuration
) != 1) {
878 return configuration
;
882 ct
.bRequestType
= USB_DIR_IN
;
883 ct
.bRequest
= USB_REQ_GET_CONFIGURATION
;
887 ct
.data
= &configuration
;
890 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
892 perror("usb_linux_get_configuration");
896 /* in address state */
897 if (configuration
== 0) {
901 return configuration
;
904 static uint8_t usb_linux_get_alt_setting(USBHostDevice
*s
,
905 uint8_t configuration
, uint8_t interface
)
908 struct usb_ctrltransfer ct
;
911 if (usb_fs_type
== USB_FS_SYS
) {
912 char device_name
[64], line
[1024];
915 sprintf(device_name
, "%d-%s:%d.%d", s
->bus_num
, s
->port
,
916 (int)configuration
, (int)interface
);
918 if (!usb_host_read_file(line
, sizeof(line
), "bAlternateSetting",
922 if (sscanf(line
, "%d", &alt_setting
) != 1) {
929 ct
.bRequestType
= USB_DIR_IN
| USB_RECIP_INTERFACE
;
930 ct
.bRequest
= USB_REQ_GET_INTERFACE
;
932 ct
.wIndex
= interface
;
934 ct
.data
= &alt_setting
;
936 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
938 /* Assume alt 0 on error */
945 /* returns 1 on problem encountered or 0 for success */
946 static int usb_linux_update_endp_table(USBHostDevice
*s
)
948 uint8_t *descriptors
;
949 uint8_t devep
, type
, configuration
, alt_interface
;
950 int interface
, length
, i
;
952 for (i
= 0; i
< MAX_ENDPOINTS
; i
++)
953 s
->endp_table
[i
].type
= INVALID_EP_TYPE
;
955 i
= usb_linux_get_configuration(s
);
960 /* get the desired configuration, interface, and endpoint descriptors
961 * from device description */
962 descriptors
= &s
->descr
[18];
963 length
= s
->descr_len
- 18;
966 if (descriptors
[i
+ 1] != USB_DT_CONFIG
||
967 descriptors
[i
+ 5] != configuration
) {
968 DPRINTF("invalid descriptor data - configuration\n");
974 if (descriptors
[i
+ 1] != USB_DT_INTERFACE
||
975 (descriptors
[i
+ 1] == USB_DT_INTERFACE
&&
976 descriptors
[i
+ 4] == 0)) {
981 interface
= descriptors
[i
+ 2];
982 alt_interface
= usb_linux_get_alt_setting(s
, configuration
, interface
);
984 /* the current interface descriptor is the active interface
985 * and has endpoints */
986 if (descriptors
[i
+ 3] != alt_interface
) {
991 /* advance to the endpoints */
992 while (i
< length
&& descriptors
[i
+1] != USB_DT_ENDPOINT
) {
1000 if (descriptors
[i
+ 1] != USB_DT_ENDPOINT
) {
1004 devep
= descriptors
[i
+ 2];
1005 switch (descriptors
[i
+ 3] & 0x3) {
1007 type
= USBDEVFS_URB_TYPE_CONTROL
;
1010 type
= USBDEVFS_URB_TYPE_ISO
;
1011 s
->endp_table
[(devep
& 0xf) - 1].max_packet_size
=
1012 descriptors
[i
+ 4] + (descriptors
[i
+ 5] << 8);
1015 type
= USBDEVFS_URB_TYPE_BULK
;
1018 type
= USBDEVFS_URB_TYPE_INTERRUPT
;
1021 DPRINTF("usb_host: malformed endpoint type\n");
1022 type
= USBDEVFS_URB_TYPE_BULK
;
1024 s
->endp_table
[(devep
& 0xf) - 1].type
= type
;
1025 s
->endp_table
[(devep
& 0xf) - 1].halted
= 0;
1027 i
+= descriptors
[i
];
1033 static int usb_host_open(USBHostDevice
*dev
, int bus_num
,
1034 int addr
, char *port
, const char *prod_name
)
1037 struct usbdevfs_connectinfo ci
;
1040 if (dev
->fd
!= -1) {
1043 printf("husb: open device %d.%d\n", bus_num
, addr
);
1045 if (!usb_host_device_path
) {
1046 perror("husb: USB Host Device Path not set");
1049 snprintf(buf
, sizeof(buf
), "%s/%03d/%03d", usb_host_device_path
,
1051 fd
= open(buf
, O_RDWR
| O_NONBLOCK
);
1056 DPRINTF("husb: opened %s\n", buf
);
1058 dev
->bus_num
= bus_num
;
1060 strcpy(dev
->port
, port
);
1063 /* read the device description */
1064 dev
->descr_len
= read(fd
, dev
->descr
, sizeof(dev
->descr
));
1065 if (dev
->descr_len
<= 0) {
1066 perror("husb: reading device data failed");
1073 printf("=== begin dumping device descriptor data ===\n");
1074 for (x
= 0; x
< dev
->descr_len
; x
++) {
1075 printf("%02x ", dev
->descr
[x
]);
1077 printf("\n=== end dumping device descriptor data ===\n");
1083 * Initial configuration is -1 which makes us claim first
1084 * available config. We used to start with 1, which does not
1085 * always work. I've seen devices where first config starts
1088 if (!usb_host_claim_interfaces(dev
, -1)) {
1092 ret
= ioctl(fd
, USBDEVFS_CONNECTINFO
, &ci
);
1094 perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
1098 printf("husb: grabbed usb device %d.%d\n", bus_num
, addr
);
1100 ret
= usb_linux_update_endp_table(dev
);
1106 dev
->dev
.speed
= USB_SPEED_LOW
;
1108 dev
->dev
.speed
= USB_SPEED_HIGH
;
1111 if (!prod_name
|| prod_name
[0] == '\0') {
1112 snprintf(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1113 "host:%d.%d", bus_num
, addr
);
1115 pstrcpy(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1119 /* USB devio uses 'write' flag to check for async completions */
1120 qemu_set_fd_handler(dev
->fd
, NULL
, async_complete
, dev
);
1122 usb_device_attach(&dev
->dev
);
1133 static int usb_host_close(USBHostDevice
*dev
)
1137 if (dev
->fd
== -1) {
1141 qemu_set_fd_handler(dev
->fd
, NULL
, NULL
, NULL
);
1143 for (i
= 1; i
<= MAX_ENDPOINTS
; i
++) {
1144 if (is_isoc(dev
, i
)) {
1145 usb_host_stop_n_free_iso(dev
, i
);
1148 async_complete(dev
);
1150 usb_device_detach(&dev
->dev
);
1151 ioctl(dev
->fd
, USBDEVFS_RESET
);
1157 static void usb_host_exit_notifier(struct Notifier
* n
)
1159 USBHostDevice
*s
= container_of(n
, USBHostDevice
, exit
);
1162 ioctl(s
->fd
, USBDEVFS_RESET
);
1166 static int usb_host_initfn(USBDevice
*dev
)
1168 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
1170 dev
->auto_attach
= 0;
1172 QTAILQ_INSERT_TAIL(&hostdevs
, s
, next
);
1173 s
->exit
.notify
= usb_host_exit_notifier
;
1174 qemu_add_exit_notifier(&s
->exit
);
1175 usb_host_auto_check(NULL
);
1179 static struct USBDeviceInfo usb_host_dev_info
= {
1180 .product_desc
= "USB Host Device",
1181 .qdev
.name
= "usb-host",
1182 .qdev
.size
= sizeof(USBHostDevice
),
1183 .init
= usb_host_initfn
,
1184 .handle_packet
= usb_generic_handle_packet
,
1185 .handle_data
= usb_host_handle_data
,
1186 .handle_control
= usb_host_handle_control
,
1187 .handle_reset
= usb_host_handle_reset
,
1188 .handle_destroy
= usb_host_handle_destroy
,
1189 .usbdevice_name
= "host",
1190 .usbdevice_init
= usb_host_device_open
,
1191 .qdev
.props
= (Property
[]) {
1192 DEFINE_PROP_UINT32("hostbus", USBHostDevice
, match
.bus_num
, 0),
1193 DEFINE_PROP_UINT32("hostaddr", USBHostDevice
, match
.addr
, 0),
1194 DEFINE_PROP_STRING("hostport", USBHostDevice
, match
.port
),
1195 DEFINE_PROP_HEX32("vendorid", USBHostDevice
, match
.vendor_id
, 0),
1196 DEFINE_PROP_HEX32("productid", USBHostDevice
, match
.product_id
, 0),
1197 DEFINE_PROP_END_OF_LIST(),
1201 static void usb_host_register_devices(void)
1203 usb_qdev_register(&usb_host_dev_info
);
1205 device_init(usb_host_register_devices
)
1207 USBDevice
*usb_host_device_open(const char *devname
)
1209 struct USBAutoFilter filter
;
1213 dev
= usb_create(NULL
/* FIXME */, "usb-host");
1215 if (strstr(devname
, "auto:")) {
1216 if (parse_filter(devname
, &filter
) < 0) {
1220 if ((p
= strchr(devname
, '.'))) {
1221 filter
.bus_num
= strtoul(devname
, NULL
, 0);
1222 filter
.addr
= strtoul(p
+ 1, NULL
, 0);
1223 filter
.vendor_id
= 0;
1224 filter
.product_id
= 0;
1225 } else if ((p
= strchr(devname
, ':'))) {
1228 filter
.vendor_id
= strtoul(devname
, NULL
, 16);
1229 filter
.product_id
= strtoul(p
+ 1, NULL
, 16);
1235 qdev_prop_set_uint32(&dev
->qdev
, "hostbus", filter
.bus_num
);
1236 qdev_prop_set_uint32(&dev
->qdev
, "hostaddr", filter
.addr
);
1237 qdev_prop_set_uint32(&dev
->qdev
, "vendorid", filter
.vendor_id
);
1238 qdev_prop_set_uint32(&dev
->qdev
, "productid", filter
.product_id
);
1239 qdev_init_nofail(&dev
->qdev
);
1243 qdev_free(&dev
->qdev
);
1247 int usb_host_device_close(const char *devname
)
1250 char product_name
[PRODUCT_NAME_SZ
];
1254 if (strstr(devname
, "auto:")) {
1255 return usb_host_auto_del(devname
);
1257 if (usb_host_find_device(&bus_num
, &addr
, product_name
,
1258 sizeof(product_name
), devname
) < 0) {
1261 s
= hostdev_find(bus_num
, addr
);
1263 usb_device_delete_addr(s
->bus_num
, s
->dev
.addr
);
1271 static int get_tag_value(char *buf
, int buf_size
,
1272 const char *str
, const char *tag
,
1273 const char *stopchars
)
1277 p
= strstr(str
, tag
);
1282 while (qemu_isspace(*p
)) {
1286 while (*p
!= '\0' && !strchr(stopchars
, *p
)) {
1287 if ((q
- buf
) < (buf_size
- 1)) {
1297 * Use /proc/bus/usb/devices or /dev/bus/usb/devices file to determine
1298 * host's USB devices. This is legacy support since many distributions
1299 * are moving to /sys/bus/usb
1301 static int usb_host_scan_dev(void *opaque
, USBScanFunc
*func
)
1306 int bus_num
, addr
, speed
, device_count
, class_id
, product_id
, vendor_id
;
1307 char product_name
[512];
1310 if (!usb_host_device_path
) {
1311 perror("husb: USB Host Device Path not set");
1314 snprintf(line
, sizeof(line
), "%s/devices", usb_host_device_path
);
1315 f
= fopen(line
, "r");
1317 perror("husb: cannot open devices file");
1322 bus_num
= addr
= speed
= class_id
= product_id
= vendor_id
= 0;
1324 if (fgets(line
, sizeof(line
), f
) == NULL
) {
1327 if (strlen(line
) > 0) {
1328 line
[strlen(line
) - 1] = '\0';
1330 if (line
[0] == 'T' && line
[1] == ':') {
1331 if (device_count
&& (vendor_id
|| product_id
)) {
1332 /* New device. Add the previously discovered device. */
1333 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1334 product_id
, product_name
, speed
);
1339 if (get_tag_value(buf
, sizeof(buf
), line
, "Bus=", " ") < 0) {
1342 bus_num
= atoi(buf
);
1343 if (get_tag_value(buf
, sizeof(buf
), line
, "Dev#=", " ") < 0) {
1347 if (get_tag_value(buf
, sizeof(buf
), line
, "Spd=", " ") < 0) {
1350 if (!strcmp(buf
, "480")) {
1351 speed
= USB_SPEED_HIGH
;
1352 } else if (!strcmp(buf
, "1.5")) {
1353 speed
= USB_SPEED_LOW
;
1355 speed
= USB_SPEED_FULL
;
1357 product_name
[0] = '\0';
1362 } else if (line
[0] == 'P' && line
[1] == ':') {
1363 if (get_tag_value(buf
, sizeof(buf
), line
, "Vendor=", " ") < 0) {
1366 vendor_id
= strtoul(buf
, NULL
, 16);
1367 if (get_tag_value(buf
, sizeof(buf
), line
, "ProdID=", " ") < 0) {
1370 product_id
= strtoul(buf
, NULL
, 16);
1371 } else if (line
[0] == 'S' && line
[1] == ':') {
1372 if (get_tag_value(buf
, sizeof(buf
), line
, "Product=", "") < 0) {
1375 pstrcpy(product_name
, sizeof(product_name
), buf
);
1376 } else if (line
[0] == 'D' && line
[1] == ':') {
1377 if (get_tag_value(buf
, sizeof(buf
), line
, "Cls=", " (") < 0) {
1380 class_id
= strtoul(buf
, NULL
, 16);
1384 if (device_count
&& (vendor_id
|| product_id
)) {
1385 /* Add the last device. */
1386 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1387 product_id
, product_name
, speed
);
1397 * Read sys file-system device file
1399 * @line address of buffer to put file contents in
1400 * @line_size size of line
1401 * @device_file path to device file (printf format string)
1402 * @device_name device being opened (inserted into device_file)
1404 * @return 0 failed, 1 succeeded ('line' contains data)
1406 static int usb_host_read_file(char *line
, size_t line_size
,
1407 const char *device_file
, const char *device_name
)
1411 char filename
[PATH_MAX
];
1413 snprintf(filename
, PATH_MAX
, USBSYSBUS_PATH
"/devices/%s/%s", device_name
,
1415 f
= fopen(filename
, "r");
1417 ret
= fgets(line
, line_size
, f
) != NULL
;
1425 * Use /sys/bus/usb/devices/ directory to determine host's USB
1428 * This code is based on Robert Schiele's original patches posted to
1429 * the Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
1431 static int usb_host_scan_sys(void *opaque
, USBScanFunc
*func
)
1435 int bus_num
, addr
, speed
, class_id
, product_id
, vendor_id
;
1437 char port
[MAX_PORTLEN
];
1438 char product_name
[512];
1441 dir
= opendir(USBSYSBUS_PATH
"/devices");
1443 perror("husb: cannot open devices directory");
1447 while ((de
= readdir(dir
))) {
1448 if (de
->d_name
[0] != '.' && !strchr(de
->d_name
, ':')) {
1449 if (sscanf(de
->d_name
, "%d-%7[0-9.]", &bus_num
, port
) < 2) {
1453 if (!usb_host_read_file(line
, sizeof(line
), "devnum", de
->d_name
)) {
1456 if (sscanf(line
, "%d", &addr
) != 1) {
1459 if (!usb_host_read_file(line
, sizeof(line
), "bDeviceClass",
1463 if (sscanf(line
, "%x", &class_id
) != 1) {
1467 if (!usb_host_read_file(line
, sizeof(line
), "idVendor",
1471 if (sscanf(line
, "%x", &vendor_id
) != 1) {
1474 if (!usb_host_read_file(line
, sizeof(line
), "idProduct",
1478 if (sscanf(line
, "%x", &product_id
) != 1) {
1481 if (!usb_host_read_file(line
, sizeof(line
), "product",
1485 if (strlen(line
) > 0) {
1486 line
[strlen(line
) - 1] = '\0';
1488 pstrcpy(product_name
, sizeof(product_name
), line
);
1491 if (!usb_host_read_file(line
, sizeof(line
), "speed", de
->d_name
)) {
1494 if (!strcmp(line
, "480\n")) {
1495 speed
= USB_SPEED_HIGH
;
1496 } else if (!strcmp(line
, "1.5\n")) {
1497 speed
= USB_SPEED_LOW
;
1499 speed
= USB_SPEED_FULL
;
1502 ret
= func(opaque
, bus_num
, addr
, port
, class_id
, vendor_id
,
1503 product_id
, product_name
, speed
);
1517 * Determine how to access the host's USB devices and call the
1518 * specific support function.
1520 static int usb_host_scan(void *opaque
, USBScanFunc
*func
)
1522 Monitor
*mon
= cur_mon
;
1526 const char *fs_type
[] = {"unknown", "proc", "dev", "sys"};
1527 char devpath
[PATH_MAX
];
1529 /* only check the host once */
1531 dir
= opendir(USBSYSBUS_PATH
"/devices");
1533 /* devices found in /dev/bus/usb/ (yes - not a mistake!) */
1534 strcpy(devpath
, USBDEVBUS_PATH
);
1535 usb_fs_type
= USB_FS_SYS
;
1537 DPRINTF(USBDBG_DEVOPENED
, USBSYSBUS_PATH
);
1540 f
= fopen(USBPROCBUS_PATH
"/devices", "r");
1542 /* devices found in /proc/bus/usb/ */
1543 strcpy(devpath
, USBPROCBUS_PATH
);
1544 usb_fs_type
= USB_FS_PROC
;
1546 DPRINTF(USBDBG_DEVOPENED
, USBPROCBUS_PATH
);
1549 /* try additional methods if an access method hasn't been found yet */
1550 f
= fopen(USBDEVBUS_PATH
"/devices", "r");
1552 /* devices found in /dev/bus/usb/ */
1553 strcpy(devpath
, USBDEVBUS_PATH
);
1554 usb_fs_type
= USB_FS_DEV
;
1556 DPRINTF(USBDBG_DEVOPENED
, USBDEVBUS_PATH
);
1562 monitor_printf(mon
, "husb: unable to access USB devices\n");
1567 /* the module setting (used later for opening devices) */
1568 usb_host_device_path
= qemu_mallocz(strlen(devpath
)+1);
1569 strcpy(usb_host_device_path
, devpath
);
1571 monitor_printf(mon
, "husb: using %s file-system with %s\n",
1572 fs_type
[usb_fs_type
], usb_host_device_path
);
1576 switch (usb_fs_type
) {
1579 ret
= usb_host_scan_dev(opaque
, func
);
1582 ret
= usb_host_scan_sys(opaque
, func
);
1591 static QEMUTimer
*usb_auto_timer
;
1593 static int usb_host_auto_scan(void *opaque
, int bus_num
, int addr
, char *port
,
1594 int class_id
, int vendor_id
, int product_id
,
1595 const char *product_name
, int speed
)
1597 struct USBAutoFilter
*f
;
1598 struct USBHostDevice
*s
;
1604 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1607 if (f
->bus_num
> 0 && f
->bus_num
!= bus_num
) {
1610 if (f
->addr
> 0 && f
->addr
!= addr
) {
1613 if (f
->port
!= NULL
&& (port
== NULL
|| strcmp(f
->port
, port
) != 0)) {
1617 if (f
->vendor_id
> 0 && f
->vendor_id
!= vendor_id
) {
1621 if (f
->product_id
> 0 && f
->product_id
!= product_id
) {
1624 /* We got a match */
1626 /* Already attached ? */
1630 DPRINTF("husb: auto open: bus_num %d addr %d\n", bus_num
, addr
);
1632 usb_host_open(s
, bus_num
, addr
, port
, product_name
);
1638 static void usb_host_auto_check(void *unused
)
1640 struct USBHostDevice
*s
;
1641 int unconnected
= 0;
1643 usb_host_scan(NULL
, usb_host_auto_scan
);
1645 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1651 if (unconnected
== 0) {
1652 /* nothing to watch */
1653 if (usb_auto_timer
) {
1654 qemu_del_timer(usb_auto_timer
);
1659 if (!usb_auto_timer
) {
1660 usb_auto_timer
= qemu_new_timer_ms(rt_clock
, usb_host_auto_check
, NULL
);
1661 if (!usb_auto_timer
) {
1665 qemu_mod_timer(usb_auto_timer
, qemu_get_clock_ms(rt_clock
) + 2000);
1669 * Autoconnect filter
1671 * auto:bus:dev[:vid:pid]
1672 * auto:bus.dev[:vid:pid]
1674 * bus - bus number (dec, * means any)
1675 * dev - device number (dec, * means any)
1676 * vid - vendor id (hex, * means any)
1677 * pid - product id (hex, * means any)
1679 * See 'lsusb' output.
1681 static int parse_filter(const char *spec
, struct USBAutoFilter
*f
)
1683 enum { BUS
, DEV
, VID
, PID
, DONE
};
1684 const char *p
= spec
;
1692 for (i
= BUS
; i
< DONE
; i
++) {
1693 p
= strpbrk(p
, ":.");
1703 case BUS
: f
->bus_num
= strtol(p
, NULL
, 10); break;
1704 case DEV
: f
->addr
= strtol(p
, NULL
, 10); break;
1705 case VID
: f
->vendor_id
= strtol(p
, NULL
, 16); break;
1706 case PID
: f
->product_id
= strtol(p
, NULL
, 16); break;
1711 fprintf(stderr
, "husb: invalid auto filter spec %s\n", spec
);
1718 /**********************/
1719 /* USB host device info */
1721 struct usb_class_info
{
1723 const char *class_name
;
1726 static const struct usb_class_info usb_class_info
[] = {
1727 { USB_CLASS_AUDIO
, "Audio"},
1728 { USB_CLASS_COMM
, "Communication"},
1729 { USB_CLASS_HID
, "HID"},
1730 { USB_CLASS_HUB
, "Hub" },
1731 { USB_CLASS_PHYSICAL
, "Physical" },
1732 { USB_CLASS_PRINTER
, "Printer" },
1733 { USB_CLASS_MASS_STORAGE
, "Storage" },
1734 { USB_CLASS_CDC_DATA
, "Data" },
1735 { USB_CLASS_APP_SPEC
, "Application Specific" },
1736 { USB_CLASS_VENDOR_SPEC
, "Vendor Specific" },
1737 { USB_CLASS_STILL_IMAGE
, "Still Image" },
1738 { USB_CLASS_CSCID
, "Smart Card" },
1739 { USB_CLASS_CONTENT_SEC
, "Content Security" },
1743 static const char *usb_class_str(uint8_t class)
1745 const struct usb_class_info
*p
;
1746 for(p
= usb_class_info
; p
->class != -1; p
++) {
1747 if (p
->class == class) {
1751 return p
->class_name
;
1754 static void usb_info_device(Monitor
*mon
, int bus_num
, int addr
, char *port
,
1755 int class_id
, int vendor_id
, int product_id
,
1756 const char *product_name
,
1759 const char *class_str
, *speed_str
;
1765 case USB_SPEED_FULL
:
1768 case USB_SPEED_HIGH
:
1776 monitor_printf(mon
, " Bus %d, Addr %d, Port %s, Speed %s Mb/s\n",
1777 bus_num
, addr
, port
, speed_str
);
1778 class_str
= usb_class_str(class_id
);
1780 monitor_printf(mon
, " %s:", class_str
);
1782 monitor_printf(mon
, " Class %02x:", class_id
);
1784 monitor_printf(mon
, " USB device %04x:%04x", vendor_id
, product_id
);
1785 if (product_name
[0] != '\0') {
1786 monitor_printf(mon
, ", %s", product_name
);
1788 monitor_printf(mon
, "\n");
1791 static int usb_host_info_device(void *opaque
, int bus_num
, int addr
,
1792 char *path
, int class_id
,
1793 int vendor_id
, int product_id
,
1794 const char *product_name
,
1797 Monitor
*mon
= opaque
;
1799 usb_info_device(mon
, bus_num
, addr
, path
, class_id
, vendor_id
, product_id
,
1800 product_name
, speed
);
1804 static void dec2str(int val
, char *str
, size_t size
)
1807 snprintf(str
, size
, "*");
1809 snprintf(str
, size
, "%d", val
);
1813 static void hex2str(int val
, char *str
, size_t size
)
1816 snprintf(str
, size
, "*");
1818 snprintf(str
, size
, "%04x", val
);
1822 void usb_host_info(Monitor
*mon
)
1824 struct USBAutoFilter
*f
;
1825 struct USBHostDevice
*s
;
1827 usb_host_scan(mon
, usb_host_info_device
);
1829 if (QTAILQ_EMPTY(&hostdevs
)) {
1833 monitor_printf(mon
, " Auto filters:\n");
1834 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1835 char bus
[10], addr
[10], vid
[10], pid
[10];
1837 dec2str(f
->bus_num
, bus
, sizeof(bus
));
1838 dec2str(f
->addr
, addr
, sizeof(addr
));
1839 hex2str(f
->vendor_id
, vid
, sizeof(vid
));
1840 hex2str(f
->product_id
, pid
, sizeof(pid
));
1841 monitor_printf(mon
, " Bus %s, Addr %s, Port %s, ID %s:%s\n",
1842 bus
, addr
, f
->port
? f
->port
: "*", vid
, pid
);