]> Git Repo - qemu.git/blame - usb-linux.c
uhci: rewrite UHCI emulator, fully async operation with multiple outstanding transact...
[qemu.git] / usb-linux.c
CommitLineData
bb36d470
FB
1/*
2 * Linux host USB redirector
3 *
4 * Copyright (c) 2005 Fabrice Bellard
5fafdf24 5 *
4b096fc9
AL
6 * Support for host device auto connect & disconnect
7 * Copyright (c) 2008 Max Krasnyansky
8 *
bb36d470
FB
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
87ecb68b 27#include "qemu-common.h"
1f3870ab 28#include "qemu-timer.h"
87ecb68b
PB
29#include "hw/usb.h"
30#include "console.h"
bb36d470
FB
31
32#if defined(__linux__)
33#include <dirent.h>
34#include <sys/ioctl.h>
35#include <linux/usbdevice_fs.h>
36#include <linux/version.h>
b9dc033c 37#include <signal.h>
bb36d470
FB
38
39/* We redefine it to avoid version problems */
40struct usb_ctrltransfer {
41 uint8_t bRequestType;
42 uint8_t bRequest;
43 uint16_t wValue;
44 uint16_t wIndex;
45 uint16_t wLength;
46 uint32_t timeout;
47 void *data;
48};
49
a594cfbf 50typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id,
5fafdf24 51 int vendor_id, int product_id,
a594cfbf 52 const char *product_name, int speed);
5fafdf24 53static int usb_host_find_device(int *pbus_num, int *paddr,
1f6e24e7 54 char *product_name, int product_name_size,
a594cfbf 55 const char *devname);
bb36d470 56
a594cfbf 57//#define DEBUG
b9dc033c
AZ
58//#define DEBUG_ISOCH
59//#define USE_ASYNCIO
bb36d470
FB
60
61#define USBDEVFS_PATH "/proc/bus/usb"
1f6e24e7 62#define PRODUCT_NAME_SZ 32
b9dc033c
AZ
63#define SIG_ISOCOMPLETE (SIGRTMIN+7)
64#define MAX_ENDPOINTS 16
bb36d470 65
b9dc033c
AZ
66struct sigaction sigact;
67
68/* endpoint association data */
69struct endp_data {
70 uint8_t type;
71};
72
4b096fc9
AL
73
74
b9dc033c 75/* FIXME: move USBPacket to PendingURB */
bb36d470
FB
76typedef struct USBHostDevice {
77 USBDevice dev;
78 int fd;
046833ea 79 int pipe_fds[2];
b9dc033c
AZ
80 USBPacket *packet;
81 struct endp_data endp_table[MAX_ENDPOINTS];
82 int configuration;
83 uint8_t descr[1024];
84 int descr_len;
85 int urbs_ready;
4b096fc9 86
1f3870ab 87 QEMUTimer *timer;
4b096fc9
AL
88
89 /* Host side address */
90 int bus_num;
91 int addr;
92
93 struct USBHostDevice *next;
bb36d470
FB
94} USBHostDevice;
95
4b096fc9
AL
96static USBHostDevice *hostdev_list;
97
98static void hostdev_link(USBHostDevice *dev)
99{
100 dev->next = hostdev_list;
101 hostdev_list = dev;
102}
103
104static void hostdev_unlink(USBHostDevice *dev)
105{
106 USBHostDevice *pdev = hostdev_list;
107 USBHostDevice **prev = &hostdev_list;
108
109 while (pdev) {
110 if (pdev == dev) {
111 *prev = dev->next;
112 return;
113 }
114
115 prev = &pdev->next;
116 pdev = pdev->next;
117 }
118}
119
120static USBHostDevice *hostdev_find(int bus_num, int addr)
121{
122 USBHostDevice *s = hostdev_list;
123 while (s) {
124 if (s->bus_num == bus_num && s->addr == addr)
125 return s;
126 s = s->next;
127 }
128 return NULL;
129}
130
b9dc033c
AZ
131typedef struct PendingURB {
132 struct usbdevfs_urb *urb;
b9dc033c
AZ
133 int status;
134 struct PendingURB *next;
135} PendingURB;
136
4d043a09 137static PendingURB *pending_urbs = NULL;
b9dc033c 138
4d043a09 139static int add_pending_urb(struct usbdevfs_urb *urb)
b9dc033c
AZ
140{
141 PendingURB *purb = qemu_mallocz(sizeof(PendingURB));
142 if (purb) {
143 purb->urb = urb;
b9dc033c
AZ
144 purb->status = 0;
145 purb->next = pending_urbs;
146 pending_urbs = purb;
147 return 1;
148 }
149 return 0;
150}
151
4d043a09 152static int del_pending_urb(struct usbdevfs_urb *urb)
b9dc033c
AZ
153{
154 PendingURB *purb = pending_urbs;
155 PendingURB *prev = NULL;
156
157 while (purb && purb->urb != urb) {
158 prev = purb;
159 purb = purb->next;
160 }
161
162 if (purb && purb->urb == urb) {
163 if (prev) {
164 prev->next = purb->next;
165 } else {
166 pending_urbs = purb->next;
167 }
168 qemu_free(purb);
169 return 1;
170 }
171 return 0;
172}
173
4d043a09
AZ
174#ifdef USE_ASYNCIO
175static PendingURB *get_pending_urb(struct usbdevfs_urb *urb)
b9dc033c
AZ
176{
177 PendingURB *purb = pending_urbs;
178
179 while (purb && purb->urb != urb) {
180 purb = purb->next;
181 }
182
183 if (purb && purb->urb == urb) {
184 return purb;
185 }
186 return NULL;
187}
4d043a09 188#endif
b9dc033c
AZ
189
190static int usb_host_update_interfaces(USBHostDevice *dev, int configuration)
191{
192 int dev_descr_len, config_descr_len;
193 int interface, nb_interfaces, nb_configurations;
194 int ret, i;
195
196 if (configuration == 0) /* address state - ignore */
197 return 1;
198
199 i = 0;
200 dev_descr_len = dev->descr[0];
201 if (dev_descr_len > dev->descr_len)
202 goto fail;
203 nb_configurations = dev->descr[17];
204
205 i += dev_descr_len;
206 while (i < dev->descr_len) {
207#ifdef DEBUG
208 printf("i is %d, descr_len is %d, dl %d, dt %d\n", i, dev->descr_len,
209 dev->descr[i], dev->descr[i+1]);
210#endif
211 if (dev->descr[i+1] != USB_DT_CONFIG) {
212 i += dev->descr[i];
213 continue;
214 }
215 config_descr_len = dev->descr[i];
216
1f3870ab
AL
217#ifdef DEBUG
218 printf("config #%d need %d\n", dev->descr[i + 5], configuration);
219#endif
220
221 if (configuration < 0 || configuration == dev->descr[i + 5])
b9dc033c
AZ
222 break;
223
224 i += config_descr_len;
225 }
226
227 if (i >= dev->descr_len) {
228 printf("usb_host: error - device has no matching configuration\n");
229 goto fail;
230 }
231 nb_interfaces = dev->descr[i + 4];
232
233#ifdef USBDEVFS_DISCONNECT
234 /* earlier Linux 2.4 do not support that */
235 {
236 struct usbdevfs_ioctl ctrl;
237 for (interface = 0; interface < nb_interfaces; interface++) {
238 ctrl.ioctl_code = USBDEVFS_DISCONNECT;
239 ctrl.ifno = interface;
240 ret = ioctl(dev->fd, USBDEVFS_IOCTL, &ctrl);
241 if (ret < 0 && errno != ENODATA) {
242 perror("USBDEVFS_DISCONNECT");
243 goto fail;
244 }
245 }
246 }
247#endif
248
249 /* XXX: only grab if all interfaces are free */
250 for (interface = 0; interface < nb_interfaces; interface++) {
251 ret = ioctl(dev->fd, USBDEVFS_CLAIMINTERFACE, &interface);
252 if (ret < 0) {
253 if (errno == EBUSY) {
254 fprintf(stderr,
255 "usb_host: warning - device already grabbed\n");
256 } else {
257 perror("USBDEVFS_CLAIMINTERFACE");
258 }
259 fail:
260 return 0;
261 }
262 }
263
264#ifdef DEBUG
265 printf("usb_host: %d interfaces claimed for configuration %d\n",
266 nb_interfaces, configuration);
267#endif
268
269 return 1;
270}
271
059809e4 272static void usb_host_handle_reset(USBDevice *dev)
bb36d470
FB
273{
274#if 0
275 USBHostDevice *s = (USBHostDevice *)dev;
276 /* USBDEVFS_RESET, but not the first time as it has already be
277 done by the host OS */
278 ioctl(s->fd, USBDEVFS_RESET);
279#endif
5fafdf24 280}
bb36d470 281
059809e4
FB
282static void usb_host_handle_destroy(USBDevice *dev)
283{
284 USBHostDevice *s = (USBHostDevice *)dev;
285
1f3870ab
AL
286 qemu_del_timer(s->timer);
287
4b096fc9
AL
288 hostdev_unlink(s);
289
059809e4
FB
290 if (s->fd >= 0)
291 close(s->fd);
1f3870ab 292
059809e4
FB
293 qemu_free(s);
294}
295
b9dc033c
AZ
296static int usb_linux_update_endp_table(USBHostDevice *s);
297
bb36d470
FB
298static int usb_host_handle_control(USBDevice *dev,
299 int request,
300 int value,
301 int index,
302 int length,
303 uint8_t *data)
304{
305 USBHostDevice *s = (USBHostDevice *)dev;
306 struct usb_ctrltransfer ct;
b9dc033c
AZ
307 struct usbdevfs_setinterface si;
308 int intf_update_required = 0;
bb36d470
FB
309 int ret;
310
311 if (request == (DeviceOutRequest | USB_REQ_SET_ADDRESS)) {
312 /* specific SET_ADDRESS support */
313 dev->addr = value;
314 return 0;
b9dc033c
AZ
315 } else if (request == ((USB_RECIP_INTERFACE << 8) |
316 USB_REQ_SET_INTERFACE)) {
317 /* set alternate setting for the interface */
318 si.interface = index;
319 si.altsetting = value;
320 ret = ioctl(s->fd, USBDEVFS_SETINTERFACE, &si);
321 usb_linux_update_endp_table(s);
322 } else if (request == (DeviceOutRequest | USB_REQ_SET_CONFIGURATION)) {
323#ifdef DEBUG
324 printf("usb_host_handle_control: SET_CONFIGURATION request - "
325 "config %d\n", value & 0xff);
326#endif
327 if (s->configuration != (value & 0xff)) {
328 s->configuration = (value & 0xff);
329 intf_update_required = 1;
330 }
331 goto do_request;
bb36d470 332 } else {
b9dc033c 333 do_request:
bb36d470
FB
334 ct.bRequestType = request >> 8;
335 ct.bRequest = request;
336 ct.wValue = value;
337 ct.wIndex = index;
338 ct.wLength = length;
339 ct.timeout = 50;
340 ct.data = data;
341 ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
b9dc033c
AZ
342 }
343
344 if (ret < 0) {
345 switch(errno) {
346 case ETIMEDOUT:
347 return USB_RET_NAK;
348 default:
349 return USB_RET_STALL;
bb36d470 350 }
b9dc033c
AZ
351 } else {
352 if (intf_update_required) {
353#ifdef DEBUG
354 printf("usb_host_handle_control: updating interfaces\n");
355#endif
356 usb_host_update_interfaces(s, value & 0xff);
357 }
358 return ret;
359 }
bb36d470
FB
360}
361
b9dc033c
AZ
362static int usb_host_handle_isoch(USBDevice *dev, USBPacket *p);
363
4d611c9a 364static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
bb36d470
FB
365{
366 USBHostDevice *s = (USBHostDevice *)dev;
367 struct usbdevfs_bulktransfer bt;
368 int ret;
4d611c9a 369 uint8_t devep = p->devep;
bb36d470 370
b9dc033c
AZ
371 if (s->endp_table[p->devep - 1].type == USBDEVFS_URB_TYPE_ISO) {
372 return usb_host_handle_isoch(dev, p);
373 }
374
bb36d470
FB
375 /* XXX: optimize and handle all data types by looking at the
376 config descriptor */
4d611c9a 377 if (p->pid == USB_TOKEN_IN)
bb36d470
FB
378 devep |= 0x80;
379 bt.ep = devep;
4d611c9a 380 bt.len = p->len;
bb36d470 381 bt.timeout = 50;
4d611c9a 382 bt.data = p->data;
bb36d470
FB
383 ret = ioctl(s->fd, USBDEVFS_BULK, &bt);
384 if (ret < 0) {
385 switch(errno) {
386 case ETIMEDOUT:
387 return USB_RET_NAK;
388 case EPIPE:
389 default:
390#ifdef DEBUG
391 printf("handle_data: errno=%d\n", errno);
392#endif
393 return USB_RET_STALL;
394 }
395 } else {
396 return ret;
397 }
398}
399
4d043a09 400#ifdef USE_ASYNCIO
046833ea 401static void urb_completion_pipe_read(void *opaque)
4d043a09 402{
046833ea 403 USBHostDevice *s = opaque;
4d043a09 404 USBPacket *p = s->packet;
046833ea
AZ
405 PendingURB *pending_urb = NULL;
406 struct usbdevfs_urb *purb = NULL;
407 int len, ret;
408
409 len = read(s->pipe_fds[0], &pending_urb, sizeof(pending_urb));
410 if (len != sizeof(pending_urb)) {
411 printf("urb_completion: error reading pending_urb, len=%d\n", len);
412 return;
413 }
4d043a09 414
046833ea 415 /* FIXME: handle pending_urb->status */
4d043a09
AZ
416 del_pending_urb(pending_urb->urb);
417
418 if (!p) {
419 s->urbs_ready++;
420 return;
421 }
422
423 ret = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &purb);
424 if (ret < 0) {
046833ea 425 printf("urb_completion: REAPURBNDELAY ioctl=%d errno=%d\n",
4d043a09
AZ
426 ret, errno);
427 return;
428 }
429
430#ifdef DEBUG_ISOCH
431 if (purb == pending_urb->urb) {
046833ea 432 printf("urb_completion: urb mismatch reaped=%p pending=%p\n",
4d043a09
AZ
433 purb, urb);
434 }
435#endif
436
437 p->len = purb->actual_length;
438 usb_packet_complete(p);
439 qemu_free(purb);
440 s->packet = NULL;
441}
b9dc033c 442
4d043a09
AZ
443static void isoch_done(int signum, siginfo_t *info, void *context)
444{
b9dc033c
AZ
445 struct usbdevfs_urb *urb = (struct usbdevfs_urb *)info->si_addr;
446 USBHostDevice *s = (USBHostDevice *)urb->usercontext;
447 PendingURB *purb;
448
449 if (info->si_code != SI_ASYNCIO ||
450 info->si_signo != SIG_ISOCOMPLETE) {
451 return;
452 }
453
454 purb = get_pending_urb(urb);
455 if (purb) {
046833ea
AZ
456 purb->status = info->si_errno;
457 write(s->pipe_fds[1], &purb, sizeof(purb));
b9dc033c
AZ
458 }
459}
4d043a09 460#endif
b9dc033c
AZ
461
462static int usb_host_handle_isoch(USBDevice *dev, USBPacket *p)
463{
464 USBHostDevice *s = (USBHostDevice *)dev;
465 struct usbdevfs_urb *urb, *purb = NULL;
466 int ret;
467 uint8_t devep = p->devep;
468
469 if (p->pid == USB_TOKEN_IN)
470 devep |= 0x80;
471
472 urb = qemu_mallocz(sizeof(struct usbdevfs_urb) +
473 sizeof(struct usbdevfs_iso_packet_desc));
474 if (!urb) {
475 printf("usb_host_handle_isoch: malloc failed\n");
476 return 0;
477 }
478
479 urb->type = USBDEVFS_URB_TYPE_ISO;
480 urb->endpoint = devep;
481 urb->status = 0;
482 urb->flags = USBDEVFS_URB_ISO_ASAP;
483 urb->buffer = p->data;
484 urb->buffer_length = p->len;
485 urb->actual_length = 0;
486 urb->start_frame = 0;
487 urb->error_count = 0;
488#ifdef USE_ASYNCIO
489 urb->signr = SIG_ISOCOMPLETE;
490#else
491 urb->signr = 0;
492#endif
493 urb->usercontext = s;
494 urb->number_of_packets = 1;
495 urb->iso_frame_desc[0].length = p->len;
496 urb->iso_frame_desc[0].actual_length = 0;
497 urb->iso_frame_desc[0].status = 0;
498 ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
499 if (ret == 0) {
500 if (!add_pending_urb(urb)) {
501 printf("usb_host_handle_isoch: add_pending_urb failed %p\n", urb);
502 }
503 } else {
504 printf("usb_host_handle_isoch: SUBMITURB ioctl=%d errno=%d\n",
505 ret, errno);
506 qemu_free(urb);
507 switch(errno) {
508 case ETIMEDOUT:
509 return USB_RET_NAK;
510 case EPIPE:
511 default:
512 return USB_RET_STALL;
513 }
514 }
515#ifdef USE_ASYNCIO
516 /* FIXME: handle urbs_ready together with sync io
517 * workaround for injecting the signaled urbs into current frame */
518 if (s->urbs_ready > 0) {
519 ret = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &purb);
520 if (ret == 0) {
521 ret = purb->actual_length;
522 qemu_free(purb);
523 s->urbs_ready--;
524 }
525 return ret;
526 }
527 s->packet = p;
528 return USB_RET_ASYNC;
529#else
530 ret = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &purb);
531 if (ret == 0) {
532 if (del_pending_urb(purb)) {
533 ret = purb->actual_length;
534 qemu_free(purb);
535 } else {
536 printf("usb_host_handle_isoch: del_pending_urb failed %p\n", purb);
537 }
538 } else {
539#ifdef DEBUG_ISOCH
540 printf("usb_host_handle_isoch: REAPURBNDELAY ioctl=%d errno=%d\n",
541 ret, errno);
542#endif
543 }
544 return ret;
545#endif
546}
547
b9dc033c
AZ
548/* returns 1 on problem encountered or 0 for success */
549static int usb_linux_update_endp_table(USBHostDevice *s)
550{
551 uint8_t *descriptors;
552 uint8_t devep, type, configuration, alt_interface;
553 struct usb_ctrltransfer ct;
554 int interface, ret, length, i;
555
556 ct.bRequestType = USB_DIR_IN;
557 ct.bRequest = USB_REQ_GET_CONFIGURATION;
558 ct.wValue = 0;
559 ct.wIndex = 0;
560 ct.wLength = 1;
561 ct.data = &configuration;
562 ct.timeout = 50;
563
564 ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
565 if (ret < 0) {
566 perror("usb_linux_update_endp_table");
567 return 1;
568 }
569
570 /* in address state */
571 if (configuration == 0)
572 return 1;
573
574 /* get the desired configuration, interface, and endpoint descriptors
575 * from device description */
576 descriptors = &s->descr[18];
577 length = s->descr_len - 18;
578 i = 0;
579
580 if (descriptors[i + 1] != USB_DT_CONFIG ||
581 descriptors[i + 5] != configuration) {
582 printf("invalid descriptor data - configuration\n");
583 return 1;
584 }
585 i += descriptors[i];
586
587 while (i < length) {
588 if (descriptors[i + 1] != USB_DT_INTERFACE ||
589 (descriptors[i + 1] == USB_DT_INTERFACE &&
590 descriptors[i + 4] == 0)) {
591 i += descriptors[i];
592 continue;
593 }
594
595 interface = descriptors[i + 2];
596
597 ct.bRequestType = USB_DIR_IN | USB_RECIP_INTERFACE;
598 ct.bRequest = USB_REQ_GET_INTERFACE;
599 ct.wValue = 0;
600 ct.wIndex = interface;
601 ct.wLength = 1;
602 ct.data = &alt_interface;
603 ct.timeout = 50;
604
605 ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
606 if (ret < 0) {
607 perror("usb_linux_update_endp_table");
608 return 1;
609 }
610
611 /* the current interface descriptor is the active interface
612 * and has endpoints */
613 if (descriptors[i + 3] != alt_interface) {
614 i += descriptors[i];
615 continue;
616 }
617
618 /* advance to the endpoints */
619 while (i < length && descriptors[i +1] != USB_DT_ENDPOINT)
620 i += descriptors[i];
621
622 if (i >= length)
623 break;
624
625 while (i < length) {
626 if (descriptors[i + 1] != USB_DT_ENDPOINT)
627 break;
628
629 devep = descriptors[i + 2];
630 switch (descriptors[i + 3] & 0x3) {
631 case 0x00:
632 type = USBDEVFS_URB_TYPE_CONTROL;
633 break;
634 case 0x01:
635 type = USBDEVFS_URB_TYPE_ISO;
636 break;
637 case 0x02:
638 type = USBDEVFS_URB_TYPE_BULK;
639 break;
640 case 0x03:
641 type = USBDEVFS_URB_TYPE_INTERRUPT;
642 break;
643 default:
644 printf("usb_host: malformed endpoint type\n");
645 type = USBDEVFS_URB_TYPE_BULK;
646 }
647 s->endp_table[(devep & 0xf) - 1].type = type;
648
649 i += descriptors[i];
650 }
651 }
652 return 0;
653}
654
1f3870ab
AL
655static void usb_host_device_check(void *priv)
656{
657 USBHostDevice *s = priv;
658 struct usbdevfs_connectinfo ci;
659 int err;
660
661 err = ioctl(s->fd, USBDEVFS_CONNECTINFO, &ci);
662 if (err < 0) {
663 printf("usb device %d.%d disconnected\n", 0, s->dev.addr);
664 usb_device_del_addr(0, s->dev.addr);
665 return;
666 }
667
668 qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 1000);
669}
670
4b096fc9 671static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *prod_name)
bb36d470 672{
b9dc033c
AZ
673 int fd = -1, ret;
674 USBHostDevice *dev = NULL;
bb36d470 675 struct usbdevfs_connectinfo ci;
a594cfbf 676 char buf[1024];
1f3870ab 677
b9dc033c
AZ
678 dev = qemu_mallocz(sizeof(USBHostDevice));
679 if (!dev)
680 goto fail;
681
4b096fc9
AL
682 dev->bus_num = bus_num;
683 dev->addr = addr;
684
1f3870ab
AL
685 dev->timer = qemu_new_timer(rt_clock, usb_host_device_check, (void *) dev);
686 if (!dev->timer)
687 goto fail;
688
689#ifdef DEBUG
4b096fc9 690 printf("usb_host_device_open %d.%d\n", bus_num, addr);
b9dc033c 691#endif
3b46e624 692
5fafdf24 693 snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d",
a594cfbf 694 bus_num, addr);
b9dc033c 695 fd = open(buf, O_RDWR | O_NONBLOCK);
bb36d470 696 if (fd < 0) {
a594cfbf 697 perror(buf);
1f3870ab 698 goto fail;
bb36d470
FB
699 }
700
b9dc033c
AZ
701 /* read the device description */
702 dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
703 if (dev->descr_len <= 0) {
046833ea 704 perror("usb_host_device_open: reading device data failed");
bb36d470
FB
705 goto fail;
706 }
3b46e624 707
b9dc033c 708#ifdef DEBUG
868bfe2b 709 {
b9dc033c
AZ
710 int x;
711 printf("=== begin dumping device descriptor data ===\n");
712 for (x = 0; x < dev->descr_len; x++)
713 printf("%02x ", dev->descr[x]);
714 printf("\n=== end dumping device descriptor data ===\n");
bb36d470 715 }
a594cfbf
FB
716#endif
717
b9dc033c
AZ
718 dev->fd = fd;
719 dev->configuration = 1;
720
721 /* XXX - do something about initial configuration */
1f3870ab 722 if (!usb_host_update_interfaces(dev, -1))
b9dc033c 723 goto fail;
bb36d470
FB
724
725 ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
726 if (ret < 0) {
046833ea 727 perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
bb36d470
FB
728 goto fail;
729 }
730
731#ifdef DEBUG
a594cfbf 732 printf("host USB device %d.%d grabbed\n", bus_num, addr);
3b46e624 733#endif
bb36d470 734
b9dc033c
AZ
735 ret = usb_linux_update_endp_table(dev);
736 if (ret)
bb36d470 737 goto fail;
b9dc033c 738
bb36d470
FB
739 if (ci.slow)
740 dev->dev.speed = USB_SPEED_LOW;
741 else
742 dev->dev.speed = USB_SPEED_HIGH;
a594cfbf 743 dev->dev.handle_packet = usb_generic_handle_packet;
bb36d470
FB
744
745 dev->dev.handle_reset = usb_host_handle_reset;
746 dev->dev.handle_control = usb_host_handle_control;
747 dev->dev.handle_data = usb_host_handle_data;
059809e4 748 dev->dev.handle_destroy = usb_host_handle_destroy;
1f6e24e7 749
4b096fc9 750 if (!prod_name || prod_name[0] == '\0')
1f6e24e7 751 snprintf(dev->dev.devname, sizeof(dev->dev.devname),
4b096fc9 752 "host:%d.%d", bus_num, addr);
1f6e24e7
FB
753 else
754 pstrcpy(dev->dev.devname, sizeof(dev->dev.devname),
4b096fc9 755 prod_name);
1f6e24e7 756
b9dc033c
AZ
757#ifdef USE_ASYNCIO
758 /* set up the signal handlers */
759 sigemptyset(&sigact.sa_mask);
760 sigact.sa_sigaction = isoch_done;
761 sigact.sa_flags = SA_SIGINFO;
762 sigact.sa_restorer = 0;
763 ret = sigaction(SIG_ISOCOMPLETE, &sigact, NULL);
764 if (ret < 0) {
046833ea
AZ
765 perror("usb_host_device_open: sigaction failed");
766 goto fail;
767 }
768
769 if (pipe(dev->pipe_fds) < 0) {
770 perror("usb_host_device_open: pipe creation failed");
771 goto fail;
b9dc033c 772 }
046833ea
AZ
773 fcntl(dev->pipe_fds[0], F_SETFL, O_NONBLOCK | O_ASYNC);
774 fcntl(dev->pipe_fds[1], F_SETFL, O_NONBLOCK);
775 qemu_set_fd_handler(dev->pipe_fds[0], urb_completion_pipe_read, NULL, dev);
b9dc033c 776#endif
1f3870ab
AL
777
778 /* Start the timer to detect disconnect */
779 qemu_mod_timer(dev->timer, qemu_get_clock(rt_clock) + 1000);
780
4b096fc9
AL
781 hostdev_link(dev);
782
b9dc033c 783 dev->urbs_ready = 0;
a594cfbf 784 return (USBDevice *)dev;
4b096fc9 785
b9dc033c 786fail:
1f3870ab
AL
787 if (dev) {
788 if (dev->timer)
789 qemu_del_timer(dev->timer);
b9dc033c 790 qemu_free(dev);
1f3870ab 791 }
b9dc033c
AZ
792 close(fd);
793 return NULL;
a594cfbf 794}
bb36d470 795
4b096fc9
AL
796USBDevice *usb_host_device_open(const char *devname)
797{
798 int bus_num, addr;
799 char product_name[PRODUCT_NAME_SZ];
800
801 if (usb_host_find_device(&bus_num, &addr,
802 product_name, sizeof(product_name),
803 devname) < 0)
804 return NULL;
805
806 if (hostdev_find(bus_num, addr)) {
807 printf("host usb device %d.%d is already open\n", bus_num, addr);
808 return NULL;
809 }
810
811 return usb_host_device_open_addr(bus_num, addr, product_name);
812}
813
a594cfbf 814static int get_tag_value(char *buf, int buf_size,
5fafdf24 815 const char *str, const char *tag,
a594cfbf
FB
816 const char *stopchars)
817{
818 const char *p;
819 char *q;
820 p = strstr(str, tag);
821 if (!p)
822 return -1;
823 p += strlen(tag);
824 while (isspace(*p))
825 p++;
826 q = buf;
827 while (*p != '\0' && !strchr(stopchars, *p)) {
828 if ((q - buf) < (buf_size - 1))
829 *q++ = *p;
830 p++;
831 }
832 *q = '\0';
833 return q - buf;
bb36d470
FB
834}
835
a594cfbf 836static int usb_host_scan(void *opaque, USBScanFunc *func)
bb36d470 837{
a594cfbf
FB
838 FILE *f;
839 char line[1024];
bb36d470 840 char buf[1024];
a594cfbf
FB
841 int bus_num, addr, speed, device_count, class_id, product_id, vendor_id;
842 int ret;
843 char product_name[512];
3b46e624 844
a594cfbf
FB
845 f = fopen(USBDEVFS_PATH "/devices", "r");
846 if (!f) {
847 term_printf("Could not open %s\n", USBDEVFS_PATH "/devices");
848 return 0;
849 }
850 device_count = 0;
851 bus_num = addr = speed = class_id = product_id = vendor_id = 0;
852 ret = 0;
bb36d470 853 for(;;) {
a594cfbf 854 if (fgets(line, sizeof(line), f) == NULL)
bb36d470 855 break;
a594cfbf
FB
856 if (strlen(line) > 0)
857 line[strlen(line) - 1] = '\0';
858 if (line[0] == 'T' && line[1] == ':') {
38ca0f6d
PB
859 if (device_count && (vendor_id || product_id)) {
860 /* New device. Add the previously discovered device. */
5fafdf24 861 ret = func(opaque, bus_num, addr, class_id, vendor_id,
a594cfbf
FB
862 product_id, product_name, speed);
863 if (ret)
864 goto the_end;
865 }
866 if (get_tag_value(buf, sizeof(buf), line, "Bus=", " ") < 0)
867 goto fail;
868 bus_num = atoi(buf);
869 if (get_tag_value(buf, sizeof(buf), line, "Dev#=", " ") < 0)
870 goto fail;
871 addr = atoi(buf);
872 if (get_tag_value(buf, sizeof(buf), line, "Spd=", " ") < 0)
873 goto fail;
874 if (!strcmp(buf, "480"))
875 speed = USB_SPEED_HIGH;
876 else if (!strcmp(buf, "1.5"))
877 speed = USB_SPEED_LOW;
878 else
879 speed = USB_SPEED_FULL;
880 product_name[0] = '\0';
881 class_id = 0xff;
882 device_count++;
883 product_id = 0;
884 vendor_id = 0;
885 } else if (line[0] == 'P' && line[1] == ':') {
886 if (get_tag_value(buf, sizeof(buf), line, "Vendor=", " ") < 0)
887 goto fail;
888 vendor_id = strtoul(buf, NULL, 16);
889 if (get_tag_value(buf, sizeof(buf), line, "ProdID=", " ") < 0)
890 goto fail;
891 product_id = strtoul(buf, NULL, 16);
892 } else if (line[0] == 'S' && line[1] == ':') {
893 if (get_tag_value(buf, sizeof(buf), line, "Product=", "") < 0)
894 goto fail;
895 pstrcpy(product_name, sizeof(product_name), buf);
896 } else if (line[0] == 'D' && line[1] == ':') {
897 if (get_tag_value(buf, sizeof(buf), line, "Cls=", " (") < 0)
898 goto fail;
899 class_id = strtoul(buf, NULL, 16);
bb36d470 900 }
a594cfbf
FB
901 fail: ;
902 }
38ca0f6d
PB
903 if (device_count && (vendor_id || product_id)) {
904 /* Add the last device. */
5fafdf24 905 ret = func(opaque, bus_num, addr, class_id, vendor_id,
a594cfbf 906 product_id, product_name, speed);
bb36d470 907 }
a594cfbf
FB
908 the_end:
909 fclose(f);
910 return ret;
bb36d470
FB
911}
912
4b096fc9
AL
913struct USBAutoFilter {
914 struct USBAutoFilter *next;
915 int bus_num;
916 int addr;
917 int vendor_id;
918 int product_id;
919};
920
921static QEMUTimer *usb_auto_timer;
922static struct USBAutoFilter *usb_auto_filter;
923
924static int usb_host_auto_scan(void *opaque, int bus_num, int addr,
925 int class_id, int vendor_id, int product_id,
926 const char *product_name, int speed)
927{
928 struct USBAutoFilter *f;
929 struct USBDevice *dev;
930
931 /* Ignore hubs */
932 if (class_id == 9)
933 return 0;
934
935 for (f = usb_auto_filter; f; f = f->next) {
936 // printf("Auto match: bus_num %d addr %d vid %d pid %d\n",
937 // bus_num, addr, vendor_id, product_id);
938
939 if (f->bus_num >= 0 && f->bus_num != bus_num)
940 continue;
941
942 if (f->addr >= 0 && f->addr != addr)
943 continue;
944
945 if (f->vendor_id >= 0 && f->vendor_id != vendor_id)
946 continue;
947
948 if (f->product_id >= 0 && f->product_id != product_id)
949 continue;
950
951 /* We got a match */
952
953 /* Allredy attached ? */
954 if (hostdev_find(bus_num, addr))
955 return 0;
956
957 printf("Auto open: bus_num %d addr %d\n", bus_num, addr);
958
959 dev = usb_host_device_open_addr(bus_num, addr, product_name);
960 if (dev)
961 usb_device_add_dev(dev);
962 }
963
964 return 0;
965}
966
967static void usb_host_auto_timer(void *unused)
968{
969 usb_host_scan(NULL, usb_host_auto_scan);
970 qemu_mod_timer(usb_auto_timer, qemu_get_clock(rt_clock) + 2000);
971}
972
973/*
974 * Add autoconnect filter
975 * -1 means 'any' (device, vendor, etc)
976 */
977static void usb_host_auto_add(int bus_num, int addr, int vendor_id, int product_id)
978{
979 struct USBAutoFilter *f = qemu_mallocz(sizeof(*f));
980 if (!f) {
981 printf("Failed to allocate auto filter\n");
982 return;
983 }
984
985 f->bus_num = bus_num;
986 f->addr = addr;
987 f->vendor_id = vendor_id;
988 f->product_id = product_id;
989
990 if (!usb_auto_filter) {
991 /*
992 * First entry. Init and start the monitor.
993 * Right now we're using timer to check for new devices.
994 * If this turns out to be too expensive we can move that into a
995 * separate thread.
996 */
997 usb_auto_timer = qemu_new_timer(rt_clock, usb_host_auto_timer, NULL);
998 if (!usb_auto_timer) {
999 printf("Failed to allocate timer\n");
1000 qemu_free(f);
1001 return;
1002 }
1003
1004 /* Check for new devices every two seconds */
1005 qemu_mod_timer(usb_auto_timer, qemu_get_clock(rt_clock) + 2000);
1006 }
1007
1008 printf("Auto filter: bus_num %d addr %d vid %d pid %d\n",
1009 bus_num, addr, vendor_id, product_id);
1010
1011 f->next = usb_auto_filter;
1012 usb_auto_filter = f;
1013}
1014
a594cfbf
FB
1015typedef struct FindDeviceState {
1016 int vendor_id;
1017 int product_id;
1018 int bus_num;
1019 int addr;
1f6e24e7 1020 char product_name[PRODUCT_NAME_SZ];
a594cfbf
FB
1021} FindDeviceState;
1022
5fafdf24 1023static int usb_host_find_device_scan(void *opaque, int bus_num, int addr,
a594cfbf 1024 int class_id,
5fafdf24 1025 int vendor_id, int product_id,
a594cfbf 1026 const char *product_name, int speed)
bb36d470 1027{
a594cfbf 1028 FindDeviceState *s = opaque;
1f6e24e7
FB
1029 if ((vendor_id == s->vendor_id &&
1030 product_id == s->product_id) ||
1031 (bus_num == s->bus_num &&
1032 addr == s->addr)) {
1033 pstrcpy(s->product_name, PRODUCT_NAME_SZ, product_name);
a594cfbf
FB
1034 s->bus_num = bus_num;
1035 s->addr = addr;
1036 return 1;
1037 } else {
1038 return 0;
1039 }
1040}
bb36d470 1041
5fafdf24
TS
1042/* the syntax is :
1043 'bus.addr' (decimal numbers) or
a594cfbf 1044 'vendor_id:product_id' (hexa numbers) */
5fafdf24 1045static int usb_host_find_device(int *pbus_num, int *paddr,
1f6e24e7 1046 char *product_name, int product_name_size,
a594cfbf
FB
1047 const char *devname)
1048{
1049 const char *p;
1050 int ret;
1051 FindDeviceState fs;
1052
1053 p = strchr(devname, '.');
1054 if (p) {
1055 *pbus_num = strtoul(devname, NULL, 0);
4b096fc9
AL
1056
1057 if (*(p + 1) == '*') {
1058 usb_host_auto_add(*pbus_num, -1, -1, -1);
1059 return -1;
1060 }
1061
a594cfbf 1062 *paddr = strtoul(p + 1, NULL, 0);
1f6e24e7
FB
1063 fs.bus_num = *pbus_num;
1064 fs.addr = *paddr;
1065 ret = usb_host_scan(&fs, usb_host_find_device_scan);
1066 if (ret)
1067 pstrcpy(product_name, product_name_size, fs.product_name);
a594cfbf
FB
1068 return 0;
1069 }
1070 p = strchr(devname, ':');
1071 if (p) {
1072 fs.vendor_id = strtoul(devname, NULL, 16);
4b096fc9
AL
1073
1074 if (*(p + 1) == '*') {
1075 usb_host_auto_add(-1, -1, fs.vendor_id, -1);
1076 return -1;
1077 }
1078
a594cfbf
FB
1079 fs.product_id = strtoul(p + 1, NULL, 16);
1080 ret = usb_host_scan(&fs, usb_host_find_device_scan);
1081 if (ret) {
1082 *pbus_num = fs.bus_num;
1083 *paddr = fs.addr;
1f6e24e7 1084 pstrcpy(product_name, product_name_size, fs.product_name);
a594cfbf 1085 return 0;
bb36d470
FB
1086 }
1087 }
a594cfbf 1088 return -1;
bb36d470
FB
1089}
1090
a594cfbf
FB
1091/**********************/
1092/* USB host device info */
1093
1094struct usb_class_info {
1095 int class;
1096 const char *class_name;
1097};
1098
1099static const struct usb_class_info usb_class_info[] = {
1100 { USB_CLASS_AUDIO, "Audio"},
1101 { USB_CLASS_COMM, "Communication"},
1102 { USB_CLASS_HID, "HID"},
1103 { USB_CLASS_HUB, "Hub" },
1104 { USB_CLASS_PHYSICAL, "Physical" },
1105 { USB_CLASS_PRINTER, "Printer" },
1106 { USB_CLASS_MASS_STORAGE, "Storage" },
1107 { USB_CLASS_CDC_DATA, "Data" },
1108 { USB_CLASS_APP_SPEC, "Application Specific" },
1109 { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
1110 { USB_CLASS_STILL_IMAGE, "Still Image" },
b9dc033c 1111 { USB_CLASS_CSCID, "Smart Card" },
a594cfbf
FB
1112 { USB_CLASS_CONTENT_SEC, "Content Security" },
1113 { -1, NULL }
1114};
1115
1116static const char *usb_class_str(uint8_t class)
bb36d470 1117{
a594cfbf
FB
1118 const struct usb_class_info *p;
1119 for(p = usb_class_info; p->class != -1; p++) {
1120 if (p->class == class)
1121 break;
bb36d470 1122 }
a594cfbf
FB
1123 return p->class_name;
1124}
1125
9596ebb7
PB
1126static void usb_info_device(int bus_num, int addr, int class_id,
1127 int vendor_id, int product_id,
1128 const char *product_name,
1129 int speed)
a594cfbf
FB
1130{
1131 const char *class_str, *speed_str;
1132
1133 switch(speed) {
5fafdf24
TS
1134 case USB_SPEED_LOW:
1135 speed_str = "1.5";
a594cfbf 1136 break;
5fafdf24
TS
1137 case USB_SPEED_FULL:
1138 speed_str = "12";
a594cfbf 1139 break;
5fafdf24
TS
1140 case USB_SPEED_HIGH:
1141 speed_str = "480";
a594cfbf
FB
1142 break;
1143 default:
5fafdf24 1144 speed_str = "?";
a594cfbf
FB
1145 break;
1146 }
1147
5fafdf24 1148 term_printf(" Device %d.%d, speed %s Mb/s\n",
a594cfbf
FB
1149 bus_num, addr, speed_str);
1150 class_str = usb_class_str(class_id);
5fafdf24 1151 if (class_str)
a594cfbf
FB
1152 term_printf(" %s:", class_str);
1153 else
1154 term_printf(" Class %02x:", class_id);
1155 term_printf(" USB device %04x:%04x", vendor_id, product_id);
1156 if (product_name[0] != '\0')
1157 term_printf(", %s", product_name);
1158 term_printf("\n");
1159}
1160
5fafdf24 1161static int usb_host_info_device(void *opaque, int bus_num, int addr,
a594cfbf 1162 int class_id,
5fafdf24 1163 int vendor_id, int product_id,
a594cfbf
FB
1164 const char *product_name,
1165 int speed)
1166{
1167 usb_info_device(bus_num, addr, class_id, vendor_id, product_id,
1168 product_name, speed);
1169 return 0;
1170}
1171
1172void usb_host_info(void)
1173{
1174 usb_host_scan(NULL, usb_host_info_device);
bb36d470
FB
1175}
1176
4b096fc9
AL
1177
1178
1179
bb36d470
FB
1180#else
1181
a594cfbf
FB
1182void usb_host_info(void)
1183{
1184 term_printf("USB host devices not supported\n");
1185}
1186
bb36d470 1187/* XXX: modify configure to compile the right host driver */
a594cfbf 1188USBDevice *usb_host_device_open(const char *devname)
bb36d470
FB
1189{
1190 return NULL;
1191}
1192
1193#endif
This page took 0.332135 seconds and 4 git commands to generate.