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
97 #define INVALID_EP_TYPE 255
99 typedef struct AsyncURB AsyncURB
;
117 * Control transfer state.
118 * Note that 'buffer' _must_ follow 'req' field because
119 * we need contiguous buffer when we submit control URB.
125 struct usb_ctrlrequest req
;
126 uint8_t buffer
[8192];
129 struct USBAutoFilter
{
136 typedef struct USBHostDevice
{
147 struct ctrl_struct ctrl
;
148 struct endp_data endp_table
[MAX_ENDPOINTS
];
150 /* Host side address */
154 struct USBAutoFilter match
;
156 QTAILQ_ENTRY(USBHostDevice
) next
;
159 static QTAILQ_HEAD(, USBHostDevice
) hostdevs
= QTAILQ_HEAD_INITIALIZER(hostdevs
);
161 static int usb_host_close(USBHostDevice
*dev
);
162 static int parse_filter(const char *spec
, struct USBAutoFilter
*f
);
163 static void usb_host_auto_check(void *unused
);
164 static int usb_host_read_file(char *line
, size_t line_size
,
165 const char *device_file
, const char *device_name
);
167 static int is_isoc(USBHostDevice
*s
, int ep
)
169 return s
->endp_table
[ep
- 1].type
== USBDEVFS_URB_TYPE_ISO
;
172 static int is_valid(USBHostDevice
*s
, int ep
)
174 return s
->endp_table
[ep
- 1].type
!= INVALID_EP_TYPE
;
177 static int is_halted(USBHostDevice
*s
, int ep
)
179 return s
->endp_table
[ep
- 1].halted
;
182 static void clear_halt(USBHostDevice
*s
, int ep
)
184 s
->endp_table
[ep
- 1].halted
= 0;
187 static void set_halt(USBHostDevice
*s
, int ep
)
189 s
->endp_table
[ep
- 1].halted
= 1;
192 static void set_iso_urb(USBHostDevice
*s
, int ep
, AsyncURB
*iso_urb
)
194 s
->endp_table
[ep
- 1].iso_urb
= iso_urb
;
197 static AsyncURB
*get_iso_urb(USBHostDevice
*s
, int ep
)
199 return s
->endp_table
[ep
- 1].iso_urb
;
202 static void set_iso_urb_idx(USBHostDevice
*s
, int ep
, int i
)
204 s
->endp_table
[ep
- 1].iso_urb_idx
= i
;
207 static int get_iso_urb_idx(USBHostDevice
*s
, int ep
)
209 return s
->endp_table
[ep
- 1].iso_urb_idx
;
212 static int get_max_packet_size(USBHostDevice
*s
, int ep
)
214 return s
->endp_table
[ep
- 1].max_packet_size
;
219 * We always allocate iso packet descriptors even for bulk transfers
220 * to simplify allocation and casts.
224 struct usbdevfs_urb urb
;
225 struct usbdevfs_iso_packet_desc isocpd
[ISO_FRAME_DESC_PER_URB
];
227 /* For regular async urbs */
231 /* For buffered iso handling */
232 int iso_frame_idx
; /* -1 means in flight */
235 static AsyncURB
*async_alloc(void)
237 return (AsyncURB
*) qemu_mallocz(sizeof(AsyncURB
));
240 static void async_free(AsyncURB
*aurb
)
245 static void async_complete_ctrl(USBHostDevice
*s
, USBPacket
*p
)
247 switch(s
->ctrl
.state
) {
248 case CTRL_STATE_SETUP
:
249 if (p
->len
< s
->ctrl
.len
)
250 s
->ctrl
.len
= p
->len
;
251 s
->ctrl
.state
= CTRL_STATE_DATA
;
256 s
->ctrl
.state
= CTRL_STATE_IDLE
;
265 static void async_complete(void *opaque
)
267 USBHostDevice
*s
= opaque
;
273 int r
= ioctl(s
->fd
, USBDEVFS_REAPURBNDELAY
, &aurb
);
275 if (errno
== EAGAIN
) {
278 if (errno
== ENODEV
&& !s
->closing
) {
279 printf("husb: device %d.%d disconnected\n",
280 s
->bus_num
, s
->addr
);
282 usb_host_auto_check(NULL
);
286 DPRINTF("husb: async. reap urb failed errno %d\n", errno
);
290 DPRINTF("husb: async completed. aurb %p status %d alen %d\n",
291 aurb
, aurb
->urb
.status
, aurb
->urb
.actual_length
);
293 /* If this is a buffered iso urb mark it as complete and don't do
294 anything else (it is handled further in usb_host_handle_iso_data) */
295 if (aurb
->iso_frame_idx
== -1) {
296 if (aurb
->urb
.status
== -EPIPE
) {
297 set_halt(s
, aurb
->urb
.endpoint
& 0xf);
299 aurb
->iso_frame_idx
= 0;
306 switch (aurb
->urb
.status
) {
308 p
->len
= aurb
->urb
.actual_length
;
309 if (aurb
->urb
.type
== USBDEVFS_URB_TYPE_CONTROL
) {
310 async_complete_ctrl(s
, p
);
315 set_halt(s
, p
->devep
);
316 p
->len
= USB_RET_STALL
;
320 p
->len
= USB_RET_NAK
;
324 usb_packet_complete(p
);
331 static void async_cancel(USBPacket
*unused
, void *opaque
)
333 AsyncURB
*aurb
= opaque
;
334 USBHostDevice
*s
= aurb
->hdev
;
336 DPRINTF("husb: async cancel. aurb %p\n", aurb
);
338 /* Mark it as dead (see async_complete above) */
341 int r
= ioctl(s
->fd
, USBDEVFS_DISCARDURB
, aurb
);
343 DPRINTF("husb: async. discard urb failed errno %d\n", errno
);
347 static int usb_host_claim_interfaces(USBHostDevice
*dev
, int configuration
)
349 int dev_descr_len
, config_descr_len
;
350 int interface
, nb_interfaces
;
353 if (configuration
== 0) /* address state - ignore */
356 DPRINTF("husb: claiming interfaces. config %d\n", configuration
);
359 dev_descr_len
= dev
->descr
[0];
360 if (dev_descr_len
> dev
->descr_len
) {
365 while (i
< dev
->descr_len
) {
366 DPRINTF("husb: i is %d, descr_len is %d, dl %d, dt %d\n",
368 dev
->descr
[i
], dev
->descr
[i
+1]);
370 if (dev
->descr
[i
+1] != USB_DT_CONFIG
) {
374 config_descr_len
= dev
->descr
[i
];
376 printf("husb: config #%d need %d\n", dev
->descr
[i
+ 5], configuration
);
378 if (configuration
< 0 || configuration
== dev
->descr
[i
+ 5]) {
379 configuration
= dev
->descr
[i
+ 5];
383 i
+= config_descr_len
;
386 if (i
>= dev
->descr_len
) {
388 "husb: update iface failed. no matching configuration\n");
391 nb_interfaces
= dev
->descr
[i
+ 4];
393 #ifdef USBDEVFS_DISCONNECT
394 /* earlier Linux 2.4 do not support that */
396 struct usbdevfs_ioctl ctrl
;
397 for (interface
= 0; interface
< nb_interfaces
; interface
++) {
398 ctrl
.ioctl_code
= USBDEVFS_DISCONNECT
;
399 ctrl
.ifno
= interface
;
401 ret
= ioctl(dev
->fd
, USBDEVFS_IOCTL
, &ctrl
);
402 if (ret
< 0 && errno
!= ENODATA
) {
403 perror("USBDEVFS_DISCONNECT");
410 /* XXX: only grab if all interfaces are free */
411 for (interface
= 0; interface
< nb_interfaces
; interface
++) {
412 ret
= ioctl(dev
->fd
, USBDEVFS_CLAIMINTERFACE
, &interface
);
414 if (errno
== EBUSY
) {
415 printf("husb: update iface. device already grabbed\n");
417 perror("husb: failed to claim interface");
424 printf("husb: %d interfaces claimed for configuration %d\n",
425 nb_interfaces
, configuration
);
427 dev
->ninterfaces
= nb_interfaces
;
428 dev
->configuration
= configuration
;
432 static int usb_host_release_interfaces(USBHostDevice
*s
)
436 DPRINTF("husb: releasing interfaces\n");
438 for (i
= 0; i
< s
->ninterfaces
; i
++) {
439 ret
= ioctl(s
->fd
, USBDEVFS_RELEASEINTERFACE
, &i
);
441 perror("husb: failed to release interface");
449 static void usb_host_handle_reset(USBDevice
*dev
)
451 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
453 DPRINTF("husb: reset device %u.%u\n", s
->bus_num
, s
->addr
);
455 ioctl(s
->fd
, USBDEVFS_RESET
);
457 usb_host_claim_interfaces(s
, s
->configuration
);
460 static void usb_host_handle_destroy(USBDevice
*dev
)
462 USBHostDevice
*s
= (USBHostDevice
*)dev
;
465 QTAILQ_REMOVE(&hostdevs
, s
, next
);
466 qemu_remove_exit_notifier(&s
->exit
);
469 static int usb_linux_update_endp_table(USBHostDevice
*s
);
471 /* iso data is special, we need to keep enough urbs in flight to make sure
472 that the controller never runs out of them, otherwise the device will
473 likely suffer a buffer underrun / overrun. */
474 static AsyncURB
*usb_host_alloc_iso(USBHostDevice
*s
, uint8_t ep
, int in
)
477 int i
, j
, len
= get_max_packet_size(s
, ep
);
479 aurb
= qemu_mallocz(ISO_URB_COUNT
* sizeof(*aurb
));
480 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
481 aurb
[i
].urb
.endpoint
= ep
;
482 aurb
[i
].urb
.buffer_length
= ISO_FRAME_DESC_PER_URB
* len
;
483 aurb
[i
].urb
.buffer
= qemu_malloc(aurb
[i
].urb
.buffer_length
);
484 aurb
[i
].urb
.type
= USBDEVFS_URB_TYPE_ISO
;
485 aurb
[i
].urb
.flags
= USBDEVFS_URB_ISO_ASAP
;
486 aurb
[i
].urb
.number_of_packets
= ISO_FRAME_DESC_PER_URB
;
487 for (j
= 0 ; j
< ISO_FRAME_DESC_PER_URB
; j
++)
488 aurb
[i
].urb
.iso_frame_desc
[j
].length
= len
;
490 aurb
[i
].urb
.endpoint
|= 0x80;
491 /* Mark as fully consumed (idle) */
492 aurb
[i
].iso_frame_idx
= ISO_FRAME_DESC_PER_URB
;
495 set_iso_urb(s
, ep
, aurb
);
500 static void usb_host_stop_n_free_iso(USBHostDevice
*s
, uint8_t ep
)
503 int i
, ret
, killed
= 0, free
= 1;
505 aurb
= get_iso_urb(s
, ep
);
510 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
512 if (aurb
[i
].iso_frame_idx
== -1) {
513 ret
= ioctl(s
->fd
, USBDEVFS_DISCARDURB
, &aurb
[i
]);
515 printf("husb: discard isoc in urb failed errno %d\n", errno
);
523 /* Make sure any urbs we've killed are reaped before we free them */
528 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
529 qemu_free(aurb
[i
].urb
.buffer
);
535 printf("husb: leaking iso urbs because of discard failure\n");
536 set_iso_urb(s
, ep
, NULL
);
539 static int urb_status_to_usb_ret(int status
)
543 return USB_RET_STALL
;
549 static int usb_host_handle_iso_data(USBHostDevice
*s
, USBPacket
*p
)
552 int i
, j
, ret
, len
= 0;
554 aurb
= get_iso_urb(s
, p
->devep
);
556 aurb
= usb_host_alloc_iso(s
, p
->devep
, 1);
559 i
= get_iso_urb_idx(s
, p
->devep
);
560 j
= aurb
[i
].iso_frame_idx
;
561 if (j
>= 0 && j
< ISO_FRAME_DESC_PER_URB
) {
562 /* Check urb status */
563 if (aurb
[i
].urb
.status
) {
564 len
= urb_status_to_usb_ret(aurb
[i
].urb
.status
);
565 /* Move to the next urb */
566 aurb
[i
].iso_frame_idx
= ISO_FRAME_DESC_PER_URB
- 1;
567 /* Check frame status */
568 } else if (aurb
[i
].urb
.iso_frame_desc
[j
].status
) {
569 len
= urb_status_to_usb_ret(aurb
[i
].urb
.iso_frame_desc
[j
].status
);
570 /* Check the frame fits */
571 } else if (aurb
[i
].urb
.iso_frame_desc
[j
].actual_length
> p
->len
) {
572 printf("husb: error received isoc data is larger then packet\n");
574 /* All good copy data over */
576 len
= aurb
[i
].urb
.iso_frame_desc
[j
].actual_length
;
579 j
* aurb
[i
].urb
.iso_frame_desc
[0].length
,
582 aurb
[i
].iso_frame_idx
++;
583 if (aurb
[i
].iso_frame_idx
== ISO_FRAME_DESC_PER_URB
) {
584 i
= (i
+ 1) % ISO_URB_COUNT
;
585 set_iso_urb_idx(s
, p
->devep
, i
);
589 /* (Re)-submit all fully consumed urbs */
590 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
591 if (aurb
[i
].iso_frame_idx
== ISO_FRAME_DESC_PER_URB
) {
592 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, &aurb
[i
]);
594 printf("husb error submitting isoc urb %d: %d\n", i
, errno
);
606 aurb
[i
].iso_frame_idx
= -1;
613 static int usb_host_handle_data(USBHostDevice
*s
, USBPacket
*p
)
615 struct usbdevfs_urb
*urb
;
620 if (!is_valid(s
, p
->devep
)) {
624 if (p
->pid
== USB_TOKEN_IN
) {
625 ep
= p
->devep
| 0x80;
630 if (is_halted(s
, p
->devep
)) {
631 ret
= ioctl(s
->fd
, USBDEVFS_CLEAR_HALT
, &ep
);
633 DPRINTF("husb: failed to clear halt. ep 0x%x errno %d\n",
637 clear_halt(s
, p
->devep
);
640 if (is_isoc(s
, p
->devep
) && p
->pid
== USB_TOKEN_IN
)
641 return usb_host_handle_iso_data(s
, p
);
643 aurb
= async_alloc();
650 urb
->buffer
= p
->data
;
651 urb
->buffer_length
= p
->len
;
653 if (is_isoc(s
, p
->devep
)) {
654 /* Setup ISOC transfer */
655 urb
->type
= USBDEVFS_URB_TYPE_ISO
;
656 urb
->flags
= USBDEVFS_URB_ISO_ASAP
;
657 urb
->number_of_packets
= 1;
658 urb
->iso_frame_desc
[0].length
= p
->len
;
660 /* Setup bulk transfer */
661 urb
->type
= USBDEVFS_URB_TYPE_BULK
;
664 urb
->usercontext
= s
;
666 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
668 DPRINTF("husb: data submit. ep 0x%x len %u aurb %p\n",
669 urb
->endpoint
, p
->len
, aurb
);
672 DPRINTF("husb: submit failed. errno %d\n", errno
);
680 return USB_RET_STALL
;
684 usb_defer_packet(p
, async_cancel
, aurb
);
685 return USB_RET_ASYNC
;
688 static int ctrl_error(void)
690 if (errno
== ETIMEDOUT
) {
693 return USB_RET_STALL
;
697 static int usb_host_set_address(USBHostDevice
*s
, int addr
)
699 DPRINTF("husb: ctrl set addr %u\n", addr
);
704 static int usb_host_set_config(USBHostDevice
*s
, int config
)
706 usb_host_release_interfaces(s
);
708 int ret
= ioctl(s
->fd
, USBDEVFS_SETCONFIGURATION
, &config
);
710 DPRINTF("husb: ctrl set config %d ret %d errno %d\n", config
, ret
, errno
);
715 usb_host_claim_interfaces(s
, config
);
719 static int usb_host_set_interface(USBHostDevice
*s
, int iface
, int alt
)
721 struct usbdevfs_setinterface si
;
724 for (i
= 1; i
< MAX_ENDPOINTS
; i
++) {
726 usb_host_stop_n_free_iso(s
, i
);
730 si
.interface
= iface
;
732 ret
= ioctl(s
->fd
, USBDEVFS_SETINTERFACE
, &si
);
734 DPRINTF("husb: ctrl set iface %d altset %d ret %d errno %d\n",
735 iface
, alt
, ret
, errno
);
740 usb_linux_update_endp_table(s
);
744 static int usb_host_handle_control(USBHostDevice
*s
, USBPacket
*p
)
746 struct usbdevfs_urb
*urb
;
748 int ret
, value
, index
;
752 * Process certain standard device requests.
753 * These are infrequent and are processed synchronously.
755 value
= le16_to_cpu(s
->ctrl
.req
.wValue
);
756 index
= le16_to_cpu(s
->ctrl
.req
.wIndex
);
758 DPRINTF("husb: ctrl type 0x%x req 0x%x val 0x%x index %u len %u\n",
759 s
->ctrl
.req
.bRequestType
, s
->ctrl
.req
.bRequest
, value
, index
,
762 if (s
->ctrl
.req
.bRequestType
== 0) {
763 switch (s
->ctrl
.req
.bRequest
) {
764 case USB_REQ_SET_ADDRESS
:
765 return usb_host_set_address(s
, value
);
767 case USB_REQ_SET_CONFIGURATION
:
768 return usb_host_set_config(s
, value
& 0xff);
772 if (s
->ctrl
.req
.bRequestType
== 1 &&
773 s
->ctrl
.req
.bRequest
== USB_REQ_SET_INTERFACE
) {
774 return usb_host_set_interface(s
, index
, value
);
777 /* The rest are asynchronous */
779 buffer_len
= 8 + s
->ctrl
.len
;
780 if (buffer_len
> sizeof(s
->ctrl
.buffer
)) {
781 fprintf(stderr
, "husb: ctrl buffer too small (%u > %zu)\n",
782 buffer_len
, sizeof(s
->ctrl
.buffer
));
783 return USB_RET_STALL
;
786 aurb
= async_alloc();
791 * Setup ctrl transfer.
793 * s->ctrl is laid out such that data buffer immediately follows
794 * 'req' struct which is exactly what usbdevfs expects.
798 urb
->type
= USBDEVFS_URB_TYPE_CONTROL
;
799 urb
->endpoint
= p
->devep
;
801 urb
->buffer
= &s
->ctrl
.req
;
802 urb
->buffer_length
= buffer_len
;
804 urb
->usercontext
= s
;
806 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
808 DPRINTF("husb: submit ctrl. len %u aurb %p\n", urb
->buffer_length
, aurb
);
811 DPRINTF("husb: submit failed. errno %d\n", errno
);
819 return USB_RET_STALL
;
823 usb_defer_packet(p
, async_cancel
, aurb
);
824 return USB_RET_ASYNC
;
827 static int do_token_setup(USBDevice
*dev
, USBPacket
*p
)
829 USBHostDevice
*s
= (USBHostDevice
*) dev
;
833 return USB_RET_STALL
;
836 memcpy(&s
->ctrl
.req
, p
->data
, 8);
837 s
->ctrl
.len
= le16_to_cpu(s
->ctrl
.req
.wLength
);
839 s
->ctrl
.state
= CTRL_STATE_SETUP
;
841 if (s
->ctrl
.req
.bRequestType
& USB_DIR_IN
) {
842 ret
= usb_host_handle_control(s
, p
);
847 if (ret
< s
->ctrl
.len
) {
850 s
->ctrl
.state
= CTRL_STATE_DATA
;
852 if (s
->ctrl
.len
== 0) {
853 s
->ctrl
.state
= CTRL_STATE_ACK
;
855 s
->ctrl
.state
= CTRL_STATE_DATA
;
862 static int do_token_in(USBDevice
*dev
, USBPacket
*p
)
864 USBHostDevice
*s
= (USBHostDevice
*) dev
;
868 return usb_host_handle_data(s
, p
);
871 switch(s
->ctrl
.state
) {
873 if (!(s
->ctrl
.req
.bRequestType
& USB_DIR_IN
)) {
874 ret
= usb_host_handle_control(s
, p
);
875 if (ret
== USB_RET_ASYNC
) {
876 return USB_RET_ASYNC
;
878 s
->ctrl
.state
= CTRL_STATE_IDLE
;
879 return ret
> 0 ? 0 : ret
;
884 case CTRL_STATE_DATA
:
885 if (s
->ctrl
.req
.bRequestType
& USB_DIR_IN
) {
886 int len
= s
->ctrl
.len
- s
->ctrl
.offset
;
890 memcpy(p
->data
, s
->ctrl
.buffer
+ s
->ctrl
.offset
, len
);
891 s
->ctrl
.offset
+= len
;
892 if (s
->ctrl
.offset
>= s
->ctrl
.len
) {
893 s
->ctrl
.state
= CTRL_STATE_ACK
;
898 s
->ctrl
.state
= CTRL_STATE_IDLE
;
899 return USB_RET_STALL
;
902 return USB_RET_STALL
;
906 static int do_token_out(USBDevice
*dev
, USBPacket
*p
)
908 USBHostDevice
*s
= (USBHostDevice
*) dev
;
911 return usb_host_handle_data(s
, p
);
914 switch(s
->ctrl
.state
) {
916 if (s
->ctrl
.req
.bRequestType
& USB_DIR_IN
) {
917 s
->ctrl
.state
= CTRL_STATE_IDLE
;
920 /* ignore additional output */
924 case CTRL_STATE_DATA
:
925 if (!(s
->ctrl
.req
.bRequestType
& USB_DIR_IN
)) {
926 int len
= s
->ctrl
.len
- s
->ctrl
.offset
;
930 memcpy(s
->ctrl
.buffer
+ s
->ctrl
.offset
, p
->data
, len
);
931 s
->ctrl
.offset
+= len
;
932 if (s
->ctrl
.offset
>= s
->ctrl
.len
) {
933 s
->ctrl
.state
= CTRL_STATE_ACK
;
938 s
->ctrl
.state
= CTRL_STATE_IDLE
;
939 return USB_RET_STALL
;
942 return USB_RET_STALL
;
948 * Called by the HC (host controller).
950 * Returns length of the transaction or one of the USB_RET_XXX codes.
952 static int usb_host_handle_packet(USBDevice
*s
, USBPacket
*p
)
956 s
->state
= USB_STATE_ATTACHED
;
960 s
->state
= USB_STATE_NOTATTACHED
;
964 s
->remote_wakeup
= 0;
966 s
->state
= USB_STATE_DEFAULT
;
967 s
->info
->handle_reset(s
);
971 /* Rest of the PIDs must match our address */
972 if (s
->state
< USB_STATE_DEFAULT
|| p
->devaddr
!= s
->addr
) {
973 return USB_RET_NODEV
;
977 case USB_TOKEN_SETUP
:
978 return do_token_setup(s
, p
);
981 return do_token_in(s
, p
);
984 return do_token_out(s
, p
);
987 return USB_RET_STALL
;
991 static int usb_linux_get_configuration(USBHostDevice
*s
)
993 uint8_t configuration
;
994 struct usb_ctrltransfer ct
;
997 if (usb_fs_type
== USB_FS_SYS
) {
998 char device_name
[32], line
[1024];
1001 sprintf(device_name
, "%d-%d", s
->bus_num
, s
->devpath
);
1003 if (!usb_host_read_file(line
, sizeof(line
), "bConfigurationValue",
1007 if (sscanf(line
, "%d", &configuration
) != 1) {
1010 return configuration
;
1014 ct
.bRequestType
= USB_DIR_IN
;
1015 ct
.bRequest
= USB_REQ_GET_CONFIGURATION
;
1019 ct
.data
= &configuration
;
1022 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
1024 perror("usb_linux_get_configuration");
1028 /* in address state */
1029 if (configuration
== 0) {
1033 return configuration
;
1036 static uint8_t usb_linux_get_alt_setting(USBHostDevice
*s
,
1037 uint8_t configuration
, uint8_t interface
)
1039 uint8_t alt_setting
;
1040 struct usb_ctrltransfer ct
;
1043 if (usb_fs_type
== USB_FS_SYS
) {
1044 char device_name
[64], line
[1024];
1047 sprintf(device_name
, "%d-%d:%d.%d", s
->bus_num
, s
->devpath
,
1048 (int)configuration
, (int)interface
);
1050 if (!usb_host_read_file(line
, sizeof(line
), "bAlternateSetting",
1054 if (sscanf(line
, "%d", &alt_setting
) != 1) {
1061 ct
.bRequestType
= USB_DIR_IN
| USB_RECIP_INTERFACE
;
1062 ct
.bRequest
= USB_REQ_GET_INTERFACE
;
1064 ct
.wIndex
= interface
;
1066 ct
.data
= &alt_setting
;
1068 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
1070 /* Assume alt 0 on error */
1077 /* returns 1 on problem encountered or 0 for success */
1078 static int usb_linux_update_endp_table(USBHostDevice
*s
)
1080 uint8_t *descriptors
;
1081 uint8_t devep
, type
, configuration
, alt_interface
;
1082 int interface
, length
, i
;
1084 for (i
= 0; i
< MAX_ENDPOINTS
; i
++)
1085 s
->endp_table
[i
].type
= INVALID_EP_TYPE
;
1087 i
= usb_linux_get_configuration(s
);
1092 /* get the desired configuration, interface, and endpoint descriptors
1093 * from device description */
1094 descriptors
= &s
->descr
[18];
1095 length
= s
->descr_len
- 18;
1098 if (descriptors
[i
+ 1] != USB_DT_CONFIG
||
1099 descriptors
[i
+ 5] != configuration
) {
1100 DPRINTF("invalid descriptor data - configuration\n");
1103 i
+= descriptors
[i
];
1105 while (i
< length
) {
1106 if (descriptors
[i
+ 1] != USB_DT_INTERFACE
||
1107 (descriptors
[i
+ 1] == USB_DT_INTERFACE
&&
1108 descriptors
[i
+ 4] == 0)) {
1109 i
+= descriptors
[i
];
1113 interface
= descriptors
[i
+ 2];
1114 alt_interface
= usb_linux_get_alt_setting(s
, configuration
, interface
);
1116 /* the current interface descriptor is the active interface
1117 * and has endpoints */
1118 if (descriptors
[i
+ 3] != alt_interface
) {
1119 i
+= descriptors
[i
];
1123 /* advance to the endpoints */
1124 while (i
< length
&& descriptors
[i
+1] != USB_DT_ENDPOINT
) {
1125 i
+= descriptors
[i
];
1131 while (i
< length
) {
1132 if (descriptors
[i
+ 1] != USB_DT_ENDPOINT
) {
1136 devep
= descriptors
[i
+ 2];
1137 switch (descriptors
[i
+ 3] & 0x3) {
1139 type
= USBDEVFS_URB_TYPE_CONTROL
;
1142 type
= USBDEVFS_URB_TYPE_ISO
;
1143 s
->endp_table
[(devep
& 0xf) - 1].max_packet_size
=
1144 descriptors
[i
+ 4] + (descriptors
[i
+ 5] << 8);
1147 type
= USBDEVFS_URB_TYPE_BULK
;
1150 type
= USBDEVFS_URB_TYPE_INTERRUPT
;
1153 DPRINTF("usb_host: malformed endpoint type\n");
1154 type
= USBDEVFS_URB_TYPE_BULK
;
1156 s
->endp_table
[(devep
& 0xf) - 1].type
= type
;
1157 s
->endp_table
[(devep
& 0xf) - 1].halted
= 0;
1159 i
+= descriptors
[i
];
1165 static int usb_host_open(USBHostDevice
*dev
, int bus_num
,
1166 int addr
, int devpath
, const char *prod_name
)
1169 struct usbdevfs_connectinfo ci
;
1172 if (dev
->fd
!= -1) {
1175 printf("husb: open device %d.%d\n", bus_num
, addr
);
1177 if (!usb_host_device_path
) {
1178 perror("husb: USB Host Device Path not set");
1181 snprintf(buf
, sizeof(buf
), "%s/%03d/%03d", usb_host_device_path
,
1183 fd
= open(buf
, O_RDWR
| O_NONBLOCK
);
1188 DPRINTF("husb: opened %s\n", buf
);
1190 dev
->bus_num
= bus_num
;
1192 dev
->devpath
= devpath
;
1195 /* read the device description */
1196 dev
->descr_len
= read(fd
, dev
->descr
, sizeof(dev
->descr
));
1197 if (dev
->descr_len
<= 0) {
1198 perror("husb: reading device data failed");
1205 printf("=== begin dumping device descriptor data ===\n");
1206 for (x
= 0; x
< dev
->descr_len
; x
++) {
1207 printf("%02x ", dev
->descr
[x
]);
1209 printf("\n=== end dumping device descriptor data ===\n");
1215 * Initial configuration is -1 which makes us claim first
1216 * available config. We used to start with 1, which does not
1217 * always work. I've seen devices where first config starts
1220 if (!usb_host_claim_interfaces(dev
, -1)) {
1224 ret
= ioctl(fd
, USBDEVFS_CONNECTINFO
, &ci
);
1226 perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
1230 printf("husb: grabbed usb device %d.%d\n", bus_num
, addr
);
1232 ret
= usb_linux_update_endp_table(dev
);
1238 dev
->dev
.speed
= USB_SPEED_LOW
;
1240 dev
->dev
.speed
= USB_SPEED_HIGH
;
1243 if (!prod_name
|| prod_name
[0] == '\0') {
1244 snprintf(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1245 "host:%d.%d", bus_num
, addr
);
1247 pstrcpy(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1251 /* USB devio uses 'write' flag to check for async completions */
1252 qemu_set_fd_handler(dev
->fd
, NULL
, async_complete
, dev
);
1254 usb_device_attach(&dev
->dev
);
1265 static int usb_host_close(USBHostDevice
*dev
)
1269 if (dev
->fd
== -1) {
1273 qemu_set_fd_handler(dev
->fd
, NULL
, NULL
, NULL
);
1275 for (i
= 1; i
< MAX_ENDPOINTS
; i
++) {
1276 if (is_isoc(dev
, i
)) {
1277 usb_host_stop_n_free_iso(dev
, i
);
1280 async_complete(dev
);
1282 usb_device_detach(&dev
->dev
);
1283 ioctl(dev
->fd
, USBDEVFS_RESET
);
1289 static void usb_host_exit_notifier(struct Notifier
* n
)
1291 USBHostDevice
*s
= container_of(n
, USBHostDevice
, exit
);
1294 ioctl(s
->fd
, USBDEVFS_RESET
);
1298 static int usb_host_initfn(USBDevice
*dev
)
1300 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
1302 dev
->auto_attach
= 0;
1304 QTAILQ_INSERT_TAIL(&hostdevs
, s
, next
);
1305 s
->exit
.notify
= usb_host_exit_notifier
;
1306 qemu_add_exit_notifier(&s
->exit
);
1307 usb_host_auto_check(NULL
);
1311 static struct USBDeviceInfo usb_host_dev_info
= {
1312 .product_desc
= "USB Host Device",
1313 .qdev
.name
= "usb-host",
1314 .qdev
.size
= sizeof(USBHostDevice
),
1315 .init
= usb_host_initfn
,
1316 .handle_packet
= usb_host_handle_packet
,
1317 .handle_reset
= usb_host_handle_reset
,
1318 .handle_destroy
= usb_host_handle_destroy
,
1319 .usbdevice_name
= "host",
1320 .usbdevice_init
= usb_host_device_open
,
1321 .qdev
.props
= (Property
[]) {
1322 DEFINE_PROP_UINT32("hostbus", USBHostDevice
, match
.bus_num
, 0),
1323 DEFINE_PROP_UINT32("hostaddr", USBHostDevice
, match
.addr
, 0),
1324 DEFINE_PROP_HEX32("vendorid", USBHostDevice
, match
.vendor_id
, 0),
1325 DEFINE_PROP_HEX32("productid", USBHostDevice
, match
.product_id
, 0),
1326 DEFINE_PROP_END_OF_LIST(),
1330 static void usb_host_register_devices(void)
1332 usb_qdev_register(&usb_host_dev_info
);
1334 device_init(usb_host_register_devices
)
1336 USBDevice
*usb_host_device_open(const char *devname
)
1338 struct USBAutoFilter filter
;
1342 dev
= usb_create(NULL
/* FIXME */, "usb-host");
1344 if (strstr(devname
, "auto:")) {
1345 if (parse_filter(devname
, &filter
) < 0) {
1349 if ((p
= strchr(devname
, '.'))) {
1350 filter
.bus_num
= strtoul(devname
, NULL
, 0);
1351 filter
.addr
= strtoul(p
+ 1, NULL
, 0);
1352 filter
.vendor_id
= 0;
1353 filter
.product_id
= 0;
1354 } else if ((p
= strchr(devname
, ':'))) {
1357 filter
.vendor_id
= strtoul(devname
, NULL
, 16);
1358 filter
.product_id
= strtoul(p
+ 1, NULL
, 16);
1364 qdev_prop_set_uint32(&dev
->qdev
, "hostbus", filter
.bus_num
);
1365 qdev_prop_set_uint32(&dev
->qdev
, "hostaddr", filter
.addr
);
1366 qdev_prop_set_uint32(&dev
->qdev
, "vendorid", filter
.vendor_id
);
1367 qdev_prop_set_uint32(&dev
->qdev
, "productid", filter
.product_id
);
1368 qdev_init_nofail(&dev
->qdev
);
1372 qdev_free(&dev
->qdev
);
1376 int usb_host_device_close(const char *devname
)
1379 char product_name
[PRODUCT_NAME_SZ
];
1383 if (strstr(devname
, "auto:")) {
1384 return usb_host_auto_del(devname
);
1386 if (usb_host_find_device(&bus_num
, &addr
, product_name
,
1387 sizeof(product_name
), devname
) < 0) {
1390 s
= hostdev_find(bus_num
, addr
);
1392 usb_device_delete_addr(s
->bus_num
, s
->dev
.addr
);
1400 static int get_tag_value(char *buf
, int buf_size
,
1401 const char *str
, const char *tag
,
1402 const char *stopchars
)
1406 p
= strstr(str
, tag
);
1411 while (qemu_isspace(*p
)) {
1415 while (*p
!= '\0' && !strchr(stopchars
, *p
)) {
1416 if ((q
- buf
) < (buf_size
- 1)) {
1426 * Use /proc/bus/usb/devices or /dev/bus/usb/devices file to determine
1427 * host's USB devices. This is legacy support since many distributions
1428 * are moving to /sys/bus/usb
1430 static int usb_host_scan_dev(void *opaque
, USBScanFunc
*func
)
1435 int bus_num
, addr
, speed
, device_count
, class_id
, product_id
, vendor_id
;
1436 char product_name
[512];
1439 if (!usb_host_device_path
) {
1440 perror("husb: USB Host Device Path not set");
1443 snprintf(line
, sizeof(line
), "%s/devices", usb_host_device_path
);
1444 f
= fopen(line
, "r");
1446 perror("husb: cannot open devices file");
1451 bus_num
= addr
= speed
= class_id
= product_id
= vendor_id
= 0;
1453 if (fgets(line
, sizeof(line
), f
) == NULL
) {
1456 if (strlen(line
) > 0) {
1457 line
[strlen(line
) - 1] = '\0';
1459 if (line
[0] == 'T' && line
[1] == ':') {
1460 if (device_count
&& (vendor_id
|| product_id
)) {
1461 /* New device. Add the previously discovered device. */
1462 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1463 product_id
, product_name
, speed
);
1468 if (get_tag_value(buf
, sizeof(buf
), line
, "Bus=", " ") < 0) {
1471 bus_num
= atoi(buf
);
1472 if (get_tag_value(buf
, sizeof(buf
), line
, "Dev#=", " ") < 0) {
1476 if (get_tag_value(buf
, sizeof(buf
), line
, "Spd=", " ") < 0) {
1479 if (!strcmp(buf
, "480")) {
1480 speed
= USB_SPEED_HIGH
;
1481 } else if (!strcmp(buf
, "1.5")) {
1482 speed
= USB_SPEED_LOW
;
1484 speed
= USB_SPEED_FULL
;
1486 product_name
[0] = '\0';
1491 } else if (line
[0] == 'P' && line
[1] == ':') {
1492 if (get_tag_value(buf
, sizeof(buf
), line
, "Vendor=", " ") < 0) {
1495 vendor_id
= strtoul(buf
, NULL
, 16);
1496 if (get_tag_value(buf
, sizeof(buf
), line
, "ProdID=", " ") < 0) {
1499 product_id
= strtoul(buf
, NULL
, 16);
1500 } else if (line
[0] == 'S' && line
[1] == ':') {
1501 if (get_tag_value(buf
, sizeof(buf
), line
, "Product=", "") < 0) {
1504 pstrcpy(product_name
, sizeof(product_name
), buf
);
1505 } else if (line
[0] == 'D' && line
[1] == ':') {
1506 if (get_tag_value(buf
, sizeof(buf
), line
, "Cls=", " (") < 0) {
1509 class_id
= strtoul(buf
, NULL
, 16);
1513 if (device_count
&& (vendor_id
|| product_id
)) {
1514 /* Add the last device. */
1515 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1516 product_id
, product_name
, speed
);
1526 * Read sys file-system device file
1528 * @line address of buffer to put file contents in
1529 * @line_size size of line
1530 * @device_file path to device file (printf format string)
1531 * @device_name device being opened (inserted into device_file)
1533 * @return 0 failed, 1 succeeded ('line' contains data)
1535 static int usb_host_read_file(char *line
, size_t line_size
,
1536 const char *device_file
, const char *device_name
)
1540 char filename
[PATH_MAX
];
1542 snprintf(filename
, PATH_MAX
, USBSYSBUS_PATH
"/devices/%s/%s", device_name
,
1544 f
= fopen(filename
, "r");
1546 ret
= fgets(line
, line_size
, f
) != NULL
;
1554 * Use /sys/bus/usb/devices/ directory to determine host's USB
1557 * This code is based on Robert Schiele's original patches posted to
1558 * the Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
1560 static int usb_host_scan_sys(void *opaque
, USBScanFunc
*func
)
1564 int bus_num
, addr
, devpath
, speed
, class_id
, product_id
, vendor_id
;
1566 char product_name
[512];
1569 dir
= opendir(USBSYSBUS_PATH
"/devices");
1571 perror("husb: cannot open devices directory");
1575 while ((de
= readdir(dir
))) {
1576 if (de
->d_name
[0] != '.' && !strchr(de
->d_name
, ':')) {
1577 char *tmpstr
= de
->d_name
;
1578 if (!strncmp(de
->d_name
, "usb", 3)) {
1581 if (sscanf(tmpstr
, "%d-%d", &bus_num
, &devpath
) < 1) {
1585 if (!usb_host_read_file(line
, sizeof(line
), "devnum", de
->d_name
)) {
1588 if (sscanf(line
, "%d", &addr
) != 1) {
1591 if (!usb_host_read_file(line
, sizeof(line
), "bDeviceClass",
1595 if (sscanf(line
, "%x", &class_id
) != 1) {
1599 if (!usb_host_read_file(line
, sizeof(line
), "idVendor",
1603 if (sscanf(line
, "%x", &vendor_id
) != 1) {
1606 if (!usb_host_read_file(line
, sizeof(line
), "idProduct",
1610 if (sscanf(line
, "%x", &product_id
) != 1) {
1613 if (!usb_host_read_file(line
, sizeof(line
), "product",
1617 if (strlen(line
) > 0) {
1618 line
[strlen(line
) - 1] = '\0';
1620 pstrcpy(product_name
, sizeof(product_name
), line
);
1623 if (!usb_host_read_file(line
, sizeof(line
), "speed", de
->d_name
)) {
1626 if (!strcmp(line
, "480\n")) {
1627 speed
= USB_SPEED_HIGH
;
1628 } else if (!strcmp(line
, "1.5\n")) {
1629 speed
= USB_SPEED_LOW
;
1631 speed
= USB_SPEED_FULL
;
1634 ret
= func(opaque
, bus_num
, addr
, devpath
, class_id
, vendor_id
,
1635 product_id
, product_name
, speed
);
1649 * Determine how to access the host's USB devices and call the
1650 * specific support function.
1652 static int usb_host_scan(void *opaque
, USBScanFunc
*func
)
1654 Monitor
*mon
= cur_mon
;
1658 const char *fs_type
[] = {"unknown", "proc", "dev", "sys"};
1659 char devpath
[PATH_MAX
];
1661 /* only check the host once */
1663 dir
= opendir(USBSYSBUS_PATH
"/devices");
1665 /* devices found in /dev/bus/usb/ (yes - not a mistake!) */
1666 strcpy(devpath
, USBDEVBUS_PATH
);
1667 usb_fs_type
= USB_FS_SYS
;
1669 DPRINTF(USBDBG_DEVOPENED
, USBSYSBUS_PATH
);
1672 f
= fopen(USBPROCBUS_PATH
"/devices", "r");
1674 /* devices found in /proc/bus/usb/ */
1675 strcpy(devpath
, USBPROCBUS_PATH
);
1676 usb_fs_type
= USB_FS_PROC
;
1678 DPRINTF(USBDBG_DEVOPENED
, USBPROCBUS_PATH
);
1681 /* try additional methods if an access method hasn't been found yet */
1682 f
= fopen(USBDEVBUS_PATH
"/devices", "r");
1684 /* devices found in /dev/bus/usb/ */
1685 strcpy(devpath
, USBDEVBUS_PATH
);
1686 usb_fs_type
= USB_FS_DEV
;
1688 DPRINTF(USBDBG_DEVOPENED
, USBDEVBUS_PATH
);
1694 monitor_printf(mon
, "husb: unable to access USB devices\n");
1699 /* the module setting (used later for opening devices) */
1700 usb_host_device_path
= qemu_mallocz(strlen(devpath
)+1);
1701 strcpy(usb_host_device_path
, devpath
);
1703 monitor_printf(mon
, "husb: using %s file-system with %s\n",
1704 fs_type
[usb_fs_type
], usb_host_device_path
);
1708 switch (usb_fs_type
) {
1711 ret
= usb_host_scan_dev(opaque
, func
);
1714 ret
= usb_host_scan_sys(opaque
, func
);
1723 static QEMUTimer
*usb_auto_timer
;
1725 static int usb_host_auto_scan(void *opaque
, int bus_num
, int addr
, int devpath
,
1726 int class_id
, int vendor_id
, int product_id
,
1727 const char *product_name
, int speed
)
1729 struct USBAutoFilter
*f
;
1730 struct USBHostDevice
*s
;
1736 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1739 if (f
->bus_num
> 0 && f
->bus_num
!= bus_num
) {
1742 if (f
->addr
> 0 && f
->addr
!= addr
) {
1746 if (f
->vendor_id
> 0 && f
->vendor_id
!= vendor_id
) {
1750 if (f
->product_id
> 0 && f
->product_id
!= product_id
) {
1753 /* We got a match */
1755 /* Already attached ? */
1759 DPRINTF("husb: auto open: bus_num %d addr %d\n", bus_num
, addr
);
1761 usb_host_open(s
, bus_num
, addr
, devpath
, product_name
);
1767 static void usb_host_auto_check(void *unused
)
1769 struct USBHostDevice
*s
;
1770 int unconnected
= 0;
1772 usb_host_scan(NULL
, usb_host_auto_scan
);
1774 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1780 if (unconnected
== 0) {
1781 /* nothing to watch */
1782 if (usb_auto_timer
) {
1783 qemu_del_timer(usb_auto_timer
);
1788 if (!usb_auto_timer
) {
1789 usb_auto_timer
= qemu_new_timer_ms(rt_clock
, usb_host_auto_check
, NULL
);
1790 if (!usb_auto_timer
) {
1794 qemu_mod_timer(usb_auto_timer
, qemu_get_clock_ms(rt_clock
) + 2000);
1798 * Autoconnect filter
1800 * auto:bus:dev[:vid:pid]
1801 * auto:bus.dev[:vid:pid]
1803 * bus - bus number (dec, * means any)
1804 * dev - device number (dec, * means any)
1805 * vid - vendor id (hex, * means any)
1806 * pid - product id (hex, * means any)
1808 * See 'lsusb' output.
1810 static int parse_filter(const char *spec
, struct USBAutoFilter
*f
)
1812 enum { BUS
, DEV
, VID
, PID
, DONE
};
1813 const char *p
= spec
;
1821 for (i
= BUS
; i
< DONE
; i
++) {
1822 p
= strpbrk(p
, ":.");
1832 case BUS
: f
->bus_num
= strtol(p
, NULL
, 10); break;
1833 case DEV
: f
->addr
= strtol(p
, NULL
, 10); break;
1834 case VID
: f
->vendor_id
= strtol(p
, NULL
, 16); break;
1835 case PID
: f
->product_id
= strtol(p
, NULL
, 16); break;
1840 fprintf(stderr
, "husb: invalid auto filter spec %s\n", spec
);
1847 /**********************/
1848 /* USB host device info */
1850 struct usb_class_info
{
1852 const char *class_name
;
1855 static const struct usb_class_info usb_class_info
[] = {
1856 { USB_CLASS_AUDIO
, "Audio"},
1857 { USB_CLASS_COMM
, "Communication"},
1858 { USB_CLASS_HID
, "HID"},
1859 { USB_CLASS_HUB
, "Hub" },
1860 { USB_CLASS_PHYSICAL
, "Physical" },
1861 { USB_CLASS_PRINTER
, "Printer" },
1862 { USB_CLASS_MASS_STORAGE
, "Storage" },
1863 { USB_CLASS_CDC_DATA
, "Data" },
1864 { USB_CLASS_APP_SPEC
, "Application Specific" },
1865 { USB_CLASS_VENDOR_SPEC
, "Vendor Specific" },
1866 { USB_CLASS_STILL_IMAGE
, "Still Image" },
1867 { USB_CLASS_CSCID
, "Smart Card" },
1868 { USB_CLASS_CONTENT_SEC
, "Content Security" },
1872 static const char *usb_class_str(uint8_t class)
1874 const struct usb_class_info
*p
;
1875 for(p
= usb_class_info
; p
->class != -1; p
++) {
1876 if (p
->class == class) {
1880 return p
->class_name
;
1883 static void usb_info_device(Monitor
*mon
, int bus_num
, int addr
, int class_id
,
1884 int vendor_id
, int product_id
,
1885 const char *product_name
,
1888 const char *class_str
, *speed_str
;
1894 case USB_SPEED_FULL
:
1897 case USB_SPEED_HIGH
:
1905 monitor_printf(mon
, " Device %d.%d, speed %s Mb/s\n",
1906 bus_num
, addr
, speed_str
);
1907 class_str
= usb_class_str(class_id
);
1909 monitor_printf(mon
, " %s:", class_str
);
1911 monitor_printf(mon
, " Class %02x:", class_id
);
1913 monitor_printf(mon
, " USB device %04x:%04x", vendor_id
, product_id
);
1914 if (product_name
[0] != '\0') {
1915 monitor_printf(mon
, ", %s", product_name
);
1917 monitor_printf(mon
, "\n");
1920 static int usb_host_info_device(void *opaque
, int bus_num
, int addr
,
1921 int devpath
, int class_id
,
1922 int vendor_id
, int product_id
,
1923 const char *product_name
,
1926 Monitor
*mon
= opaque
;
1928 usb_info_device(mon
, bus_num
, addr
, class_id
, vendor_id
, product_id
,
1929 product_name
, speed
);
1933 static void dec2str(int val
, char *str
, size_t size
)
1936 snprintf(str
, size
, "*");
1938 snprintf(str
, size
, "%d", val
);
1942 static void hex2str(int val
, char *str
, size_t size
)
1945 snprintf(str
, size
, "*");
1947 snprintf(str
, size
, "%04x", val
);
1951 void usb_host_info(Monitor
*mon
)
1953 struct USBAutoFilter
*f
;
1954 struct USBHostDevice
*s
;
1956 usb_host_scan(mon
, usb_host_info_device
);
1958 if (QTAILQ_EMPTY(&hostdevs
)) {
1962 monitor_printf(mon
, " Auto filters:\n");
1963 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1964 char bus
[10], addr
[10], vid
[10], pid
[10];
1966 dec2str(f
->bus_num
, bus
, sizeof(bus
));
1967 dec2str(f
->addr
, addr
, sizeof(addr
));
1968 hex2str(f
->vendor_id
, vid
, sizeof(vid
));
1969 hex2str(f
->product_id
, pid
, sizeof(pid
));
1970 monitor_printf(mon
, " Device %s.%s ID %s:%s\n",
1971 bus
, addr
, vid
, pid
);