summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;
}