]> Git Repo - qemu.git/blame - usb-linux.c
usb: add USB_RET_IOERROR
[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 <[email protected]>
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);
d8e17efd 1195
c0e5750b 1196 epd = get_endp(s, pid, ep);
c0e5750b 1197 epd->halted = 0;
b9dc033c
AZ
1198
1199 i += descriptors[i];
1200 }
1201 }
5b6780d0
GH
1202#ifdef DEBUG
1203 usb_ep_dump(&s->dev);
1204#endif
b9dc033c
AZ
1205 return 0;
1206}
1207
e4b17767
HG
1208/*
1209 * Check if we can safely redirect a usb2 device to a usb1 virtual controller,
1210 * this function assumes this is safe, if:
1211 * 1) There are no isoc endpoints
1212 * 2) There are no interrupt endpoints with a max_packet_size > 64
1213 * Note bulk endpoints with a max_packet_size > 64 in theory also are not
1214 * usb1 compatible, but in practice this seems to work fine.
1215 */
1216static int usb_linux_full_speed_compat(USBHostDevice *dev)
1217{
1218 int i, packet_size;
1219
1220 /*
1221 * usb_linux_update_endp_table only registers info about ep in the current
1222 * interface altsettings, so we need to parse the descriptors again.
1223 */
1224 for (i = 0; (i + 5) < dev->descr_len; i += dev->descr[i]) {
1225 if (dev->descr[i + 1] == USB_DT_ENDPOINT) {
1226 switch (dev->descr[i + 3] & 0x3) {
1227 case 0x00: /* CONTROL */
1228 break;
1229 case 0x01: /* ISO */
1230 return 0;
1231 case 0x02: /* BULK */
1232 break;
1233 case 0x03: /* INTERRUPT */
1234 packet_size = dev->descr[i + 4] + (dev->descr[i + 5] << 8);
1235 if (packet_size > 64)
1236 return 0;
1237 break;
1238 }
1239 }
1240 }
1241 return 1;
1242}
1243
26a9e82a 1244static int usb_host_open(USBHostDevice *dev, int bus_num,
ba9acab9
GH
1245 int addr, const char *port,
1246 const char *prod_name, int speed)
bb36d470 1247{
b9dc033c 1248 int fd = -1, ret;
1f3870ab 1249
e6a2f500
GH
1250 trace_usb_host_open_started(bus_num, addr);
1251
2791104c 1252 if (dev->fd != -1) {
26a9e82a 1253 goto fail;
2791104c 1254 }
3b46e624 1255
097db438 1256 fd = usb_host_open_device(bus_num, addr);
bb36d470 1257 if (fd < 0) {
1f3870ab 1258 goto fail;
bb36d470 1259 }
d0f2c4c6 1260 DPRINTF("husb: opened %s\n", buf);
bb36d470 1261
806b6024
GH
1262 dev->bus_num = bus_num;
1263 dev->addr = addr;
5557d820 1264 strcpy(dev->port, port);
22f84e73 1265 dev->fd = fd;
806b6024 1266
b9dc033c
AZ
1267 /* read the device description */
1268 dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
1269 if (dev->descr_len <= 0) {
64838171 1270 perror("husb: reading device data failed");
bb36d470
FB
1271 goto fail;
1272 }
3b46e624 1273
b9dc033c 1274#ifdef DEBUG
868bfe2b 1275 {
b9dc033c
AZ
1276 int x;
1277 printf("=== begin dumping device descriptor data ===\n");
2791104c 1278 for (x = 0; x < dev->descr_len; x++) {
b9dc033c 1279 printf("%02x ", dev->descr[x]);
2791104c 1280 }
b9dc033c 1281 printf("\n=== end dumping device descriptor data ===\n");
bb36d470 1282 }
a594cfbf
FB
1283#endif
1284
b9dc033c 1285
eb7700bb
GH
1286 /* start unconfigured -- we'll wait for the guest to set a configuration */
1287 if (!usb_host_claim_interfaces(dev, 0)) {
b9dc033c 1288 goto fail;
2791104c 1289 }
bb36d470 1290
b9dc033c 1291 ret = usb_linux_update_endp_table(dev);
2791104c 1292 if (ret) {
bb36d470 1293 goto fail;
2791104c 1294 }
b9dc033c 1295
3991c35e
HG
1296 if (speed == -1) {
1297 struct usbdevfs_connectinfo ci;
1298
1299 ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
1300 if (ret < 0) {
1301 perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
1302 goto fail;
1303 }
1304
1305 if (ci.slow) {
1306 speed = USB_SPEED_LOW;
1307 } else {
1308 speed = USB_SPEED_HIGH;
1309 }
2791104c 1310 }
3991c35e 1311 dev->dev.speed = speed;
ba3f9bfb 1312 dev->dev.speedmask = (1 << speed);
e4b17767
HG
1313 if (dev->dev.speed == USB_SPEED_HIGH && usb_linux_full_speed_compat(dev)) {
1314 dev->dev.speedmask |= USB_SPEED_MASK_FULL;
1315 }
3991c35e 1316
e6a2f500 1317 trace_usb_host_open_success(bus_num, addr);
bb36d470 1318
2791104c 1319 if (!prod_name || prod_name[0] == '\0') {
0fe6d12e 1320 snprintf(dev->dev.product_desc, sizeof(dev->dev.product_desc),
4b096fc9 1321 "host:%d.%d", bus_num, addr);
2791104c 1322 } else {
0fe6d12e 1323 pstrcpy(dev->dev.product_desc, sizeof(dev->dev.product_desc),
4b096fc9 1324 prod_name);
2791104c 1325 }
1f6e24e7 1326
fa19bf83
HG
1327 ret = usb_device_attach(&dev->dev);
1328 if (ret) {
1329 goto fail;
1330 }
1331
64838171
AL
1332 /* USB devio uses 'write' flag to check for async completions */
1333 qemu_set_fd_handler(dev->fd, NULL, async_complete, dev);
1f3870ab 1334
26a9e82a 1335 return 0;
4b096fc9 1336
b9dc033c 1337fail:
e6a2f500 1338 trace_usb_host_open_failure(bus_num, addr);
1f45a81b
GH
1339 if (dev->fd != -1) {
1340 close(dev->fd);
1341 dev->fd = -1;
2791104c 1342 }
26a9e82a
GH
1343 return -1;
1344}
1345
1346static int usb_host_close(USBHostDevice *dev)
1347{
060dc841
HG
1348 int i;
1349
39fba3ad 1350 if (dev->fd == -1) {
26a9e82a 1351 return -1;
2791104c 1352 }
26a9e82a 1353
e6a2f500
GH
1354 trace_usb_host_close(dev->bus_num, dev->addr);
1355
26a9e82a
GH
1356 qemu_set_fd_handler(dev->fd, NULL, NULL, NULL);
1357 dev->closing = 1;
d8e17efd 1358 for (i = 1; i <= USB_MAX_ENDPOINTS; i++) {
c0e5750b
GH
1359 if (is_isoc(dev, USB_TOKEN_IN, i)) {
1360 usb_host_stop_n_free_iso(dev, USB_TOKEN_IN, i);
1361 }
1362 if (is_isoc(dev, USB_TOKEN_OUT, i)) {
1363 usb_host_stop_n_free_iso(dev, USB_TOKEN_OUT, i);
060dc841
HG
1364 }
1365 }
26a9e82a
GH
1366 async_complete(dev);
1367 dev->closing = 0;
39fba3ad
GH
1368 if (dev->dev.attached) {
1369 usb_device_detach(&dev->dev);
1370 }
c7662daa 1371 usb_host_do_reset(dev);
26a9e82a
GH
1372 close(dev->fd);
1373 dev->fd = -1;
1374 return 0;
1375}
1376
9e8dd451 1377static void usb_host_exit_notifier(struct Notifier *n, void *data)
b373a63a
SH
1378{
1379 USBHostDevice *s = container_of(n, USBHostDevice, exit);
1380
c75fead6 1381 usb_host_release_port(s);
b373a63a 1382 if (s->fd != -1) {
c7662daa 1383 usb_host_do_reset(s);;
b373a63a
SH
1384 }
1385}
1386
26a9e82a
GH
1387static int usb_host_initfn(USBDevice *dev)
1388{
1389 USBHostDevice *s = DO_UPCAST(USBHostDevice, dev, dev);
1390
1391 dev->auto_attach = 0;
1392 s->fd = -1;
9516bb47
GH
1393 s->hub_fd = -1;
1394
26a9e82a 1395 QTAILQ_INSERT_TAIL(&hostdevs, s, next);
b373a63a
SH
1396 s->exit.notify = usb_host_exit_notifier;
1397 qemu_add_exit_notifier(&s->exit);
26a9e82a 1398 usb_host_auto_check(NULL);
9516bb47 1399
9516bb47 1400 if (s->match.bus_num != 0 && s->match.port != NULL) {
e6274727 1401 usb_host_claim_port(s);
9516bb47 1402 }
26a9e82a 1403 return 0;
a594cfbf 1404}
bb36d470 1405
d6791578
GH
1406static const VMStateDescription vmstate_usb_host = {
1407 .name = "usb-host",
1408 .unmigratable = 1,
1409};
1410
39bffca2
AL
1411static Property usb_host_dev_properties[] = {
1412 DEFINE_PROP_UINT32("hostbus", USBHostDevice, match.bus_num, 0),
1413 DEFINE_PROP_UINT32("hostaddr", USBHostDevice, match.addr, 0),
1414 DEFINE_PROP_STRING("hostport", USBHostDevice, match.port),
1415 DEFINE_PROP_HEX32("vendorid", USBHostDevice, match.vendor_id, 0),
1416 DEFINE_PROP_HEX32("productid", USBHostDevice, match.product_id, 0),
1417 DEFINE_PROP_UINT32("isobufs", USBHostDevice, iso_urb_count, 4),
1418 DEFINE_PROP_END_OF_LIST(),
1419};
1420
62aed765
AL
1421static void usb_host_class_initfn(ObjectClass *klass, void *data)
1422{
39bffca2 1423 DeviceClass *dc = DEVICE_CLASS(klass);
62aed765
AL
1424 USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
1425
1426 uc->init = usb_host_initfn;
1427 uc->product_desc = "USB Host Device";
62aed765
AL
1428 uc->cancel_packet = usb_host_async_cancel;
1429 uc->handle_data = usb_host_handle_data;
1430 uc->handle_control = usb_host_handle_control;
1431 uc->handle_reset = usb_host_handle_reset;
1432 uc->handle_destroy = usb_host_handle_destroy;
39bffca2
AL
1433 dc->vmsd = &vmstate_usb_host;
1434 dc->props = usb_host_dev_properties;
62aed765
AL
1435}
1436
39bffca2
AL
1437static TypeInfo usb_host_dev_info = {
1438 .name = "usb-host",
1439 .parent = TYPE_USB_DEVICE,
1440 .instance_size = sizeof(USBHostDevice),
1441 .class_init = usb_host_class_initfn,
806b6024
GH
1442};
1443
83f7d43a 1444static void usb_host_register_types(void)
806b6024 1445{
39bffca2 1446 type_register_static(&usb_host_dev_info);
ba02430f 1447 usb_legacy_register("usb-host", "host", usb_host_device_open);
806b6024 1448}
83f7d43a
AF
1449
1450type_init(usb_host_register_types)
806b6024 1451
3741715c 1452USBDevice *usb_host_device_open(USBBus *bus, const char *devname)
4b096fc9 1453{
0745eb1e 1454 struct USBAutoFilter filter;
26a9e82a 1455 USBDevice *dev;
26a9e82a
GH
1456 char *p;
1457
3741715c 1458 dev = usb_create(bus, "usb-host");
4b096fc9 1459
5d0c5750 1460 if (strstr(devname, "auto:")) {
2791104c 1461 if (parse_filter(devname, &filter) < 0) {
26a9e82a 1462 goto fail;
2791104c 1463 }
26a9e82a
GH
1464 } else {
1465 if ((p = strchr(devname, '.'))) {
0745eb1e
MA
1466 filter.bus_num = strtoul(devname, NULL, 0);
1467 filter.addr = strtoul(p + 1, NULL, 0);
1468 filter.vendor_id = 0;
1469 filter.product_id = 0;
26a9e82a 1470 } else if ((p = strchr(devname, ':'))) {
0745eb1e
MA
1471 filter.bus_num = 0;
1472 filter.addr = 0;
26a9e82a 1473 filter.vendor_id = strtoul(devname, NULL, 16);
0745eb1e 1474 filter.product_id = strtoul(p + 1, NULL, 16);
26a9e82a
GH
1475 } else {
1476 goto fail;
1477 }
5d0c5750 1478 }
4b096fc9 1479
0745eb1e
MA
1480 qdev_prop_set_uint32(&dev->qdev, "hostbus", filter.bus_num);
1481 qdev_prop_set_uint32(&dev->qdev, "hostaddr", filter.addr);
26a9e82a
GH
1482 qdev_prop_set_uint32(&dev->qdev, "vendorid", filter.vendor_id);
1483 qdev_prop_set_uint32(&dev->qdev, "productid", filter.product_id);
beb6f0de 1484 qdev_init_nofail(&dev->qdev);
26a9e82a 1485 return dev;
5d0c5750 1486
26a9e82a
GH
1487fail:
1488 qdev_free(&dev->qdev);
1489 return NULL;
4b096fc9 1490}
5d0c5750
AL
1491
1492int usb_host_device_close(const char *devname)
1493{
26a9e82a 1494#if 0
5d0c5750
AL
1495 char product_name[PRODUCT_NAME_SZ];
1496 int bus_num, addr;
1497 USBHostDevice *s;
1498
2791104c 1499 if (strstr(devname, "auto:")) {
5d0c5750 1500 return usb_host_auto_del(devname);
2791104c
DA
1501 }
1502 if (usb_host_find_device(&bus_num, &addr, product_name,
1503 sizeof(product_name), devname) < 0) {
5d0c5750 1504 return -1;
2791104c 1505 }
5d0c5750
AL
1506 s = hostdev_find(bus_num, addr);
1507 if (s) {
a5d2f727 1508 usb_device_delete_addr(s->bus_num, s->dev.addr);
5d0c5750
AL
1509 return 0;
1510 }
26a9e82a 1511#endif
5d0c5750
AL
1512
1513 return -1;
1514}
a5d2f727 1515
0f431527
AL
1516/*
1517 * Read sys file-system device file
1518 *
1519 * @line address of buffer to put file contents in
1520 * @line_size size of line
1521 * @device_file path to device file (printf format string)
1522 * @device_name device being opened (inserted into device_file)
1523 *
1524 * @return 0 failed, 1 succeeded ('line' contains data)
1525 */
2791104c
DA
1526static int usb_host_read_file(char *line, size_t line_size,
1527 const char *device_file, const char *device_name)
0f431527
AL
1528{
1529 FILE *f;
1530 int ret = 0;
1531 char filename[PATH_MAX];
1532
097db438 1533 snprintf(filename, PATH_MAX, "/sys/bus/usb/devices/%s/%s", device_name,
b4e237aa 1534 device_file);
0f431527
AL
1535 f = fopen(filename, "r");
1536 if (f) {
9f99cee7 1537 ret = fgets(line, line_size, f) != NULL;
0f431527 1538 fclose(f);
0f431527
AL
1539 }
1540
1541 return ret;
1542}
1543
1544/*
1545 * Use /sys/bus/usb/devices/ directory to determine host's USB
1546 * devices.
1547 *
1548 * This code is based on Robert Schiele's original patches posted to
1549 * the Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
1550 */
097db438 1551static int usb_host_scan(void *opaque, USBScanFunc *func)
0f431527 1552{
660f11be 1553 DIR *dir = NULL;
0f431527 1554 char line[1024];
5557d820 1555 int bus_num, addr, speed, class_id, product_id, vendor_id;
0f431527 1556 int ret = 0;
5557d820 1557 char port[MAX_PORTLEN];
0f431527
AL
1558 char product_name[512];
1559 struct dirent *de;
1560
097db438 1561 dir = opendir("/sys/bus/usb/devices");
0f431527 1562 if (!dir) {
097db438
GH
1563 perror("husb: opendir /sys/bus/usb/devices");
1564 fprintf(stderr, "husb: please make sure sysfs is mounted at /sys\n");
0f431527
AL
1565 goto the_end;
1566 }
1567
1568 while ((de = readdir(dir))) {
1569 if (de->d_name[0] != '.' && !strchr(de->d_name, ':')) {
5557d820
GH
1570 if (sscanf(de->d_name, "%d-%7[0-9.]", &bus_num, port) < 2) {
1571 continue;
0f5160d1 1572 }
0f431527 1573
2791104c 1574 if (!usb_host_read_file(line, sizeof(line), "devnum", de->d_name)) {
0f431527 1575 goto the_end;
2791104c
DA
1576 }
1577 if (sscanf(line, "%d", &addr) != 1) {
0f431527 1578 goto the_end;
2791104c 1579 }
b4e237aa 1580 if (!usb_host_read_file(line, sizeof(line), "bDeviceClass",
2791104c 1581 de->d_name)) {
0f431527 1582 goto the_end;
2791104c
DA
1583 }
1584 if (sscanf(line, "%x", &class_id) != 1) {
0f431527 1585 goto the_end;
2791104c 1586 }
0f431527 1587
2791104c
DA
1588 if (!usb_host_read_file(line, sizeof(line), "idVendor",
1589 de->d_name)) {
0f431527 1590 goto the_end;
2791104c
DA
1591 }
1592 if (sscanf(line, "%x", &vendor_id) != 1) {
0f431527 1593 goto the_end;
2791104c 1594 }
b4e237aa 1595 if (!usb_host_read_file(line, sizeof(line), "idProduct",
2791104c 1596 de->d_name)) {
0f431527 1597 goto the_end;
2791104c
DA
1598 }
1599 if (sscanf(line, "%x", &product_id) != 1) {
0f431527 1600 goto the_end;
2791104c 1601 }
b4e237aa
BS
1602 if (!usb_host_read_file(line, sizeof(line), "product",
1603 de->d_name)) {
0f431527
AL
1604 *product_name = 0;
1605 } else {
2791104c 1606 if (strlen(line) > 0) {
0f431527 1607 line[strlen(line) - 1] = '\0';
2791104c 1608 }
0f431527
AL
1609 pstrcpy(product_name, sizeof(product_name), line);
1610 }
1611
2791104c 1612 if (!usb_host_read_file(line, sizeof(line), "speed", de->d_name)) {
0f431527 1613 goto the_end;
2791104c 1614 }
f264cfbf
HG
1615 if (!strcmp(line, "5000\n")) {
1616 speed = USB_SPEED_SUPER;
1617 } else if (!strcmp(line, "480\n")) {
0f431527 1618 speed = USB_SPEED_HIGH;
2791104c 1619 } else if (!strcmp(line, "1.5\n")) {
0f431527 1620 speed = USB_SPEED_LOW;
2791104c 1621 } else {
0f431527 1622 speed = USB_SPEED_FULL;
2791104c 1623 }
0f431527 1624
5557d820 1625 ret = func(opaque, bus_num, addr, port, class_id, vendor_id,
0f431527 1626 product_id, product_name, speed);
2791104c 1627 if (ret) {
0f431527 1628 goto the_end;
2791104c 1629 }
0f431527
AL
1630 }
1631 }
1632 the_end:
2791104c 1633 if (dir) {
0f431527 1634 closedir(dir);
2791104c 1635 }
0f431527
AL
1636 return ret;
1637}
1638
4b096fc9 1639static QEMUTimer *usb_auto_timer;
4b096fc9 1640
ba9acab9
GH
1641static int usb_host_auto_scan(void *opaque, int bus_num,
1642 int addr, const char *port,
26a9e82a
GH
1643 int class_id, int vendor_id, int product_id,
1644 const char *product_name, int speed)
4b096fc9
AL
1645{
1646 struct USBAutoFilter *f;
26a9e82a 1647 struct USBHostDevice *s;
4b096fc9
AL
1648
1649 /* Ignore hubs */
1650 if (class_id == 9)
1651 return 0;
1652
26a9e82a
GH
1653 QTAILQ_FOREACH(s, &hostdevs, next) {
1654 f = &s->match;
1655
2791104c 1656 if (f->bus_num > 0 && f->bus_num != bus_num) {
4b096fc9 1657 continue;
2791104c
DA
1658 }
1659 if (f->addr > 0 && f->addr != addr) {
4b096fc9 1660 continue;
2791104c 1661 }
9056a297
GH
1662 if (f->port != NULL && (port == NULL || strcmp(f->port, port) != 0)) {
1663 continue;
1664 }
4b096fc9 1665
2791104c 1666 if (f->vendor_id > 0 && f->vendor_id != vendor_id) {
4b096fc9 1667 continue;
2791104c 1668 }
4b096fc9 1669
2791104c 1670 if (f->product_id > 0 && f->product_id != product_id) {
4b096fc9 1671 continue;
2791104c 1672 }
4b096fc9 1673 /* We got a match */
3ee886c5
GH
1674 s->seen++;
1675 if (s->errcount >= 3) {
1676 return 0;
1677 }
4b096fc9 1678
33e66b86 1679 /* Already attached ? */
2791104c 1680 if (s->fd != -1) {
4b096fc9 1681 return 0;
2791104c 1682 }
d0f2c4c6 1683 DPRINTF("husb: auto open: bus_num %d addr %d\n", bus_num, addr);
4b096fc9 1684
3ee886c5
GH
1685 if (usb_host_open(s, bus_num, addr, port, product_name, speed) < 0) {
1686 s->errcount++;
1687 }
97f86166 1688 break;
4b096fc9
AL
1689 }
1690
1691 return 0;
1692}
1693
26a9e82a 1694static void usb_host_auto_check(void *unused)
4b096fc9 1695{
26a9e82a
GH
1696 struct USBHostDevice *s;
1697 int unconnected = 0;
1698
4b096fc9 1699 usb_host_scan(NULL, usb_host_auto_scan);
26a9e82a
GH
1700
1701 QTAILQ_FOREACH(s, &hostdevs, next) {
2791104c 1702 if (s->fd == -1) {
26a9e82a 1703 unconnected++;
2791104c 1704 }
3ee886c5
GH
1705 if (s->seen == 0) {
1706 s->errcount = 0;
1707 }
1708 s->seen = 0;
26a9e82a
GH
1709 }
1710
1711 if (unconnected == 0) {
1712 /* nothing to watch */
2791104c 1713 if (usb_auto_timer) {
26a9e82a 1714 qemu_del_timer(usb_auto_timer);
e6a2f500 1715 trace_usb_host_auto_scan_disabled();
2791104c 1716 }
26a9e82a
GH
1717 return;
1718 }
1719
1720 if (!usb_auto_timer) {
7bd427d8 1721 usb_auto_timer = qemu_new_timer_ms(rt_clock, usb_host_auto_check, NULL);
2791104c 1722 if (!usb_auto_timer) {
26a9e82a 1723 return;
2791104c 1724 }
e6a2f500 1725 trace_usb_host_auto_scan_enabled();
26a9e82a 1726 }
7bd427d8 1727 qemu_mod_timer(usb_auto_timer, qemu_get_clock_ms(rt_clock) + 2000);
4b096fc9
AL
1728}
1729
1730/*
5d0c5750
AL
1731 * Autoconnect filter
1732 * Format:
1733 * auto:bus:dev[:vid:pid]
1734 * auto:bus.dev[:vid:pid]
1735 *
1736 * bus - bus number (dec, * means any)
1737 * dev - device number (dec, * means any)
1738 * vid - vendor id (hex, * means any)
1739 * pid - product id (hex, * means any)
1740 *
1741 * See 'lsusb' output.
4b096fc9 1742 */
5d0c5750 1743static int parse_filter(const char *spec, struct USBAutoFilter *f)
4b096fc9 1744{
5d0c5750
AL
1745 enum { BUS, DEV, VID, PID, DONE };
1746 const char *p = spec;
1747 int i;
1748
0745eb1e
MA
1749 f->bus_num = 0;
1750 f->addr = 0;
1751 f->vendor_id = 0;
1752 f->product_id = 0;
5d0c5750
AL
1753
1754 for (i = BUS; i < DONE; i++) {
2791104c
DA
1755 p = strpbrk(p, ":.");
1756 if (!p) {
1757 break;
1758 }
5d0c5750 1759 p++;
5d0c5750 1760
2791104c
DA
1761 if (*p == '*') {
1762 continue;
1763 }
5d0c5750
AL
1764 switch(i) {
1765 case BUS: f->bus_num = strtol(p, NULL, 10); break;
1766 case DEV: f->addr = strtol(p, NULL, 10); break;
1767 case VID: f->vendor_id = strtol(p, NULL, 16); break;
1768 case PID: f->product_id = strtol(p, NULL, 16); break;
1769 }
1770 }
1771
1772 if (i < DEV) {
1773 fprintf(stderr, "husb: invalid auto filter spec %s\n", spec);
1774 return -1;
1775 }
1776
1777 return 0;
1778}
1779
a594cfbf
FB
1780/**********************/
1781/* USB host device info */
1782
1783struct usb_class_info {
1784 int class;
1785 const char *class_name;
1786};
1787
1788static const struct usb_class_info usb_class_info[] = {
1789 { USB_CLASS_AUDIO, "Audio"},
1790 { USB_CLASS_COMM, "Communication"},
1791 { USB_CLASS_HID, "HID"},
1792 { USB_CLASS_HUB, "Hub" },
1793 { USB_CLASS_PHYSICAL, "Physical" },
1794 { USB_CLASS_PRINTER, "Printer" },
1795 { USB_CLASS_MASS_STORAGE, "Storage" },
1796 { USB_CLASS_CDC_DATA, "Data" },
1797 { USB_CLASS_APP_SPEC, "Application Specific" },
1798 { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
1799 { USB_CLASS_STILL_IMAGE, "Still Image" },
b9dc033c 1800 { USB_CLASS_CSCID, "Smart Card" },
a594cfbf
FB
1801 { USB_CLASS_CONTENT_SEC, "Content Security" },
1802 { -1, NULL }
1803};
1804
1805static const char *usb_class_str(uint8_t class)
bb36d470 1806{
a594cfbf
FB
1807 const struct usb_class_info *p;
1808 for(p = usb_class_info; p->class != -1; p++) {
2791104c 1809 if (p->class == class) {
a594cfbf 1810 break;
2791104c 1811 }
bb36d470 1812 }
a594cfbf
FB
1813 return p->class_name;
1814}
1815
ba9acab9
GH
1816static void usb_info_device(Monitor *mon, int bus_num,
1817 int addr, const char *port,
5557d820 1818 int class_id, int vendor_id, int product_id,
9596ebb7
PB
1819 const char *product_name,
1820 int speed)
a594cfbf
FB
1821{
1822 const char *class_str, *speed_str;
1823
1824 switch(speed) {
5fafdf24
TS
1825 case USB_SPEED_LOW:
1826 speed_str = "1.5";
a594cfbf 1827 break;
5fafdf24
TS
1828 case USB_SPEED_FULL:
1829 speed_str = "12";
a594cfbf 1830 break;
5fafdf24
TS
1831 case USB_SPEED_HIGH:
1832 speed_str = "480";
a594cfbf 1833 break;
f264cfbf
HG
1834 case USB_SPEED_SUPER:
1835 speed_str = "5000";
1836 break;
a594cfbf 1837 default:
5fafdf24 1838 speed_str = "?";
a594cfbf
FB
1839 break;
1840 }
1841
5557d820
GH
1842 monitor_printf(mon, " Bus %d, Addr %d, Port %s, Speed %s Mb/s\n",
1843 bus_num, addr, port, speed_str);
a594cfbf 1844 class_str = usb_class_str(class_id);
2791104c 1845 if (class_str) {
376253ec 1846 monitor_printf(mon, " %s:", class_str);
2791104c 1847 } else {
376253ec 1848 monitor_printf(mon, " Class %02x:", class_id);
2791104c 1849 }
376253ec 1850 monitor_printf(mon, " USB device %04x:%04x", vendor_id, product_id);
2791104c 1851 if (product_name[0] != '\0') {
376253ec 1852 monitor_printf(mon, ", %s", product_name);
2791104c 1853 }
376253ec 1854 monitor_printf(mon, "\n");
a594cfbf
FB
1855}
1856
5fafdf24 1857static int usb_host_info_device(void *opaque, int bus_num, int addr,
ba9acab9 1858 const char *path, int class_id,
5fafdf24 1859 int vendor_id, int product_id,
a594cfbf
FB
1860 const char *product_name,
1861 int speed)
1862{
179da8af
BS
1863 Monitor *mon = opaque;
1864
5557d820 1865 usb_info_device(mon, bus_num, addr, path, class_id, vendor_id, product_id,
a594cfbf
FB
1866 product_name, speed);
1867 return 0;
1868}
1869
ac4ffb5a 1870static void dec2str(int val, char *str, size_t size)
5d0c5750 1871{
2791104c 1872 if (val == 0) {
ac4ffb5a 1873 snprintf(str, size, "*");
2791104c
DA
1874 } else {
1875 snprintf(str, size, "%d", val);
1876 }
5d0c5750
AL
1877}
1878
ac4ffb5a 1879static void hex2str(int val, char *str, size_t size)
5d0c5750 1880{
2791104c 1881 if (val == 0) {
ac4ffb5a 1882 snprintf(str, size, "*");
2791104c 1883 } else {
26a9e82a 1884 snprintf(str, size, "%04x", val);
2791104c 1885 }
5d0c5750
AL
1886}
1887
376253ec 1888void usb_host_info(Monitor *mon)
a594cfbf 1889{
5d0c5750 1890 struct USBAutoFilter *f;
26a9e82a 1891 struct USBHostDevice *s;
5d0c5750 1892
179da8af 1893 usb_host_scan(mon, usb_host_info_device);
5d0c5750 1894
2791104c 1895 if (QTAILQ_EMPTY(&hostdevs)) {
26a9e82a 1896 return;
2791104c
DA
1897 }
1898
26a9e82a
GH
1899 monitor_printf(mon, " Auto filters:\n");
1900 QTAILQ_FOREACH(s, &hostdevs, next) {
5d0c5750 1901 char bus[10], addr[10], vid[10], pid[10];
26a9e82a 1902 f = &s->match;
ac4ffb5a
AL
1903 dec2str(f->bus_num, bus, sizeof(bus));
1904 dec2str(f->addr, addr, sizeof(addr));
1905 hex2str(f->vendor_id, vid, sizeof(vid));
1906 hex2str(f->product_id, pid, sizeof(pid));
9056a297
GH
1907 monitor_printf(mon, " Bus %s, Addr %s, Port %s, ID %s:%s\n",
1908 bus, addr, f->port ? f->port : "*", vid, pid);
5d0c5750 1909 }
bb36d470 1910}
This page took 0.924277 seconds and 4 git commands to generate.