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) {
669 aurb
[i
].iso_frame_idx
= -1;
677 static int usb_host_handle_data(USBHostDevice
*s
, USBPacket
*p
)
679 struct usbdevfs_urb
*urb
;
684 if (!is_valid(s
, p
->devep
)) {
688 if (p
->pid
== USB_TOKEN_IN
) {
689 ep
= p
->devep
| 0x80;
694 if (is_halted(s
, p
->devep
)) {
695 ret
= ioctl(s
->fd
, USBDEVFS_CLEAR_HALT
, &ep
);
697 DPRINTF("husb: failed to clear halt. ep 0x%x errno %d\n",
701 clear_halt(s
, p
->devep
);
704 if (is_isoc(s
, p
->devep
)) {
705 return usb_host_handle_iso_data(s
, p
, p
->pid
== USB_TOKEN_IN
);
708 aurb
= async_alloc();
715 urb
->buffer
= p
->data
;
716 urb
->buffer_length
= p
->len
;
717 urb
->type
= USBDEVFS_URB_TYPE_BULK
;
718 urb
->usercontext
= s
;
720 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
722 DPRINTF("husb: data submit. ep 0x%x len %u aurb %p\n",
723 urb
->endpoint
, p
->len
, aurb
);
726 DPRINTF("husb: submit failed. errno %d\n", errno
);
734 return USB_RET_STALL
;
738 usb_defer_packet(p
, async_cancel
, aurb
);
739 return USB_RET_ASYNC
;
742 static int ctrl_error(void)
744 if (errno
== ETIMEDOUT
) {
747 return USB_RET_STALL
;
751 static int usb_host_set_address(USBHostDevice
*s
, int addr
)
753 DPRINTF("husb: ctrl set addr %u\n", addr
);
758 static int usb_host_set_config(USBHostDevice
*s
, int config
)
760 usb_host_release_interfaces(s
);
762 int ret
= ioctl(s
->fd
, USBDEVFS_SETCONFIGURATION
, &config
);
764 DPRINTF("husb: ctrl set config %d ret %d errno %d\n", config
, ret
, errno
);
769 usb_host_claim_interfaces(s
, config
);
773 static int usb_host_set_interface(USBHostDevice
*s
, int iface
, int alt
)
775 struct usbdevfs_setinterface si
;
778 for (i
= 1; i
<= MAX_ENDPOINTS
; i
++) {
780 usb_host_stop_n_free_iso(s
, i
);
784 si
.interface
= iface
;
786 ret
= ioctl(s
->fd
, USBDEVFS_SETINTERFACE
, &si
);
788 DPRINTF("husb: ctrl set iface %d altset %d ret %d errno %d\n",
789 iface
, alt
, ret
, errno
);
794 usb_linux_update_endp_table(s
);
798 static int usb_host_handle_control(USBHostDevice
*s
, USBPacket
*p
)
800 struct usbdevfs_urb
*urb
;
802 int ret
, value
, index
;
806 * Process certain standard device requests.
807 * These are infrequent and are processed synchronously.
809 value
= le16_to_cpu(s
->ctrl
.req
.wValue
);
810 index
= le16_to_cpu(s
->ctrl
.req
.wIndex
);
812 DPRINTF("husb: ctrl type 0x%x req 0x%x val 0x%x index %u len %u\n",
813 s
->ctrl
.req
.bRequestType
, s
->ctrl
.req
.bRequest
, value
, index
,
816 if (s
->ctrl
.req
.bRequestType
== 0) {
817 switch (s
->ctrl
.req
.bRequest
) {
818 case USB_REQ_SET_ADDRESS
:
819 return usb_host_set_address(s
, value
);
821 case USB_REQ_SET_CONFIGURATION
:
822 return usb_host_set_config(s
, value
& 0xff);
826 if (s
->ctrl
.req
.bRequestType
== 1 &&
827 s
->ctrl
.req
.bRequest
== USB_REQ_SET_INTERFACE
) {
828 return usb_host_set_interface(s
, index
, value
);
831 /* The rest are asynchronous */
833 buffer_len
= 8 + s
->ctrl
.len
;
834 if (buffer_len
> sizeof(s
->ctrl
.buffer
)) {
835 fprintf(stderr
, "husb: ctrl buffer too small (%u > %zu)\n",
836 buffer_len
, sizeof(s
->ctrl
.buffer
));
837 return USB_RET_STALL
;
840 aurb
= async_alloc();
845 * Setup ctrl transfer.
847 * s->ctrl is laid out such that data buffer immediately follows
848 * 'req' struct which is exactly what usbdevfs expects.
852 urb
->type
= USBDEVFS_URB_TYPE_CONTROL
;
853 urb
->endpoint
= p
->devep
;
855 urb
->buffer
= &s
->ctrl
.req
;
856 urb
->buffer_length
= buffer_len
;
858 urb
->usercontext
= s
;
860 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
862 DPRINTF("husb: submit ctrl. len %u aurb %p\n", urb
->buffer_length
, aurb
);
865 DPRINTF("husb: submit failed. errno %d\n", errno
);
873 return USB_RET_STALL
;
877 usb_defer_packet(p
, async_cancel
, aurb
);
878 return USB_RET_ASYNC
;
881 static int do_token_setup(USBDevice
*dev
, USBPacket
*p
)
883 USBHostDevice
*s
= (USBHostDevice
*) dev
;
887 return USB_RET_STALL
;
890 memcpy(&s
->ctrl
.req
, p
->data
, 8);
891 s
->ctrl
.len
= le16_to_cpu(s
->ctrl
.req
.wLength
);
893 s
->ctrl
.state
= CTRL_STATE_SETUP
;
895 if (s
->ctrl
.req
.bRequestType
& USB_DIR_IN
) {
896 ret
= usb_host_handle_control(s
, p
);
901 if (ret
< s
->ctrl
.len
) {
904 s
->ctrl
.state
= CTRL_STATE_DATA
;
906 if (s
->ctrl
.len
== 0) {
907 s
->ctrl
.state
= CTRL_STATE_ACK
;
909 s
->ctrl
.state
= CTRL_STATE_DATA
;
916 static int do_token_in(USBDevice
*dev
, USBPacket
*p
)
918 USBHostDevice
*s
= (USBHostDevice
*) dev
;
922 return usb_host_handle_data(s
, p
);
925 switch(s
->ctrl
.state
) {
927 if (!(s
->ctrl
.req
.bRequestType
& USB_DIR_IN
)) {
928 ret
= usb_host_handle_control(s
, p
);
929 if (ret
== USB_RET_ASYNC
) {
930 return USB_RET_ASYNC
;
932 s
->ctrl
.state
= CTRL_STATE_IDLE
;
933 return ret
> 0 ? 0 : ret
;
938 case CTRL_STATE_DATA
:
939 if (s
->ctrl
.req
.bRequestType
& USB_DIR_IN
) {
940 int len
= s
->ctrl
.len
- s
->ctrl
.offset
;
944 memcpy(p
->data
, s
->ctrl
.buffer
+ s
->ctrl
.offset
, len
);
945 s
->ctrl
.offset
+= len
;
946 if (s
->ctrl
.offset
>= s
->ctrl
.len
) {
947 s
->ctrl
.state
= CTRL_STATE_ACK
;
952 s
->ctrl
.state
= CTRL_STATE_IDLE
;
953 return USB_RET_STALL
;
956 return USB_RET_STALL
;
960 static int do_token_out(USBDevice
*dev
, USBPacket
*p
)
962 USBHostDevice
*s
= (USBHostDevice
*) dev
;
965 return usb_host_handle_data(s
, p
);
968 switch(s
->ctrl
.state
) {
970 if (s
->ctrl
.req
.bRequestType
& USB_DIR_IN
) {
971 s
->ctrl
.state
= CTRL_STATE_IDLE
;
974 /* ignore additional output */
978 case CTRL_STATE_DATA
:
979 if (!(s
->ctrl
.req
.bRequestType
& USB_DIR_IN
)) {
980 int len
= s
->ctrl
.len
- s
->ctrl
.offset
;
984 memcpy(s
->ctrl
.buffer
+ s
->ctrl
.offset
, p
->data
, len
);
985 s
->ctrl
.offset
+= len
;
986 if (s
->ctrl
.offset
>= s
->ctrl
.len
) {
987 s
->ctrl
.state
= CTRL_STATE_ACK
;
992 s
->ctrl
.state
= CTRL_STATE_IDLE
;
993 return USB_RET_STALL
;
996 return USB_RET_STALL
;
1002 * Called by the HC (host controller).
1004 * Returns length of the transaction or one of the USB_RET_XXX codes.
1006 static int usb_host_handle_packet(USBDevice
*s
, USBPacket
*p
)
1009 case USB_MSG_ATTACH
:
1010 s
->state
= USB_STATE_ATTACHED
;
1013 case USB_MSG_DETACH
:
1014 s
->state
= USB_STATE_NOTATTACHED
;
1018 s
->remote_wakeup
= 0;
1020 s
->state
= USB_STATE_DEFAULT
;
1021 s
->info
->handle_reset(s
);
1025 /* Rest of the PIDs must match our address */
1026 if (s
->state
< USB_STATE_DEFAULT
|| p
->devaddr
!= s
->addr
) {
1027 return USB_RET_NODEV
;
1031 case USB_TOKEN_SETUP
:
1032 return do_token_setup(s
, p
);
1035 return do_token_in(s
, p
);
1038 return do_token_out(s
, p
);
1041 return USB_RET_STALL
;
1045 static int usb_linux_get_configuration(USBHostDevice
*s
)
1047 uint8_t configuration
;
1048 struct usb_ctrltransfer ct
;
1051 if (usb_fs_type
== USB_FS_SYS
) {
1052 char device_name
[32], line
[1024];
1055 sprintf(device_name
, "%d-%d", s
->bus_num
, s
->devpath
);
1057 if (!usb_host_read_file(line
, sizeof(line
), "bConfigurationValue",
1061 if (sscanf(line
, "%d", &configuration
) != 1) {
1064 return configuration
;
1068 ct
.bRequestType
= USB_DIR_IN
;
1069 ct
.bRequest
= USB_REQ_GET_CONFIGURATION
;
1073 ct
.data
= &configuration
;
1076 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
1078 perror("usb_linux_get_configuration");
1082 /* in address state */
1083 if (configuration
== 0) {
1087 return configuration
;
1090 static uint8_t usb_linux_get_alt_setting(USBHostDevice
*s
,
1091 uint8_t configuration
, uint8_t interface
)
1093 uint8_t alt_setting
;
1094 struct usb_ctrltransfer ct
;
1097 if (usb_fs_type
== USB_FS_SYS
) {
1098 char device_name
[64], line
[1024];
1101 sprintf(device_name
, "%d-%d:%d.%d", s
->bus_num
, s
->devpath
,
1102 (int)configuration
, (int)interface
);
1104 if (!usb_host_read_file(line
, sizeof(line
), "bAlternateSetting",
1108 if (sscanf(line
, "%d", &alt_setting
) != 1) {
1115 ct
.bRequestType
= USB_DIR_IN
| USB_RECIP_INTERFACE
;
1116 ct
.bRequest
= USB_REQ_GET_INTERFACE
;
1118 ct
.wIndex
= interface
;
1120 ct
.data
= &alt_setting
;
1122 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
1124 /* Assume alt 0 on error */
1131 /* returns 1 on problem encountered or 0 for success */
1132 static int usb_linux_update_endp_table(USBHostDevice
*s
)
1134 uint8_t *descriptors
;
1135 uint8_t devep
, type
, configuration
, alt_interface
;
1136 int interface
, length
, i
;
1138 for (i
= 0; i
< MAX_ENDPOINTS
; i
++)
1139 s
->endp_table
[i
].type
= INVALID_EP_TYPE
;
1141 i
= usb_linux_get_configuration(s
);
1146 /* get the desired configuration, interface, and endpoint descriptors
1147 * from device description */
1148 descriptors
= &s
->descr
[18];
1149 length
= s
->descr_len
- 18;
1152 if (descriptors
[i
+ 1] != USB_DT_CONFIG
||
1153 descriptors
[i
+ 5] != configuration
) {
1154 DPRINTF("invalid descriptor data - configuration\n");
1157 i
+= descriptors
[i
];
1159 while (i
< length
) {
1160 if (descriptors
[i
+ 1] != USB_DT_INTERFACE
||
1161 (descriptors
[i
+ 1] == USB_DT_INTERFACE
&&
1162 descriptors
[i
+ 4] == 0)) {
1163 i
+= descriptors
[i
];
1167 interface
= descriptors
[i
+ 2];
1168 alt_interface
= usb_linux_get_alt_setting(s
, configuration
, interface
);
1170 /* the current interface descriptor is the active interface
1171 * and has endpoints */
1172 if (descriptors
[i
+ 3] != alt_interface
) {
1173 i
+= descriptors
[i
];
1177 /* advance to the endpoints */
1178 while (i
< length
&& descriptors
[i
+1] != USB_DT_ENDPOINT
) {
1179 i
+= descriptors
[i
];
1185 while (i
< length
) {
1186 if (descriptors
[i
+ 1] != USB_DT_ENDPOINT
) {
1190 devep
= descriptors
[i
+ 2];
1191 switch (descriptors
[i
+ 3] & 0x3) {
1193 type
= USBDEVFS_URB_TYPE_CONTROL
;
1196 type
= USBDEVFS_URB_TYPE_ISO
;
1197 s
->endp_table
[(devep
& 0xf) - 1].max_packet_size
=
1198 descriptors
[i
+ 4] + (descriptors
[i
+ 5] << 8);
1201 type
= USBDEVFS_URB_TYPE_BULK
;
1204 type
= USBDEVFS_URB_TYPE_INTERRUPT
;
1207 DPRINTF("usb_host: malformed endpoint type\n");
1208 type
= USBDEVFS_URB_TYPE_BULK
;
1210 s
->endp_table
[(devep
& 0xf) - 1].type
= type
;
1211 s
->endp_table
[(devep
& 0xf) - 1].halted
= 0;
1213 i
+= descriptors
[i
];
1219 static int usb_host_open(USBHostDevice
*dev
, int bus_num
,
1220 int addr
, int devpath
, const char *prod_name
)
1223 struct usbdevfs_connectinfo ci
;
1226 if (dev
->fd
!= -1) {
1229 printf("husb: open device %d.%d\n", bus_num
, addr
);
1231 if (!usb_host_device_path
) {
1232 perror("husb: USB Host Device Path not set");
1235 snprintf(buf
, sizeof(buf
), "%s/%03d/%03d", usb_host_device_path
,
1237 fd
= open(buf
, O_RDWR
| O_NONBLOCK
);
1242 DPRINTF("husb: opened %s\n", buf
);
1244 dev
->bus_num
= bus_num
;
1246 dev
->devpath
= devpath
;
1249 /* read the device description */
1250 dev
->descr_len
= read(fd
, dev
->descr
, sizeof(dev
->descr
));
1251 if (dev
->descr_len
<= 0) {
1252 perror("husb: reading device data failed");
1259 printf("=== begin dumping device descriptor data ===\n");
1260 for (x
= 0; x
< dev
->descr_len
; x
++) {
1261 printf("%02x ", dev
->descr
[x
]);
1263 printf("\n=== end dumping device descriptor data ===\n");
1269 * Initial configuration is -1 which makes us claim first
1270 * available config. We used to start with 1, which does not
1271 * always work. I've seen devices where first config starts
1274 if (!usb_host_claim_interfaces(dev
, -1)) {
1278 ret
= ioctl(fd
, USBDEVFS_CONNECTINFO
, &ci
);
1280 perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
1284 printf("husb: grabbed usb device %d.%d\n", bus_num
, addr
);
1286 ret
= usb_linux_update_endp_table(dev
);
1292 dev
->dev
.speed
= USB_SPEED_LOW
;
1294 dev
->dev
.speed
= USB_SPEED_HIGH
;
1297 if (!prod_name
|| prod_name
[0] == '\0') {
1298 snprintf(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1299 "host:%d.%d", bus_num
, addr
);
1301 pstrcpy(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1305 /* USB devio uses 'write' flag to check for async completions */
1306 qemu_set_fd_handler(dev
->fd
, NULL
, async_complete
, dev
);
1308 usb_device_attach(&dev
->dev
);
1319 static int usb_host_close(USBHostDevice
*dev
)
1323 if (dev
->fd
== -1) {
1327 qemu_set_fd_handler(dev
->fd
, NULL
, NULL
, NULL
);
1329 for (i
= 1; i
<= MAX_ENDPOINTS
; i
++) {
1330 if (is_isoc(dev
, i
)) {
1331 usb_host_stop_n_free_iso(dev
, i
);
1334 async_complete(dev
);
1336 usb_device_detach(&dev
->dev
);
1337 ioctl(dev
->fd
, USBDEVFS_RESET
);
1343 static void usb_host_exit_notifier(struct Notifier
* n
)
1345 USBHostDevice
*s
= container_of(n
, USBHostDevice
, exit
);
1348 ioctl(s
->fd
, USBDEVFS_RESET
);
1352 static int usb_host_initfn(USBDevice
*dev
)
1354 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
1356 dev
->auto_attach
= 0;
1358 QTAILQ_INSERT_TAIL(&hostdevs
, s
, next
);
1359 s
->exit
.notify
= usb_host_exit_notifier
;
1360 qemu_add_exit_notifier(&s
->exit
);
1361 usb_host_auto_check(NULL
);
1365 static struct USBDeviceInfo usb_host_dev_info
= {
1366 .product_desc
= "USB Host Device",
1367 .qdev
.name
= "usb-host",
1368 .qdev
.size
= sizeof(USBHostDevice
),
1369 .init
= usb_host_initfn
,
1370 .handle_packet
= usb_host_handle_packet
,
1371 .handle_reset
= usb_host_handle_reset
,
1372 .handle_destroy
= usb_host_handle_destroy
,
1373 .usbdevice_name
= "host",
1374 .usbdevice_init
= usb_host_device_open
,
1375 .qdev
.props
= (Property
[]) {
1376 DEFINE_PROP_UINT32("hostbus", USBHostDevice
, match
.bus_num
, 0),
1377 DEFINE_PROP_UINT32("hostaddr", USBHostDevice
, match
.addr
, 0),
1378 DEFINE_PROP_HEX32("vendorid", USBHostDevice
, match
.vendor_id
, 0),
1379 DEFINE_PROP_HEX32("productid", USBHostDevice
, match
.product_id
, 0),
1380 DEFINE_PROP_END_OF_LIST(),
1384 static void usb_host_register_devices(void)
1386 usb_qdev_register(&usb_host_dev_info
);
1388 device_init(usb_host_register_devices
)
1390 USBDevice
*usb_host_device_open(const char *devname
)
1392 struct USBAutoFilter filter
;
1396 dev
= usb_create(NULL
/* FIXME */, "usb-host");
1398 if (strstr(devname
, "auto:")) {
1399 if (parse_filter(devname
, &filter
) < 0) {
1403 if ((p
= strchr(devname
, '.'))) {
1404 filter
.bus_num
= strtoul(devname
, NULL
, 0);
1405 filter
.addr
= strtoul(p
+ 1, NULL
, 0);
1406 filter
.vendor_id
= 0;
1407 filter
.product_id
= 0;
1408 } else if ((p
= strchr(devname
, ':'))) {
1411 filter
.vendor_id
= strtoul(devname
, NULL
, 16);
1412 filter
.product_id
= strtoul(p
+ 1, NULL
, 16);
1418 qdev_prop_set_uint32(&dev
->qdev
, "hostbus", filter
.bus_num
);
1419 qdev_prop_set_uint32(&dev
->qdev
, "hostaddr", filter
.addr
);
1420 qdev_prop_set_uint32(&dev
->qdev
, "vendorid", filter
.vendor_id
);
1421 qdev_prop_set_uint32(&dev
->qdev
, "productid", filter
.product_id
);
1422 qdev_init_nofail(&dev
->qdev
);
1426 qdev_free(&dev
->qdev
);
1430 int usb_host_device_close(const char *devname
)
1433 char product_name
[PRODUCT_NAME_SZ
];
1437 if (strstr(devname
, "auto:")) {
1438 return usb_host_auto_del(devname
);
1440 if (usb_host_find_device(&bus_num
, &addr
, product_name
,
1441 sizeof(product_name
), devname
) < 0) {
1444 s
= hostdev_find(bus_num
, addr
);
1446 usb_device_delete_addr(s
->bus_num
, s
->dev
.addr
);
1454 static int get_tag_value(char *buf
, int buf_size
,
1455 const char *str
, const char *tag
,
1456 const char *stopchars
)
1460 p
= strstr(str
, tag
);
1465 while (qemu_isspace(*p
)) {
1469 while (*p
!= '\0' && !strchr(stopchars
, *p
)) {
1470 if ((q
- buf
) < (buf_size
- 1)) {
1480 * Use /proc/bus/usb/devices or /dev/bus/usb/devices file to determine
1481 * host's USB devices. This is legacy support since many distributions
1482 * are moving to /sys/bus/usb
1484 static int usb_host_scan_dev(void *opaque
, USBScanFunc
*func
)
1489 int bus_num
, addr
, speed
, device_count
, class_id
, product_id
, vendor_id
;
1490 char product_name
[512];
1493 if (!usb_host_device_path
) {
1494 perror("husb: USB Host Device Path not set");
1497 snprintf(line
, sizeof(line
), "%s/devices", usb_host_device_path
);
1498 f
= fopen(line
, "r");
1500 perror("husb: cannot open devices file");
1505 bus_num
= addr
= speed
= class_id
= product_id
= vendor_id
= 0;
1507 if (fgets(line
, sizeof(line
), f
) == NULL
) {
1510 if (strlen(line
) > 0) {
1511 line
[strlen(line
) - 1] = '\0';
1513 if (line
[0] == 'T' && line
[1] == ':') {
1514 if (device_count
&& (vendor_id
|| product_id
)) {
1515 /* New device. Add the previously discovered device. */
1516 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1517 product_id
, product_name
, speed
);
1522 if (get_tag_value(buf
, sizeof(buf
), line
, "Bus=", " ") < 0) {
1525 bus_num
= atoi(buf
);
1526 if (get_tag_value(buf
, sizeof(buf
), line
, "Dev#=", " ") < 0) {
1530 if (get_tag_value(buf
, sizeof(buf
), line
, "Spd=", " ") < 0) {
1533 if (!strcmp(buf
, "480")) {
1534 speed
= USB_SPEED_HIGH
;
1535 } else if (!strcmp(buf
, "1.5")) {
1536 speed
= USB_SPEED_LOW
;
1538 speed
= USB_SPEED_FULL
;
1540 product_name
[0] = '\0';
1545 } else if (line
[0] == 'P' && line
[1] == ':') {
1546 if (get_tag_value(buf
, sizeof(buf
), line
, "Vendor=", " ") < 0) {
1549 vendor_id
= strtoul(buf
, NULL
, 16);
1550 if (get_tag_value(buf
, sizeof(buf
), line
, "ProdID=", " ") < 0) {
1553 product_id
= strtoul(buf
, NULL
, 16);
1554 } else if (line
[0] == 'S' && line
[1] == ':') {
1555 if (get_tag_value(buf
, sizeof(buf
), line
, "Product=", "") < 0) {
1558 pstrcpy(product_name
, sizeof(product_name
), buf
);
1559 } else if (line
[0] == 'D' && line
[1] == ':') {
1560 if (get_tag_value(buf
, sizeof(buf
), line
, "Cls=", " (") < 0) {
1563 class_id
= strtoul(buf
, NULL
, 16);
1567 if (device_count
&& (vendor_id
|| product_id
)) {
1568 /* Add the last device. */
1569 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1570 product_id
, product_name
, speed
);
1580 * Read sys file-system device file
1582 * @line address of buffer to put file contents in
1583 * @line_size size of line
1584 * @device_file path to device file (printf format string)
1585 * @device_name device being opened (inserted into device_file)
1587 * @return 0 failed, 1 succeeded ('line' contains data)
1589 static int usb_host_read_file(char *line
, size_t line_size
,
1590 const char *device_file
, const char *device_name
)
1594 char filename
[PATH_MAX
];
1596 snprintf(filename
, PATH_MAX
, USBSYSBUS_PATH
"/devices/%s/%s", device_name
,
1598 f
= fopen(filename
, "r");
1600 ret
= fgets(line
, line_size
, f
) != NULL
;
1608 * Use /sys/bus/usb/devices/ directory to determine host's USB
1611 * This code is based on Robert Schiele's original patches posted to
1612 * the Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
1614 static int usb_host_scan_sys(void *opaque
, USBScanFunc
*func
)
1618 int bus_num
, addr
, devpath
, speed
, class_id
, product_id
, vendor_id
;
1620 char product_name
[512];
1623 dir
= opendir(USBSYSBUS_PATH
"/devices");
1625 perror("husb: cannot open devices directory");
1629 while ((de
= readdir(dir
))) {
1630 if (de
->d_name
[0] != '.' && !strchr(de
->d_name
, ':')) {
1631 char *tmpstr
= de
->d_name
;
1632 if (!strncmp(de
->d_name
, "usb", 3)) {
1635 if (sscanf(tmpstr
, "%d-%d", &bus_num
, &devpath
) < 1) {
1639 if (!usb_host_read_file(line
, sizeof(line
), "devnum", de
->d_name
)) {
1642 if (sscanf(line
, "%d", &addr
) != 1) {
1645 if (!usb_host_read_file(line
, sizeof(line
), "bDeviceClass",
1649 if (sscanf(line
, "%x", &class_id
) != 1) {
1653 if (!usb_host_read_file(line
, sizeof(line
), "idVendor",
1657 if (sscanf(line
, "%x", &vendor_id
) != 1) {
1660 if (!usb_host_read_file(line
, sizeof(line
), "idProduct",
1664 if (sscanf(line
, "%x", &product_id
) != 1) {
1667 if (!usb_host_read_file(line
, sizeof(line
), "product",
1671 if (strlen(line
) > 0) {
1672 line
[strlen(line
) - 1] = '\0';
1674 pstrcpy(product_name
, sizeof(product_name
), line
);
1677 if (!usb_host_read_file(line
, sizeof(line
), "speed", de
->d_name
)) {
1680 if (!strcmp(line
, "480\n")) {
1681 speed
= USB_SPEED_HIGH
;
1682 } else if (!strcmp(line
, "1.5\n")) {
1683 speed
= USB_SPEED_LOW
;
1685 speed
= USB_SPEED_FULL
;
1688 ret
= func(opaque
, bus_num
, addr
, devpath
, class_id
, vendor_id
,
1689 product_id
, product_name
, speed
);
1703 * Determine how to access the host's USB devices and call the
1704 * specific support function.
1706 static int usb_host_scan(void *opaque
, USBScanFunc
*func
)
1708 Monitor
*mon
= cur_mon
;
1712 const char *fs_type
[] = {"unknown", "proc", "dev", "sys"};
1713 char devpath
[PATH_MAX
];
1715 /* only check the host once */
1717 dir
= opendir(USBSYSBUS_PATH
"/devices");
1719 /* devices found in /dev/bus/usb/ (yes - not a mistake!) */
1720 strcpy(devpath
, USBDEVBUS_PATH
);
1721 usb_fs_type
= USB_FS_SYS
;
1723 DPRINTF(USBDBG_DEVOPENED
, USBSYSBUS_PATH
);
1726 f
= fopen(USBPROCBUS_PATH
"/devices", "r");
1728 /* devices found in /proc/bus/usb/ */
1729 strcpy(devpath
, USBPROCBUS_PATH
);
1730 usb_fs_type
= USB_FS_PROC
;
1732 DPRINTF(USBDBG_DEVOPENED
, USBPROCBUS_PATH
);
1735 /* try additional methods if an access method hasn't been found yet */
1736 f
= fopen(USBDEVBUS_PATH
"/devices", "r");
1738 /* devices found in /dev/bus/usb/ */
1739 strcpy(devpath
, USBDEVBUS_PATH
);
1740 usb_fs_type
= USB_FS_DEV
;
1742 DPRINTF(USBDBG_DEVOPENED
, USBDEVBUS_PATH
);
1748 monitor_printf(mon
, "husb: unable to access USB devices\n");
1753 /* the module setting (used later for opening devices) */
1754 usb_host_device_path
= qemu_mallocz(strlen(devpath
)+1);
1755 strcpy(usb_host_device_path
, devpath
);
1757 monitor_printf(mon
, "husb: using %s file-system with %s\n",
1758 fs_type
[usb_fs_type
], usb_host_device_path
);
1762 switch (usb_fs_type
) {
1765 ret
= usb_host_scan_dev(opaque
, func
);
1768 ret
= usb_host_scan_sys(opaque
, func
);
1777 static QEMUTimer
*usb_auto_timer
;
1779 static int usb_host_auto_scan(void *opaque
, int bus_num
, int addr
, int devpath
,
1780 int class_id
, int vendor_id
, int product_id
,
1781 const char *product_name
, int speed
)
1783 struct USBAutoFilter
*f
;
1784 struct USBHostDevice
*s
;
1790 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1793 if (f
->bus_num
> 0 && f
->bus_num
!= bus_num
) {
1796 if (f
->addr
> 0 && f
->addr
!= addr
) {
1800 if (f
->vendor_id
> 0 && f
->vendor_id
!= vendor_id
) {
1804 if (f
->product_id
> 0 && f
->product_id
!= product_id
) {
1807 /* We got a match */
1809 /* Already attached ? */
1813 DPRINTF("husb: auto open: bus_num %d addr %d\n", bus_num
, addr
);
1815 usb_host_open(s
, bus_num
, addr
, devpath
, product_name
);
1821 static void usb_host_auto_check(void *unused
)
1823 struct USBHostDevice
*s
;
1824 int unconnected
= 0;
1826 usb_host_scan(NULL
, usb_host_auto_scan
);
1828 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1834 if (unconnected
== 0) {
1835 /* nothing to watch */
1836 if (usb_auto_timer
) {
1837 qemu_del_timer(usb_auto_timer
);
1842 if (!usb_auto_timer
) {
1843 usb_auto_timer
= qemu_new_timer_ms(rt_clock
, usb_host_auto_check
, NULL
);
1844 if (!usb_auto_timer
) {
1848 qemu_mod_timer(usb_auto_timer
, qemu_get_clock_ms(rt_clock
) + 2000);
1852 * Autoconnect filter
1854 * auto:bus:dev[:vid:pid]
1855 * auto:bus.dev[:vid:pid]
1857 * bus - bus number (dec, * means any)
1858 * dev - device number (dec, * means any)
1859 * vid - vendor id (hex, * means any)
1860 * pid - product id (hex, * means any)
1862 * See 'lsusb' output.
1864 static int parse_filter(const char *spec
, struct USBAutoFilter
*f
)
1866 enum { BUS
, DEV
, VID
, PID
, DONE
};
1867 const char *p
= spec
;
1875 for (i
= BUS
; i
< DONE
; i
++) {
1876 p
= strpbrk(p
, ":.");
1886 case BUS
: f
->bus_num
= strtol(p
, NULL
, 10); break;
1887 case DEV
: f
->addr
= strtol(p
, NULL
, 10); break;
1888 case VID
: f
->vendor_id
= strtol(p
, NULL
, 16); break;
1889 case PID
: f
->product_id
= strtol(p
, NULL
, 16); break;
1894 fprintf(stderr
, "husb: invalid auto filter spec %s\n", spec
);
1901 /**********************/
1902 /* USB host device info */
1904 struct usb_class_info
{
1906 const char *class_name
;
1909 static const struct usb_class_info usb_class_info
[] = {
1910 { USB_CLASS_AUDIO
, "Audio"},
1911 { USB_CLASS_COMM
, "Communication"},
1912 { USB_CLASS_HID
, "HID"},
1913 { USB_CLASS_HUB
, "Hub" },
1914 { USB_CLASS_PHYSICAL
, "Physical" },
1915 { USB_CLASS_PRINTER
, "Printer" },
1916 { USB_CLASS_MASS_STORAGE
, "Storage" },
1917 { USB_CLASS_CDC_DATA
, "Data" },
1918 { USB_CLASS_APP_SPEC
, "Application Specific" },
1919 { USB_CLASS_VENDOR_SPEC
, "Vendor Specific" },
1920 { USB_CLASS_STILL_IMAGE
, "Still Image" },
1921 { USB_CLASS_CSCID
, "Smart Card" },
1922 { USB_CLASS_CONTENT_SEC
, "Content Security" },
1926 static const char *usb_class_str(uint8_t class)
1928 const struct usb_class_info
*p
;
1929 for(p
= usb_class_info
; p
->class != -1; p
++) {
1930 if (p
->class == class) {
1934 return p
->class_name
;
1937 static void usb_info_device(Monitor
*mon
, int bus_num
, int addr
, int class_id
,
1938 int vendor_id
, int product_id
,
1939 const char *product_name
,
1942 const char *class_str
, *speed_str
;
1948 case USB_SPEED_FULL
:
1951 case USB_SPEED_HIGH
:
1959 monitor_printf(mon
, " Device %d.%d, speed %s Mb/s\n",
1960 bus_num
, addr
, speed_str
);
1961 class_str
= usb_class_str(class_id
);
1963 monitor_printf(mon
, " %s:", class_str
);
1965 monitor_printf(mon
, " Class %02x:", class_id
);
1967 monitor_printf(mon
, " USB device %04x:%04x", vendor_id
, product_id
);
1968 if (product_name
[0] != '\0') {
1969 monitor_printf(mon
, ", %s", product_name
);
1971 monitor_printf(mon
, "\n");
1974 static int usb_host_info_device(void *opaque
, int bus_num
, int addr
,
1975 int devpath
, int class_id
,
1976 int vendor_id
, int product_id
,
1977 const char *product_name
,
1980 Monitor
*mon
= opaque
;
1982 usb_info_device(mon
, bus_num
, addr
, class_id
, vendor_id
, product_id
,
1983 product_name
, speed
);
1987 static void dec2str(int val
, char *str
, size_t size
)
1990 snprintf(str
, size
, "*");
1992 snprintf(str
, size
, "%d", val
);
1996 static void hex2str(int val
, char *str
, size_t size
)
1999 snprintf(str
, size
, "*");
2001 snprintf(str
, size
, "%04x", val
);
2005 void usb_host_info(Monitor
*mon
)
2007 struct USBAutoFilter
*f
;
2008 struct USBHostDevice
*s
;
2010 usb_host_scan(mon
, usb_host_info_device
);
2012 if (QTAILQ_EMPTY(&hostdevs
)) {
2016 monitor_printf(mon
, " Auto filters:\n");
2017 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
2018 char bus
[10], addr
[10], vid
[10], pid
[10];
2020 dec2str(f
->bus_num
, bus
, sizeof(bus
));
2021 dec2str(f
->addr
, addr
, sizeof(addr
));
2022 hex2str(f
->vendor_id
, vid
, sizeof(vid
));
2023 hex2str(f
->product_id
, pid
, sizeof(pid
));
2024 monitor_printf(mon
, " Device %s.%s ID %s:%s\n",
2025 bus
, addr
, vid
, pid
);