diff options
author | Peter Wu <peter@lekensteyn.nl> | 2014-03-16 13:08:09 +0100 |
---|---|---|
committer | Peter Wu <peter@lekensteyn.nl> | 2014-03-16 13:08:09 +0100 |
commit | 4d7e03e61d7a27f0a80e837f945d896c4a7f0cce (patch) | |
tree | 2ddedba198b05cc36077c07f7f18189986113b64 /hw | |
parent | b85614cb9e5912b3fc0b11cec82417efaad3b1a7 (diff) | |
download | qemu-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.c | 17 |
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; } |