]> git.proxmox.com Git - qemu.git/blame - usb-linux.c
monitor: fix build breakage for !CONFIG_VNC
[qemu.git] / usb-linux.c
CommitLineData
bb36d470
FB
1/*
2 * Linux host USB redirector
3 *
4 * Copyright (c) 2005 Fabrice Bellard
5fafdf24 5 *
64838171
AL
6 * Copyright (c) 2008 Max Krasnyansky
7 * Support for host device auto connect & disconnect
5d0c5750 8 * Major rewrite to support fully async operation
4b096fc9 9 *
0f431527
AL
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
13 *
bb36d470
FB
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:
20 *
21 * The above copyright notice and this permission notice shall be included in
22 * all copies or substantial portions of the Software.
23 *
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
30 * THE SOFTWARE.
31 */
446ab128 32
87ecb68b 33#include "qemu-common.h"
1f3870ab 34#include "qemu-timer.h"
376253ec 35#include "monitor.h"
b373a63a 36#include "sysemu.h"
bb36d470 37
bb36d470
FB
38#include <dirent.h>
39#include <sys/ioctl.h>
bb36d470 40
446ab128
AL
41#include <linux/usbdevice_fs.h>
42#include <linux/version.h>
43#include "hw/usb.h"
bb36d470 44
d9cf1578
BS
45/* We redefine it to avoid version problems */
46struct usb_ctrltransfer {
47 uint8_t bRequestType;
48 uint8_t bRequest;
49 uint16_t wValue;
50 uint16_t wIndex;
51 uint16_t wLength;
52 uint32_t timeout;
53 void *data;
54};
55
5557d820 56typedef int USBScanFunc(void *opaque, int bus_num, int addr, char *port,
0f5160d1 57 int class_id, int vendor_id, int product_id,
a594cfbf 58 const char *product_name, int speed);
26a9e82a 59
0745eb1e 60//#define DEBUG
64838171
AL
61
62#ifdef DEBUG
d0f2c4c6 63#define DPRINTF printf
64838171 64#else
d0f2c4c6 65#define DPRINTF(...)
64838171 66#endif
bb36d470 67
5be8e1f2
BS
68#define USBDBG_DEVOPENED "husb: opened %s/devices\n"
69
0f431527 70#define USBPROCBUS_PATH "/proc/bus/usb"
1f6e24e7 71#define PRODUCT_NAME_SZ 32
3a4854b3 72#define MAX_ENDPOINTS 15
5557d820 73#define MAX_PORTLEN 16
0f431527
AL
74#define USBDEVBUS_PATH "/dev/bus/usb"
75#define USBSYSBUS_PATH "/sys/bus/usb"
76
77static char *usb_host_device_path;
78
79#define USB_FS_NONE 0
80#define USB_FS_PROC 1
81#define USB_FS_DEV 2
82#define USB_FS_SYS 3
83
84static int usb_fs_type;
bb36d470 85
b9dc033c 86/* endpoint association data */
060dc841 87#define ISO_FRAME_DESC_PER_URB 32
a0b5fece 88#define INVALID_EP_TYPE 255
060dc841 89
71138531
GH
90/* devio.c limits single requests to 16k */
91#define MAX_USBFS_BUFFER_SIZE 16384
92
060dc841
HG
93typedef struct AsyncURB AsyncURB;
94
b9dc033c
AZ
95struct endp_data {
96 uint8_t type;
64838171 97 uint8_t halted;
bb6d5498 98 uint8_t iso_started;
060dc841
HG
99 AsyncURB *iso_urb;
100 int iso_urb_idx;
bb6d5498 101 int iso_buffer_used;
060dc841 102 int max_packet_size;
82887262 103 int inflight;
b9dc033c
AZ
104};
105
26a9e82a
GH
106struct USBAutoFilter {
107 uint32_t bus_num;
108 uint32_t addr;
9056a297 109 char *port;
26a9e82a
GH
110 uint32_t vendor_id;
111 uint32_t product_id;
112};
113
bb36d470
FB
114typedef struct USBHostDevice {
115 USBDevice dev;
64838171
AL
116 int fd;
117
f8ddbfbc 118 uint8_t descr[8192];
64838171
AL
119 int descr_len;
120 int configuration;
446ab128 121 int ninterfaces;
24772c1e 122 int closing;
b81bcd8a 123 uint32_t iso_urb_count;
b373a63a 124 Notifier exit;
64838171 125
b9dc033c 126 struct endp_data endp_table[MAX_ENDPOINTS];
7a8fc83f 127 QLIST_HEAD(, AsyncURB) aurbs;
4b096fc9 128
4b096fc9
AL
129 /* Host side address */
130 int bus_num;
131 int addr;
5557d820 132 char port[MAX_PORTLEN];
26a9e82a 133 struct USBAutoFilter match;
4b096fc9 134
26a9e82a 135 QTAILQ_ENTRY(USBHostDevice) next;
bb36d470
FB
136} USBHostDevice;
137
26a9e82a
GH
138static QTAILQ_HEAD(, USBHostDevice) hostdevs = QTAILQ_HEAD_INITIALIZER(hostdevs);
139
140static int usb_host_close(USBHostDevice *dev);
141static int parse_filter(const char *spec, struct USBAutoFilter *f);
142static void usb_host_auto_check(void *unused);
2cc59d8c
HG
143static int usb_host_read_file(char *line, size_t line_size,
144 const char *device_file, const char *device_name);
26a9e82a 145
ca3a36cf
GH
146static struct endp_data *get_endp(USBHostDevice *s, int ep)
147{
148 return s->endp_table + ep - 1;
149}
150
64838171
AL
151static int is_isoc(USBHostDevice *s, int ep)
152{
ca3a36cf 153 return get_endp(s, ep)->type == USBDEVFS_URB_TYPE_ISO;
64838171
AL
154}
155
a0b5fece
HG
156static int is_valid(USBHostDevice *s, int ep)
157{
ca3a36cf 158 return get_endp(s, ep)->type != INVALID_EP_TYPE;
a0b5fece
HG
159}
160
64838171
AL
161static int is_halted(USBHostDevice *s, int ep)
162{
ca3a36cf 163 return get_endp(s, ep)->halted;
64838171
AL
164}
165
166static void clear_halt(USBHostDevice *s, int ep)
167{
ca3a36cf 168 get_endp(s, ep)->halted = 0;
64838171
AL
169}
170
171static void set_halt(USBHostDevice *s, int ep)
172{
ca3a36cf 173 get_endp(s, ep)->halted = 1;
64838171
AL
174}
175
bb6d5498
HG
176static int is_iso_started(USBHostDevice *s, int ep)
177{
ca3a36cf 178 return get_endp(s, ep)->iso_started;
bb6d5498
HG
179}
180
181static void clear_iso_started(USBHostDevice *s, int ep)
182{
ca3a36cf 183 get_endp(s, ep)->iso_started = 0;
bb6d5498
HG
184}
185
186static void set_iso_started(USBHostDevice *s, int ep)
187{
82887262
GH
188 struct endp_data *e = get_endp(s, ep);
189 if (!e->iso_started) {
190 e->iso_started = 1;
191 e->inflight = 0;
192 }
193}
194
195static int change_iso_inflight(USBHostDevice *s, int ep, int value)
196{
197 struct endp_data *e = get_endp(s, ep);
198
199 e->inflight += value;
200 return e->inflight;
bb6d5498
HG
201}
202
060dc841
HG
203static void set_iso_urb(USBHostDevice *s, int ep, AsyncURB *iso_urb)
204{
ca3a36cf 205 get_endp(s, ep)->iso_urb = iso_urb;
060dc841
HG
206}
207
208static AsyncURB *get_iso_urb(USBHostDevice *s, int ep)
209{
ca3a36cf 210 return get_endp(s, ep)->iso_urb;
060dc841
HG
211}
212
213static void set_iso_urb_idx(USBHostDevice *s, int ep, int i)
214{
ca3a36cf 215 get_endp(s, ep)->iso_urb_idx = i;
060dc841
HG
216}
217
218static int get_iso_urb_idx(USBHostDevice *s, int ep)
219{
ca3a36cf 220 return get_endp(s, ep)->iso_urb_idx;
060dc841
HG
221}
222
bb6d5498
HG
223static void set_iso_buffer_used(USBHostDevice *s, int ep, int i)
224{
ca3a36cf 225 get_endp(s, ep)->iso_buffer_used = i;
bb6d5498
HG
226}
227
228static int get_iso_buffer_used(USBHostDevice *s, int ep)
229{
ca3a36cf 230 return get_endp(s, ep)->iso_buffer_used;
bb6d5498
HG
231}
232
6dfcdccb
GH
233static void set_max_packet_size(USBHostDevice *s, int ep, uint8_t *descriptor)
234{
235 int raw = descriptor[4] + (descriptor[5] << 8);
236 int size, microframes;
237
238 size = raw & 0x7ff;
239 switch ((raw >> 11) & 3) {
240 case 1: microframes = 2; break;
241 case 2: microframes = 3; break;
242 default: microframes = 1; break;
243 }
ca3a36cf 244 get_endp(s, ep)->max_packet_size = size * microframes;
6dfcdccb
GH
245}
246
060dc841
HG
247static int get_max_packet_size(USBHostDevice *s, int ep)
248{
ca3a36cf 249 return get_endp(s, ep)->max_packet_size;
060dc841
HG
250}
251
2791104c 252/*
64838171 253 * Async URB state.
060dc841 254 * We always allocate iso packet descriptors even for bulk transfers
2791104c 255 * to simplify allocation and casts.
64838171 256 */
060dc841 257struct AsyncURB
64838171
AL
258{
259 struct usbdevfs_urb urb;
060dc841 260 struct usbdevfs_iso_packet_desc isocpd[ISO_FRAME_DESC_PER_URB];
7a8fc83f
GH
261 USBHostDevice *hdev;
262 QLIST_ENTRY(AsyncURB) next;
b9dc033c 263
060dc841 264 /* For regular async urbs */
64838171 265 USBPacket *packet;
71138531 266 int more; /* large transfer, more urbs follow */
060dc841
HG
267
268 /* For buffered iso handling */
269 int iso_frame_idx; /* -1 means in flight */
270};
b9dc033c 271
7a8fc83f 272static AsyncURB *async_alloc(USBHostDevice *s)
b9dc033c 273{
7a8fc83f
GH
274 AsyncURB *aurb = qemu_mallocz(sizeof(AsyncURB));
275 aurb->hdev = s;
276 QLIST_INSERT_HEAD(&s->aurbs, aurb, next);
277 return aurb;
b9dc033c
AZ
278}
279
64838171 280static void async_free(AsyncURB *aurb)
b9dc033c 281{
7a8fc83f 282 QLIST_REMOVE(aurb, next);
64838171
AL
283 qemu_free(aurb);
284}
b9dc033c 285
41c01ee7
GH
286static void do_disconnect(USBHostDevice *s)
287{
288 printf("husb: device %d.%d disconnected\n",
289 s->bus_num, s->addr);
290 usb_host_close(s);
291 usb_host_auto_check(NULL);
292}
293
64838171
AL
294static void async_complete(void *opaque)
295{
296 USBHostDevice *s = opaque;
297 AsyncURB *aurb;
82887262 298 int urbs = 0;
64838171
AL
299
300 while (1) {
2791104c 301 USBPacket *p;
b9dc033c 302
2791104c 303 int r = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &aurb);
64838171 304 if (r < 0) {
2791104c 305 if (errno == EAGAIN) {
82887262
GH
306 if (urbs > 2) {
307 fprintf(stderr, "husb: %d iso urbs finished at once\n", urbs);
308 }
64838171 309 return;
2791104c 310 }
24772c1e 311 if (errno == ENODEV && !s->closing) {
41c01ee7 312 do_disconnect(s);
64838171
AL
313 return;
314 }
315
d0f2c4c6 316 DPRINTF("husb: async. reap urb failed errno %d\n", errno);
64838171 317 return;
b9dc033c 318 }
64838171 319
2791104c 320 DPRINTF("husb: async completed. aurb %p status %d alen %d\n",
64838171
AL
321 aurb, aurb->urb.status, aurb->urb.actual_length);
322
060dc841
HG
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) {
82887262 326 int inflight;
060dc841
HG
327 if (aurb->urb.status == -EPIPE) {
328 set_halt(s, aurb->urb.endpoint & 0xf);
329 }
330 aurb->iso_frame_idx = 0;
82887262
GH
331 urbs++;
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");
335 }
060dc841
HG
336 continue;
337 }
338
339 p = aurb->packet;
340
2791104c 341 if (p) {
64838171
AL
342 switch (aurb->urb.status) {
343 case 0:
71138531 344 p->len += aurb->urb.actual_length;
64838171
AL
345 break;
346
347 case -EPIPE:
348 set_halt(s, p->devep);
2791104c
DA
349 p->len = USB_RET_STALL;
350 break;
dcc7e25f 351
64838171
AL
352 default:
353 p->len = USB_RET_NAK;
354 break;
355 }
356
50b7963e
HG
357 if (aurb->urb.type == USBDEVFS_URB_TYPE_CONTROL) {
358 usb_generic_async_ctrl_complete(&s->dev, p);
71138531 359 } else if (!aurb->more) {
50b7963e
HG
360 usb_packet_complete(&s->dev, p);
361 }
2791104c 362 }
64838171
AL
363
364 async_free(aurb);
b9dc033c 365 }
b9dc033c
AZ
366}
367
eb5e680a 368static void usb_host_async_cancel(USBDevice *dev, USBPacket *p)
b9dc033c 369{
eb5e680a 370 USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
227ebeb5 371 AsyncURB *aurb;
b9dc033c 372
227ebeb5
GH
373 QLIST_FOREACH(aurb, &s->aurbs, next) {
374 if (p != aurb->packet) {
375 continue;
376 }
64838171 377
227ebeb5 378 DPRINTF("husb: async cancel: packet %p, aurb %p\n", p, aurb);
b9dc033c 379
227ebeb5
GH
380 /* Mark it as dead (see async_complete above) */
381 aurb->packet = NULL;
382
383 int r = ioctl(s->fd, USBDEVFS_DISCARDURB, aurb);
384 if (r < 0) {
385 DPRINTF("husb: async. discard urb failed errno %d\n", errno);
386 }
b9dc033c 387 }
b9dc033c
AZ
388}
389
446ab128 390static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
b9dc033c 391{
41c01ee7 392 const char *op = NULL;
b9dc033c 393 int dev_descr_len, config_descr_len;
d4c4e6fd 394 int interface, nb_interfaces;
b9dc033c
AZ
395 int ret, i;
396
397 if (configuration == 0) /* address state - ignore */
398 return 1;
399
d0f2c4c6 400 DPRINTF("husb: claiming interfaces. config %d\n", configuration);
446ab128 401
b9dc033c
AZ
402 i = 0;
403 dev_descr_len = dev->descr[0];
2791104c 404 if (dev_descr_len > dev->descr_len) {
61c1117f
HG
405 fprintf(stderr, "husb: update iface failed. descr too short\n");
406 return 0;
2791104c 407 }
b9dc033c
AZ
408
409 i += dev_descr_len;
410 while (i < dev->descr_len) {
2791104c
DA
411 DPRINTF("husb: i is %d, descr_len is %d, dl %d, dt %d\n",
412 i, dev->descr_len,
b9dc033c 413 dev->descr[i], dev->descr[i+1]);
64838171 414
b9dc033c
AZ
415 if (dev->descr[i+1] != USB_DT_CONFIG) {
416 i += dev->descr[i];
417 continue;
418 }
419 config_descr_len = dev->descr[i];
420
2791104c 421 printf("husb: config #%d need %d\n", dev->descr[i + 5], configuration);
1f3870ab 422
446ab128
AL
423 if (configuration < 0 || configuration == dev->descr[i + 5]) {
424 configuration = dev->descr[i + 5];
b9dc033c 425 break;
446ab128 426 }
b9dc033c
AZ
427
428 i += config_descr_len;
429 }
430
431 if (i >= dev->descr_len) {
2791104c
DA
432 fprintf(stderr,
433 "husb: update iface failed. no matching configuration\n");
61c1117f 434 return 0;
b9dc033c
AZ
435 }
436 nb_interfaces = dev->descr[i + 4];
437
438#ifdef USBDEVFS_DISCONNECT
439 /* earlier Linux 2.4 do not support that */
440 {
441 struct usbdevfs_ioctl ctrl;
442 for (interface = 0; interface < nb_interfaces; interface++) {
443 ctrl.ioctl_code = USBDEVFS_DISCONNECT;
444 ctrl.ifno = interface;
021730f7 445 ctrl.data = 0;
41c01ee7 446 op = "USBDEVFS_DISCONNECT";
b9dc033c
AZ
447 ret = ioctl(dev->fd, USBDEVFS_IOCTL, &ctrl);
448 if (ret < 0 && errno != ENODATA) {
b9dc033c
AZ
449 goto fail;
450 }
451 }
452 }
453#endif
454
455 /* XXX: only grab if all interfaces are free */
456 for (interface = 0; interface < nb_interfaces; interface++) {
41c01ee7 457 op = "USBDEVFS_CLAIMINTERFACE";
b9dc033c
AZ
458 ret = ioctl(dev->fd, USBDEVFS_CLAIMINTERFACE, &interface);
459 if (ret < 0) {
460 if (errno == EBUSY) {
64838171 461 printf("husb: update iface. device already grabbed\n");
b9dc033c 462 } else {
64838171 463 perror("husb: failed to claim interface");
b9dc033c 464 }
41c01ee7 465 goto fail;
b9dc033c
AZ
466 }
467 }
468
64838171 469 printf("husb: %d interfaces claimed for configuration %d\n",
b9dc033c 470 nb_interfaces, configuration);
b9dc033c 471
446ab128
AL
472 dev->ninterfaces = nb_interfaces;
473 dev->configuration = configuration;
474 return 1;
41c01ee7
GH
475
476fail:
477 if (errno == ENODEV) {
478 do_disconnect(dev);
479 }
480 perror(op);
481 return 0;
446ab128
AL
482}
483
484static int usb_host_release_interfaces(USBHostDevice *s)
485{
486 int ret, i;
487
d0f2c4c6 488 DPRINTF("husb: releasing interfaces\n");
446ab128
AL
489
490 for (i = 0; i < s->ninterfaces; i++) {
491 ret = ioctl(s->fd, USBDEVFS_RELEASEINTERFACE, &i);
492 if (ret < 0) {
493 perror("husb: failed to release interface");
494 return 0;
495 }
496 }
497
b9dc033c
AZ
498 return 1;
499}
500
059809e4 501static void usb_host_handle_reset(USBDevice *dev)
bb36d470 502{
26a9e82a 503 USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
64838171 504
d0f2c4c6 505 DPRINTF("husb: reset device %u.%u\n", s->bus_num, s->addr);
64838171 506
bb36d470 507 ioctl(s->fd, USBDEVFS_RESET);
446ab128
AL
508
509 usb_host_claim_interfaces(s, s->configuration);
5fafdf24 510}
bb36d470 511
059809e4
FB
512static void usb_host_handle_destroy(USBDevice *dev)
513{
514 USBHostDevice *s = (USBHostDevice *)dev;
515
26a9e82a
GH
516 usb_host_close(s);
517 QTAILQ_REMOVE(&hostdevs, s, next);
b373a63a 518 qemu_remove_exit_notifier(&s->exit);
059809e4
FB
519}
520
b9dc033c
AZ
521static int usb_linux_update_endp_table(USBHostDevice *s);
522
060dc841
HG
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. */
526static AsyncURB *usb_host_alloc_iso(USBHostDevice *s, uint8_t ep, int in)
527{
528 AsyncURB *aurb;
529 int i, j, len = get_max_packet_size(s, ep);
530
b81bcd8a
GH
531 aurb = qemu_mallocz(s->iso_urb_count * sizeof(*aurb));
532 for (i = 0; i < s->iso_urb_count; i++) {
060dc841
HG
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;
541 if (in) {
542 aurb[i].urb.endpoint |= 0x80;
543 /* Mark as fully consumed (idle) */
544 aurb[i].iso_frame_idx = ISO_FRAME_DESC_PER_URB;
545 }
546 }
547 set_iso_urb(s, ep, aurb);
548
549 return aurb;
550}
551
552static void usb_host_stop_n_free_iso(USBHostDevice *s, uint8_t ep)
553{
554 AsyncURB *aurb;
555 int i, ret, killed = 0, free = 1;
556
557 aurb = get_iso_urb(s, ep);
558 if (!aurb) {
559 return;
560 }
561
b81bcd8a 562 for (i = 0; i < s->iso_urb_count; i++) {
060dc841
HG
563 /* in flight? */
564 if (aurb[i].iso_frame_idx == -1) {
565 ret = ioctl(s->fd, USBDEVFS_DISCARDURB, &aurb[i]);
566 if (ret < 0) {
567 printf("husb: discard isoc in urb failed errno %d\n", errno);
568 free = 0;
569 continue;
570 }
571 killed++;
572 }
573 }
574
575 /* Make sure any urbs we've killed are reaped before we free them */
576 if (killed) {
577 async_complete(s);
578 }
579
b81bcd8a 580 for (i = 0; i < s->iso_urb_count; i++) {
060dc841
HG
581 qemu_free(aurb[i].urb.buffer);
582 }
583
584 if (free)
585 qemu_free(aurb);
586 else
587 printf("husb: leaking iso urbs because of discard failure\n");
588 set_iso_urb(s, ep, NULL);
bb6d5498
HG
589 set_iso_urb_idx(s, ep, 0);
590 clear_iso_started(s, ep);
060dc841
HG
591}
592
593static int urb_status_to_usb_ret(int status)
594{
595 switch (status) {
596 case -EPIPE:
597 return USB_RET_STALL;
598 default:
599 return USB_RET_NAK;
600 }
601}
602
bb6d5498 603static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in)
060dc841
HG
604{
605 AsyncURB *aurb;
bb6d5498 606 int i, j, ret, max_packet_size, offset, len = 0;
975f2998
HG
607
608 max_packet_size = get_max_packet_size(s, p->devep);
609 if (max_packet_size == 0)
610 return USB_RET_NAK;
060dc841
HG
611
612 aurb = get_iso_urb(s, p->devep);
613 if (!aurb) {
bb6d5498 614 aurb = usb_host_alloc_iso(s, p->devep, in);
060dc841
HG
615 }
616
617 i = get_iso_urb_idx(s, p->devep);
618 j = aurb[i].iso_frame_idx;
619 if (j >= 0 && j < ISO_FRAME_DESC_PER_URB) {
bb6d5498
HG
620 if (in) {
621 /* Check urb status */
622 if (aurb[i].urb.status) {
623 len = urb_status_to_usb_ret(aurb[i].urb.status);
624 /* Move to the next urb */
625 aurb[i].iso_frame_idx = ISO_FRAME_DESC_PER_URB - 1;
626 /* Check frame status */
627 } else if (aurb[i].urb.iso_frame_desc[j].status) {
628 len = urb_status_to_usb_ret(
629 aurb[i].urb.iso_frame_desc[j].status);
630 /* Check the frame fits */
631 } else if (aurb[i].urb.iso_frame_desc[j].actual_length > p->len) {
632 printf("husb: received iso data is larger then packet\n");
633 len = USB_RET_NAK;
634 /* All good copy data over */
635 } else {
636 len = aurb[i].urb.iso_frame_desc[j].actual_length;
637 memcpy(p->data,
638 aurb[i].urb.buffer +
639 j * aurb[i].urb.iso_frame_desc[0].length,
640 len);
641 }
060dc841 642 } else {
bb6d5498
HG
643 len = p->len;
644 offset = (j == 0) ? 0 : get_iso_buffer_used(s, p->devep);
645
646 /* Check the frame fits */
647 if (len > max_packet_size) {
648 printf("husb: send iso data is larger then max packet size\n");
649 return USB_RET_NAK;
650 }
651
652 /* All good copy data over */
653 memcpy(aurb[i].urb.buffer + offset, p->data, len);
654 aurb[i].urb.iso_frame_desc[j].length = len;
655 offset += len;
656 set_iso_buffer_used(s, p->devep, offset);
657
658 /* Start the stream once we have buffered enough data */
659 if (!is_iso_started(s, p->devep) && i == 1 && j == 8) {
660 set_iso_started(s, p->devep);
661 }
060dc841
HG
662 }
663 aurb[i].iso_frame_idx++;
664 if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {
b81bcd8a 665 i = (i + 1) % s->iso_urb_count;
060dc841
HG
666 set_iso_urb_idx(s, p->devep, i);
667 }
bb6d5498
HG
668 } else {
669 if (in) {
670 set_iso_started(s, p->devep);
671 } else {
672 DPRINTF("hubs: iso out error no free buffer, dropping packet\n");
673 }
060dc841
HG
674 }
675
bb6d5498
HG
676 if (is_iso_started(s, p->devep)) {
677 /* (Re)-submit all fully consumed / filled urbs */
b81bcd8a 678 for (i = 0; i < s->iso_urb_count; i++) {
bb6d5498
HG
679 if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {
680 ret = ioctl(s->fd, USBDEVFS_SUBMITURB, &aurb[i]);
681 if (ret < 0) {
682 printf("husb error submitting iso urb %d: %d\n", i, errno);
683 if (!in || len == 0) {
684 switch(errno) {
685 case ETIMEDOUT:
686 len = USB_RET_NAK;
0225e254 687 break;
bb6d5498
HG
688 case EPIPE:
689 default:
690 len = USB_RET_STALL;
691 }
060dc841 692 }
bb6d5498 693 break;
060dc841 694 }
bb6d5498 695 aurb[i].iso_frame_idx = -1;
82887262 696 change_iso_inflight(s, p->devep, +1);
060dc841 697 }
060dc841
HG
698 }
699 }
700
701 return len;
702}
703
50b7963e 704static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
bb36d470 705{
50b7963e 706 USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
64838171 707 struct usbdevfs_urb *urb;
446ab128 708 AsyncURB *aurb;
71138531
GH
709 int ret, rem;
710 uint8_t *pbuf;
060dc841 711 uint8_t ep;
b9dc033c 712
a0b5fece
HG
713 if (!is_valid(s, p->devep)) {
714 return USB_RET_NAK;
715 }
716
2791104c 717 if (p->pid == USB_TOKEN_IN) {
060dc841 718 ep = p->devep | 0x80;
2791104c 719 } else {
060dc841 720 ep = p->devep;
2791104c 721 }
64838171
AL
722
723 if (is_halted(s, p->devep)) {
060dc841 724 ret = ioctl(s->fd, USBDEVFS_CLEAR_HALT, &ep);
64838171 725 if (ret < 0) {
2791104c 726 DPRINTF("husb: failed to clear halt. ep 0x%x errno %d\n",
060dc841 727 ep, errno);
bb36d470 728 return USB_RET_NAK;
bb36d470 729 }
64838171 730 clear_halt(s, p->devep);
4d043a09
AZ
731 }
732
bb6d5498
HG
733 if (is_isoc(s, p->devep)) {
734 return usb_host_handle_iso_data(s, p, p->pid == USB_TOKEN_IN);
735 }
060dc841 736
71138531
GH
737 rem = p->len;
738 pbuf = p->data;
739 p->len = 0;
740 while (rem) {
741 aurb = async_alloc(s);
742 aurb->packet = p;
743
744 urb = &aurb->urb;
745 urb->endpoint = ep;
746 urb->type = USBDEVFS_URB_TYPE_BULK;
747 urb->usercontext = s;
748 urb->buffer = pbuf;
749
750 if (rem > MAX_USBFS_BUFFER_SIZE) {
751 urb->buffer_length = MAX_USBFS_BUFFER_SIZE;
752 aurb->more = 1;
753 } else {
754 urb->buffer_length = rem;
755 aurb->more = 0;
756 }
757 pbuf += urb->buffer_length;
758 rem -= urb->buffer_length;
b9dc033c 759
71138531 760 ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
b9dc033c 761
71138531
GH
762 DPRINTF("husb: data submit: ep 0x%x, len %u, more %d, packet %p, aurb %p\n",
763 urb->endpoint, urb->buffer_length, aurb->more, p, aurb);
b9dc033c 764
71138531
GH
765 if (ret < 0) {
766 DPRINTF("husb: submit failed. errno %d\n", errno);
767 async_free(aurb);
b9dc033c 768
71138531
GH
769 switch(errno) {
770 case ETIMEDOUT:
771 return USB_RET_NAK;
772 case EPIPE:
773 default:
774 return USB_RET_STALL;
775 }
b9dc033c
AZ
776 }
777 }
64838171 778
b9dc033c 779 return USB_RET_ASYNC;
b9dc033c
AZ
780}
781
446ab128
AL
782static int ctrl_error(void)
783{
2791104c 784 if (errno == ETIMEDOUT) {
446ab128 785 return USB_RET_NAK;
2791104c 786 } else {
446ab128 787 return USB_RET_STALL;
2791104c 788 }
446ab128
AL
789}
790
791static int usb_host_set_address(USBHostDevice *s, int addr)
792{
d0f2c4c6 793 DPRINTF("husb: ctrl set addr %u\n", addr);
446ab128
AL
794 s->dev.addr = addr;
795 return 0;
796}
797
798static int usb_host_set_config(USBHostDevice *s, int config)
799{
800 usb_host_release_interfaces(s);
801
802 int ret = ioctl(s->fd, USBDEVFS_SETCONFIGURATION, &config);
2791104c 803
d0f2c4c6 804 DPRINTF("husb: ctrl set config %d ret %d errno %d\n", config, ret, errno);
2791104c
DA
805
806 if (ret < 0) {
446ab128 807 return ctrl_error();
2791104c 808 }
446ab128
AL
809 usb_host_claim_interfaces(s, config);
810 return 0;
811}
812
813static int usb_host_set_interface(USBHostDevice *s, int iface, int alt)
814{
815 struct usbdevfs_setinterface si;
060dc841
HG
816 int i, ret;
817
3a4854b3 818 for (i = 1; i <= MAX_ENDPOINTS; i++) {
060dc841
HG
819 if (is_isoc(s, i)) {
820 usb_host_stop_n_free_iso(s, i);
821 }
822 }
446ab128
AL
823
824 si.interface = iface;
825 si.altsetting = alt;
826 ret = ioctl(s->fd, USBDEVFS_SETINTERFACE, &si);
446ab128 827
2791104c
DA
828 DPRINTF("husb: ctrl set iface %d altset %d ret %d errno %d\n",
829 iface, alt, ret, errno);
830
831 if (ret < 0) {
832 return ctrl_error();
833 }
446ab128
AL
834 usb_linux_update_endp_table(s);
835 return 0;
836}
837
50b7963e
HG
838static int usb_host_handle_control(USBDevice *dev, USBPacket *p,
839 int request, int value, int index, int length, uint8_t *data)
446ab128 840{
50b7963e 841 USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
446ab128
AL
842 struct usbdevfs_urb *urb;
843 AsyncURB *aurb;
50b7963e 844 int ret;
446ab128 845
2791104c 846 /*
446ab128
AL
847 * Process certain standard device requests.
848 * These are infrequent and are processed synchronously.
849 */
446ab128 850
50b7963e 851 /* Note request is (bRequestType << 8) | bRequest */
d0f2c4c6 852 DPRINTF("husb: ctrl type 0x%x req 0x%x val 0x%x index %u len %u\n",
50b7963e 853 request >> 8, request & 0xff, value, index, length);
446ab128 854
50b7963e
HG
855 switch (request) {
856 case DeviceOutRequest | USB_REQ_SET_ADDRESS:
857 return usb_host_set_address(s, value);
446ab128 858
50b7963e
HG
859 case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
860 return usb_host_set_config(s, value & 0xff);
446ab128 861
50b7963e 862 case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
446ab128 863 return usb_host_set_interface(s, index, value);
2791104c 864 }
446ab128
AL
865
866 /* The rest are asynchronous */
867
50b7963e
HG
868 if (length > sizeof(dev->data_buf)) {
869 fprintf(stderr, "husb: ctrl buffer too small (%d > %zu)\n",
870 length, sizeof(dev->data_buf));
b2e3b6e9 871 return USB_RET_STALL;
c4c0e236
JP
872 }
873
7a8fc83f 874 aurb = async_alloc(s);
446ab128
AL
875 aurb->packet = p;
876
2791104c 877 /*
446ab128
AL
878 * Setup ctrl transfer.
879 *
a0102082 880 * s->ctrl is laid out such that data buffer immediately follows
446ab128 881 * 'req' struct which is exactly what usbdevfs expects.
2791104c 882 */
446ab128
AL
883 urb = &aurb->urb;
884
885 urb->type = USBDEVFS_URB_TYPE_CONTROL;
886 urb->endpoint = p->devep;
887
50b7963e
HG
888 urb->buffer = &dev->setup_buf;
889 urb->buffer_length = length + 8;
446ab128
AL
890
891 urb->usercontext = s;
892
893 ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
894
d0f2c4c6 895 DPRINTF("husb: submit ctrl. len %u aurb %p\n", urb->buffer_length, aurb);
446ab128
AL
896
897 if (ret < 0) {
d0f2c4c6 898 DPRINTF("husb: submit failed. errno %d\n", errno);
446ab128
AL
899 async_free(aurb);
900
901 switch(errno) {
902 case ETIMEDOUT:
903 return USB_RET_NAK;
904 case EPIPE:
905 default:
906 return USB_RET_STALL;
907 }
908 }
909
446ab128
AL
910 return USB_RET_ASYNC;
911}
912
71d71bbd 913static int usb_linux_get_configuration(USBHostDevice *s)
b9dc033c 914{
71d71bbd 915 uint8_t configuration;
e41b3910 916 struct usb_ctrltransfer ct;
71d71bbd 917 int ret;
b9dc033c 918
2cc59d8c
HG
919 if (usb_fs_type == USB_FS_SYS) {
920 char device_name[32], line[1024];
921 int configuration;
922
5557d820 923 sprintf(device_name, "%d-%s", s->bus_num, s->port);
2cc59d8c
HG
924
925 if (!usb_host_read_file(line, sizeof(line), "bConfigurationValue",
926 device_name)) {
927 goto usbdevfs;
928 }
929 if (sscanf(line, "%d", &configuration) != 1) {
930 goto usbdevfs;
931 }
932 return configuration;
933 }
934
935usbdevfs:
b9dc033c
AZ
936 ct.bRequestType = USB_DIR_IN;
937 ct.bRequest = USB_REQ_GET_CONFIGURATION;
938 ct.wValue = 0;
939 ct.wIndex = 0;
940 ct.wLength = 1;
941 ct.data = &configuration;
942 ct.timeout = 50;
943
944 ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
945 if (ret < 0) {
71d71bbd
HG
946 perror("usb_linux_get_configuration");
947 return -1;
b9dc033c
AZ
948 }
949
950 /* in address state */
2791104c 951 if (configuration == 0) {
71d71bbd 952 return -1;
2791104c 953 }
b9dc033c 954
71d71bbd
HG
955 return configuration;
956}
957
ed3a328d
HG
958static uint8_t usb_linux_get_alt_setting(USBHostDevice *s,
959 uint8_t configuration, uint8_t interface)
960{
961 uint8_t alt_setting;
962 struct usb_ctrltransfer ct;
963 int ret;
964
c43831fb
HG
965 if (usb_fs_type == USB_FS_SYS) {
966 char device_name[64], line[1024];
967 int alt_setting;
968
5557d820 969 sprintf(device_name, "%d-%s:%d.%d", s->bus_num, s->port,
c43831fb
HG
970 (int)configuration, (int)interface);
971
972 if (!usb_host_read_file(line, sizeof(line), "bAlternateSetting",
973 device_name)) {
974 goto usbdevfs;
975 }
976 if (sscanf(line, "%d", &alt_setting) != 1) {
977 goto usbdevfs;
978 }
979 return alt_setting;
980 }
981
982usbdevfs:
ed3a328d
HG
983 ct.bRequestType = USB_DIR_IN | USB_RECIP_INTERFACE;
984 ct.bRequest = USB_REQ_GET_INTERFACE;
985 ct.wValue = 0;
986 ct.wIndex = interface;
987 ct.wLength = 1;
988 ct.data = &alt_setting;
989 ct.timeout = 50;
990 ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
991 if (ret < 0) {
992 /* Assume alt 0 on error */
993 return 0;
994 }
995
996 return alt_setting;
997}
998
71d71bbd
HG
999/* returns 1 on problem encountered or 0 for success */
1000static int usb_linux_update_endp_table(USBHostDevice *s)
1001{
1002 uint8_t *descriptors;
1003 uint8_t devep, type, configuration, alt_interface;
ed3a328d 1004 int interface, length, i;
71d71bbd 1005
a0b5fece
HG
1006 for (i = 0; i < MAX_ENDPOINTS; i++)
1007 s->endp_table[i].type = INVALID_EP_TYPE;
1008
71d71bbd
HG
1009 i = usb_linux_get_configuration(s);
1010 if (i < 0)
1011 return 1;
1012 configuration = i;
1013
b9dc033c
AZ
1014 /* get the desired configuration, interface, and endpoint descriptors
1015 * from device description */
1016 descriptors = &s->descr[18];
1017 length = s->descr_len - 18;
1018 i = 0;
1019
1020 if (descriptors[i + 1] != USB_DT_CONFIG ||
1021 descriptors[i + 5] != configuration) {
d0f2c4c6 1022 DPRINTF("invalid descriptor data - configuration\n");
b9dc033c
AZ
1023 return 1;
1024 }
1025 i += descriptors[i];
1026
1027 while (i < length) {
1028 if (descriptors[i + 1] != USB_DT_INTERFACE ||
1029 (descriptors[i + 1] == USB_DT_INTERFACE &&
1030 descriptors[i + 4] == 0)) {
1031 i += descriptors[i];
1032 continue;
1033 }
1034
1035 interface = descriptors[i + 2];
ed3a328d 1036 alt_interface = usb_linux_get_alt_setting(s, configuration, interface);
b9dc033c
AZ
1037
1038 /* the current interface descriptor is the active interface
1039 * and has endpoints */
1040 if (descriptors[i + 3] != alt_interface) {
1041 i += descriptors[i];
1042 continue;
1043 }
1044
1045 /* advance to the endpoints */
2791104c 1046 while (i < length && descriptors[i +1] != USB_DT_ENDPOINT) {
b9dc033c 1047 i += descriptors[i];
2791104c 1048 }
b9dc033c
AZ
1049
1050 if (i >= length)
1051 break;
1052
1053 while (i < length) {
2791104c 1054 if (descriptors[i + 1] != USB_DT_ENDPOINT) {
b9dc033c 1055 break;
2791104c 1056 }
b9dc033c
AZ
1057
1058 devep = descriptors[i + 2];
130314f8
HG
1059 if ((devep & 0x0f) == 0) {
1060 fprintf(stderr, "usb-linux: invalid ep descriptor, ep == 0\n");
1061 return 1;
1062 }
1063
b9dc033c
AZ
1064 switch (descriptors[i + 3] & 0x3) {
1065 case 0x00:
1066 type = USBDEVFS_URB_TYPE_CONTROL;
1067 break;
1068 case 0x01:
1069 type = USBDEVFS_URB_TYPE_ISO;
6dfcdccb 1070 set_max_packet_size(s, (devep & 0xf), descriptors + i);
b9dc033c
AZ
1071 break;
1072 case 0x02:
1073 type = USBDEVFS_URB_TYPE_BULK;
1074 break;
1075 case 0x03:
1076 type = USBDEVFS_URB_TYPE_INTERRUPT;
1077 break;
ddbda432
AL
1078 default:
1079 DPRINTF("usb_host: malformed endpoint type\n");
1080 type = USBDEVFS_URB_TYPE_BULK;
b9dc033c
AZ
1081 }
1082 s->endp_table[(devep & 0xf) - 1].type = type;
64838171 1083 s->endp_table[(devep & 0xf) - 1].halted = 0;
b9dc033c
AZ
1084
1085 i += descriptors[i];
1086 }
1087 }
1088 return 0;
1089}
1090
e4b17767
HG
1091/*
1092 * Check if we can safely redirect a usb2 device to a usb1 virtual controller,
1093 * this function assumes this is safe, if:
1094 * 1) There are no isoc endpoints
1095 * 2) There are no interrupt endpoints with a max_packet_size > 64
1096 * Note bulk endpoints with a max_packet_size > 64 in theory also are not
1097 * usb1 compatible, but in practice this seems to work fine.
1098 */
1099static int usb_linux_full_speed_compat(USBHostDevice *dev)
1100{
1101 int i, packet_size;
1102
1103 /*
1104 * usb_linux_update_endp_table only registers info about ep in the current
1105 * interface altsettings, so we need to parse the descriptors again.
1106 */
1107 for (i = 0; (i + 5) < dev->descr_len; i += dev->descr[i]) {
1108 if (dev->descr[i + 1] == USB_DT_ENDPOINT) {
1109 switch (dev->descr[i + 3] & 0x3) {
1110 case 0x00: /* CONTROL */
1111 break;
1112 case 0x01: /* ISO */
1113 return 0;
1114 case 0x02: /* BULK */
1115 break;
1116 case 0x03: /* INTERRUPT */
1117 packet_size = dev->descr[i + 4] + (dev->descr[i + 5] << 8);
1118 if (packet_size > 64)
1119 return 0;
1120 break;
1121 }
1122 }
1123 }
1124 return 1;
1125}
1126
26a9e82a 1127static int usb_host_open(USBHostDevice *dev, int bus_num,
3991c35e 1128 int addr, char *port, const char *prod_name, int speed)
bb36d470 1129{
b9dc033c 1130 int fd = -1, ret;
a594cfbf 1131 char buf[1024];
1f3870ab 1132
2791104c 1133 if (dev->fd != -1) {
26a9e82a 1134 goto fail;
2791104c 1135 }
64838171 1136 printf("husb: open device %d.%d\n", bus_num, addr);
3b46e624 1137
0f431527
AL
1138 if (!usb_host_device_path) {
1139 perror("husb: USB Host Device Path not set");
1140 goto fail;
1141 }
1142 snprintf(buf, sizeof(buf), "%s/%03d/%03d", usb_host_device_path,
a594cfbf 1143 bus_num, addr);
b9dc033c 1144 fd = open(buf, O_RDWR | O_NONBLOCK);
bb36d470 1145 if (fd < 0) {
a594cfbf 1146 perror(buf);
1f3870ab 1147 goto fail;
bb36d470 1148 }
d0f2c4c6 1149 DPRINTF("husb: opened %s\n", buf);
bb36d470 1150
806b6024
GH
1151 dev->bus_num = bus_num;
1152 dev->addr = addr;
5557d820 1153 strcpy(dev->port, port);
22f84e73 1154 dev->fd = fd;
806b6024 1155
b9dc033c
AZ
1156 /* read the device description */
1157 dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
1158 if (dev->descr_len <= 0) {
64838171 1159 perror("husb: reading device data failed");
bb36d470
FB
1160 goto fail;
1161 }
3b46e624 1162
b9dc033c 1163#ifdef DEBUG
868bfe2b 1164 {
b9dc033c
AZ
1165 int x;
1166 printf("=== begin dumping device descriptor data ===\n");
2791104c 1167 for (x = 0; x < dev->descr_len; x++) {
b9dc033c 1168 printf("%02x ", dev->descr[x]);
2791104c 1169 }
b9dc033c 1170 printf("\n=== end dumping device descriptor data ===\n");
bb36d470 1171 }
a594cfbf
FB
1172#endif
1173
b9dc033c 1174
2791104c
DA
1175 /*
1176 * Initial configuration is -1 which makes us claim first
446ab128 1177 * available config. We used to start with 1, which does not
2791104c 1178 * always work. I've seen devices where first config starts
446ab128
AL
1179 * with 2.
1180 */
2791104c 1181 if (!usb_host_claim_interfaces(dev, -1)) {
b9dc033c 1182 goto fail;
2791104c 1183 }
bb36d470 1184
b9dc033c 1185 ret = usb_linux_update_endp_table(dev);
2791104c 1186 if (ret) {
bb36d470 1187 goto fail;
2791104c 1188 }
b9dc033c 1189
3991c35e
HG
1190 if (speed == -1) {
1191 struct usbdevfs_connectinfo ci;
1192
1193 ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
1194 if (ret < 0) {
1195 perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
1196 goto fail;
1197 }
1198
1199 if (ci.slow) {
1200 speed = USB_SPEED_LOW;
1201 } else {
1202 speed = USB_SPEED_HIGH;
1203 }
2791104c 1204 }
3991c35e 1205 dev->dev.speed = speed;
ba3f9bfb 1206 dev->dev.speedmask = (1 << speed);
e4b17767
HG
1207 if (dev->dev.speed == USB_SPEED_HIGH && usb_linux_full_speed_compat(dev)) {
1208 dev->dev.speedmask |= USB_SPEED_MASK_FULL;
1209 }
3991c35e
HG
1210
1211 printf("husb: grabbed usb device %d.%d\n", bus_num, addr);
bb36d470 1212
2791104c 1213 if (!prod_name || prod_name[0] == '\0') {
0fe6d12e 1214 snprintf(dev->dev.product_desc, sizeof(dev->dev.product_desc),
4b096fc9 1215 "host:%d.%d", bus_num, addr);
2791104c 1216 } else {
0fe6d12e 1217 pstrcpy(dev->dev.product_desc, sizeof(dev->dev.product_desc),
4b096fc9 1218 prod_name);
2791104c 1219 }
1f6e24e7 1220
fa19bf83
HG
1221 ret = usb_device_attach(&dev->dev);
1222 if (ret) {
1223 goto fail;
1224 }
1225
64838171
AL
1226 /* USB devio uses 'write' flag to check for async completions */
1227 qemu_set_fd_handler(dev->fd, NULL, async_complete, dev);
1f3870ab 1228
26a9e82a 1229 return 0;
4b096fc9 1230
b9dc033c 1231fail:
1f45a81b
GH
1232 if (dev->fd != -1) {
1233 close(dev->fd);
1234 dev->fd = -1;
2791104c 1235 }
26a9e82a
GH
1236 return -1;
1237}
1238
1239static int usb_host_close(USBHostDevice *dev)
1240{
060dc841
HG
1241 int i;
1242
1f45a81b 1243 if (dev->fd == -1 || !dev->dev.attached) {
26a9e82a 1244 return -1;
2791104c 1245 }
26a9e82a
GH
1246
1247 qemu_set_fd_handler(dev->fd, NULL, NULL, NULL);
1248 dev->closing = 1;
3a4854b3 1249 for (i = 1; i <= MAX_ENDPOINTS; i++) {
060dc841
HG
1250 if (is_isoc(dev, i)) {
1251 usb_host_stop_n_free_iso(dev, i);
1252 }
1253 }
26a9e82a
GH
1254 async_complete(dev);
1255 dev->closing = 0;
1256 usb_device_detach(&dev->dev);
00ff227a 1257 ioctl(dev->fd, USBDEVFS_RESET);
26a9e82a
GH
1258 close(dev->fd);
1259 dev->fd = -1;
1260 return 0;
1261}
1262
9e8dd451 1263static void usb_host_exit_notifier(struct Notifier *n, void *data)
b373a63a
SH
1264{
1265 USBHostDevice *s = container_of(n, USBHostDevice, exit);
1266
1267 if (s->fd != -1) {
1268 ioctl(s->fd, USBDEVFS_RESET);
1269 }
1270}
1271
26a9e82a
GH
1272static int usb_host_initfn(USBDevice *dev)
1273{
1274 USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
1275
1276 dev->auto_attach = 0;
1277 s->fd = -1;
1278 QTAILQ_INSERT_TAIL(&hostdevs, s, next);
b373a63a
SH
1279 s->exit.notify = usb_host_exit_notifier;
1280 qemu_add_exit_notifier(&s->exit);
26a9e82a
GH
1281 usb_host_auto_check(NULL);
1282 return 0;
a594cfbf 1283}
bb36d470 1284
806b6024 1285static struct USBDeviceInfo usb_host_dev_info = {
06384698 1286 .product_desc = "USB Host Device",
556cd098 1287 .qdev.name = "usb-host",
806b6024
GH
1288 .qdev.size = sizeof(USBHostDevice),
1289 .init = usb_host_initfn,
50b7963e 1290 .handle_packet = usb_generic_handle_packet,
eb5e680a 1291 .cancel_packet = usb_host_async_cancel,
50b7963e
HG
1292 .handle_data = usb_host_handle_data,
1293 .handle_control = usb_host_handle_control,
806b6024 1294 .handle_reset = usb_host_handle_reset,
806b6024 1295 .handle_destroy = usb_host_handle_destroy,
26a9e82a
GH
1296 .usbdevice_name = "host",
1297 .usbdevice_init = usb_host_device_open,
1298 .qdev.props = (Property[]) {
1299 DEFINE_PROP_UINT32("hostbus", USBHostDevice, match.bus_num, 0),
1300 DEFINE_PROP_UINT32("hostaddr", USBHostDevice, match.addr, 0),
9056a297 1301 DEFINE_PROP_STRING("hostport", USBHostDevice, match.port),
26a9e82a
GH
1302 DEFINE_PROP_HEX32("vendorid", USBHostDevice, match.vendor_id, 0),
1303 DEFINE_PROP_HEX32("productid", USBHostDevice, match.product_id, 0),
b81bcd8a 1304 DEFINE_PROP_UINT32("isobufs", USBHostDevice, iso_urb_count, 4),
26a9e82a
GH
1305 DEFINE_PROP_END_OF_LIST(),
1306 },
806b6024
GH
1307};
1308
1309static void usb_host_register_devices(void)
1310{
1311 usb_qdev_register(&usb_host_dev_info);
1312}
1313device_init(usb_host_register_devices)
1314
4b096fc9
AL
1315USBDevice *usb_host_device_open(const char *devname)
1316{
0745eb1e 1317 struct USBAutoFilter filter;
26a9e82a 1318 USBDevice *dev;
26a9e82a
GH
1319 char *p;
1320
556cd098 1321 dev = usb_create(NULL /* FIXME */, "usb-host");
4b096fc9 1322
5d0c5750 1323 if (strstr(devname, "auto:")) {
2791104c 1324 if (parse_filter(devname, &filter) < 0) {
26a9e82a 1325 goto fail;
2791104c 1326 }
26a9e82a
GH
1327 } else {
1328 if ((p = strchr(devname, '.'))) {
0745eb1e
MA
1329 filter.bus_num = strtoul(devname, NULL, 0);
1330 filter.addr = strtoul(p + 1, NULL, 0);
1331 filter.vendor_id = 0;
1332 filter.product_id = 0;
26a9e82a 1333 } else if ((p = strchr(devname, ':'))) {
0745eb1e
MA
1334 filter.bus_num = 0;
1335 filter.addr = 0;
26a9e82a 1336 filter.vendor_id = strtoul(devname, NULL, 16);
0745eb1e 1337 filter.product_id = strtoul(p + 1, NULL, 16);
26a9e82a
GH
1338 } else {
1339 goto fail;
1340 }
5d0c5750 1341 }
4b096fc9 1342
0745eb1e
MA
1343 qdev_prop_set_uint32(&dev->qdev, "hostbus", filter.bus_num);
1344 qdev_prop_set_uint32(&dev->qdev, "hostaddr", filter.addr);
26a9e82a
GH
1345 qdev_prop_set_uint32(&dev->qdev, "vendorid", filter.vendor_id);
1346 qdev_prop_set_uint32(&dev->qdev, "productid", filter.product_id);
beb6f0de 1347 qdev_init_nofail(&dev->qdev);
26a9e82a 1348 return dev;
5d0c5750 1349
26a9e82a
GH
1350fail:
1351 qdev_free(&dev->qdev);
1352 return NULL;
4b096fc9 1353}
5d0c5750
AL
1354
1355int usb_host_device_close(const char *devname)
1356{
26a9e82a 1357#if 0
5d0c5750
AL
1358 char product_name[PRODUCT_NAME_SZ];
1359 int bus_num, addr;
1360 USBHostDevice *s;
1361
2791104c 1362 if (strstr(devname, "auto:")) {
5d0c5750 1363 return usb_host_auto_del(devname);
2791104c
DA
1364 }
1365 if (usb_host_find_device(&bus_num, &addr, product_name,
1366 sizeof(product_name), devname) < 0) {
5d0c5750 1367 return -1;
2791104c 1368 }
5d0c5750
AL
1369 s = hostdev_find(bus_num, addr);
1370 if (s) {
a5d2f727 1371 usb_device_delete_addr(s->bus_num, s->dev.addr);
5d0c5750
AL
1372 return 0;
1373 }
26a9e82a 1374#endif
5d0c5750
AL
1375
1376 return -1;
1377}
a5d2f727 1378
a594cfbf 1379static int get_tag_value(char *buf, int buf_size,
5fafdf24 1380 const char *str, const char *tag,
a594cfbf
FB
1381 const char *stopchars)
1382{
1383 const char *p;
1384 char *q;
1385 p = strstr(str, tag);
2791104c 1386 if (!p) {
a594cfbf 1387 return -1;
2791104c 1388 }
a594cfbf 1389 p += strlen(tag);
2791104c 1390 while (qemu_isspace(*p)) {
a594cfbf 1391 p++;
2791104c 1392 }
a594cfbf
FB
1393 q = buf;
1394 while (*p != '\0' && !strchr(stopchars, *p)) {
2791104c 1395 if ((q - buf) < (buf_size - 1)) {
a594cfbf 1396 *q++ = *p;
2791104c 1397 }
a594cfbf
FB
1398 p++;
1399 }
1400 *q = '\0';
1401 return q - buf;
bb36d470
FB
1402}
1403
0f431527
AL
1404/*
1405 * Use /proc/bus/usb/devices or /dev/bus/usb/devices file to determine
1406 * host's USB devices. This is legacy support since many distributions
1407 * are moving to /sys/bus/usb
1408 */
1409static int usb_host_scan_dev(void *opaque, USBScanFunc *func)
bb36d470 1410{
660f11be 1411 FILE *f = NULL;
a594cfbf 1412 char line[1024];
bb36d470 1413 char buf[1024];
a594cfbf 1414 int bus_num, addr, speed, device_count, class_id, product_id, vendor_id;
a594cfbf 1415 char product_name[512];
0f431527 1416 int ret = 0;
3b46e624 1417
0f431527
AL
1418 if (!usb_host_device_path) {
1419 perror("husb: USB Host Device Path not set");
1420 goto the_end;
1421 }
1422 snprintf(line, sizeof(line), "%s/devices", usb_host_device_path);
1423 f = fopen(line, "r");
a594cfbf 1424 if (!f) {
0f431527
AL
1425 perror("husb: cannot open devices file");
1426 goto the_end;
a594cfbf 1427 }
0f431527 1428
a594cfbf 1429 device_count = 0;
3991c35e
HG
1430 bus_num = addr = class_id = product_id = vendor_id = 0;
1431 speed = -1; /* Can't get the speed from /[proc|dev]/bus/usb/devices */
bb36d470 1432 for(;;) {
2791104c 1433 if (fgets(line, sizeof(line), f) == NULL) {
bb36d470 1434 break;
2791104c
DA
1435 }
1436 if (strlen(line) > 0) {
a594cfbf 1437 line[strlen(line) - 1] = '\0';
2791104c 1438 }
a594cfbf 1439 if (line[0] == 'T' && line[1] == ':') {
38ca0f6d
PB
1440 if (device_count && (vendor_id || product_id)) {
1441 /* New device. Add the previously discovered device. */
0f5160d1 1442 ret = func(opaque, bus_num, addr, 0, class_id, vendor_id,
a594cfbf 1443 product_id, product_name, speed);
2791104c 1444 if (ret) {
a594cfbf 1445 goto the_end;
2791104c 1446 }
a594cfbf 1447 }
2791104c 1448 if (get_tag_value(buf, sizeof(buf), line, "Bus=", " ") < 0) {
a594cfbf 1449 goto fail;
2791104c 1450 }
a594cfbf 1451 bus_num = atoi(buf);
2791104c 1452 if (get_tag_value(buf, sizeof(buf), line, "Dev#=", " ") < 0) {
a594cfbf 1453 goto fail;
2791104c 1454 }
a594cfbf 1455 addr = atoi(buf);
2791104c 1456 if (get_tag_value(buf, sizeof(buf), line, "Spd=", " ") < 0) {
a594cfbf 1457 goto fail;
2791104c 1458 }
f264cfbf
HG
1459 if (!strcmp(buf, "5000")) {
1460 speed = USB_SPEED_SUPER;
1461 } else if (!strcmp(buf, "480")) {
a594cfbf 1462 speed = USB_SPEED_HIGH;
2791104c 1463 } else if (!strcmp(buf, "1.5")) {
a594cfbf 1464 speed = USB_SPEED_LOW;
2791104c 1465 } else {
a594cfbf 1466 speed = USB_SPEED_FULL;
2791104c 1467 }
a594cfbf
FB
1468 product_name[0] = '\0';
1469 class_id = 0xff;
1470 device_count++;
1471 product_id = 0;
1472 vendor_id = 0;
1473 } else if (line[0] == 'P' && line[1] == ':') {
2791104c 1474 if (get_tag_value(buf, sizeof(buf), line, "Vendor=", " ") < 0) {
a594cfbf 1475 goto fail;
2791104c 1476 }
a594cfbf 1477 vendor_id = strtoul(buf, NULL, 16);
2791104c 1478 if (get_tag_value(buf, sizeof(buf), line, "ProdID=", " ") < 0) {
a594cfbf 1479 goto fail;
2791104c 1480 }
a594cfbf
FB
1481 product_id = strtoul(buf, NULL, 16);
1482 } else if (line[0] == 'S' && line[1] == ':') {
2791104c 1483 if (get_tag_value(buf, sizeof(buf), line, "Product=", "") < 0) {
a594cfbf 1484 goto fail;
2791104c 1485 }
a594cfbf
FB
1486 pstrcpy(product_name, sizeof(product_name), buf);
1487 } else if (line[0] == 'D' && line[1] == ':') {
2791104c 1488 if (get_tag_value(buf, sizeof(buf), line, "Cls=", " (") < 0) {
a594cfbf 1489 goto fail;
2791104c 1490 }
a594cfbf 1491 class_id = strtoul(buf, NULL, 16);
bb36d470 1492 }
a594cfbf
FB
1493 fail: ;
1494 }
38ca0f6d
PB
1495 if (device_count && (vendor_id || product_id)) {
1496 /* Add the last device. */
0f5160d1 1497 ret = func(opaque, bus_num, addr, 0, class_id, vendor_id,
a594cfbf 1498 product_id, product_name, speed);
bb36d470 1499 }
a594cfbf 1500 the_end:
2791104c 1501 if (f) {
0f431527 1502 fclose(f);
2791104c 1503 }
0f431527
AL
1504 return ret;
1505}
1506
1507/*
1508 * Read sys file-system device file
1509 *
1510 * @line address of buffer to put file contents in
1511 * @line_size size of line
1512 * @device_file path to device file (printf format string)
1513 * @device_name device being opened (inserted into device_file)
1514 *
1515 * @return 0 failed, 1 succeeded ('line' contains data)
1516 */
2791104c
DA
1517static int usb_host_read_file(char *line, size_t line_size,
1518 const char *device_file, const char *device_name)
0f431527
AL
1519{
1520 FILE *f;
1521 int ret = 0;
1522 char filename[PATH_MAX];
1523
b4e237aa
BS
1524 snprintf(filename, PATH_MAX, USBSYSBUS_PATH "/devices/%s/%s", device_name,
1525 device_file);
0f431527
AL
1526 f = fopen(filename, "r");
1527 if (f) {
9f99cee7 1528 ret = fgets(line, line_size, f) != NULL;
0f431527 1529 fclose(f);
0f431527
AL
1530 }
1531
1532 return ret;
1533}
1534
1535/*
1536 * Use /sys/bus/usb/devices/ directory to determine host's USB
1537 * devices.
1538 *
1539 * This code is based on Robert Schiele's original patches posted to
1540 * the Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
1541 */
1542static int usb_host_scan_sys(void *opaque, USBScanFunc *func)
1543{
660f11be 1544 DIR *dir = NULL;
0f431527 1545 char line[1024];
5557d820 1546 int bus_num, addr, speed, class_id, product_id, vendor_id;
0f431527 1547 int ret = 0;
5557d820 1548 char port[MAX_PORTLEN];
0f431527
AL
1549 char product_name[512];
1550 struct dirent *de;
1551
1552 dir = opendir(USBSYSBUS_PATH "/devices");
1553 if (!dir) {
1554 perror("husb: cannot open devices directory");
1555 goto the_end;
1556 }
1557
1558 while ((de = readdir(dir))) {
1559 if (de->d_name[0] != '.' && !strchr(de->d_name, ':')) {
5557d820
GH
1560 if (sscanf(de->d_name, "%d-%7[0-9.]", &bus_num, port) < 2) {
1561 continue;
0f5160d1 1562 }
0f431527 1563
2791104c 1564 if (!usb_host_read_file(line, sizeof(line), "devnum", de->d_name)) {
0f431527 1565 goto the_end;
2791104c
DA
1566 }
1567 if (sscanf(line, "%d", &addr) != 1) {
0f431527 1568 goto the_end;
2791104c 1569 }
b4e237aa 1570 if (!usb_host_read_file(line, sizeof(line), "bDeviceClass",
2791104c 1571 de->d_name)) {
0f431527 1572 goto the_end;
2791104c
DA
1573 }
1574 if (sscanf(line, "%x", &class_id) != 1) {
0f431527 1575 goto the_end;
2791104c 1576 }
0f431527 1577
2791104c
DA
1578 if (!usb_host_read_file(line, sizeof(line), "idVendor",
1579 de->d_name)) {
0f431527 1580 goto the_end;
2791104c
DA
1581 }
1582 if (sscanf(line, "%x", &vendor_id) != 1) {
0f431527 1583 goto the_end;
2791104c 1584 }
b4e237aa 1585 if (!usb_host_read_file(line, sizeof(line), "idProduct",
2791104c 1586 de->d_name)) {
0f431527 1587 goto the_end;
2791104c
DA
1588 }
1589 if (sscanf(line, "%x", &product_id) != 1) {
0f431527 1590 goto the_end;
2791104c 1591 }
b4e237aa
BS
1592 if (!usb_host_read_file(line, sizeof(line), "product",
1593 de->d_name)) {
0f431527
AL
1594 *product_name = 0;
1595 } else {
2791104c 1596 if (strlen(line) > 0) {
0f431527 1597 line[strlen(line) - 1] = '\0';
2791104c 1598 }
0f431527
AL
1599 pstrcpy(product_name, sizeof(product_name), line);
1600 }
1601
2791104c 1602 if (!usb_host_read_file(line, sizeof(line), "speed", de->d_name)) {
0f431527 1603 goto the_end;
2791104c 1604 }
f264cfbf
HG
1605 if (!strcmp(line, "5000\n")) {
1606 speed = USB_SPEED_SUPER;
1607 } else if (!strcmp(line, "480\n")) {
0f431527 1608 speed = USB_SPEED_HIGH;
2791104c 1609 } else if (!strcmp(line, "1.5\n")) {
0f431527 1610 speed = USB_SPEED_LOW;
2791104c 1611 } else {
0f431527 1612 speed = USB_SPEED_FULL;
2791104c 1613 }
0f431527 1614
5557d820 1615 ret = func(opaque, bus_num, addr, port, class_id, vendor_id,
0f431527 1616 product_id, product_name, speed);
2791104c 1617 if (ret) {
0f431527 1618 goto the_end;
2791104c 1619 }
0f431527
AL
1620 }
1621 }
1622 the_end:
2791104c 1623 if (dir) {
0f431527 1624 closedir(dir);
2791104c 1625 }
0f431527
AL
1626 return ret;
1627}
1628
1629/*
1630 * Determine how to access the host's USB devices and call the
1631 * specific support function.
1632 */
1633static int usb_host_scan(void *opaque, USBScanFunc *func)
1634{
376253ec 1635 Monitor *mon = cur_mon;
660f11be
BS
1636 FILE *f = NULL;
1637 DIR *dir = NULL;
0f431527 1638 int ret = 0;
0f431527
AL
1639 const char *fs_type[] = {"unknown", "proc", "dev", "sys"};
1640 char devpath[PATH_MAX];
1641
1642 /* only check the host once */
1643 if (!usb_fs_type) {
55496240
MM
1644 dir = opendir(USBSYSBUS_PATH "/devices");
1645 if (dir) {
1646 /* devices found in /dev/bus/usb/ (yes - not a mistake!) */
1647 strcpy(devpath, USBDEVBUS_PATH);
1648 usb_fs_type = USB_FS_SYS;
1649 closedir(dir);
d0f2c4c6 1650 DPRINTF(USBDBG_DEVOPENED, USBSYSBUS_PATH);
55496240
MM
1651 goto found_devices;
1652 }
0f431527
AL
1653 f = fopen(USBPROCBUS_PATH "/devices", "r");
1654 if (f) {
1655 /* devices found in /proc/bus/usb/ */
1656 strcpy(devpath, USBPROCBUS_PATH);
1657 usb_fs_type = USB_FS_PROC;
1658 fclose(f);
d0f2c4c6 1659 DPRINTF(USBDBG_DEVOPENED, USBPROCBUS_PATH);
f16a0db3 1660 goto found_devices;
0f431527
AL
1661 }
1662 /* try additional methods if an access method hasn't been found yet */
1663 f = fopen(USBDEVBUS_PATH "/devices", "r");
f16a0db3 1664 if (f) {
0f431527
AL
1665 /* devices found in /dev/bus/usb/ */
1666 strcpy(devpath, USBDEVBUS_PATH);
1667 usb_fs_type = USB_FS_DEV;
1668 fclose(f);
d0f2c4c6 1669 DPRINTF(USBDBG_DEVOPENED, USBDEVBUS_PATH);
f16a0db3 1670 goto found_devices;
0f431527 1671 }
f16a0db3 1672 found_devices:
22babebb 1673 if (!usb_fs_type) {
2791104c 1674 if (mon) {
eba6fe87 1675 monitor_printf(mon, "husb: unable to access USB devices\n");
2791104c 1676 }
f16a0db3 1677 return -ENOENT;
0f431527
AL
1678 }
1679
1680 /* the module setting (used later for opening devices) */
1681 usb_host_device_path = qemu_mallocz(strlen(devpath)+1);
1eec614b 1682 strcpy(usb_host_device_path, devpath);
2791104c 1683 if (mon) {
eba6fe87
GH
1684 monitor_printf(mon, "husb: using %s file-system with %s\n",
1685 fs_type[usb_fs_type], usb_host_device_path);
2791104c 1686 }
0f431527
AL
1687 }
1688
1689 switch (usb_fs_type) {
1690 case USB_FS_PROC:
1691 case USB_FS_DEV:
1692 ret = usb_host_scan_dev(opaque, func);
1693 break;
1694 case USB_FS_SYS:
1695 ret = usb_host_scan_sys(opaque, func);
1696 break;
f16a0db3
AL
1697 default:
1698 ret = -EINVAL;
1699 break;
0f431527 1700 }
a594cfbf 1701 return ret;
bb36d470
FB
1702}
1703
4b096fc9 1704static QEMUTimer *usb_auto_timer;
4b096fc9 1705
5557d820 1706static int usb_host_auto_scan(void *opaque, int bus_num, int addr, char *port,
26a9e82a
GH
1707 int class_id, int vendor_id, int product_id,
1708 const char *product_name, int speed)
4b096fc9
AL
1709{
1710 struct USBAutoFilter *f;
26a9e82a 1711 struct USBHostDevice *s;
4b096fc9
AL
1712
1713 /* Ignore hubs */
1714 if (class_id == 9)
1715 return 0;
1716
26a9e82a
GH
1717 QTAILQ_FOREACH(s, &hostdevs, next) {
1718 f = &s->match;
1719
2791104c 1720 if (f->bus_num > 0 && f->bus_num != bus_num) {
4b096fc9 1721 continue;
2791104c
DA
1722 }
1723 if (f->addr > 0 && f->addr != addr) {
4b096fc9 1724 continue;
2791104c 1725 }
9056a297
GH
1726 if (f->port != NULL && (port == NULL || strcmp(f->port, port) != 0)) {
1727 continue;
1728 }
4b096fc9 1729
2791104c 1730 if (f->vendor_id > 0 && f->vendor_id != vendor_id) {
4b096fc9 1731 continue;
2791104c 1732 }
4b096fc9 1733
2791104c 1734 if (f->product_id > 0 && f->product_id != product_id) {
4b096fc9 1735 continue;
2791104c 1736 }
4b096fc9
AL
1737 /* We got a match */
1738
33e66b86 1739 /* Already attached ? */
2791104c 1740 if (s->fd != -1) {
4b096fc9 1741 return 0;
2791104c 1742 }
d0f2c4c6 1743 DPRINTF("husb: auto open: bus_num %d addr %d\n", bus_num, addr);
4b096fc9 1744
3991c35e 1745 usb_host_open(s, bus_num, addr, port, product_name, speed);
97f86166 1746 break;
4b096fc9
AL
1747 }
1748
1749 return 0;
1750}
1751
26a9e82a 1752static void usb_host_auto_check(void *unused)
4b096fc9 1753{
26a9e82a
GH
1754 struct USBHostDevice *s;
1755 int unconnected = 0;
1756
4b096fc9 1757 usb_host_scan(NULL, usb_host_auto_scan);
26a9e82a
GH
1758
1759 QTAILQ_FOREACH(s, &hostdevs, next) {
2791104c 1760 if (s->fd == -1) {
26a9e82a 1761 unconnected++;
2791104c 1762 }
26a9e82a
GH
1763 }
1764
1765 if (unconnected == 0) {
1766 /* nothing to watch */
2791104c 1767 if (usb_auto_timer) {
26a9e82a 1768 qemu_del_timer(usb_auto_timer);
2791104c 1769 }
26a9e82a
GH
1770 return;
1771 }
1772
1773 if (!usb_auto_timer) {
7bd427d8 1774 usb_auto_timer = qemu_new_timer_ms(rt_clock, usb_host_auto_check, NULL);
2791104c 1775 if (!usb_auto_timer) {
26a9e82a 1776 return;
2791104c 1777 }
26a9e82a 1778 }
7bd427d8 1779 qemu_mod_timer(usb_auto_timer, qemu_get_clock_ms(rt_clock) + 2000);
4b096fc9
AL
1780}
1781
1782/*
5d0c5750
AL
1783 * Autoconnect filter
1784 * Format:
1785 * auto:bus:dev[:vid:pid]
1786 * auto:bus.dev[:vid:pid]
1787 *
1788 * bus - bus number (dec, * means any)
1789 * dev - device number (dec, * means any)
1790 * vid - vendor id (hex, * means any)
1791 * pid - product id (hex, * means any)
1792 *
1793 * See 'lsusb' output.
4b096fc9 1794 */
5d0c5750 1795static int parse_filter(const char *spec, struct USBAutoFilter *f)
4b096fc9 1796{
5d0c5750
AL
1797 enum { BUS, DEV, VID, PID, DONE };
1798 const char *p = spec;
1799 int i;
1800
0745eb1e
MA
1801 f->bus_num = 0;
1802 f->addr = 0;
1803 f->vendor_id = 0;
1804 f->product_id = 0;
5d0c5750
AL
1805
1806 for (i = BUS; i < DONE; i++) {
2791104c
DA
1807 p = strpbrk(p, ":.");
1808 if (!p) {
1809 break;
1810 }
5d0c5750 1811 p++;
5d0c5750 1812
2791104c
DA
1813 if (*p == '*') {
1814 continue;
1815 }
5d0c5750
AL
1816 switch(i) {
1817 case BUS: f->bus_num = strtol(p, NULL, 10); break;
1818 case DEV: f->addr = strtol(p, NULL, 10); break;
1819 case VID: f->vendor_id = strtol(p, NULL, 16); break;
1820 case PID: f->product_id = strtol(p, NULL, 16); break;
1821 }
1822 }
1823
1824 if (i < DEV) {
1825 fprintf(stderr, "husb: invalid auto filter spec %s\n", spec);
1826 return -1;
1827 }
1828
1829 return 0;
1830}
1831
a594cfbf
FB
1832/**********************/
1833/* USB host device info */
1834
1835struct usb_class_info {
1836 int class;
1837 const char *class_name;
1838};
1839
1840static const struct usb_class_info usb_class_info[] = {
1841 { USB_CLASS_AUDIO, "Audio"},
1842 { USB_CLASS_COMM, "Communication"},
1843 { USB_CLASS_HID, "HID"},
1844 { USB_CLASS_HUB, "Hub" },
1845 { USB_CLASS_PHYSICAL, "Physical" },
1846 { USB_CLASS_PRINTER, "Printer" },
1847 { USB_CLASS_MASS_STORAGE, "Storage" },
1848 { USB_CLASS_CDC_DATA, "Data" },
1849 { USB_CLASS_APP_SPEC, "Application Specific" },
1850 { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
1851 { USB_CLASS_STILL_IMAGE, "Still Image" },
b9dc033c 1852 { USB_CLASS_CSCID, "Smart Card" },
a594cfbf
FB
1853 { USB_CLASS_CONTENT_SEC, "Content Security" },
1854 { -1, NULL }
1855};
1856
1857static const char *usb_class_str(uint8_t class)
bb36d470 1858{
a594cfbf
FB
1859 const struct usb_class_info *p;
1860 for(p = usb_class_info; p->class != -1; p++) {
2791104c 1861 if (p->class == class) {
a594cfbf 1862 break;
2791104c 1863 }
bb36d470 1864 }
a594cfbf
FB
1865 return p->class_name;
1866}
1867
5557d820
GH
1868static void usb_info_device(Monitor *mon, int bus_num, int addr, char *port,
1869 int class_id, int vendor_id, int product_id,
9596ebb7
PB
1870 const char *product_name,
1871 int speed)
a594cfbf
FB
1872{
1873 const char *class_str, *speed_str;
1874
1875 switch(speed) {
5fafdf24
TS
1876 case USB_SPEED_LOW:
1877 speed_str = "1.5";
a594cfbf 1878 break;
5fafdf24
TS
1879 case USB_SPEED_FULL:
1880 speed_str = "12";
a594cfbf 1881 break;
5fafdf24
TS
1882 case USB_SPEED_HIGH:
1883 speed_str = "480";
a594cfbf 1884 break;
f264cfbf
HG
1885 case USB_SPEED_SUPER:
1886 speed_str = "5000";
1887 break;
a594cfbf 1888 default:
5fafdf24 1889 speed_str = "?";
a594cfbf
FB
1890 break;
1891 }
1892
5557d820
GH
1893 monitor_printf(mon, " Bus %d, Addr %d, Port %s, Speed %s Mb/s\n",
1894 bus_num, addr, port, speed_str);
a594cfbf 1895 class_str = usb_class_str(class_id);
2791104c 1896 if (class_str) {
376253ec 1897 monitor_printf(mon, " %s:", class_str);
2791104c 1898 } else {
376253ec 1899 monitor_printf(mon, " Class %02x:", class_id);
2791104c 1900 }
376253ec 1901 monitor_printf(mon, " USB device %04x:%04x", vendor_id, product_id);
2791104c 1902 if (product_name[0] != '\0') {
376253ec 1903 monitor_printf(mon, ", %s", product_name);
2791104c 1904 }
376253ec 1905 monitor_printf(mon, "\n");
a594cfbf
FB
1906}
1907
5fafdf24 1908static int usb_host_info_device(void *opaque, int bus_num, int addr,
5557d820 1909 char *path, int class_id,
5fafdf24 1910 int vendor_id, int product_id,
a594cfbf
FB
1911 const char *product_name,
1912 int speed)
1913{
179da8af
BS
1914 Monitor *mon = opaque;
1915
5557d820 1916 usb_info_device(mon, bus_num, addr, path, class_id, vendor_id, product_id,
a594cfbf
FB
1917 product_name, speed);
1918 return 0;
1919}
1920
ac4ffb5a 1921static void dec2str(int val, char *str, size_t size)
5d0c5750 1922{
2791104c 1923 if (val == 0) {
ac4ffb5a 1924 snprintf(str, size, "*");
2791104c
DA
1925 } else {
1926 snprintf(str, size, "%d", val);
1927 }
5d0c5750
AL
1928}
1929
ac4ffb5a 1930static void hex2str(int val, char *str, size_t size)
5d0c5750 1931{
2791104c 1932 if (val == 0) {
ac4ffb5a 1933 snprintf(str, size, "*");
2791104c 1934 } else {
26a9e82a 1935 snprintf(str, size, "%04x", val);
2791104c 1936 }
5d0c5750
AL
1937}
1938
376253ec 1939void usb_host_info(Monitor *mon)
a594cfbf 1940{
5d0c5750 1941 struct USBAutoFilter *f;
26a9e82a 1942 struct USBHostDevice *s;
5d0c5750 1943
179da8af 1944 usb_host_scan(mon, usb_host_info_device);
5d0c5750 1945
2791104c 1946 if (QTAILQ_EMPTY(&hostdevs)) {
26a9e82a 1947 return;
2791104c
DA
1948 }
1949
26a9e82a
GH
1950 monitor_printf(mon, " Auto filters:\n");
1951 QTAILQ_FOREACH(s, &hostdevs, next) {
5d0c5750 1952 char bus[10], addr[10], vid[10], pid[10];
26a9e82a 1953 f = &s->match;
ac4ffb5a
AL
1954 dec2str(f->bus_num, bus, sizeof(bus));
1955 dec2str(f->addr, addr, sizeof(addr));
1956 hex2str(f->vendor_id, vid, sizeof(vid));
1957 hex2str(f->product_id, pid, sizeof(pid));
9056a297
GH
1958 monitor_printf(mon, " Bus %s, Addr %s, Port %s, ID %s:%s\n",
1959 bus, addr, f->port ? f->port : "*", vid, pid);
5d0c5750 1960 }
bb36d470 1961}