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 struct usb_ctrlrequest
{
65 typedef int USBScanFunc(void *opaque
, int bus_num
, int addr
, int devpath
,
66 int class_id
, int vendor_id
, int product_id
,
67 const char *product_name
, int speed
);
72 #define DPRINTF printf
77 #define USBDBG_DEVOPENED "husb: opened %s/devices\n"
79 #define USBPROCBUS_PATH "/proc/bus/usb"
80 #define PRODUCT_NAME_SZ 32
81 #define MAX_ENDPOINTS 16
82 #define USBDEVBUS_PATH "/dev/bus/usb"
83 #define USBSYSBUS_PATH "/sys/bus/usb"
85 static char *usb_host_device_path
;
92 static int usb_fs_type
;
94 /* endpoint association data */
95 #define ISO_FRAME_DESC_PER_URB 32
96 #define ISO_URB_COUNT 3
98 typedef struct AsyncURB AsyncURB
;
116 * Control transfer state.
117 * Note that 'buffer' _must_ follow 'req' field because
118 * we need contiguous buffer when we submit control URB.
124 struct usb_ctrlrequest req
;
125 uint8_t buffer
[8192];
128 struct USBAutoFilter
{
135 typedef struct USBHostDevice
{
146 struct ctrl_struct ctrl
;
147 struct endp_data endp_table
[MAX_ENDPOINTS
];
149 /* Host side address */
153 struct USBAutoFilter match
;
155 QTAILQ_ENTRY(USBHostDevice
) next
;
158 static QTAILQ_HEAD(, USBHostDevice
) hostdevs
= QTAILQ_HEAD_INITIALIZER(hostdevs
);
160 static int usb_host_close(USBHostDevice
*dev
);
161 static int parse_filter(const char *spec
, struct USBAutoFilter
*f
);
162 static void usb_host_auto_check(void *unused
);
163 static int usb_host_read_file(char *line
, size_t line_size
,
164 const char *device_file
, const char *device_name
);
166 static int is_isoc(USBHostDevice
*s
, int ep
)
168 return s
->endp_table
[ep
- 1].type
== USBDEVFS_URB_TYPE_ISO
;
171 static int is_halted(USBHostDevice
*s
, int ep
)
173 return s
->endp_table
[ep
- 1].halted
;
176 static void clear_halt(USBHostDevice
*s
, int ep
)
178 s
->endp_table
[ep
- 1].halted
= 0;
181 static void set_halt(USBHostDevice
*s
, int ep
)
183 s
->endp_table
[ep
- 1].halted
= 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 int get_max_packet_size(USBHostDevice
*s
, int ep
)
208 return s
->endp_table
[ep
- 1].max_packet_size
;
213 * We always allocate iso packet descriptors even for bulk transfers
214 * to simplify allocation and casts.
218 struct usbdevfs_urb urb
;
219 struct usbdevfs_iso_packet_desc isocpd
[ISO_FRAME_DESC_PER_URB
];
221 /* For regular async urbs */
225 /* For buffered iso handling */
226 int iso_frame_idx
; /* -1 means in flight */
229 static AsyncURB
*async_alloc(void)
231 return (AsyncURB
*) qemu_mallocz(sizeof(AsyncURB
));
234 static void async_free(AsyncURB
*aurb
)
239 static void async_complete_ctrl(USBHostDevice
*s
, USBPacket
*p
)
241 switch(s
->ctrl
.state
) {
242 case CTRL_STATE_SETUP
:
243 if (p
->len
< s
->ctrl
.len
)
244 s
->ctrl
.len
= p
->len
;
245 s
->ctrl
.state
= CTRL_STATE_DATA
;
250 s
->ctrl
.state
= CTRL_STATE_IDLE
;
259 static void async_complete(void *opaque
)
261 USBHostDevice
*s
= opaque
;
267 int r
= ioctl(s
->fd
, USBDEVFS_REAPURBNDELAY
, &aurb
);
269 if (errno
== EAGAIN
) {
272 if (errno
== ENODEV
&& !s
->closing
) {
273 printf("husb: device %d.%d disconnected\n",
274 s
->bus_num
, s
->addr
);
276 usb_host_auto_check(NULL
);
280 DPRINTF("husb: async. reap urb failed errno %d\n", errno
);
284 DPRINTF("husb: async completed. aurb %p status %d alen %d\n",
285 aurb
, aurb
->urb
.status
, aurb
->urb
.actual_length
);
287 /* If this is a buffered iso urb mark it as complete and don't do
288 anything else (it is handled further in usb_host_handle_iso_data) */
289 if (aurb
->iso_frame_idx
== -1) {
290 if (aurb
->urb
.status
== -EPIPE
) {
291 set_halt(s
, aurb
->urb
.endpoint
& 0xf);
293 aurb
->iso_frame_idx
= 0;
300 switch (aurb
->urb
.status
) {
302 p
->len
= aurb
->urb
.actual_length
;
303 if (aurb
->urb
.type
== USBDEVFS_URB_TYPE_CONTROL
) {
304 async_complete_ctrl(s
, p
);
309 set_halt(s
, p
->devep
);
310 p
->len
= USB_RET_STALL
;
314 p
->len
= USB_RET_NAK
;
318 usb_packet_complete(p
);
325 static void async_cancel(USBPacket
*unused
, void *opaque
)
327 AsyncURB
*aurb
= opaque
;
328 USBHostDevice
*s
= aurb
->hdev
;
330 DPRINTF("husb: async cancel. aurb %p\n", aurb
);
332 /* Mark it as dead (see async_complete above) */
335 int r
= ioctl(s
->fd
, USBDEVFS_DISCARDURB
, aurb
);
337 DPRINTF("husb: async. discard urb failed errno %d\n", errno
);
341 static int usb_host_claim_interfaces(USBHostDevice
*dev
, int configuration
)
343 int dev_descr_len
, config_descr_len
;
344 int interface
, nb_interfaces
;
347 if (configuration
== 0) /* address state - ignore */
350 DPRINTF("husb: claiming interfaces. config %d\n", configuration
);
353 dev_descr_len
= dev
->descr
[0];
354 if (dev_descr_len
> dev
->descr_len
) {
359 while (i
< dev
->descr_len
) {
360 DPRINTF("husb: i is %d, descr_len is %d, dl %d, dt %d\n",
362 dev
->descr
[i
], dev
->descr
[i
+1]);
364 if (dev
->descr
[i
+1] != USB_DT_CONFIG
) {
368 config_descr_len
= dev
->descr
[i
];
370 printf("husb: config #%d need %d\n", dev
->descr
[i
+ 5], configuration
);
372 if (configuration
< 0 || configuration
== dev
->descr
[i
+ 5]) {
373 configuration
= dev
->descr
[i
+ 5];
377 i
+= config_descr_len
;
380 if (i
>= dev
->descr_len
) {
382 "husb: update iface failed. no matching configuration\n");
385 nb_interfaces
= dev
->descr
[i
+ 4];
387 #ifdef USBDEVFS_DISCONNECT
388 /* earlier Linux 2.4 do not support that */
390 struct usbdevfs_ioctl ctrl
;
391 for (interface
= 0; interface
< nb_interfaces
; interface
++) {
392 ctrl
.ioctl_code
= USBDEVFS_DISCONNECT
;
393 ctrl
.ifno
= interface
;
395 ret
= ioctl(dev
->fd
, USBDEVFS_IOCTL
, &ctrl
);
396 if (ret
< 0 && errno
!= ENODATA
) {
397 perror("USBDEVFS_DISCONNECT");
404 /* XXX: only grab if all interfaces are free */
405 for (interface
= 0; interface
< nb_interfaces
; interface
++) {
406 ret
= ioctl(dev
->fd
, USBDEVFS_CLAIMINTERFACE
, &interface
);
408 if (errno
== EBUSY
) {
409 printf("husb: update iface. device already grabbed\n");
411 perror("husb: failed to claim interface");
418 printf("husb: %d interfaces claimed for configuration %d\n",
419 nb_interfaces
, configuration
);
421 dev
->ninterfaces
= nb_interfaces
;
422 dev
->configuration
= configuration
;
426 static int usb_host_release_interfaces(USBHostDevice
*s
)
430 DPRINTF("husb: releasing interfaces\n");
432 for (i
= 0; i
< s
->ninterfaces
; i
++) {
433 ret
= ioctl(s
->fd
, USBDEVFS_RELEASEINTERFACE
, &i
);
435 perror("husb: failed to release interface");
443 static void usb_host_handle_reset(USBDevice
*dev
)
445 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
447 DPRINTF("husb: reset device %u.%u\n", s
->bus_num
, s
->addr
);
449 ioctl(s
->fd
, USBDEVFS_RESET
);
451 usb_host_claim_interfaces(s
, s
->configuration
);
454 static void usb_host_handle_destroy(USBDevice
*dev
)
456 USBHostDevice
*s
= (USBHostDevice
*)dev
;
459 QTAILQ_REMOVE(&hostdevs
, s
, next
);
460 qemu_remove_exit_notifier(&s
->exit
);
463 static int usb_linux_update_endp_table(USBHostDevice
*s
);
465 /* iso data is special, we need to keep enough urbs in flight to make sure
466 that the controller never runs out of them, otherwise the device will
467 likely suffer a buffer underrun / overrun. */
468 static AsyncURB
*usb_host_alloc_iso(USBHostDevice
*s
, uint8_t ep
, int in
)
471 int i
, j
, len
= get_max_packet_size(s
, ep
);
473 aurb
= qemu_mallocz(ISO_URB_COUNT
* sizeof(*aurb
));
474 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
475 aurb
[i
].urb
.endpoint
= ep
;
476 aurb
[i
].urb
.buffer_length
= ISO_FRAME_DESC_PER_URB
* len
;
477 aurb
[i
].urb
.buffer
= qemu_malloc(aurb
[i
].urb
.buffer_length
);
478 aurb
[i
].urb
.type
= USBDEVFS_URB_TYPE_ISO
;
479 aurb
[i
].urb
.flags
= USBDEVFS_URB_ISO_ASAP
;
480 aurb
[i
].urb
.number_of_packets
= ISO_FRAME_DESC_PER_URB
;
481 for (j
= 0 ; j
< ISO_FRAME_DESC_PER_URB
; j
++)
482 aurb
[i
].urb
.iso_frame_desc
[j
].length
= len
;
484 aurb
[i
].urb
.endpoint
|= 0x80;
485 /* Mark as fully consumed (idle) */
486 aurb
[i
].iso_frame_idx
= ISO_FRAME_DESC_PER_URB
;
489 set_iso_urb(s
, ep
, aurb
);
494 static void usb_host_stop_n_free_iso(USBHostDevice
*s
, uint8_t ep
)
497 int i
, ret
, killed
= 0, free
= 1;
499 aurb
= get_iso_urb(s
, ep
);
504 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
506 if (aurb
[i
].iso_frame_idx
== -1) {
507 ret
= ioctl(s
->fd
, USBDEVFS_DISCARDURB
, &aurb
[i
]);
509 printf("husb: discard isoc in urb failed errno %d\n", errno
);
517 /* Make sure any urbs we've killed are reaped before we free them */
522 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
523 qemu_free(aurb
[i
].urb
.buffer
);
529 printf("husb: leaking iso urbs because of discard failure\n");
530 set_iso_urb(s
, ep
, NULL
);
533 static int urb_status_to_usb_ret(int status
)
537 return USB_RET_STALL
;
543 static int usb_host_handle_iso_data(USBHostDevice
*s
, USBPacket
*p
)
546 int i
, j
, ret
, len
= 0;
548 aurb
= get_iso_urb(s
, p
->devep
);
550 aurb
= usb_host_alloc_iso(s
, p
->devep
, 1);
553 i
= get_iso_urb_idx(s
, p
->devep
);
554 j
= aurb
[i
].iso_frame_idx
;
555 if (j
>= 0 && j
< ISO_FRAME_DESC_PER_URB
) {
556 /* Check urb status */
557 if (aurb
[i
].urb
.status
) {
558 len
= urb_status_to_usb_ret(aurb
[i
].urb
.status
);
559 /* Move to the next urb */
560 aurb
[i
].iso_frame_idx
= ISO_FRAME_DESC_PER_URB
- 1;
561 /* Check frame status */
562 } else if (aurb
[i
].urb
.iso_frame_desc
[j
].status
) {
563 len
= urb_status_to_usb_ret(aurb
[i
].urb
.iso_frame_desc
[j
].status
);
564 /* Check the frame fits */
565 } else if (aurb
[i
].urb
.iso_frame_desc
[j
].actual_length
> p
->len
) {
566 printf("husb: error received isoc data is larger then packet\n");
568 /* All good copy data over */
570 len
= aurb
[i
].urb
.iso_frame_desc
[j
].actual_length
;
573 j
* aurb
[i
].urb
.iso_frame_desc
[0].length
,
576 aurb
[i
].iso_frame_idx
++;
577 if (aurb
[i
].iso_frame_idx
== ISO_FRAME_DESC_PER_URB
) {
578 i
= (i
+ 1) % ISO_URB_COUNT
;
579 set_iso_urb_idx(s
, p
->devep
, i
);
583 /* (Re)-submit all fully consumed urbs */
584 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
585 if (aurb
[i
].iso_frame_idx
== ISO_FRAME_DESC_PER_URB
) {
586 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, &aurb
[i
]);
588 printf("husb error submitting isoc urb %d: %d\n", i
, errno
);
600 aurb
[i
].iso_frame_idx
= -1;
607 static int usb_host_handle_data(USBHostDevice
*s
, USBPacket
*p
)
609 struct usbdevfs_urb
*urb
;
614 if (p
->pid
== USB_TOKEN_IN
) {
615 ep
= p
->devep
| 0x80;
620 if (is_halted(s
, p
->devep
)) {
621 ret
= ioctl(s
->fd
, USBDEVFS_CLEAR_HALT
, &ep
);
623 DPRINTF("husb: failed to clear halt. ep 0x%x errno %d\n",
627 clear_halt(s
, p
->devep
);
630 if (is_isoc(s
, p
->devep
) && p
->pid
== USB_TOKEN_IN
)
631 return usb_host_handle_iso_data(s
, p
);
633 aurb
= async_alloc();
640 urb
->buffer
= p
->data
;
641 urb
->buffer_length
= p
->len
;
643 if (is_isoc(s
, p
->devep
)) {
644 /* Setup ISOC transfer */
645 urb
->type
= USBDEVFS_URB_TYPE_ISO
;
646 urb
->flags
= USBDEVFS_URB_ISO_ASAP
;
647 urb
->number_of_packets
= 1;
648 urb
->iso_frame_desc
[0].length
= p
->len
;
650 /* Setup bulk transfer */
651 urb
->type
= USBDEVFS_URB_TYPE_BULK
;
654 urb
->usercontext
= s
;
656 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
658 DPRINTF("husb: data submit. ep 0x%x len %u aurb %p\n",
659 urb
->endpoint
, p
->len
, aurb
);
662 DPRINTF("husb: submit failed. errno %d\n", errno
);
670 return USB_RET_STALL
;
674 usb_defer_packet(p
, async_cancel
, aurb
);
675 return USB_RET_ASYNC
;
678 static int ctrl_error(void)
680 if (errno
== ETIMEDOUT
) {
683 return USB_RET_STALL
;
687 static int usb_host_set_address(USBHostDevice
*s
, int addr
)
689 DPRINTF("husb: ctrl set addr %u\n", addr
);
694 static int usb_host_set_config(USBHostDevice
*s
, int config
)
696 usb_host_release_interfaces(s
);
698 int ret
= ioctl(s
->fd
, USBDEVFS_SETCONFIGURATION
, &config
);
700 DPRINTF("husb: ctrl set config %d ret %d errno %d\n", config
, ret
, errno
);
705 usb_host_claim_interfaces(s
, config
);
709 static int usb_host_set_interface(USBHostDevice
*s
, int iface
, int alt
)
711 struct usbdevfs_setinterface si
;
714 for (i
= 1; i
< MAX_ENDPOINTS
; i
++) {
716 usb_host_stop_n_free_iso(s
, i
);
720 si
.interface
= iface
;
722 ret
= ioctl(s
->fd
, USBDEVFS_SETINTERFACE
, &si
);
724 DPRINTF("husb: ctrl set iface %d altset %d ret %d errno %d\n",
725 iface
, alt
, ret
, errno
);
730 usb_linux_update_endp_table(s
);
734 static int usb_host_handle_control(USBHostDevice
*s
, USBPacket
*p
)
736 struct usbdevfs_urb
*urb
;
738 int ret
, value
, index
;
742 * Process certain standard device requests.
743 * These are infrequent and are processed synchronously.
745 value
= le16_to_cpu(s
->ctrl
.req
.wValue
);
746 index
= le16_to_cpu(s
->ctrl
.req
.wIndex
);
748 DPRINTF("husb: ctrl type 0x%x req 0x%x val 0x%x index %u len %u\n",
749 s
->ctrl
.req
.bRequestType
, s
->ctrl
.req
.bRequest
, value
, index
,
752 if (s
->ctrl
.req
.bRequestType
== 0) {
753 switch (s
->ctrl
.req
.bRequest
) {
754 case USB_REQ_SET_ADDRESS
:
755 return usb_host_set_address(s
, value
);
757 case USB_REQ_SET_CONFIGURATION
:
758 return usb_host_set_config(s
, value
& 0xff);
762 if (s
->ctrl
.req
.bRequestType
== 1 &&
763 s
->ctrl
.req
.bRequest
== USB_REQ_SET_INTERFACE
) {
764 return usb_host_set_interface(s
, index
, value
);
767 /* The rest are asynchronous */
769 buffer_len
= 8 + s
->ctrl
.len
;
770 if (buffer_len
> sizeof(s
->ctrl
.buffer
)) {
771 fprintf(stderr
, "husb: ctrl buffer too small (%u > %zu)\n",
772 buffer_len
, sizeof(s
->ctrl
.buffer
));
773 return USB_RET_STALL
;
776 aurb
= async_alloc();
781 * Setup ctrl transfer.
783 * s->ctrl is laid out such that data buffer immediately follows
784 * 'req' struct which is exactly what usbdevfs expects.
788 urb
->type
= USBDEVFS_URB_TYPE_CONTROL
;
789 urb
->endpoint
= p
->devep
;
791 urb
->buffer
= &s
->ctrl
.req
;
792 urb
->buffer_length
= buffer_len
;
794 urb
->usercontext
= s
;
796 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
798 DPRINTF("husb: submit ctrl. len %u aurb %p\n", urb
->buffer_length
, aurb
);
801 DPRINTF("husb: submit failed. errno %d\n", errno
);
809 return USB_RET_STALL
;
813 usb_defer_packet(p
, async_cancel
, aurb
);
814 return USB_RET_ASYNC
;
817 static int do_token_setup(USBDevice
*dev
, USBPacket
*p
)
819 USBHostDevice
*s
= (USBHostDevice
*) dev
;
823 return USB_RET_STALL
;
826 memcpy(&s
->ctrl
.req
, p
->data
, 8);
827 s
->ctrl
.len
= le16_to_cpu(s
->ctrl
.req
.wLength
);
829 s
->ctrl
.state
= CTRL_STATE_SETUP
;
831 if (s
->ctrl
.req
.bRequestType
& USB_DIR_IN
) {
832 ret
= usb_host_handle_control(s
, p
);
837 if (ret
< s
->ctrl
.len
) {
840 s
->ctrl
.state
= CTRL_STATE_DATA
;
842 if (s
->ctrl
.len
== 0) {
843 s
->ctrl
.state
= CTRL_STATE_ACK
;
845 s
->ctrl
.state
= CTRL_STATE_DATA
;
852 static int do_token_in(USBDevice
*dev
, USBPacket
*p
)
854 USBHostDevice
*s
= (USBHostDevice
*) dev
;
858 return usb_host_handle_data(s
, p
);
861 switch(s
->ctrl
.state
) {
863 if (!(s
->ctrl
.req
.bRequestType
& USB_DIR_IN
)) {
864 ret
= usb_host_handle_control(s
, p
);
865 if (ret
== USB_RET_ASYNC
) {
866 return USB_RET_ASYNC
;
868 s
->ctrl
.state
= CTRL_STATE_IDLE
;
869 return ret
> 0 ? 0 : ret
;
874 case CTRL_STATE_DATA
:
875 if (s
->ctrl
.req
.bRequestType
& USB_DIR_IN
) {
876 int len
= s
->ctrl
.len
- s
->ctrl
.offset
;
880 memcpy(p
->data
, s
->ctrl
.buffer
+ s
->ctrl
.offset
, len
);
881 s
->ctrl
.offset
+= len
;
882 if (s
->ctrl
.offset
>= s
->ctrl
.len
) {
883 s
->ctrl
.state
= CTRL_STATE_ACK
;
888 s
->ctrl
.state
= CTRL_STATE_IDLE
;
889 return USB_RET_STALL
;
892 return USB_RET_STALL
;
896 static int do_token_out(USBDevice
*dev
, USBPacket
*p
)
898 USBHostDevice
*s
= (USBHostDevice
*) dev
;
901 return usb_host_handle_data(s
, p
);
904 switch(s
->ctrl
.state
) {
906 if (s
->ctrl
.req
.bRequestType
& USB_DIR_IN
) {
907 s
->ctrl
.state
= CTRL_STATE_IDLE
;
910 /* ignore additional output */
914 case CTRL_STATE_DATA
:
915 if (!(s
->ctrl
.req
.bRequestType
& USB_DIR_IN
)) {
916 int len
= s
->ctrl
.len
- s
->ctrl
.offset
;
920 memcpy(s
->ctrl
.buffer
+ s
->ctrl
.offset
, p
->data
, len
);
921 s
->ctrl
.offset
+= len
;
922 if (s
->ctrl
.offset
>= s
->ctrl
.len
) {
923 s
->ctrl
.state
= CTRL_STATE_ACK
;
928 s
->ctrl
.state
= CTRL_STATE_IDLE
;
929 return USB_RET_STALL
;
932 return USB_RET_STALL
;
938 * Called by the HC (host controller).
940 * Returns length of the transaction or one of the USB_RET_XXX codes.
942 static int usb_host_handle_packet(USBDevice
*s
, USBPacket
*p
)
946 s
->state
= USB_STATE_ATTACHED
;
950 s
->state
= USB_STATE_NOTATTACHED
;
954 s
->remote_wakeup
= 0;
956 s
->state
= USB_STATE_DEFAULT
;
957 s
->info
->handle_reset(s
);
961 /* Rest of the PIDs must match our address */
962 if (s
->state
< USB_STATE_DEFAULT
|| p
->devaddr
!= s
->addr
) {
963 return USB_RET_NODEV
;
967 case USB_TOKEN_SETUP
:
968 return do_token_setup(s
, p
);
971 return do_token_in(s
, p
);
974 return do_token_out(s
, p
);
977 return USB_RET_STALL
;
981 static int usb_linux_get_configuration(USBHostDevice
*s
)
983 uint8_t configuration
;
984 struct usb_ctrltransfer ct
;
987 if (usb_fs_type
== USB_FS_SYS
) {
988 char device_name
[32], line
[1024];
991 sprintf(device_name
, "%d-%d", s
->bus_num
, s
->devpath
);
993 if (!usb_host_read_file(line
, sizeof(line
), "bConfigurationValue",
997 if (sscanf(line
, "%d", &configuration
) != 1) {
1000 return configuration
;
1004 ct
.bRequestType
= USB_DIR_IN
;
1005 ct
.bRequest
= USB_REQ_GET_CONFIGURATION
;
1009 ct
.data
= &configuration
;
1012 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
1014 perror("usb_linux_get_configuration");
1018 /* in address state */
1019 if (configuration
== 0) {
1023 return configuration
;
1026 static uint8_t usb_linux_get_alt_setting(USBHostDevice
*s
,
1027 uint8_t configuration
, uint8_t interface
)
1029 uint8_t alt_setting
;
1030 struct usb_ctrltransfer ct
;
1033 if (usb_fs_type
== USB_FS_SYS
) {
1034 char device_name
[64], line
[1024];
1037 sprintf(device_name
, "%d-%d:%d.%d", s
->bus_num
, s
->devpath
,
1038 (int)configuration
, (int)interface
);
1040 if (!usb_host_read_file(line
, sizeof(line
), "bAlternateSetting",
1044 if (sscanf(line
, "%d", &alt_setting
) != 1) {
1051 ct
.bRequestType
= USB_DIR_IN
| USB_RECIP_INTERFACE
;
1052 ct
.bRequest
= USB_REQ_GET_INTERFACE
;
1054 ct
.wIndex
= interface
;
1056 ct
.data
= &alt_setting
;
1058 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
1060 /* Assume alt 0 on error */
1067 /* returns 1 on problem encountered or 0 for success */
1068 static int usb_linux_update_endp_table(USBHostDevice
*s
)
1070 uint8_t *descriptors
;
1071 uint8_t devep
, type
, configuration
, alt_interface
;
1072 int interface
, length
, i
;
1074 i
= usb_linux_get_configuration(s
);
1079 /* get the desired configuration, interface, and endpoint descriptors
1080 * from device description */
1081 descriptors
= &s
->descr
[18];
1082 length
= s
->descr_len
- 18;
1085 if (descriptors
[i
+ 1] != USB_DT_CONFIG
||
1086 descriptors
[i
+ 5] != configuration
) {
1087 DPRINTF("invalid descriptor data - configuration\n");
1090 i
+= descriptors
[i
];
1092 while (i
< length
) {
1093 if (descriptors
[i
+ 1] != USB_DT_INTERFACE
||
1094 (descriptors
[i
+ 1] == USB_DT_INTERFACE
&&
1095 descriptors
[i
+ 4] == 0)) {
1096 i
+= descriptors
[i
];
1100 interface
= descriptors
[i
+ 2];
1101 alt_interface
= usb_linux_get_alt_setting(s
, configuration
, interface
);
1103 /* the current interface descriptor is the active interface
1104 * and has endpoints */
1105 if (descriptors
[i
+ 3] != alt_interface
) {
1106 i
+= descriptors
[i
];
1110 /* advance to the endpoints */
1111 while (i
< length
&& descriptors
[i
+1] != USB_DT_ENDPOINT
) {
1112 i
+= descriptors
[i
];
1118 while (i
< length
) {
1119 if (descriptors
[i
+ 1] != USB_DT_ENDPOINT
) {
1123 devep
= descriptors
[i
+ 2];
1124 switch (descriptors
[i
+ 3] & 0x3) {
1126 type
= USBDEVFS_URB_TYPE_CONTROL
;
1129 type
= USBDEVFS_URB_TYPE_ISO
;
1130 s
->endp_table
[(devep
& 0xf) - 1].max_packet_size
=
1131 descriptors
[i
+ 4] + (descriptors
[i
+ 5] << 8);
1134 type
= USBDEVFS_URB_TYPE_BULK
;
1137 type
= USBDEVFS_URB_TYPE_INTERRUPT
;
1140 DPRINTF("usb_host: malformed endpoint type\n");
1141 type
= USBDEVFS_URB_TYPE_BULK
;
1143 s
->endp_table
[(devep
& 0xf) - 1].type
= type
;
1144 s
->endp_table
[(devep
& 0xf) - 1].halted
= 0;
1146 i
+= descriptors
[i
];
1152 static int usb_host_open(USBHostDevice
*dev
, int bus_num
,
1153 int addr
, int devpath
, const char *prod_name
)
1156 struct usbdevfs_connectinfo ci
;
1159 if (dev
->fd
!= -1) {
1162 printf("husb: open device %d.%d\n", bus_num
, addr
);
1164 if (!usb_host_device_path
) {
1165 perror("husb: USB Host Device Path not set");
1168 snprintf(buf
, sizeof(buf
), "%s/%03d/%03d", usb_host_device_path
,
1170 fd
= open(buf
, O_RDWR
| O_NONBLOCK
);
1175 DPRINTF("husb: opened %s\n", buf
);
1177 dev
->bus_num
= bus_num
;
1179 dev
->devpath
= devpath
;
1182 /* read the device description */
1183 dev
->descr_len
= read(fd
, dev
->descr
, sizeof(dev
->descr
));
1184 if (dev
->descr_len
<= 0) {
1185 perror("husb: reading device data failed");
1192 printf("=== begin dumping device descriptor data ===\n");
1193 for (x
= 0; x
< dev
->descr_len
; x
++) {
1194 printf("%02x ", dev
->descr
[x
]);
1196 printf("\n=== end dumping device descriptor data ===\n");
1202 * Initial configuration is -1 which makes us claim first
1203 * available config. We used to start with 1, which does not
1204 * always work. I've seen devices where first config starts
1207 if (!usb_host_claim_interfaces(dev
, -1)) {
1211 ret
= ioctl(fd
, USBDEVFS_CONNECTINFO
, &ci
);
1213 perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
1217 printf("husb: grabbed usb device %d.%d\n", bus_num
, addr
);
1219 ret
= usb_linux_update_endp_table(dev
);
1225 dev
->dev
.speed
= USB_SPEED_LOW
;
1227 dev
->dev
.speed
= USB_SPEED_HIGH
;
1230 if (!prod_name
|| prod_name
[0] == '\0') {
1231 snprintf(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1232 "host:%d.%d", bus_num
, addr
);
1234 pstrcpy(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1238 /* USB devio uses 'write' flag to check for async completions */
1239 qemu_set_fd_handler(dev
->fd
, NULL
, async_complete
, dev
);
1241 usb_device_attach(&dev
->dev
);
1252 static int usb_host_close(USBHostDevice
*dev
)
1256 if (dev
->fd
== -1) {
1260 qemu_set_fd_handler(dev
->fd
, NULL
, NULL
, NULL
);
1262 for (i
= 1; i
< MAX_ENDPOINTS
; i
++) {
1263 if (is_isoc(dev
, i
)) {
1264 usb_host_stop_n_free_iso(dev
, i
);
1267 async_complete(dev
);
1269 usb_device_detach(&dev
->dev
);
1270 ioctl(dev
->fd
, USBDEVFS_RESET
);
1276 static void usb_host_exit_notifier(struct Notifier
* n
)
1278 USBHostDevice
*s
= container_of(n
, USBHostDevice
, exit
);
1281 ioctl(s
->fd
, USBDEVFS_RESET
);
1285 static int usb_host_initfn(USBDevice
*dev
)
1287 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
1289 dev
->auto_attach
= 0;
1291 QTAILQ_INSERT_TAIL(&hostdevs
, s
, next
);
1292 s
->exit
.notify
= usb_host_exit_notifier
;
1293 qemu_add_exit_notifier(&s
->exit
);
1294 usb_host_auto_check(NULL
);
1298 static struct USBDeviceInfo usb_host_dev_info
= {
1299 .product_desc
= "USB Host Device",
1300 .qdev
.name
= "usb-host",
1301 .qdev
.size
= sizeof(USBHostDevice
),
1302 .init
= usb_host_initfn
,
1303 .handle_packet
= usb_host_handle_packet
,
1304 .handle_reset
= usb_host_handle_reset
,
1305 .handle_destroy
= usb_host_handle_destroy
,
1306 .usbdevice_name
= "host",
1307 .usbdevice_init
= usb_host_device_open
,
1308 .qdev
.props
= (Property
[]) {
1309 DEFINE_PROP_UINT32("hostbus", USBHostDevice
, match
.bus_num
, 0),
1310 DEFINE_PROP_UINT32("hostaddr", USBHostDevice
, match
.addr
, 0),
1311 DEFINE_PROP_HEX32("vendorid", USBHostDevice
, match
.vendor_id
, 0),
1312 DEFINE_PROP_HEX32("productid", USBHostDevice
, match
.product_id
, 0),
1313 DEFINE_PROP_END_OF_LIST(),
1317 static void usb_host_register_devices(void)
1319 usb_qdev_register(&usb_host_dev_info
);
1321 device_init(usb_host_register_devices
)
1323 USBDevice
*usb_host_device_open(const char *devname
)
1325 struct USBAutoFilter filter
;
1329 dev
= usb_create(NULL
/* FIXME */, "usb-host");
1331 if (strstr(devname
, "auto:")) {
1332 if (parse_filter(devname
, &filter
) < 0) {
1336 if ((p
= strchr(devname
, '.'))) {
1337 filter
.bus_num
= strtoul(devname
, NULL
, 0);
1338 filter
.addr
= strtoul(p
+ 1, NULL
, 0);
1339 filter
.vendor_id
= 0;
1340 filter
.product_id
= 0;
1341 } else if ((p
= strchr(devname
, ':'))) {
1344 filter
.vendor_id
= strtoul(devname
, NULL
, 16);
1345 filter
.product_id
= strtoul(p
+ 1, NULL
, 16);
1351 qdev_prop_set_uint32(&dev
->qdev
, "hostbus", filter
.bus_num
);
1352 qdev_prop_set_uint32(&dev
->qdev
, "hostaddr", filter
.addr
);
1353 qdev_prop_set_uint32(&dev
->qdev
, "vendorid", filter
.vendor_id
);
1354 qdev_prop_set_uint32(&dev
->qdev
, "productid", filter
.product_id
);
1355 qdev_init_nofail(&dev
->qdev
);
1359 qdev_free(&dev
->qdev
);
1363 int usb_host_device_close(const char *devname
)
1366 char product_name
[PRODUCT_NAME_SZ
];
1370 if (strstr(devname
, "auto:")) {
1371 return usb_host_auto_del(devname
);
1373 if (usb_host_find_device(&bus_num
, &addr
, product_name
,
1374 sizeof(product_name
), devname
) < 0) {
1377 s
= hostdev_find(bus_num
, addr
);
1379 usb_device_delete_addr(s
->bus_num
, s
->dev
.addr
);
1387 static int get_tag_value(char *buf
, int buf_size
,
1388 const char *str
, const char *tag
,
1389 const char *stopchars
)
1393 p
= strstr(str
, tag
);
1398 while (qemu_isspace(*p
)) {
1402 while (*p
!= '\0' && !strchr(stopchars
, *p
)) {
1403 if ((q
- buf
) < (buf_size
- 1)) {
1413 * Use /proc/bus/usb/devices or /dev/bus/usb/devices file to determine
1414 * host's USB devices. This is legacy support since many distributions
1415 * are moving to /sys/bus/usb
1417 static int usb_host_scan_dev(void *opaque
, USBScanFunc
*func
)
1422 int bus_num
, addr
, speed
, device_count
, class_id
, product_id
, vendor_id
;
1423 char product_name
[512];
1426 if (!usb_host_device_path
) {
1427 perror("husb: USB Host Device Path not set");
1430 snprintf(line
, sizeof(line
), "%s/devices", usb_host_device_path
);
1431 f
= fopen(line
, "r");
1433 perror("husb: cannot open devices file");
1438 bus_num
= addr
= speed
= class_id
= product_id
= vendor_id
= 0;
1440 if (fgets(line
, sizeof(line
), f
) == NULL
) {
1443 if (strlen(line
) > 0) {
1444 line
[strlen(line
) - 1] = '\0';
1446 if (line
[0] == 'T' && line
[1] == ':') {
1447 if (device_count
&& (vendor_id
|| product_id
)) {
1448 /* New device. Add the previously discovered device. */
1449 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1450 product_id
, product_name
, speed
);
1455 if (get_tag_value(buf
, sizeof(buf
), line
, "Bus=", " ") < 0) {
1458 bus_num
= atoi(buf
);
1459 if (get_tag_value(buf
, sizeof(buf
), line
, "Dev#=", " ") < 0) {
1463 if (get_tag_value(buf
, sizeof(buf
), line
, "Spd=", " ") < 0) {
1466 if (!strcmp(buf
, "480")) {
1467 speed
= USB_SPEED_HIGH
;
1468 } else if (!strcmp(buf
, "1.5")) {
1469 speed
= USB_SPEED_LOW
;
1471 speed
= USB_SPEED_FULL
;
1473 product_name
[0] = '\0';
1478 } else if (line
[0] == 'P' && line
[1] == ':') {
1479 if (get_tag_value(buf
, sizeof(buf
), line
, "Vendor=", " ") < 0) {
1482 vendor_id
= strtoul(buf
, NULL
, 16);
1483 if (get_tag_value(buf
, sizeof(buf
), line
, "ProdID=", " ") < 0) {
1486 product_id
= strtoul(buf
, NULL
, 16);
1487 } else if (line
[0] == 'S' && line
[1] == ':') {
1488 if (get_tag_value(buf
, sizeof(buf
), line
, "Product=", "") < 0) {
1491 pstrcpy(product_name
, sizeof(product_name
), buf
);
1492 } else if (line
[0] == 'D' && line
[1] == ':') {
1493 if (get_tag_value(buf
, sizeof(buf
), line
, "Cls=", " (") < 0) {
1496 class_id
= strtoul(buf
, NULL
, 16);
1500 if (device_count
&& (vendor_id
|| product_id
)) {
1501 /* Add the last device. */
1502 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1503 product_id
, product_name
, speed
);
1513 * Read sys file-system device file
1515 * @line address of buffer to put file contents in
1516 * @line_size size of line
1517 * @device_file path to device file (printf format string)
1518 * @device_name device being opened (inserted into device_file)
1520 * @return 0 failed, 1 succeeded ('line' contains data)
1522 static int usb_host_read_file(char *line
, size_t line_size
,
1523 const char *device_file
, const char *device_name
)
1527 char filename
[PATH_MAX
];
1529 snprintf(filename
, PATH_MAX
, USBSYSBUS_PATH
"/devices/%s/%s", device_name
,
1531 f
= fopen(filename
, "r");
1533 ret
= fgets(line
, line_size
, f
) != NULL
;
1541 * Use /sys/bus/usb/devices/ directory to determine host's USB
1544 * This code is based on Robert Schiele's original patches posted to
1545 * the Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
1547 static int usb_host_scan_sys(void *opaque
, USBScanFunc
*func
)
1551 int bus_num
, addr
, devpath
, speed
, class_id
, product_id
, vendor_id
;
1553 char product_name
[512];
1556 dir
= opendir(USBSYSBUS_PATH
"/devices");
1558 perror("husb: cannot open devices directory");
1562 while ((de
= readdir(dir
))) {
1563 if (de
->d_name
[0] != '.' && !strchr(de
->d_name
, ':')) {
1564 char *tmpstr
= de
->d_name
;
1565 if (!strncmp(de
->d_name
, "usb", 3)) {
1568 if (sscanf(tmpstr
, "%d-%d", &bus_num
, &devpath
) < 1) {
1572 if (!usb_host_read_file(line
, sizeof(line
), "devnum", de
->d_name
)) {
1575 if (sscanf(line
, "%d", &addr
) != 1) {
1578 if (!usb_host_read_file(line
, sizeof(line
), "bDeviceClass",
1582 if (sscanf(line
, "%x", &class_id
) != 1) {
1586 if (!usb_host_read_file(line
, sizeof(line
), "idVendor",
1590 if (sscanf(line
, "%x", &vendor_id
) != 1) {
1593 if (!usb_host_read_file(line
, sizeof(line
), "idProduct",
1597 if (sscanf(line
, "%x", &product_id
) != 1) {
1600 if (!usb_host_read_file(line
, sizeof(line
), "product",
1604 if (strlen(line
) > 0) {
1605 line
[strlen(line
) - 1] = '\0';
1607 pstrcpy(product_name
, sizeof(product_name
), line
);
1610 if (!usb_host_read_file(line
, sizeof(line
), "speed", de
->d_name
)) {
1613 if (!strcmp(line
, "480\n")) {
1614 speed
= USB_SPEED_HIGH
;
1615 } else if (!strcmp(line
, "1.5\n")) {
1616 speed
= USB_SPEED_LOW
;
1618 speed
= USB_SPEED_FULL
;
1621 ret
= func(opaque
, bus_num
, addr
, devpath
, class_id
, vendor_id
,
1622 product_id
, product_name
, speed
);
1636 * Determine how to access the host's USB devices and call the
1637 * specific support function.
1639 static int usb_host_scan(void *opaque
, USBScanFunc
*func
)
1641 Monitor
*mon
= cur_mon
;
1645 const char *fs_type
[] = {"unknown", "proc", "dev", "sys"};
1646 char devpath
[PATH_MAX
];
1648 /* only check the host once */
1650 dir
= opendir(USBSYSBUS_PATH
"/devices");
1652 /* devices found in /dev/bus/usb/ (yes - not a mistake!) */
1653 strcpy(devpath
, USBDEVBUS_PATH
);
1654 usb_fs_type
= USB_FS_SYS
;
1656 DPRINTF(USBDBG_DEVOPENED
, USBSYSBUS_PATH
);
1659 f
= fopen(USBPROCBUS_PATH
"/devices", "r");
1661 /* devices found in /proc/bus/usb/ */
1662 strcpy(devpath
, USBPROCBUS_PATH
);
1663 usb_fs_type
= USB_FS_PROC
;
1665 DPRINTF(USBDBG_DEVOPENED
, USBPROCBUS_PATH
);
1668 /* try additional methods if an access method hasn't been found yet */
1669 f
= fopen(USBDEVBUS_PATH
"/devices", "r");
1671 /* devices found in /dev/bus/usb/ */
1672 strcpy(devpath
, USBDEVBUS_PATH
);
1673 usb_fs_type
= USB_FS_DEV
;
1675 DPRINTF(USBDBG_DEVOPENED
, USBDEVBUS_PATH
);
1681 monitor_printf(mon
, "husb: unable to access USB devices\n");
1686 /* the module setting (used later for opening devices) */
1687 usb_host_device_path
= qemu_mallocz(strlen(devpath
)+1);
1688 strcpy(usb_host_device_path
, devpath
);
1690 monitor_printf(mon
, "husb: using %s file-system with %s\n",
1691 fs_type
[usb_fs_type
], usb_host_device_path
);
1695 switch (usb_fs_type
) {
1698 ret
= usb_host_scan_dev(opaque
, func
);
1701 ret
= usb_host_scan_sys(opaque
, func
);
1710 static QEMUTimer
*usb_auto_timer
;
1712 static int usb_host_auto_scan(void *opaque
, int bus_num
, int addr
, int devpath
,
1713 int class_id
, int vendor_id
, int product_id
,
1714 const char *product_name
, int speed
)
1716 struct USBAutoFilter
*f
;
1717 struct USBHostDevice
*s
;
1723 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1726 if (f
->bus_num
> 0 && f
->bus_num
!= bus_num
) {
1729 if (f
->addr
> 0 && f
->addr
!= addr
) {
1733 if (f
->vendor_id
> 0 && f
->vendor_id
!= vendor_id
) {
1737 if (f
->product_id
> 0 && f
->product_id
!= product_id
) {
1740 /* We got a match */
1742 /* Already attached ? */
1746 DPRINTF("husb: auto open: bus_num %d addr %d\n", bus_num
, addr
);
1748 usb_host_open(s
, bus_num
, addr
, devpath
, product_name
);
1754 static void usb_host_auto_check(void *unused
)
1756 struct USBHostDevice
*s
;
1757 int unconnected
= 0;
1759 usb_host_scan(NULL
, usb_host_auto_scan
);
1761 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1767 if (unconnected
== 0) {
1768 /* nothing to watch */
1769 if (usb_auto_timer
) {
1770 qemu_del_timer(usb_auto_timer
);
1775 if (!usb_auto_timer
) {
1776 usb_auto_timer
= qemu_new_timer_ms(rt_clock
, usb_host_auto_check
, NULL
);
1777 if (!usb_auto_timer
) {
1781 qemu_mod_timer(usb_auto_timer
, qemu_get_clock_ms(rt_clock
) + 2000);
1785 * Autoconnect filter
1787 * auto:bus:dev[:vid:pid]
1788 * auto:bus.dev[:vid:pid]
1790 * bus - bus number (dec, * means any)
1791 * dev - device number (dec, * means any)
1792 * vid - vendor id (hex, * means any)
1793 * pid - product id (hex, * means any)
1795 * See 'lsusb' output.
1797 static int parse_filter(const char *spec
, struct USBAutoFilter
*f
)
1799 enum { BUS
, DEV
, VID
, PID
, DONE
};
1800 const char *p
= spec
;
1808 for (i
= BUS
; i
< DONE
; i
++) {
1809 p
= strpbrk(p
, ":.");
1819 case BUS
: f
->bus_num
= strtol(p
, NULL
, 10); break;
1820 case DEV
: f
->addr
= strtol(p
, NULL
, 10); break;
1821 case VID
: f
->vendor_id
= strtol(p
, NULL
, 16); break;
1822 case PID
: f
->product_id
= strtol(p
, NULL
, 16); break;
1827 fprintf(stderr
, "husb: invalid auto filter spec %s\n", spec
);
1834 /**********************/
1835 /* USB host device info */
1837 struct usb_class_info
{
1839 const char *class_name
;
1842 static const struct usb_class_info usb_class_info
[] = {
1843 { USB_CLASS_AUDIO
, "Audio"},
1844 { USB_CLASS_COMM
, "Communication"},
1845 { USB_CLASS_HID
, "HID"},
1846 { USB_CLASS_HUB
, "Hub" },
1847 { USB_CLASS_PHYSICAL
, "Physical" },
1848 { USB_CLASS_PRINTER
, "Printer" },
1849 { USB_CLASS_MASS_STORAGE
, "Storage" },
1850 { USB_CLASS_CDC_DATA
, "Data" },
1851 { USB_CLASS_APP_SPEC
, "Application Specific" },
1852 { USB_CLASS_VENDOR_SPEC
, "Vendor Specific" },
1853 { USB_CLASS_STILL_IMAGE
, "Still Image" },
1854 { USB_CLASS_CSCID
, "Smart Card" },
1855 { USB_CLASS_CONTENT_SEC
, "Content Security" },
1859 static const char *usb_class_str(uint8_t class)
1861 const struct usb_class_info
*p
;
1862 for(p
= usb_class_info
; p
->class != -1; p
++) {
1863 if (p
->class == class) {
1867 return p
->class_name
;
1870 static void usb_info_device(Monitor
*mon
, int bus_num
, int addr
, int class_id
,
1871 int vendor_id
, int product_id
,
1872 const char *product_name
,
1875 const char *class_str
, *speed_str
;
1881 case USB_SPEED_FULL
:
1884 case USB_SPEED_HIGH
:
1892 monitor_printf(mon
, " Device %d.%d, speed %s Mb/s\n",
1893 bus_num
, addr
, speed_str
);
1894 class_str
= usb_class_str(class_id
);
1896 monitor_printf(mon
, " %s:", class_str
);
1898 monitor_printf(mon
, " Class %02x:", class_id
);
1900 monitor_printf(mon
, " USB device %04x:%04x", vendor_id
, product_id
);
1901 if (product_name
[0] != '\0') {
1902 monitor_printf(mon
, ", %s", product_name
);
1904 monitor_printf(mon
, "\n");
1907 static int usb_host_info_device(void *opaque
, int bus_num
, int addr
,
1908 int devpath
, int class_id
,
1909 int vendor_id
, int product_id
,
1910 const char *product_name
,
1913 Monitor
*mon
= opaque
;
1915 usb_info_device(mon
, bus_num
, addr
, class_id
, vendor_id
, product_id
,
1916 product_name
, speed
);
1920 static void dec2str(int val
, char *str
, size_t size
)
1923 snprintf(str
, size
, "*");
1925 snprintf(str
, size
, "%d", val
);
1929 static void hex2str(int val
, char *str
, size_t size
)
1932 snprintf(str
, size
, "*");
1934 snprintf(str
, size
, "%04x", val
);
1938 void usb_host_info(Monitor
*mon
)
1940 struct USBAutoFilter
*f
;
1941 struct USBHostDevice
*s
;
1943 usb_host_scan(mon
, usb_host_info_device
);
1945 if (QTAILQ_EMPTY(&hostdevs
)) {
1949 monitor_printf(mon
, " Auto filters:\n");
1950 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1951 char bus
[10], addr
[10], vid
[10], pid
[10];
1953 dec2str(f
->bus_num
, bus
, sizeof(bus
));
1954 dec2str(f
->addr
, addr
, sizeof(addr
));
1955 hex2str(f
->vendor_id
, vid
, sizeof(vid
));
1956 hex2str(f
->product_id
, pid
, sizeof(pid
));
1957 monitor_printf(mon
, " Device %s.%s ID %s:%s\n",
1958 bus
, addr
, vid
, pid
);