Commit 64838171c464b642d68160ba78b6bfd9c7281516

Authored by aliguori
1 parent 54f254f9

husb: rewrite Linux host USB layer, fully async operation (Max Krasnyansky)

This is a follow up to the async UHCI patch. Both BULK and ISOC transactions
are now fully asynchrounous. I left CONTROL synchronous for now, ideally
we want it to be async too and it should not be that hard to do now.

This patch obviously requires UHCI patch. The combo has been tested with
various devices. See the UHCI patch description for list of the devices.
Most of the testing was done with the KVM flavor of QEMU.

Signed-off-by: Max Krasnyansky <maxk@kernel.org>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5051 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 182 additions and 278 deletions
usb-linux.c
@@ -3,8 +3,9 @@ @@ -3,8 +3,9 @@
3 * 3 *
4 * Copyright (c) 2005 Fabrice Bellard 4 * Copyright (c) 2005 Fabrice Bellard
5 * 5 *
6 - * Support for host device auto connect & disconnect  
7 - * Copyright (c) 2008 Max Krasnyansky 6 + * Copyright (c) 2008 Max Krasnyansky
  7 + * Support for host device auto connect & disconnect
  8 + * Magor rewrite to support fully async operation
8 * 9 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy 10 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal 11 * of this software and associated documentation files (the "Software"), to deal
@@ -55,12 +56,15 @@ static int usb_host_find_device(int *pbus_num, int *paddr, @@ -55,12 +56,15 @@ static int usb_host_find_device(int *pbus_num, int *paddr,
55 const char *devname); 56 const char *devname);
56 57
57 //#define DEBUG 58 //#define DEBUG
58 -//#define DEBUG_ISOCH  
59 -//#define USE_ASYNCIO 59 +
  60 +#ifdef DEBUG
  61 +#define dprintf printf
  62 +#else
  63 +#define dprintf(...)
  64 +#endif
60 65
61 #define USBDEVFS_PATH "/proc/bus/usb" 66 #define USBDEVFS_PATH "/proc/bus/usb"
62 #define PRODUCT_NAME_SZ 32 67 #define PRODUCT_NAME_SZ 32
63 -#define SIG_ISOCOMPLETE (SIGRTMIN+7)  
64 #define MAX_ENDPOINTS 16 68 #define MAX_ENDPOINTS 16
65 69
66 struct sigaction sigact; 70 struct sigaction sigact;
@@ -68,21 +72,18 @@ struct sigaction sigact; @@ -68,21 +72,18 @@ struct sigaction sigact;
68 /* endpoint association data */ 72 /* endpoint association data */
69 struct endp_data { 73 struct endp_data {
70 uint8_t type; 74 uint8_t type;
  75 + uint8_t halted;
71 }; 76 };
72 77
73 -  
74 -  
75 -/* FIXME: move USBPacket to PendingURB */  
76 typedef struct USBHostDevice { 78 typedef struct USBHostDevice {
77 USBDevice dev; 79 USBDevice dev;
78 - int fd;  
79 - int pipe_fds[2];  
80 - USBPacket *packet; 80 + int fd;
  81 +
  82 + uint8_t descr[1024];
  83 + int descr_len;
  84 + int configuration;
  85 +
81 struct endp_data endp_table[MAX_ENDPOINTS]; 86 struct endp_data endp_table[MAX_ENDPOINTS];
82 - int configuration;  
83 - uint8_t descr[1024];  
84 - int descr_len;  
85 - int urbs_ready;  
86 87
87 QEMUTimer *timer; 88 QEMUTimer *timer;
88 89
@@ -93,6 +94,26 @@ typedef struct USBHostDevice { @@ -93,6 +94,26 @@ typedef struct USBHostDevice {
93 struct USBHostDevice *next; 94 struct USBHostDevice *next;
94 } USBHostDevice; 95 } USBHostDevice;
95 96
  97 +static int is_isoc(USBHostDevice *s, int ep)
  98 +{
  99 + return s->endp_table[ep - 1].type == USBDEVFS_URB_TYPE_ISO;
  100 +}
  101 +
  102 +static int is_halted(USBHostDevice *s, int ep)
  103 +{
  104 + return s->endp_table[ep - 1].halted;
  105 +}
  106 +
  107 +static void clear_halt(USBHostDevice *s, int ep)
  108 +{
  109 + s->endp_table[ep - 1].halted = 0;
  110 +}
  111 +
  112 +static void set_halt(USBHostDevice *s, int ep)
  113 +{
  114 + s->endp_table[ep - 1].halted = 1;
  115 +}
  116 +
96 static USBHostDevice *hostdev_list; 117 static USBHostDevice *hostdev_list;
97 118
98 static void hostdev_link(USBHostDevice *dev) 119 static void hostdev_link(USBHostDevice *dev)
@@ -128,64 +149,94 @@ static USBHostDevice *hostdev_find(int bus_num, int addr) @@ -128,64 +149,94 @@ static USBHostDevice *hostdev_find(int bus_num, int addr)
128 return NULL; 149 return NULL;
129 } 150 }
130 151
131 -typedef struct PendingURB {  
132 - struct usbdevfs_urb *urb;  
133 - int status;  
134 - struct PendingURB *next;  
135 -} PendingURB; 152 +/*
  153 + * Async URB state.
  154 + * We always allocate one isoc descriptor even for bulk transfers
  155 + * to simplify allocation and casts.
  156 + */
  157 +typedef struct AsyncURB
  158 +{
  159 + struct usbdevfs_urb urb;
  160 + struct usbdevfs_iso_packet_desc isocpd;
136 161
137 -static PendingURB *pending_urbs = NULL; 162 + USBPacket *packet;
  163 + USBHostDevice *hdev;
  164 +} AsyncURB;
138 165
139 -static int add_pending_urb(struct usbdevfs_urb *urb) 166 +static AsyncURB *async_alloc(void)
140 { 167 {
141 - PendingURB *purb = qemu_mallocz(sizeof(PendingURB));  
142 - if (purb) {  
143 - purb->urb = urb;  
144 - purb->status = 0;  
145 - purb->next = pending_urbs;  
146 - pending_urbs = purb;  
147 - return 1;  
148 - }  
149 - return 0; 168 + return (AsyncURB *) qemu_mallocz(sizeof(AsyncURB));
150 } 169 }
151 170
152 -static int del_pending_urb(struct usbdevfs_urb *urb) 171 +static void async_free(AsyncURB *aurb)
153 { 172 {
154 - PendingURB *purb = pending_urbs;  
155 - PendingURB *prev = NULL; 173 + qemu_free(aurb);
  174 +}
156 175
157 - while (purb && purb->urb != urb) {  
158 - prev = purb;  
159 - purb = purb->next;  
160 - } 176 +static void async_complete(void *opaque)
  177 +{
  178 + USBHostDevice *s = opaque;
  179 + AsyncURB *aurb;
  180 +
  181 + while (1) {
  182 + USBPacket *p;
161 183
162 - if (purb && purb->urb == urb) {  
163 - if (prev) {  
164 - prev->next = purb->next;  
165 - } else {  
166 - pending_urbs = purb->next; 184 + int r = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &aurb);
  185 + if (r < 0) {
  186 + if (errno == EAGAIN)
  187 + return;
  188 +
  189 + if (errno == ENODEV) {
  190 + printf("husb: device %d.%d disconnected\n", s->bus_num, s->addr);
  191 + usb_device_del_addr(0, s->dev.addr);
  192 + return;
  193 + }
  194 +
  195 + dprintf("husb: async. reap urb failed errno %d\n", errno);
  196 + return;
167 } 197 }
168 - qemu_free(purb);  
169 - return 1; 198 +
  199 + p = aurb->packet;
  200 +
  201 + dprintf("husb: async completed. aurb %p status %d alen %d\n",
  202 + aurb, aurb->urb.status, aurb->urb.actual_length);
  203 +
  204 + if (p) {
  205 + switch (aurb->urb.status) {
  206 + case 0:
  207 + p->len = aurb->urb.actual_length;
  208 + break;
  209 +
  210 + case -EPIPE:
  211 + set_halt(s, p->devep);
  212 + /* fall through */
  213 + default:
  214 + p->len = USB_RET_NAK;
  215 + break;
  216 + }
  217 +
  218 + usb_packet_complete(p);
  219 + }
  220 +
  221 + async_free(aurb);
170 } 222 }
171 - return 0;  
172 } 223 }
173 224
174 -#ifdef USE_ASYNCIO  
175 -static PendingURB *get_pending_urb(struct usbdevfs_urb *urb) 225 +static void async_cancel(USBPacket *unused, void *opaque)
176 { 226 {
177 - PendingURB *purb = pending_urbs; 227 + AsyncURB *aurb = opaque;
  228 + USBHostDevice *s = aurb->hdev;
178 229
179 - while (purb && purb->urb != urb) {  
180 - purb = purb->next;  
181 - } 230 + dprintf("husb: async cancel. aurb %p\n", aurb);
  231 +
  232 + /* Mark it as dead (see async_complete above) */
  233 + aurb->packet = NULL;
182 234
183 - if (purb && purb->urb == urb) {  
184 - return purb; 235 + int r = ioctl(s->fd, USBDEVFS_DISCARDURB, aurb);
  236 + if (r < 0) {
  237 + dprintf("husb: async. discard urb failed errno %d\n", errno);
185 } 238 }
186 - return NULL;  
187 } 239 }
188 -#endif  
189 240
190 static int usb_host_update_interfaces(USBHostDevice *dev, int configuration) 241 static int usb_host_update_interfaces(USBHostDevice *dev, int configuration)
191 { 242 {
@@ -204,19 +255,16 @@ static int usb_host_update_interfaces(USBHostDevice *dev, int configuration) @@ -204,19 +255,16 @@ static int usb_host_update_interfaces(USBHostDevice *dev, int configuration)
204 255
205 i += dev_descr_len; 256 i += dev_descr_len;
206 while (i < dev->descr_len) { 257 while (i < dev->descr_len) {
207 -#ifdef DEBUG  
208 - printf("i is %d, descr_len is %d, dl %d, dt %d\n", i, dev->descr_len, 258 + dprintf("husb: i is %d, descr_len is %d, dl %d, dt %d\n", i, dev->descr_len,
209 dev->descr[i], dev->descr[i+1]); 259 dev->descr[i], dev->descr[i+1]);
210 -#endif 260 +
211 if (dev->descr[i+1] != USB_DT_CONFIG) { 261 if (dev->descr[i+1] != USB_DT_CONFIG) {
212 i += dev->descr[i]; 262 i += dev->descr[i];
213 continue; 263 continue;
214 } 264 }
215 config_descr_len = dev->descr[i]; 265 config_descr_len = dev->descr[i];
216 266
217 -#ifdef DEBUG  
218 - printf("config #%d need %d\n", dev->descr[i + 5], configuration);  
219 -#endif 267 + printf("husb: config #%d need %d\n", dev->descr[i + 5], configuration);
220 268
221 if (configuration < 0 || configuration == dev->descr[i + 5]) 269 if (configuration < 0 || configuration == dev->descr[i + 5])
222 break; 270 break;
@@ -225,7 +273,7 @@ static int usb_host_update_interfaces(USBHostDevice *dev, int configuration) @@ -225,7 +273,7 @@ static int usb_host_update_interfaces(USBHostDevice *dev, int configuration)
225 } 273 }
226 274
227 if (i >= dev->descr_len) { 275 if (i >= dev->descr_len) {
228 - printf("usb_host: error - device has no matching configuration\n"); 276 + printf("husb: update iface failed. no matching configuration\n");
229 goto fail; 277 goto fail;
230 } 278 }
231 nb_interfaces = dev->descr[i + 4]; 279 nb_interfaces = dev->descr[i + 4];
@@ -251,32 +299,29 @@ static int usb_host_update_interfaces(USBHostDevice *dev, int configuration) @@ -251,32 +299,29 @@ static int usb_host_update_interfaces(USBHostDevice *dev, int configuration)
251 ret = ioctl(dev->fd, USBDEVFS_CLAIMINTERFACE, &interface); 299 ret = ioctl(dev->fd, USBDEVFS_CLAIMINTERFACE, &interface);
252 if (ret < 0) { 300 if (ret < 0) {
253 if (errno == EBUSY) { 301 if (errno == EBUSY) {
254 - fprintf(stderr,  
255 - "usb_host: warning - device already grabbed\n"); 302 + printf("husb: update iface. device already grabbed\n");
256 } else { 303 } else {
257 - perror("USBDEVFS_CLAIMINTERFACE"); 304 + perror("husb: failed to claim interface");
258 } 305 }
259 fail: 306 fail:
260 return 0; 307 return 0;
261 } 308 }
262 } 309 }
263 310
264 -#ifdef DEBUG  
265 - printf("usb_host: %d interfaces claimed for configuration %d\n", 311 + printf("husb: %d interfaces claimed for configuration %d\n",
266 nb_interfaces, configuration); 312 nb_interfaces, configuration);
267 -#endif  
268 313
269 return 1; 314 return 1;
270 } 315 }
271 316
272 static void usb_host_handle_reset(USBDevice *dev) 317 static void usb_host_handle_reset(USBDevice *dev)
273 { 318 {
274 -#if 0  
275 USBHostDevice *s = (USBHostDevice *)dev; 319 USBHostDevice *s = (USBHostDevice *)dev;
276 - /* USBDEVFS_RESET, but not the first time as it has already be  
277 - done by the host OS */ 320 +
  321 + dprintf("husb: reset device %u.%u\n", s->bus_num, s->addr);
  322 +
278 ioctl(s->fd, USBDEVFS_RESET); 323 ioctl(s->fd, USBDEVFS_RESET);
279 -#endif 324 + usb_host_update_interfaces(s, s->configuration);
280 } 325 }
281 326
282 static void usb_host_handle_destroy(USBDevice *dev) 327 static void usb_host_handle_destroy(USBDevice *dev)
@@ -284,9 +329,12 @@ static void usb_host_handle_destroy(USBDevice *dev) @@ -284,9 +329,12 @@ static void usb_host_handle_destroy(USBDevice *dev)
284 USBHostDevice *s = (USBHostDevice *)dev; 329 USBHostDevice *s = (USBHostDevice *)dev;
285 330
286 qemu_del_timer(s->timer); 331 qemu_del_timer(s->timer);
  332 + qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
287 333
288 hostdev_unlink(s); 334 hostdev_unlink(s);
289 335
  336 + async_complete(s);
  337 +
290 if (s->fd >= 0) 338 if (s->fd >= 0)
291 close(s->fd); 339 close(s->fd);
292 340
@@ -320,10 +368,7 @@ static int usb_host_handle_control(USBDevice *dev, @@ -320,10 +368,7 @@ static int usb_host_handle_control(USBDevice *dev,
320 ret = ioctl(s->fd, USBDEVFS_SETINTERFACE, &si); 368 ret = ioctl(s->fd, USBDEVFS_SETINTERFACE, &si);
321 usb_linux_update_endp_table(s); 369 usb_linux_update_endp_table(s);
322 } else if (request == (DeviceOutRequest | USB_REQ_SET_CONFIGURATION)) { 370 } else if (request == (DeviceOutRequest | USB_REQ_SET_CONFIGURATION)) {
323 -#ifdef DEBUG  
324 - printf("usb_host_handle_control: SET_CONFIGURATION request - "  
325 - "config %d\n", value & 0xff);  
326 -#endif 371 + dprintf("husb: ctrl set config %d\n", value & 0xff);
327 if (s->configuration != (value & 0xff)) { 372 if (s->configuration != (value & 0xff)) {
328 s->configuration = (value & 0xff); 373 s->configuration = (value & 0xff);
329 intf_update_required = 1; 374 intf_update_required = 1;
@@ -339,6 +384,9 @@ static int usb_host_handle_control(USBDevice *dev, @@ -339,6 +384,9 @@ static int usb_host_handle_control(USBDevice *dev,
339 ct.timeout = 50; 384 ct.timeout = 50;
340 ct.data = data; 385 ct.data = data;
341 ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct); 386 ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
  387 +
  388 + dprintf("husb: ctrl req 0x%x val 0x%x index %u len %u ret %d\n",
  389 + ct.bRequest, ct.wValue, ct.wIndex, ct.wLength, ret);
342 } 390 }
343 391
344 if (ret < 0) { 392 if (ret < 0) {
@@ -350,160 +398,69 @@ static int usb_host_handle_control(USBDevice *dev, @@ -350,160 +398,69 @@ static int usb_host_handle_control(USBDevice *dev,
350 } 398 }
351 } else { 399 } else {
352 if (intf_update_required) { 400 if (intf_update_required) {
353 -#ifdef DEBUG  
354 - printf("usb_host_handle_control: updating interfaces\n");  
355 -#endif 401 + dprintf("husb: updating interfaces\n");
356 usb_host_update_interfaces(s, value & 0xff); 402 usb_host_update_interfaces(s, value & 0xff);
357 } 403 }
358 return ret; 404 return ret;
359 } 405 }
360 } 406 }
361 407
362 -static int usb_host_handle_isoch(USBDevice *dev, USBPacket *p);  
363 -  
364 static int usb_host_handle_data(USBDevice *dev, USBPacket *p) 408 static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
365 { 409 {
366 - USBHostDevice *s = (USBHostDevice *)dev;  
367 - struct usbdevfs_bulktransfer bt; 410 + USBHostDevice *s = (USBHostDevice *) dev;
  411 + AsyncURB *aurb;
  412 + struct usbdevfs_urb *urb;
368 int ret; 413 int ret;
369 - uint8_t devep = p->devep;  
370 414
371 - if (s->endp_table[p->devep - 1].type == USBDEVFS_URB_TYPE_ISO) {  
372 - return usb_host_handle_isoch(dev, p); 415 + aurb = async_alloc();
  416 + if (!aurb) {
  417 + dprintf("husb: async malloc failed\n");
  418 + return USB_RET_NAK;
373 } 419 }
  420 + aurb->hdev = s;
  421 + aurb->packet = p;
  422 +
  423 + urb = &aurb->urb;
374 424
375 - /* XXX: optimize and handle all data types by looking at the  
376 - config descriptor */  
377 if (p->pid == USB_TOKEN_IN) 425 if (p->pid == USB_TOKEN_IN)
378 - devep |= 0x80;  
379 - bt.ep = devep;  
380 - bt.len = p->len;  
381 - bt.timeout = 50;  
382 - bt.data = p->data;  
383 - ret = ioctl(s->fd, USBDEVFS_BULK, &bt);  
384 - if (ret < 0) {  
385 - switch(errno) {  
386 - case ETIMEDOUT: 426 + urb->endpoint = p->devep | 0x80;
  427 + else
  428 + urb->endpoint = p->devep;
  429 +
  430 + if (is_halted(s, p->devep)) {
  431 + ret = ioctl(s->fd, USBDEVFS_CLEAR_HALT, &urb->endpoint);
  432 + if (ret < 0) {
  433 + dprintf("husb: failed to clear halt. ep 0x%x errno %d\n",
  434 + urb->endpoint, errno);
387 return USB_RET_NAK; 435 return USB_RET_NAK;
388 - case EPIPE:  
389 - default:  
390 -#ifdef DEBUG  
391 - printf("handle_data: errno=%d\n", errno);  
392 -#endif  
393 - return USB_RET_STALL;  
394 } 436 }
395 - } else {  
396 - return ret;  
397 - }  
398 -}  
399 -  
400 -#ifdef USE_ASYNCIO  
401 -static void urb_completion_pipe_read(void *opaque)  
402 -{  
403 - USBHostDevice *s = opaque;  
404 - USBPacket *p = s->packet;  
405 - PendingURB *pending_urb = NULL;  
406 - struct usbdevfs_urb *purb = NULL;  
407 - int len, ret;  
408 -  
409 - len = read(s->pipe_fds[0], &pending_urb, sizeof(pending_urb));  
410 - if (len != sizeof(pending_urb)) {  
411 - printf("urb_completion: error reading pending_urb, len=%d\n", len);  
412 - return;  
413 - }  
414 -  
415 - /* FIXME: handle pending_urb->status */  
416 - del_pending_urb(pending_urb->urb);  
417 -  
418 - if (!p) {  
419 - s->urbs_ready++;  
420 - return; 437 + clear_halt(s, p->devep);
421 } 438 }
422 439
423 - ret = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &purb);  
424 - if (ret < 0) {  
425 - printf("urb_completion: REAPURBNDELAY ioctl=%d errno=%d\n",  
426 - ret, errno);  
427 - return;  
428 - }  
429 -  
430 -#ifdef DEBUG_ISOCH  
431 - if (purb == pending_urb->urb) {  
432 - printf("urb_completion: urb mismatch reaped=%p pending=%p\n",  
433 - purb, urb);  
434 - }  
435 -#endif  
436 -  
437 - p->len = purb->actual_length;  
438 - usb_packet_complete(p);  
439 - qemu_free(purb);  
440 - s->packet = NULL;  
441 -}  
442 -  
443 -static void isoch_done(int signum, siginfo_t *info, void *context)  
444 -{  
445 - struct usbdevfs_urb *urb = (struct usbdevfs_urb *)info->si_addr;  
446 - USBHostDevice *s = (USBHostDevice *)urb->usercontext;  
447 - PendingURB *purb; 440 + urb->buffer = p->data;
  441 + urb->buffer_length = p->len;
448 442
449 - if (info->si_code != SI_ASYNCIO ||  
450 - info->si_signo != SIG_ISOCOMPLETE) {  
451 - return; 443 + if (is_isoc(s, p->devep)) {
  444 + /* Setup ISOC transfer */
  445 + urb->type = USBDEVFS_URB_TYPE_ISO;
  446 + urb->flags = USBDEVFS_URB_ISO_ASAP;
  447 + urb->number_of_packets = 1;
  448 + urb->iso_frame_desc[0].length = p->len;
  449 + } else {
  450 + /* Setup bulk transfer */
  451 + urb->type = USBDEVFS_URB_TYPE_BULK;
452 } 452 }
453 453
454 - purb = get_pending_urb(urb);  
455 - if (purb) {  
456 - purb->status = info->si_errno;  
457 - write(s->pipe_fds[1], &purb, sizeof(purb));  
458 - }  
459 -}  
460 -#endif 454 + urb->usercontext = s;
461 455
462 -static int usb_host_handle_isoch(USBDevice *dev, USBPacket *p)  
463 -{  
464 - USBHostDevice *s = (USBHostDevice *)dev;  
465 - struct usbdevfs_urb *urb, *purb = NULL;  
466 - int ret;  
467 - uint8_t devep = p->devep; 456 + ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
468 457
469 - if (p->pid == USB_TOKEN_IN)  
470 - devep |= 0x80; 458 + dprintf("husb: data submit. ep 0x%x len %u aurb %p\n", urb->endpoint, p->len, aurb);
471 459
472 - urb = qemu_mallocz(sizeof(struct usbdevfs_urb) +  
473 - sizeof(struct usbdevfs_iso_packet_desc));  
474 - if (!urb) {  
475 - printf("usb_host_handle_isoch: malloc failed\n");  
476 - return 0;  
477 - } 460 + if (ret < 0) {
  461 + dprintf("husb: submit failed. errno %d\n", errno);
  462 + async_free(aurb);
478 463
479 - urb->type = USBDEVFS_URB_TYPE_ISO;  
480 - urb->endpoint = devep;  
481 - urb->status = 0;  
482 - urb->flags = USBDEVFS_URB_ISO_ASAP;  
483 - urb->buffer = p->data;  
484 - urb->buffer_length = p->len;  
485 - urb->actual_length = 0;  
486 - urb->start_frame = 0;  
487 - urb->error_count = 0;  
488 -#ifdef USE_ASYNCIO  
489 - urb->signr = SIG_ISOCOMPLETE;  
490 -#else  
491 - urb->signr = 0;  
492 -#endif  
493 - urb->usercontext = s;  
494 - urb->number_of_packets = 1;  
495 - urb->iso_frame_desc[0].length = p->len;  
496 - urb->iso_frame_desc[0].actual_length = 0;  
497 - urb->iso_frame_desc[0].status = 0;  
498 - ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);  
499 - if (ret == 0) {  
500 - if (!add_pending_urb(urb)) {  
501 - printf("usb_host_handle_isoch: add_pending_urb failed %p\n", urb);  
502 - }  
503 - } else {  
504 - printf("usb_host_handle_isoch: SUBMITURB ioctl=%d errno=%d\n",  
505 - ret, errno);  
506 - qemu_free(urb);  
507 switch(errno) { 464 switch(errno) {
508 case ETIMEDOUT: 465 case ETIMEDOUT:
509 return USB_RET_NAK; 466 return USB_RET_NAK;
@@ -512,37 +469,9 @@ static int usb_host_handle_isoch(USBDevice *dev, USBPacket *p) @@ -512,37 +469,9 @@ static int usb_host_handle_isoch(USBDevice *dev, USBPacket *p)
512 return USB_RET_STALL; 469 return USB_RET_STALL;
513 } 470 }
514 } 471 }
515 -#ifdef USE_ASYNCIO  
516 - /* FIXME: handle urbs_ready together with sync io  
517 - * workaround for injecting the signaled urbs into current frame */  
518 - if (s->urbs_ready > 0) {  
519 - ret = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &purb);  
520 - if (ret == 0) {  
521 - ret = purb->actual_length;  
522 - qemu_free(purb);  
523 - s->urbs_ready--;  
524 - }  
525 - return ret;  
526 - }  
527 - s->packet = p; 472 +
  473 + usb_defer_packet(p, async_cancel, aurb);
528 return USB_RET_ASYNC; 474 return USB_RET_ASYNC;
529 -#else  
530 - ret = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &purb);  
531 - if (ret == 0) {  
532 - if (del_pending_urb(purb)) {  
533 - ret = purb->actual_length;  
534 - qemu_free(purb);  
535 - } else {  
536 - printf("usb_host_handle_isoch: del_pending_urb failed %p\n", purb);  
537 - }  
538 - } else {  
539 -#ifdef DEBUG_ISOCH  
540 - printf("usb_host_handle_isoch: REAPURBNDELAY ioctl=%d errno=%d\n",  
541 - ret, errno);  
542 -#endif  
543 - }  
544 - return ret;  
545 -#endif  
546 } 475 }
547 476
548 /* returns 1 on problem encountered or 0 for success */ 477 /* returns 1 on problem encountered or 0 for success */
@@ -579,7 +508,7 @@ static int usb_linux_update_endp_table(USBHostDevice *s) @@ -579,7 +508,7 @@ static int usb_linux_update_endp_table(USBHostDevice *s)
579 508
580 if (descriptors[i + 1] != USB_DT_CONFIG || 509 if (descriptors[i + 1] != USB_DT_CONFIG ||
581 descriptors[i + 5] != configuration) { 510 descriptors[i + 5] != configuration) {
582 - printf("invalid descriptor data - configuration\n"); 511 + dprintf("invalid descriptor data - configuration\n");
583 return 1; 512 return 1;
584 } 513 }
585 i += descriptors[i]; 514 i += descriptors[i];
@@ -641,10 +570,11 @@ static int usb_linux_update_endp_table(USBHostDevice *s) @@ -641,10 +570,11 @@ static int usb_linux_update_endp_table(USBHostDevice *s)
641 type = USBDEVFS_URB_TYPE_INTERRUPT; 570 type = USBDEVFS_URB_TYPE_INTERRUPT;
642 break; 571 break;
643 default: 572 default:
644 - printf("usb_host: malformed endpoint type\n"); 573 + dprintf("usb_host: malformed endpoint type\n");
645 type = USBDEVFS_URB_TYPE_BULK; 574 type = USBDEVFS_URB_TYPE_BULK;
646 } 575 }
647 s->endp_table[(devep & 0xf) - 1].type = type; 576 s->endp_table[(devep & 0xf) - 1].type = type;
  577 + s->endp_table[(devep & 0xf) - 1].halted = 0;
648 578
649 i += descriptors[i]; 579 i += descriptors[i];
650 } 580 }
@@ -660,7 +590,7 @@ static void usb_host_device_check(void *priv) @@ -660,7 +590,7 @@ static void usb_host_device_check(void *priv)
660 590
661 err = ioctl(s->fd, USBDEVFS_CONNECTINFO, &ci); 591 err = ioctl(s->fd, USBDEVFS_CONNECTINFO, &ci);
662 if (err < 0) { 592 if (err < 0) {
663 - printf("usb device %d.%d disconnected\n", 0, s->dev.addr); 593 + printf("husb: device %d.%d disconnected\n", s->bus_num, s->addr);
664 usb_device_del_addr(0, s->dev.addr); 594 usb_device_del_addr(0, s->dev.addr);
665 return; 595 return;
666 } 596 }
@@ -686,9 +616,7 @@ static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *p @@ -686,9 +616,7 @@ static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *p
686 if (!dev->timer) 616 if (!dev->timer)
687 goto fail; 617 goto fail;
688 618
689 -#ifdef DEBUG  
690 - printf("usb_host_device_open %d.%d\n", bus_num, addr);  
691 -#endif 619 + printf("husb: open device %d.%d\n", bus_num, addr);
692 620
693 snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d", 621 snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d",
694 bus_num, addr); 622 bus_num, addr);
@@ -701,7 +629,7 @@ static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *p @@ -701,7 +629,7 @@ static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *p
701 /* read the device description */ 629 /* read the device description */
702 dev->descr_len = read(fd, dev->descr, sizeof(dev->descr)); 630 dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
703 if (dev->descr_len <= 0) { 631 if (dev->descr_len <= 0) {
704 - perror("usb_host_device_open: reading device data failed"); 632 + perror("husb: reading device data failed");
705 goto fail; 633 goto fail;
706 } 634 }
707 635
@@ -728,9 +656,7 @@ static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *p @@ -728,9 +656,7 @@ static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *p
728 goto fail; 656 goto fail;
729 } 657 }
730 658
731 -#ifdef DEBUG  
732 - printf("host USB device %d.%d grabbed\n", bus_num, addr);  
733 -#endif 659 + printf("husb: grabbed usb device %d.%d\n", bus_num, addr);
734 660
735 ret = usb_linux_update_endp_table(dev); 661 ret = usb_linux_update_endp_table(dev);
736 if (ret) 662 if (ret)
@@ -754,34 +680,15 @@ static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *p @@ -754,34 +680,15 @@ static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *p
754 pstrcpy(dev->dev.devname, sizeof(dev->dev.devname), 680 pstrcpy(dev->dev.devname, sizeof(dev->dev.devname),
755 prod_name); 681 prod_name);
756 682
757 -#ifdef USE_ASYNCIO  
758 - /* set up the signal handlers */  
759 - sigemptyset(&sigact.sa_mask);  
760 - sigact.sa_sigaction = isoch_done;  
761 - sigact.sa_flags = SA_SIGINFO;  
762 - sigact.sa_restorer = 0;  
763 - ret = sigaction(SIG_ISOCOMPLETE, &sigact, NULL);  
764 - if (ret < 0) {  
765 - perror("usb_host_device_open: sigaction failed");  
766 - goto fail;  
767 - }  
768 -  
769 - if (pipe(dev->pipe_fds) < 0) {  
770 - perror("usb_host_device_open: pipe creation failed");  
771 - goto fail;  
772 - }  
773 - fcntl(dev->pipe_fds[0], F_SETFL, O_NONBLOCK | O_ASYNC);  
774 - fcntl(dev->pipe_fds[1], F_SETFL, O_NONBLOCK);  
775 - qemu_set_fd_handler(dev->pipe_fds[0], urb_completion_pipe_read, NULL, dev);  
776 -#endif 683 + /* USB devio uses 'write' flag to check for async completions */
  684 + qemu_set_fd_handler(dev->fd, NULL, async_complete, dev);
777 685
778 /* Start the timer to detect disconnect */ 686 /* Start the timer to detect disconnect */
779 qemu_mod_timer(dev->timer, qemu_get_clock(rt_clock) + 1000); 687 qemu_mod_timer(dev->timer, qemu_get_clock(rt_clock) + 1000);
780 688
781 hostdev_link(dev); 689 hostdev_link(dev);
782 690
783 - dev->urbs_ready = 0;  
784 - return (USBDevice *)dev; 691 + return (USBDevice *) dev;
785 692
786 fail: 693 fail:
787 if (dev) { 694 if (dev) {
@@ -804,7 +711,7 @@ USBDevice *usb_host_device_open(const char *devname) @@ -804,7 +711,7 @@ USBDevice *usb_host_device_open(const char *devname)
804 return NULL; 711 return NULL;
805 712
806 if (hostdev_find(bus_num, addr)) { 713 if (hostdev_find(bus_num, addr)) {
807 - printf("host usb device %d.%d is already open\n", bus_num, addr); 714 + term_printf("husb: host usb device %d.%d is already open\n", bus_num, addr);
808 return NULL; 715 return NULL;
809 } 716 }
810 717
@@ -844,7 +751,7 @@ static int usb_host_scan(void *opaque, USBScanFunc *func) @@ -844,7 +751,7 @@ static int usb_host_scan(void *opaque, USBScanFunc *func)
844 751
845 f = fopen(USBDEVFS_PATH "/devices", "r"); 752 f = fopen(USBDEVFS_PATH "/devices", "r");
846 if (!f) { 753 if (!f) {
847 - term_printf("Could not open %s\n", USBDEVFS_PATH "/devices"); 754 + term_printf("husb: could not open %s\n", USBDEVFS_PATH "/devices");
848 return 0; 755 return 0;
849 } 756 }
850 device_count = 0; 757 device_count = 0;
@@ -954,7 +861,7 @@ static int usb_host_auto_scan(void *opaque, int bus_num, int addr, @@ -954,7 +861,7 @@ static int usb_host_auto_scan(void *opaque, int bus_num, int addr,
954 if (hostdev_find(bus_num, addr)) 861 if (hostdev_find(bus_num, addr))
955 return 0; 862 return 0;
956 863
957 - printf("Auto open: bus_num %d addr %d\n", bus_num, addr); 864 + dprintf("husb: auto open: bus_num %d addr %d\n", bus_num, addr);
958 865
959 dev = usb_host_device_open_addr(bus_num, addr, product_name); 866 dev = usb_host_device_open_addr(bus_num, addr, product_name);
960 if (dev) 867 if (dev)
@@ -978,7 +885,7 @@ static void usb_host_auto_add(int bus_num, int addr, int vendor_id, int product_ @@ -978,7 +885,7 @@ static void usb_host_auto_add(int bus_num, int addr, int vendor_id, int product_
978 { 885 {
979 struct USBAutoFilter *f = qemu_mallocz(sizeof(*f)); 886 struct USBAutoFilter *f = qemu_mallocz(sizeof(*f));
980 if (!f) { 887 if (!f) {
981 - printf("Failed to allocate auto filter\n"); 888 + printf("husb: failed to allocate auto filter\n");
982 return; 889 return;
983 } 890 }
984 891
@@ -996,7 +903,7 @@ static void usb_host_auto_add(int bus_num, int addr, int vendor_id, int product_ @@ -996,7 +903,7 @@ static void usb_host_auto_add(int bus_num, int addr, int vendor_id, int product_
996 */ 903 */
997 usb_auto_timer = qemu_new_timer(rt_clock, usb_host_auto_timer, NULL); 904 usb_auto_timer = qemu_new_timer(rt_clock, usb_host_auto_timer, NULL);
998 if (!usb_auto_timer) { 905 if (!usb_auto_timer) {
999 - printf("Failed to allocate timer\n"); 906 + printf("husb: failed to allocate timer\n");
1000 qemu_free(f); 907 qemu_free(f);
1001 return; 908 return;
1002 } 909 }
@@ -1005,7 +912,7 @@ static void usb_host_auto_add(int bus_num, int addr, int vendor_id, int product_ @@ -1005,7 +912,7 @@ static void usb_host_auto_add(int bus_num, int addr, int vendor_id, int product_
1005 qemu_mod_timer(usb_auto_timer, qemu_get_clock(rt_clock) + 2000); 912 qemu_mod_timer(usb_auto_timer, qemu_get_clock(rt_clock) + 2000);
1006 } 913 }
1007 914
1008 - printf("Auto filter: bus_num %d addr %d vid %d pid %d\n", 915 + dprintf("husb: auto filter: bus_num %d addr %d vid %d pid %d\n",
1009 bus_num, addr, vendor_id, product_id); 916 bus_num, addr, vendor_id, product_id);
1010 917
1011 f->next = usb_auto_filter; 918 f->next = usb_auto_filter;
@@ -1174,9 +1081,6 @@ void usb_host_info(void) @@ -1174,9 +1081,6 @@ void usb_host_info(void)
1174 usb_host_scan(NULL, usb_host_info_device); 1081 usb_host_scan(NULL, usb_host_info_device);
1175 } 1082 }
1176 1083
1177 -  
1178 -  
1179 -  
1180 #else 1084 #else
1181 1085
1182 void usb_host_info(void) 1086 void usb_host_info(void)