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