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"
40 #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 typedef int USBScanFunc(void *opaque
, int bus_num
, int addr
, const char *port
,
58 int class_id
, int vendor_id
, int product_id
,
59 const char *product_name
, int speed
);
64 #define DPRINTF printf
69 #define PRODUCT_NAME_SZ 32
70 #define MAX_PORTLEN 16
72 /* endpoint association data */
73 #define ISO_FRAME_DESC_PER_URB 32
75 /* devio.c limits single requests to 16k */
76 #define MAX_USBFS_BUFFER_SIZE 16384
78 typedef struct AsyncURB AsyncURB
;
89 struct USBAutoFilter
{
97 typedef struct USBHostDevice
{
106 uint32_t iso_urb_count
;
109 struct endp_data ep_in
[USB_MAX_ENDPOINTS
];
110 struct endp_data ep_out
[USB_MAX_ENDPOINTS
];
111 QLIST_HEAD(, AsyncURB
) aurbs
;
113 /* Host side address */
116 char port
[MAX_PORTLEN
];
117 struct USBAutoFilter match
;
120 QTAILQ_ENTRY(USBHostDevice
) next
;
123 static QTAILQ_HEAD(, USBHostDevice
) hostdevs
= QTAILQ_HEAD_INITIALIZER(hostdevs
);
125 static int usb_host_close(USBHostDevice
*dev
);
126 static int parse_filter(const char *spec
, struct USBAutoFilter
*f
);
127 static void usb_host_auto_check(void *unused
);
128 static int usb_host_read_file(char *line
, size_t line_size
,
129 const char *device_file
, const char *device_name
);
130 static int usb_linux_update_endp_table(USBHostDevice
*s
);
132 static int usb_host_usbfs_type(USBHostDevice
*s
, USBPacket
*p
)
134 static const int usbfs
[] = {
135 [USB_ENDPOINT_XFER_CONTROL
] = USBDEVFS_URB_TYPE_CONTROL
,
136 [USB_ENDPOINT_XFER_ISOC
] = USBDEVFS_URB_TYPE_ISO
,
137 [USB_ENDPOINT_XFER_BULK
] = USBDEVFS_URB_TYPE_BULK
,
138 [USB_ENDPOINT_XFER_INT
] = USBDEVFS_URB_TYPE_INTERRUPT
,
140 uint8_t type
= p
->ep
->type
;
141 assert(type
< ARRAY_SIZE(usbfs
));
145 static int usb_host_do_reset(USBHostDevice
*dev
)
151 gettimeofday(&s
, NULL
);
152 ret
= ioctl(dev
->fd
, USBDEVFS_RESET
);
153 gettimeofday(&e
, NULL
);
154 usecs
= (e
.tv_sec
- s
.tv_sec
) * 1000000;
155 usecs
+= e
.tv_usec
- s
.tv_usec
;
156 if (usecs
> 1000000) {
157 /* more than a second, something is fishy, broken usb device? */
158 fprintf(stderr
, "husb: device %d:%d reset took %d.%06d seconds\n",
159 dev
->bus_num
, dev
->addr
, usecs
/ 1000000, usecs
% 1000000);
164 static struct endp_data
*get_endp(USBHostDevice
*s
, int pid
, int ep
)
166 struct endp_data
*eps
= pid
== USB_TOKEN_IN
? s
->ep_in
: s
->ep_out
;
167 assert(pid
== USB_TOKEN_IN
|| pid
== USB_TOKEN_OUT
);
168 assert(ep
> 0 && ep
<= USB_MAX_ENDPOINTS
);
172 static int is_isoc(USBHostDevice
*s
, int pid
, int ep
)
174 return usb_ep_get_type(&s
->dev
, pid
, ep
) == USB_ENDPOINT_XFER_ISOC
;
177 static int is_valid(USBHostDevice
*s
, int pid
, int ep
)
179 return usb_ep_get_type(&s
->dev
, pid
, ep
) != USB_ENDPOINT_XFER_INVALID
;
182 static int is_halted(USBHostDevice
*s
, int pid
, int ep
)
184 return get_endp(s
, pid
, ep
)->halted
;
187 static void clear_halt(USBHostDevice
*s
, int pid
, int ep
)
189 trace_usb_host_ep_clear_halt(s
->bus_num
, s
->addr
, ep
);
190 get_endp(s
, pid
, ep
)->halted
= 0;
193 static void set_halt(USBHostDevice
*s
, int pid
, int ep
)
196 trace_usb_host_ep_set_halt(s
->bus_num
, s
->addr
, ep
);
197 get_endp(s
, pid
, ep
)->halted
= 1;
201 static int is_iso_started(USBHostDevice
*s
, int pid
, int ep
)
203 return get_endp(s
, pid
, ep
)->iso_started
;
206 static void clear_iso_started(USBHostDevice
*s
, int pid
, int ep
)
208 trace_usb_host_ep_stop_iso(s
->bus_num
, s
->addr
, ep
);
209 get_endp(s
, pid
, ep
)->iso_started
= 0;
212 static void set_iso_started(USBHostDevice
*s
, int pid
, int ep
)
214 struct endp_data
*e
= get_endp(s
, pid
, ep
);
216 trace_usb_host_ep_start_iso(s
->bus_num
, s
->addr
, ep
);
217 if (!e
->iso_started
) {
223 static int change_iso_inflight(USBHostDevice
*s
, int pid
, int ep
, int value
)
225 struct endp_data
*e
= get_endp(s
, pid
, ep
);
227 e
->inflight
+= value
;
231 static void set_iso_urb(USBHostDevice
*s
, int pid
, int ep
, AsyncURB
*iso_urb
)
233 get_endp(s
, pid
, ep
)->iso_urb
= iso_urb
;
236 static AsyncURB
*get_iso_urb(USBHostDevice
*s
, int pid
, int ep
)
238 return get_endp(s
, pid
, ep
)->iso_urb
;
241 static void set_iso_urb_idx(USBHostDevice
*s
, int pid
, int ep
, int i
)
243 get_endp(s
, pid
, ep
)->iso_urb_idx
= i
;
246 static int get_iso_urb_idx(USBHostDevice
*s
, int pid
, int ep
)
248 return get_endp(s
, pid
, ep
)->iso_urb_idx
;
251 static void set_iso_buffer_used(USBHostDevice
*s
, int pid
, int ep
, int i
)
253 get_endp(s
, pid
, ep
)->iso_buffer_used
= i
;
256 static int get_iso_buffer_used(USBHostDevice
*s
, int pid
, int ep
)
258 return get_endp(s
, pid
, ep
)->iso_buffer_used
;
263 * We always allocate iso packet descriptors even for bulk transfers
264 * to simplify allocation and casts.
268 struct usbdevfs_urb urb
;
269 struct usbdevfs_iso_packet_desc isocpd
[ISO_FRAME_DESC_PER_URB
];
271 QLIST_ENTRY(AsyncURB
) next
;
273 /* For regular async urbs */
275 int more
; /* large transfer, more urbs follow */
277 /* For buffered iso handling */
278 int iso_frame_idx
; /* -1 means in flight */
281 static AsyncURB
*async_alloc(USBHostDevice
*s
)
283 AsyncURB
*aurb
= g_malloc0(sizeof(AsyncURB
));
285 QLIST_INSERT_HEAD(&s
->aurbs
, aurb
, next
);
289 static void async_free(AsyncURB
*aurb
)
291 QLIST_REMOVE(aurb
, next
);
295 static void do_disconnect(USBHostDevice
*s
)
298 usb_host_auto_check(NULL
);
301 static void async_complete(void *opaque
)
303 USBHostDevice
*s
= opaque
;
310 int r
= ioctl(s
->fd
, USBDEVFS_REAPURBNDELAY
, &aurb
);
312 if (errno
== EAGAIN
) {
314 fprintf(stderr
, "husb: %d iso urbs finished at once\n", urbs
);
318 if (errno
== ENODEV
) {
320 trace_usb_host_disconnect(s
->bus_num
, s
->addr
);
326 perror("USBDEVFS_REAPURBNDELAY");
330 DPRINTF("husb: async completed. aurb %p status %d alen %d\n",
331 aurb
, aurb
->urb
.status
, aurb
->urb
.actual_length
);
333 /* If this is a buffered iso urb mark it as complete and don't do
334 anything else (it is handled further in usb_host_handle_iso_data) */
335 if (aurb
->iso_frame_idx
== -1) {
337 int pid
= (aurb
->urb
.endpoint
& USB_DIR_IN
) ?
338 USB_TOKEN_IN
: USB_TOKEN_OUT
;
339 int ep
= aurb
->urb
.endpoint
& 0xf;
340 if (aurb
->urb
.status
== -EPIPE
) {
341 set_halt(s
, pid
, ep
);
343 aurb
->iso_frame_idx
= 0;
345 inflight
= change_iso_inflight(s
, pid
, ep
, -1);
346 if (inflight
== 0 && is_iso_started(s
, pid
, ep
)) {
347 fprintf(stderr
, "husb: out of buffers for iso stream\n");
353 trace_usb_host_urb_complete(s
->bus_num
, s
->addr
, aurb
, aurb
->urb
.status
,
354 aurb
->urb
.actual_length
, aurb
->more
);
357 switch (aurb
->urb
.status
) {
359 p
->result
+= aurb
->urb
.actual_length
;
363 set_halt(s
, p
->pid
, p
->ep
->nr
);
364 p
->result
= USB_RET_STALL
;
368 p
->result
= USB_RET_NAK
;
372 if (aurb
->urb
.type
== USBDEVFS_URB_TYPE_CONTROL
) {
373 trace_usb_host_req_complete(s
->bus_num
, s
->addr
, p
->result
);
374 usb_generic_async_ctrl_complete(&s
->dev
, p
);
375 } else if (!aurb
->more
) {
376 trace_usb_host_req_complete(s
->bus_num
, s
->addr
, p
->result
);
377 usb_packet_complete(&s
->dev
, p
);
385 static void usb_host_async_cancel(USBDevice
*dev
, USBPacket
*p
)
387 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
390 QLIST_FOREACH(aurb
, &s
->aurbs
, next
) {
391 if (p
!= aurb
->packet
) {
395 DPRINTF("husb: async cancel: packet %p, aurb %p\n", p
, aurb
);
397 /* Mark it as dead (see async_complete above) */
400 int r
= ioctl(s
->fd
, USBDEVFS_DISCARDURB
, aurb
);
402 DPRINTF("husb: async. discard urb failed errno %d\n", errno
);
407 static int usb_host_open_device(int bus
, int addr
)
409 const char *usbfs
= NULL
;
414 rc
= stat("/dev/bus/usb", &st
);
415 if (rc
== 0 && S_ISDIR(st
.st_mode
)) {
416 /* udev-created device nodes available */
417 usbfs
= "/dev/bus/usb";
419 /* fallback: usbfs mounted below /proc */
420 usbfs
= "/proc/bus/usb";
423 snprintf(filename
, sizeof(filename
), "%s/%03d/%03d",
425 fd
= open(filename
, O_RDWR
| O_NONBLOCK
);
427 fprintf(stderr
, "husb: open %s: %s\n", filename
, strerror(errno
));
432 static int usb_host_claim_port(USBHostDevice
*s
)
434 #ifdef USBDEVFS_CLAIM_PORT
435 char *h
, hub_name
[64], line
[1024];
438 snprintf(hub_name
, sizeof(hub_name
), "%d-%s",
439 s
->match
.bus_num
, s
->match
.port
);
441 /* try strip off last ".$portnr" to get hub */
442 h
= strrchr(hub_name
, '.');
444 s
->hub_port
= atoi(h
+1);
447 /* no dot in there -> it is the root hub */
448 snprintf(hub_name
, sizeof(hub_name
), "usb%d",
450 s
->hub_port
= atoi(s
->match
.port
);
453 if (!usb_host_read_file(line
, sizeof(line
), "devnum",
457 if (sscanf(line
, "%d", &hub_addr
) != 1) {
461 s
->hub_fd
= usb_host_open_device(s
->match
.bus_num
, hub_addr
);
466 ret
= ioctl(s
->hub_fd
, USBDEVFS_CLAIM_PORT
, &s
->hub_port
);
473 trace_usb_host_claim_port(s
->match
.bus_num
, hub_addr
, s
->hub_port
);
480 static void usb_host_release_port(USBHostDevice
*s
)
482 if (s
->hub_fd
== -1) {
485 #ifdef USBDEVFS_RELEASE_PORT
486 ioctl(s
->hub_fd
, USBDEVFS_RELEASE_PORT
, &s
->hub_port
);
492 static int usb_host_disconnect_ifaces(USBHostDevice
*dev
, int nb_interfaces
)
494 /* earlier Linux 2.4 do not support that */
495 #ifdef USBDEVFS_DISCONNECT
496 struct usbdevfs_ioctl ctrl
;
499 for (interface
= 0; interface
< nb_interfaces
; interface
++) {
500 ctrl
.ioctl_code
= USBDEVFS_DISCONNECT
;
501 ctrl
.ifno
= interface
;
503 ret
= ioctl(dev
->fd
, USBDEVFS_IOCTL
, &ctrl
);
504 if (ret
< 0 && errno
!= ENODATA
) {
505 perror("USBDEVFS_DISCONNECT");
513 static int usb_linux_get_num_interfaces(USBHostDevice
*s
)
515 char device_name
[64], line
[1024];
516 int num_interfaces
= 0;
518 sprintf(device_name
, "%d-%s", s
->bus_num
, s
->port
);
519 if (!usb_host_read_file(line
, sizeof(line
), "bNumInterfaces",
523 if (sscanf(line
, "%d", &num_interfaces
) != 1) {
526 return num_interfaces
;
529 static int usb_host_claim_interfaces(USBHostDevice
*dev
, int configuration
)
531 const char *op
= NULL
;
532 int dev_descr_len
, config_descr_len
;
533 int interface
, nb_interfaces
;
536 for (i
= 0; i
< USB_MAX_INTERFACES
; i
++) {
537 dev
->dev
.altsetting
[i
] = 0;
540 if (configuration
== 0) { /* address state - ignore */
541 dev
->dev
.ninterfaces
= 0;
542 dev
->dev
.configuration
= 0;
546 DPRINTF("husb: claiming interfaces. config %d\n", configuration
);
549 dev_descr_len
= dev
->descr
[0];
550 if (dev_descr_len
> dev
->descr_len
) {
551 fprintf(stderr
, "husb: update iface failed. descr too short\n");
556 while (i
< dev
->descr_len
) {
557 DPRINTF("husb: i is %d, descr_len is %d, dl %d, dt %d\n",
559 dev
->descr
[i
], dev
->descr
[i
+1]);
561 if (dev
->descr
[i
+1] != USB_DT_CONFIG
) {
565 config_descr_len
= dev
->descr
[i
];
567 DPRINTF("husb: config #%d need %d\n", dev
->descr
[i
+ 5], configuration
);
569 if (configuration
== dev
->descr
[i
+ 5]) {
570 configuration
= dev
->descr
[i
+ 5];
574 i
+= config_descr_len
;
577 if (i
>= dev
->descr_len
) {
579 "husb: update iface failed. no matching configuration\n");
582 nb_interfaces
= dev
->descr
[i
+ 4];
584 if (usb_host_disconnect_ifaces(dev
, nb_interfaces
) < 0) {
588 /* XXX: only grab if all interfaces are free */
589 for (interface
= 0; interface
< nb_interfaces
; interface
++) {
590 op
= "USBDEVFS_CLAIMINTERFACE";
591 ret
= ioctl(dev
->fd
, USBDEVFS_CLAIMINTERFACE
, &interface
);
597 trace_usb_host_claim_interfaces(dev
->bus_num
, dev
->addr
,
598 nb_interfaces
, configuration
);
600 dev
->dev
.ninterfaces
= nb_interfaces
;
601 dev
->dev
.configuration
= configuration
;
605 if (errno
== ENODEV
) {
612 static int usb_host_release_interfaces(USBHostDevice
*s
)
616 trace_usb_host_release_interfaces(s
->bus_num
, s
->addr
);
618 for (i
= 0; i
< s
->dev
.ninterfaces
; i
++) {
619 ret
= ioctl(s
->fd
, USBDEVFS_RELEASEINTERFACE
, &i
);
621 perror("USBDEVFS_RELEASEINTERFACE");
628 static void usb_host_handle_reset(USBDevice
*dev
)
630 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
632 trace_usb_host_reset(s
->bus_num
, s
->addr
);
634 usb_host_do_reset(s
);;
636 usb_host_claim_interfaces(s
, 0);
637 usb_linux_update_endp_table(s
);
640 static void usb_host_handle_destroy(USBDevice
*dev
)
642 USBHostDevice
*s
= (USBHostDevice
*)dev
;
644 usb_host_release_port(s
);
646 QTAILQ_REMOVE(&hostdevs
, s
, next
);
647 qemu_remove_exit_notifier(&s
->exit
);
650 /* iso data is special, we need to keep enough urbs in flight to make sure
651 that the controller never runs out of them, otherwise the device will
652 likely suffer a buffer underrun / overrun. */
653 static AsyncURB
*usb_host_alloc_iso(USBHostDevice
*s
, int pid
, uint8_t ep
)
656 int i
, j
, len
= usb_ep_get_max_packet_size(&s
->dev
, pid
, ep
);
658 aurb
= g_malloc0(s
->iso_urb_count
* sizeof(*aurb
));
659 for (i
= 0; i
< s
->iso_urb_count
; i
++) {
660 aurb
[i
].urb
.endpoint
= ep
;
661 aurb
[i
].urb
.buffer_length
= ISO_FRAME_DESC_PER_URB
* len
;
662 aurb
[i
].urb
.buffer
= g_malloc(aurb
[i
].urb
.buffer_length
);
663 aurb
[i
].urb
.type
= USBDEVFS_URB_TYPE_ISO
;
664 aurb
[i
].urb
.flags
= USBDEVFS_URB_ISO_ASAP
;
665 aurb
[i
].urb
.number_of_packets
= ISO_FRAME_DESC_PER_URB
;
666 for (j
= 0 ; j
< ISO_FRAME_DESC_PER_URB
; j
++)
667 aurb
[i
].urb
.iso_frame_desc
[j
].length
= len
;
668 if (pid
== USB_TOKEN_IN
) {
669 aurb
[i
].urb
.endpoint
|= 0x80;
670 /* Mark as fully consumed (idle) */
671 aurb
[i
].iso_frame_idx
= ISO_FRAME_DESC_PER_URB
;
674 set_iso_urb(s
, pid
, ep
, aurb
);
679 static void usb_host_stop_n_free_iso(USBHostDevice
*s
, int pid
, uint8_t ep
)
682 int i
, ret
, killed
= 0, free
= 1;
684 aurb
= get_iso_urb(s
, pid
, ep
);
689 for (i
= 0; i
< s
->iso_urb_count
; i
++) {
691 if (aurb
[i
].iso_frame_idx
== -1) {
692 ret
= ioctl(s
->fd
, USBDEVFS_DISCARDURB
, &aurb
[i
]);
694 perror("USBDEVFS_DISCARDURB");
702 /* Make sure any urbs we've killed are reaped before we free them */
707 for (i
= 0; i
< s
->iso_urb_count
; i
++) {
708 g_free(aurb
[i
].urb
.buffer
);
714 printf("husb: leaking iso urbs because of discard failure\n");
715 set_iso_urb(s
, pid
, ep
, NULL
);
716 set_iso_urb_idx(s
, pid
, ep
, 0);
717 clear_iso_started(s
, pid
, ep
);
720 static int urb_status_to_usb_ret(int status
)
724 return USB_RET_STALL
;
730 static int usb_host_handle_iso_data(USBHostDevice
*s
, USBPacket
*p
, int in
)
733 int i
, j
, ret
, max_packet_size
, offset
, len
= 0;
736 max_packet_size
= p
->ep
->max_packet_size
;
737 if (max_packet_size
== 0)
740 aurb
= get_iso_urb(s
, p
->pid
, p
->ep
->nr
);
742 aurb
= usb_host_alloc_iso(s
, p
->pid
, p
->ep
->nr
);
745 i
= get_iso_urb_idx(s
, p
->pid
, p
->ep
->nr
);
746 j
= aurb
[i
].iso_frame_idx
;
747 if (j
>= 0 && j
< ISO_FRAME_DESC_PER_URB
) {
749 /* Check urb status */
750 if (aurb
[i
].urb
.status
) {
751 len
= urb_status_to_usb_ret(aurb
[i
].urb
.status
);
752 /* Move to the next urb */
753 aurb
[i
].iso_frame_idx
= ISO_FRAME_DESC_PER_URB
- 1;
754 /* Check frame status */
755 } else if (aurb
[i
].urb
.iso_frame_desc
[j
].status
) {
756 len
= urb_status_to_usb_ret(
757 aurb
[i
].urb
.iso_frame_desc
[j
].status
);
758 /* Check the frame fits */
759 } else if (aurb
[i
].urb
.iso_frame_desc
[j
].actual_length
761 printf("husb: received iso data is larger then packet\n");
763 /* All good copy data over */
765 len
= aurb
[i
].urb
.iso_frame_desc
[j
].actual_length
;
766 buf
= aurb
[i
].urb
.buffer
+
767 j
* aurb
[i
].urb
.iso_frame_desc
[0].length
;
768 usb_packet_copy(p
, buf
, len
);
772 offset
= (j
== 0) ? 0 : get_iso_buffer_used(s
, p
->pid
, p
->ep
->nr
);
774 /* Check the frame fits */
775 if (len
> max_packet_size
) {
776 printf("husb: send iso data is larger then max packet size\n");
780 /* All good copy data over */
781 usb_packet_copy(p
, aurb
[i
].urb
.buffer
+ offset
, len
);
782 aurb
[i
].urb
.iso_frame_desc
[j
].length
= len
;
784 set_iso_buffer_used(s
, p
->pid
, p
->ep
->nr
, offset
);
786 /* Start the stream once we have buffered enough data */
787 if (!is_iso_started(s
, p
->pid
, p
->ep
->nr
) && i
== 1 && j
== 8) {
788 set_iso_started(s
, p
->pid
, p
->ep
->nr
);
791 aurb
[i
].iso_frame_idx
++;
792 if (aurb
[i
].iso_frame_idx
== ISO_FRAME_DESC_PER_URB
) {
793 i
= (i
+ 1) % s
->iso_urb_count
;
794 set_iso_urb_idx(s
, p
->pid
, p
->ep
->nr
, i
);
798 set_iso_started(s
, p
->pid
, p
->ep
->nr
);
800 DPRINTF("hubs: iso out error no free buffer, dropping packet\n");
804 if (is_iso_started(s
, p
->pid
, p
->ep
->nr
)) {
805 /* (Re)-submit all fully consumed / filled urbs */
806 for (i
= 0; i
< s
->iso_urb_count
; i
++) {
807 if (aurb
[i
].iso_frame_idx
== ISO_FRAME_DESC_PER_URB
) {
808 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, &aurb
[i
]);
810 perror("USBDEVFS_SUBMITURB");
811 if (!in
|| len
== 0) {
823 aurb
[i
].iso_frame_idx
= -1;
824 change_iso_inflight(s
, p
->pid
, p
->ep
->nr
, 1);
832 static int usb_host_handle_data(USBDevice
*dev
, USBPacket
*p
)
834 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
835 struct usbdevfs_urb
*urb
;
837 int ret
, rem
, prem
, v
;
841 trace_usb_host_req_data(s
->bus_num
, s
->addr
,
842 p
->pid
== USB_TOKEN_IN
,
843 p
->ep
->nr
, p
->iov
.size
);
845 if (!is_valid(s
, p
->pid
, p
->ep
->nr
)) {
846 trace_usb_host_req_complete(s
->bus_num
, s
->addr
, USB_RET_NAK
);
850 if (p
->pid
== USB_TOKEN_IN
) {
851 ep
= p
->ep
->nr
| 0x80;
856 if (is_halted(s
, p
->pid
, p
->ep
->nr
)) {
857 unsigned int arg
= ep
;
858 ret
= ioctl(s
->fd
, USBDEVFS_CLEAR_HALT
, &arg
);
860 perror("USBDEVFS_CLEAR_HALT");
861 trace_usb_host_req_complete(s
->bus_num
, s
->addr
, USB_RET_NAK
);
864 clear_halt(s
, p
->pid
, p
->ep
->nr
);
867 if (is_isoc(s
, p
->pid
, p
->ep
->nr
)) {
868 return usb_host_handle_iso_data(s
, p
, p
->pid
== USB_TOKEN_IN
);
872 prem
= p
->iov
.iov
[v
].iov_len
;
873 pbuf
= p
->iov
.iov
[v
].iov_base
;
878 assert(v
< p
->iov
.niov
);
879 prem
= p
->iov
.iov
[v
].iov_len
;
880 pbuf
= p
->iov
.iov
[v
].iov_base
;
883 aurb
= async_alloc(s
);
888 urb
->type
= usb_host_usbfs_type(s
, p
);
889 urb
->usercontext
= s
;
891 urb
->buffer_length
= prem
;
893 if (urb
->buffer_length
> MAX_USBFS_BUFFER_SIZE
) {
894 urb
->buffer_length
= MAX_USBFS_BUFFER_SIZE
;
896 pbuf
+= urb
->buffer_length
;
897 prem
-= urb
->buffer_length
;
898 rem
-= urb
->buffer_length
;
903 trace_usb_host_urb_submit(s
->bus_num
, s
->addr
, aurb
,
904 urb
->buffer_length
, aurb
->more
);
905 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
907 DPRINTF("husb: data submit: ep 0x%x, len %u, more %d, packet %p, aurb %p\n",
908 urb
->endpoint
, urb
->buffer_length
, aurb
->more
, p
, aurb
);
911 perror("USBDEVFS_SUBMITURB");
916 trace_usb_host_req_complete(s
->bus_num
, s
->addr
, USB_RET_NAK
);
920 trace_usb_host_req_complete(s
->bus_num
, s
->addr
, USB_RET_STALL
);
921 return USB_RET_STALL
;
926 return USB_RET_ASYNC
;
929 static int ctrl_error(void)
931 if (errno
== ETIMEDOUT
) {
934 return USB_RET_STALL
;
938 static int usb_host_set_address(USBHostDevice
*s
, int addr
)
940 trace_usb_host_set_address(s
->bus_num
, s
->addr
, addr
);
945 static int usb_host_set_config(USBHostDevice
*s
, int config
)
949 trace_usb_host_set_config(s
->bus_num
, s
->addr
, config
);
951 usb_host_release_interfaces(s
);
954 ret
= ioctl(s
->fd
, USBDEVFS_SETCONFIGURATION
, &config
);
956 DPRINTF("husb: ctrl set config %d ret %d errno %d\n", config
, ret
, errno
);
958 if (ret
< 0 && errno
== EBUSY
&& first
) {
959 /* happens if usb device is in use by host drivers */
960 int count
= usb_linux_get_num_interfaces(s
);
962 DPRINTF("husb: busy -> disconnecting %d interfaces\n", count
);
963 usb_host_disconnect_ifaces(s
, count
);
972 usb_host_claim_interfaces(s
, config
);
973 usb_linux_update_endp_table(s
);
977 static int usb_host_set_interface(USBHostDevice
*s
, int iface
, int alt
)
979 struct usbdevfs_setinterface si
;
982 trace_usb_host_set_interface(s
->bus_num
, s
->addr
, iface
, alt
);
984 for (i
= 1; i
<= USB_MAX_ENDPOINTS
; i
++) {
985 if (is_isoc(s
, USB_TOKEN_IN
, i
)) {
986 usb_host_stop_n_free_iso(s
, USB_TOKEN_IN
, i
);
988 if (is_isoc(s
, USB_TOKEN_OUT
, i
)) {
989 usb_host_stop_n_free_iso(s
, USB_TOKEN_OUT
, i
);
993 if (iface
>= USB_MAX_INTERFACES
) {
994 return USB_RET_STALL
;
997 si
.interface
= iface
;
999 ret
= ioctl(s
->fd
, USBDEVFS_SETINTERFACE
, &si
);
1001 DPRINTF("husb: ctrl set iface %d altset %d ret %d errno %d\n",
1002 iface
, alt
, ret
, errno
);
1005 return ctrl_error();
1008 s
->dev
.altsetting
[iface
] = alt
;
1009 usb_linux_update_endp_table(s
);
1013 static int usb_host_handle_control(USBDevice
*dev
, USBPacket
*p
,
1014 int request
, int value
, int index
, int length
, uint8_t *data
)
1016 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
1017 struct usbdevfs_urb
*urb
;
1022 * Process certain standard device requests.
1023 * These are infrequent and are processed synchronously.
1026 /* Note request is (bRequestType << 8) | bRequest */
1027 trace_usb_host_req_control(s
->bus_num
, s
->addr
, request
, value
, index
);
1030 case DeviceOutRequest
| USB_REQ_SET_ADDRESS
:
1031 return usb_host_set_address(s
, value
);
1033 case DeviceOutRequest
| USB_REQ_SET_CONFIGURATION
:
1034 return usb_host_set_config(s
, value
& 0xff);
1036 case InterfaceOutRequest
| USB_REQ_SET_INTERFACE
:
1037 return usb_host_set_interface(s
, index
, value
);
1040 /* The rest are asynchronous */
1042 if (length
> sizeof(dev
->data_buf
)) {
1043 fprintf(stderr
, "husb: ctrl buffer too small (%d > %zu)\n",
1044 length
, sizeof(dev
->data_buf
));
1045 return USB_RET_STALL
;
1048 aurb
= async_alloc(s
);
1052 * Setup ctrl transfer.
1054 * s->ctrl is laid out such that data buffer immediately follows
1055 * 'req' struct which is exactly what usbdevfs expects.
1059 urb
->type
= USBDEVFS_URB_TYPE_CONTROL
;
1060 urb
->endpoint
= p
->ep
->nr
;
1062 urb
->buffer
= &dev
->setup_buf
;
1063 urb
->buffer_length
= length
+ 8;
1065 urb
->usercontext
= s
;
1067 trace_usb_host_urb_submit(s
->bus_num
, s
->addr
, aurb
,
1068 urb
->buffer_length
, aurb
->more
);
1069 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
1071 DPRINTF("husb: submit ctrl. len %u aurb %p\n", urb
->buffer_length
, aurb
);
1074 DPRINTF("husb: submit failed. errno %d\n", errno
);
1082 return USB_RET_STALL
;
1086 return USB_RET_ASYNC
;
1089 static uint8_t usb_linux_get_alt_setting(USBHostDevice
*s
,
1090 uint8_t configuration
, uint8_t interface
)
1092 char device_name
[64], line
[1024];
1095 sprintf(device_name
, "%d-%s:%d.%d", s
->bus_num
, s
->port
,
1096 (int)configuration
, (int)interface
);
1098 if (!usb_host_read_file(line
, sizeof(line
), "bAlternateSetting",
1100 /* Assume alt 0 on error */
1103 if (sscanf(line
, "%d", &alt_setting
) != 1) {
1104 /* Assume alt 0 on error */
1110 /* returns 1 on problem encountered or 0 for success */
1111 static int usb_linux_update_endp_table(USBHostDevice
*s
)
1113 uint8_t *descriptors
;
1114 uint8_t devep
, type
, alt_interface
;
1116 int interface
, length
, i
, ep
, pid
;
1117 struct endp_data
*epd
;
1119 usb_ep_init(&s
->dev
);
1121 if (s
->dev
.configuration
== 0) {
1122 /* not configured yet -- leave all endpoints disabled */
1126 /* get the desired configuration, interface, and endpoint descriptors
1127 * from device description */
1128 descriptors
= &s
->descr
[18];
1129 length
= s
->descr_len
- 18;
1132 while (i
< length
) {
1133 if (descriptors
[i
+ 1] != USB_DT_CONFIG
) {
1134 fprintf(stderr
, "invalid descriptor data\n");
1136 } else if (descriptors
[i
+ 5] != s
->dev
.configuration
) {
1137 DPRINTF("not requested configuration %d\n", s
->dev
.configuration
);
1138 i
+= (descriptors
[i
+ 3] << 8) + descriptors
[i
+ 2];
1141 i
+= descriptors
[i
];
1143 if (descriptors
[i
+ 1] != USB_DT_INTERFACE
||
1144 (descriptors
[i
+ 1] == USB_DT_INTERFACE
&&
1145 descriptors
[i
+ 4] == 0)) {
1146 i
+= descriptors
[i
];
1150 interface
= descriptors
[i
+ 2];
1151 alt_interface
= usb_linux_get_alt_setting(s
, s
->dev
.configuration
,
1154 /* the current interface descriptor is the active interface
1155 * and has endpoints */
1156 if (descriptors
[i
+ 3] != alt_interface
) {
1157 i
+= descriptors
[i
];
1161 /* advance to the endpoints */
1162 while (i
< length
&& descriptors
[i
+1] != USB_DT_ENDPOINT
) {
1163 i
+= descriptors
[i
];
1169 while (i
< length
) {
1170 if (descriptors
[i
+ 1] != USB_DT_ENDPOINT
) {
1174 devep
= descriptors
[i
+ 2];
1175 pid
= (devep
& USB_DIR_IN
) ? USB_TOKEN_IN
: USB_TOKEN_OUT
;
1178 fprintf(stderr
, "usb-linux: invalid ep descriptor, ep == 0\n");
1182 type
= descriptors
[i
+ 3] & 0x3;
1183 raw
= descriptors
[i
+ 4] + (descriptors
[i
+ 5] << 8);
1184 usb_ep_set_max_packet_size(&s
->dev
, pid
, ep
, raw
);
1185 assert(usb_ep_get_type(&s
->dev
, pid
, ep
) ==
1186 USB_ENDPOINT_XFER_INVALID
);
1187 usb_ep_set_type(&s
->dev
, pid
, ep
, type
);
1188 usb_ep_set_ifnum(&s
->dev
, pid
, ep
, interface
);
1190 epd
= get_endp(s
, pid
, ep
);
1193 i
+= descriptors
[i
];
1197 usb_ep_dump(&s
->dev
);
1203 * Check if we can safely redirect a usb2 device to a usb1 virtual controller,
1204 * this function assumes this is safe, if:
1205 * 1) There are no isoc endpoints
1206 * 2) There are no interrupt endpoints with a max_packet_size > 64
1207 * Note bulk endpoints with a max_packet_size > 64 in theory also are not
1208 * usb1 compatible, but in practice this seems to work fine.
1210 static int usb_linux_full_speed_compat(USBHostDevice
*dev
)
1215 * usb_linux_update_endp_table only registers info about ep in the current
1216 * interface altsettings, so we need to parse the descriptors again.
1218 for (i
= 0; (i
+ 5) < dev
->descr_len
; i
+= dev
->descr
[i
]) {
1219 if (dev
->descr
[i
+ 1] == USB_DT_ENDPOINT
) {
1220 switch (dev
->descr
[i
+ 3] & 0x3) {
1221 case 0x00: /* CONTROL */
1223 case 0x01: /* ISO */
1225 case 0x02: /* BULK */
1227 case 0x03: /* INTERRUPT */
1228 packet_size
= dev
->descr
[i
+ 4] + (dev
->descr
[i
+ 5] << 8);
1229 if (packet_size
> 64)
1238 static int usb_host_open(USBHostDevice
*dev
, int bus_num
,
1239 int addr
, const char *port
,
1240 const char *prod_name
, int speed
)
1244 trace_usb_host_open_started(bus_num
, addr
);
1246 if (dev
->fd
!= -1) {
1250 fd
= usb_host_open_device(bus_num
, addr
);
1254 DPRINTF("husb: opened %s\n", buf
);
1256 dev
->bus_num
= bus_num
;
1258 strcpy(dev
->port
, port
);
1261 /* read the device description */
1262 dev
->descr_len
= read(fd
, dev
->descr
, sizeof(dev
->descr
));
1263 if (dev
->descr_len
<= 0) {
1264 perror("husb: reading device data failed");
1271 printf("=== begin dumping device descriptor data ===\n");
1272 for (x
= 0; x
< dev
->descr_len
; x
++) {
1273 printf("%02x ", dev
->descr
[x
]);
1275 printf("\n=== end dumping device descriptor data ===\n");
1280 /* start unconfigured -- we'll wait for the guest to set a configuration */
1281 if (!usb_host_claim_interfaces(dev
, 0)) {
1285 ret
= usb_linux_update_endp_table(dev
);
1291 struct usbdevfs_connectinfo ci
;
1293 ret
= ioctl(fd
, USBDEVFS_CONNECTINFO
, &ci
);
1295 perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
1300 speed
= USB_SPEED_LOW
;
1302 speed
= USB_SPEED_HIGH
;
1305 dev
->dev
.speed
= speed
;
1306 dev
->dev
.speedmask
= (1 << speed
);
1307 if (dev
->dev
.speed
== USB_SPEED_HIGH
&& usb_linux_full_speed_compat(dev
)) {
1308 dev
->dev
.speedmask
|= USB_SPEED_MASK_FULL
;
1311 trace_usb_host_open_success(bus_num
, addr
);
1313 if (!prod_name
|| prod_name
[0] == '\0') {
1314 snprintf(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1315 "host:%d.%d", bus_num
, addr
);
1317 pstrcpy(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1321 ret
= usb_device_attach(&dev
->dev
);
1326 /* USB devio uses 'write' flag to check for async completions */
1327 qemu_set_fd_handler(dev
->fd
, NULL
, async_complete
, dev
);
1332 trace_usb_host_open_failure(bus_num
, addr
);
1333 if (dev
->fd
!= -1) {
1340 static int usb_host_close(USBHostDevice
*dev
)
1344 if (dev
->fd
== -1) {
1348 trace_usb_host_close(dev
->bus_num
, dev
->addr
);
1350 qemu_set_fd_handler(dev
->fd
, NULL
, NULL
, NULL
);
1352 for (i
= 1; i
<= USB_MAX_ENDPOINTS
; i
++) {
1353 if (is_isoc(dev
, USB_TOKEN_IN
, i
)) {
1354 usb_host_stop_n_free_iso(dev
, USB_TOKEN_IN
, i
);
1356 if (is_isoc(dev
, USB_TOKEN_OUT
, i
)) {
1357 usb_host_stop_n_free_iso(dev
, USB_TOKEN_OUT
, i
);
1360 async_complete(dev
);
1362 if (dev
->dev
.attached
) {
1363 usb_device_detach(&dev
->dev
);
1365 usb_host_do_reset(dev
);
1371 static void usb_host_exit_notifier(struct Notifier
*n
, void *data
)
1373 USBHostDevice
*s
= container_of(n
, USBHostDevice
, exit
);
1375 usb_host_release_port(s
);
1377 usb_host_do_reset(s
);;
1381 static int usb_host_initfn(USBDevice
*dev
)
1383 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
1385 dev
->auto_attach
= 0;
1389 QTAILQ_INSERT_TAIL(&hostdevs
, s
, next
);
1390 s
->exit
.notify
= usb_host_exit_notifier
;
1391 qemu_add_exit_notifier(&s
->exit
);
1392 usb_host_auto_check(NULL
);
1394 if (s
->match
.bus_num
!= 0 && s
->match
.port
!= NULL
) {
1395 usb_host_claim_port(s
);
1400 static const VMStateDescription vmstate_usb_host
= {
1405 static Property usb_host_dev_properties
[] = {
1406 DEFINE_PROP_UINT32("hostbus", USBHostDevice
, match
.bus_num
, 0),
1407 DEFINE_PROP_UINT32("hostaddr", USBHostDevice
, match
.addr
, 0),
1408 DEFINE_PROP_STRING("hostport", USBHostDevice
, match
.port
),
1409 DEFINE_PROP_HEX32("vendorid", USBHostDevice
, match
.vendor_id
, 0),
1410 DEFINE_PROP_HEX32("productid", USBHostDevice
, match
.product_id
, 0),
1411 DEFINE_PROP_UINT32("isobufs", USBHostDevice
, iso_urb_count
, 4),
1412 DEFINE_PROP_END_OF_LIST(),
1415 static void usb_host_class_initfn(ObjectClass
*klass
, void *data
)
1417 DeviceClass
*dc
= DEVICE_CLASS(klass
);
1418 USBDeviceClass
*uc
= USB_DEVICE_CLASS(klass
);
1420 uc
->init
= usb_host_initfn
;
1421 uc
->product_desc
= "USB Host Device";
1422 uc
->cancel_packet
= usb_host_async_cancel
;
1423 uc
->handle_data
= usb_host_handle_data
;
1424 uc
->handle_control
= usb_host_handle_control
;
1425 uc
->handle_reset
= usb_host_handle_reset
;
1426 uc
->handle_destroy
= usb_host_handle_destroy
;
1427 dc
->vmsd
= &vmstate_usb_host
;
1428 dc
->props
= usb_host_dev_properties
;
1431 static TypeInfo usb_host_dev_info
= {
1433 .parent
= TYPE_USB_DEVICE
,
1434 .instance_size
= sizeof(USBHostDevice
),
1435 .class_init
= usb_host_class_initfn
,
1438 static void usb_host_register_types(void)
1440 type_register_static(&usb_host_dev_info
);
1441 usb_legacy_register("usb-host", "host", usb_host_device_open
);
1444 type_init(usb_host_register_types
)
1446 USBDevice
*usb_host_device_open(const char *devname
)
1448 struct USBAutoFilter filter
;
1452 dev
= usb_create(NULL
/* FIXME */, "usb-host");
1454 if (strstr(devname
, "auto:")) {
1455 if (parse_filter(devname
, &filter
) < 0) {
1459 if ((p
= strchr(devname
, '.'))) {
1460 filter
.bus_num
= strtoul(devname
, NULL
, 0);
1461 filter
.addr
= strtoul(p
+ 1, NULL
, 0);
1462 filter
.vendor_id
= 0;
1463 filter
.product_id
= 0;
1464 } else if ((p
= strchr(devname
, ':'))) {
1467 filter
.vendor_id
= strtoul(devname
, NULL
, 16);
1468 filter
.product_id
= strtoul(p
+ 1, NULL
, 16);
1474 qdev_prop_set_uint32(&dev
->qdev
, "hostbus", filter
.bus_num
);
1475 qdev_prop_set_uint32(&dev
->qdev
, "hostaddr", filter
.addr
);
1476 qdev_prop_set_uint32(&dev
->qdev
, "vendorid", filter
.vendor_id
);
1477 qdev_prop_set_uint32(&dev
->qdev
, "productid", filter
.product_id
);
1478 qdev_init_nofail(&dev
->qdev
);
1482 qdev_free(&dev
->qdev
);
1486 int usb_host_device_close(const char *devname
)
1489 char product_name
[PRODUCT_NAME_SZ
];
1493 if (strstr(devname
, "auto:")) {
1494 return usb_host_auto_del(devname
);
1496 if (usb_host_find_device(&bus_num
, &addr
, product_name
,
1497 sizeof(product_name
), devname
) < 0) {
1500 s
= hostdev_find(bus_num
, addr
);
1502 usb_device_delete_addr(s
->bus_num
, s
->dev
.addr
);
1511 * Read sys file-system device file
1513 * @line address of buffer to put file contents in
1514 * @line_size size of line
1515 * @device_file path to device file (printf format string)
1516 * @device_name device being opened (inserted into device_file)
1518 * @return 0 failed, 1 succeeded ('line' contains data)
1520 static int usb_host_read_file(char *line
, size_t line_size
,
1521 const char *device_file
, const char *device_name
)
1525 char filename
[PATH_MAX
];
1527 snprintf(filename
, PATH_MAX
, "/sys/bus/usb/devices/%s/%s", device_name
,
1529 f
= fopen(filename
, "r");
1531 ret
= fgets(line
, line_size
, f
) != NULL
;
1539 * Use /sys/bus/usb/devices/ directory to determine host's USB
1542 * This code is based on Robert Schiele's original patches posted to
1543 * the Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
1545 static int usb_host_scan(void *opaque
, USBScanFunc
*func
)
1549 int bus_num
, addr
, speed
, class_id
, product_id
, vendor_id
;
1551 char port
[MAX_PORTLEN
];
1552 char product_name
[512];
1555 dir
= opendir("/sys/bus/usb/devices");
1557 perror("husb: opendir /sys/bus/usb/devices");
1558 fprintf(stderr
, "husb: please make sure sysfs is mounted at /sys\n");
1562 while ((de
= readdir(dir
))) {
1563 if (de
->d_name
[0] != '.' && !strchr(de
->d_name
, ':')) {
1564 if (sscanf(de
->d_name
, "%d-%7[0-9.]", &bus_num
, port
) < 2) {
1568 if (!usb_host_read_file(line
, sizeof(line
), "devnum", de
->d_name
)) {
1571 if (sscanf(line
, "%d", &addr
) != 1) {
1574 if (!usb_host_read_file(line
, sizeof(line
), "bDeviceClass",
1578 if (sscanf(line
, "%x", &class_id
) != 1) {
1582 if (!usb_host_read_file(line
, sizeof(line
), "idVendor",
1586 if (sscanf(line
, "%x", &vendor_id
) != 1) {
1589 if (!usb_host_read_file(line
, sizeof(line
), "idProduct",
1593 if (sscanf(line
, "%x", &product_id
) != 1) {
1596 if (!usb_host_read_file(line
, sizeof(line
), "product",
1600 if (strlen(line
) > 0) {
1601 line
[strlen(line
) - 1] = '\0';
1603 pstrcpy(product_name
, sizeof(product_name
), line
);
1606 if (!usb_host_read_file(line
, sizeof(line
), "speed", de
->d_name
)) {
1609 if (!strcmp(line
, "5000\n")) {
1610 speed
= USB_SPEED_SUPER
;
1611 } else if (!strcmp(line
, "480\n")) {
1612 speed
= USB_SPEED_HIGH
;
1613 } else if (!strcmp(line
, "1.5\n")) {
1614 speed
= USB_SPEED_LOW
;
1616 speed
= USB_SPEED_FULL
;
1619 ret
= func(opaque
, bus_num
, addr
, port
, class_id
, vendor_id
,
1620 product_id
, product_name
, speed
);
1633 static QEMUTimer
*usb_auto_timer
;
1635 static int usb_host_auto_scan(void *opaque
, int bus_num
,
1636 int addr
, const char *port
,
1637 int class_id
, int vendor_id
, int product_id
,
1638 const char *product_name
, int speed
)
1640 struct USBAutoFilter
*f
;
1641 struct USBHostDevice
*s
;
1647 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1650 if (f
->bus_num
> 0 && f
->bus_num
!= bus_num
) {
1653 if (f
->addr
> 0 && f
->addr
!= addr
) {
1656 if (f
->port
!= NULL
&& (port
== NULL
|| strcmp(f
->port
, port
) != 0)) {
1660 if (f
->vendor_id
> 0 && f
->vendor_id
!= vendor_id
) {
1664 if (f
->product_id
> 0 && f
->product_id
!= product_id
) {
1667 /* We got a match */
1669 if (s
->errcount
>= 3) {
1673 /* Already attached ? */
1677 DPRINTF("husb: auto open: bus_num %d addr %d\n", bus_num
, addr
);
1679 if (usb_host_open(s
, bus_num
, addr
, port
, product_name
, speed
) < 0) {
1688 static void usb_host_auto_check(void *unused
)
1690 struct USBHostDevice
*s
;
1691 int unconnected
= 0;
1693 usb_host_scan(NULL
, usb_host_auto_scan
);
1695 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1705 if (unconnected
== 0) {
1706 /* nothing to watch */
1707 if (usb_auto_timer
) {
1708 qemu_del_timer(usb_auto_timer
);
1709 trace_usb_host_auto_scan_disabled();
1714 if (!usb_auto_timer
) {
1715 usb_auto_timer
= qemu_new_timer_ms(rt_clock
, usb_host_auto_check
, NULL
);
1716 if (!usb_auto_timer
) {
1719 trace_usb_host_auto_scan_enabled();
1721 qemu_mod_timer(usb_auto_timer
, qemu_get_clock_ms(rt_clock
) + 2000);
1725 * Autoconnect filter
1727 * auto:bus:dev[:vid:pid]
1728 * auto:bus.dev[:vid:pid]
1730 * bus - bus number (dec, * means any)
1731 * dev - device number (dec, * means any)
1732 * vid - vendor id (hex, * means any)
1733 * pid - product id (hex, * means any)
1735 * See 'lsusb' output.
1737 static int parse_filter(const char *spec
, struct USBAutoFilter
*f
)
1739 enum { BUS
, DEV
, VID
, PID
, DONE
};
1740 const char *p
= spec
;
1748 for (i
= BUS
; i
< DONE
; i
++) {
1749 p
= strpbrk(p
, ":.");
1759 case BUS
: f
->bus_num
= strtol(p
, NULL
, 10); break;
1760 case DEV
: f
->addr
= strtol(p
, NULL
, 10); break;
1761 case VID
: f
->vendor_id
= strtol(p
, NULL
, 16); break;
1762 case PID
: f
->product_id
= strtol(p
, NULL
, 16); break;
1767 fprintf(stderr
, "husb: invalid auto filter spec %s\n", spec
);
1774 /**********************/
1775 /* USB host device info */
1777 struct usb_class_info
{
1779 const char *class_name
;
1782 static const struct usb_class_info usb_class_info
[] = {
1783 { USB_CLASS_AUDIO
, "Audio"},
1784 { USB_CLASS_COMM
, "Communication"},
1785 { USB_CLASS_HID
, "HID"},
1786 { USB_CLASS_HUB
, "Hub" },
1787 { USB_CLASS_PHYSICAL
, "Physical" },
1788 { USB_CLASS_PRINTER
, "Printer" },
1789 { USB_CLASS_MASS_STORAGE
, "Storage" },
1790 { USB_CLASS_CDC_DATA
, "Data" },
1791 { USB_CLASS_APP_SPEC
, "Application Specific" },
1792 { USB_CLASS_VENDOR_SPEC
, "Vendor Specific" },
1793 { USB_CLASS_STILL_IMAGE
, "Still Image" },
1794 { USB_CLASS_CSCID
, "Smart Card" },
1795 { USB_CLASS_CONTENT_SEC
, "Content Security" },
1799 static const char *usb_class_str(uint8_t class)
1801 const struct usb_class_info
*p
;
1802 for(p
= usb_class_info
; p
->class != -1; p
++) {
1803 if (p
->class == class) {
1807 return p
->class_name
;
1810 static void usb_info_device(Monitor
*mon
, int bus_num
,
1811 int addr
, const char *port
,
1812 int class_id
, int vendor_id
, int product_id
,
1813 const char *product_name
,
1816 const char *class_str
, *speed_str
;
1822 case USB_SPEED_FULL
:
1825 case USB_SPEED_HIGH
:
1828 case USB_SPEED_SUPER
:
1836 monitor_printf(mon
, " Bus %d, Addr %d, Port %s, Speed %s Mb/s\n",
1837 bus_num
, addr
, port
, speed_str
);
1838 class_str
= usb_class_str(class_id
);
1840 monitor_printf(mon
, " %s:", class_str
);
1842 monitor_printf(mon
, " Class %02x:", class_id
);
1844 monitor_printf(mon
, " USB device %04x:%04x", vendor_id
, product_id
);
1845 if (product_name
[0] != '\0') {
1846 monitor_printf(mon
, ", %s", product_name
);
1848 monitor_printf(mon
, "\n");
1851 static int usb_host_info_device(void *opaque
, int bus_num
, int addr
,
1852 const char *path
, int class_id
,
1853 int vendor_id
, int product_id
,
1854 const char *product_name
,
1857 Monitor
*mon
= opaque
;
1859 usb_info_device(mon
, bus_num
, addr
, path
, class_id
, vendor_id
, product_id
,
1860 product_name
, speed
);
1864 static void dec2str(int val
, char *str
, size_t size
)
1867 snprintf(str
, size
, "*");
1869 snprintf(str
, size
, "%d", val
);
1873 static void hex2str(int val
, char *str
, size_t size
)
1876 snprintf(str
, size
, "*");
1878 snprintf(str
, size
, "%04x", val
);
1882 void usb_host_info(Monitor
*mon
)
1884 struct USBAutoFilter
*f
;
1885 struct USBHostDevice
*s
;
1887 usb_host_scan(mon
, usb_host_info_device
);
1889 if (QTAILQ_EMPTY(&hostdevs
)) {
1893 monitor_printf(mon
, " Auto filters:\n");
1894 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1895 char bus
[10], addr
[10], vid
[10], pid
[10];
1897 dec2str(f
->bus_num
, bus
, sizeof(bus
));
1898 dec2str(f
->addr
, addr
, sizeof(addr
));
1899 hex2str(f
->vendor_id
, vid
, sizeof(vid
));
1900 hex2str(f
->product_id
, pid
, sizeof(pid
));
1901 monitor_printf(mon
, " Bus %s, Addr %s, Port %s, ID %s:%s\n",
1902 bus
, addr
, f
->port
? f
->port
: "*", vid
, pid
);