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 15
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
;
119 * Control transfer state.
120 * Note that 'buffer' _must_ follow 'req' field because
121 * we need contiguous buffer when we submit control URB.
127 struct usb_ctrlrequest req
;
128 uint8_t buffer
[8192];
131 struct USBAutoFilter
{
138 typedef struct USBHostDevice
{
149 struct ctrl_struct ctrl
;
150 struct endp_data endp_table
[MAX_ENDPOINTS
];
152 /* Host side address */
156 struct USBAutoFilter match
;
158 QTAILQ_ENTRY(USBHostDevice
) next
;
161 static QTAILQ_HEAD(, USBHostDevice
) hostdevs
= QTAILQ_HEAD_INITIALIZER(hostdevs
);
163 static int usb_host_close(USBHostDevice
*dev
);
164 static int parse_filter(const char *spec
, struct USBAutoFilter
*f
);
165 static void usb_host_auto_check(void *unused
);
166 static int usb_host_read_file(char *line
, size_t line_size
,
167 const char *device_file
, const char *device_name
);
169 static int is_isoc(USBHostDevice
*s
, int ep
)
171 return s
->endp_table
[ep
- 1].type
== USBDEVFS_URB_TYPE_ISO
;
174 static int is_valid(USBHostDevice
*s
, int ep
)
176 return s
->endp_table
[ep
- 1].type
!= INVALID_EP_TYPE
;
179 static int is_halted(USBHostDevice
*s
, int ep
)
181 return s
->endp_table
[ep
- 1].halted
;
184 static void clear_halt(USBHostDevice
*s
, int ep
)
186 s
->endp_table
[ep
- 1].halted
= 0;
189 static void set_halt(USBHostDevice
*s
, int ep
)
191 s
->endp_table
[ep
- 1].halted
= 1;
194 static int is_iso_started(USBHostDevice
*s
, int ep
)
196 return s
->endp_table
[ep
- 1].iso_started
;
199 static void clear_iso_started(USBHostDevice
*s
, int ep
)
201 s
->endp_table
[ep
- 1].iso_started
= 0;
204 static void set_iso_started(USBHostDevice
*s
, int ep
)
206 s
->endp_table
[ep
- 1].iso_started
= 1;
209 static void set_iso_urb(USBHostDevice
*s
, int ep
, AsyncURB
*iso_urb
)
211 s
->endp_table
[ep
- 1].iso_urb
= iso_urb
;
214 static AsyncURB
*get_iso_urb(USBHostDevice
*s
, int ep
)
216 return s
->endp_table
[ep
- 1].iso_urb
;
219 static void set_iso_urb_idx(USBHostDevice
*s
, int ep
, int i
)
221 s
->endp_table
[ep
- 1].iso_urb_idx
= i
;
224 static int get_iso_urb_idx(USBHostDevice
*s
, int ep
)
226 return s
->endp_table
[ep
- 1].iso_urb_idx
;
229 static void set_iso_buffer_used(USBHostDevice
*s
, int ep
, int i
)
231 s
->endp_table
[ep
- 1].iso_buffer_used
= i
;
234 static int get_iso_buffer_used(USBHostDevice
*s
, int ep
)
236 return s
->endp_table
[ep
- 1].iso_buffer_used
;
239 static int get_max_packet_size(USBHostDevice
*s
, int ep
)
241 return s
->endp_table
[ep
- 1].max_packet_size
;
246 * We always allocate iso packet descriptors even for bulk transfers
247 * to simplify allocation and casts.
251 struct usbdevfs_urb urb
;
252 struct usbdevfs_iso_packet_desc isocpd
[ISO_FRAME_DESC_PER_URB
];
254 /* For regular async urbs */
258 /* For buffered iso handling */
259 int iso_frame_idx
; /* -1 means in flight */
262 static AsyncURB
*async_alloc(void)
264 return (AsyncURB
*) qemu_mallocz(sizeof(AsyncURB
));
267 static void async_free(AsyncURB
*aurb
)
272 static void async_complete_ctrl(USBHostDevice
*s
, USBPacket
*p
)
274 switch(s
->ctrl
.state
) {
275 case CTRL_STATE_SETUP
:
276 if (p
->len
< s
->ctrl
.len
)
277 s
->ctrl
.len
= p
->len
;
278 s
->ctrl
.state
= CTRL_STATE_DATA
;
283 s
->ctrl
.state
= CTRL_STATE_IDLE
;
292 static void async_complete(void *opaque
)
294 USBHostDevice
*s
= opaque
;
300 int r
= ioctl(s
->fd
, USBDEVFS_REAPURBNDELAY
, &aurb
);
302 if (errno
== EAGAIN
) {
305 if (errno
== ENODEV
&& !s
->closing
) {
306 printf("husb: device %d.%d disconnected\n",
307 s
->bus_num
, s
->addr
);
309 usb_host_auto_check(NULL
);
313 DPRINTF("husb: async. reap urb failed errno %d\n", errno
);
317 DPRINTF("husb: async completed. aurb %p status %d alen %d\n",
318 aurb
, aurb
->urb
.status
, aurb
->urb
.actual_length
);
320 /* If this is a buffered iso urb mark it as complete and don't do
321 anything else (it is handled further in usb_host_handle_iso_data) */
322 if (aurb
->iso_frame_idx
== -1) {
323 if (aurb
->urb
.status
== -EPIPE
) {
324 set_halt(s
, aurb
->urb
.endpoint
& 0xf);
326 aurb
->iso_frame_idx
= 0;
333 switch (aurb
->urb
.status
) {
335 p
->len
= aurb
->urb
.actual_length
;
336 if (aurb
->urb
.type
== USBDEVFS_URB_TYPE_CONTROL
) {
337 async_complete_ctrl(s
, p
);
342 set_halt(s
, p
->devep
);
343 p
->len
= USB_RET_STALL
;
347 p
->len
= USB_RET_NAK
;
351 usb_packet_complete(&s
->dev
, p
);
358 static void async_cancel(USBPacket
*unused
, void *opaque
)
360 AsyncURB
*aurb
= opaque
;
361 USBHostDevice
*s
= aurb
->hdev
;
363 DPRINTF("husb: async cancel. aurb %p\n", aurb
);
365 /* Mark it as dead (see async_complete above) */
368 int r
= ioctl(s
->fd
, USBDEVFS_DISCARDURB
, aurb
);
370 DPRINTF("husb: async. discard urb failed errno %d\n", errno
);
374 static int usb_host_claim_interfaces(USBHostDevice
*dev
, int configuration
)
376 int dev_descr_len
, config_descr_len
;
377 int interface
, nb_interfaces
;
380 if (configuration
== 0) /* address state - ignore */
383 DPRINTF("husb: claiming interfaces. config %d\n", configuration
);
386 dev_descr_len
= dev
->descr
[0];
387 if (dev_descr_len
> dev
->descr_len
) {
392 while (i
< dev
->descr_len
) {
393 DPRINTF("husb: i is %d, descr_len is %d, dl %d, dt %d\n",
395 dev
->descr
[i
], dev
->descr
[i
+1]);
397 if (dev
->descr
[i
+1] != USB_DT_CONFIG
) {
401 config_descr_len
= dev
->descr
[i
];
403 printf("husb: config #%d need %d\n", dev
->descr
[i
+ 5], configuration
);
405 if (configuration
< 0 || configuration
== dev
->descr
[i
+ 5]) {
406 configuration
= dev
->descr
[i
+ 5];
410 i
+= config_descr_len
;
413 if (i
>= dev
->descr_len
) {
415 "husb: update iface failed. no matching configuration\n");
418 nb_interfaces
= dev
->descr
[i
+ 4];
420 #ifdef USBDEVFS_DISCONNECT
421 /* earlier Linux 2.4 do not support that */
423 struct usbdevfs_ioctl ctrl
;
424 for (interface
= 0; interface
< nb_interfaces
; interface
++) {
425 ctrl
.ioctl_code
= USBDEVFS_DISCONNECT
;
426 ctrl
.ifno
= interface
;
428 ret
= ioctl(dev
->fd
, USBDEVFS_IOCTL
, &ctrl
);
429 if (ret
< 0 && errno
!= ENODATA
) {
430 perror("USBDEVFS_DISCONNECT");
437 /* XXX: only grab if all interfaces are free */
438 for (interface
= 0; interface
< nb_interfaces
; interface
++) {
439 ret
= ioctl(dev
->fd
, USBDEVFS_CLAIMINTERFACE
, &interface
);
441 if (errno
== EBUSY
) {
442 printf("husb: update iface. device already grabbed\n");
444 perror("husb: failed to claim interface");
451 printf("husb: %d interfaces claimed for configuration %d\n",
452 nb_interfaces
, configuration
);
454 dev
->ninterfaces
= nb_interfaces
;
455 dev
->configuration
= configuration
;
459 static int usb_host_release_interfaces(USBHostDevice
*s
)
463 DPRINTF("husb: releasing interfaces\n");
465 for (i
= 0; i
< s
->ninterfaces
; i
++) {
466 ret
= ioctl(s
->fd
, USBDEVFS_RELEASEINTERFACE
, &i
);
468 perror("husb: failed to release interface");
476 static void usb_host_handle_reset(USBDevice
*dev
)
478 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
480 DPRINTF("husb: reset device %u.%u\n", s
->bus_num
, s
->addr
);
482 ioctl(s
->fd
, USBDEVFS_RESET
);
484 usb_host_claim_interfaces(s
, s
->configuration
);
487 static void usb_host_handle_destroy(USBDevice
*dev
)
489 USBHostDevice
*s
= (USBHostDevice
*)dev
;
492 QTAILQ_REMOVE(&hostdevs
, s
, next
);
493 qemu_remove_exit_notifier(&s
->exit
);
496 static int usb_linux_update_endp_table(USBHostDevice
*s
);
498 /* iso data is special, we need to keep enough urbs in flight to make sure
499 that the controller never runs out of them, otherwise the device will
500 likely suffer a buffer underrun / overrun. */
501 static AsyncURB
*usb_host_alloc_iso(USBHostDevice
*s
, uint8_t ep
, int in
)
504 int i
, j
, len
= get_max_packet_size(s
, ep
);
506 aurb
= qemu_mallocz(ISO_URB_COUNT
* sizeof(*aurb
));
507 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
508 aurb
[i
].urb
.endpoint
= ep
;
509 aurb
[i
].urb
.buffer_length
= ISO_FRAME_DESC_PER_URB
* len
;
510 aurb
[i
].urb
.buffer
= qemu_malloc(aurb
[i
].urb
.buffer_length
);
511 aurb
[i
].urb
.type
= USBDEVFS_URB_TYPE_ISO
;
512 aurb
[i
].urb
.flags
= USBDEVFS_URB_ISO_ASAP
;
513 aurb
[i
].urb
.number_of_packets
= ISO_FRAME_DESC_PER_URB
;
514 for (j
= 0 ; j
< ISO_FRAME_DESC_PER_URB
; j
++)
515 aurb
[i
].urb
.iso_frame_desc
[j
].length
= len
;
517 aurb
[i
].urb
.endpoint
|= 0x80;
518 /* Mark as fully consumed (idle) */
519 aurb
[i
].iso_frame_idx
= ISO_FRAME_DESC_PER_URB
;
522 set_iso_urb(s
, ep
, aurb
);
527 static void usb_host_stop_n_free_iso(USBHostDevice
*s
, uint8_t ep
)
530 int i
, ret
, killed
= 0, free
= 1;
532 aurb
= get_iso_urb(s
, ep
);
537 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
539 if (aurb
[i
].iso_frame_idx
== -1) {
540 ret
= ioctl(s
->fd
, USBDEVFS_DISCARDURB
, &aurb
[i
]);
542 printf("husb: discard isoc in urb failed errno %d\n", errno
);
550 /* Make sure any urbs we've killed are reaped before we free them */
555 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
556 qemu_free(aurb
[i
].urb
.buffer
);
562 printf("husb: leaking iso urbs because of discard failure\n");
563 set_iso_urb(s
, ep
, NULL
);
564 set_iso_urb_idx(s
, ep
, 0);
565 clear_iso_started(s
, ep
);
568 static int urb_status_to_usb_ret(int status
)
572 return USB_RET_STALL
;
578 static int usb_host_handle_iso_data(USBHostDevice
*s
, USBPacket
*p
, int in
)
581 int i
, j
, ret
, max_packet_size
, offset
, len
= 0;
583 max_packet_size
= get_max_packet_size(s
, p
->devep
);
584 if (max_packet_size
== 0)
587 aurb
= get_iso_urb(s
, p
->devep
);
589 aurb
= usb_host_alloc_iso(s
, p
->devep
, in
);
592 i
= get_iso_urb_idx(s
, p
->devep
);
593 j
= aurb
[i
].iso_frame_idx
;
594 if (j
>= 0 && j
< ISO_FRAME_DESC_PER_URB
) {
596 /* Check urb status */
597 if (aurb
[i
].urb
.status
) {
598 len
= urb_status_to_usb_ret(aurb
[i
].urb
.status
);
599 /* Move to the next urb */
600 aurb
[i
].iso_frame_idx
= ISO_FRAME_DESC_PER_URB
- 1;
601 /* Check frame status */
602 } else if (aurb
[i
].urb
.iso_frame_desc
[j
].status
) {
603 len
= urb_status_to_usb_ret(
604 aurb
[i
].urb
.iso_frame_desc
[j
].status
);
605 /* Check the frame fits */
606 } else if (aurb
[i
].urb
.iso_frame_desc
[j
].actual_length
> p
->len
) {
607 printf("husb: received iso data is larger then packet\n");
609 /* All good copy data over */
611 len
= aurb
[i
].urb
.iso_frame_desc
[j
].actual_length
;
614 j
* aurb
[i
].urb
.iso_frame_desc
[0].length
,
619 offset
= (j
== 0) ? 0 : get_iso_buffer_used(s
, p
->devep
);
621 /* Check the frame fits */
622 if (len
> max_packet_size
) {
623 printf("husb: send iso data is larger then max packet size\n");
627 /* All good copy data over */
628 memcpy(aurb
[i
].urb
.buffer
+ offset
, p
->data
, len
);
629 aurb
[i
].urb
.iso_frame_desc
[j
].length
= len
;
631 set_iso_buffer_used(s
, p
->devep
, offset
);
633 /* Start the stream once we have buffered enough data */
634 if (!is_iso_started(s
, p
->devep
) && i
== 1 && j
== 8) {
635 set_iso_started(s
, p
->devep
);
638 aurb
[i
].iso_frame_idx
++;
639 if (aurb
[i
].iso_frame_idx
== ISO_FRAME_DESC_PER_URB
) {
640 i
= (i
+ 1) % ISO_URB_COUNT
;
641 set_iso_urb_idx(s
, p
->devep
, i
);
645 set_iso_started(s
, p
->devep
);
647 DPRINTF("hubs: iso out error no free buffer, dropping packet\n");
651 if (is_iso_started(s
, p
->devep
)) {
652 /* (Re)-submit all fully consumed / filled urbs */
653 for (i
= 0; i
< ISO_URB_COUNT
; i
++) {
654 if (aurb
[i
].iso_frame_idx
== ISO_FRAME_DESC_PER_URB
) {
655 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, &aurb
[i
]);
657 printf("husb error submitting iso urb %d: %d\n", i
, errno
);
658 if (!in
|| len
== 0) {
670 aurb
[i
].iso_frame_idx
= -1;
678 static int usb_host_handle_data(USBHostDevice
*s
, USBPacket
*p
)
680 struct usbdevfs_urb
*urb
;
685 if (!is_valid(s
, p
->devep
)) {
689 if (p
->pid
== USB_TOKEN_IN
) {
690 ep
= p
->devep
| 0x80;
695 if (is_halted(s
, p
->devep
)) {
696 ret
= ioctl(s
->fd
, USBDEVFS_CLEAR_HALT
, &ep
);
698 DPRINTF("husb: failed to clear halt. ep 0x%x errno %d\n",
702 clear_halt(s
, p
->devep
);
705 if (is_isoc(s
, p
->devep
)) {
706 return usb_host_handle_iso_data(s
, p
, p
->pid
== USB_TOKEN_IN
);
709 aurb
= async_alloc();
716 urb
->buffer
= p
->data
;
717 urb
->buffer_length
= p
->len
;
718 urb
->type
= USBDEVFS_URB_TYPE_BULK
;
719 urb
->usercontext
= s
;
721 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
723 DPRINTF("husb: data submit. ep 0x%x len %u aurb %p\n",
724 urb
->endpoint
, p
->len
, aurb
);
727 DPRINTF("husb: submit failed. errno %d\n", errno
);
735 return USB_RET_STALL
;
739 usb_defer_packet(p
, async_cancel
, aurb
);
740 return USB_RET_ASYNC
;
743 static int ctrl_error(void)
745 if (errno
== ETIMEDOUT
) {
748 return USB_RET_STALL
;
752 static int usb_host_set_address(USBHostDevice
*s
, int addr
)
754 DPRINTF("husb: ctrl set addr %u\n", addr
);
759 static int usb_host_set_config(USBHostDevice
*s
, int config
)
761 usb_host_release_interfaces(s
);
763 int ret
= ioctl(s
->fd
, USBDEVFS_SETCONFIGURATION
, &config
);
765 DPRINTF("husb: ctrl set config %d ret %d errno %d\n", config
, ret
, errno
);
770 usb_host_claim_interfaces(s
, config
);
774 static int usb_host_set_interface(USBHostDevice
*s
, int iface
, int alt
)
776 struct usbdevfs_setinterface si
;
779 for (i
= 1; i
<= MAX_ENDPOINTS
; i
++) {
781 usb_host_stop_n_free_iso(s
, i
);
785 si
.interface
= iface
;
787 ret
= ioctl(s
->fd
, USBDEVFS_SETINTERFACE
, &si
);
789 DPRINTF("husb: ctrl set iface %d altset %d ret %d errno %d\n",
790 iface
, alt
, ret
, errno
);
795 usb_linux_update_endp_table(s
);
799 static int usb_host_handle_control(USBHostDevice
*s
, USBPacket
*p
)
801 struct usbdevfs_urb
*urb
;
803 int ret
, value
, index
;
807 * Process certain standard device requests.
808 * These are infrequent and are processed synchronously.
810 value
= le16_to_cpu(s
->ctrl
.req
.wValue
);
811 index
= le16_to_cpu(s
->ctrl
.req
.wIndex
);
813 DPRINTF("husb: ctrl type 0x%x req 0x%x val 0x%x index %u len %u\n",
814 s
->ctrl
.req
.bRequestType
, s
->ctrl
.req
.bRequest
, value
, index
,
817 if (s
->ctrl
.req
.bRequestType
== 0) {
818 switch (s
->ctrl
.req
.bRequest
) {
819 case USB_REQ_SET_ADDRESS
:
820 return usb_host_set_address(s
, value
);
822 case USB_REQ_SET_CONFIGURATION
:
823 return usb_host_set_config(s
, value
& 0xff);
827 if (s
->ctrl
.req
.bRequestType
== 1 &&
828 s
->ctrl
.req
.bRequest
== USB_REQ_SET_INTERFACE
) {
829 return usb_host_set_interface(s
, index
, value
);
832 /* The rest are asynchronous */
834 buffer_len
= 8 + s
->ctrl
.len
;
835 if (buffer_len
> sizeof(s
->ctrl
.buffer
)) {
836 fprintf(stderr
, "husb: ctrl buffer too small (%u > %zu)\n",
837 buffer_len
, sizeof(s
->ctrl
.buffer
));
838 return USB_RET_STALL
;
841 aurb
= async_alloc();
846 * Setup ctrl transfer.
848 * s->ctrl is laid out such that data buffer immediately follows
849 * 'req' struct which is exactly what usbdevfs expects.
853 urb
->type
= USBDEVFS_URB_TYPE_CONTROL
;
854 urb
->endpoint
= p
->devep
;
856 urb
->buffer
= &s
->ctrl
.req
;
857 urb
->buffer_length
= buffer_len
;
859 urb
->usercontext
= s
;
861 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
863 DPRINTF("husb: submit ctrl. len %u aurb %p\n", urb
->buffer_length
, aurb
);
866 DPRINTF("husb: submit failed. errno %d\n", errno
);
874 return USB_RET_STALL
;
878 usb_defer_packet(p
, async_cancel
, aurb
);
879 return USB_RET_ASYNC
;
882 static int do_token_setup(USBDevice
*dev
, USBPacket
*p
)
884 USBHostDevice
*s
= (USBHostDevice
*) dev
;
888 return USB_RET_STALL
;
891 memcpy(&s
->ctrl
.req
, p
->data
, 8);
892 s
->ctrl
.len
= le16_to_cpu(s
->ctrl
.req
.wLength
);
894 s
->ctrl
.state
= CTRL_STATE_SETUP
;
896 if (s
->ctrl
.req
.bRequestType
& USB_DIR_IN
) {
897 ret
= usb_host_handle_control(s
, p
);
902 if (ret
< s
->ctrl
.len
) {
905 s
->ctrl
.state
= CTRL_STATE_DATA
;
907 if (s
->ctrl
.len
== 0) {
908 s
->ctrl
.state
= CTRL_STATE_ACK
;
910 s
->ctrl
.state
= CTRL_STATE_DATA
;
917 static int do_token_in(USBDevice
*dev
, USBPacket
*p
)
919 USBHostDevice
*s
= (USBHostDevice
*) dev
;
923 return usb_host_handle_data(s
, p
);
926 switch(s
->ctrl
.state
) {
928 if (!(s
->ctrl
.req
.bRequestType
& USB_DIR_IN
)) {
929 ret
= usb_host_handle_control(s
, p
);
930 if (ret
== USB_RET_ASYNC
) {
931 return USB_RET_ASYNC
;
933 s
->ctrl
.state
= CTRL_STATE_IDLE
;
934 return ret
> 0 ? 0 : ret
;
939 case CTRL_STATE_DATA
:
940 if (s
->ctrl
.req
.bRequestType
& USB_DIR_IN
) {
941 int len
= s
->ctrl
.len
- s
->ctrl
.offset
;
945 memcpy(p
->data
, s
->ctrl
.buffer
+ s
->ctrl
.offset
, len
);
946 s
->ctrl
.offset
+= len
;
947 if (s
->ctrl
.offset
>= s
->ctrl
.len
) {
948 s
->ctrl
.state
= CTRL_STATE_ACK
;
953 s
->ctrl
.state
= CTRL_STATE_IDLE
;
954 return USB_RET_STALL
;
957 return USB_RET_STALL
;
961 static int do_token_out(USBDevice
*dev
, USBPacket
*p
)
963 USBHostDevice
*s
= (USBHostDevice
*) dev
;
966 return usb_host_handle_data(s
, p
);
969 switch(s
->ctrl
.state
) {
971 if (s
->ctrl
.req
.bRequestType
& USB_DIR_IN
) {
972 s
->ctrl
.state
= CTRL_STATE_IDLE
;
975 /* ignore additional output */
979 case CTRL_STATE_DATA
:
980 if (!(s
->ctrl
.req
.bRequestType
& USB_DIR_IN
)) {
981 int len
= s
->ctrl
.len
- s
->ctrl
.offset
;
985 memcpy(s
->ctrl
.buffer
+ s
->ctrl
.offset
, p
->data
, len
);
986 s
->ctrl
.offset
+= len
;
987 if (s
->ctrl
.offset
>= s
->ctrl
.len
) {
988 s
->ctrl
.state
= CTRL_STATE_ACK
;
993 s
->ctrl
.state
= CTRL_STATE_IDLE
;
994 return USB_RET_STALL
;
997 return USB_RET_STALL
;
1003 * Called by the HC (host controller).
1005 * Returns length of the transaction or one of the USB_RET_XXX codes.
1007 static int usb_host_handle_packet(USBDevice
*s
, USBPacket
*p
)
1010 case USB_MSG_ATTACH
:
1011 s
->state
= USB_STATE_ATTACHED
;
1014 case USB_MSG_DETACH
:
1015 s
->state
= USB_STATE_NOTATTACHED
;
1019 s
->remote_wakeup
= 0;
1021 s
->state
= USB_STATE_DEFAULT
;
1022 s
->info
->handle_reset(s
);
1026 /* Rest of the PIDs must match our address */
1027 if (s
->state
< USB_STATE_DEFAULT
|| p
->devaddr
!= s
->addr
) {
1028 return USB_RET_NODEV
;
1032 case USB_TOKEN_SETUP
:
1033 return do_token_setup(s
, p
);
1036 return do_token_in(s
, p
);
1039 return do_token_out(s
, p
);
1042 return USB_RET_STALL
;
1046 static int usb_linux_get_configuration(USBHostDevice
*s
)
1048 uint8_t configuration
;
1049 struct usb_ctrltransfer ct
;
1052 if (usb_fs_type
== USB_FS_SYS
) {
1053 char device_name
[32], line
[1024];
1056 sprintf(device_name
, "%d-%d", s
->bus_num
, s
->devpath
);
1058 if (!usb_host_read_file(line
, sizeof(line
), "bConfigurationValue",
1062 if (sscanf(line
, "%d", &configuration
) != 1) {
1065 return configuration
;
1069 ct
.bRequestType
= USB_DIR_IN
;
1070 ct
.bRequest
= USB_REQ_GET_CONFIGURATION
;
1074 ct
.data
= &configuration
;
1077 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
1079 perror("usb_linux_get_configuration");
1083 /* in address state */
1084 if (configuration
== 0) {
1088 return configuration
;
1091 static uint8_t usb_linux_get_alt_setting(USBHostDevice
*s
,
1092 uint8_t configuration
, uint8_t interface
)
1094 uint8_t alt_setting
;
1095 struct usb_ctrltransfer ct
;
1098 if (usb_fs_type
== USB_FS_SYS
) {
1099 char device_name
[64], line
[1024];
1102 sprintf(device_name
, "%d-%d:%d.%d", s
->bus_num
, s
->devpath
,
1103 (int)configuration
, (int)interface
);
1105 if (!usb_host_read_file(line
, sizeof(line
), "bAlternateSetting",
1109 if (sscanf(line
, "%d", &alt_setting
) != 1) {
1116 ct
.bRequestType
= USB_DIR_IN
| USB_RECIP_INTERFACE
;
1117 ct
.bRequest
= USB_REQ_GET_INTERFACE
;
1119 ct
.wIndex
= interface
;
1121 ct
.data
= &alt_setting
;
1123 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
1125 /* Assume alt 0 on error */
1132 /* returns 1 on problem encountered or 0 for success */
1133 static int usb_linux_update_endp_table(USBHostDevice
*s
)
1135 uint8_t *descriptors
;
1136 uint8_t devep
, type
, configuration
, alt_interface
;
1137 int interface
, length
, i
;
1139 for (i
= 0; i
< MAX_ENDPOINTS
; i
++)
1140 s
->endp_table
[i
].type
= INVALID_EP_TYPE
;
1142 i
= usb_linux_get_configuration(s
);
1147 /* get the desired configuration, interface, and endpoint descriptors
1148 * from device description */
1149 descriptors
= &s
->descr
[18];
1150 length
= s
->descr_len
- 18;
1153 if (descriptors
[i
+ 1] != USB_DT_CONFIG
||
1154 descriptors
[i
+ 5] != configuration
) {
1155 DPRINTF("invalid descriptor data - configuration\n");
1158 i
+= descriptors
[i
];
1160 while (i
< length
) {
1161 if (descriptors
[i
+ 1] != USB_DT_INTERFACE
||
1162 (descriptors
[i
+ 1] == USB_DT_INTERFACE
&&
1163 descriptors
[i
+ 4] == 0)) {
1164 i
+= descriptors
[i
];
1168 interface
= descriptors
[i
+ 2];
1169 alt_interface
= usb_linux_get_alt_setting(s
, configuration
, interface
);
1171 /* the current interface descriptor is the active interface
1172 * and has endpoints */
1173 if (descriptors
[i
+ 3] != alt_interface
) {
1174 i
+= descriptors
[i
];
1178 /* advance to the endpoints */
1179 while (i
< length
&& descriptors
[i
+1] != USB_DT_ENDPOINT
) {
1180 i
+= descriptors
[i
];
1186 while (i
< length
) {
1187 if (descriptors
[i
+ 1] != USB_DT_ENDPOINT
) {
1191 devep
= descriptors
[i
+ 2];
1192 switch (descriptors
[i
+ 3] & 0x3) {
1194 type
= USBDEVFS_URB_TYPE_CONTROL
;
1197 type
= USBDEVFS_URB_TYPE_ISO
;
1198 s
->endp_table
[(devep
& 0xf) - 1].max_packet_size
=
1199 descriptors
[i
+ 4] + (descriptors
[i
+ 5] << 8);
1202 type
= USBDEVFS_URB_TYPE_BULK
;
1205 type
= USBDEVFS_URB_TYPE_INTERRUPT
;
1208 DPRINTF("usb_host: malformed endpoint type\n");
1209 type
= USBDEVFS_URB_TYPE_BULK
;
1211 s
->endp_table
[(devep
& 0xf) - 1].type
= type
;
1212 s
->endp_table
[(devep
& 0xf) - 1].halted
= 0;
1214 i
+= descriptors
[i
];
1220 static int usb_host_open(USBHostDevice
*dev
, int bus_num
,
1221 int addr
, int devpath
, const char *prod_name
)
1224 struct usbdevfs_connectinfo ci
;
1227 if (dev
->fd
!= -1) {
1230 printf("husb: open device %d.%d\n", bus_num
, addr
);
1232 if (!usb_host_device_path
) {
1233 perror("husb: USB Host Device Path not set");
1236 snprintf(buf
, sizeof(buf
), "%s/%03d/%03d", usb_host_device_path
,
1238 fd
= open(buf
, O_RDWR
| O_NONBLOCK
);
1243 DPRINTF("husb: opened %s\n", buf
);
1245 dev
->bus_num
= bus_num
;
1247 dev
->devpath
= devpath
;
1250 /* read the device description */
1251 dev
->descr_len
= read(fd
, dev
->descr
, sizeof(dev
->descr
));
1252 if (dev
->descr_len
<= 0) {
1253 perror("husb: reading device data failed");
1260 printf("=== begin dumping device descriptor data ===\n");
1261 for (x
= 0; x
< dev
->descr_len
; x
++) {
1262 printf("%02x ", dev
->descr
[x
]);
1264 printf("\n=== end dumping device descriptor data ===\n");
1270 * Initial configuration is -1 which makes us claim first
1271 * available config. We used to start with 1, which does not
1272 * always work. I've seen devices where first config starts
1275 if (!usb_host_claim_interfaces(dev
, -1)) {
1279 ret
= ioctl(fd
, USBDEVFS_CONNECTINFO
, &ci
);
1281 perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
1285 printf("husb: grabbed usb device %d.%d\n", bus_num
, addr
);
1287 ret
= usb_linux_update_endp_table(dev
);
1293 dev
->dev
.speed
= USB_SPEED_LOW
;
1295 dev
->dev
.speed
= USB_SPEED_HIGH
;
1298 if (!prod_name
|| prod_name
[0] == '\0') {
1299 snprintf(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1300 "host:%d.%d", bus_num
, addr
);
1302 pstrcpy(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1306 /* USB devio uses 'write' flag to check for async completions */
1307 qemu_set_fd_handler(dev
->fd
, NULL
, async_complete
, dev
);
1309 usb_device_attach(&dev
->dev
);
1320 static int usb_host_close(USBHostDevice
*dev
)
1324 if (dev
->fd
== -1) {
1328 qemu_set_fd_handler(dev
->fd
, NULL
, NULL
, NULL
);
1330 for (i
= 1; i
<= MAX_ENDPOINTS
; i
++) {
1331 if (is_isoc(dev
, i
)) {
1332 usb_host_stop_n_free_iso(dev
, i
);
1335 async_complete(dev
);
1337 usb_device_detach(&dev
->dev
);
1338 ioctl(dev
->fd
, USBDEVFS_RESET
);
1344 static void usb_host_exit_notifier(struct Notifier
* n
)
1346 USBHostDevice
*s
= container_of(n
, USBHostDevice
, exit
);
1349 ioctl(s
->fd
, USBDEVFS_RESET
);
1353 static int usb_host_initfn(USBDevice
*dev
)
1355 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
1357 dev
->auto_attach
= 0;
1359 QTAILQ_INSERT_TAIL(&hostdevs
, s
, next
);
1360 s
->exit
.notify
= usb_host_exit_notifier
;
1361 qemu_add_exit_notifier(&s
->exit
);
1362 usb_host_auto_check(NULL
);
1366 static struct USBDeviceInfo usb_host_dev_info
= {
1367 .product_desc
= "USB Host Device",
1368 .qdev
.name
= "usb-host",
1369 .qdev
.size
= sizeof(USBHostDevice
),
1370 .init
= usb_host_initfn
,
1371 .handle_packet
= usb_host_handle_packet
,
1372 .handle_reset
= usb_host_handle_reset
,
1373 .handle_destroy
= usb_host_handle_destroy
,
1374 .usbdevice_name
= "host",
1375 .usbdevice_init
= usb_host_device_open
,
1376 .qdev
.props
= (Property
[]) {
1377 DEFINE_PROP_UINT32("hostbus", USBHostDevice
, match
.bus_num
, 0),
1378 DEFINE_PROP_UINT32("hostaddr", USBHostDevice
, match
.addr
, 0),
1379 DEFINE_PROP_HEX32("vendorid", USBHostDevice
, match
.vendor_id
, 0),
1380 DEFINE_PROP_HEX32("productid", USBHostDevice
, match
.product_id
, 0),
1381 DEFINE_PROP_END_OF_LIST(),
1385 static void usb_host_register_devices(void)
1387 usb_qdev_register(&usb_host_dev_info
);
1389 device_init(usb_host_register_devices
)
1391 USBDevice
*usb_host_device_open(const char *devname
)
1393 struct USBAutoFilter filter
;
1397 dev
= usb_create(NULL
/* FIXME */, "usb-host");
1399 if (strstr(devname
, "auto:")) {
1400 if (parse_filter(devname
, &filter
) < 0) {
1404 if ((p
= strchr(devname
, '.'))) {
1405 filter
.bus_num
= strtoul(devname
, NULL
, 0);
1406 filter
.addr
= strtoul(p
+ 1, NULL
, 0);
1407 filter
.vendor_id
= 0;
1408 filter
.product_id
= 0;
1409 } else if ((p
= strchr(devname
, ':'))) {
1412 filter
.vendor_id
= strtoul(devname
, NULL
, 16);
1413 filter
.product_id
= strtoul(p
+ 1, NULL
, 16);
1419 qdev_prop_set_uint32(&dev
->qdev
, "hostbus", filter
.bus_num
);
1420 qdev_prop_set_uint32(&dev
->qdev
, "hostaddr", filter
.addr
);
1421 qdev_prop_set_uint32(&dev
->qdev
, "vendorid", filter
.vendor_id
);
1422 qdev_prop_set_uint32(&dev
->qdev
, "productid", filter
.product_id
);
1423 qdev_init_nofail(&dev
->qdev
);
1427 qdev_free(&dev
->qdev
);
1431 int usb_host_device_close(const char *devname
)
1434 char product_name
[PRODUCT_NAME_SZ
];
1438 if (strstr(devname
, "auto:")) {
1439 return usb_host_auto_del(devname
);
1441 if (usb_host_find_device(&bus_num
, &addr
, product_name
,
1442 sizeof(product_name
), devname
) < 0) {
1445 s
= hostdev_find(bus_num
, addr
);
1447 usb_device_delete_addr(s
->bus_num
, s
->dev
.addr
);
1455 static int get_tag_value(char *buf
, int buf_size
,
1456 const char *str
, const char *tag
,
1457 const char *stopchars
)
1461 p
= strstr(str
, tag
);
1466 while (qemu_isspace(*p
)) {
1470 while (*p
!= '\0' && !strchr(stopchars
, *p
)) {
1471 if ((q
- buf
) < (buf_size
- 1)) {
1481 * Use /proc/bus/usb/devices or /dev/bus/usb/devices file to determine
1482 * host's USB devices. This is legacy support since many distributions
1483 * are moving to /sys/bus/usb
1485 static int usb_host_scan_dev(void *opaque
, USBScanFunc
*func
)
1490 int bus_num
, addr
, speed
, device_count
, class_id
, product_id
, vendor_id
;
1491 char product_name
[512];
1494 if (!usb_host_device_path
) {
1495 perror("husb: USB Host Device Path not set");
1498 snprintf(line
, sizeof(line
), "%s/devices", usb_host_device_path
);
1499 f
= fopen(line
, "r");
1501 perror("husb: cannot open devices file");
1506 bus_num
= addr
= speed
= class_id
= product_id
= vendor_id
= 0;
1508 if (fgets(line
, sizeof(line
), f
) == NULL
) {
1511 if (strlen(line
) > 0) {
1512 line
[strlen(line
) - 1] = '\0';
1514 if (line
[0] == 'T' && line
[1] == ':') {
1515 if (device_count
&& (vendor_id
|| product_id
)) {
1516 /* New device. Add the previously discovered device. */
1517 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1518 product_id
, product_name
, speed
);
1523 if (get_tag_value(buf
, sizeof(buf
), line
, "Bus=", " ") < 0) {
1526 bus_num
= atoi(buf
);
1527 if (get_tag_value(buf
, sizeof(buf
), line
, "Dev#=", " ") < 0) {
1531 if (get_tag_value(buf
, sizeof(buf
), line
, "Spd=", " ") < 0) {
1534 if (!strcmp(buf
, "480")) {
1535 speed
= USB_SPEED_HIGH
;
1536 } else if (!strcmp(buf
, "1.5")) {
1537 speed
= USB_SPEED_LOW
;
1539 speed
= USB_SPEED_FULL
;
1541 product_name
[0] = '\0';
1546 } else if (line
[0] == 'P' && line
[1] == ':') {
1547 if (get_tag_value(buf
, sizeof(buf
), line
, "Vendor=", " ") < 0) {
1550 vendor_id
= strtoul(buf
, NULL
, 16);
1551 if (get_tag_value(buf
, sizeof(buf
), line
, "ProdID=", " ") < 0) {
1554 product_id
= strtoul(buf
, NULL
, 16);
1555 } else if (line
[0] == 'S' && line
[1] == ':') {
1556 if (get_tag_value(buf
, sizeof(buf
), line
, "Product=", "") < 0) {
1559 pstrcpy(product_name
, sizeof(product_name
), buf
);
1560 } else if (line
[0] == 'D' && line
[1] == ':') {
1561 if (get_tag_value(buf
, sizeof(buf
), line
, "Cls=", " (") < 0) {
1564 class_id
= strtoul(buf
, NULL
, 16);
1568 if (device_count
&& (vendor_id
|| product_id
)) {
1569 /* Add the last device. */
1570 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1571 product_id
, product_name
, speed
);
1581 * Read sys file-system device file
1583 * @line address of buffer to put file contents in
1584 * @line_size size of line
1585 * @device_file path to device file (printf format string)
1586 * @device_name device being opened (inserted into device_file)
1588 * @return 0 failed, 1 succeeded ('line' contains data)
1590 static int usb_host_read_file(char *line
, size_t line_size
,
1591 const char *device_file
, const char *device_name
)
1595 char filename
[PATH_MAX
];
1597 snprintf(filename
, PATH_MAX
, USBSYSBUS_PATH
"/devices/%s/%s", device_name
,
1599 f
= fopen(filename
, "r");
1601 ret
= fgets(line
, line_size
, f
) != NULL
;
1609 * Use /sys/bus/usb/devices/ directory to determine host's USB
1612 * This code is based on Robert Schiele's original patches posted to
1613 * the Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
1615 static int usb_host_scan_sys(void *opaque
, USBScanFunc
*func
)
1619 int bus_num
, addr
, devpath
, speed
, class_id
, product_id
, vendor_id
;
1621 char product_name
[512];
1624 dir
= opendir(USBSYSBUS_PATH
"/devices");
1626 perror("husb: cannot open devices directory");
1630 while ((de
= readdir(dir
))) {
1631 if (de
->d_name
[0] != '.' && !strchr(de
->d_name
, ':')) {
1632 char *tmpstr
= de
->d_name
;
1633 if (!strncmp(de
->d_name
, "usb", 3)) {
1636 if (sscanf(tmpstr
, "%d-%d", &bus_num
, &devpath
) < 1) {
1640 if (!usb_host_read_file(line
, sizeof(line
), "devnum", de
->d_name
)) {
1643 if (sscanf(line
, "%d", &addr
) != 1) {
1646 if (!usb_host_read_file(line
, sizeof(line
), "bDeviceClass",
1650 if (sscanf(line
, "%x", &class_id
) != 1) {
1654 if (!usb_host_read_file(line
, sizeof(line
), "idVendor",
1658 if (sscanf(line
, "%x", &vendor_id
) != 1) {
1661 if (!usb_host_read_file(line
, sizeof(line
), "idProduct",
1665 if (sscanf(line
, "%x", &product_id
) != 1) {
1668 if (!usb_host_read_file(line
, sizeof(line
), "product",
1672 if (strlen(line
) > 0) {
1673 line
[strlen(line
) - 1] = '\0';
1675 pstrcpy(product_name
, sizeof(product_name
), line
);
1678 if (!usb_host_read_file(line
, sizeof(line
), "speed", de
->d_name
)) {
1681 if (!strcmp(line
, "480\n")) {
1682 speed
= USB_SPEED_HIGH
;
1683 } else if (!strcmp(line
, "1.5\n")) {
1684 speed
= USB_SPEED_LOW
;
1686 speed
= USB_SPEED_FULL
;
1689 ret
= func(opaque
, bus_num
, addr
, devpath
, class_id
, vendor_id
,
1690 product_id
, product_name
, speed
);
1704 * Determine how to access the host's USB devices and call the
1705 * specific support function.
1707 static int usb_host_scan(void *opaque
, USBScanFunc
*func
)
1709 Monitor
*mon
= cur_mon
;
1713 const char *fs_type
[] = {"unknown", "proc", "dev", "sys"};
1714 char devpath
[PATH_MAX
];
1716 /* only check the host once */
1718 dir
= opendir(USBSYSBUS_PATH
"/devices");
1720 /* devices found in /dev/bus/usb/ (yes - not a mistake!) */
1721 strcpy(devpath
, USBDEVBUS_PATH
);
1722 usb_fs_type
= USB_FS_SYS
;
1724 DPRINTF(USBDBG_DEVOPENED
, USBSYSBUS_PATH
);
1727 f
= fopen(USBPROCBUS_PATH
"/devices", "r");
1729 /* devices found in /proc/bus/usb/ */
1730 strcpy(devpath
, USBPROCBUS_PATH
);
1731 usb_fs_type
= USB_FS_PROC
;
1733 DPRINTF(USBDBG_DEVOPENED
, USBPROCBUS_PATH
);
1736 /* try additional methods if an access method hasn't been found yet */
1737 f
= fopen(USBDEVBUS_PATH
"/devices", "r");
1739 /* devices found in /dev/bus/usb/ */
1740 strcpy(devpath
, USBDEVBUS_PATH
);
1741 usb_fs_type
= USB_FS_DEV
;
1743 DPRINTF(USBDBG_DEVOPENED
, USBDEVBUS_PATH
);
1749 monitor_printf(mon
, "husb: unable to access USB devices\n");
1754 /* the module setting (used later for opening devices) */
1755 usb_host_device_path
= qemu_mallocz(strlen(devpath
)+1);
1756 strcpy(usb_host_device_path
, devpath
);
1758 monitor_printf(mon
, "husb: using %s file-system with %s\n",
1759 fs_type
[usb_fs_type
], usb_host_device_path
);
1763 switch (usb_fs_type
) {
1766 ret
= usb_host_scan_dev(opaque
, func
);
1769 ret
= usb_host_scan_sys(opaque
, func
);
1778 static QEMUTimer
*usb_auto_timer
;
1780 static int usb_host_auto_scan(void *opaque
, int bus_num
, int addr
, int devpath
,
1781 int class_id
, int vendor_id
, int product_id
,
1782 const char *product_name
, int speed
)
1784 struct USBAutoFilter
*f
;
1785 struct USBHostDevice
*s
;
1791 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1794 if (f
->bus_num
> 0 && f
->bus_num
!= bus_num
) {
1797 if (f
->addr
> 0 && f
->addr
!= addr
) {
1801 if (f
->vendor_id
> 0 && f
->vendor_id
!= vendor_id
) {
1805 if (f
->product_id
> 0 && f
->product_id
!= product_id
) {
1808 /* We got a match */
1810 /* Already attached ? */
1814 DPRINTF("husb: auto open: bus_num %d addr %d\n", bus_num
, addr
);
1816 usb_host_open(s
, bus_num
, addr
, devpath
, product_name
);
1822 static void usb_host_auto_check(void *unused
)
1824 struct USBHostDevice
*s
;
1825 int unconnected
= 0;
1827 usb_host_scan(NULL
, usb_host_auto_scan
);
1829 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1835 if (unconnected
== 0) {
1836 /* nothing to watch */
1837 if (usb_auto_timer
) {
1838 qemu_del_timer(usb_auto_timer
);
1843 if (!usb_auto_timer
) {
1844 usb_auto_timer
= qemu_new_timer_ms(rt_clock
, usb_host_auto_check
, NULL
);
1845 if (!usb_auto_timer
) {
1849 qemu_mod_timer(usb_auto_timer
, qemu_get_clock_ms(rt_clock
) + 2000);
1853 * Autoconnect filter
1855 * auto:bus:dev[:vid:pid]
1856 * auto:bus.dev[:vid:pid]
1858 * bus - bus number (dec, * means any)
1859 * dev - device number (dec, * means any)
1860 * vid - vendor id (hex, * means any)
1861 * pid - product id (hex, * means any)
1863 * See 'lsusb' output.
1865 static int parse_filter(const char *spec
, struct USBAutoFilter
*f
)
1867 enum { BUS
, DEV
, VID
, PID
, DONE
};
1868 const char *p
= spec
;
1876 for (i
= BUS
; i
< DONE
; i
++) {
1877 p
= strpbrk(p
, ":.");
1887 case BUS
: f
->bus_num
= strtol(p
, NULL
, 10); break;
1888 case DEV
: f
->addr
= strtol(p
, NULL
, 10); break;
1889 case VID
: f
->vendor_id
= strtol(p
, NULL
, 16); break;
1890 case PID
: f
->product_id
= strtol(p
, NULL
, 16); break;
1895 fprintf(stderr
, "husb: invalid auto filter spec %s\n", spec
);
1902 /**********************/
1903 /* USB host device info */
1905 struct usb_class_info
{
1907 const char *class_name
;
1910 static const struct usb_class_info usb_class_info
[] = {
1911 { USB_CLASS_AUDIO
, "Audio"},
1912 { USB_CLASS_COMM
, "Communication"},
1913 { USB_CLASS_HID
, "HID"},
1914 { USB_CLASS_HUB
, "Hub" },
1915 { USB_CLASS_PHYSICAL
, "Physical" },
1916 { USB_CLASS_PRINTER
, "Printer" },
1917 { USB_CLASS_MASS_STORAGE
, "Storage" },
1918 { USB_CLASS_CDC_DATA
, "Data" },
1919 { USB_CLASS_APP_SPEC
, "Application Specific" },
1920 { USB_CLASS_VENDOR_SPEC
, "Vendor Specific" },
1921 { USB_CLASS_STILL_IMAGE
, "Still Image" },
1922 { USB_CLASS_CSCID
, "Smart Card" },
1923 { USB_CLASS_CONTENT_SEC
, "Content Security" },
1927 static const char *usb_class_str(uint8_t class)
1929 const struct usb_class_info
*p
;
1930 for(p
= usb_class_info
; p
->class != -1; p
++) {
1931 if (p
->class == class) {
1935 return p
->class_name
;
1938 static void usb_info_device(Monitor
*mon
, int bus_num
, int addr
, int class_id
,
1939 int vendor_id
, int product_id
,
1940 const char *product_name
,
1943 const char *class_str
, *speed_str
;
1949 case USB_SPEED_FULL
:
1952 case USB_SPEED_HIGH
:
1960 monitor_printf(mon
, " Device %d.%d, speed %s Mb/s\n",
1961 bus_num
, addr
, speed_str
);
1962 class_str
= usb_class_str(class_id
);
1964 monitor_printf(mon
, " %s:", class_str
);
1966 monitor_printf(mon
, " Class %02x:", class_id
);
1968 monitor_printf(mon
, " USB device %04x:%04x", vendor_id
, product_id
);
1969 if (product_name
[0] != '\0') {
1970 monitor_printf(mon
, ", %s", product_name
);
1972 monitor_printf(mon
, "\n");
1975 static int usb_host_info_device(void *opaque
, int bus_num
, int addr
,
1976 int devpath
, int class_id
,
1977 int vendor_id
, int product_id
,
1978 const char *product_name
,
1981 Monitor
*mon
= opaque
;
1983 usb_info_device(mon
, bus_num
, addr
, class_id
, vendor_id
, product_id
,
1984 product_name
, speed
);
1988 static void dec2str(int val
, char *str
, size_t size
)
1991 snprintf(str
, size
, "*");
1993 snprintf(str
, size
, "%d", val
);
1997 static void hex2str(int val
, char *str
, size_t size
)
2000 snprintf(str
, size
, "*");
2002 snprintf(str
, size
, "%04x", val
);
2006 void usb_host_info(Monitor
*mon
)
2008 struct USBAutoFilter
*f
;
2009 struct USBHostDevice
*s
;
2011 usb_host_scan(mon
, usb_host_info_device
);
2013 if (QTAILQ_EMPTY(&hostdevs
)) {
2017 monitor_printf(mon
, " Auto filters:\n");
2018 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
2019 char bus
[10], addr
[10], vid
[10], pid
[10];
2021 dec2str(f
->bus_num
, bus
, sizeof(bus
));
2022 dec2str(f
->addr
, addr
, sizeof(addr
));
2023 hex2str(f
->vendor_id
, vid
, sizeof(vid
));
2024 hex2str(f
->product_id
, pid
, sizeof(pid
));
2025 monitor_printf(mon
, " Device %s.%s ID %s:%s\n",
2026 bus
, addr
, vid
, pid
);