Commit 446ab1284e0648eb9e2bfd08edb769bcd22dccb2

Authored by aliguori
1 parent 9d0efc88

husb: Make control transactions asynchronous (Max Krasnyansky)

USB is 99.8% async now :). 0.2% is the three control requests that
we need to execute synchronously. We could off-load that to a thread
or something but it's not worth the pain since those requests are
performed only during device initialization (ie when device is
connected to the VM).

The change is a bit bigger than I wanted due to the fact that generic
handle_packet()/handle_control() interface was not designed for
async transactions. So I ended up adding custom handle_packet()
code to usb-linux. We can make that generic if/when some other
component needs it.

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@5204 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 371 additions and 93 deletions
usb-linux.c
@@ -25,28 +25,20 @@ @@ -25,28 +25,20 @@
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 * THE SOFTWARE. 26 * THE SOFTWARE.
27 */ 27 */
  28 +
28 #include "qemu-common.h" 29 #include "qemu-common.h"
29 #include "qemu-timer.h" 30 #include "qemu-timer.h"
30 -#include "hw/usb.h"  
31 #include "console.h" 31 #include "console.h"
32 32
33 #if defined(__linux__) 33 #if defined(__linux__)
34 #include <dirent.h> 34 #include <dirent.h>
35 #include <sys/ioctl.h> 35 #include <sys/ioctl.h>
36 -#include <linux/usbdevice_fs.h>  
37 -#include <linux/version.h>  
38 #include <signal.h> 36 #include <signal.h>
39 37
40 -/* We redefine it to avoid version problems */  
41 -struct usb_ctrltransfer {  
42 - uint8_t bRequestType;  
43 - uint8_t bRequest;  
44 - uint16_t wValue;  
45 - uint16_t wIndex;  
46 - uint16_t wLength;  
47 - uint32_t timeout;  
48 - void *data;  
49 -}; 38 +#include <linux/usb/ch9.h>
  39 +#include <linux/usbdevice_fs.h>
  40 +#include <linux/version.h>
  41 +#include "hw/usb.h"
50 42
51 typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id, 43 typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id,
52 int vendor_id, int product_id, 44 int vendor_id, int product_id,
@@ -54,7 +46,6 @@ typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id, @@ -54,7 +46,6 @@ typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id,
54 static int usb_host_find_device(int *pbus_num, int *paddr, 46 static int usb_host_find_device(int *pbus_num, int *paddr,
55 char *product_name, int product_name_size, 47 char *product_name, int product_name_size,
56 const char *devname); 48 const char *devname);
57 -  
58 //#define DEBUG 49 //#define DEBUG
59 50
60 #ifdef DEBUG 51 #ifdef DEBUG
@@ -67,14 +58,32 @@ static int usb_host_find_device(int *pbus_num, int *paddr, @@ -67,14 +58,32 @@ static int usb_host_find_device(int *pbus_num, int *paddr,
67 #define PRODUCT_NAME_SZ 32 58 #define PRODUCT_NAME_SZ 32
68 #define MAX_ENDPOINTS 16 59 #define MAX_ENDPOINTS 16
69 60
70 -struct sigaction sigact;  
71 -  
72 /* endpoint association data */ 61 /* endpoint association data */
73 struct endp_data { 62 struct endp_data {
74 uint8_t type; 63 uint8_t type;
75 uint8_t halted; 64 uint8_t halted;
76 }; 65 };
77 66
  67 +enum {
  68 + CTRL_STATE_IDLE = 0,
  69 + CTRL_STATE_SETUP,
  70 + CTRL_STATE_DATA,
  71 + CTRL_STATE_ACK
  72 +};
  73 +
  74 +/*
  75 + * Control transfer state.
  76 + * Note that 'buffer' _must_ follow 'req' field because
  77 + * we need contigious buffer when we submit control URB.
  78 + */
  79 +struct ctrl_struct {
  80 + uint16_t len;
  81 + uint16_t offset;
  82 + uint8_t state;
  83 + struct usb_ctrlrequest req;
  84 + uint8_t buffer[1024];
  85 +};
  86 +
78 typedef struct USBHostDevice { 87 typedef struct USBHostDevice {
79 USBDevice dev; 88 USBDevice dev;
80 int fd; 89 int fd;
@@ -82,8 +91,10 @@ typedef struct USBHostDevice { @@ -82,8 +91,10 @@ typedef struct USBHostDevice {
82 uint8_t descr[1024]; 91 uint8_t descr[1024];
83 int descr_len; 92 int descr_len;
84 int configuration; 93 int configuration;
  94 + int ninterfaces;
85 int closing; 95 int closing;
86 96
  97 + struct ctrl_struct ctrl;
87 struct endp_data endp_table[MAX_ENDPOINTS]; 98 struct endp_data endp_table[MAX_ENDPOINTS];
88 99
89 /* Host side address */ 100 /* Host side address */
@@ -172,6 +183,26 @@ static void async_free(AsyncURB *aurb) @@ -172,6 +183,26 @@ static void async_free(AsyncURB *aurb)
172 qemu_free(aurb); 183 qemu_free(aurb);
173 } 184 }
174 185
  186 +static void async_complete_ctrl(USBHostDevice *s, USBPacket *p)
  187 +{
  188 + switch(s->ctrl.state) {
  189 + case CTRL_STATE_SETUP:
  190 + if (p->len < s->ctrl.len)
  191 + s->ctrl.len = p->len;
  192 + s->ctrl.state = CTRL_STATE_DATA;
  193 + p->len = 8;
  194 + break;
  195 +
  196 + case CTRL_STATE_ACK:
  197 + s->ctrl.state = CTRL_STATE_IDLE;
  198 + p->len = 0;
  199 + break;
  200 +
  201 + default:
  202 + break;
  203 + }
  204 +}
  205 +
175 static void async_complete(void *opaque) 206 static void async_complete(void *opaque)
176 { 207 {
177 USBHostDevice *s = opaque; 208 USBHostDevice *s = opaque;
@@ -204,6 +235,8 @@ static void async_complete(void *opaque) @@ -204,6 +235,8 @@ static void async_complete(void *opaque)
204 switch (aurb->urb.status) { 235 switch (aurb->urb.status) {
205 case 0: 236 case 0:
206 p->len = aurb->urb.actual_length; 237 p->len = aurb->urb.actual_length;
  238 + if (aurb->urb.type == USBDEVFS_URB_TYPE_CONTROL)
  239 + async_complete_ctrl(s, p);
207 break; 240 break;
208 241
209 case -EPIPE: 242 case -EPIPE:
@@ -237,7 +270,7 @@ static void async_cancel(USBPacket *unused, void *opaque) @@ -237,7 +270,7 @@ static void async_cancel(USBPacket *unused, void *opaque)
237 } 270 }
238 } 271 }
239 272
240 -static int usb_host_update_interfaces(USBHostDevice *dev, int configuration) 273 +static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration)
241 { 274 {
242 int dev_descr_len, config_descr_len; 275 int dev_descr_len, config_descr_len;
243 int interface, nb_interfaces, nb_configurations; 276 int interface, nb_interfaces, nb_configurations;
@@ -246,6 +279,8 @@ static int usb_host_update_interfaces(USBHostDevice *dev, int configuration) @@ -246,6 +279,8 @@ static int usb_host_update_interfaces(USBHostDevice *dev, int configuration)
246 if (configuration == 0) /* address state - ignore */ 279 if (configuration == 0) /* address state - ignore */
247 return 1; 280 return 1;
248 281
  282 + dprintf("husb: claiming interfaces. config %d\n", configuration);
  283 +
249 i = 0; 284 i = 0;
250 dev_descr_len = dev->descr[0]; 285 dev_descr_len = dev->descr[0];
251 if (dev_descr_len > dev->descr_len) 286 if (dev_descr_len > dev->descr_len)
@@ -265,8 +300,10 @@ static int usb_host_update_interfaces(USBHostDevice *dev, int configuration) @@ -265,8 +300,10 @@ static int usb_host_update_interfaces(USBHostDevice *dev, int configuration)
265 300
266 printf("husb: config #%d need %d\n", dev->descr[i + 5], configuration); 301 printf("husb: config #%d need %d\n", dev->descr[i + 5], configuration);
267 302
268 - if (configuration < 0 || configuration == dev->descr[i + 5]) 303 + if (configuration < 0 || configuration == dev->descr[i + 5]) {
  304 + configuration = dev->descr[i + 5];
269 break; 305 break;
  306 + }
270 307
271 i += config_descr_len; 308 i += config_descr_len;
272 } 309 }
@@ -310,17 +347,37 @@ static int usb_host_update_interfaces(USBHostDevice *dev, int configuration) @@ -310,17 +347,37 @@ static int usb_host_update_interfaces(USBHostDevice *dev, int configuration)
310 printf("husb: %d interfaces claimed for configuration %d\n", 347 printf("husb: %d interfaces claimed for configuration %d\n",
311 nb_interfaces, configuration); 348 nb_interfaces, configuration);
312 349
  350 + dev->ninterfaces = nb_interfaces;
  351 + dev->configuration = configuration;
  352 + return 1;
  353 +}
  354 +
  355 +static int usb_host_release_interfaces(USBHostDevice *s)
  356 +{
  357 + int ret, i;
  358 +
  359 + dprintf("husb: releasing interfaces\n");
  360 +
  361 + for (i = 0; i < s->ninterfaces; i++) {
  362 + ret = ioctl(s->fd, USBDEVFS_RELEASEINTERFACE, &i);
  363 + if (ret < 0) {
  364 + perror("husb: failed to release interface");
  365 + return 0;
  366 + }
  367 + }
  368 +
313 return 1; 369 return 1;
314 } 370 }
315 371
316 static void usb_host_handle_reset(USBDevice *dev) 372 static void usb_host_handle_reset(USBDevice *dev)
317 { 373 {
318 - USBHostDevice *s = (USBHostDevice *)dev; 374 + USBHostDevice *s = (USBHostDevice *) dev;
319 375
320 dprintf("husb: reset device %u.%u\n", s->bus_num, s->addr); 376 dprintf("husb: reset device %u.%u\n", s->bus_num, s->addr);
321 377
322 ioctl(s->fd, USBDEVFS_RESET); 378 ioctl(s->fd, USBDEVFS_RESET);
323 - usb_host_update_interfaces(s, s->configuration); 379 +
  380 + usb_host_claim_interfaces(s, s->configuration);
324 } 381 }
325 382
326 static void usb_host_handle_destroy(USBDevice *dev) 383 static void usb_host_handle_destroy(USBDevice *dev)
@@ -343,73 +400,10 @@ static void usb_host_handle_destroy(USBDevice *dev) @@ -343,73 +400,10 @@ static void usb_host_handle_destroy(USBDevice *dev)
343 400
344 static int usb_linux_update_endp_table(USBHostDevice *s); 401 static int usb_linux_update_endp_table(USBHostDevice *s);
345 402
346 -static int usb_host_handle_control(USBDevice *dev,  
347 - int request,  
348 - int value,  
349 - int index,  
350 - int length,  
351 - uint8_t *data)  
352 -{  
353 - USBHostDevice *s = (USBHostDevice *)dev;  
354 - struct usb_ctrltransfer ct;  
355 - struct usbdevfs_setinterface si;  
356 - int intf_update_required = 0;  
357 - int ret;  
358 -  
359 - if (request == (DeviceOutRequest | USB_REQ_SET_ADDRESS)) {  
360 - /* specific SET_ADDRESS support */  
361 - dev->addr = value;  
362 - return 0;  
363 - } else if (request == ((USB_RECIP_INTERFACE << 8) |  
364 - USB_REQ_SET_INTERFACE)) {  
365 - /* set alternate setting for the interface */  
366 - si.interface = index;  
367 - si.altsetting = value;  
368 - ret = ioctl(s->fd, USBDEVFS_SETINTERFACE, &si);  
369 - usb_linux_update_endp_table(s);  
370 - } else if (request == (DeviceOutRequest | USB_REQ_SET_CONFIGURATION)) {  
371 - dprintf("husb: ctrl set config %d\n", value & 0xff);  
372 - if (s->configuration != (value & 0xff)) {  
373 - s->configuration = (value & 0xff);  
374 - intf_update_required = 1;  
375 - }  
376 - goto do_request;  
377 - } else {  
378 - do_request:  
379 - ct.bRequestType = request >> 8;  
380 - ct.bRequest = request;  
381 - ct.wValue = value;  
382 - ct.wIndex = index;  
383 - ct.wLength = length;  
384 - ct.timeout = 50;  
385 - ct.data = data;  
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);  
390 - }  
391 -  
392 - if (ret < 0) {  
393 - switch(errno) {  
394 - case ETIMEDOUT:  
395 - return USB_RET_NAK;  
396 - default:  
397 - return USB_RET_STALL;  
398 - }  
399 - } else {  
400 - if (intf_update_required) {  
401 - dprintf("husb: updating interfaces\n");  
402 - usb_host_update_interfaces(s, value & 0xff);  
403 - }  
404 - return ret;  
405 - }  
406 -}  
407 -  
408 -static int usb_host_handle_data(USBDevice *dev, USBPacket *p) 403 +static int usb_host_handle_data(USBHostDevice *s, USBPacket *p)
409 { 404 {
410 - USBHostDevice *s = (USBHostDevice *) dev;  
411 - AsyncURB *aurb;  
412 struct usbdevfs_urb *urb; 405 struct usbdevfs_urb *urb;
  406 + AsyncURB *aurb;
413 int ret; 407 int ret;
414 408
415 aurb = async_alloc(); 409 aurb = async_alloc();
@@ -474,12 +468,292 @@ static int usb_host_handle_data(USBDevice *dev, USBPacket *p) @@ -474,12 +468,292 @@ static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
474 return USB_RET_ASYNC; 468 return USB_RET_ASYNC;
475 } 469 }
476 470
  471 +static int ctrl_error(void)
  472 +{
  473 + if (errno == ETIMEDOUT)
  474 + return USB_RET_NAK;
  475 + else
  476 + return USB_RET_STALL;
  477 +}
  478 +
  479 +static int usb_host_set_address(USBHostDevice *s, int addr)
  480 +{
  481 + dprintf("husb: ctrl set addr %u\n", addr);
  482 + s->dev.addr = addr;
  483 + return 0;
  484 +}
  485 +
  486 +static int usb_host_set_config(USBHostDevice *s, int config)
  487 +{
  488 + usb_host_release_interfaces(s);
  489 +
  490 + int ret = ioctl(s->fd, USBDEVFS_SETCONFIGURATION, &config);
  491 +
  492 + dprintf("husb: ctrl set config %d ret %d errno %d\n", config, ret, errno);
  493 +
  494 + if (ret < 0)
  495 + return ctrl_error();
  496 +
  497 + usb_host_claim_interfaces(s, config);
  498 + return 0;
  499 +}
  500 +
  501 +static int usb_host_set_interface(USBHostDevice *s, int iface, int alt)
  502 +{
  503 + struct usbdevfs_setinterface si;
  504 + int ret;
  505 +
  506 + si.interface = iface;
  507 + si.altsetting = alt;
  508 + ret = ioctl(s->fd, USBDEVFS_SETINTERFACE, &si);
  509 +
  510 + dprintf("husb: ctrl set iface %d altset %d ret %d errno %d\n",
  511 + iface, alt, ret, errno);
  512 +
  513 + if (ret < 0)
  514 + return ctrl_error();
  515 +
  516 + usb_linux_update_endp_table(s);
  517 + return 0;
  518 +}
  519 +
  520 +static int usb_host_handle_control(USBHostDevice *s, USBPacket *p)
  521 +{
  522 + struct usbdevfs_urb *urb;
  523 + AsyncURB *aurb;
  524 + int ret, value, index;
  525 +
  526 + /*
  527 + * Process certain standard device requests.
  528 + * These are infrequent and are processed synchronously.
  529 + */
  530 + value = le16_to_cpu(s->ctrl.req.wValue);
  531 + index = le16_to_cpu(s->ctrl.req.wIndex);
  532 +
  533 + dprintf("husb: ctrl type 0x%x req 0x%x val 0x%x index %u len %u\n",
  534 + s->ctrl.req.bRequestType, s->ctrl.req.bRequest, value, index,
  535 + s->ctrl.len);
  536 +
  537 + if (s->ctrl.req.bRequestType == 0) {
  538 + switch (s->ctrl.req.bRequest) {
  539 + case USB_REQ_SET_ADDRESS:
  540 + return usb_host_set_address(s, value);
  541 +
  542 + case USB_REQ_SET_CONFIGURATION:
  543 + return usb_host_set_config(s, value & 0xff);
  544 + }
  545 + }
  546 +
  547 + if (s->ctrl.req.bRequestType == 1 &&
  548 + s->ctrl.req.bRequest == USB_REQ_SET_INTERFACE)
  549 + return usb_host_set_interface(s, index, value);
  550 +
  551 + /* The rest are asynchronous */
  552 +
  553 + aurb = async_alloc();
  554 + if (!aurb) {
  555 + dprintf("husb: async malloc failed\n");
  556 + return USB_RET_NAK;
  557 + }
  558 + aurb->hdev = s;
  559 + aurb->packet = p;
  560 +
  561 + /*
  562 + * Setup ctrl transfer.
  563 + *
  564 + * s->ctrl is layed out such that data buffer immediately follows
  565 + * 'req' struct which is exactly what usbdevfs expects.
  566 + */
  567 + urb = &aurb->urb;
  568 +
  569 + urb->type = USBDEVFS_URB_TYPE_CONTROL;
  570 + urb->endpoint = p->devep;
  571 +
  572 + urb->buffer = &s->ctrl.req;
  573 + urb->buffer_length = 8 + s->ctrl.len;
  574 +
  575 + urb->usercontext = s;
  576 +
  577 + ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
  578 +
  579 + dprintf("husb: submit ctrl. len %u aurb %p\n", urb->buffer_length, aurb);
  580 +
  581 + if (ret < 0) {
  582 + dprintf("husb: submit failed. errno %d\n", errno);
  583 + async_free(aurb);
  584 +
  585 + switch(errno) {
  586 + case ETIMEDOUT:
  587 + return USB_RET_NAK;
  588 + case EPIPE:
  589 + default:
  590 + return USB_RET_STALL;
  591 + }
  592 + }
  593 +
  594 + usb_defer_packet(p, async_cancel, aurb);
  595 + return USB_RET_ASYNC;
  596 +}
  597 +
  598 +static int do_token_setup(USBDevice *dev, USBPacket *p)
  599 +{
  600 + USBHostDevice *s = (USBHostDevice *) dev;
  601 + int ret = 0;
  602 +
  603 + if (p->len != 8)
  604 + return USB_RET_STALL;
  605 +
  606 + memcpy(&s->ctrl.req, p->data, 8);
  607 + s->ctrl.len = le16_to_cpu(s->ctrl.req.wLength);
  608 + s->ctrl.offset = 0;
  609 + s->ctrl.state = CTRL_STATE_SETUP;
  610 +
  611 + if (s->ctrl.req.bRequestType & USB_DIR_IN) {
  612 + ret = usb_host_handle_control(s, p);
  613 + if (ret < 0)
  614 + return ret;
  615 +
  616 + if (ret < s->ctrl.len)
  617 + s->ctrl.len = ret;
  618 + s->ctrl.state = CTRL_STATE_DATA;
  619 + } else {
  620 + if (s->ctrl.len == 0)
  621 + s->ctrl.state = CTRL_STATE_ACK;
  622 + else
  623 + s->ctrl.state = CTRL_STATE_DATA;
  624 + }
  625 +
  626 + return ret;
  627 +}
  628 +
  629 +static int do_token_in(USBDevice *dev, USBPacket *p)
  630 +{
  631 + USBHostDevice *s = (USBHostDevice *) dev;
  632 + int ret = 0;
  633 +
  634 + if (p->devep != 0)
  635 + return usb_host_handle_data(s, p);
  636 +
  637 + switch(s->ctrl.state) {
  638 + case CTRL_STATE_ACK:
  639 + if (!(s->ctrl.req.bRequestType & USB_DIR_IN)) {
  640 + ret = usb_host_handle_control(s, p);
  641 + if (ret == USB_RET_ASYNC)
  642 + return USB_RET_ASYNC;
  643 +
  644 + s->ctrl.state = CTRL_STATE_IDLE;
  645 + return ret > 0 ? 0 : ret;
  646 + }
  647 +
  648 + return 0;
  649 +
  650 + case CTRL_STATE_DATA:
  651 + if (s->ctrl.req.bRequestType & USB_DIR_IN) {
  652 + int len = s->ctrl.len - s->ctrl.offset;
  653 + if (len > p->len)
  654 + len = p->len;
  655 + memcpy(p->data, s->ctrl.buffer + s->ctrl.offset, len);
  656 + s->ctrl.offset += len;
  657 + if (s->ctrl.offset >= s->ctrl.len)
  658 + s->ctrl.state = CTRL_STATE_ACK;
  659 + return len;
  660 + }
  661 +
  662 + s->ctrl.state = CTRL_STATE_IDLE;
  663 + return USB_RET_STALL;
  664 +
  665 + default:
  666 + return USB_RET_STALL;
  667 + }
  668 +}
  669 +
  670 +static int do_token_out(USBDevice *dev, USBPacket *p)
  671 +{
  672 + USBHostDevice *s = (USBHostDevice *) dev;
  673 +
  674 + if (p->devep != 0)
  675 + return usb_host_handle_data(s, p);
  676 +
  677 + switch(s->ctrl.state) {
  678 + case CTRL_STATE_ACK:
  679 + if (s->ctrl.req.bRequestType & USB_DIR_IN) {
  680 + s->ctrl.state = CTRL_STATE_IDLE;
  681 + /* transfer OK */
  682 + } else {
  683 + /* ignore additional output */
  684 + }
  685 + return 0;
  686 +
  687 + case CTRL_STATE_DATA:
  688 + if (!(s->ctrl.req.bRequestType & USB_DIR_IN)) {
  689 + int len = s->ctrl.len - s->ctrl.offset;
  690 + if (len > p->len)
  691 + len = p->len;
  692 + memcpy(s->ctrl.buffer + s->ctrl.offset, p->data, len);
  693 + s->ctrl.offset += len;
  694 + if (s->ctrl.offset >= s->ctrl.len)
  695 + s->ctrl.state = CTRL_STATE_ACK;
  696 + return len;
  697 + }
  698 +
  699 + s->ctrl.state = CTRL_STATE_IDLE;
  700 + return USB_RET_STALL;
  701 +
  702 + default:
  703 + return USB_RET_STALL;
  704 + }
  705 +}
  706 +
  707 +/*
  708 + * Packet handler.
  709 + * Called by the HC (host controller).
  710 + *
  711 + * Returns length of the transaction or one of the USB_RET_XXX codes.
  712 + */
  713 +int usb_host_handle_packet(USBDevice *s, USBPacket *p)
  714 +{
  715 + switch(p->pid) {
  716 + case USB_MSG_ATTACH:
  717 + s->state = USB_STATE_ATTACHED;
  718 + return 0;
  719 +
  720 + case USB_MSG_DETACH:
  721 + s->state = USB_STATE_NOTATTACHED;
  722 + return 0;
  723 +
  724 + case USB_MSG_RESET:
  725 + s->remote_wakeup = 0;
  726 + s->addr = 0;
  727 + s->state = USB_STATE_DEFAULT;
  728 + s->handle_reset(s);
  729 + return 0;
  730 + }
  731 +
  732 + /* Rest of the PIDs must match our address */
  733 + if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
  734 + return USB_RET_NODEV;
  735 +
  736 + switch (p->pid) {
  737 + case USB_TOKEN_SETUP:
  738 + return do_token_setup(s, p);
  739 +
  740 + case USB_TOKEN_IN:
  741 + return do_token_in(s, p);
  742 +
  743 + case USB_TOKEN_OUT:
  744 + return do_token_out(s, p);
  745 +
  746 + default:
  747 + return USB_RET_STALL;
  748 + }
  749 +}
  750 +
477 /* returns 1 on problem encountered or 0 for success */ 751 /* returns 1 on problem encountered or 0 for success */
478 static int usb_linux_update_endp_table(USBHostDevice *s) 752 static int usb_linux_update_endp_table(USBHostDevice *s)
479 { 753 {
480 uint8_t *descriptors; 754 uint8_t *descriptors;
481 uint8_t devep, type, configuration, alt_interface; 755 uint8_t devep, type, configuration, alt_interface;
482 - struct usb_ctrltransfer ct; 756 + struct usbdevfs_ctrltransfer ct;
483 int interface, ret, length, i; 757 int interface, ret, length, i;
484 758
485 ct.bRequestType = USB_DIR_IN; 759 ct.bRequestType = USB_DIR_IN;
@@ -624,10 +898,14 @@ static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *p @@ -624,10 +898,14 @@ static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *p
624 #endif 898 #endif
625 899
626 dev->fd = fd; 900 dev->fd = fd;
627 - dev->configuration = 1;  
628 901
629 - /* XXX - do something about initial configuration */  
630 - if (!usb_host_update_interfaces(dev, -1)) 902 + /*
  903 + * Initial configuration is -1 which makes us claim first
  904 + * available config. We used to start with 1, which does not
  905 + * always work. I've seen devices where first config starts
  906 + * with 2.
  907 + */
  908 + if (!usb_host_claim_interfaces(dev, -1))
631 goto fail; 909 goto fail;
632 910
633 ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci); 911 ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
@@ -646,11 +924,9 @@ static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *p @@ -646,11 +924,9 @@ static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *p
646 dev->dev.speed = USB_SPEED_LOW; 924 dev->dev.speed = USB_SPEED_LOW;
647 else 925 else
648 dev->dev.speed = USB_SPEED_HIGH; 926 dev->dev.speed = USB_SPEED_HIGH;
649 - dev->dev.handle_packet = usb_generic_handle_packet;  
650 927
651 - dev->dev.handle_reset = usb_host_handle_reset;  
652 - dev->dev.handle_control = usb_host_handle_control;  
653 - dev->dev.handle_data = usb_host_handle_data; 928 + dev->dev.handle_packet = usb_host_handle_packet;
  929 + dev->dev.handle_reset = usb_host_handle_reset;
654 dev->dev.handle_destroy = usb_host_handle_destroy; 930 dev->dev.handle_destroy = usb_host_handle_destroy;
655 931
656 if (!prod_name || prod_name[0] == '\0') 932 if (!prod_name || prod_name[0] == '\0')
@@ -1055,6 +1331,8 @@ void usb_host_info(void) @@ -1055,6 +1331,8 @@ void usb_host_info(void)
1055 1331
1056 #else 1332 #else
1057 1333
  1334 +#include "hw/usb.h"
  1335 +
1058 void usb_host_info(void) 1336 void usb_host_info(void)
1059 { 1337 {
1060 term_printf("USB host devices not supported\n"); 1338 term_printf("USB host devices not supported\n");