1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
---
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);
|