]> git.proxmox.com Git - qemu.git/blame - usb-linux.c
usb: track altsetting 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
1de14d43
GH
547 for (i = 0; i < USB_MAX_INTERFACES; i++) {
548 dev->dev.altsetting[i] = 0;
549 }
550
eb7700bb 551 if (configuration == 0) { /* address state - ignore */
65360511
GH
552 dev->dev.ninterfaces = 0;
553 dev->dev.configuration = 0;
b9dc033c 554 return 1;
eb7700bb 555 }
b9dc033c 556
d0f2c4c6 557 DPRINTF("husb: claiming interfaces. config %d\n", configuration);
446ab128 558
b9dc033c
AZ
559 i = 0;
560 dev_descr_len = dev->descr[0];
2791104c 561 if (dev_descr_len > dev->descr_len) {
61c1117f
HG
562 fprintf(stderr, "husb: update iface failed. descr too short\n");
563 return 0;
2791104c 564 }
b9dc033c
AZ
565
566 i += dev_descr_len;
567 while (i < dev->descr_len) {
2791104c
DA
568 DPRINTF("husb: i is %d, descr_len is %d, dl %d, dt %d\n",
569 i, dev->descr_len,
b9dc033c 570 dev->descr[i], dev->descr[i+1]);
64838171 571
b9dc033c
AZ
572 if (dev->descr[i+1] != USB_DT_CONFIG) {
573 i += dev->descr[i];
574 continue;
575 }
576 config_descr_len = dev->descr[i];
577
e6a2f500 578 DPRINTF("husb: config #%d need %d\n", dev->descr[i + 5], configuration);
1f3870ab 579
eb7700bb 580 if (configuration == dev->descr[i + 5]) {
446ab128 581 configuration = dev->descr[i + 5];
b9dc033c 582 break;
446ab128 583 }
b9dc033c
AZ
584
585 i += config_descr_len;
586 }
587
588 if (i >= dev->descr_len) {
2791104c
DA
589 fprintf(stderr,
590 "husb: update iface failed. no matching configuration\n");
61c1117f 591 return 0;
b9dc033c
AZ
592 }
593 nb_interfaces = dev->descr[i + 4];
594
e6274727
GH
595 if (usb_host_disconnect_ifaces(dev, nb_interfaces) < 0) {
596 goto fail;
b9dc033c 597 }
b9dc033c
AZ
598
599 /* XXX: only grab if all interfaces are free */
600 for (interface = 0; interface < nb_interfaces; interface++) {
41c01ee7 601 op = "USBDEVFS_CLAIMINTERFACE";
b9dc033c
AZ
602 ret = ioctl(dev->fd, USBDEVFS_CLAIMINTERFACE, &interface);
603 if (ret < 0) {
41c01ee7 604 goto fail;
b9dc033c
AZ
605 }
606 }
607
e6a2f500
GH
608 trace_usb_host_claim_interfaces(dev->bus_num, dev->addr,
609 nb_interfaces, configuration);
b9dc033c 610
65360511
GH
611 dev->dev.ninterfaces = nb_interfaces;
612 dev->dev.configuration = configuration;
446ab128 613 return 1;
41c01ee7
GH
614
615fail:
616 if (errno == ENODEV) {
617 do_disconnect(dev);
618 }
619 perror(op);
620 return 0;
446ab128
AL
621}
622
623static int usb_host_release_interfaces(USBHostDevice *s)
624{
625 int ret, i;
626
e6a2f500 627 trace_usb_host_release_interfaces(s->bus_num, s->addr);
446ab128 628
65360511 629 for (i = 0; i < s->dev.ninterfaces; i++) {
446ab128
AL
630 ret = ioctl(s->fd, USBDEVFS_RELEASEINTERFACE, &i);
631 if (ret < 0) {
e6a2f500 632 perror("USBDEVFS_RELEASEINTERFACE");
446ab128
AL
633 return 0;
634 }
635 }
b9dc033c
AZ
636 return 1;
637}
638
059809e4 639static void usb_host_handle_reset(USBDevice *dev)
bb36d470 640{
26a9e82a 641 USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
64838171 642
e6a2f500 643 trace_usb_host_reset(s->bus_num, s->addr);
64838171 644
c7662daa 645 usb_host_do_reset(s);;
446ab128 646
eb7700bb 647 usb_host_claim_interfaces(s, 0);
9b87e19b 648 usb_linux_update_endp_table(s);
5fafdf24 649}
bb36d470 650
059809e4
FB
651static void usb_host_handle_destroy(USBDevice *dev)
652{
653 USBHostDevice *s = (USBHostDevice *)dev;
654
c75fead6 655 usb_host_release_port(s);
26a9e82a
GH
656 usb_host_close(s);
657 QTAILQ_REMOVE(&hostdevs, s, next);
b373a63a 658 qemu_remove_exit_notifier(&s->exit);
059809e4
FB
659}
660
060dc841
HG
661/* iso data is special, we need to keep enough urbs in flight to make sure
662 that the controller never runs out of them, otherwise the device will
663 likely suffer a buffer underrun / overrun. */
c0e5750b 664static AsyncURB *usb_host_alloc_iso(USBHostDevice *s, int pid, uint8_t ep)
060dc841
HG
665{
666 AsyncURB *aurb;
c0e5750b 667 int i, j, len = get_max_packet_size(s, pid, ep);
060dc841 668
7267c094 669 aurb = g_malloc0(s->iso_urb_count * sizeof(*aurb));
b81bcd8a 670 for (i = 0; i < s->iso_urb_count; i++) {
060dc841
HG
671 aurb[i].urb.endpoint = ep;
672 aurb[i].urb.buffer_length = ISO_FRAME_DESC_PER_URB * len;
7267c094 673 aurb[i].urb.buffer = g_malloc(aurb[i].urb.buffer_length);
060dc841
HG
674 aurb[i].urb.type = USBDEVFS_URB_TYPE_ISO;
675 aurb[i].urb.flags = USBDEVFS_URB_ISO_ASAP;
676 aurb[i].urb.number_of_packets = ISO_FRAME_DESC_PER_URB;
677 for (j = 0 ; j < ISO_FRAME_DESC_PER_URB; j++)
678 aurb[i].urb.iso_frame_desc[j].length = len;
c0e5750b 679 if (pid == USB_TOKEN_IN) {
060dc841
HG
680 aurb[i].urb.endpoint |= 0x80;
681 /* Mark as fully consumed (idle) */
682 aurb[i].iso_frame_idx = ISO_FRAME_DESC_PER_URB;
683 }
684 }
c0e5750b 685 set_iso_urb(s, pid, ep, aurb);
060dc841
HG
686
687 return aurb;
688}
689
c0e5750b 690static void usb_host_stop_n_free_iso(USBHostDevice *s, int pid, uint8_t ep)
060dc841
HG
691{
692 AsyncURB *aurb;
693 int i, ret, killed = 0, free = 1;
694
c0e5750b 695 aurb = get_iso_urb(s, pid, ep);
060dc841
HG
696 if (!aurb) {
697 return;
698 }
699
b81bcd8a 700 for (i = 0; i < s->iso_urb_count; i++) {
060dc841
HG
701 /* in flight? */
702 if (aurb[i].iso_frame_idx == -1) {
703 ret = ioctl(s->fd, USBDEVFS_DISCARDURB, &aurb[i]);
704 if (ret < 0) {
e6a2f500 705 perror("USBDEVFS_DISCARDURB");
060dc841
HG
706 free = 0;
707 continue;
708 }
709 killed++;
710 }
711 }
712
713 /* Make sure any urbs we've killed are reaped before we free them */
714 if (killed) {
715 async_complete(s);
716 }
717
b81bcd8a 718 for (i = 0; i < s->iso_urb_count; i++) {
7267c094 719 g_free(aurb[i].urb.buffer);
060dc841
HG
720 }
721
722 if (free)
7267c094 723 g_free(aurb);
060dc841
HG
724 else
725 printf("husb: leaking iso urbs because of discard failure\n");
c0e5750b
GH
726 set_iso_urb(s, pid, ep, NULL);
727 set_iso_urb_idx(s, pid, ep, 0);
728 clear_iso_started(s, pid, ep);
060dc841
HG
729}
730
731static int urb_status_to_usb_ret(int status)
732{
733 switch (status) {
734 case -EPIPE:
735 return USB_RET_STALL;
736 default:
737 return USB_RET_NAK;
738 }
739}
740
bb6d5498 741static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in)
060dc841
HG
742{
743 AsyncURB *aurb;
bb6d5498 744 int i, j, ret, max_packet_size, offset, len = 0;
4f4321c1 745 uint8_t *buf;
975f2998 746
c0e5750b 747 max_packet_size = get_max_packet_size(s, p->pid, p->devep);
975f2998
HG
748 if (max_packet_size == 0)
749 return USB_RET_NAK;
060dc841 750
c0e5750b 751 aurb = get_iso_urb(s, p->pid, p->devep);
060dc841 752 if (!aurb) {
c0e5750b 753 aurb = usb_host_alloc_iso(s, p->pid, p->devep);
060dc841
HG
754 }
755
c0e5750b 756 i = get_iso_urb_idx(s, p->pid, p->devep);
060dc841
HG
757 j = aurb[i].iso_frame_idx;
758 if (j >= 0 && j < ISO_FRAME_DESC_PER_URB) {
bb6d5498
HG
759 if (in) {
760 /* Check urb status */
761 if (aurb[i].urb.status) {
762 len = urb_status_to_usb_ret(aurb[i].urb.status);
763 /* Move to the next urb */
764 aurb[i].iso_frame_idx = ISO_FRAME_DESC_PER_URB - 1;
765 /* Check frame status */
766 } else if (aurb[i].urb.iso_frame_desc[j].status) {
767 len = urb_status_to_usb_ret(
768 aurb[i].urb.iso_frame_desc[j].status);
769 /* Check the frame fits */
4f4321c1
GH
770 } else if (aurb[i].urb.iso_frame_desc[j].actual_length
771 > p->iov.size) {
bb6d5498
HG
772 printf("husb: received iso data is larger then packet\n");
773 len = USB_RET_NAK;
774 /* All good copy data over */
775 } else {
776 len = aurb[i].urb.iso_frame_desc[j].actual_length;
4f4321c1
GH
777 buf = aurb[i].urb.buffer +
778 j * aurb[i].urb.iso_frame_desc[0].length;
779 usb_packet_copy(p, buf, len);
bb6d5498 780 }
060dc841 781 } else {
4f4321c1 782 len = p->iov.size;
c0e5750b 783 offset = (j == 0) ? 0 : get_iso_buffer_used(s, p->pid, p->devep);
bb6d5498
HG
784
785 /* Check the frame fits */
786 if (len > max_packet_size) {
787 printf("husb: send iso data is larger then max packet size\n");
788 return USB_RET_NAK;
789 }
790
791 /* All good copy data over */
4f4321c1 792 usb_packet_copy(p, aurb[i].urb.buffer + offset, len);
bb6d5498
HG
793 aurb[i].urb.iso_frame_desc[j].length = len;
794 offset += len;
c0e5750b 795 set_iso_buffer_used(s, p->pid, p->devep, offset);
bb6d5498
HG
796
797 /* Start the stream once we have buffered enough data */
c0e5750b
GH
798 if (!is_iso_started(s, p->pid, p->devep) && i == 1 && j == 8) {
799 set_iso_started(s, p->pid, p->devep);
bb6d5498 800 }
060dc841
HG
801 }
802 aurb[i].iso_frame_idx++;
803 if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {
b81bcd8a 804 i = (i + 1) % s->iso_urb_count;
c0e5750b 805 set_iso_urb_idx(s, p->pid, p->devep, i);
060dc841 806 }
bb6d5498
HG
807 } else {
808 if (in) {
c0e5750b 809 set_iso_started(s, p->pid, p->devep);
bb6d5498
HG
810 } else {
811 DPRINTF("hubs: iso out error no free buffer, dropping packet\n");
812 }
060dc841
HG
813 }
814
c0e5750b 815 if (is_iso_started(s, p->pid, p->devep)) {
bb6d5498 816 /* (Re)-submit all fully consumed / filled urbs */
b81bcd8a 817 for (i = 0; i < s->iso_urb_count; i++) {
bb6d5498
HG
818 if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {
819 ret = ioctl(s->fd, USBDEVFS_SUBMITURB, &aurb[i]);
820 if (ret < 0) {
e6a2f500 821 perror("USBDEVFS_SUBMITURB");
bb6d5498
HG
822 if (!in || len == 0) {
823 switch(errno) {
824 case ETIMEDOUT:
825 len = USB_RET_NAK;
0225e254 826 break;
bb6d5498
HG
827 case EPIPE:
828 default:
829 len = USB_RET_STALL;
830 }
060dc841 831 }
bb6d5498 832 break;
060dc841 833 }
bb6d5498 834 aurb[i].iso_frame_idx = -1;
c0e5750b 835 change_iso_inflight(s, p->pid, p->devep, 1);
060dc841 836 }
060dc841
HG
837 }
838 }
839
840 return len;
841}
842
50b7963e 843static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
bb36d470 844{
50b7963e 845 USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
64838171 846 struct usbdevfs_urb *urb;
446ab128 847 AsyncURB *aurb;
b621bab4 848 int ret, rem, prem, v;
71138531 849 uint8_t *pbuf;
060dc841 850 uint8_t ep;
b9dc033c 851
e6a2f500
GH
852 trace_usb_host_req_data(s->bus_num, s->addr,
853 p->pid == USB_TOKEN_IN,
854 p->devep, p->iov.size);
855
c0e5750b 856 if (!is_valid(s, p->pid, p->devep)) {
e6a2f500 857 trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_NAK);
a0b5fece
HG
858 return USB_RET_NAK;
859 }
860
2791104c 861 if (p->pid == USB_TOKEN_IN) {
060dc841 862 ep = p->devep | 0x80;
2791104c 863 } else {
060dc841 864 ep = p->devep;
2791104c 865 }
64838171 866
c0e5750b 867 if (is_halted(s, p->pid, p->devep)) {
9b87e19b
GH
868 unsigned int arg = ep;
869 ret = ioctl(s->fd, USBDEVFS_CLEAR_HALT, &arg);
64838171 870 if (ret < 0) {
e6a2f500
GH
871 perror("USBDEVFS_CLEAR_HALT");
872 trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_NAK);
bb36d470 873 return USB_RET_NAK;
bb36d470 874 }
c0e5750b 875 clear_halt(s, p->pid, p->devep);
4d043a09
AZ
876 }
877
c0e5750b 878 if (is_isoc(s, p->pid, p->devep)) {
bb6d5498
HG
879 return usb_host_handle_iso_data(s, p, p->pid == USB_TOKEN_IN);
880 }
060dc841 881
b621bab4
GH
882 v = 0;
883 prem = p->iov.iov[v].iov_len;
884 pbuf = p->iov.iov[v].iov_base;
885 rem = p->iov.size;
71138531 886 while (rem) {
b621bab4
GH
887 if (prem == 0) {
888 v++;
889 assert(v < p->iov.niov);
890 prem = p->iov.iov[v].iov_len;
891 pbuf = p->iov.iov[v].iov_base;
892 assert(prem <= rem);
893 }
71138531
GH
894 aurb = async_alloc(s);
895 aurb->packet = p;
896
897 urb = &aurb->urb;
898 urb->endpoint = ep;
899 urb->type = USBDEVFS_URB_TYPE_BULK;
900 urb->usercontext = s;
901 urb->buffer = pbuf;
b621bab4 902 urb->buffer_length = prem;
71138531 903
b621bab4 904 if (urb->buffer_length > MAX_USBFS_BUFFER_SIZE) {
71138531 905 urb->buffer_length = MAX_USBFS_BUFFER_SIZE;
71138531
GH
906 }
907 pbuf += urb->buffer_length;
b621bab4 908 prem -= urb->buffer_length;
71138531 909 rem -= urb->buffer_length;
b621bab4
GH
910 if (rem) {
911 aurb->more = 1;
912 }
b9dc033c 913
e6a2f500
GH
914 trace_usb_host_urb_submit(s->bus_num, s->addr, aurb,
915 urb->buffer_length, aurb->more);
71138531 916 ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
b9dc033c 917
71138531
GH
918 DPRINTF("husb: data submit: ep 0x%x, len %u, more %d, packet %p, aurb %p\n",
919 urb->endpoint, urb->buffer_length, aurb->more, p, aurb);
b9dc033c 920
71138531 921 if (ret < 0) {
e6a2f500 922 perror("USBDEVFS_SUBMITURB");
71138531 923 async_free(aurb);
b9dc033c 924
71138531
GH
925 switch(errno) {
926 case ETIMEDOUT:
e6a2f500 927 trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_NAK);
71138531
GH
928 return USB_RET_NAK;
929 case EPIPE:
930 default:
e6a2f500 931 trace_usb_host_req_complete(s->bus_num, s->addr, USB_RET_STALL);
71138531
GH
932 return USB_RET_STALL;
933 }
b9dc033c
AZ
934 }
935 }
64838171 936
b9dc033c 937 return USB_RET_ASYNC;
b9dc033c
AZ
938}
939
446ab128
AL
940static int ctrl_error(void)
941{
2791104c 942 if (errno == ETIMEDOUT) {
446ab128 943 return USB_RET_NAK;
2791104c 944 } else {
446ab128 945 return USB_RET_STALL;
2791104c 946 }
446ab128
AL
947}
948
949static int usb_host_set_address(USBHostDevice *s, int addr)
950{
e6a2f500 951 trace_usb_host_set_address(s->bus_num, s->addr, addr);
446ab128
AL
952 s->dev.addr = addr;
953 return 0;
954}
955
956static int usb_host_set_config(USBHostDevice *s, int config)
957{
0fcc3bfc
GH
958 int ret, first = 1;
959
e6a2f500
GH
960 trace_usb_host_set_config(s->bus_num, s->addr, config);
961
446ab128
AL
962 usb_host_release_interfaces(s);
963
0fcc3bfc
GH
964again:
965 ret = ioctl(s->fd, USBDEVFS_SETCONFIGURATION, &config);
2791104c 966
d0f2c4c6 967 DPRINTF("husb: ctrl set config %d ret %d errno %d\n", config, ret, errno);
2791104c 968
0fcc3bfc
GH
969 if (ret < 0 && errno == EBUSY && first) {
970 /* happens if usb device is in use by host drivers */
971 int count = usb_linux_get_num_interfaces(s);
972 if (count > 0) {
973 DPRINTF("husb: busy -> disconnecting %d interfaces\n", count);
974 usb_host_disconnect_ifaces(s, count);
975 first = 0;
976 goto again;
977 }
978 }
979
2791104c 980 if (ret < 0) {
446ab128 981 return ctrl_error();
2791104c 982 }
446ab128 983 usb_host_claim_interfaces(s, config);
eb7700bb 984 usb_linux_update_endp_table(s);
446ab128
AL
985 return 0;
986}
987
988static int usb_host_set_interface(USBHostDevice *s, int iface, int alt)
989{
990 struct usbdevfs_setinterface si;
060dc841
HG
991 int i, ret;
992
e6a2f500
GH
993 trace_usb_host_set_interface(s->bus_num, s->addr, iface, alt);
994
3a4854b3 995 for (i = 1; i <= MAX_ENDPOINTS; i++) {
c0e5750b
GH
996 if (is_isoc(s, USB_TOKEN_IN, i)) {
997 usb_host_stop_n_free_iso(s, USB_TOKEN_IN, i);
998 }
999 if (is_isoc(s, USB_TOKEN_OUT, i)) {
1000 usb_host_stop_n_free_iso(s, USB_TOKEN_OUT, i);
060dc841
HG
1001 }
1002 }
446ab128 1003
1de14d43
GH
1004 if (iface >= USB_MAX_INTERFACES) {
1005 return USB_RET_STALL;
1006 }
1007
446ab128
AL
1008 si.interface = iface;
1009 si.altsetting = alt;
1010 ret = ioctl(s->fd, USBDEVFS_SETINTERFACE, &si);
446ab128 1011
2791104c
DA
1012 DPRINTF("husb: ctrl set iface %d altset %d ret %d errno %d\n",
1013 iface, alt, ret, errno);
1014
1015 if (ret < 0) {
1016 return ctrl_error();
1017 }
1de14d43
GH
1018
1019 s->dev.altsetting[iface] = alt;
446ab128
AL
1020 usb_linux_update_endp_table(s);
1021 return 0;
1022}
1023
50b7963e
HG
1024static int usb_host_handle_control(USBDevice *dev, USBPacket *p,
1025 int request, int value, int index, int length, uint8_t *data)
446ab128 1026{
50b7963e 1027 USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
446ab128
AL
1028 struct usbdevfs_urb *urb;
1029 AsyncURB *aurb;
50b7963e 1030 int ret;
446ab128 1031
2791104c 1032 /*
446ab128
AL
1033 * Process certain standard device requests.
1034 * These are infrequent and are processed synchronously.
1035 */
446ab128 1036
50b7963e 1037 /* Note request is (bRequestType << 8) | bRequest */
e6a2f500 1038 trace_usb_host_req_control(s->bus_num, s->addr, request, value, index);
446ab128 1039
50b7963e
HG
1040 switch (request) {
1041 case DeviceOutRequest | USB_REQ_SET_ADDRESS:
1042 return usb_host_set_address(s, value);
446ab128 1043
50b7963e
HG
1044 case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
1045 return usb_host_set_config(s, value & 0xff);
446ab128 1046
50b7963e 1047 case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
446ab128 1048 return usb_host_set_interface(s, index, value);
2791104c 1049 }
446ab128
AL
1050
1051 /* The rest are asynchronous */
1052
50b7963e
HG
1053 if (length > sizeof(dev->data_buf)) {
1054 fprintf(stderr, "husb: ctrl buffer too small (%d > %zu)\n",
1055 length, sizeof(dev->data_buf));
b2e3b6e9 1056 return USB_RET_STALL;
c4c0e236
JP
1057 }
1058
7a8fc83f 1059 aurb = async_alloc(s);
446ab128
AL
1060 aurb->packet = p;
1061
2791104c 1062 /*
446ab128
AL
1063 * Setup ctrl transfer.
1064 *
a0102082 1065 * s->ctrl is laid out such that data buffer immediately follows
446ab128 1066 * 'req' struct which is exactly what usbdevfs expects.
2791104c 1067 */
446ab128
AL
1068 urb = &aurb->urb;
1069
1070 urb->type = USBDEVFS_URB_TYPE_CONTROL;
1071 urb->endpoint = p->devep;
1072
50b7963e
HG
1073 urb->buffer = &dev->setup_buf;
1074 urb->buffer_length = length + 8;
446ab128
AL
1075
1076 urb->usercontext = s;
1077
e6a2f500
GH
1078 trace_usb_host_urb_submit(s->bus_num, s->addr, aurb,
1079 urb->buffer_length, aurb->more);
446ab128
AL
1080 ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
1081
d0f2c4c6 1082 DPRINTF("husb: submit ctrl. len %u aurb %p\n", urb->buffer_length, aurb);
446ab128
AL
1083
1084 if (ret < 0) {
d0f2c4c6 1085 DPRINTF("husb: submit failed. errno %d\n", errno);
446ab128
AL
1086 async_free(aurb);
1087
1088 switch(errno) {
1089 case ETIMEDOUT:
1090 return USB_RET_NAK;
1091 case EPIPE:
1092 default:
1093 return USB_RET_STALL;
1094 }
1095 }
1096
446ab128
AL
1097 return USB_RET_ASYNC;
1098}
1099
ed3a328d
HG
1100static uint8_t usb_linux_get_alt_setting(USBHostDevice *s,
1101 uint8_t configuration, uint8_t interface)
1102{
097db438
GH
1103 char device_name[64], line[1024];
1104 int alt_setting;
c43831fb 1105
097db438
GH
1106 sprintf(device_name, "%d-%s:%d.%d", s->bus_num, s->port,
1107 (int)configuration, (int)interface);
c43831fb 1108
097db438
GH
1109 if (!usb_host_read_file(line, sizeof(line), "bAlternateSetting",
1110 device_name)) {
1111 /* Assume alt 0 on error */
1112 return 0;
1113 }
1114 if (sscanf(line, "%d", &alt_setting) != 1) {
ed3a328d
HG
1115 /* Assume alt 0 on error */
1116 return 0;
1117 }
ed3a328d
HG
1118 return alt_setting;
1119}
1120
71d71bbd
HG
1121/* returns 1 on problem encountered or 0 for success */
1122static int usb_linux_update_endp_table(USBHostDevice *s)
1123{
1124 uint8_t *descriptors;
eb7700bb 1125 uint8_t devep, type, alt_interface;
c0e5750b
GH
1126 int interface, length, i, ep, pid;
1127 struct endp_data *epd;
71d71bbd 1128
c0e5750b
GH
1129 for (i = 0; i < MAX_ENDPOINTS; i++) {
1130 s->ep_in[i].type = INVALID_EP_TYPE;
1131 s->ep_out[i].type = INVALID_EP_TYPE;
1132 }
a0b5fece 1133
65360511 1134 if (s->dev.configuration == 0) {
eb7700bb
GH
1135 /* not configured yet -- leave all endpoints disabled */
1136 return 0;
1137 }
71d71bbd 1138
b9dc033c
AZ
1139 /* get the desired configuration, interface, and endpoint descriptors
1140 * from device description */
1141 descriptors = &s->descr[18];
1142 length = s->descr_len - 18;
1143 i = 0;
1144
b9dc033c 1145 while (i < length) {
7279a85f
CBB
1146 if (descriptors[i + 1] != USB_DT_CONFIG) {
1147 fprintf(stderr, "invalid descriptor data\n");
1148 return 1;
65360511
GH
1149 } else if (descriptors[i + 5] != s->dev.configuration) {
1150 DPRINTF("not requested configuration %d\n", s->dev.configuration);
7279a85f
CBB
1151 i += (descriptors[i + 3] << 8) + descriptors[i + 2];
1152 continue;
1153 }
7279a85f
CBB
1154 i += descriptors[i];
1155
b9dc033c
AZ
1156 if (descriptors[i + 1] != USB_DT_INTERFACE ||
1157 (descriptors[i + 1] == USB_DT_INTERFACE &&
1158 descriptors[i + 4] == 0)) {
1159 i += descriptors[i];
1160 continue;
1161 }
1162
1163 interface = descriptors[i + 2];
65360511 1164 alt_interface = usb_linux_get_alt_setting(s, s->dev.configuration,
eb7700bb 1165 interface);
b9dc033c
AZ
1166
1167 /* the current interface descriptor is the active interface
1168 * and has endpoints */
1169 if (descriptors[i + 3] != alt_interface) {
1170 i += descriptors[i];
1171 continue;
1172 }
1173
1174 /* advance to the endpoints */
2791104c 1175 while (i < length && descriptors[i +1] != USB_DT_ENDPOINT) {
b9dc033c 1176 i += descriptors[i];
2791104c 1177 }
b9dc033c
AZ
1178
1179 if (i >= length)
1180 break;
1181
1182 while (i < length) {
2791104c 1183 if (descriptors[i + 1] != USB_DT_ENDPOINT) {
b9dc033c 1184 break;
2791104c 1185 }
b9dc033c
AZ
1186
1187 devep = descriptors[i + 2];
c0e5750b
GH
1188 pid = (devep & USB_DIR_IN) ? USB_TOKEN_IN : USB_TOKEN_OUT;
1189 ep = devep & 0xf;
1190 if (ep == 0) {
130314f8
HG
1191 fprintf(stderr, "usb-linux: invalid ep descriptor, ep == 0\n");
1192 return 1;
1193 }
1194
b9dc033c
AZ
1195 switch (descriptors[i + 3] & 0x3) {
1196 case 0x00:
1197 type = USBDEVFS_URB_TYPE_CONTROL;
1198 break;
1199 case 0x01:
1200 type = USBDEVFS_URB_TYPE_ISO;
c0e5750b 1201 set_max_packet_size(s, pid, ep, descriptors + i);
b9dc033c
AZ
1202 break;
1203 case 0x02:
1204 type = USBDEVFS_URB_TYPE_BULK;
1205 break;
1206 case 0x03:
1207 type = USBDEVFS_URB_TYPE_INTERRUPT;
1208 break;
ddbda432
AL
1209 default:
1210 DPRINTF("usb_host: malformed endpoint type\n");
1211 type = USBDEVFS_URB_TYPE_BULK;
b9dc033c 1212 }
c0e5750b
GH
1213 epd = get_endp(s, pid, ep);
1214 assert(epd->type == INVALID_EP_TYPE);
1215 epd->type = type;
1216 epd->halted = 0;
b9dc033c
AZ
1217
1218 i += descriptors[i];
1219 }
1220 }
1221 return 0;
1222}
1223
e4b17767
HG
1224/*
1225 * Check if we can safely redirect a usb2 device to a usb1 virtual controller,
1226 * this function assumes this is safe, if:
1227 * 1) There are no isoc endpoints
1228 * 2) There are no interrupt endpoints with a max_packet_size > 64
1229 * Note bulk endpoints with a max_packet_size > 64 in theory also are not
1230 * usb1 compatible, but in practice this seems to work fine.
1231 */
1232static int usb_linux_full_speed_compat(USBHostDevice *dev)
1233{
1234 int i, packet_size;
1235
1236 /*
1237 * usb_linux_update_endp_table only registers info about ep in the current
1238 * interface altsettings, so we need to parse the descriptors again.
1239 */
1240 for (i = 0; (i + 5) < dev->descr_len; i += dev->descr[i]) {
1241 if (dev->descr[i + 1] == USB_DT_ENDPOINT) {
1242 switch (dev->descr[i + 3] & 0x3) {
1243 case 0x00: /* CONTROL */
1244 break;
1245 case 0x01: /* ISO */
1246 return 0;
1247 case 0x02: /* BULK */
1248 break;
1249 case 0x03: /* INTERRUPT */
1250 packet_size = dev->descr[i + 4] + (dev->descr[i + 5] << 8);
1251 if (packet_size > 64)
1252 return 0;
1253 break;
1254 }
1255 }
1256 }
1257 return 1;
1258}
1259
26a9e82a 1260static int usb_host_open(USBHostDevice *dev, int bus_num,
ba9acab9
GH
1261 int addr, const char *port,
1262 const char *prod_name, int speed)
bb36d470 1263{
b9dc033c 1264 int fd = -1, ret;
1f3870ab 1265
e6a2f500
GH
1266 trace_usb_host_open_started(bus_num, addr);
1267
2791104c 1268 if (dev->fd != -1) {
26a9e82a 1269 goto fail;
2791104c 1270 }
3b46e624 1271
097db438 1272 fd = usb_host_open_device(bus_num, addr);
bb36d470 1273 if (fd < 0) {
1f3870ab 1274 goto fail;
bb36d470 1275 }
d0f2c4c6 1276 DPRINTF("husb: opened %s\n", buf);
bb36d470 1277
806b6024
GH
1278 dev->bus_num = bus_num;
1279 dev->addr = addr;
5557d820 1280 strcpy(dev->port, port);
22f84e73 1281 dev->fd = fd;
806b6024 1282
b9dc033c
AZ
1283 /* read the device description */
1284 dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
1285 if (dev->descr_len <= 0) {
64838171 1286 perror("husb: reading device data failed");
bb36d470
FB
1287 goto fail;
1288 }
3b46e624 1289
b9dc033c 1290#ifdef DEBUG
868bfe2b 1291 {
b9dc033c
AZ
1292 int x;
1293 printf("=== begin dumping device descriptor data ===\n");
2791104c 1294 for (x = 0; x < dev->descr_len; x++) {
b9dc033c 1295 printf("%02x ", dev->descr[x]);
2791104c 1296 }
b9dc033c 1297 printf("\n=== end dumping device descriptor data ===\n");
bb36d470 1298 }
a594cfbf
FB
1299#endif
1300
b9dc033c 1301
eb7700bb
GH
1302 /* start unconfigured -- we'll wait for the guest to set a configuration */
1303 if (!usb_host_claim_interfaces(dev, 0)) {
b9dc033c 1304 goto fail;
2791104c 1305 }
bb36d470 1306
b9dc033c 1307 ret = usb_linux_update_endp_table(dev);
2791104c 1308 if (ret) {
bb36d470 1309 goto fail;
2791104c 1310 }
b9dc033c 1311
3991c35e
HG
1312 if (speed == -1) {
1313 struct usbdevfs_connectinfo ci;
1314
1315 ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
1316 if (ret < 0) {
1317 perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
1318 goto fail;
1319 }
1320
1321 if (ci.slow) {
1322 speed = USB_SPEED_LOW;
1323 } else {
1324 speed = USB_SPEED_HIGH;
1325 }
2791104c 1326 }
3991c35e 1327 dev->dev.speed = speed;
ba3f9bfb 1328 dev->dev.speedmask = (1 << speed);
e4b17767
HG
1329 if (dev->dev.speed == USB_SPEED_HIGH && usb_linux_full_speed_compat(dev)) {
1330 dev->dev.speedmask |= USB_SPEED_MASK_FULL;
1331 }
3991c35e 1332
e6a2f500 1333 trace_usb_host_open_success(bus_num, addr);
bb36d470 1334
2791104c 1335 if (!prod_name || prod_name[0] == '\0') {
0fe6d12e 1336 snprintf(dev->dev.product_desc, sizeof(dev->dev.product_desc),
4b096fc9 1337 "host:%d.%d", bus_num, addr);
2791104c 1338 } else {
0fe6d12e 1339 pstrcpy(dev->dev.product_desc, sizeof(dev->dev.product_desc),
4b096fc9 1340 prod_name);
2791104c 1341 }
1f6e24e7 1342
fa19bf83
HG
1343 ret = usb_device_attach(&dev->dev);
1344 if (ret) {
1345 goto fail;
1346 }
1347
64838171
AL
1348 /* USB devio uses 'write' flag to check for async completions */
1349 qemu_set_fd_handler(dev->fd, NULL, async_complete, dev);
1f3870ab 1350
26a9e82a 1351 return 0;
4b096fc9 1352
b9dc033c 1353fail:
e6a2f500 1354 trace_usb_host_open_failure(bus_num, addr);
1f45a81b
GH
1355 if (dev->fd != -1) {
1356 close(dev->fd);
1357 dev->fd = -1;
2791104c 1358 }
26a9e82a
GH
1359 return -1;
1360}
1361
1362static int usb_host_close(USBHostDevice *dev)
1363{
060dc841
HG
1364 int i;
1365
39fba3ad 1366 if (dev->fd == -1) {
26a9e82a 1367 return -1;
2791104c 1368 }
26a9e82a 1369
e6a2f500
GH
1370 trace_usb_host_close(dev->bus_num, dev->addr);
1371
26a9e82a
GH
1372 qemu_set_fd_handler(dev->fd, NULL, NULL, NULL);
1373 dev->closing = 1;
3a4854b3 1374 for (i = 1; i <= MAX_ENDPOINTS; i++) {
c0e5750b
GH
1375 if (is_isoc(dev, USB_TOKEN_IN, i)) {
1376 usb_host_stop_n_free_iso(dev, USB_TOKEN_IN, i);
1377 }
1378 if (is_isoc(dev, USB_TOKEN_OUT, i)) {
1379 usb_host_stop_n_free_iso(dev, USB_TOKEN_OUT, i);
060dc841
HG
1380 }
1381 }
26a9e82a
GH
1382 async_complete(dev);
1383 dev->closing = 0;
39fba3ad
GH
1384 if (dev->dev.attached) {
1385 usb_device_detach(&dev->dev);
1386 }
c7662daa 1387 usb_host_do_reset(dev);
26a9e82a
GH
1388 close(dev->fd);
1389 dev->fd = -1;
1390 return 0;
1391}
1392
9e8dd451 1393static void usb_host_exit_notifier(struct Notifier *n, void *data)
b373a63a
SH
1394{
1395 USBHostDevice *s = container_of(n, USBHostDevice, exit);
1396
c75fead6 1397 usb_host_release_port(s);
b373a63a 1398 if (s->fd != -1) {
c7662daa 1399 usb_host_do_reset(s);;
b373a63a
SH
1400 }
1401}
1402
26a9e82a
GH
1403static int usb_host_initfn(USBDevice *dev)
1404{
1405 USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
1406
1407 dev->auto_attach = 0;
1408 s->fd = -1;
9516bb47
GH
1409 s->hub_fd = -1;
1410
26a9e82a 1411 QTAILQ_INSERT_TAIL(&hostdevs, s, next);
b373a63a
SH
1412 s->exit.notify = usb_host_exit_notifier;
1413 qemu_add_exit_notifier(&s->exit);
26a9e82a 1414 usb_host_auto_check(NULL);
9516bb47 1415
9516bb47 1416 if (s->match.bus_num != 0 && s->match.port != NULL) {
e6274727 1417 usb_host_claim_port(s);
9516bb47 1418 }
26a9e82a 1419 return 0;
a594cfbf 1420}
bb36d470 1421
d6791578
GH
1422static const VMStateDescription vmstate_usb_host = {
1423 .name = "usb-host",
1424 .unmigratable = 1,
1425};
1426
806b6024 1427static struct USBDeviceInfo usb_host_dev_info = {
06384698 1428 .product_desc = "USB Host Device",
556cd098 1429 .qdev.name = "usb-host",
806b6024 1430 .qdev.size = sizeof(USBHostDevice),
d6791578 1431 .qdev.vmsd = &vmstate_usb_host,
806b6024 1432 .init = usb_host_initfn,
50b7963e 1433 .handle_packet = usb_generic_handle_packet,
eb5e680a 1434 .cancel_packet = usb_host_async_cancel,
50b7963e
HG
1435 .handle_data = usb_host_handle_data,
1436 .handle_control = usb_host_handle_control,
806b6024 1437 .handle_reset = usb_host_handle_reset,
806b6024 1438 .handle_destroy = usb_host_handle_destroy,
26a9e82a
GH
1439 .usbdevice_name = "host",
1440 .usbdevice_init = usb_host_device_open,
1441 .qdev.props = (Property[]) {
1442 DEFINE_PROP_UINT32("hostbus", USBHostDevice, match.bus_num, 0),
1443 DEFINE_PROP_UINT32("hostaddr", USBHostDevice, match.addr, 0),
9056a297 1444 DEFINE_PROP_STRING("hostport", USBHostDevice, match.port),
26a9e82a
GH
1445 DEFINE_PROP_HEX32("vendorid", USBHostDevice, match.vendor_id, 0),
1446 DEFINE_PROP_HEX32("productid", USBHostDevice, match.product_id, 0),
b81bcd8a 1447 DEFINE_PROP_UINT32("isobufs", USBHostDevice, iso_urb_count, 4),
26a9e82a
GH
1448 DEFINE_PROP_END_OF_LIST(),
1449 },
806b6024
GH
1450};
1451
1452static void usb_host_register_devices(void)
1453{
1454 usb_qdev_register(&usb_host_dev_info);
1455}
1456device_init(usb_host_register_devices)
1457
4b096fc9
AL
1458USBDevice *usb_host_device_open(const char *devname)
1459{
0745eb1e 1460 struct USBAutoFilter filter;
26a9e82a 1461 USBDevice *dev;
26a9e82a
GH
1462 char *p;
1463
556cd098 1464 dev = usb_create(NULL /* FIXME */, "usb-host");
4b096fc9 1465
5d0c5750 1466 if (strstr(devname, "auto:")) {
2791104c 1467 if (parse_filter(devname, &filter) < 0) {
26a9e82a 1468 goto fail;
2791104c 1469 }
26a9e82a
GH
1470 } else {
1471 if ((p = strchr(devname, '.'))) {
0745eb1e
MA
1472 filter.bus_num = strtoul(devname, NULL, 0);
1473 filter.addr = strtoul(p + 1, NULL, 0);
1474 filter.vendor_id = 0;
1475 filter.product_id = 0;
26a9e82a 1476 } else if ((p = strchr(devname, ':'))) {
0745eb1e
MA
1477 filter.bus_num = 0;
1478 filter.addr = 0;
26a9e82a 1479 filter.vendor_id = strtoul(devname, NULL, 16);
0745eb1e 1480 filter.product_id = strtoul(p + 1, NULL, 16);
26a9e82a
GH
1481 } else {
1482 goto fail;
1483 }
5d0c5750 1484 }
4b096fc9 1485
0745eb1e
MA
1486 qdev_prop_set_uint32(&dev->qdev, "hostbus", filter.bus_num);
1487 qdev_prop_set_uint32(&dev->qdev, "hostaddr", filter.addr);
26a9e82a
GH
1488 qdev_prop_set_uint32(&dev->qdev, "vendorid", filter.vendor_id);
1489 qdev_prop_set_uint32(&dev->qdev, "productid", filter.product_id);
beb6f0de 1490 qdev_init_nofail(&dev->qdev);
26a9e82a 1491 return dev;
5d0c5750 1492
26a9e82a
GH
1493fail:
1494 qdev_free(&dev->qdev);
1495 return NULL;
4b096fc9 1496}
5d0c5750
AL
1497
1498int usb_host_device_close(const char *devname)
1499{
26a9e82a 1500#if 0
5d0c5750
AL
1501 char product_name[PRODUCT_NAME_SZ];
1502 int bus_num, addr;
1503 USBHostDevice *s;
1504
2791104c 1505 if (strstr(devname, "auto:")) {
5d0c5750 1506 return usb_host_auto_del(devname);
2791104c
DA
1507 }
1508 if (usb_host_find_device(&bus_num, &addr, product_name,
1509 sizeof(product_name), devname) < 0) {
5d0c5750 1510 return -1;
2791104c 1511 }
5d0c5750
AL
1512 s = hostdev_find(bus_num, addr);
1513 if (s) {
a5d2f727 1514 usb_device_delete_addr(s->bus_num, s->dev.addr);
5d0c5750
AL
1515 return 0;
1516 }
26a9e82a 1517#endif
5d0c5750
AL
1518
1519 return -1;
1520}
a5d2f727 1521
0f431527
AL
1522/*
1523 * Read sys file-system device file
1524 *
1525 * @line address of buffer to put file contents in
1526 * @line_size size of line
1527 * @device_file path to device file (printf format string)
1528 * @device_name device being opened (inserted into device_file)
1529 *
1530 * @return 0 failed, 1 succeeded ('line' contains data)
1531 */
2791104c
DA
1532static int usb_host_read_file(char *line, size_t line_size,
1533 const char *device_file, const char *device_name)
0f431527
AL
1534{
1535 FILE *f;
1536 int ret = 0;
1537 char filename[PATH_MAX];
1538
097db438 1539 snprintf(filename, PATH_MAX, "/sys/bus/usb/devices/%s/%s", device_name,
b4e237aa 1540 device_file);
0f431527
AL
1541 f = fopen(filename, "r");
1542 if (f) {
9f99cee7 1543 ret = fgets(line, line_size, f) != NULL;
0f431527 1544 fclose(f);
0f431527
AL
1545 }
1546
1547 return ret;
1548}
1549
1550/*
1551 * Use /sys/bus/usb/devices/ directory to determine host's USB
1552 * devices.
1553 *
1554 * This code is based on Robert Schiele's original patches posted to
1555 * the Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
1556 */
097db438 1557static int usb_host_scan(void *opaque, USBScanFunc *func)
0f431527 1558{
660f11be 1559 DIR *dir = NULL;
0f431527 1560 char line[1024];
5557d820 1561 int bus_num, addr, speed, class_id, product_id, vendor_id;
0f431527 1562 int ret = 0;
5557d820 1563 char port[MAX_PORTLEN];
0f431527
AL
1564 char product_name[512];
1565 struct dirent *de;
1566
097db438 1567 dir = opendir("/sys/bus/usb/devices");
0f431527 1568 if (!dir) {
097db438
GH
1569 perror("husb: opendir /sys/bus/usb/devices");
1570 fprintf(stderr, "husb: please make sure sysfs is mounted at /sys\n");
0f431527
AL
1571 goto the_end;
1572 }
1573
1574 while ((de = readdir(dir))) {
1575 if (de->d_name[0] != '.' && !strchr(de->d_name, ':')) {
5557d820
GH
1576 if (sscanf(de->d_name, "%d-%7[0-9.]", &bus_num, port) < 2) {
1577 continue;
0f5160d1 1578 }
0f431527 1579
2791104c 1580 if (!usb_host_read_file(line, sizeof(line), "devnum", de->d_name)) {
0f431527 1581 goto the_end;
2791104c
DA
1582 }
1583 if (sscanf(line, "%d", &addr) != 1) {
0f431527 1584 goto the_end;
2791104c 1585 }
b4e237aa 1586 if (!usb_host_read_file(line, sizeof(line), "bDeviceClass",
2791104c 1587 de->d_name)) {
0f431527 1588 goto the_end;
2791104c
DA
1589 }
1590 if (sscanf(line, "%x", &class_id) != 1) {
0f431527 1591 goto the_end;
2791104c 1592 }
0f431527 1593
2791104c
DA
1594 if (!usb_host_read_file(line, sizeof(line), "idVendor",
1595 de->d_name)) {
0f431527 1596 goto the_end;
2791104c
DA
1597 }
1598 if (sscanf(line, "%x", &vendor_id) != 1) {
0f431527 1599 goto the_end;
2791104c 1600 }
b4e237aa 1601 if (!usb_host_read_file(line, sizeof(line), "idProduct",
2791104c 1602 de->d_name)) {
0f431527 1603 goto the_end;
2791104c
DA
1604 }
1605 if (sscanf(line, "%x", &product_id) != 1) {
0f431527 1606 goto the_end;
2791104c 1607 }
b4e237aa
BS
1608 if (!usb_host_read_file(line, sizeof(line), "product",
1609 de->d_name)) {
0f431527
AL
1610 *product_name = 0;
1611 } else {
2791104c 1612 if (strlen(line) > 0) {
0f431527 1613 line[strlen(line) - 1] = '\0';
2791104c 1614 }
0f431527
AL
1615 pstrcpy(product_name, sizeof(product_name), line);
1616 }
1617
2791104c 1618 if (!usb_host_read_file(line, sizeof(line), "speed", de->d_name)) {
0f431527 1619 goto the_end;
2791104c 1620 }
f264cfbf
HG
1621 if (!strcmp(line, "5000\n")) {
1622 speed = USB_SPEED_SUPER;
1623 } else if (!strcmp(line, "480\n")) {
0f431527 1624 speed = USB_SPEED_HIGH;
2791104c 1625 } else if (!strcmp(line, "1.5\n")) {
0f431527 1626 speed = USB_SPEED_LOW;
2791104c 1627 } else {
0f431527 1628 speed = USB_SPEED_FULL;
2791104c 1629 }
0f431527 1630
5557d820 1631 ret = func(opaque, bus_num, addr, port, class_id, vendor_id,
0f431527 1632 product_id, product_name, speed);
2791104c 1633 if (ret) {
0f431527 1634 goto the_end;
2791104c 1635 }
0f431527
AL
1636 }
1637 }
1638 the_end:
2791104c 1639 if (dir) {
0f431527 1640 closedir(dir);
2791104c 1641 }
0f431527
AL
1642 return ret;
1643}
1644
4b096fc9 1645static QEMUTimer *usb_auto_timer;
4b096fc9 1646
ba9acab9
GH
1647static int usb_host_auto_scan(void *opaque, int bus_num,
1648 int addr, const char *port,
26a9e82a
GH
1649 int class_id, int vendor_id, int product_id,
1650 const char *product_name, int speed)
4b096fc9
AL
1651{
1652 struct USBAutoFilter *f;
26a9e82a 1653 struct USBHostDevice *s;
4b096fc9
AL
1654
1655 /* Ignore hubs */
1656 if (class_id == 9)
1657 return 0;
1658
26a9e82a
GH
1659 QTAILQ_FOREACH(s, &hostdevs, next) {
1660 f = &s->match;
1661
2791104c 1662 if (f->bus_num > 0 && f->bus_num != bus_num) {
4b096fc9 1663 continue;
2791104c
DA
1664 }
1665 if (f->addr > 0 && f->addr != addr) {
4b096fc9 1666 continue;
2791104c 1667 }
9056a297
GH
1668 if (f->port != NULL && (port == NULL || strcmp(f->port, port) != 0)) {
1669 continue;
1670 }
4b096fc9 1671
2791104c 1672 if (f->vendor_id > 0 && f->vendor_id != vendor_id) {
4b096fc9 1673 continue;
2791104c 1674 }
4b096fc9 1675
2791104c 1676 if (f->product_id > 0 && f->product_id != product_id) {
4b096fc9 1677 continue;
2791104c 1678 }
4b096fc9 1679 /* We got a match */
3ee886c5
GH
1680 s->seen++;
1681 if (s->errcount >= 3) {
1682 return 0;
1683 }
4b096fc9 1684
33e66b86 1685 /* Already attached ? */
2791104c 1686 if (s->fd != -1) {
4b096fc9 1687 return 0;
2791104c 1688 }
d0f2c4c6 1689 DPRINTF("husb: auto open: bus_num %d addr %d\n", bus_num, addr);
4b096fc9 1690
3ee886c5
GH
1691 if (usb_host_open(s, bus_num, addr, port, product_name, speed) < 0) {
1692 s->errcount++;
1693 }
97f86166 1694 break;
4b096fc9
AL
1695 }
1696
1697 return 0;
1698}
1699
26a9e82a 1700static void usb_host_auto_check(void *unused)
4b096fc9 1701{
26a9e82a
GH
1702 struct USBHostDevice *s;
1703 int unconnected = 0;
1704
4b096fc9 1705 usb_host_scan(NULL, usb_host_auto_scan);
26a9e82a
GH
1706
1707 QTAILQ_FOREACH(s, &hostdevs, next) {
2791104c 1708 if (s->fd == -1) {
26a9e82a 1709 unconnected++;
2791104c 1710 }
3ee886c5
GH
1711 if (s->seen == 0) {
1712 s->errcount = 0;
1713 }
1714 s->seen = 0;
26a9e82a
GH
1715 }
1716
1717 if (unconnected == 0) {
1718 /* nothing to watch */
2791104c 1719 if (usb_auto_timer) {
26a9e82a 1720 qemu_del_timer(usb_auto_timer);
e6a2f500 1721 trace_usb_host_auto_scan_disabled();
2791104c 1722 }
26a9e82a
GH
1723 return;
1724 }
1725
1726 if (!usb_auto_timer) {
7bd427d8 1727 usb_auto_timer = qemu_new_timer_ms(rt_clock, usb_host_auto_check, NULL);
2791104c 1728 if (!usb_auto_timer) {
26a9e82a 1729 return;
2791104c 1730 }
e6a2f500 1731 trace_usb_host_auto_scan_enabled();
26a9e82a 1732 }
7bd427d8 1733 qemu_mod_timer(usb_auto_timer, qemu_get_clock_ms(rt_clock) + 2000);
4b096fc9
AL
1734}
1735
1736/*
5d0c5750
AL
1737 * Autoconnect filter
1738 * Format:
1739 * auto:bus:dev[:vid:pid]
1740 * auto:bus.dev[:vid:pid]
1741 *
1742 * bus - bus number (dec, * means any)
1743 * dev - device number (dec, * means any)
1744 * vid - vendor id (hex, * means any)
1745 * pid - product id (hex, * means any)
1746 *
1747 * See 'lsusb' output.
4b096fc9 1748 */
5d0c5750 1749static int parse_filter(const char *spec, struct USBAutoFilter *f)
4b096fc9 1750{
5d0c5750
AL
1751 enum { BUS, DEV, VID, PID, DONE };
1752 const char *p = spec;
1753 int i;
1754
0745eb1e
MA
1755 f->bus_num = 0;
1756 f->addr = 0;
1757 f->vendor_id = 0;
1758 f->product_id = 0;
5d0c5750
AL
1759
1760 for (i = BUS; i < DONE; i++) {
2791104c
DA
1761 p = strpbrk(p, ":.");
1762 if (!p) {
1763 break;
1764 }
5d0c5750 1765 p++;
5d0c5750 1766
2791104c
DA
1767 if (*p == '*') {
1768 continue;
1769 }
5d0c5750
AL
1770 switch(i) {
1771 case BUS: f->bus_num = strtol(p, NULL, 10); break;
1772 case DEV: f->addr = strtol(p, NULL, 10); break;
1773 case VID: f->vendor_id = strtol(p, NULL, 16); break;
1774 case PID: f->product_id = strtol(p, NULL, 16); break;
1775 }
1776 }
1777
1778 if (i < DEV) {
1779 fprintf(stderr, "husb: invalid auto filter spec %s\n", spec);
1780 return -1;
1781 }
1782
1783 return 0;
1784}
1785
a594cfbf
FB
1786/**********************/
1787/* USB host device info */
1788
1789struct usb_class_info {
1790 int class;
1791 const char *class_name;
1792};
1793
1794static const struct usb_class_info usb_class_info[] = {
1795 { USB_CLASS_AUDIO, "Audio"},
1796 { USB_CLASS_COMM, "Communication"},
1797 { USB_CLASS_HID, "HID"},
1798 { USB_CLASS_HUB, "Hub" },
1799 { USB_CLASS_PHYSICAL, "Physical" },
1800 { USB_CLASS_PRINTER, "Printer" },
1801 { USB_CLASS_MASS_STORAGE, "Storage" },
1802 { USB_CLASS_CDC_DATA, "Data" },
1803 { USB_CLASS_APP_SPEC, "Application Specific" },
1804 { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
1805 { USB_CLASS_STILL_IMAGE, "Still Image" },
b9dc033c 1806 { USB_CLASS_CSCID, "Smart Card" },
a594cfbf
FB
1807 { USB_CLASS_CONTENT_SEC, "Content Security" },
1808 { -1, NULL }
1809};
1810
1811static const char *usb_class_str(uint8_t class)
bb36d470 1812{
a594cfbf
FB
1813 const struct usb_class_info *p;
1814 for(p = usb_class_info; p->class != -1; p++) {
2791104c 1815 if (p->class == class) {
a594cfbf 1816 break;
2791104c 1817 }
bb36d470 1818 }
a594cfbf
FB
1819 return p->class_name;
1820}
1821
ba9acab9
GH
1822static void usb_info_device(Monitor *mon, int bus_num,
1823 int addr, const char *port,
5557d820 1824 int class_id, int vendor_id, int product_id,
9596ebb7
PB
1825 const char *product_name,
1826 int speed)
a594cfbf
FB
1827{
1828 const char *class_str, *speed_str;
1829
1830 switch(speed) {
5fafdf24
TS
1831 case USB_SPEED_LOW:
1832 speed_str = "1.5";
a594cfbf 1833 break;
5fafdf24
TS
1834 case USB_SPEED_FULL:
1835 speed_str = "12";
a594cfbf 1836 break;
5fafdf24
TS
1837 case USB_SPEED_HIGH:
1838 speed_str = "480";
a594cfbf 1839 break;
f264cfbf
HG
1840 case USB_SPEED_SUPER:
1841 speed_str = "5000";
1842 break;
a594cfbf 1843 default:
5fafdf24 1844 speed_str = "?";
a594cfbf
FB
1845 break;
1846 }
1847
5557d820
GH
1848 monitor_printf(mon, " Bus %d, Addr %d, Port %s, Speed %s Mb/s\n",
1849 bus_num, addr, port, speed_str);
a594cfbf 1850 class_str = usb_class_str(class_id);
2791104c 1851 if (class_str) {
376253ec 1852 monitor_printf(mon, " %s:", class_str);
2791104c 1853 } else {
376253ec 1854 monitor_printf(mon, " Class %02x:", class_id);
2791104c 1855 }
376253ec 1856 monitor_printf(mon, " USB device %04x:%04x", vendor_id, product_id);
2791104c 1857 if (product_name[0] != '\0') {
376253ec 1858 monitor_printf(mon, ", %s", product_name);
2791104c 1859 }
376253ec 1860 monitor_printf(mon, "\n");
a594cfbf
FB
1861}
1862
5fafdf24 1863static int usb_host_info_device(void *opaque, int bus_num, int addr,
ba9acab9 1864 const char *path, int class_id,
5fafdf24 1865 int vendor_id, int product_id,
a594cfbf
FB
1866 const char *product_name,
1867 int speed)
1868{
179da8af
BS
1869 Monitor *mon = opaque;
1870
5557d820 1871 usb_info_device(mon, bus_num, addr, path, class_id, vendor_id, product_id,
a594cfbf
FB
1872 product_name, speed);
1873 return 0;
1874}
1875
ac4ffb5a 1876static void dec2str(int val, char *str, size_t size)
5d0c5750 1877{
2791104c 1878 if (val == 0) {
ac4ffb5a 1879 snprintf(str, size, "*");
2791104c
DA
1880 } else {
1881 snprintf(str, size, "%d", val);
1882 }
5d0c5750
AL
1883}
1884
ac4ffb5a 1885static void hex2str(int val, char *str, size_t size)
5d0c5750 1886{
2791104c 1887 if (val == 0) {
ac4ffb5a 1888 snprintf(str, size, "*");
2791104c 1889 } else {
26a9e82a 1890 snprintf(str, size, "%04x", val);
2791104c 1891 }
5d0c5750
AL
1892}
1893
376253ec 1894void usb_host_info(Monitor *mon)
a594cfbf 1895{
5d0c5750 1896 struct USBAutoFilter *f;
26a9e82a 1897 struct USBHostDevice *s;
5d0c5750 1898
179da8af 1899 usb_host_scan(mon, usb_host_info_device);
5d0c5750 1900
2791104c 1901 if (QTAILQ_EMPTY(&hostdevs)) {
26a9e82a 1902 return;
2791104c
DA
1903 }
1904
26a9e82a
GH
1905 monitor_printf(mon, " Auto filters:\n");
1906 QTAILQ_FOREACH(s, &hostdevs, next) {
5d0c5750 1907 char bus[10], addr[10], vid[10], pid[10];
26a9e82a 1908 f = &s->match;
ac4ffb5a
AL
1909 dec2str(f->bus_num, bus, sizeof(bus));
1910 dec2str(f->addr, addr, sizeof(addr));
1911 hex2str(f->vendor_id, vid, sizeof(vid));
1912 hex2str(f->product_id, pid, sizeof(pid));
9056a297
GH
1913 monitor_printf(mon, " Bus %s, Addr %s, Port %s, ID %s:%s\n",
1914 bus, addr, f->port ? f->port : "*", vid, pid);
5d0c5750 1915 }
bb36d470 1916}