summaryrefslogtreecommitdiff
path: root/hw/usb/dump.c
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2014-03-15 17:51:06 +0100
committerPeter Wu <peter@lekensteyn.nl>2014-03-16 00:10:06 +0100
commitf47dd59ee594e62029a919b20fc048ce8421b0c2 (patch)
treef1699dfa7a8643256695012fd7309acbe2e36ad6 /hw/usb/dump.c
parent43d6464d410136f1c083a6df263bb71319eb2244 (diff)
downloadqemu-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.c56
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) {