summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2014-03-15 19:11:35 +0100
committerPeter Wu <peter@lekensteyn.nl>2014-03-16 00:10:06 +0100
commit8338d28302fad8e8abc00fcb36751b9728f746b2 (patch)
treec7527049d93713a07a480076ad02222d2bf0c51a
parent94a49b505d904ee976d999364bf19945eac7b991 (diff)
downloadqemu-8338d28302fad8e8abc00fcb36751b9728f746b2.tar.gz
usbdump: fix reversal of URB length and captured length
The "length" field stores the expected size of data. "len_cap" stores the real length of the data in the current packet (the "captured" data). Also try to set a slightly more sane length value depending on submission type, but this is much braindead. Signed-off-by: Peter Wu <peter@lekensteyn.nl>
-rw-r--r--hw/usb/dump.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/hw/usb/dump.c b/hw/usb/dump.c
index 4c6445e379..b756e5840b 100644
--- a/hw/usb/dump.c
+++ b/hw/usb/dump.c
@@ -105,7 +105,7 @@ static void usb_dump_packet(UsbDumpState *s, struct usbmon_packet *usbhdr,
{
struct pcap_sf_pkthdr hdr;
size_t orig_size;
- unsigned datalen = usbhdr->length;
+ unsigned datalen = usbhdr->len_cap;
/* Early return in case of previous error. */
if (s->fd < 0) {
@@ -224,11 +224,18 @@ static void init_from_usbpacket(UsbDumpState *s, struct usbmon_packet *u,
}
/* uint32_t - 32: Length of data (submitted or actual) */
- u->length = datalen;
+ if (ev_type == 'S') {
+ /* This is supposed to contain the length of the data buffer, but is
+ * much broken and probably unreliable. For IN transfers, it will always
+ * be 0 where Linux sets the size it would expect. */
+ u->length = p->actual_length;
+ } else {
+ /* actual length of the callback data */
+ u->length = datalen;
+ }
/* uint32_t - 36: Delivered length */
- u->len_cap = 0; /* TODO: find a sane value for this */
- // (this is also the "allowed" length for callback?)
+ u->len_cap = datalen;
// TODO: s.setup data? Only valid for Control Submissions
if (ev_type == 'S' && p->ep->type == USB_ENDPOINT_XFER_CONTROL) {