Module Name:    src
Committed By:   bouyer
Date:           Thu Jul 17 19:58:18 UTC 2014

Modified Files:
        src/sys/arch/arm/omap: tiotg.c
        src/sys/dev/usb: motg.c motgvar.h

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


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/omap/tiotg.c
cvs rdiff -u -r1.1 -r1.2 src/sys/dev/usb/motg.c src/sys/dev/usb/motgvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/omap/tiotg.c
diff -u src/sys/arch/arm/omap/tiotg.c:1.1 src/sys/arch/arm/omap/tiotg.c:1.2
--- src/sys/arch/arm/omap/tiotg.c:1.1	Wed Jul 16 18:27:19 2014
+++ src/sys/arch/arm/omap/tiotg.c	Thu Jul 17 19:58:18 2014
@@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: tiotg.c,v 1.
 #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 @@ ti_motg_intr(void *v)
 {
 	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;

Index: src/sys/dev/usb/motg.c
diff -u src/sys/dev/usb/motg.c:1.1 src/sys/dev/usb/motg.c:1.2
--- src/sys/dev/usb/motg.c:1.1	Wed Jul 16 18:22:23 2014
+++ src/sys/dev/usb/motg.c	Thu Jul 17 19:58:18 2014
@@ -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 @@ motg_open(usbd_pipe_handle pipe)
 	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 @@ motg_poll(struct usbd_bus *bus)
 
 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 @@ motg_intr(struct motg_softc *sc, uint16_
 	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)
 {
Index: src/sys/dev/usb/motgvar.h
diff -u src/sys/dev/usb/motgvar.h:1.1 src/sys/dev/usb/motgvar.h:1.2
--- src/sys/dev/usb/motgvar.h:1.1	Wed Jul 16 18:22:23 2014
+++ src/sys/dev/usb/motgvar.h	Thu Jul 17 19:58:18 2014
@@ -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 @@ struct motg_xfer {
 
 
 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);

Reply via email to