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