--- usb-linux.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) --- qemu-0.12.3.orig/usb-linux.c +++ qemu-0.12.3/usb-linux.c @@ -150,6 +150,57 @@ static int usb_host_close(USBHostDevice static int parse_filter(const char *spec, struct USBAutoFilter *f); static void usb_host_auto_check(void *unused); +static unsigned int get_vendor_id(USBHostDevice *dev) +{ + return dev->descr[9] | ((unsigned int)dev->descr[8] << 8); +} + +static unsigned int get_device_id(USBHostDevice *dev) +{ + return dev->descr[11] | ((unsigned int)dev->descr[10] << 8); +} + +static char toAscii(char c) +{ + if (c >= 32 && c <= 126) + return c; + return '.'; +} + +static void dump(USBHostDevice *dev, const char *prefix, unsigned int ep, char *buf, size_t size) +{ + size_t i; + char ascii[17]; + char tmp[2] = { 0, }; + + printf("Dev %04X:%04X EP%02X %s len=%u\n", + get_vendor_id(dev), get_device_id(dev), + ep, prefix, (unsigned int)size); + + memset(ascii, 0, sizeof(ascii)); + for (i = 0; i < size; i++) { + if (i % 16 == 0) { + if (i != 0) { + printf(" |%s|\n", ascii); + memset(ascii, 0, sizeof(ascii)); + } + printf("[%04X]: ", i); + } + if (i % 2 == 0) + printf(" %02X", buf[i]); + else + printf("%02X", buf[i]); + tmp[0] = toAscii(buf[i]); + strcat(ascii, tmp); + } + if (strlen(ascii)) { + for ( ; i % 16; i++) + printf(" %s", (i % 2 == 0) ? " " : ""); + printf(" |%s|", ascii); + } + printf("\n\n"); +} + static int is_isoc(USBHostDevice *s, int ep) { return s->endp_table[ep - 1].type == USBDEVFS_URB_TYPE_ISO; @@ -247,8 +298,14 @@ static void async_complete(void *opaque) switch (aurb->urb.status) { case 0: p->len = aurb->urb.actual_length; - if (aurb->urb.type == USBDEVFS_URB_TYPE_CONTROL) + if (aurb->urb.type == USBDEVFS_URB_TYPE_CONTROL) { + if (((char *)aurb->urb.buffer)[0] & 0x80) + dump(s, "Control IN", 0, aurb->urb.buffer, aurb->urb.buffer_length); async_complete_ctrl(s, p); + } else { + if (p->pid == USB_TOKEN_IN) + dump(s, "Bulk IN", aurb->urb.endpoint, aurb->urb.buffer, aurb->urb.buffer_length); + } break; case -EPIPE: @@ -447,6 +504,8 @@ static int usb_host_handle_data(USBHostD urb->usercontext = s; + if (p->pid != USB_TOKEN_IN) + dump(s, "Bulk OUT", urb->endpoint, urb->buffer, urb->buffer_length); ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb); dprintf("husb: data submit. ep 0x%x len %u aurb %p\n", urb->endpoint, p->len, aurb); @@ -538,16 +597,20 @@ static int usb_host_handle_control(USBHo if (s->ctrl.req.bRequestType == 0) { switch (s->ctrl.req.bRequest) { case USB_REQ_SET_ADDRESS: + printf("USB SET_ADDRESS %u\n", value); return usb_host_set_address(s, value); case USB_REQ_SET_CONFIGURATION: + printf("USB SET_CONFIGURATION %u\n", value & 0xFF); return usb_host_set_config(s, value & 0xff); } } if (s->ctrl.req.bRequestType == 1 && - s->ctrl.req.bRequest == USB_REQ_SET_INTERFACE) + s->ctrl.req.bRequest == USB_REQ_SET_INTERFACE) { + printf("USB SET_INTERFACE %u %u\n", index, value); return usb_host_set_interface(s, index, value); + } /* The rest are asynchronous */ @@ -578,6 +641,8 @@ static int usb_host_handle_control(USBHo urb->usercontext = s; + if (!(((char *)urb->buffer)[0] & 0x80)) + dump(s, "Control OUT", 0, urb->buffer, urb->buffer_length); ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb); dprintf("husb: submit ctrl. len %u aurb %p\n", urb->buffer_length, aurb);