diff options
author | Peter Wu <peter@lekensteyn.nl> | 2014-03-15 17:51:06 +0100 |
---|---|---|
committer | Peter Wu <peter@lekensteyn.nl> | 2014-03-16 00:10:06 +0100 |
commit | f47dd59ee594e62029a919b20fc048ce8421b0c2 (patch) | |
tree | f1699dfa7a8643256695012fd7309acbe2e36ad6 /hw/usb/dump.c | |
parent | 43d6464d410136f1c083a6df263bb71319eb2244 (diff) | |
download | qemu-f47dd59ee594e62029a919b20fc048ce8421b0c2.tar.gz |
usbdump: initial API extension for handle_data
Signed-off-by: Peter Wu <peter@lekensteyn.nl>
Diffstat (limited to 'hw/usb/dump.c')
-rw-r--r-- | hw/usb/dump.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/hw/usb/dump.c b/hw/usb/dump.c index eb4ce336e4..bff9bcd601 100644 --- a/hw/usb/dump.c +++ b/hw/usb/dump.c @@ -258,6 +258,9 @@ static void init_from_usbpacket(UsbDumpState *s, struct usbmon_packet *u, } + +/* control transfers; data request for interrupt, bulk, isochronous transfers */ + void usb_dump_submit(UsbDumpState *s, USBPacket *p) { struct usbmon_packet u; @@ -283,6 +286,8 @@ void usb_dump_submit(UsbDumpState *s, USBPacket *p) assert(ep_type == USB_ENDPOINT_XFER_ISOC || ep_type == USB_ENDPOINT_XFER_BULK || ep_type == USB_ENDPOINT_XFER_INT); + /* no data submitted, must be a IN request */ + assert(pid == USB_TOKEN_IN); } init_from_usbpacket(s, &u, p, 'S', datalen); @@ -313,12 +318,63 @@ void usb_dump_complete(UsbDumpState *s, USBPacket *p) assert(ep_type == USB_ENDPOINT_XFER_ISOC || ep_type == USB_ENDPOINT_XFER_BULK || ep_type == USB_ENDPOINT_XFER_INT); + /* no ack of data, must have received data for processing. + * Alternative: no data could be created due to an error. */ + assert(pid == USB_TOKEN_OUT || + (pid == USB_TOKEN_IN && p->status != USB_RET_SUCCESS)); } init_from_usbpacket(s, &u, p, 'C', datalen); usb_dump_packet(s, &u, dev->data_buf); } + +/* data for interrupt, bulk, isochronous transfers */ + +void usb_dump_submit_data(UsbDumpState *s, USBPacket *p, + uint8_t *data, size_t len) +{ + struct usbmon_packet u; + uint8_t pid = p->pid; + uint8_t ep_type = p->ep->type; + + /* fail early if not configured */ + if (!s || s->fd < 0) { + return; + } + + assert(ep_type == USB_ENDPOINT_XFER_ISOC || + ep_type == USB_ENDPOINT_XFER_BULK || + ep_type == USB_ENDPOINT_XFER_INT); + /* got data for device, must be an OUT request */ + assert(pid == USB_TOKEN_OUT); + + init_from_usbpacket(s, &u, p, 'S', len); + usb_dump_packet(s, &u, data); +} + +void usb_dump_complete_data(UsbDumpState *s, USBPacket *p, + uint8_t *data, size_t len) +{ + struct usbmon_packet u; + uint8_t pid = p->pid; + uint8_t ep_type = p->ep->type; + + /* fail early if not configured */ + if (!s || s->fd < 0) { + return; + } + + assert(ep_type == USB_ENDPOINT_XFER_ISOC || + ep_type == USB_ENDPOINT_XFER_BULK || + ep_type == USB_ENDPOINT_XFER_INT); + /* device made some data for host */ + assert(pid == USB_TOKEN_IN); + + init_from_usbpacket(s, &u, p, 'C', len); + usb_dump_packet(s, &u, data); +} + void usb_dump_cleanup(UsbDumpState *s) { if (s->fd >= 0) { |