aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-06-19 17:54:30 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-06-19 17:54:30 +0100
commitcef8fd68364ad754d4f0050a215376cdf0ec744a (patch)
tree1d93ad481e890c5a96cd646959a3ca4512f80db9
parenta1fbe750fd90d29309fd037ab98f263367aaf770 (diff)
parentad3c5412f2704672bb212bb82035c9b1a72db782 (diff)
Merge remote-tracking branch 'remotes/kraxel/tags/pull-usb-20170614-1' into staging
usb: bugfixes for ehci and xhci # gpg: Signature made Wed 14 Jun 2017 08:44:01 BST # gpg: using RSA key 0x4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/pull-usb-20170614-1: ehci: stop recursive calls to ehci_work_bh xhci: only update dequeue ptr on completed transfers Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/usb/hcd-ehci.c7
-rw-r--r--hw/usb/hcd-ehci.h1
-rw-r--r--hw/usb/hcd-xhci.c6
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);