Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 10 Sep 2012 12: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: r240312 - head/sys/dev/usb/controller
Message-ID:  <201209101223.q8ACNub9052213@svn.freebsd.org>

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

Log:
  Fix for IRQ hang in DWC OTG host mode.

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

Modified: head/sys/dev/usb/controller/dwc_otg.c
==============================================================================
--- head/sys/dev/usb/controller/dwc_otg.c	Mon Sep 10 12:11:11 2012	(r240311)
+++ head/sys/dev/usb/controller/dwc_otg.c	Mon Sep 10 12:23:56 2012	(r240312)
@@ -498,8 +498,16 @@ dwc_otg_host_channel_alloc(struct dwc_ot
 			DPRINTF("HCCHAR=0x%08x(0x%08x) HCSPLT=0x%08x\n",
 			    td->hcchar, temp, td->hcsplt);
 
+			/* clear leftover interrupts */
 			temp = DWC_OTG_READ_4(sc, DOTG_HCINT(x));
 			DWC_OTG_WRITE_4(sc, DOTG_HCINT(x), temp);
+
+			/* enable interrupts */
+			DWC_OTG_WRITE_4(sc, DOTG_HCINTMSK(x),
+			    HCINT_STALL | HCINT_BBLERR |
+			    HCINT_AHBERR | HCINT_CHHLTD | HCINT_XACTERR |
+			    HCINT_XFERCOMPL);
+
 			DWC_OTG_WRITE_4(sc, DOTG_HCSPLT(x), td->hcsplt);
 			DWC_OTG_WRITE_4(sc, DOTG_HCTSIZ(x), 0);
 			DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(x), 0);
@@ -569,12 +577,6 @@ dwc_otg_host_setup_tx(struct dwc_otg_td 
 	/* must enable channel before writing data to FIFO */
 	DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(td->channel), temp);
 
-	/* enable interrupts */
-	DWC_OTG_WRITE_4(sc, DOTG_HCINTMSK(td->channel),
-	    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,
 	    DOTG_DFIFO(td->channel), (uint32_t *)&req, sizeof(req) / 4);
@@ -875,12 +877,6 @@ not_complete:
 	    (td->toggle ? (HCTSIZ_PID_DATA1 << HCTSIZ_PID_SHIFT) :
 	    (HCTSIZ_PID_DATA0 << HCTSIZ_PID_SHIFT)));
 
-	/* enable interrupts */
-	DWC_OTG_WRITE_4(sc, DOTG_HCINTMSK(td->channel),
-	    HCINT_STALL | HCINT_BBLERR |
-	    HCINT_AHBERR | HCINT_CHHLTD | HCINT_XACTERR |
-	    HCINT_XFERCOMPL);
-
 	temp |= HCCHAR_EPDIR_IN;
 
 	/* must enable channel before data can be received */
@@ -1123,12 +1119,6 @@ dwc_otg_host_data_tx(struct dwc_otg_td *
 	/* must enable before writing data to FIFO */
 	DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(td->channel), temp);
 
-	/* enable interrupts */
-	DWC_OTG_WRITE_4(sc, DOTG_HCINTMSK(td->channel),
-	    HCINT_STALL | HCINT_BBLERR |
-	    HCINT_AHBERR | HCINT_CHHLTD | HCINT_XACTERR |
-	    HCINT_XFERCOMPL);
-
 	if (count != 0) {
 
 		/* clear topmost word before copy */
@@ -1632,7 +1622,17 @@ dwc_otg_interrupt(struct dwc_otg_softc *
 	    status, haint, DWC_OTG_READ_4(sc, DOTG_HFNUM));
 
 	if (haint != 0) {
+		uint8_t x;
 
+		/* clear left-over interrupts */
+		for (x = 0; x != sc->sc_host_ch_max; x++) {
+			/* check if channel is disabled */
+			if (sc->sc_hcchar[x] == 0) {
+				uint32_t temp;
+				temp = DWC_OTG_READ_4(sc, DOTG_HCINT(x));
+				DWC_OTG_WRITE_4(sc, DOTG_HCINT(x), temp);
+			}
+		}
 	}
 
 	if (status & GINTSTS_USBRST) {
@@ -2064,7 +2064,7 @@ dwc_otg_setup_standard_chain(struct usb_
 		td = xfer->td_transfer_first;
 		td->toggle = (xfer->endpoint->toggle_next ? 1 : 0);
 
-		td->hcchar = ((xfer->max_packet_count & 3) << HCCHAR_MC_SHIFT) |
+		td->hcchar =
 			(xfer->address << HCCHAR_DEVADDR_SHIFT) |
 			(xfer_type << HCCHAR_EPTYPE_SHIFT) |
 			((xfer->endpointno & UE_ADDR) << HCCHAR_EPNUM_SHIFT) |
@@ -2092,6 +2092,14 @@ dwc_otg_setup_standard_chain(struct usb_
 				td->hcsplt = 0;
 			}
 			break;
+		case USB_SPEED_HIGH:
+			td->hcsplt = 0;
+			if (xfer_type == UE_ISOCHRONOUS ||
+			    xfer_type == UE_INTERRUPT) {
+				td->hcchar |= ((xfer->max_packet_count & 3)
+				    << HCCHAR_MC_SHIFT);
+			}
+			break;
 		default:
 			td->hcsplt = 0;
 			break;



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