The register traces show what the guest wrote, but not which transfer
path the write chose, how much each call moved, or when the host gave up
on a packet.

Add one event per path, so the name says which path ran and a single
path can be enabled on its own: a kick, a transfer result, and a
cancelled packet.

Signed-off-by: Jamin Lin <[email protected]>
---
 hw/usb/aspeed-udc.c | 23 +++++++++++++++++++++++
 hw/usb/trace-events |  7 +++++++
 2 files changed, 30 insertions(+)

diff --git a/hw/usb/aspeed-udc.c b/hw/usb/aspeed-udc.c
index 09f5913aef..1c99e45d9a 100644
--- a/hw/usb/aspeed-udc.c
+++ b/hw/usb/aspeed-udc.c
@@ -565,6 +565,9 @@ static AspeedUDCXferResult 
aspeed_udc_ep_xfer_in_desc(AspeedUDCState *s,
         aspeed_udc_raise_ep_ack(s, ep);
     }
 
+    trace_aspeed_udc_ep_xfer_in_desc(ep, (uint32_t)p->actual_length,
+                                     done ? "done" : "more");
+
     return done ? ASPEED_UDC_XFER_DONE : ASPEED_UDC_XFER_MORE;
 }
 
@@ -606,6 +609,9 @@ static AspeedUDCXferResult 
aspeed_udc_ep_xfer_in_single(AspeedUDCState *s,
      * buffer, and the next IN request sends the rest.
      */
     if (e->single_buf_off < buf_len) {
+        trace_aspeed_udc_ep_xfer_in_single(ep,
+                                           (uint32_t)p->actual_length,
+                                           "buffer left");
         return ASPEED_UDC_XFER_DONE;
     }
 
@@ -619,6 +625,9 @@ static AspeedUDCXferResult 
aspeed_udc_ep_xfer_in_single(AspeedUDCState *s,
                                         PROC_STS, EP_DMA_CTRL_STS_TX_IDLE);
     aspeed_udc_raise_ep_ack(s, ep);
 
+    trace_aspeed_udc_ep_xfer_in_single(ep, (uint32_t)p->actual_length,
+                                       "done");
+
     return ASPEED_UDC_XFER_DONE;
 }
 
@@ -664,9 +673,15 @@ static AspeedUDCXferResult 
aspeed_udc_ep_xfer_out_single(AspeedUDCState *s,
     aspeed_udc_raise_ep_ack(s, ep);
 
     if ((uint32_t)p->actual_length >= pktiov->size) {
+        trace_aspeed_udc_ep_xfer_out_single(ep,
+                                            (uint32_t)p->actual_length,
+                                            "done");
         return ASPEED_UDC_XFER_DONE;
     }
 
+    trace_aspeed_udc_ep_xfer_out_single(ep, (uint32_t)p->actual_length,
+                                        "more");
+
     return ASPEED_UDC_XFER_MORE;
 }
 
@@ -686,6 +701,8 @@ static void aspeed_udc_ep_in_kick_desc(AspeedUDCState *s, 
int ep,
     uint32_t cur_rptr = FIELD_EX32(old_val, EP_DMA_STS, RPTR);
     USBPacket *p = e->pkt;
 
+    trace_aspeed_udc_ep_in_kick_desc(ep);
+
     /*
      * A normal kick only sets the write pointer and leaves the read-pointer
      * field 0 (the read pointer is ours to advance). The guest resets the ring
@@ -735,6 +752,8 @@ static void aspeed_udc_ep_in_kick_single(AspeedUDCState *s, 
int ep)
     AspeedUDCEP *e = &s->ep[ep];
     USBPacket *p = e->pkt;
 
+    trace_aspeed_udc_ep_in_kick_single(ep);
+
     /* Do nothing if no host request is waiting, or no buffer was queued. */
     if (!p || !FIELD_EX32(e->regs[R_EP_DMA_STS], EP_DMA_STS, WPTR)) {
         return;
@@ -770,6 +789,8 @@ static void aspeed_udc_ep_out_kick_single(AspeedUDCState 
*s, int ep)
     AspeedUDCEP *e = &s->ep[ep];
     USBPacket *p = e->pkt;
 
+    trace_aspeed_udc_ep_out_kick_single(ep);
+
     /* nothing to do unless an OUT packet is waiting and a buffer is ready */
     if (!p || !FIELD_EX32(e->regs[R_EP_DMA_STS], EP_DMA_STS, WPTR)) {
         return;
@@ -1155,6 +1176,8 @@ static void aspeed_udc_gadget_cancel_packet(USBDevice 
*udev, USBPacket *p)
     AspeedUDCState *s = ASPEED_UDC_GADGET(udev)->udc;
     int i;
 
+    trace_aspeed_udc_cancel_packet(p->ep->nr);
+
     if (s->ep0_packet == p) {
         s->ep0_packet = NULL;
     }
diff --git a/hw/usb/trace-events b/hw/usb/trace-events
index e84561d2e8..3b828da36d 100644
--- a/hw/usb/trace-events
+++ b/hw/usb/trace-events
@@ -395,6 +395,13 @@ aspeed_udc_handle_data(int ep_nr, const char *dir, 
uint32_t iov, int ep_idx) "ep
 aspeed_udc_ep_data_in(unsigned ep, uint32_t rptr, uint32_t wptr, uint32_t iov) 
"ep %u, rptr %u, wptr %u, iov %u"
 aspeed_udc_ep_data_out(unsigned ep, uint32_t wptr, uint32_t avail, uint32_t 
iov) "ep %u, wptr %u, avail %u, iov %u"
 aspeed_udc_ep_ack(unsigned ep) "ep %u"
+aspeed_udc_ep_in_kick_desc(int ep) "ep %d"
+aspeed_udc_ep_in_kick_single(int ep) "ep %d"
+aspeed_udc_ep_out_kick_single(int ep) "ep %d"
+aspeed_udc_ep_xfer_in_desc(int ep, uint32_t sent, const char *res) "ep %d, 
sent %u, %s"
+aspeed_udc_ep_xfer_in_single(int ep, uint32_t sent, const char *res) "ep %d, 
sent %u, %s"
+aspeed_udc_ep_xfer_out_single(int ep, uint32_t received, const char *res) "ep 
%d, received %u, %s"
+aspeed_udc_cancel_packet(int ep) "ep %d"
 
 # redirect-server.c
 usbredir_server_chardev_open(void) "chardev opened"
-- 
2.53.0

Reply via email to