Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 10 Sep 2012 08:23:56 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r240302 - head/sys/dev/usb/controller
Message-ID:  <201209100823.q8A8Nued019928@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Mon Sep 10 08:23:56 2012
New Revision: 240302
URL: http://svn.freebsd.org/changeset/base/240302

Log:
  Cleanup interrupt handling in Host Mode.

Modified:
  head/sys/dev/usb/controller/dwc_otg.c
  head/sys/dev/usb/controller/dwc_otg.h

Modified: head/sys/dev/usb/controller/dwc_otg.c
==============================================================================
--- head/sys/dev/usb/controller/dwc_otg.c	Mon Sep 10 08:16:45 2012	(r240301)
+++ head/sys/dev/usb/controller/dwc_otg.c	Mon Sep 10 08:23:56 2012	(r240302)
@@ -488,13 +488,15 @@ dwc_otg_host_channel_alloc(struct dwc_ot
 
 			/* check if channel is enabled */
 			temp = DWC_OTG_READ_4(sc, DOTG_HCCHAR(x));
-			if (temp & HCCHAR_CHENA)
+			if (temp & HCCHAR_CHENA) {
+				DPRINTF("CH=%d is BUSY\n", x);
 				continue;
+			}
 
 			sc->sc_hcchar[x] = td->hcchar;
 
-			DPRINTF("HCCHAR=0x%08x HCSPLT=0x%08x\n",
-			    td->hcchar, td->hcsplt);
+			DPRINTF("HCCHAR=0x%08x(0x%08x) HCSPLT=0x%08x\n",
+			    td->hcchar, temp, td->hcsplt);
 
 			temp = DWC_OTG_READ_4(sc, DOTG_HCINT(x));
 			DWC_OTG_WRITE_4(sc, DOTG_HCINT(x), temp);
@@ -502,6 +504,11 @@ dwc_otg_host_channel_alloc(struct dwc_ot
 			DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(x), 0);
 			DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(x), 0);
 
+			/* reset TX FIFO */
+			DWC_OTG_WRITE_4(sc, DOTG_GRSTCTL,
+			    GRSTCTL_TXFIFO(x) |
+			    GRSTCTL_TXFFLSH);
+
 			/* set channel */
 			td->channel = x;
 
@@ -534,7 +541,8 @@ dwc_otg_host_setup_tx(struct dwc_otg_td 
 	DPRINTF("HPTXSTS=0x%08x\n", temp);
 
 	max_buffer = 4 * (temp & HPTXSTS_PTXFSPCAVAIL_MASK);
-	max_frames = (temp & HPTXSTS_PTXQSPCAVAIL_MASK) >> HPTXSTS_PTXQSPCAVAIL_SHIFT;
+	max_frames = (temp & HPTXSTS_PTXQSPCAVAIL_MASK)
+	    >> HPTXSTS_PTXQSPCAVAIL_SHIFT;
 
 	max_buffer = max_buffer - (max_buffer % td->max_packet_size);
 	if (max_buffer == 0 || max_frames == 0)
@@ -563,11 +571,9 @@ dwc_otg_host_setup_tx(struct dwc_otg_td 
 
 	/* enable interrupts */
 	DWC_OTG_WRITE_4(sc, DOTG_HCINTMSK(td->channel),
-	    HCINT_STALL | HCINT_DATATGLERR | HCINT_BBLERR |
-	    HCINT_AHBERR | HCINT_CHHLTD | HCINT_XFERCOMPL);
-
-	sc->sc_haint_mask |= (1 << td->channel);
-	DWC_OTG_WRITE_4(sc, DOTG_HAINTMSK, sc->sc_haint_mask);
+	    HCINT_STALL | HCINT_BBLERR |
+	    HCINT_AHBERR | HCINT_CHHLTD | HCINT_XACTERR |
+	    HCINT_XFERCOMPL);
 
 	/* transfer data into FIFO */
 	bus_space_write_region_4(sc->sc_io_tag, sc->sc_io_hdl,
@@ -744,8 +750,8 @@ dwc_otg_host_data_rx(struct dwc_otg_td *
 		return (0);		/* complete */
 	}
 
-	if (temp & (HCINT_DATATGLERR | HCINT_BBLERR |
-	    HCINT_AHBERR | HCINT_CHHLTD)) {
+	if (temp & (HCINT_BBLERR |
+	    HCINT_AHBERR | HCINT_CHHLTD | HCINT_XACTERR)) {
 		td->error_any = 1;
 		return (0);		/* complete */
 	}
@@ -871,11 +877,9 @@ not_complete:
 
 	/* enable interrupts */
 	DWC_OTG_WRITE_4(sc, DOTG_HCINTMSK(td->channel),
-	    HCINT_STALL | HCINT_DATATGLERR | HCINT_BBLERR |
-	    HCINT_AHBERR | HCINT_CHHLTD | HCINT_XFERCOMPL);
-
-	sc->sc_haint_mask |= (1 << td->channel);
-	DWC_OTG_WRITE_4(sc, DOTG_HAINTMSK, sc->sc_haint_mask);
+	    HCINT_STALL | HCINT_BBLERR |
+	    HCINT_AHBERR | HCINT_CHHLTD | HCINT_XACTERR |
+	    HCINT_XFERCOMPL);
 
 	temp |= HCCHAR_EPDIR_IN;
 
@@ -1029,8 +1033,8 @@ dwc_otg_host_data_tx(struct dwc_otg_td *
 		return (0);		/* complete */
 	}
 
-	if (temp & (HCINT_DATATGLERR | HCINT_BBLERR |
-	    HCINT_AHBERR | HCINT_CHHLTD)) {
+	if (temp & (HCINT_BBLERR |
+	    HCINT_AHBERR | HCINT_CHHLTD | HCINT_XACTERR)) {
 		td->error_any = 1;
 		return (0);		/* complete */
 	}
@@ -1067,7 +1071,8 @@ dwc_otg_host_data_tx(struct dwc_otg_td *
 	temp = DWC_OTG_READ_4(sc, DOTG_HPTXSTS);
 
 	max_buffer = 4 * (temp & HPTXSTS_PTXFSPCAVAIL_MASK);
-	max_frames = (temp & HPTXSTS_PTXQSPCAVAIL_MASK) >> HPTXSTS_PTXQSPCAVAIL_SHIFT;
+	max_frames = (temp & HPTXSTS_PTXQSPCAVAIL_MASK)
+	    >> HPTXSTS_PTXQSPCAVAIL_SHIFT;
 
 	max_buffer = max_buffer - (max_buffer % td->max_packet_size);
 	if (max_buffer == 0 || max_frames < 2)
@@ -1120,11 +1125,9 @@ dwc_otg_host_data_tx(struct dwc_otg_td *
 
 	/* enable interrupts */
 	DWC_OTG_WRITE_4(sc, DOTG_HCINTMSK(td->channel),
-	    HCINT_STALL | HCINT_DATATGLERR | HCINT_BBLERR |
-	    HCINT_AHBERR | HCINT_CHHLTD | HCINT_XFERCOMPL);
-
-	sc->sc_haint_mask |= (1 << td->channel);
-	DWC_OTG_WRITE_4(sc, DOTG_HAINTMSK, sc->sc_haint_mask);
+	    HCINT_STALL | HCINT_BBLERR |
+	    HCINT_AHBERR | HCINT_CHHLTD | HCINT_XACTERR |
+	    HCINT_XFERCOMPL);
 
 	if (count != 0) {
 
@@ -1372,8 +1375,8 @@ dwc_otg_host_data_tx_sync(struct dwc_otg
 		return (0);		/* complete */
 	}
 
-	if (temp & (HCINT_DATATGLERR | HCINT_BBLERR |
-	    HCINT_AHBERR | HCINT_CHHLTD)) {
+	if (temp & (HCINT_BBLERR |
+	    HCINT_AHBERR | HCINT_CHHLTD | HCINT_XACTERR)) {
 		td->error_any = 1;
 		return (0);		/* complete */
 	}
@@ -1615,6 +1618,7 @@ void
 dwc_otg_interrupt(struct dwc_otg_softc *sc)
 {
 	uint32_t status;
+	uint32_t haint;
 
 	USB_BUS_LOCK(&sc->sc_bus);
 
@@ -1622,13 +1626,13 @@ dwc_otg_interrupt(struct dwc_otg_softc *
 	status = DWC_OTG_READ_4(sc, DOTG_GINTSTS);
 	DWC_OTG_WRITE_4(sc, DOTG_GINTSTS, status);
 
-	DPRINTFN(14, "GINTSTS=0x%08x\n", status);
+	haint = DWC_OTG_READ_4(sc, DOTG_HAINT);
+
+	DPRINTFN(14, "GINTSTS=0x%08x HAINT=0x%08x HFNUM=0x%08x\n",
+	    status, haint, DWC_OTG_READ_4(sc, DOTG_HFNUM));
+
+	if (haint != 0) {
 
-	if (status & GINTSTS_HCHINT) {
-		uint32_t temp = DWC_OTG_READ_4(sc, DOTG_HAINT);
-		DWC_OTG_WRITE_4(sc, DOTG_HAINT, temp);
-		DPRINTFN(14, "HAINT=0x%08x HFNUM=0x%08x\n",
-		    temp, DWC_OTG_READ_4(sc, DOTG_HFNUM));
 	}
 
 	if (status & GINTSTS_USBRST) {
@@ -2208,8 +2212,7 @@ dwc_otg_standard_done_sub(struct usb_xfe
 
 	xfer->td_transfer_cache = td;
 
-	return (error ?
-	    USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION);
+	return (error);
 }
 
 static void
@@ -2278,8 +2281,7 @@ dwc_otg_device_done(struct usb_xfer *xfe
 
 			struct dwc_otg_softc *sc = DWC_OTG_BUS2SC(xfer->xroot->bus);
 
-			sc->sc_haint_mask &= ~(1 << td->channel);
-			DWC_OTG_WRITE_4(sc, DOTG_HAINTMSK, sc->sc_haint_mask);
+			DWC_OTG_WRITE_4(sc, DOTG_HCINTMSK(td->channel), 0);
 			DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(td->channel),
 			    HCCHAR_CHENA | HCCHAR_CHDIS);
 
@@ -2627,16 +2629,15 @@ dwc_otg_init(struct dwc_otg_softc *sc)
 		uint8_t x;
 
 		for (x = 0; x != sc->sc_host_ch_max; x++) {
-			/* disable interrupt */
+			/* disable channel interrupts */
 			DWC_OTG_WRITE_4(sc, DOTG_HCINTMSK(x), 0);
-			DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(x), HCCHAR_CHENA | HCCHAR_CHDIS);
-			temp = DWC_OTG_READ_4(sc, DOTG_HCINT(x));
-			DWC_OTG_WRITE_4(sc, DOTG_HCINT(x), temp);
+			DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(x),
+			    HCCHAR_CHENA | HCCHAR_CHDIS);
 		}
 
-		/* disable host channel interrupts */
-		sc->sc_haint_mask = 0;
-		DWC_OTG_WRITE_4(sc, DOTG_HAINTMSK, 0);
+		/* enable host channel interrupts */
+		DWC_OTG_WRITE_4(sc, DOTG_HAINTMSK,
+		    (1 << sc->sc_host_ch_max) - 1);
 
 		/* setup clocks */
 		temp = DWC_OTG_READ_4(sc, DOTG_HCFG);
@@ -3569,7 +3570,7 @@ dwc_otg_device_resume(struct usb_device 
 
 	DPRINTF("\n");
 
-	/* Disable relevant Host channels before going to suspend */
+	/* Enable relevant Host channels before resuming */
 
 	USB_BUS_LOCK(udev->bus);
 

Modified: head/sys/dev/usb/controller/dwc_otg.h
==============================================================================
--- head/sys/dev/usb/controller/dwc_otg.h	Mon Sep 10 08:16:45 2012	(r240301)
+++ head/sys/dev/usb/controller/dwc_otg.h	Mon Sep 10 08:23:56 2012	(r240302)
@@ -151,7 +151,6 @@ struct dwc_otg_softc {
 	uint32_t sc_sof_refs;
 	uint32_t sc_sof_val;
 	uint32_t sc_hprt_val;
-	uint32_t sc_haint_mask;
 
 	uint16_t sc_active_rx_ep;
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201209100823.q8A8Nued019928>