From owner-svn-src-head@FreeBSD.ORG Mon Sep 10 12:23:57 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E2663106566B; Mon, 10 Sep 2012 12:23:56 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id CDB888FC15; Mon, 10 Sep 2012 12:23:56 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q8ACNujZ052215; Mon, 10 Sep 2012 12:23:56 GMT (envelope-from hselasky@svn.freebsd.org) Received: (from hselasky@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q8ACNub9052213; Mon, 10 Sep 2012 12:23:56 GMT (envelope-from hselasky@svn.freebsd.org) Message-Id: <201209101223.q8ACNub9052213@svn.freebsd.org> From: Hans Petter Selasky Date: Mon, 10 Sep 2012 12:23:56 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r240312 - head/sys/dev/usb/controller X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Sep 2012 12:23:57 -0000 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;