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
, max_packet_size
, len
= 0;
554 max_packet_size
= get_max_packet_size(s
, p
->devep
);
555 if (max_packet_size
== 0)
558 aurb
= get_iso_urb(s
, p
->devep
);
560 aurb
= usb_host_alloc_iso(s
, p
->devep
, 1);
563 i
= get_iso_urb_idx(s
, p
->devep
);
564 j
= aurb
[i
].iso_frame_idx
;
565 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(aurb
[i
].urb
.iso_frame_desc
[j
].status
);
574 /* Check the frame fits */
575 } else if (aurb
[i
].urb
.iso_frame_desc
[j
].actual_length
> p
->len
) {
576 printf("husb: error received isoc data is larger then packet\n");
578 /* All good copy data over */
580 len
= aurb
[i
].urb
.iso_frame_desc
[j
].actual_length
;
583 j
* aurb
[i
].urb
.iso_frame_desc
[0].length
,
586 aurb
[i
].iso_frame_idx
++;
587 if (aurb
[i
].iso_frame_idx
== ISO_FRAME_DESC_PER_URB
) {
588 i
= (i
+ 1) % ISO_URB_COUNT
;
589 set_iso_urb_idx(s
, p
->devep
, i
);
593 /* (Re)-submit all fully consumed urbs */
594 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
595 if (aurb
[i
].iso_frame_idx
== ISO_FRAME_DESC_PER_URB
) {
596 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, &aurb
[i
]);
598 printf("husb error submitting isoc urb %d: %d\n", i
, errno
);
610 aurb
[i
].iso_frame_idx
= -1;
617 static int usb_host_handle_data(USBHostDevice
*s
, USBPacket
*p
)
619 struct usbdevfs_urb
*urb
;
624 if (!is_valid(s
, p
->devep
)) {
628 if (p
->pid
== USB_TOKEN_IN
) {
629 ep
= p
->devep
| 0x80;
634 if (is_halted(s
, p
->devep
)) {
635 ret
= ioctl(s
->fd
, USBDEVFS_CLEAR_HALT
, &ep
);
637 DPRINTF("husb: failed to clear halt. ep 0x%x errno %d\n",
641 clear_halt(s
, p
->devep
);
644 if (is_isoc(s
, p
->devep
) && p
->pid
== USB_TOKEN_IN
)
645 return usb_host_handle_iso_data(s
, p
);
647 aurb
= async_alloc();
654 urb
->buffer
= p
->data
;
655 urb
->buffer_length
= p
->len
;
657 if (is_isoc(s
, p
->devep
)) {
658 /* Setup ISOC transfer */
659 urb
->type
= USBDEVFS_URB_TYPE_ISO
;
660 urb
->flags
= USBDEVFS_URB_ISO_ASAP
;
661 urb
->number_of_packets
= 1;
662 urb
->iso_frame_desc
[0].length
= p
->len
;
664 /* Setup bulk transfer */
665 urb
->type
= USBDEVFS_URB_TYPE_BULK
;
668 urb
->usercontext
= s
;
670 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
672 DPRINTF("husb: data submit. ep 0x%x len %u aurb %p\n",
673 urb
->endpoint
, p
->len
, aurb
);
676 DPRINTF("husb: submit failed. errno %d\n", errno
);
684 return USB_RET_STALL
;
688 usb_defer_packet(p
, async_cancel
, aurb
);
689 return USB_RET_ASYNC
;
692 static int ctrl_error(void)
694 if (errno
== ETIMEDOUT
) {
697 return USB_RET_STALL
;
701 static int usb_host_set_address(USBHostDevice
*s
, int addr
)
703 DPRINTF("husb: ctrl set addr %u\n", addr
);
708 static int usb_host_set_config(USBHostDevice
*s
, int config
)
710 usb_host_release_interfaces(s
);
712 int ret
= ioctl(s
->fd
, USBDEVFS_SETCONFIGURATION
, &config
);
714 DPRINTF("husb: ctrl set config %d ret %d errno %d\n", config
, ret
, errno
);
719 usb_host_claim_interfaces(s
, config
);
723 static int usb_host_set_interface(USBHostDevice
*s
, int iface
, int alt
)
725 struct usbdevfs_setinterface si
;
728 for (i
= 1; i
< MAX_ENDPOINTS
; i
++) {
730 usb_host_stop_n_free_iso(s
, i
);
734 si
.interface
= iface
;
736 ret
= ioctl(s
->fd
, USBDEVFS_SETINTERFACE
, &si
);
738 DPRINTF("husb: ctrl set iface %d altset %d ret %d errno %d\n",
739 iface
, alt
, ret
, errno
);
744 usb_linux_update_endp_table(s
);
748 static int usb_host_handle_control(USBHostDevice
*s
, USBPacket
*p
)
750 struct usbdevfs_urb
*urb
;
752 int ret
, value
, index
;
756 * Process certain standard device requests.
757 * These are infrequent and are processed synchronously.
759 value
= le16_to_cpu(s
->ctrl
.req
.wValue
);
760 index
= le16_to_cpu(s
->ctrl
.req
.wIndex
);
762 DPRINTF("husb: ctrl type 0x%x req 0x%x val 0x%x index %u len %u\n",
763 s
->ctrl
.req
.bRequestType
, s
->ctrl
.req
.bRequest
, value
, index
,
766 if (s
->ctrl
.req
.bRequestType
== 0) {
767 switch (s
->ctrl
.req
.bRequest
) {
768 case USB_REQ_SET_ADDRESS
:
769 return usb_host_set_address(s
, value
);
771 case USB_REQ_SET_CONFIGURATION
:
772 return usb_host_set_config(s
, value
& 0xff);
776 if (s
->ctrl
.req
.bRequestType
== 1 &&
777 s
->ctrl
.req
.bRequest
== USB_REQ_SET_INTERFACE
) {
778 return usb_host_set_interface(s
, index
, value
);
781 /* The rest are asynchronous */
783 buffer_len
= 8 + s
->ctrl
.len
;
784 if (buffer_len
> sizeof(s
->ctrl
.buffer
)) {
785 fprintf(stderr
, "husb: ctrl buffer too small (%u > %zu)\n",
786 buffer_len
, sizeof(s
->ctrl
.buffer
));
787 return USB_RET_STALL
;
790 aurb
= async_alloc();
795 * Setup ctrl transfer.
797 * s->ctrl is laid out such that data buffer immediately follows
798 * 'req' struct which is exactly what usbdevfs expects.
802 urb
->type
= USBDEVFS_URB_TYPE_CONTROL
;
803 urb
->endpoint
= p
->devep
;
805 urb
->buffer
= &s
->ctrl
.req
;
806 urb
->buffer_length
= buffer_len
;
808 urb
->usercontext
= s
;
810 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
812 DPRINTF("husb: submit ctrl. len %u aurb %p\n", urb
->buffer_length
, aurb
);
815 DPRINTF("husb: submit failed. errno %d\n", errno
);
823 return USB_RET_STALL
;
827 usb_defer_packet(p
, async_cancel
, aurb
);
828 return USB_RET_ASYNC
;
831 static int do_token_setup(USBDevice
*dev
, USBPacket
*p
)
833 USBHostDevice
*s
= (USBHostDevice
*) dev
;
837 return USB_RET_STALL
;
840 memcpy(&s
->ctrl
.req
, p
->data
, 8);
841 s
->ctrl
.len
= le16_to_cpu(s
->ctrl
.req
.wLength
);
843 s
->ctrl
.state
= CTRL_STATE_SETUP
;
845 if (s
->ctrl
.req
.bRequestType
& USB_DIR_IN
) {
846 ret
= usb_host_handle_control(s
, p
);
851 if (ret
< s
->ctrl
.len
) {
854 s
->ctrl
.state
= CTRL_STATE_DATA
;
856 if (s
->ctrl
.len
== 0) {
857 s
->ctrl
.state
= CTRL_STATE_ACK
;
859 s
->ctrl
.state
= CTRL_STATE_DATA
;
866 static int do_token_in(USBDevice
*dev
, USBPacket
*p
)
868 USBHostDevice
*s
= (USBHostDevice
*) dev
;
872 return usb_host_handle_data(s
, p
);
875 switch(s
->ctrl
.state
) {
877 if (!(s
->ctrl
.req
.bRequestType
& USB_DIR_IN
)) {
878 ret
= usb_host_handle_control(s
, p
);
879 if (ret
== USB_RET_ASYNC
) {
880 return USB_RET_ASYNC
;
882 s
->ctrl
.state
= CTRL_STATE_IDLE
;
883 return ret
> 0 ? 0 : ret
;
888 case CTRL_STATE_DATA
:
889 if (s
->ctrl
.req
.bRequestType
& USB_DIR_IN
) {
890 int len
= s
->ctrl
.len
- s
->ctrl
.offset
;
894 memcpy(p
->data
, s
->ctrl
.buffer
+ s
->ctrl
.offset
, len
);
895 s
->ctrl
.offset
+= len
;
896 if (s
->ctrl
.offset
>= s
->ctrl
.len
) {
897 s
->ctrl
.state
= CTRL_STATE_ACK
;
902 s
->ctrl
.state
= CTRL_STATE_IDLE
;
903 return USB_RET_STALL
;
906 return USB_RET_STALL
;
910 static int do_token_out(USBDevice
*dev
, USBPacket
*p
)
912 USBHostDevice
*s
= (USBHostDevice
*) dev
;
915 return usb_host_handle_data(s
, p
);
918 switch(s
->ctrl
.state
) {
920 if (s
->ctrl
.req
.bRequestType
& USB_DIR_IN
) {
921 s
->ctrl
.state
= CTRL_STATE_IDLE
;
924 /* ignore additional output */
928 case CTRL_STATE_DATA
:
929 if (!(s
->ctrl
.req
.bRequestType
& USB_DIR_IN
)) {
930 int len
= s
->ctrl
.len
- s
->ctrl
.offset
;
934 memcpy(s
->ctrl
.buffer
+ s
->ctrl
.offset
, p
->data
, len
);
935 s
->ctrl
.offset
+= len
;
936 if (s
->ctrl
.offset
>= s
->ctrl
.len
) {
937 s
->ctrl
.state
= CTRL_STATE_ACK
;
942 s
->ctrl
.state
= CTRL_STATE_IDLE
;
943 return USB_RET_STALL
;
946 return USB_RET_STALL
;
952 * Called by the HC (host controller).
954 * Returns length of the transaction or one of the USB_RET_XXX codes.
956 static int usb_host_handle_packet(USBDevice
*s
, USBPacket
*p
)
960 s
->state
= USB_STATE_ATTACHED
;
964 s
->state
= USB_STATE_NOTATTACHED
;
968 s
->remote_wakeup
= 0;
970 s
->state
= USB_STATE_DEFAULT
;
971 s
->info
->handle_reset(s
);
975 /* Rest of the PIDs must match our address */
976 if (s
->state
< USB_STATE_DEFAULT
|| p
->devaddr
!= s
->addr
) {
977 return USB_RET_NODEV
;
981 case USB_TOKEN_SETUP
:
982 return do_token_setup(s
, p
);
985 return do_token_in(s
, p
);
988 return do_token_out(s
, p
);
991 return USB_RET_STALL
;
995 static int usb_linux_get_configuration(USBHostDevice
*s
)
997 uint8_t configuration
;
998 struct usb_ctrltransfer ct
;
1001 if (usb_fs_type
== USB_FS_SYS
) {
1002 char device_name
[32], line
[1024];
1005 sprintf(device_name
, "%d-%d", s
->bus_num
, s
->devpath
);
1007 if (!usb_host_read_file(line
, sizeof(line
), "bConfigurationValue",
1011 if (sscanf(line
, "%d", &configuration
) != 1) {
1014 return configuration
;
1018 ct
.bRequestType
= USB_DIR_IN
;
1019 ct
.bRequest
= USB_REQ_GET_CONFIGURATION
;
1023 ct
.data
= &configuration
;
1026 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
1028 perror("usb_linux_get_configuration");
1032 /* in address state */
1033 if (configuration
== 0) {
1037 return configuration
;
1040 static uint8_t usb_linux_get_alt_setting(USBHostDevice
*s
,
1041 uint8_t configuration
, uint8_t interface
)
1043 uint8_t alt_setting
;
1044 struct usb_ctrltransfer ct
;
1047 if (usb_fs_type
== USB_FS_SYS
) {
1048 char device_name
[64], line
[1024];
1051 sprintf(device_name
, "%d-%d:%d.%d", s
->bus_num
, s
->devpath
,
1052 (int)configuration
, (int)interface
);
1054 if (!usb_host_read_file(line
, sizeof(line
), "bAlternateSetting",
1058 if (sscanf(line
, "%d", &alt_setting
) != 1) {
1065 ct
.bRequestType
= USB_DIR_IN
| USB_RECIP_INTERFACE
;
1066 ct
.bRequest
= USB_REQ_GET_INTERFACE
;
1068 ct
.wIndex
= interface
;
1070 ct
.data
= &alt_setting
;
1072 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
1074 /* Assume alt 0 on error */
1081 /* returns 1 on problem encountered or 0 for success */
1082 static int usb_linux_update_endp_table(USBHostDevice
*s
)
1084 uint8_t *descriptors
;
1085 uint8_t devep
, type
, configuration
, alt_interface
;
1086 int interface
, length
, i
;
1088 for (i
= 0; i
< MAX_ENDPOINTS
; i
++)
1089 s
->endp_table
[i
].type
= INVALID_EP_TYPE
;
1091 i
= usb_linux_get_configuration(s
);
1096 /* get the desired configuration, interface, and endpoint descriptors
1097 * from device description */
1098 descriptors
= &s
->descr
[18];
1099 length
= s
->descr_len
- 18;
1102 if (descriptors
[i
+ 1] != USB_DT_CONFIG
||
1103 descriptors
[i
+ 5] != configuration
) {
1104 DPRINTF("invalid descriptor data - configuration\n");
1107 i
+= descriptors
[i
];
1109 while (i
< length
) {
1110 if (descriptors
[i
+ 1] != USB_DT_INTERFACE
||
1111 (descriptors
[i
+ 1] == USB_DT_INTERFACE
&&
1112 descriptors
[i
+ 4] == 0)) {
1113 i
+= descriptors
[i
];
1117 interface
= descriptors
[i
+ 2];
1118 alt_interface
= usb_linux_get_alt_setting(s
, configuration
, interface
);
1120 /* the current interface descriptor is the active interface
1121 * and has endpoints */
1122 if (descriptors
[i
+ 3] != alt_interface
) {
1123 i
+= descriptors
[i
];
1127 /* advance to the endpoints */
1128 while (i
< length
&& descriptors
[i
+1] != USB_DT_ENDPOINT
) {
1129 i
+= descriptors
[i
];
1135 while (i
< length
) {
1136 if (descriptors
[i
+ 1] != USB_DT_ENDPOINT
) {
1140 devep
= descriptors
[i
+ 2];
1141 switch (descriptors
[i
+ 3] & 0x3) {
1143 type
= USBDEVFS_URB_TYPE_CONTROL
;
1146 type
= USBDEVFS_URB_TYPE_ISO
;
1147 s
->endp_table
[(devep
& 0xf) - 1].max_packet_size
=
1148 descriptors
[i
+ 4] + (descriptors
[i
+ 5] << 8);
1151 type
= USBDEVFS_URB_TYPE_BULK
;
1154 type
= USBDEVFS_URB_TYPE_INTERRUPT
;
1157 DPRINTF("usb_host: malformed endpoint type\n");
1158 type
= USBDEVFS_URB_TYPE_BULK
;
1160 s
->endp_table
[(devep
& 0xf) - 1].type
= type
;
1161 s
->endp_table
[(devep
& 0xf) - 1].halted
= 0;
1163 i
+= descriptors
[i
];
1169 static int usb_host_open(USBHostDevice
*dev
, int bus_num
,
1170 int addr
, int devpath
, const char *prod_name
)
1173 struct usbdevfs_connectinfo ci
;
1176 if (dev
->fd
!= -1) {
1179 printf("husb: open device %d.%d\n", bus_num
, addr
);
1181 if (!usb_host_device_path
) {
1182 perror("husb: USB Host Device Path not set");
1185 snprintf(buf
, sizeof(buf
), "%s/%03d/%03d", usb_host_device_path
,
1187 fd
= open(buf
, O_RDWR
| O_NONBLOCK
);
1192 DPRINTF("husb: opened %s\n", buf
);
1194 dev
->bus_num
= bus_num
;
1196 dev
->devpath
= devpath
;
1199 /* read the device description */
1200 dev
->descr_len
= read(fd
, dev
->descr
, sizeof(dev
->descr
));
1201 if (dev
->descr_len
<= 0) {
1202 perror("husb: reading device data failed");
1209 printf("=== begin dumping device descriptor data ===\n");
1210 for (x
= 0; x
< dev
->descr_len
; x
++) {
1211 printf("%02x ", dev
->descr
[x
]);
1213 printf("\n=== end dumping device descriptor data ===\n");
1219 * Initial configuration is -1 which makes us claim first
1220 * available config. We used to start with 1, which does not
1221 * always work. I've seen devices where first config starts
1224 if (!usb_host_claim_interfaces(dev
, -1)) {
1228 ret
= ioctl(fd
, USBDEVFS_CONNECTINFO
, &ci
);
1230 perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
1234 printf("husb: grabbed usb device %d.%d\n", bus_num
, addr
);
1236 ret
= usb_linux_update_endp_table(dev
);
1242 dev
->dev
.speed
= USB_SPEED_LOW
;
1244 dev
->dev
.speed
= USB_SPEED_HIGH
;
1247 if (!prod_name
|| prod_name
[0] == '\0') {
1248 snprintf(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1249 "host:%d.%d", bus_num
, addr
);
1251 pstrcpy(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1255 /* USB devio uses 'write' flag to check for async completions */
1256 qemu_set_fd_handler(dev
->fd
, NULL
, async_complete
, dev
);
1258 usb_device_attach(&dev
->dev
);
1269 static int usb_host_close(USBHostDevice
*dev
)
1273 if (dev
->fd
== -1) {
1277 qemu_set_fd_handler(dev
->fd
, NULL
, NULL
, NULL
);
1279 for (i
= 1; i
< MAX_ENDPOINTS
; i
++) {
1280 if (is_isoc(dev
, i
)) {
1281 usb_host_stop_n_free_iso(dev
, i
);
1284 async_complete(dev
);
1286 usb_device_detach(&dev
->dev
);
1287 ioctl(dev
->fd
, USBDEVFS_RESET
);
1293 static void usb_host_exit_notifier(struct Notifier
* n
)
1295 USBHostDevice
*s
= container_of(n
, USBHostDevice
, exit
);
1298 ioctl(s
->fd
, USBDEVFS_RESET
);
1302 static int usb_host_initfn(USBDevice
*dev
)
1304 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
1306 dev
->auto_attach
= 0;
1308 QTAILQ_INSERT_TAIL(&hostdevs
, s
, next
);
1309 s
->exit
.notify
= usb_host_exit_notifier
;
1310 qemu_add_exit_notifier(&s
->exit
);
1311 usb_host_auto_check(NULL
);
1315 static struct USBDeviceInfo usb_host_dev_info
= {
1316 .product_desc
= "USB Host Device",
1317 .qdev
.name
= "usb-host",
1318 .qdev
.size
= sizeof(USBHostDevice
),
1319 .init
= usb_host_initfn
,
1320 .handle_packet
= usb_host_handle_packet
,
1321 .handle_reset
= usb_host_handle_reset
,
1322 .handle_destroy
= usb_host_handle_destroy
,
1323 .usbdevice_name
= "host",
1324 .usbdevice_init
= usb_host_device_open
,
1325 .qdev
.props
= (Property
[]) {
1326 DEFINE_PROP_UINT32("hostbus", USBHostDevice
, match
.bus_num
, 0),
1327 DEFINE_PROP_UINT32("hostaddr", USBHostDevice
, match
.addr
, 0),
1328 DEFINE_PROP_HEX32("vendorid", USBHostDevice
, match
.vendor_id
, 0),
1329 DEFINE_PROP_HEX32("productid", USBHostDevice
, match
.product_id
, 0),
1330 DEFINE_PROP_END_OF_LIST(),
1334 static void usb_host_register_devices(void)
1336 usb_qdev_register(&usb_host_dev_info
);
1338 device_init(usb_host_register_devices
)
1340 USBDevice
*usb_host_device_open(const char *devname
)
1342 struct USBAutoFilter filter
;
1346 dev
= usb_create(NULL
/* FIXME */, "usb-host");
1348 if (strstr(devname
, "auto:")) {
1349 if (parse_filter(devname
, &filter
) < 0) {
1353 if ((p
= strchr(devname
, '.'))) {
1354 filter
.bus_num
= strtoul(devname
, NULL
, 0);
1355 filter
.addr
= strtoul(p
+ 1, NULL
, 0);
1356 filter
.vendor_id
= 0;
1357 filter
.product_id
= 0;
1358 } else if ((p
= strchr(devname
, ':'))) {
1361 filter
.vendor_id
= strtoul(devname
, NULL
, 16);
1362 filter
.product_id
= strtoul(p
+ 1, NULL
, 16);
1368 qdev_prop_set_uint32(&dev
->qdev
, "hostbus", filter
.bus_num
);
1369 qdev_prop_set_uint32(&dev
->qdev
, "hostaddr", filter
.addr
);
1370 qdev_prop_set_uint32(&dev
->qdev
, "vendorid", filter
.vendor_id
);
1371 qdev_prop_set_uint32(&dev
->qdev
, "productid", filter
.product_id
);
1372 qdev_init_nofail(&dev
->qdev
);
1376 qdev_free(&dev
->qdev
);
1380 int usb_host_device_close(const char *devname
)
1383 char product_name
[PRODUCT_NAME_SZ
];
1387 if (strstr(devname
, "auto:")) {
1388 return usb_host_auto_del(devname
);
1390 if (usb_host_find_device(&bus_num
, &addr
, product_name
,
1391 sizeof(product_name
), devname
) < 0) {
1394 s
= hostdev_find(bus_num
, addr
);
1396 usb_device_delete_addr(s
->bus_num
, s
->dev
.addr
);
1404 static int get_tag_value(char *buf
, int buf_size
,
1405 const char *str
, const char *tag
,
1406 const char *stopchars
)
1410 p
= strstr(str
, tag
);
1415 while (qemu_isspace(*p
)) {
1419 while (*p
!= '\0' && !strchr(stopchars
, *p
)) {
1420 if ((q
- buf
) < (buf_size
- 1)) {
1430 * Use /proc/bus/usb/devices or /dev/bus/usb/devices file to determine
1431 * host's USB devices. This is legacy support since many distributions
1432 * are moving to /sys/bus/usb
1434 static int usb_host_scan_dev(void *opaque
, USBScanFunc
*func
)
1439 int bus_num
, addr
, speed
, device_count
, class_id
, product_id
, vendor_id
;
1440 char product_name
[512];
1443 if (!usb_host_device_path
) {
1444 perror("husb: USB Host Device Path not set");
1447 snprintf(line
, sizeof(line
), "%s/devices", usb_host_device_path
);
1448 f
= fopen(line
, "r");
1450 perror("husb: cannot open devices file");
1455 bus_num
= addr
= speed
= class_id
= product_id
= vendor_id
= 0;
1457 if (fgets(line
, sizeof(line
), f
) == NULL
) {
1460 if (strlen(line
) > 0) {
1461 line
[strlen(line
) - 1] = '\0';
1463 if (line
[0] == 'T' && line
[1] == ':') {
1464 if (device_count
&& (vendor_id
|| product_id
)) {
1465 /* New device. Add the previously discovered device. */
1466 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1467 product_id
, product_name
, speed
);
1472 if (get_tag_value(buf
, sizeof(buf
), line
, "Bus=", " ") < 0) {
1475 bus_num
= atoi(buf
);
1476 if (get_tag_value(buf
, sizeof(buf
), line
, "Dev#=", " ") < 0) {
1480 if (get_tag_value(buf
, sizeof(buf
), line
, "Spd=", " ") < 0) {
1483 if (!strcmp(buf
, "480")) {
1484 speed
= USB_SPEED_HIGH
;
1485 } else if (!strcmp(buf
, "1.5")) {
1486 speed
= USB_SPEED_LOW
;
1488 speed
= USB_SPEED_FULL
;
1490 product_name
[0] = '\0';
1495 } else if (line
[0] == 'P' && line
[1] == ':') {
1496 if (get_tag_value(buf
, sizeof(buf
), line
, "Vendor=", " ") < 0) {
1499 vendor_id
= strtoul(buf
, NULL
, 16);
1500 if (get_tag_value(buf
, sizeof(buf
), line
, "ProdID=", " ") < 0) {
1503 product_id
= strtoul(buf
, NULL
, 16);
1504 } else if (line
[0] == 'S' && line
[1] == ':') {
1505 if (get_tag_value(buf
, sizeof(buf
), line
, "Product=", "") < 0) {
1508 pstrcpy(product_name
, sizeof(product_name
), buf
);
1509 } else if (line
[0] == 'D' && line
[1] == ':') {
1510 if (get_tag_value(buf
, sizeof(buf
), line
, "Cls=", " (") < 0) {
1513 class_id
= strtoul(buf
, NULL
, 16);
1517 if (device_count
&& (vendor_id
|| product_id
)) {
1518 /* Add the last device. */
1519 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1520 product_id
, product_name
, speed
);
1530 * Read sys file-system device file
1532 * @line address of buffer to put file contents in
1533 * @line_size size of line
1534 * @device_file path to device file (printf format string)
1535 * @device_name device being opened (inserted into device_file)
1537 * @return 0 failed, 1 succeeded ('line' contains data)
1539 static int usb_host_read_file(char *line
, size_t line_size
,
1540 const char *device_file
, const char *device_name
)
1544 char filename
[PATH_MAX
];
1546 snprintf(filename
, PATH_MAX
, USBSYSBUS_PATH
"/devices/%s/%s", device_name
,
1548 f
= fopen(filename
, "r");
1550 ret
= fgets(line
, line_size
, f
) != NULL
;
1558 * Use /sys/bus/usb/devices/ directory to determine host's USB
1561 * This code is based on Robert Schiele's original patches posted to
1562 * the Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
1564 static int usb_host_scan_sys(void *opaque
, USBScanFunc
*func
)
1568 int bus_num
, addr
, devpath
, speed
, class_id
, product_id
, vendor_id
;
1570 char product_name
[512];
1573 dir
= opendir(USBSYSBUS_PATH
"/devices");
1575 perror("husb: cannot open devices directory");
1579 while ((de
= readdir(dir
))) {
1580 if (de
->d_name
[0] != '.' && !strchr(de
->d_name
, ':')) {
1581 char *tmpstr
= de
->d_name
;
1582 if (!strncmp(de
->d_name
, "usb", 3)) {
1585 if (sscanf(tmpstr
, "%d-%d", &bus_num
, &devpath
) < 1) {
1589 if (!usb_host_read_file(line
, sizeof(line
), "devnum", de
->d_name
)) {
1592 if (sscanf(line
, "%d", &addr
) != 1) {
1595 if (!usb_host_read_file(line
, sizeof(line
), "bDeviceClass",
1599 if (sscanf(line
, "%x", &class_id
) != 1) {
1603 if (!usb_host_read_file(line
, sizeof(line
), "idVendor",
1607 if (sscanf(line
, "%x", &vendor_id
) != 1) {
1610 if (!usb_host_read_file(line
, sizeof(line
), "idProduct",
1614 if (sscanf(line
, "%x", &product_id
) != 1) {
1617 if (!usb_host_read_file(line
, sizeof(line
), "product",
1621 if (strlen(line
) > 0) {
1622 line
[strlen(line
) - 1] = '\0';
1624 pstrcpy(product_name
, sizeof(product_name
), line
);
1627 if (!usb_host_read_file(line
, sizeof(line
), "speed", de
->d_name
)) {
1630 if (!strcmp(line
, "480\n")) {
1631 speed
= USB_SPEED_HIGH
;
1632 } else if (!strcmp(line
, "1.5\n")) {
1633 speed
= USB_SPEED_LOW
;
1635 speed
= USB_SPEED_FULL
;
1638 ret
= func(opaque
, bus_num
, addr
, devpath
, class_id
, vendor_id
,
1639 product_id
, product_name
, speed
);
1653 * Determine how to access the host's USB devices and call the
1654 * specific support function.
1656 static int usb_host_scan(void *opaque
, USBScanFunc
*func
)
1658 Monitor
*mon
= cur_mon
;
1662 const char *fs_type
[] = {"unknown", "proc", "dev", "sys"};
1663 char devpath
[PATH_MAX
];
1665 /* only check the host once */
1667 dir
= opendir(USBSYSBUS_PATH
"/devices");
1669 /* devices found in /dev/bus/usb/ (yes - not a mistake!) */
1670 strcpy(devpath
, USBDEVBUS_PATH
);
1671 usb_fs_type
= USB_FS_SYS
;
1673 DPRINTF(USBDBG_DEVOPENED
, USBSYSBUS_PATH
);
1676 f
= fopen(USBPROCBUS_PATH
"/devices", "r");
1678 /* devices found in /proc/bus/usb/ */
1679 strcpy(devpath
, USBPROCBUS_PATH
);
1680 usb_fs_type
= USB_FS_PROC
;
1682 DPRINTF(USBDBG_DEVOPENED
, USBPROCBUS_PATH
);
1685 /* try additional methods if an access method hasn't been found yet */
1686 f
= fopen(USBDEVBUS_PATH
"/devices", "r");
1688 /* devices found in /dev/bus/usb/ */
1689 strcpy(devpath
, USBDEVBUS_PATH
);
1690 usb_fs_type
= USB_FS_DEV
;
1692 DPRINTF(USBDBG_DEVOPENED
, USBDEVBUS_PATH
);
1698 monitor_printf(mon
, "husb: unable to access USB devices\n");
1703 /* the module setting (used later for opening devices) */
1704 usb_host_device_path
= qemu_mallocz(strlen(devpath
)+1);
1705 strcpy(usb_host_device_path
, devpath
);
1707 monitor_printf(mon
, "husb: using %s file-system with %s\n",
1708 fs_type
[usb_fs_type
], usb_host_device_path
);
1712 switch (usb_fs_type
) {
1715 ret
= usb_host_scan_dev(opaque
, func
);
1718 ret
= usb_host_scan_sys(opaque
, func
);
1727 static QEMUTimer
*usb_auto_timer
;
1729 static int usb_host_auto_scan(void *opaque
, int bus_num
, int addr
, int devpath
,
1730 int class_id
, int vendor_id
, int product_id
,
1731 const char *product_name
, int speed
)
1733 struct USBAutoFilter
*f
;
1734 struct USBHostDevice
*s
;
1740 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1743 if (f
->bus_num
> 0 && f
->bus_num
!= bus_num
) {
1746 if (f
->addr
> 0 && f
->addr
!= addr
) {
1750 if (f
->vendor_id
> 0 && f
->vendor_id
!= vendor_id
) {
1754 if (f
->product_id
> 0 && f
->product_id
!= product_id
) {
1757 /* We got a match */
1759 /* Already attached ? */
1763 DPRINTF("husb: auto open: bus_num %d addr %d\n", bus_num
, addr
);
1765 usb_host_open(s
, bus_num
, addr
, devpath
, product_name
);
1771 static void usb_host_auto_check(void *unused
)
1773 struct USBHostDevice
*s
;
1774 int unconnected
= 0;
1776 usb_host_scan(NULL
, usb_host_auto_scan
);
1778 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1784 if (unconnected
== 0) {
1785 /* nothing to watch */
1786 if (usb_auto_timer
) {
1787 qemu_del_timer(usb_auto_timer
);
1792 if (!usb_auto_timer
) {
1793 usb_auto_timer
= qemu_new_timer_ms(rt_clock
, usb_host_auto_check
, NULL
);
1794 if (!usb_auto_timer
) {
1798 qemu_mod_timer(usb_auto_timer
, qemu_get_clock_ms(rt_clock
) + 2000);
1802 * Autoconnect filter
1804 * auto:bus:dev[:vid:pid]
1805 * auto:bus.dev[:vid:pid]
1807 * bus - bus number (dec, * means any)
1808 * dev - device number (dec, * means any)
1809 * vid - vendor id (hex, * means any)
1810 * pid - product id (hex, * means any)
1812 * See 'lsusb' output.
1814 static int parse_filter(const char *spec
, struct USBAutoFilter
*f
)
1816 enum { BUS
, DEV
, VID
, PID
, DONE
};
1817 const char *p
= spec
;
1825 for (i
= BUS
; i
< DONE
; i
++) {
1826 p
= strpbrk(p
, ":.");
1836 case BUS
: f
->bus_num
= strtol(p
, NULL
, 10); break;
1837 case DEV
: f
->addr
= strtol(p
, NULL
, 10); break;
1838 case VID
: f
->vendor_id
= strtol(p
, NULL
, 16); break;
1839 case PID
: f
->product_id
= strtol(p
, NULL
, 16); break;
1844 fprintf(stderr
, "husb: invalid auto filter spec %s\n", spec
);
1851 /**********************/
1852 /* USB host device info */
1854 struct usb_class_info
{
1856 const char *class_name
;
1859 static const struct usb_class_info usb_class_info
[] = {
1860 { USB_CLASS_AUDIO
, "Audio"},
1861 { USB_CLASS_COMM
, "Communication"},
1862 { USB_CLASS_HID
, "HID"},
1863 { USB_CLASS_HUB
, "Hub" },
1864 { USB_CLASS_PHYSICAL
, "Physical" },
1865 { USB_CLASS_PRINTER
, "Printer" },
1866 { USB_CLASS_MASS_STORAGE
, "Storage" },
1867 { USB_CLASS_CDC_DATA
, "Data" },
1868 { USB_CLASS_APP_SPEC
, "Application Specific" },
1869 { USB_CLASS_VENDOR_SPEC
, "Vendor Specific" },
1870 { USB_CLASS_STILL_IMAGE
, "Still Image" },
1871 { USB_CLASS_CSCID
, "Smart Card" },
1872 { USB_CLASS_CONTENT_SEC
, "Content Security" },
1876 static const char *usb_class_str(uint8_t class)
1878 const struct usb_class_info
*p
;
1879 for(p
= usb_class_info
; p
->class != -1; p
++) {
1880 if (p
->class == class) {
1884 return p
->class_name
;
1887 static void usb_info_device(Monitor
*mon
, int bus_num
, int addr
, int class_id
,
1888 int vendor_id
, int product_id
,
1889 const char *product_name
,
1892 const char *class_str
, *speed_str
;
1898 case USB_SPEED_FULL
:
1901 case USB_SPEED_HIGH
:
1909 monitor_printf(mon
, " Device %d.%d, speed %s Mb/s\n",
1910 bus_num
, addr
, speed_str
);
1911 class_str
= usb_class_str(class_id
);
1913 monitor_printf(mon
, " %s:", class_str
);
1915 monitor_printf(mon
, " Class %02x:", class_id
);
1917 monitor_printf(mon
, " USB device %04x:%04x", vendor_id
, product_id
);
1918 if (product_name
[0] != '\0') {
1919 monitor_printf(mon
, ", %s", product_name
);
1921 monitor_printf(mon
, "\n");
1924 static int usb_host_info_device(void *opaque
, int bus_num
, int addr
,
1925 int devpath
, int class_id
,
1926 int vendor_id
, int product_id
,
1927 const char *product_name
,
1930 Monitor
*mon
= opaque
;
1932 usb_info_device(mon
, bus_num
, addr
, class_id
, vendor_id
, product_id
,
1933 product_name
, speed
);
1937 static void dec2str(int val
, char *str
, size_t size
)
1940 snprintf(str
, size
, "*");
1942 snprintf(str
, size
, "%d", val
);
1946 static void hex2str(int val
, char *str
, size_t size
)
1949 snprintf(str
, size
, "*");
1951 snprintf(str
, size
, "%04x", val
);
1955 void usb_host_info(Monitor
*mon
)
1957 struct USBAutoFilter
*f
;
1958 struct USBHostDevice
*s
;
1960 usb_host_scan(mon
, usb_host_info_device
);
1962 if (QTAILQ_EMPTY(&hostdevs
)) {
1966 monitor_printf(mon
, " Auto filters:\n");
1967 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1968 char bus
[10], addr
[10], vid
[10], pid
[10];
1970 dec2str(f
->bus_num
, bus
, sizeof(bus
));
1971 dec2str(f
->addr
, addr
, sizeof(addr
));
1972 hex2str(f
->vendor_id
, vid
, sizeof(vid
));
1973 hex2str(f
->product_id
, pid
, sizeof(pid
));
1974 monitor_printf(mon
, " Device %s.%s ID %s:%s\n",
1975 bus
, addr
, vid
, pid
);