Source-Changes-HG archive

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

[src/trunk]: src/sys Try to recover from vbus errors. Some devices draw too much



details:   https://anonhg.NetBSD.org/src/rev/48c9e0ffd318
branches:  trunk
changeset: 797442:48c9e0ffd318
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Thu Jul 17 19:58:18 2014 +0000

description:
Try to recover from vbus errors. Some devices draw too much
current at plug time, causing a trancient error.

diffstat:

 sys/arch/arm/omap/tiotg.c |  34 +++++++++++++++++++++++++---------
 sys/dev/usb/motg.c        |  24 +++++++++++++++++-------
 sys/dev/usb/motgvar.h     |   5 +++--
 3 files changed, 45 insertions(+), 18 deletions(-)

diffs (154 lines):

diff -r fce55328cc01 -r 48c9e0ffd318 sys/arch/arm/omap/tiotg.c
--- a/sys/arch/arm/omap/tiotg.c Thu Jul 17 19:23:40 2014 +0000
+++ b/sys/arch/arm/omap/tiotg.c Thu Jul 17 19:58:18 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tiotg.c,v 1.1 2014/07/16 18:27:19 bouyer Exp $ */
+/* $NetBSD: tiotg.c,v 1.2 2014/07/17 19:58:18 bouyer Exp $ */
 /*
  * Copyright (c) 2013 Manuel Bouyer.  All rights reserved.
  *
@@ -24,7 +24,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tiotg.c,v 1.1 2014/07/16 18:27:19 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tiotg.c,v 1.2 2014/07/17 19:58:18 bouyer Exp $");
 
 #include "opt_omap.h"
 #include "locators.h"
@@ -54,6 +54,7 @@
 #include <dev/usb/usbdi.h>
 #include <dev/usb/usbdivar.h>
 #include <dev/usb/usb_mem.h>
+#include <dev/usb/motgreg.h>
 #include <dev/usb/motgvar.h>
 
 #define MOTG_DEBUG
@@ -376,27 +377,42 @@
 {
        struct ti_motg_softc *sc = v;
        uint32_t stat, stat0, stat1;
-       int vbus = 0;
        int rv = 0;
+       int i;
 
        mutex_spin_enter(&sc->sc_motg.sc_intr_lock);
        stat = TIOTG_USBC_READ4(sc, USBCTRL_STAT);
        stat0 = TIOTG_USBC_READ4(sc, USBCTRL_IRQ_STAT0);
        stat1 = TIOTG_USBC_READ4(sc, USBCTRL_IRQ_STAT1);
-       DPRINTF(("USB %d 0x%x 0x%x stat %d\n", sc->sc_ctrlport, stat0, stat1, stat));
+       DPRINTF(("USB %d 0x%x 0x%x stat %d\n",
+           sc->sc_ctrlport, stat0, stat1, stat));
+       /* try to deal with vbus errors */
+       if (stat1 & MUSB2_MASK_IVBUSERR ) {
+               stat1 &= ~MUSB2_MASK_IVBUSERR;
+               for (i = 0; i < 1000; i++) {
+                       TIOTG_USBC_WRITE4(sc, USBCTRL_IRQ_STAT1,
+                           MUSB2_MASK_IVBUSERR);
+                       motg_intr_vbus(&sc->sc_motg, stat & 0x1);
+                       delay(1000);
+                       stat = TIOTG_USBC_READ4(sc, USBCTRL_STAT);
+                       if (stat & 0x1)
+                               break;
+               }
+       }
        if (stat0) {
                TIOTG_USBC_WRITE4(sc, USBCTRL_IRQ_STAT0, stat0);
        }
        if (stat1) {
                TIOTG_USBC_WRITE4(sc, USBCTRL_IRQ_STAT1, stat1);
        }
-       if (stat1 & USBCTRL_IRQ_STAT1_DRVVBUS) {
-               vbus = ((stat & 0x1) ? 1 : 0);
-               DPRINTF(("USB %d stat %d\n", sc->sc_ctrlport, stat));
+       if ((stat & 0x1) == 0) {
+               mutex_spin_exit(&sc->sc_motg.sc_intr_lock);
+               aprint_error_dev(sc->sc_motg.sc_dev, ": vbus error\n");
+               return 1;
        }
-       if (stat0 != 0 || stat1 != 0 || stat != 0) {
+       if (stat0 != 0 || stat1 != 0) {
                rv = motg_intr(&sc->sc_motg, ((stat0 >> 16) & 0xffff),
-                           stat0 & 0xffff, stat1 & 0xff, vbus);
+                           stat0 & 0xffff, stat1 & 0xff);
        }
        mutex_spin_exit(&sc->sc_motg.sc_intr_lock);
        return rv;
diff -r fce55328cc01 -r 48c9e0ffd318 sys/dev/usb/motg.c
--- a/sys/dev/usb/motg.c        Thu Jul 17 19:23:40 2014 +0000
+++ b/sys/dev/usb/motg.c        Thu Jul 17 19:58:18 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: motg.c,v 1.1 2014/07/16 18:22:23 bouyer Exp $  */
+/*     $NetBSD: motg.c,v 1.2 2014/07/17 19:58:18 bouyer Exp $  */
 
 /*
  * Copyright (c) 1998, 2004, 2011, 2012, 2014 The NetBSD Foundation, Inc.
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: motg.c,v 1.1 2014/07/16 18:22:23 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: motg.c,v 1.2 2014/07/17 19:58:18 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -464,10 +464,6 @@
        struct motg_softc *sc = pipe->device->bus->hci_private;
        struct motg_pipe *otgpipe = (struct motg_pipe *)pipe;
        usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
-#if 0
-       usbd_status err = USBD_NOMEM;
-       int ival;
-#endif
 
        DPRINTF(("motg_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
                     pipe, pipe->device->address,
@@ -660,7 +656,7 @@
 
 int
 motg_intr(struct motg_softc *sc, uint16_t rx_ep, uint16_t tx_ep,
-    uint8_t ctrl, int vbus)
+    uint8_t ctrl)
 {
        KASSERT(mutex_owned(&sc->sc_intr_lock));
        sc->sc_intr_tx_ep = tx_ep;
@@ -674,6 +670,20 @@
        return 1;
 }
 
+int
+motg_intr_vbus(struct motg_softc *sc, int vbus)
+{
+       uint8_t val;
+       if (sc->sc_mode == MOTG_MODE_HOST && vbus == 0) {
+               DPRINTF(("motg_intr_vbus: vbus down, try to re-enable\n"));
+               /* try to re-enter session for Host mode */
+               val = UREAD1(sc, MUSB2_REG_DEVCTL);
+               val |= MUSB2_MASK_SESS;
+               UWRITE1(sc, MUSB2_REG_DEVCTL, val);
+       }
+       return 1;
+}
+
 usbd_status
 motg_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size)
 {
diff -r fce55328cc01 -r 48c9e0ffd318 sys/dev/usb/motgvar.h
--- a/sys/dev/usb/motgvar.h     Thu Jul 17 19:23:40 2014 +0000
+++ b/sys/dev/usb/motgvar.h     Thu Jul 17 19:58:18 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: motgvar.h,v 1.1 2014/07/16 18:22:23 bouyer Exp $       */
+/*     $NetBSD: motgvar.h,v 1.2 2014/07/17 19:58:18 bouyer Exp $       */
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -121,7 +121,8 @@
 
 
 usbd_status    motg_init(struct motg_softc *);
-int            motg_intr(struct motg_softc *, uint16_t, uint16_t, uint8_t, int);
+int            motg_intr(struct motg_softc *, uint16_t, uint16_t, uint8_t);
+int            motg_intr_vbus(struct motg_softc *, int);
 int            motg_detach(struct motg_softc *, int);
 void           motg_childdet(device_t, device_t);
 int            motg_activate(device_t, enum devact);



Home | Main Index | Thread Index | Old Index