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
= qemu_mallocz(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
= qemu_mallocz(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
= qemu_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 qemu_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
;
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
);
738 assert(p
->iov
.niov
== 1); /* temporary */
739 rem
= p
->iov
.iov
[0].iov_len
;
740 pbuf
= p
->iov
.iov
[0].iov_base
;
742 aurb
= async_alloc(s
);
747 urb
->type
= USBDEVFS_URB_TYPE_BULK
;
748 urb
->usercontext
= s
;
751 if (rem
> MAX_USBFS_BUFFER_SIZE
) {
752 urb
->buffer_length
= MAX_USBFS_BUFFER_SIZE
;
755 urb
->buffer_length
= rem
;
758 pbuf
+= urb
->buffer_length
;
759 rem
-= urb
->buffer_length
;
761 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
763 DPRINTF("husb: data submit: ep 0x%x, len %u, more %d, packet %p, aurb %p\n",
764 urb
->endpoint
, urb
->buffer_length
, aurb
->more
, p
, aurb
);
767 DPRINTF("husb: submit failed. errno %d\n", errno
);
775 return USB_RET_STALL
;
780 return USB_RET_ASYNC
;
783 static int ctrl_error(void)
785 if (errno
== ETIMEDOUT
) {
788 return USB_RET_STALL
;
792 static int usb_host_set_address(USBHostDevice
*s
, int addr
)
794 DPRINTF("husb: ctrl set addr %u\n", addr
);
799 static int usb_host_set_config(USBHostDevice
*s
, int config
)
801 usb_host_release_interfaces(s
);
803 int ret
= ioctl(s
->fd
, USBDEVFS_SETCONFIGURATION
, &config
);
805 DPRINTF("husb: ctrl set config %d ret %d errno %d\n", config
, ret
, errno
);
810 usb_host_claim_interfaces(s
, config
);
814 static int usb_host_set_interface(USBHostDevice
*s
, int iface
, int alt
)
816 struct usbdevfs_setinterface si
;
819 for (i
= 1; i
<= MAX_ENDPOINTS
; i
++) {
821 usb_host_stop_n_free_iso(s
, i
);
825 si
.interface
= iface
;
827 ret
= ioctl(s
->fd
, USBDEVFS_SETINTERFACE
, &si
);
829 DPRINTF("husb: ctrl set iface %d altset %d ret %d errno %d\n",
830 iface
, alt
, ret
, errno
);
835 usb_linux_update_endp_table(s
);
839 static int usb_host_handle_control(USBDevice
*dev
, USBPacket
*p
,
840 int request
, int value
, int index
, int length
, uint8_t *data
)
842 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
843 struct usbdevfs_urb
*urb
;
848 * Process certain standard device requests.
849 * These are infrequent and are processed synchronously.
852 /* Note request is (bRequestType << 8) | bRequest */
853 DPRINTF("husb: ctrl type 0x%x req 0x%x val 0x%x index %u len %u\n",
854 request
>> 8, request
& 0xff, value
, index
, length
);
857 case DeviceOutRequest
| USB_REQ_SET_ADDRESS
:
858 return usb_host_set_address(s
, value
);
860 case DeviceOutRequest
| USB_REQ_SET_CONFIGURATION
:
861 return usb_host_set_config(s
, value
& 0xff);
863 case InterfaceOutRequest
| USB_REQ_SET_INTERFACE
:
864 return usb_host_set_interface(s
, index
, value
);
867 /* The rest are asynchronous */
869 if (length
> sizeof(dev
->data_buf
)) {
870 fprintf(stderr
, "husb: ctrl buffer too small (%d > %zu)\n",
871 length
, sizeof(dev
->data_buf
));
872 return USB_RET_STALL
;
875 aurb
= async_alloc(s
);
879 * Setup ctrl transfer.
881 * s->ctrl is laid out such that data buffer immediately follows
882 * 'req' struct which is exactly what usbdevfs expects.
886 urb
->type
= USBDEVFS_URB_TYPE_CONTROL
;
887 urb
->endpoint
= p
->devep
;
889 urb
->buffer
= &dev
->setup_buf
;
890 urb
->buffer_length
= length
+ 8;
892 urb
->usercontext
= s
;
894 ret
= ioctl(s
->fd
, USBDEVFS_SUBMITURB
, urb
);
896 DPRINTF("husb: submit ctrl. len %u aurb %p\n", urb
->buffer_length
, aurb
);
899 DPRINTF("husb: submit failed. errno %d\n", errno
);
907 return USB_RET_STALL
;
911 return USB_RET_ASYNC
;
914 static int usb_linux_get_configuration(USBHostDevice
*s
)
916 uint8_t configuration
;
917 struct usb_ctrltransfer ct
;
920 if (usb_fs_type
== USB_FS_SYS
) {
921 char device_name
[32], line
[1024];
924 sprintf(device_name
, "%d-%s", s
->bus_num
, s
->port
);
926 if (!usb_host_read_file(line
, sizeof(line
), "bConfigurationValue",
930 if (sscanf(line
, "%d", &configuration
) != 1) {
933 return configuration
;
937 ct
.bRequestType
= USB_DIR_IN
;
938 ct
.bRequest
= USB_REQ_GET_CONFIGURATION
;
942 ct
.data
= &configuration
;
945 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
947 perror("usb_linux_get_configuration");
951 /* in address state */
952 if (configuration
== 0) {
956 return configuration
;
959 static uint8_t usb_linux_get_alt_setting(USBHostDevice
*s
,
960 uint8_t configuration
, uint8_t interface
)
963 struct usb_ctrltransfer ct
;
966 if (usb_fs_type
== USB_FS_SYS
) {
967 char device_name
[64], line
[1024];
970 sprintf(device_name
, "%d-%s:%d.%d", s
->bus_num
, s
->port
,
971 (int)configuration
, (int)interface
);
973 if (!usb_host_read_file(line
, sizeof(line
), "bAlternateSetting",
977 if (sscanf(line
, "%d", &alt_setting
) != 1) {
984 ct
.bRequestType
= USB_DIR_IN
| USB_RECIP_INTERFACE
;
985 ct
.bRequest
= USB_REQ_GET_INTERFACE
;
987 ct
.wIndex
= interface
;
989 ct
.data
= &alt_setting
;
991 ret
= ioctl(s
->fd
, USBDEVFS_CONTROL
, &ct
);
993 /* Assume alt 0 on error */
1000 /* returns 1 on problem encountered or 0 for success */
1001 static int usb_linux_update_endp_table(USBHostDevice
*s
)
1003 uint8_t *descriptors
;
1004 uint8_t devep
, type
, configuration
, alt_interface
;
1005 int interface
, length
, i
;
1007 for (i
= 0; i
< MAX_ENDPOINTS
; i
++)
1008 s
->endp_table
[i
].type
= INVALID_EP_TYPE
;
1010 i
= usb_linux_get_configuration(s
);
1015 /* get the desired configuration, interface, and endpoint descriptors
1016 * from device description */
1017 descriptors
= &s
->descr
[18];
1018 length
= s
->descr_len
- 18;
1021 if (descriptors
[i
+ 1] != USB_DT_CONFIG
||
1022 descriptors
[i
+ 5] != configuration
) {
1023 DPRINTF("invalid descriptor data - configuration\n");
1026 i
+= descriptors
[i
];
1028 while (i
< length
) {
1029 if (descriptors
[i
+ 1] != USB_DT_INTERFACE
||
1030 (descriptors
[i
+ 1] == USB_DT_INTERFACE
&&
1031 descriptors
[i
+ 4] == 0)) {
1032 i
+= descriptors
[i
];
1036 interface
= descriptors
[i
+ 2];
1037 alt_interface
= usb_linux_get_alt_setting(s
, configuration
, interface
);
1039 /* the current interface descriptor is the active interface
1040 * and has endpoints */
1041 if (descriptors
[i
+ 3] != alt_interface
) {
1042 i
+= descriptors
[i
];
1046 /* advance to the endpoints */
1047 while (i
< length
&& descriptors
[i
+1] != USB_DT_ENDPOINT
) {
1048 i
+= descriptors
[i
];
1054 while (i
< length
) {
1055 if (descriptors
[i
+ 1] != USB_DT_ENDPOINT
) {
1059 devep
= descriptors
[i
+ 2];
1060 if ((devep
& 0x0f) == 0) {
1061 fprintf(stderr
, "usb-linux: invalid ep descriptor, ep == 0\n");
1065 switch (descriptors
[i
+ 3] & 0x3) {
1067 type
= USBDEVFS_URB_TYPE_CONTROL
;
1070 type
= USBDEVFS_URB_TYPE_ISO
;
1071 set_max_packet_size(s
, (devep
& 0xf), descriptors
+ i
);
1074 type
= USBDEVFS_URB_TYPE_BULK
;
1077 type
= USBDEVFS_URB_TYPE_INTERRUPT
;
1080 DPRINTF("usb_host: malformed endpoint type\n");
1081 type
= USBDEVFS_URB_TYPE_BULK
;
1083 s
->endp_table
[(devep
& 0xf) - 1].type
= type
;
1084 s
->endp_table
[(devep
& 0xf) - 1].halted
= 0;
1086 i
+= descriptors
[i
];
1093 * Check if we can safely redirect a usb2 device to a usb1 virtual controller,
1094 * this function assumes this is safe, if:
1095 * 1) There are no isoc endpoints
1096 * 2) There are no interrupt endpoints with a max_packet_size > 64
1097 * Note bulk endpoints with a max_packet_size > 64 in theory also are not
1098 * usb1 compatible, but in practice this seems to work fine.
1100 static int usb_linux_full_speed_compat(USBHostDevice
*dev
)
1105 * usb_linux_update_endp_table only registers info about ep in the current
1106 * interface altsettings, so we need to parse the descriptors again.
1108 for (i
= 0; (i
+ 5) < dev
->descr_len
; i
+= dev
->descr
[i
]) {
1109 if (dev
->descr
[i
+ 1] == USB_DT_ENDPOINT
) {
1110 switch (dev
->descr
[i
+ 3] & 0x3) {
1111 case 0x00: /* CONTROL */
1113 case 0x01: /* ISO */
1115 case 0x02: /* BULK */
1117 case 0x03: /* INTERRUPT */
1118 packet_size
= dev
->descr
[i
+ 4] + (dev
->descr
[i
+ 5] << 8);
1119 if (packet_size
> 64)
1128 static int usb_host_open(USBHostDevice
*dev
, int bus_num
,
1129 int addr
, char *port
, const char *prod_name
, int speed
)
1134 if (dev
->fd
!= -1) {
1137 printf("husb: open device %d.%d\n", bus_num
, addr
);
1139 if (!usb_host_device_path
) {
1140 perror("husb: USB Host Device Path not set");
1143 snprintf(buf
, sizeof(buf
), "%s/%03d/%03d", usb_host_device_path
,
1145 fd
= open(buf
, O_RDWR
| O_NONBLOCK
);
1150 DPRINTF("husb: opened %s\n", buf
);
1152 dev
->bus_num
= bus_num
;
1154 strcpy(dev
->port
, port
);
1157 /* read the device description */
1158 dev
->descr_len
= read(fd
, dev
->descr
, sizeof(dev
->descr
));
1159 if (dev
->descr_len
<= 0) {
1160 perror("husb: reading device data failed");
1167 printf("=== begin dumping device descriptor data ===\n");
1168 for (x
= 0; x
< dev
->descr_len
; x
++) {
1169 printf("%02x ", dev
->descr
[x
]);
1171 printf("\n=== end dumping device descriptor data ===\n");
1177 * Initial configuration is -1 which makes us claim first
1178 * available config. We used to start with 1, which does not
1179 * always work. I've seen devices where first config starts
1182 if (!usb_host_claim_interfaces(dev
, -1)) {
1186 ret
= usb_linux_update_endp_table(dev
);
1192 struct usbdevfs_connectinfo ci
;
1194 ret
= ioctl(fd
, USBDEVFS_CONNECTINFO
, &ci
);
1196 perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
1201 speed
= USB_SPEED_LOW
;
1203 speed
= USB_SPEED_HIGH
;
1206 dev
->dev
.speed
= speed
;
1207 dev
->dev
.speedmask
= (1 << speed
);
1208 if (dev
->dev
.speed
== USB_SPEED_HIGH
&& usb_linux_full_speed_compat(dev
)) {
1209 dev
->dev
.speedmask
|= USB_SPEED_MASK_FULL
;
1212 printf("husb: grabbed usb device %d.%d\n", bus_num
, addr
);
1214 if (!prod_name
|| prod_name
[0] == '\0') {
1215 snprintf(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1216 "host:%d.%d", bus_num
, addr
);
1218 pstrcpy(dev
->dev
.product_desc
, sizeof(dev
->dev
.product_desc
),
1222 ret
= usb_device_attach(&dev
->dev
);
1227 /* USB devio uses 'write' flag to check for async completions */
1228 qemu_set_fd_handler(dev
->fd
, NULL
, async_complete
, dev
);
1233 if (dev
->fd
!= -1) {
1240 static int usb_host_close(USBHostDevice
*dev
)
1244 if (dev
->fd
== -1 || !dev
->dev
.attached
) {
1248 qemu_set_fd_handler(dev
->fd
, NULL
, NULL
, NULL
);
1250 for (i
= 1; i
<= MAX_ENDPOINTS
; i
++) {
1251 if (is_isoc(dev
, i
)) {
1252 usb_host_stop_n_free_iso(dev
, i
);
1255 async_complete(dev
);
1257 usb_device_detach(&dev
->dev
);
1258 ioctl(dev
->fd
, USBDEVFS_RESET
);
1264 static void usb_host_exit_notifier(struct Notifier
*n
, void *data
)
1266 USBHostDevice
*s
= container_of(n
, USBHostDevice
, exit
);
1269 ioctl(s
->fd
, USBDEVFS_RESET
);
1273 static int usb_host_initfn(USBDevice
*dev
)
1275 USBHostDevice
*s
= DO_UPCAST(USBHostDevice
, dev
, dev
);
1277 dev
->auto_attach
= 0;
1279 QTAILQ_INSERT_TAIL(&hostdevs
, s
, next
);
1280 s
->exit
.notify
= usb_host_exit_notifier
;
1281 qemu_add_exit_notifier(&s
->exit
);
1282 usb_host_auto_check(NULL
);
1286 static struct USBDeviceInfo usb_host_dev_info
= {
1287 .product_desc
= "USB Host Device",
1288 .qdev
.name
= "usb-host",
1289 .qdev
.size
= sizeof(USBHostDevice
),
1290 .init
= usb_host_initfn
,
1291 .handle_packet
= usb_generic_handle_packet
,
1292 .cancel_packet
= usb_host_async_cancel
,
1293 .handle_data
= usb_host_handle_data
,
1294 .handle_control
= usb_host_handle_control
,
1295 .handle_reset
= usb_host_handle_reset
,
1296 .handle_destroy
= usb_host_handle_destroy
,
1297 .usbdevice_name
= "host",
1298 .usbdevice_init
= usb_host_device_open
,
1299 .qdev
.props
= (Property
[]) {
1300 DEFINE_PROP_UINT32("hostbus", USBHostDevice
, match
.bus_num
, 0),
1301 DEFINE_PROP_UINT32("hostaddr", USBHostDevice
, match
.addr
, 0),
1302 DEFINE_PROP_STRING("hostport", USBHostDevice
, match
.port
),
1303 DEFINE_PROP_HEX32("vendorid", USBHostDevice
, match
.vendor_id
, 0),
1304 DEFINE_PROP_HEX32("productid", USBHostDevice
, match
.product_id
, 0),
1305 DEFINE_PROP_UINT32("isobufs", USBHostDevice
, iso_urb_count
, 4),
1306 DEFINE_PROP_END_OF_LIST(),
1310 static void usb_host_register_devices(void)
1312 usb_qdev_register(&usb_host_dev_info
);
1314 device_init(usb_host_register_devices
)
1316 USBDevice
*usb_host_device_open(const char *devname
)
1318 struct USBAutoFilter filter
;
1322 dev
= usb_create(NULL
/* FIXME */, "usb-host");
1324 if (strstr(devname
, "auto:")) {
1325 if (parse_filter(devname
, &filter
) < 0) {
1329 if ((p
= strchr(devname
, '.'))) {
1330 filter
.bus_num
= strtoul(devname
, NULL
, 0);
1331 filter
.addr
= strtoul(p
+ 1, NULL
, 0);
1332 filter
.vendor_id
= 0;
1333 filter
.product_id
= 0;
1334 } else if ((p
= strchr(devname
, ':'))) {
1337 filter
.vendor_id
= strtoul(devname
, NULL
, 16);
1338 filter
.product_id
= strtoul(p
+ 1, NULL
, 16);
1344 qdev_prop_set_uint32(&dev
->qdev
, "hostbus", filter
.bus_num
);
1345 qdev_prop_set_uint32(&dev
->qdev
, "hostaddr", filter
.addr
);
1346 qdev_prop_set_uint32(&dev
->qdev
, "vendorid", filter
.vendor_id
);
1347 qdev_prop_set_uint32(&dev
->qdev
, "productid", filter
.product_id
);
1348 qdev_init_nofail(&dev
->qdev
);
1352 qdev_free(&dev
->qdev
);
1356 int usb_host_device_close(const char *devname
)
1359 char product_name
[PRODUCT_NAME_SZ
];
1363 if (strstr(devname
, "auto:")) {
1364 return usb_host_auto_del(devname
);
1366 if (usb_host_find_device(&bus_num
, &addr
, product_name
,
1367 sizeof(product_name
), devname
) < 0) {
1370 s
= hostdev_find(bus_num
, addr
);
1372 usb_device_delete_addr(s
->bus_num
, s
->dev
.addr
);
1380 static int get_tag_value(char *buf
, int buf_size
,
1381 const char *str
, const char *tag
,
1382 const char *stopchars
)
1386 p
= strstr(str
, tag
);
1391 while (qemu_isspace(*p
)) {
1395 while (*p
!= '\0' && !strchr(stopchars
, *p
)) {
1396 if ((q
- buf
) < (buf_size
- 1)) {
1406 * Use /proc/bus/usb/devices or /dev/bus/usb/devices file to determine
1407 * host's USB devices. This is legacy support since many distributions
1408 * are moving to /sys/bus/usb
1410 static int usb_host_scan_dev(void *opaque
, USBScanFunc
*func
)
1415 int bus_num
, addr
, speed
, device_count
, class_id
, product_id
, vendor_id
;
1416 char product_name
[512];
1419 if (!usb_host_device_path
) {
1420 perror("husb: USB Host Device Path not set");
1423 snprintf(line
, sizeof(line
), "%s/devices", usb_host_device_path
);
1424 f
= fopen(line
, "r");
1426 perror("husb: cannot open devices file");
1431 bus_num
= addr
= class_id
= product_id
= vendor_id
= 0;
1432 speed
= -1; /* Can't get the speed from /[proc|dev]/bus/usb/devices */
1434 if (fgets(line
, sizeof(line
), f
) == NULL
) {
1437 if (strlen(line
) > 0) {
1438 line
[strlen(line
) - 1] = '\0';
1440 if (line
[0] == 'T' && line
[1] == ':') {
1441 if (device_count
&& (vendor_id
|| product_id
)) {
1442 /* New device. Add the previously discovered device. */
1443 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1444 product_id
, product_name
, speed
);
1449 if (get_tag_value(buf
, sizeof(buf
), line
, "Bus=", " ") < 0) {
1452 bus_num
= atoi(buf
);
1453 if (get_tag_value(buf
, sizeof(buf
), line
, "Dev#=", " ") < 0) {
1457 if (get_tag_value(buf
, sizeof(buf
), line
, "Spd=", " ") < 0) {
1460 if (!strcmp(buf
, "5000")) {
1461 speed
= USB_SPEED_SUPER
;
1462 } else if (!strcmp(buf
, "480")) {
1463 speed
= USB_SPEED_HIGH
;
1464 } else if (!strcmp(buf
, "1.5")) {
1465 speed
= USB_SPEED_LOW
;
1467 speed
= USB_SPEED_FULL
;
1469 product_name
[0] = '\0';
1474 } else if (line
[0] == 'P' && line
[1] == ':') {
1475 if (get_tag_value(buf
, sizeof(buf
), line
, "Vendor=", " ") < 0) {
1478 vendor_id
= strtoul(buf
, NULL
, 16);
1479 if (get_tag_value(buf
, sizeof(buf
), line
, "ProdID=", " ") < 0) {
1482 product_id
= strtoul(buf
, NULL
, 16);
1483 } else if (line
[0] == 'S' && line
[1] == ':') {
1484 if (get_tag_value(buf
, sizeof(buf
), line
, "Product=", "") < 0) {
1487 pstrcpy(product_name
, sizeof(product_name
), buf
);
1488 } else if (line
[0] == 'D' && line
[1] == ':') {
1489 if (get_tag_value(buf
, sizeof(buf
), line
, "Cls=", " (") < 0) {
1492 class_id
= strtoul(buf
, NULL
, 16);
1496 if (device_count
&& (vendor_id
|| product_id
)) {
1497 /* Add the last device. */
1498 ret
= func(opaque
, bus_num
, addr
, 0, class_id
, vendor_id
,
1499 product_id
, product_name
, speed
);
1509 * Read sys file-system device file
1511 * @line address of buffer to put file contents in
1512 * @line_size size of line
1513 * @device_file path to device file (printf format string)
1514 * @device_name device being opened (inserted into device_file)
1516 * @return 0 failed, 1 succeeded ('line' contains data)
1518 static int usb_host_read_file(char *line
, size_t line_size
,
1519 const char *device_file
, const char *device_name
)
1523 char filename
[PATH_MAX
];
1525 snprintf(filename
, PATH_MAX
, USBSYSBUS_PATH
"/devices/%s/%s", device_name
,
1527 f
= fopen(filename
, "r");
1529 ret
= fgets(line
, line_size
, f
) != NULL
;
1537 * Use /sys/bus/usb/devices/ directory to determine host's USB
1540 * This code is based on Robert Schiele's original patches posted to
1541 * the Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
1543 static int usb_host_scan_sys(void *opaque
, USBScanFunc
*func
)
1547 int bus_num
, addr
, speed
, class_id
, product_id
, vendor_id
;
1549 char port
[MAX_PORTLEN
];
1550 char product_name
[512];
1553 dir
= opendir(USBSYSBUS_PATH
"/devices");
1555 perror("husb: cannot open devices directory");
1559 while ((de
= readdir(dir
))) {
1560 if (de
->d_name
[0] != '.' && !strchr(de
->d_name
, ':')) {
1561 if (sscanf(de
->d_name
, "%d-%7[0-9.]", &bus_num
, port
) < 2) {
1565 if (!usb_host_read_file(line
, sizeof(line
), "devnum", de
->d_name
)) {
1568 if (sscanf(line
, "%d", &addr
) != 1) {
1571 if (!usb_host_read_file(line
, sizeof(line
), "bDeviceClass",
1575 if (sscanf(line
, "%x", &class_id
) != 1) {
1579 if (!usb_host_read_file(line
, sizeof(line
), "idVendor",
1583 if (sscanf(line
, "%x", &vendor_id
) != 1) {
1586 if (!usb_host_read_file(line
, sizeof(line
), "idProduct",
1590 if (sscanf(line
, "%x", &product_id
) != 1) {
1593 if (!usb_host_read_file(line
, sizeof(line
), "product",
1597 if (strlen(line
) > 0) {
1598 line
[strlen(line
) - 1] = '\0';
1600 pstrcpy(product_name
, sizeof(product_name
), line
);
1603 if (!usb_host_read_file(line
, sizeof(line
), "speed", de
->d_name
)) {
1606 if (!strcmp(line
, "5000\n")) {
1607 speed
= USB_SPEED_SUPER
;
1608 } else if (!strcmp(line
, "480\n")) {
1609 speed
= USB_SPEED_HIGH
;
1610 } else if (!strcmp(line
, "1.5\n")) {
1611 speed
= USB_SPEED_LOW
;
1613 speed
= USB_SPEED_FULL
;
1616 ret
= func(opaque
, bus_num
, addr
, port
, class_id
, vendor_id
,
1617 product_id
, product_name
, speed
);
1631 * Determine how to access the host's USB devices and call the
1632 * specific support function.
1634 static int usb_host_scan(void *opaque
, USBScanFunc
*func
)
1636 Monitor
*mon
= cur_mon
;
1640 const char *fs_type
[] = {"unknown", "proc", "dev", "sys"};
1641 char devpath
[PATH_MAX
];
1643 /* only check the host once */
1645 dir
= opendir(USBSYSBUS_PATH
"/devices");
1647 /* devices found in /dev/bus/usb/ (yes - not a mistake!) */
1648 strcpy(devpath
, USBDEVBUS_PATH
);
1649 usb_fs_type
= USB_FS_SYS
;
1651 DPRINTF(USBDBG_DEVOPENED
, USBSYSBUS_PATH
);
1654 f
= fopen(USBPROCBUS_PATH
"/devices", "r");
1656 /* devices found in /proc/bus/usb/ */
1657 strcpy(devpath
, USBPROCBUS_PATH
);
1658 usb_fs_type
= USB_FS_PROC
;
1660 DPRINTF(USBDBG_DEVOPENED
, USBPROCBUS_PATH
);
1663 /* try additional methods if an access method hasn't been found yet */
1664 f
= fopen(USBDEVBUS_PATH
"/devices", "r");
1666 /* devices found in /dev/bus/usb/ */
1667 strcpy(devpath
, USBDEVBUS_PATH
);
1668 usb_fs_type
= USB_FS_DEV
;
1670 DPRINTF(USBDBG_DEVOPENED
, USBDEVBUS_PATH
);
1676 monitor_printf(mon
, "husb: unable to access USB devices\n");
1681 /* the module setting (used later for opening devices) */
1682 usb_host_device_path
= qemu_mallocz(strlen(devpath
)+1);
1683 strcpy(usb_host_device_path
, devpath
);
1685 monitor_printf(mon
, "husb: using %s file-system with %s\n",
1686 fs_type
[usb_fs_type
], usb_host_device_path
);
1690 switch (usb_fs_type
) {
1693 ret
= usb_host_scan_dev(opaque
, func
);
1696 ret
= usb_host_scan_sys(opaque
, func
);
1705 static QEMUTimer
*usb_auto_timer
;
1707 static int usb_host_auto_scan(void *opaque
, int bus_num
, int addr
, char *port
,
1708 int class_id
, int vendor_id
, int product_id
,
1709 const char *product_name
, int speed
)
1711 struct USBAutoFilter
*f
;
1712 struct USBHostDevice
*s
;
1718 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1721 if (f
->bus_num
> 0 && f
->bus_num
!= bus_num
) {
1724 if (f
->addr
> 0 && f
->addr
!= addr
) {
1727 if (f
->port
!= NULL
&& (port
== NULL
|| strcmp(f
->port
, port
) != 0)) {
1731 if (f
->vendor_id
> 0 && f
->vendor_id
!= vendor_id
) {
1735 if (f
->product_id
> 0 && f
->product_id
!= product_id
) {
1738 /* We got a match */
1740 /* Already attached ? */
1744 DPRINTF("husb: auto open: bus_num %d addr %d\n", bus_num
, addr
);
1746 usb_host_open(s
, bus_num
, addr
, port
, product_name
, speed
);
1753 static void usb_host_auto_check(void *unused
)
1755 struct USBHostDevice
*s
;
1756 int unconnected
= 0;
1758 usb_host_scan(NULL
, usb_host_auto_scan
);
1760 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1766 if (unconnected
== 0) {
1767 /* nothing to watch */
1768 if (usb_auto_timer
) {
1769 qemu_del_timer(usb_auto_timer
);
1774 if (!usb_auto_timer
) {
1775 usb_auto_timer
= qemu_new_timer_ms(rt_clock
, usb_host_auto_check
, NULL
);
1776 if (!usb_auto_timer
) {
1780 qemu_mod_timer(usb_auto_timer
, qemu_get_clock_ms(rt_clock
) + 2000);
1784 * Autoconnect filter
1786 * auto:bus:dev[:vid:pid]
1787 * auto:bus.dev[:vid:pid]
1789 * bus - bus number (dec, * means any)
1790 * dev - device number (dec, * means any)
1791 * vid - vendor id (hex, * means any)
1792 * pid - product id (hex, * means any)
1794 * See 'lsusb' output.
1796 static int parse_filter(const char *spec
, struct USBAutoFilter
*f
)
1798 enum { BUS
, DEV
, VID
, PID
, DONE
};
1799 const char *p
= spec
;
1807 for (i
= BUS
; i
< DONE
; i
++) {
1808 p
= strpbrk(p
, ":.");
1818 case BUS
: f
->bus_num
= strtol(p
, NULL
, 10); break;
1819 case DEV
: f
->addr
= strtol(p
, NULL
, 10); break;
1820 case VID
: f
->vendor_id
= strtol(p
, NULL
, 16); break;
1821 case PID
: f
->product_id
= strtol(p
, NULL
, 16); break;
1826 fprintf(stderr
, "husb: invalid auto filter spec %s\n", spec
);
1833 /**********************/
1834 /* USB host device info */
1836 struct usb_class_info
{
1838 const char *class_name
;
1841 static const struct usb_class_info usb_class_info
[] = {
1842 { USB_CLASS_AUDIO
, "Audio"},
1843 { USB_CLASS_COMM
, "Communication"},
1844 { USB_CLASS_HID
, "HID"},
1845 { USB_CLASS_HUB
, "Hub" },
1846 { USB_CLASS_PHYSICAL
, "Physical" },
1847 { USB_CLASS_PRINTER
, "Printer" },
1848 { USB_CLASS_MASS_STORAGE
, "Storage" },
1849 { USB_CLASS_CDC_DATA
, "Data" },
1850 { USB_CLASS_APP_SPEC
, "Application Specific" },
1851 { USB_CLASS_VENDOR_SPEC
, "Vendor Specific" },
1852 { USB_CLASS_STILL_IMAGE
, "Still Image" },
1853 { USB_CLASS_CSCID
, "Smart Card" },
1854 { USB_CLASS_CONTENT_SEC
, "Content Security" },
1858 static const char *usb_class_str(uint8_t class)
1860 const struct usb_class_info
*p
;
1861 for(p
= usb_class_info
; p
->class != -1; p
++) {
1862 if (p
->class == class) {
1866 return p
->class_name
;
1869 static void usb_info_device(Monitor
*mon
, int bus_num
, int addr
, char *port
,
1870 int class_id
, int vendor_id
, int product_id
,
1871 const char *product_name
,
1874 const char *class_str
, *speed_str
;
1880 case USB_SPEED_FULL
:
1883 case USB_SPEED_HIGH
:
1886 case USB_SPEED_SUPER
:
1894 monitor_printf(mon
, " Bus %d, Addr %d, Port %s, Speed %s Mb/s\n",
1895 bus_num
, addr
, port
, speed_str
);
1896 class_str
= usb_class_str(class_id
);
1898 monitor_printf(mon
, " %s:", class_str
);
1900 monitor_printf(mon
, " Class %02x:", class_id
);
1902 monitor_printf(mon
, " USB device %04x:%04x", vendor_id
, product_id
);
1903 if (product_name
[0] != '\0') {
1904 monitor_printf(mon
, ", %s", product_name
);
1906 monitor_printf(mon
, "\n");
1909 static int usb_host_info_device(void *opaque
, int bus_num
, int addr
,
1910 char *path
, int class_id
,
1911 int vendor_id
, int product_id
,
1912 const char *product_name
,
1915 Monitor
*mon
= opaque
;
1917 usb_info_device(mon
, bus_num
, addr
, path
, class_id
, vendor_id
, product_id
,
1918 product_name
, speed
);
1922 static void dec2str(int val
, char *str
, size_t size
)
1925 snprintf(str
, size
, "*");
1927 snprintf(str
, size
, "%d", val
);
1931 static void hex2str(int val
, char *str
, size_t size
)
1934 snprintf(str
, size
, "*");
1936 snprintf(str
, size
, "%04x", val
);
1940 void usb_host_info(Monitor
*mon
)
1942 struct USBAutoFilter
*f
;
1943 struct USBHostDevice
*s
;
1945 usb_host_scan(mon
, usb_host_info_device
);
1947 if (QTAILQ_EMPTY(&hostdevs
)) {
1951 monitor_printf(mon
, " Auto filters:\n");
1952 QTAILQ_FOREACH(s
, &hostdevs
, next
) {
1953 char bus
[10], addr
[10], vid
[10], pid
[10];
1955 dec2str(f
->bus_num
, bus
, sizeof(bus
));
1956 dec2str(f
->addr
, addr
, sizeof(addr
));
1957 hex2str(f
->vendor_id
, vid
, sizeof(vid
));
1958 hex2str(f
->product_id
, pid
, sizeof(pid
));
1959 monitor_printf(mon
, " Bus %s, Addr %s, Port %s, ID %s:%s\n",
1960 bus
, addr
, f
->port
? f
->port
: "*", vid
, pid
);