From owner-svn-src-all@FreeBSD.ORG Mon Sep 10 08:23:57 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 12700106564A; Mon, 10 Sep 2012 08:23:57 +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 F08088FC14; Mon, 10 Sep 2012 08: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 q8A8NuN9019931; Mon, 10 Sep 2012 08: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 q8A8Nued019928; Mon, 10 Sep 2012 08:23:56 GMT (envelope-from hselasky@svn.freebsd.org) Message-Id: <201209100823.q8A8Nued019928@svn.freebsd.org> From: Hans Petter Selasky Date: Mon, 10 Sep 2012 08: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: r240302 - head/sys/dev/usb/controller X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 10 Sep 2012 08:23:57 -0000 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;