Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/nick-nhusb]: src/sys/dev/usb Serialise commands



details:   https://anonhg.NetBSD.org/src/rev/f8739ac4eefe
branches:  nick-nhusb
changeset: 334512:f8739ac4eefe
user:      skrll <skrll%NetBSD.org@localhost>
date:      Mon May 30 06:48:46 2016 +0000

description:
Serialise commands

diffstat:

 sys/dev/usb/xhci.c    |  30 +++++++++++++++++++++---------
 sys/dev/usb/xhcivar.h |   4 +++-
 2 files changed, 24 insertions(+), 10 deletions(-)

diffs (107 lines):

diff -r 2dc24ca56288 -r f8739ac4eefe sys/dev/usb/xhci.c
--- a/sys/dev/usb/xhci.c        Mon May 30 06:46:50 2016 +0000
+++ b/sys/dev/usb/xhci.c        Mon May 30 06:48:46 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: xhci.c,v 1.28.2.69 2016/05/29 08:44:31 skrll Exp $     */
+/*     $NetBSD: xhci.c,v 1.28.2.70 2016/05/30 06:48:46 skrll Exp $     */
 
 /*
  * Copyright (c) 2013 Jonathan A. Kollasch
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.28.2.69 2016/05/29 08:44:31 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.28.2.70 2016/05/30 06:48:46 skrll Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -1017,6 +1017,7 @@
        }
 
        cv_init(&sc->sc_command_cv, "xhcicmd");
+       cv_init(&sc->sc_cmdbusy_cv, "xhcicmdq");
        mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
        mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB);
        cv_init(&sc->sc_softwake_cv, "xhciab");
@@ -2024,11 +2025,15 @@
 
        XHCIHIST_FUNC(); XHCIHIST_CALLED();
 
+       KASSERT(mutex_owned(&sc->sc_lock));
+
        trb_0 = le64toh(trb->trb_0);
        trb_2 = le32toh(trb->trb_2);
        trb_3 = le32toh(trb->trb_3);
 
        if (trb_0 == sc->sc_command_addr) {
+               sc->sc_resultpending = false;
+
                sc->sc_result_trb.trb_0 = trb_0;
                sc->sc_result_trb.trb_2 = trb_2;
                sc->sc_result_trb.trb_3 = trb_3;
@@ -2633,9 +2638,11 @@
        KASSERTMSG(!cpu_intr_p() && !cpu_softintr_p(), "called from intr ctx");
        KASSERT(mutex_owned(&sc->sc_lock));
 
-       /* XXX KASSERT may fire when cv_timedwait unlocks sc_lock */
-       KASSERT(sc->sc_command_addr == 0);
+       while (sc->sc_command_addr != 0)
+               cv_wait(&sc->sc_cmdbusy_cv, &sc->sc_lock);
+
        sc->sc_command_addr = xhci_ring_trbp(cr, cr->xr_ep);
+       sc->sc_resultpending = true;
 
        mutex_enter(&cr->xr_lock);
        xhci_ring_put(sc, cr, NULL, trb, 1);
@@ -2643,11 +2650,13 @@
 
        xhci_db_write_4(sc, XHCI_DOORBELL(0), 0);
 
-       if (cv_timedwait(&sc->sc_command_cv, &sc->sc_lock,
-           MAX(1, mstohz(timeout))) == EWOULDBLOCK) {
-               xhci_abort_command(sc);
-               err = USBD_TIMEOUT;
-               goto timedout;
+       while (sc->sc_resultpending) {
+               if (cv_timedwait(&sc->sc_command_cv, &sc->sc_lock,
+                   MAX(1, mstohz(timeout))) == EWOULDBLOCK) {
+                       xhci_abort_command(sc);
+                       err = USBD_TIMEOUT;
+                       goto timedout;
+               }
        }
 
        trb->trb_0 = sc->sc_result_trb.trb_0;
@@ -2671,7 +2680,10 @@
        }
 
 timedout:
+       sc->sc_resultpending = false;
        sc->sc_command_addr = 0;
+       cv_broadcast(&sc->sc_cmdbusy_cv);
+
        return err;
 }
 
diff -r 2dc24ca56288 -r f8739ac4eefe sys/dev/usb/xhcivar.h
--- a/sys/dev/usb/xhcivar.h     Mon May 30 06:46:50 2016 +0000
+++ b/sys/dev/usb/xhcivar.h     Mon May 30 06:48:46 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: xhcivar.h,v 1.4.12.10 2016/05/29 08:44:31 skrll Exp $  */
+/*     $NetBSD: xhcivar.h,v 1.4.12.11 2016/05/30 06:48:46 skrll Exp $  */
 
 /*
  * Copyright (c) 2013 Jonathan A. Kollasch
@@ -113,9 +113,11 @@
        usb_dma_t sc_spbufarray_dma;
        usb_dma_t *sc_spbuf_dma;
 
+       kcondvar_t sc_cmdbusy_cv;
        kcondvar_t sc_command_cv;
        bus_addr_t sc_command_addr;
        struct xhci_trb sc_result_trb;
+       bool sc_resultpending;
 
        bool sc_ac64;
        bool sc_dying;



Home | Main Index | Thread Index | Old Index