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>
41 #include <linux/usbdevice_fs.h>
42 #include <linux/version.h>
45 /* We redefine it to avoid version problems */
46 struct usb_ctrltransfer
{
56 typedef int USBScanFunc(void *opaque
, int bus_num
, int addr
, char *port
,
57 int class_id
, int vendor_id
, int product_id
,
58 const char *product_name
, int speed
);
63 #define DPRINTF printf
68 #define USBDBG_DEVOPENED "husb: opened %s/devices\n"
70 #define USBPROCBUS_PATH "/proc/bus/usb"
71 #define PRODUCT_NAME_SZ 32
72 #define MAX_ENDPOINTS 15
73 #define MAX_PORTLEN 16
74 #define USBDEVBUS_PATH "/dev/bus/usb"
75 #define USBSYSBUS_PATH "/sys/bus/usb"
77 static char *usb_host_device_path
;
84 static int usb_fs_type
;
86 /* endpoint association data */
87 #define ISO_FRAME_DESC_PER_URB 32
88 #define INVALID_EP_TYPE 255
90 /* devio.c limits single requests to 16k */
91 #define MAX_USBFS_BUFFER_SIZE 16384
93 typedef struct AsyncURB AsyncURB
;
106 struct USBAutoFilter
{
114 typedef struct USBHostDevice
{
123 uint32_t iso_urb_count
;
126 struct endp_data endp_table
[MAX_ENDPOINTS
];
127 QLIST_HEAD(, AsyncURB
) aurbs
;
129 /* Host side address */
132 char port
[MAX_PORTLEN
];
133 struct USBAutoFilter match
;
135 QTAILQ_ENTRY(USBHostDevice
) next
;
138 static QTAILQ_HEAD(, USBHostDevice
) hostdevs
= QTAILQ_HEAD_INITIALIZER(hostdevs
);
140 static int usb_host_close(USBHostDevice
*dev
);
141 static int parse_filter(const char *spec
, struct USBAutoFilter
*f
);
142 static void usb_host_auto_check(void *unused
);
143 static int usb_host_read_file(char *line
, size_t line_size
,
144 const char *device_file
, const char *device_name
);
146 static struct endp_data
*get_endp(USBHostDevice
*s
, int ep
)
148 return s
->endp_table
+ ep
- 1;
151 static int is_isoc(USBHostDevice
*s
, int ep
)
153 return get_endp(s
, ep
)->type
== USBDEVFS_URB_TYPE_ISO
;
156 static int is_valid(USBHostDevice
*s
, int ep
)
158 return get_endp(s
, ep
)->type
!= INVALID_EP_TYPE
;
161 static int is_halted(USBHostDevice
*s
, int ep
)
163 return get_endp(s
, ep
)->halted
;
166 static void clear_halt(USBHostDevice
*s
, int ep
)
168 get_endp(s
, ep
)->halted
= 0;
171 static void set_halt(USBHostDevice
*s
, int ep
)
173 get_endp(s
, ep
)->halted
= 1;
176 static int is_iso_started(USBHostDevice
*s
, int ep
)
178 return get_endp(s
, ep
)->iso_started
;
181 static void clear_iso_started(USBHostDevice
*s
, int ep
)
183 get_endp(s
, ep
)->iso_started
= 0;
186 static void set_iso_started(USBHostDevice
*s
, int ep
)
188 struct endp_data
*e
= get_endp(s
, ep
);
189 if (!e
->iso_started
) {
195 static int change_iso_inflight(USBHostDevice
*s
, int ep
, int value
)
197 struct endp_data
*e
= get_endp(s
, ep
);
199 e
->inflight
+= value
;
203 static void set_iso_urb(USBHostDevice
*s
, int ep
, AsyncURB
*iso_urb
)
205 get_endp(s
, ep
)->iso_urb
= iso_urb
;
208 static AsyncURB
*get_iso_urb(USBHostDevice
*s
, int ep
)
210 return get_endp(s
, ep
)->iso_urb
;
213 static void set_iso_urb_idx(USBHostDevice
*s
, int ep
, int i
)
215 get_endp(s
, ep
)->iso_urb_idx
= i
;
218 static int get_iso_urb_idx(USBHostDevice
*s
, int ep
)
220 return get_endp(s
, ep
)->iso_urb_idx
;
223 static void set_iso_buffer_used(USBHostDevice
*s
, int ep
, int i
)
225 get_endp(s
, ep
)->iso_buffer_used
= i
;
228 static int get_iso_buffer_used(USBHostDevice
*s
, int ep
)
230 return get_endp(s
, ep
)->iso_buffer_used
;
233 static void set_max_packet_size(USBHostDevice
*s
, int ep
, uint8_t *descriptor
)
235 int raw
= descriptor
[4] + (descriptor
[5] << 8);
236 int size
, microframes
;
239 switch ((raw
>> 11) & 3) {
240 case 1: microframes
= 2; break;
241 case 2: microframes
= 3; break;
242 default: microframes
= 1; break;
244 get_endp(s
, ep
)->max_packet_size
= size
* microframes
;
247 static int get_max_packet_size(USBHostDevice
*s
, int ep
)
249 return get_endp(s
, ep
)->max_packet_size
;
254 * We always allocate iso packet descriptors even for bulk transfers
255 * to simplify allocation and casts.
259 struct usbdevfs_urb urb
;
260 struct usbdevfs_iso_packet_desc isocpd
[ISO_FRAME_DESC_PER_URB
];
262 QLIST_ENTRY(AsyncURB
) next
;
264 /* For regular async urbs */
266 int more
; /* large transfer, more urbs follow */
268 /* For buffered iso handling */
269 int iso_frame_idx
; /* -1 means in flight */
272 static AsyncURB
*async_alloc(USBHostDevice
*s
)
274 AsyncURB
*aurb
= g_malloc0(sizeof(AsyncURB
));
276 QLIST_INSERT_HEAD(&s
->aurbs
, aurb
, next
);
280 static void async_free(AsyncURB
*aurb
)
282 QLIST_REMOVE(aurb
, next
);
286 static void do_disconnect(USBHostDevice
*s
)
288 printf("husb: device %d.%d disconnected\n",
289 s
->bus_num
, s
->addr
);
291 usb_host_auto_check(NULL
);
294 static void async_complete(void *opaque
)
296 USBHostDevice
*s
= opaque
;
303 int r
= ioctl(s
->fd
, USBDEVFS_REAPURBNDELAY
, &aurb
);
305 if (errno
== EAGAIN
) {
307 fprintf(stderr
, "husb: %d iso urbs finished at once\n", urbs
);
311 if (errno
== ENODEV
&& !s
->closing
) {
316 DPRINTF("husb: async. reap urb failed errno %d\n", errno
);
320 DPRINTF("husb: async completed. aurb %p status %d alen %d\n",
321 aurb
, aurb
->urb
.status
, aurb
->urb
.actual_length
);
323 /* If this is a buffered iso urb mark it as complete and don't do
324 anything else (it is handled further in usb_host_handle_iso_data) */
325 if (aurb
->iso_frame_idx
== -1) {
327 if (aurb
->urb
.status
== -EPIPE
) {
328 set_halt(s
, aurb
->urb
.endpoint
& 0xf);
330 aurb
->iso_frame_idx
= 0;
332 inflight
= change_iso_inflight(s
, aurb
->urb
.endpoint
& 0xf, -1);
333 if (inflight
== 0 && is_iso_started(s
, aurb
->urb
.endpoint
& 0xf)) {
334 fprintf(stderr
, "husb: out of buffers for iso stream\n");
342 switch (aurb
->urb
.status
) {
344 p
->result
+= aurb
->urb
.actual_length
;
348 set_halt(s
, p
->devep
);
349 p
->result
= USB_RET_STALL
;
353 p
->result
= USB_RET_NAK
;
357 if (aurb
->urb
.type
== USBDEVFS_URB_TYPE_CONTROL
) {
358 usb_generic_async_ctrl_complete(&s
->dev
, p
);
359 } else if (!aurb
->more
) {
360 usb_packet_complete(&s
->dev
, p
);
368 static void usb_host_async_cancel(USBDevice
*dev
, USBPacket
*p
)
370 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
373 QLIST_FOREACH(aurb
, &s
->aurbs
, next
) {
374 if (p
!= aurb
->packet
) {
378 DPRINTF("husb: async cancel: packet %p, aurb %p\n", p
, aurb
);
380 /* Mark it as dead (see async_complete above) */
383 int r
= ioctl(s
->fd
, USBDEVFS_DISCARDURB
, aurb
);
385 DPRINTF("husb: async. discard urb failed errno %d\n", errno
);
390 static int usb_host_claim_interfaces(USBHostDevice
*dev
, int configuration
)
392 const char *op
= NULL
;
393 int dev_descr_len
, config_descr_len
;
394 int interface
, nb_interfaces
;
397 if (configuration
== 0) /* address state - ignore */
400 DPRINTF("husb: claiming interfaces. config %d\n", configuration
);
403 dev_descr_len
= dev
->descr
[0];
404 if (dev_descr_len
> dev
->descr_len
) {
405 fprintf(stderr
, "husb: update iface failed. descr too short\n");
410 while (i
< dev
->descr_len
) {
411 DPRINTF("husb: i is %d, descr_len is %d, dl %d, dt %d\n",
413 dev
->descr
[i
], dev
->descr
[i
+1]);
415 if (dev
->descr
[i
+1] != USB_DT_CONFIG
) {
419 config_descr_len
= dev
->descr
[i
];
421 printf("husb: config #%d need %d\n", dev
->descr
[i
+ 5], configuration
);
423 if (configuration
< 0 || configuration
== dev
->descr
[i
+ 5]) {
424 configuration
= dev
->descr
[i
+ 5];
428 i
+= config_descr_len
;
431 if (i
>= dev
->descr_len
) {
433 "husb: update iface failed. no matching configuration\n");
436 nb_interfaces
= dev
->descr
[i
+ 4];
438 #ifdef USBDEVFS_DISCONNECT
439 /* earlier Linux 2.4 do not support that */
441 struct usbdevfs_ioctl ctrl
;
442 for (interface
= 0; interface
< nb_interfaces
; interface
++) {
443 ctrl
.ioctl_code
= USBDEVFS_DISCONNECT
;
444 ctrl
.ifno
= interface
;
446 op
= "USBDEVFS_DISCONNECT";
447 ret
= ioctl(dev
->fd
, USBDEVFS_IOCTL
, &ctrl
);
448 if (ret
< 0 && errno
!= ENODATA
) {
455 /* XXX: only grab if all interfaces are free */
456 for (interface
= 0; interface
< nb_interfaces
; interface
++) {
457 op
= "USBDEVFS_CLAIMINTERFACE";
458 ret
= ioctl(dev
->fd
, USBDEVFS_CLAIMINTERFACE
, &interface
);
460 if (errno
== EBUSY
) {
461 printf("husb: update iface. device already grabbed\n");
463 perror("husb: failed to claim interface");
469 printf("husb: %d interfaces claimed for configuration %d\n",
470 nb_interfaces
, configuration
);
472 dev
->ninterfaces
= nb_interfaces
;
473 dev
->configuration
= configuration
;
477 if (errno
== ENODEV
) {
484 static int usb_host_release_interfaces(USBHostDevice
*s
)
488 DPRINTF("husb: releasing interfaces\n");
490 for (i
= 0; i
< s
->ninterfaces
; i
++) {
491 ret
= ioctl(s
->fd
, USBDEVFS_RELEASEINTERFACE
, &i
);
493 perror("husb: failed to release interface");
501 static void usb_host_handle_reset(USBDevice
*dev
)
503 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
505 DPRINTF("husb: reset device %u.%u\n", s
->bus_num
, s
->addr
);
507 ioctl(s
->fd
, USBDEVFS_RESET
);
509 usb_host_claim_interfaces(s
, s
->configuration
);
512 static void usb_host_handle_destroy(USBDevice
*dev
)
514 USBHostDevice
*s
= (USBHostDevice
*)dev
;
517 QTAILQ_REMOVE(&hostdevs
, s
, next
);
518 qemu_remove_exit_notifier(&s
->exit
);
521 static int usb_linux_update_endp_table(USBHostDevice
*s
);
523 /* iso data is special, we need to keep enough urbs in flight to make sure
524 that the controller never runs out of them, otherwise the device will
525 likely suffer a buffer underrun / overrun. */
526 static AsyncURB
*usb_host_alloc_iso(USBHostDevice
*s
, uint8_t ep
, int in
)
529 int i
, j
, len
= get_max_packet_size(s
, ep
);
531 aurb
= g_malloc0(s
->iso_urb_count
* sizeof(*aurb
));
532 for (i
= 0; i
< s
->iso_urb_count
; i
++) {
533 aurb
[i
].urb
.endpoint
= ep
;
534 aurb
[i
].urb
.buffer_length
= ISO_FRAME_DESC_PER_URB
* len
;
535 aurb
[i
].urb
.buffer
= g_malloc(aurb
[i
].urb
.buffer_length
);
536 aurb
[i
].urb
.type
= USBDEVFS_URB_TYPE_ISO
;
537 aurb
[i
].urb
.flags
= USBDEVFS_URB_ISO_ASAP
;
538 aurb
[i
].urb
.number_of_packets
= ISO_FRAME_DESC_PER_URB
;
539 for (j
= 0 ; j
< ISO_FRAME_DESC_PER_URB
; j
++)
540 aurb
[i
].urb
.iso_frame_desc
[j
].length
= len
;
542 aurb
[i
].urb
.endpoint
|= 0x80;
543 /* Mark as fully consumed (idle) */
544 aurb
[i
].iso_frame_idx
= ISO_FRAME_DESC_PER_URB
;
547 set_iso_urb(s
, ep
, aurb
);
552 static void usb_host_stop_n_free_iso(USBHostDevice
*s
, uint8_t ep
)
555 int i
, ret
, killed
= 0, free
= 1;
557 aurb
= get_iso_urb(s
, ep
);
562 for (i
= 0; i
< s
->iso_urb_count
; i
++) {
564 if (aurb
[i
].iso_frame_idx
== -1) {
565 ret
= ioctl(s
->fd
, USBDEVFS_DISCARDURB
, &aurb
[i
]);
567 printf("husb: discard isoc in urb failed errno %d\n", errno
);
575 /* Make sure any urbs we've killed are reaped before we free them */
580 for (i
= 0; i
< s
->iso_urb_count
; i
++) {
581 g_free(aurb
[i
].urb
.buffer
);
587 printf("husb: leaking iso urbs because of discard failure\n");
588 set_iso_urb(s
, ep
, NULL
);
589 set_iso_urb_idx(s
, ep
, 0);
590 clear_iso_started(s
, ep
);
593 static int urb_status_to_usb_ret(int status
)
597 return USB_RET_STALL
;
603 static int usb_host_handle_iso_data(USBHostDevice
*s
, USBPacket
*p
, int in
)
606 int i
, j
, ret
, max_packet_size
, offset
, len
= 0;
609 max_packet_size
= get_max_packet_size(s
, p
->devep
);
610 if (max_packet_size
== 0)
613 aurb
= get_iso_urb(s
, p
->devep
);
615 aurb
= usb_host_alloc_iso(s
, p
->devep
, in
);
618 i
= get_iso_urb_idx(s
, p
->devep
);
619 j
= aurb
[i
].iso_frame_idx
;
620 if (j
>= 0 && j
< ISO_FRAME_DESC_PER_URB
) {
622 /* Check urb status */
623 if (aurb
[i
].urb
.status
) {
624 len
= urb_status_to_usb_ret(aurb
[i
].urb
.status
);
625 /* Move to the next urb */
626 aurb
[i
].iso_frame_idx
= ISO_FRAME_DESC_PER_URB
- 1;
627 /* Check frame status */
628 } else if (aurb
[i
].urb
.iso_frame_desc
[j
].status
) {
629 len
= urb_status_to_usb_ret(
630 aurb
[i
].urb
.iso_frame_desc
[j
].status
);
631 /* Check the frame fits */
632 } else if (aurb
[i
].urb
.iso_frame_desc
[j
].actual_length
634 printf("husb: received iso data is larger then packet\n");
636 /* All good copy data over */
638 len
= aurb
[i
].urb
.iso_frame_desc
[j
].actual_length
;
639 buf
= aurb
[i
].urb
.buffer
+
640 j
* aurb
[i
].urb
.iso_frame_desc
[0].length
;
641 usb_packet_copy(p
, buf
, len
);
645 offset
= (j
== 0) ? 0 : get_iso_buffer_used(s
, p
->devep
);
647 /* Check the frame fits */
648 if (len
> max_packet_size
) {
649 printf("husb: send iso data is larger then max packet size\n");
653 /* All good copy data over */
654 usb_packet_copy(p
, aurb
[i
].urb
.buffer
+ offset
, len
);
655 aurb
[i
].urb
.iso_frame_desc
[j
].length
= len
;
657 set_iso_buffer_used(s
, p
->devep
, offset
);
659 /* Start the stream once we have buffered enough data */
660 if (!is_iso_started(s
, p
->devep
) && i
== 1 && j
== 8) {
661 set_iso_started(s
, p
->devep
);
664 aurb
[i
].iso_frame_idx
++;
665 if (aurb
[i
].iso_frame_idx
== ISO_FRAME_DESC_PER_URB
) {
666 i
= (i
+ 1) % s
->iso_urb_count
;
667 set_iso_urb_idx(s
, p
->devep
, i
);
671 set_iso_started(s
, p
->devep
);
673 DPRINTF("hubs: iso out error no free buffer, dropping packet\n");
677 if (is_iso_started(s
, p
->devep
)) {
678 /* (Re)-submit all fully consumed / filled urbs */
679 for (i
= 0; i
< s
->iso_urb_count
; i
++) {
680 if (aurb
[i
].iso_frame_idx
== ISO_FRAME_DESC_PER_URB
) {
681 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, &aurb
[i
]);
683 printf("husb error submitting iso urb %d: %d\n", i
, errno
);
684 if (!in
|| len
== 0) {
696 aurb
[i
].iso_frame_idx
= -1;
697 change_iso_inflight(s
, p
->devep
, +1);
705 static int usb_host_handle_data(USBDevice
*dev
, USBPacket
*p
)
707 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
708 struct usbdevfs_urb
*urb
;
710 int ret
, rem
, prem
, v
;
714 if (!is_valid(s
, p
->devep
)) {
718 if (p
->pid
== USB_TOKEN_IN
) {
719 ep
= p
->devep
| 0x80;
724 if (is_halted(s
, p
->devep
)) {
725 ret
= ioctl(s
->fd
, USBDEVFS_CLEAR_HALT
, &ep
);
727 DPRINTF("husb: failed to clear halt. ep 0x%x errno %d\n",
731 clear_halt(s
, p
->devep
);
734 if (is_isoc(s
, p
->devep
)) {
735 return usb_host_handle_iso_data(s
, p
, p
->pid
== USB_TOKEN_IN
);
739 prem
= p
->iov
.iov
[v
].iov_len
;
740 pbuf
= p
->iov
.iov
[v
].iov_base
;
745 assert(v
< p
->iov
.niov
);
746 prem
= p
->iov
.iov
[v
].iov_len
;
747 pbuf
= p
->iov
.iov
[v
].iov_base
;
750 aurb
= async_alloc(s
);
755 urb
->type
= USBDEVFS_URB_TYPE_BULK
;
756 urb
->usercontext
= s
;
758 urb
->buffer_length
= prem
;
760 if (urb
->buffer_length
> MAX_USBFS_BUFFER_SIZE
) {
761 urb
->buffer_length
= MAX_USBFS_BUFFER_SIZE
;
763 pbuf
+= urb
->buffer_length
;
764 prem
-= urb
->buffer_length
;
765 rem
-= urb
->buffer_length
;
770 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
772 DPRINTF("husb: data submit: ep 0x%x, len %u, more %d, packet %p, aurb %p\n",
773 urb
->endpoint
, urb
->buffer_length
, aurb
->more
, p
, aurb
);
776 DPRINTF("husb: submit failed. errno %d\n", errno
);
784 return USB_RET_STALL
;
789 return USB_RET_ASYNC
;
792 static int ctrl_error(void)
794 if (errno
== ETIMEDOUT
) {
797 return USB_RET_STALL
;
801 static int usb_host_set_address(USBHostDevice
*s
, int addr
)
803 DPRINTF("husb: ctrl set addr %u\n", addr
);
808 static int usb_host_set_config(USBHostDevice
*s
, int config
)
810 usb_host_release_interfaces(s
);
812 int ret
= ioctl(s
->fd
, USBDEVFS_SETCONFIGURATION
, &config
);
814 DPRINTF("husb: ctrl set config %d ret %d errno %d\n", config
, ret
, errno
);
819 usb_host_claim_interfaces(s
, config
);
823 static int usb_host_set_interface(USBHostDevice
*s
, int iface
, int alt
)
825 struct usbdevfs_setinterface si
;
828 for (i
= 1; i
<= MAX_ENDPOINTS
; i
++) {
830 usb_host_stop_n_free_iso(s
, i
);
834 si
.interface
= iface
;
836 ret
= ioctl(s
->fd
, USBDEVFS_SETINTERFACE
, &si
);
838 DPRINTF("husb: ctrl set iface %d altset %d ret %d errno %d\n",
839 iface
, alt
, ret
, errno
);
844 usb_linux_update_endp_table(s
);
848 static int usb_host_handle_control(USBDevice
*dev
, USBPacket
*p
,
849 int request
, int value
, int index
, int length
, uint8_t *data
)
851 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
852 struct usbdevfs_urb
*urb
;
857 * Process certain standard device requests.
858 * These are infrequent and are processed synchronously.
861 /* Note request is (bRequestType << 8) | bRequest */
862 DPRINTF("husb: ctrl type 0x%x req 0x%x val 0x%x index %u len %u\n",
863 request
>> 8, request
& 0xff, value
, index
, length
);
866 case DeviceOutRequest
| USB_REQ_SET_ADDRESS
:
867 return usb_host_set_address(s
, value
);
869 case DeviceOutRequest
| USB_REQ_SET_CONFIGURATION
:
870 return usb_host_set_config(s
, value
& 0xff);
872 case InterfaceOutRequest
| USB_REQ_SET_INTERFACE
:
873 return usb_host_set_interface(s
, index
, value
);
876 /* The rest are asynchronous */
878 if (length
> sizeof(dev
->data_buf
)) {
879 fprintf(stderr
, "husb: ctrl buffer too small (%d > %zu)\n",
880 length
, sizeof(dev
->data_buf
));
881 return USB_RET_STALL
;
884 aurb
= async_alloc(s
);
888 * Setup ctrl transfer.
890 * s->ctrl is laid out such that data buffer immediately follows
891 * 'req' struct which is exactly what usbdevfs expects.
895 urb
->type
= USBDEVFS_URB_TYPE_CONTROL
;
896 urb
->endpoint
= p
->devep
;
898 urb
->buffer
= &dev
->setup_buf
;
899 urb
->buffer_length
= length
+ 8;
901 urb
->usercontext
= s
;
903 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
905 DPRINTF("husb: submit ctrl. len %u aurb %p\n", urb
->buffer_length
, aurb
);
908 DPRINTF("husb: submit failed. errno %d\n", errno
);
916 return USB_RET_STALL
;
920 return USB_RET_ASYNC
;
923 static int usb_linux_get_configuration(USBHostDevice
*s
)
925 uint8_t configuration
;
926 struct usb_ctrltransfer ct
;
929 if (usb_fs_type
== USB_FS_SYS
) {
930 char device_name
[32], line
[1024];
933 sprintf(device_name
, "%d-%s", s
->bus_num
, s
->port
);
935 if (!usb_host_read_file(line
, sizeof(line
), "bConfigurationValue",
939 if (sscanf(line
, "%d", &configuration
) != 1) {
942 return configuration
;
946 ct
.bRequestType
= USB_DIR_IN
;
947 ct
.bRequest
= USB_REQ_GET_CONFIGURATION
;
951 ct
.data
= &configuration
;
954 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
956 perror("usb_linux_get_configuration");
960 /* in address state */
961 if (configuration
== 0) {
965 return configuration
;
968 static uint8_t usb_linux_get_alt_setting(USBHostDevice
*s
,
969 uint8_t configuration
, uint8_t interface
)
972 struct usb_ctrltransfer ct
;
975 if (usb_fs_type
== USB_FS_SYS
) {
976 char device_name
[64], line
[1024];
979 sprintf(device_name
, "%d-%s:%d.%d", s
->bus_num
, s
->port
,
980 (int)configuration
, (int)interface
);
982 if (!usb_host_read_file(line
, sizeof(line
), "bAlternateSetting",
986 if (sscanf(line
, "%d", &alt_setting
) != 1) {
993 ct
.bRequestType
= USB_DIR_IN
| USB_RECIP_INTERFACE
;
994 ct
.bRequest
= USB_REQ_GET_INTERFACE
;
996 ct
.wIndex
= interface
;
998 ct
.data
= &alt_setting
;
1000 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
1002 /* Assume alt 0 on error */
1009 /* returns 1 on problem encountered or 0 for success */
1010 static int usb_linux_update_endp_table(USBHostDevice
*s
)
1012 uint8_t *descriptors
;
1013 uint8_t devep
, type
, configuration
, alt_interface
;
1014 int interface
, length
, i
;
1016 for (i
= 0; i
< MAX_ENDPOINTS
; i
++)
1017 s
->endp_table
[i
].type
= INVALID_EP_TYPE
;
1019 i
= usb_linux_get_configuration(s
);
1024 /* get the desired configuration, interface, and endpoint descriptors
1025 * from device description */
1026 descriptors
= &s
->descr
[18];
1027 length
= s
->descr_len
- 18;
1030 if (descriptors
[i
+ 1] != USB_DT_CONFIG
||
1031 descriptors
[i
+ 5] != configuration
) {
1032 DPRINTF("invalid descriptor data - configuration\n");
1035 i
+= descriptors
[i
];
1037 while (i
< length
) {
1038 if (descriptors
[i
+ 1] != USB_DT_INTERFACE
||
1039 (descriptors
[i
+ 1] == USB_DT_INTERFACE
&&
1040 descriptors
[i
+ 4] == 0)) {
1041 i
+= descriptors
[i
];
1045 interface
= descriptors
[i
+ 2];
1046 alt_interface
= usb_linux_get_alt_setting(s
, configuration
, interface
);
1048 /* the current interface descriptor is the active interface
1049 * and has endpoints */
1050 if (descriptors
[i
+ 3] != alt_interface
) {
1051 i
+= descriptors
[i
];
1055 /* advance to the endpoints */
1056 while (i
< length
&& descriptors
[i
+1] != USB_DT_ENDPOINT
) {
1057 i
+= descriptors
[i
];
1063 while (i
< length
) {
1064 if (descriptors
[i
+ 1] != USB_DT_ENDPOINT
) {
1068 devep
= descriptors
[i
+ 2];
1069 if ((devep
& 0x0f) == 0) {
1070 fprintf(stderr
, "usb-linux: invalid ep descriptor, ep == 0\n");
1074 switch (descriptors
[i
+ 3] & 0x3) {
1076 type
= USBDEVFS_URB_TYPE_CONTROL
;
1079 type
= USBDEVFS_URB_TYPE_ISO
;
1080 set_max_packet_size(s
, (devep
& 0xf), descriptors
+ i
);
1083 type
= USBDEVFS_URB_TYPE_BULK
;
1086 type
= USBDEVFS_URB_TYPE_INTERRUPT
;
1089 DPRINTF("usb_host: malformed endpoint type\n");
1090 type
= USBDEVFS_URB_TYPE_BULK
;
1092 s
->endp_table
[(devep
& 0xf) - 1].type
= type
;
1093 s
->endp_table
[(devep
& 0xf) - 1].halted
= 0;
1095 i
+= descriptors
[i
];
1102 * Check if we can safely redirect a usb2 device to a usb1 virtual controller,
1103 * this function assumes this is safe, if:
1104 * 1) There are no isoc endpoints
1105 * 2) There are no interrupt endpoints with a max_packet_size > 64
1106 * Note bulk endpoints with a max_packet_size > 64 in theory also are not
1107 * usb1 compatible, but in practice this seems to work fine.
1109 static int usb_linux_full_speed_compat(USBHostDevice
*dev
)
1114 * usb_linux_update_endp_table only registers info about ep in the current
1115 * interface altsettings, so we need to parse the descriptors again.
1117 for (i
= 0; (i
+ 5) < dev
->descr_len
; i
+= dev
->descr
[i
]) {
1118 if (dev
->descr
[i
+ 1] == USB_DT_ENDPOINT
) {
1119 switch (dev
->descr
[i
+ 3] & 0x3) {
1120 case 0x00: /* CONTROL */
1122 case 0x01: /* ISO */
1124 case 0x02: /* BULK */
1126 case 0x03: /* INTERRUPT */
1127 packet_size
= dev
->descr
[i
+ 4] + (dev
->descr
[i
+ 5] << 8);
1128 if (packet_size
> 64)
1137 static int usb_host_open(USBHostDevice
*dev
, int bus_num
,
1138 int addr
, char *port
, const char *prod_name
, int speed
)
1143 if (dev
->fd
!= -1) {
1146 printf("husb: open device %d.%d\n", bus_num
, addr
);
1148 if (!usb_host_device_path
) {
1149 perror("husb: USB Host Device Path not set");
1152 snprintf(buf
, sizeof(buf
), "%s/%03d/%03d", usb_host_device_path
,
1154 fd
= open(buf
, O_RDWR
| O_NONBLOCK
);
1159 DPRINTF("husb: opened %s\n", buf
);
1161 dev
->bus_num
= bus_num
;
1163 strcpy(dev
->port
, port
);
1166 /* read the device description */
1167 dev
->descr_len
= read(fd
, dev
->descr
, sizeof(dev
->descr
));
1168 if (dev
->descr_len
<= 0) {
1169 perror("husb: reading device data failed");
1176 printf("=== begin dumping device descriptor data ===\n");
1177 for (x
= 0; x
< dev
->descr_len
; x
++) {
1178 printf("%02x ", dev
->descr
[x
]);
1180 printf("\n=== end dumping device descriptor data ===\n");
1186 * Initial configuration is -1 which makes us claim first
1187 * available config. We used to start with 1, which does not
1188 * always work. I've seen devices where first config starts
1191 if (!usb_host_claim_interfaces(dev
, -1)) {
1195 ret
= usb_linux_update_endp_table(dev
);
1201 struct usbdevfs_connectinfo ci
;
1203 ret
= ioctl(fd
, USBDEVFS_CONNECTINFO
, &ci
);
1205 perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
1210 speed
= USB_SPEED_LOW
;
1212 speed
= USB_SPEED_HIGH
;
1215 dev
->dev
.speed
= speed
;
1216 dev
->dev
.speedmask
= (1 << speed
);
1217 if (dev
->dev
.speed
== USB_SPEED_HIGH
&& usb_linux_full_speed_compat(dev
)) {
1218 dev
->dev
.speedmask
|= USB_SPEED_MASK_FULL
;
1221 printf("husb: grabbed usb device %d.%d\n", bus_num
, addr
);
1223 if (!prod_name
|| prod_name
[0] == '\0') {
1224 snprintf(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1225 "host:%d.%d", bus_num
, addr
);
1227 pstrcpy(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1231 ret
= usb_device_attach(&dev
->dev
);
1236 /* USB devio uses 'write' flag to check for async completions */
1237 qemu_set_fd_handler(dev
->fd
, NULL
, async_complete
, dev
);
1242 if (dev
->fd
!= -1) {
1249 static int usb_host_close(USBHostDevice
*dev
)
1253 if (dev
->fd
== -1 || !dev
->dev
.attached
) {
1257 qemu_set_fd_handler(dev
->fd
, NULL
, NULL
, NULL
);
1259 for (i
= 1; i
<= MAX_ENDPOINTS
; i
++) {
1260 if (is_isoc(dev
, i
)) {
1261 usb_host_stop_n_free_iso(dev
, i
);
1264 async_complete(dev
);
1266 usb_device_detach(&dev
->dev
);
1267 ioctl(dev
->fd
, USBDEVFS_RESET
);
1273 static void usb_host_exit_notifier(struct Notifier
*n
, void *data
)
1275 USBHostDevice
*s
= container_of(n
, USBHostDevice
, exit
);
1278 ioctl(s
->fd
, USBDEVFS_RESET
);
1282 static int usb_host_initfn(USBDevice
*dev
)
1284 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
1286 dev
->auto_attach
= 0;
1288 QTAILQ_INSERT_TAIL(&hostdevs
, s
, next
);
1289 s
->exit
.notify
= usb_host_exit_notifier
;
1290 qemu_add_exit_notifier(&s
->exit
);
1291 usb_host_auto_check(NULL
);
1295 static struct USBDeviceInfo usb_host_dev_info
= {
1296 .product_desc
= "USB Host Device",
1297 .qdev
.name
= "usb-host",
1298 .qdev
.size
= sizeof(USBHostDevice
),
1299 .init
= usb_host_initfn
,
1300 .handle_packet
= usb_generic_handle_packet
,
1301 .cancel_packet
= usb_host_async_cancel
,
1302 .handle_data
= usb_host_handle_data
,
1303 .handle_control
= usb_host_handle_control
,
1304 .handle_reset
= usb_host_handle_reset
,
1305 .handle_destroy
= usb_host_handle_destroy
,
1306 .usbdevice_name
= "host",
1307 .usbdevice_init
= usb_host_device_open
,
1308 .qdev
.props
= (Property
[]) {
1309 DEFINE_PROP_UINT32("hostbus", USBHostDevice
, match
.bus_num
, 0),
1310 DEFINE_PROP_UINT32("hostaddr", USBHostDevice
, match
.addr
, 0),
1311 DEFINE_PROP_STRING("hostport", USBHostDevice
, match
.port
),
1312 DEFINE_PROP_HEX32("vendorid", USBHostDevice
, match
.vendor_id
, 0),
1313 DEFINE_PROP_HEX32("productid", USBHostDevice
, match
.product_id
, 0),
1314 DEFINE_PROP_UINT32("isobufs", USBHostDevice
, iso_urb_count
, 4),
1315 DEFINE_PROP_END_OF_LIST(),
1319 static void usb_host_register_devices(void)
1321 usb_qdev_register(&usb_host_dev_info
);
1323 device_init(usb_host_register_devices
)
1325 USBDevice
*usb_host_device_open(const char *devname
)
1327 struct USBAutoFilter filter
;
1331 dev
= usb_create(NULL
/* FIXME */, "usb-host");
1333 if (strstr(devname
, "auto:")) {
1334 if (parse_filter(devname
, &filter
) < 0) {
1338 if ((p
= strchr(devname
, '.'))) {
1339 filter
.bus_num
= strtoul(devname
, NULL
, 0);
1340 filter
.addr
= strtoul(p
+ 1, NULL
, 0);
1341 filter
.vendor_id
= 0;
1342 filter
.product_id
= 0;
1343 } else if ((p
= strchr(devname
, ':'))) {
1346 filter
.vendor_id
= strtoul(devname
, NULL
, 16);
1347 filter
.product_id
= strtoul(p
+ 1, NULL
, 16);
1353 qdev_prop_set_uint32(&dev
->qdev
, "hostbus", filter
.bus_num
);
1354 qdev_prop_set_uint32(&dev
->qdev
, "hostaddr", filter
.addr
);
1355 qdev_prop_set_uint32(&dev
->qdev
, "vendorid", filter
.vendor_id
);
1356 qdev_prop_set_uint32(&dev
->qdev
, "productid", filter
.product_id
);
1357 qdev_init_nofail(&dev
->qdev
);
1361 qdev_free(&dev
->qdev
);
1365 int usb_host_device_close(const char *devname
)
1368 char product_name
[PRODUCT_NAME_SZ
];
1372 if (strstr(devname
, "auto:")) {
1373 return usb_host_auto_del(devname
);
1375 if (usb_host_find_device(&bus_num
, &addr
, product_name
,
1376 sizeof(product_name
), devname
) < 0) {
1379 s
= hostdev_find(bus_num
, addr
);
1381 usb_device_delete_addr(s
->bus_num
, s
->dev
.addr
);
1389 static int get_tag_value(char *buf
, int buf_size
,
1390 const char *str
, const char *tag
,
1391 const char *stopchars
)
1395 p
= strstr(str
, tag
);
1400 while (qemu_isspace(*p
)) {
1404 while (*p
!= '\0' && !strchr(stopchars
, *p
)) {
1405 if ((q
- buf
) < (buf_size
- 1)) {
1415 * Use /proc/bus/usb/devices or /dev/bus/usb/devices file to determine
1416 * host's USB devices. This is legacy support since many distributions
1417 * are moving to /sys/bus/usb
1419 static int usb_host_scan_dev(void *opaque
, USBScanFunc
*func
)
1424 int bus_num
, addr
, speed
, device_count
, class_id
, product_id
, vendor_id
;
1425 char product_name
[512];
1428 if (!usb_host_device_path
) {
1429 perror("husb: USB Host Device Path not set");
1432 snprintf(line
, sizeof(line
), "%s/devices", usb_host_device_path
);
1433 f
= fopen(line
, "r");
1435 perror("husb: cannot open devices file");
1440 bus_num
= addr
= class_id
= product_id
= vendor_id
= 0;
1441 speed
= -1; /* Can't get the speed from /[proc|dev]/bus/usb/devices */
1443 if (fgets(line
, sizeof(line
), f
) == NULL
) {
1446 if (strlen(line
) > 0) {
1447 line
[strlen(line
) - 1] = '\0';
1449 if (line
[0] == 'T' && line
[1] == ':') {
1450 if (device_count
&& (vendor_id
|| product_id
)) {
1451 /* New device. Add the previously discovered device. */
1452 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1453 product_id
, product_name
, speed
);
1458 if (get_tag_value(buf
, sizeof(buf
), line
, "Bus=", " ") < 0) {
1461 bus_num
= atoi(buf
);
1462 if (get_tag_value(buf
, sizeof(buf
), line
, "Dev#=", " ") < 0) {
1466 if (get_tag_value(buf
, sizeof(buf
), line
, "Spd=", " ") < 0) {
1469 if (!strcmp(buf
, "5000")) {
1470 speed
= USB_SPEED_SUPER
;
1471 } else if (!strcmp(buf
, "480")) {
1472 speed
= USB_SPEED_HIGH
;
1473 } else if (!strcmp(buf
, "1.5")) {
1474 speed
= USB_SPEED_LOW
;
1476 speed
= USB_SPEED_FULL
;
1478 product_name
[0] = '\0';
1483 } else if (line
[0] == 'P' && line
[1] == ':') {
1484 if (get_tag_value(buf
, sizeof(buf
), line
, "Vendor=", " ") < 0) {
1487 vendor_id
= strtoul(buf
, NULL
, 16);
1488 if (get_tag_value(buf
, sizeof(buf
), line
, "ProdID=", " ") < 0) {
1491 product_id
= strtoul(buf
, NULL
, 16);
1492 } else if (line
[0] == 'S' && line
[1] == ':') {
1493 if (get_tag_value(buf
, sizeof(buf
), line
, "Product=", "") < 0) {
1496 pstrcpy(product_name
, sizeof(product_name
), buf
);
1497 } else if (line
[0] == 'D' && line
[1] == ':') {
1498 if (get_tag_value(buf
, sizeof(buf
), line
, "Cls=", " (") < 0) {
1501 class_id
= strtoul(buf
, NULL
, 16);
1505 if (device_count
&& (vendor_id
|| product_id
)) {
1506 /* Add the last device. */
1507 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1508 product_id
, product_name
, speed
);
1518 * Read sys file-system device file
1520 * @line address of buffer to put file contents in
1521 * @line_size size of line
1522 * @device_file path to device file (printf format string)
1523 * @device_name device being opened (inserted into device_file)
1525 * @return 0 failed, 1 succeeded ('line' contains data)
1527 static int usb_host_read_file(char *line
, size_t line_size
,
1528 const char *device_file
, const char *device_name
)
1532 char filename
[PATH_MAX
];
1534 snprintf(filename
, PATH_MAX
, USBSYSBUS_PATH
"/devices/%s/%s", device_name
,
1536 f
= fopen(filename
, "r");
1538 ret
= fgets(line
, line_size
, f
) != NULL
;
1546 * Use /sys/bus/usb/devices/ directory to determine host's USB
1549 * This code is based on Robert Schiele's original patches posted to
1550 * the Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
1552 static int usb_host_scan_sys(void *opaque
, USBScanFunc
*func
)
1556 int bus_num
, addr
, speed
, class_id
, product_id
, vendor_id
;
1558 char port
[MAX_PORTLEN
];
1559 char product_name
[512];
1562 dir
= opendir(USBSYSBUS_PATH
"/devices");
1564 perror("husb: cannot open devices directory");
1568 while ((de
= readdir(dir
))) {
1569 if (de
->d_name
[0] != '.' && !strchr(de
->d_name
, ':')) {
1570 if (sscanf(de
->d_name
, "%d-%7[0-9.]", &bus_num
, port
) < 2) {
1574 if (!usb_host_read_file(line
, sizeof(line
), "devnum", de
->d_name
)) {
1577 if (sscanf(line
, "%d", &addr
) != 1) {
1580 if (!usb_host_read_file(line
, sizeof(line
), "bDeviceClass",
1584 if (sscanf(line
, "%x", &class_id
) != 1) {
1588 if (!usb_host_read_file(line
, sizeof(line
), "idVendor",
1592 if (sscanf(line
, "%x", &vendor_id
) != 1) {
1595 if (!usb_host_read_file(line
, sizeof(line
), "idProduct",
1599 if (sscanf(line
, "%x", &product_id
) != 1) {
1602 if (!usb_host_read_file(line
, sizeof(line
), "product",
1606 if (strlen(line
) > 0) {
1607 line
[strlen(line
) - 1] = '\0';
1609 pstrcpy(product_name
, sizeof(product_name
), line
);
1612 if (!usb_host_read_file(line
, sizeof(line
), "speed", de
->d_name
)) {
1615 if (!strcmp(line
, "5000\n")) {
1616 speed
= USB_SPEED_SUPER
;
1617 } else if (!strcmp(line
, "480\n")) {
1618 speed
= USB_SPEED_HIGH
;
1619 } else if (!strcmp(line
, "1.5\n")) {
1620 speed
= USB_SPEED_LOW
;
1622 speed
= USB_SPEED_FULL
;
1625 ret
= func(opaque
, bus_num
, addr
, port
, class_id
, vendor_id
,
1626 product_id
, product_name
, speed
);
1640 * Determine how to access the host's USB devices and call the
1641 * specific support function.
1643 static int usb_host_scan(void *opaque
, USBScanFunc
*func
)
1645 Monitor
*mon
= cur_mon
;
1649 const char *fs_type
[] = {"unknown", "proc", "dev", "sys"};
1650 char devpath
[PATH_MAX
];
1652 /* only check the host once */
1654 dir
= opendir(USBSYSBUS_PATH
"/devices");
1656 /* devices found in /dev/bus/usb/ (yes - not a mistake!) */
1657 strcpy(devpath
, USBDEVBUS_PATH
);
1658 usb_fs_type
= USB_FS_SYS
;
1660 DPRINTF(USBDBG_DEVOPENED
, USBSYSBUS_PATH
);
1663 f
= fopen(USBPROCBUS_PATH
"/devices", "r");
1665 /* devices found in /proc/bus/usb/ */
1666 strcpy(devpath
, USBPROCBUS_PATH
);
1667 usb_fs_type
= USB_FS_PROC
;
1669 DPRINTF(USBDBG_DEVOPENED
, USBPROCBUS_PATH
);
1672 /* try additional methods if an access method hasn't been found yet */
1673 f
= fopen(USBDEVBUS_PATH
"/devices", "r");
1675 /* devices found in /dev/bus/usb/ */
1676 strcpy(devpath
, USBDEVBUS_PATH
);
1677 usb_fs_type
= USB_FS_DEV
;
1679 DPRINTF(USBDBG_DEVOPENED
, USBDEVBUS_PATH
);
1685 monitor_printf(mon
, "husb: unable to access USB devices\n");
1690 /* the module setting (used later for opening devices) */
1691 usb_host_device_path
= g_malloc0(strlen(devpath
)+1);
1692 strcpy(usb_host_device_path
, devpath
);
1694 monitor_printf(mon
, "husb: using %s file-system with %s\n",
1695 fs_type
[usb_fs_type
], usb_host_device_path
);
1699 switch (usb_fs_type
) {
1702 ret
= usb_host_scan_dev(opaque
, func
);
1705 ret
= usb_host_scan_sys(opaque
, func
);
1714 static QEMUTimer
*usb_auto_timer
;
1716 static int usb_host_auto_scan(void *opaque
, int bus_num
, int addr
, char *port
,
1717 int class_id
, int vendor_id
, int product_id
,
1718 const char *product_name
, int speed
)
1720 struct USBAutoFilter
*f
;
1721 struct USBHostDevice
*s
;
1727 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1730 if (f
->bus_num
> 0 && f
->bus_num
!= bus_num
) {
1733 if (f
->addr
> 0 && f
->addr
!= addr
) {
1736 if (f
->port
!= NULL
&& (port
== NULL
|| strcmp(f
->port
, port
) != 0)) {
1740 if (f
->vendor_id
> 0 && f
->vendor_id
!= vendor_id
) {
1744 if (f
->product_id
> 0 && f
->product_id
!= product_id
) {
1747 /* We got a match */
1749 /* Already attached ? */
1753 DPRINTF("husb: auto open: bus_num %d addr %d\n", bus_num
, addr
);
1755 usb_host_open(s
, bus_num
, addr
, port
, product_name
, speed
);
1762 static void usb_host_auto_check(void *unused
)
1764 struct USBHostDevice
*s
;
1765 int unconnected
= 0;
1767 usb_host_scan(NULL
, usb_host_auto_scan
);
1769 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1775 if (unconnected
== 0) {
1776 /* nothing to watch */
1777 if (usb_auto_timer
) {
1778 qemu_del_timer(usb_auto_timer
);
1783 if (!usb_auto_timer
) {
1784 usb_auto_timer
= qemu_new_timer_ms(rt_clock
, usb_host_auto_check
, NULL
);
1785 if (!usb_auto_timer
) {
1789 qemu_mod_timer(usb_auto_timer
, qemu_get_clock_ms(rt_clock
) + 2000);
1793 * Autoconnect filter
1795 * auto:bus:dev[:vid:pid]
1796 * auto:bus.dev[:vid:pid]
1798 * bus - bus number (dec, * means any)
1799 * dev - device number (dec, * means any)
1800 * vid - vendor id (hex, * means any)
1801 * pid - product id (hex, * means any)
1803 * See 'lsusb' output.
1805 static int parse_filter(const char *spec
, struct USBAutoFilter
*f
)
1807 enum { BUS
, DEV
, VID
, PID
, DONE
};
1808 const char *p
= spec
;
1816 for (i
= BUS
; i
< DONE
; i
++) {
1817 p
= strpbrk(p
, ":.");
1827 case BUS
: f
->bus_num
= strtol(p
, NULL
, 10); break;
1828 case DEV
: f
->addr
= strtol(p
, NULL
, 10); break;
1829 case VID
: f
->vendor_id
= strtol(p
, NULL
, 16); break;
1830 case PID
: f
->product_id
= strtol(p
, NULL
, 16); break;
1835 fprintf(stderr
, "husb: invalid auto filter spec %s\n", spec
);
1842 /**********************/
1843 /* USB host device info */
1845 struct usb_class_info
{
1847 const char *class_name
;
1850 static const struct usb_class_info usb_class_info
[] = {
1851 { USB_CLASS_AUDIO
, "Audio"},
1852 { USB_CLASS_COMM
, "Communication"},
1853 { USB_CLASS_HID
, "HID"},
1854 { USB_CLASS_HUB
, "Hub" },
1855 { USB_CLASS_PHYSICAL
, "Physical" },
1856 { USB_CLASS_PRINTER
, "Printer" },
1857 { USB_CLASS_MASS_STORAGE
, "Storage" },
1858 { USB_CLASS_CDC_DATA
, "Data" },
1859 { USB_CLASS_APP_SPEC
, "Application Specific" },
1860 { USB_CLASS_VENDOR_SPEC
, "Vendor Specific" },
1861 { USB_CLASS_STILL_IMAGE
, "Still Image" },
1862 { USB_CLASS_CSCID
, "Smart Card" },
1863 { USB_CLASS_CONTENT_SEC
, "Content Security" },
1867 static const char *usb_class_str(uint8_t class)
1869 const struct usb_class_info
*p
;
1870 for(p
= usb_class_info
; p
->class != -1; p
++) {
1871 if (p
->class == class) {
1875 return p
->class_name
;
1878 static void usb_info_device(Monitor
*mon
, int bus_num
, int addr
, char *port
,
1879 int class_id
, int vendor_id
, int product_id
,
1880 const char *product_name
,
1883 const char *class_str
, *speed_str
;
1889 case USB_SPEED_FULL
:
1892 case USB_SPEED_HIGH
:
1895 case USB_SPEED_SUPER
:
1903 monitor_printf(mon
, " Bus %d, Addr %d, Port %s, Speed %s Mb/s\n",
1904 bus_num
, addr
, port
, speed_str
);
1905 class_str
= usb_class_str(class_id
);
1907 monitor_printf(mon
, " %s:", class_str
);
1909 monitor_printf(mon
, " Class %02x:", class_id
);
1911 monitor_printf(mon
, " USB device %04x:%04x", vendor_id
, product_id
);
1912 if (product_name
[0] != '\0') {
1913 monitor_printf(mon
, ", %s", product_name
);
1915 monitor_printf(mon
, "\n");
1918 static int usb_host_info_device(void *opaque
, int bus_num
, int addr
,
1919 char *path
, int class_id
,
1920 int vendor_id
, int product_id
,
1921 const char *product_name
,
1924 Monitor
*mon
= opaque
;
1926 usb_info_device(mon
, bus_num
, addr
, path
, class_id
, vendor_id
, product_id
,
1927 product_name
, speed
);
1931 static void dec2str(int val
, char *str
, size_t size
)
1934 snprintf(str
, size
, "*");
1936 snprintf(str
, size
, "%d", val
);
1940 static void hex2str(int val
, char *str
, size_t size
)
1943 snprintf(str
, size
, "*");
1945 snprintf(str
, size
, "%04x", val
);
1949 void usb_host_info(Monitor
*mon
)
1951 struct USBAutoFilter
*f
;
1952 struct USBHostDevice
*s
;
1954 usb_host_scan(mon
, usb_host_info_device
);
1956 if (QTAILQ_EMPTY(&hostdevs
)) {
1960 monitor_printf(mon
, " Auto filters:\n");
1961 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1962 char bus
[10], addr
[10], vid
[10], pid
[10];
1964 dec2str(f
->bus_num
, bus
, sizeof(bus
));
1965 dec2str(f
->addr
, addr
, sizeof(addr
));
1966 hex2str(f
->vendor_id
, vid
, sizeof(vid
));
1967 hex2str(f
->product_id
, pid
, sizeof(pid
));
1968 monitor_printf(mon
, " Bus %s, Addr %s, Port %s, ID %s:%s\n",
1969 bus
, addr
, f
->port
? f
->port
: "*", vid
, pid
);