summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2014-03-16 13:08:09 +0100
committerPeter Wu <peter@lekensteyn.nl>2014-03-16 13:08:09 +0100
commit4d7e03e61d7a27f0a80e837f945d896c4a7f0cce (patch)
tree2ddedba198b05cc36077c07f7f18189986113b64 /hw
parentb85614cb9e5912b3fc0b11cec82417efaad3b1a7 (diff)
downloadqemu-4d7e03e61d7a27f0a80e837f945d896c4a7f0cce.tar.gz
usb-hid: usbdump example for control and interrupt IN
This is verified to reproduce the same capture as done inside the VM. The differences are in time, bInterval, URB length, URB ID and the Copy of transfer flags. Signed-off-by: Peter Wu <peter@lekensteyn.nl>
Diffstat (limited to 'hw')
-rw-r--r--hw/usb/dev-hid.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c
index f36e617632..7fef1ea41d 100644
--- a/hw/usb/dev-hid.c
+++ b/hw/usb/dev-hid.c
@@ -28,6 +28,7 @@
#include "hw/usb/desc.h"
#include "qemu/timer.h"
#include "hw/input/hid.h"
+#include "hw/usb/dump.h"
/* HID interface requests */
#define GET_REPORT 0xa101
@@ -47,6 +48,7 @@ typedef struct USBHIDState {
USBEndpoint *intr;
HIDState hid;
uint32_t usb_version;
+ UsbDumpState *usb_dump_state;
} USBHIDState;
enum {
@@ -448,8 +450,11 @@ static void usb_hid_handle_control(USBDevice *dev, USBPacket *p,
HIDState *hs = &us->hid;
int ret;
+ usb_dump_submit(us->usb_dump_state, p);
+
ret = usb_desc_handle_control(dev, p, request, value, index, length, data);
if (ret >= 0) {
+ usb_dump_complete(us->usb_dump_state, p);
return;
}
@@ -519,6 +524,7 @@ static void usb_hid_handle_control(USBDevice *dev, USBPacket *p,
p->status = USB_RET_STALL;
break;
}
+ usb_dump_complete(us->usb_dump_state, p);
}
static void usb_hid_handle_data(USBDevice *dev, USBPacket *p)
@@ -544,7 +550,11 @@ static void usb_hid_handle_data(USBDevice *dev, USBPacket *p)
} else if (hs->kind == HID_KEYBOARD) {
len = hid_keyboard_poll(hs, buf, p->iov.size);
}
+ /* feed back data to host */
+ usb_dump_complete_data(us->usb_dump_state, p, buf, len);
usb_packet_copy(p, buf, len);
+ /* as this is an interrupt, pretend that host submitted request */
+ usb_dump_submit(us->usb_dump_state, p);
} else {
goto fail;
}
@@ -561,6 +571,11 @@ static void usb_hid_handle_destroy(USBDevice *dev)
{
USBHIDState *us = DO_UPCAST(USBHIDState, dev, dev);
+ if (us->usb_dump_state) {
+ usb_dump_cleanup(us->usb_dump_state);
+ g_free(us->usb_dump_state);
+ us->usb_dump_state = NULL;
+ }
hid_free(&us->hid);
}
@@ -574,6 +589,8 @@ static int usb_hid_initfn(USBDevice *dev, int kind)
usb_desc_init(dev);
us->intr = usb_ep_get(dev, USB_TOKEN_IN, 1);
hid_init(&us->hid, kind, usb_hid_changed);
+ // TODO: API sucks...
+ us->usb_dump_state = usb_dump_init_alloc("/tmp/usbdump.pcap");
return 0;
}