diff options
Diffstat (limited to 'hw/usb')
-rw-r--r-- | hw/usb/hcd-ehci.c | 7 | ||||
-rw-r--r-- | hw/usb/hcd-ehci.h | 1 | ||||
-rw-r--r-- | hw/usb/hcd-xhci.c | 6 |
3 files changed, 12 insertions, 2 deletions
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index 17c572c55f..73090e01ad 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -2241,6 +2241,11 @@ static void ehci_work_bh(void *opaque) uint64_t uframes, skipped_uframes; int i; + if (ehci->working) { + return; + } + ehci->working = true; + t_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); ns_elapsed = t_now - ehci->last_run_ns; uframes = ns_elapsed / UFRAME_TIMER_NS; @@ -2322,6 +2327,8 @@ static void ehci_work_bh(void *opaque) } timer_mod(ehci->frame_timer, expire_time); } + + ehci->working = false; } static void ehci_work_timer(void *opaque) diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h index 938d8aa284..821f1ded43 100644 --- a/hw/usb/hcd-ehci.h +++ b/hw/usb/hcd-ehci.h @@ -297,6 +297,7 @@ struct EHCIState { */ QEMUTimer *frame_timer; QEMUBH *async_bh; + bool working; uint32_t astate; /* Current state in asynchronous schedule */ uint32_t pstate; /* Current state in periodic schedule */ USBPort ports[NB_PORTS]; diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index a0c7960a7b..760135c0d2 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -1912,6 +1912,8 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid) } assert(!xfer->running_retry); if (xfer->complete) { + /* update ring dequeue ptr */ + xhci_set_ep_state(xhci, epctx, stctx, epctx->state); xhci_ep_free_xfer(epctx->retry); } epctx->retry = NULL; @@ -1962,6 +1964,8 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid) xhci_fire_transfer(xhci, xfer, epctx); } if (xfer->complete) { + /* update ring dequeue ptr */ + xhci_set_ep_state(xhci, epctx, stctx, epctx->state); xhci_ep_free_xfer(xfer); xfer = NULL; } @@ -1979,8 +1983,6 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid) break; } } - /* update ring dequeue ptr */ - xhci_set_ep_state(xhci, epctx, stctx, epctx->state); epctx->kick_active--; ep = xhci_epid_to_usbep(epctx); |