|
@@ -54,6 +54,8 @@
|
|
#define ER_FULL_HACK
|
|
#define ER_FULL_HACK
|
|
|
|
|
|
#define TRB_LINK_LIMIT 4
|
|
#define TRB_LINK_LIMIT 4
|
|
|
|
+#define COMMAND_LIMIT 256
|
|
|
|
+#define TRANSFER_LIMIT 256
|
|
|
|
|
|
#define LEN_CAP 0x40
|
|
#define LEN_CAP 0x40
|
|
#define LEN_OPER (0x400 + 0x10 * MAXPORTS)
|
|
#define LEN_OPER (0x400 + 0x10 * MAXPORTS)
|
|
@@ -1032,6 +1034,7 @@ static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRing *ring, XHCITRB *trb,
|
|
return type;
|
|
return type;
|
|
} else {
|
|
} else {
|
|
if (++link_cnt > TRB_LINK_LIMIT) {
|
|
if (++link_cnt > TRB_LINK_LIMIT) {
|
|
|
|
+ trace_usb_xhci_enforced_limit("trb-link");
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
ring->dequeue = xhci_mask64(trb->parameter);
|
|
ring->dequeue = xhci_mask64(trb->parameter);
|
|
@@ -2150,6 +2153,7 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
|
|
XHCIRing *ring;
|
|
XHCIRing *ring;
|
|
USBEndpoint *ep = NULL;
|
|
USBEndpoint *ep = NULL;
|
|
uint64_t mfindex;
|
|
uint64_t mfindex;
|
|
|
|
+ unsigned int count = 0;
|
|
int length;
|
|
int length;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
@@ -2262,6 +2266,10 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
|
|
epctx->retry = xfer;
|
|
epctx->retry = xfer;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
+ if (count++ > TRANSFER_LIMIT) {
|
|
|
|
+ trace_usb_xhci_enforced_limit("transfers");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
epctx->kick_active--;
|
|
epctx->kick_active--;
|
|
|
|
|
|
@@ -2734,7 +2742,7 @@ static void xhci_process_commands(XHCIState *xhci)
|
|
TRBType type;
|
|
TRBType type;
|
|
XHCIEvent event = {ER_COMMAND_COMPLETE, CC_SUCCESS};
|
|
XHCIEvent event = {ER_COMMAND_COMPLETE, CC_SUCCESS};
|
|
dma_addr_t addr;
|
|
dma_addr_t addr;
|
|
- unsigned int i, slotid = 0;
|
|
|
|
|
|
+ unsigned int i, slotid = 0, count = 0;
|
|
|
|
|
|
DPRINTF("xhci_process_commands()\n");
|
|
DPRINTF("xhci_process_commands()\n");
|
|
if (!xhci_running(xhci)) {
|
|
if (!xhci_running(xhci)) {
|
|
@@ -2848,6 +2856,11 @@ static void xhci_process_commands(XHCIState *xhci)
|
|
}
|
|
}
|
|
event.slotid = slotid;
|
|
event.slotid = slotid;
|
|
xhci_event(xhci, &event, 0);
|
|
xhci_event(xhci, &event, 0);
|
|
|
|
+
|
|
|
|
+ if (count++ > COMMAND_LIMIT) {
|
|
|
|
+ trace_usb_xhci_enforced_limit("commands");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|