From owner-svn-src-head@FreeBSD.ORG Wed Sep 12 19:15:30 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 08036106566C; Wed, 12 Sep 2012 19:15:30 +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 E79488FC0A; Wed, 12 Sep 2012 19:15:29 +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 q8CJFTBN031654; Wed, 12 Sep 2012 19:15:29 GMT (envelope-from hselasky@svn.freebsd.org) Received: (from hselasky@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q8CJFTwk031651; Wed, 12 Sep 2012 19:15:29 GMT (envelope-from hselasky@svn.freebsd.org) Message-Id: <201209121915.q8CJFTwk031651@svn.freebsd.org> From: Hans Petter Selasky Date: Wed, 12 Sep 2012 19:15:29 +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: r240419 - 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: Wed, 12 Sep 2012 19:15:30 -0000 Author: hselasky Date: Wed Sep 12 19:15:29 2012 New Revision: 240419 URL: http://svn.freebsd.org/changeset/base/240419 Log: Fix TX FIFO sizes. Correct FIFO 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 Wed Sep 12 18:18:14 2012 (r240418) +++ head/sys/dev/usb/controller/dwc_otg.c Wed Sep 12 19:15:29 2012 (r240419) @@ -211,24 +211,34 @@ dwc_otg_init_fifo(struct dwc_otg_softc * return (EINVAL); } - DWC_OTG_WRITE_4(sc, DOTG_GNPTXFSIZ, (0x10 << 16) | (tx_start / 4)); - fifo_size -= 0x40; - tx_start += 0x40; - - /* setup control endpoint profile */ - sc->sc_hw_ep_profile[0].usb = dwc_otg_ep_profile[0]; - if (mode == DWC_MODE_HOST) { /* reset active endpoints */ sc->sc_active_rx_ep = 0; + fifo_size /= 2; + + DWC_OTG_WRITE_4(sc, DOTG_GNPTXFSIZ, + ((fifo_size / 4) << 16) | + (tx_start / 4)); + + tx_start += fifo_size; + DWC_OTG_WRITE_4(sc, DOTG_HPTXFSIZ, ((fifo_size / 4) << 16) | (tx_start / 4)); } + if (mode == DWC_MODE_DEVICE) { + DWC_OTG_WRITE_4(sc, DOTG_GNPTXFSIZ, + (0x10 << 16) | (tx_start / 4)); + fifo_size -= 0x40; + tx_start += 0x40; + + /* setup control endpoint profile */ + sc->sc_hw_ep_profile[0].usb = dwc_otg_ep_profile[0]; + /* reset active endpoints */ sc->sc_active_rx_ep = 1; @@ -521,18 +531,11 @@ dwc_otg_host_channel_alloc(struct dwc_ot /* enable interrupts */ DWC_OTG_WRITE_4(sc, DOTG_HCINTMSK(x), HCINT_STALL | HCINT_BBLERR | - HCINT_AHBERR | HCINT_CHHLTD | - HCINT_XACTERR | HCINT_XFERCOMPL | - HCINT_NAK | HCINT_NYET); + HCINT_AHBERR | HCINT_XACTERR | + HCINT_XFERCOMPL | HCINT_NAK); 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); - - /* reset TX FIFO */ - DWC_OTG_WRITE_4(sc, DOTG_GRSTCTL, - GRSTCTL_TXFIFO(x) | - GRSTCTL_TXFFLSH); /* set channel */ td->channel = x; @@ -581,8 +584,7 @@ dwc_otg_host_setup_tx(struct dwc_otg_td return (0); /* complete */ } - if (temp & (HCINT_BBLERR | - HCINT_AHBERR | HCINT_CHHLTD | HCINT_XACTERR)) { + if (temp & (HCINT_BBLERR | HCINT_AHBERR | HCINT_XACTERR)) { td->error_any = 1; return (0); /* complete */ } @@ -783,7 +785,6 @@ dwc_otg_host_data_rx(struct dwc_otg_td * struct dwc_otg_softc *sc; uint32_t temp; uint16_t count; - uint8_t got_short; uint8_t ep_type; if (dwc_otg_host_channel_alloc(td)) @@ -800,24 +801,25 @@ dwc_otg_host_data_rx(struct dwc_otg_td * temp, DWC_OTG_READ_4(sc, DOTG_HCCHAR(td->channel)), DWC_OTG_READ_4(sc, DOTG_HCTSIZ(td->channel))); - if (temp & HCINT_NAK) + if (temp & HCINT_NAK) { td->did_nak = 1; + /* disable channel - will generate a halted event */ + DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(td->channel), + HCCHAR_CHENA | HCCHAR_CHDIS); + } + if (temp & HCINT_STALL) { td->error_stall = 1; td->error_any = 1; return (0); /* complete */ } - if (temp & (HCINT_BBLERR | - HCINT_AHBERR | HCINT_CHHLTD | HCINT_XACTERR)) { + if (temp & (HCINT_BBLERR | HCINT_AHBERR | HCINT_XACTERR)) { td->error_any = 1; return (0); /* complete */ } - if (temp & HCINT_XFERCOMPL) - td->did_complete = 1; - /* check endpoint status */ if (sc->sc_last_rx_status == 0) goto not_complete; @@ -826,14 +828,22 @@ dwc_otg_host_data_rx(struct dwc_otg_td * goto not_complete; switch (sc->sc_last_rx_status & GRXSTSRD_PKTSTS_MASK) { + case GRXSTSRH_HALTED: + DPRINTF("HALTED\n"); + td->did_complete = 1; + break; + case GRXSTSRH_IN_COMPLETE: + DPRINTF("COMPLETE\n"); + /* disable channel - will generate a halted event */ + DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(td->channel), + HCCHAR_CHENA | HCCHAR_CHDIS); + break; case GRXSTSRH_IN_DATA: DPRINTF("DATA\n"); td->toggle ^= 1; - got_short = 0; - /* get the packet byte count */ count = GRXSTSRD_BCNT_GET(sc->sc_last_rx_status); @@ -842,7 +852,7 @@ dwc_otg_host_data_rx(struct dwc_otg_td * if (count < td->max_packet_size) { /* we have a short packet */ td->short_pkt = 1; - got_short = 1; + td->got_short = 1; } else { /* invalid USB packet */ td->error_any = 1; @@ -863,35 +873,33 @@ dwc_otg_host_data_rx(struct dwc_otg_td * return (0); /* we are complete */ } - usbd_copy_in(td->pc, td->offset, sc->sc_rx_bounce_buffer, count); + usbd_copy_in(td->pc, td->offset, + sc->sc_rx_bounce_buffer, count); + td->remainder -= count; td->offset += count; - - /* release FIFO */ - dwc_otg_common_rx_ack(sc); - - /* check if we are complete */ - if ((td->remainder == 0) || got_short) { - if (td->short_pkt) { - /* we are complete */ - return (0); - } - /* else need to receive a zero length packet */ - } break; default: DPRINTF("OTHER\n"); - - /* release FIFO */ - dwc_otg_common_rx_ack(sc); break; } + /* release FIFO */ + dwc_otg_common_rx_ack(sc); not_complete: - if (td->did_complete == 0 && td->did_nak == 0) + if (td->did_complete == 0) return (1); /* busy */ + /* check if we are complete */ + if ((td->remainder == 0) || (td->got_short != 0)) { + if (td->short_pkt) { + /* we are complete */ + return (0); + } + /* else need to receive a zero length packet */ + } + temp = sc->sc_hcchar[td->channel]; ep_type = ((temp & HCCHAR_EPTYPE_MASK) >> @@ -1077,8 +1085,10 @@ dwc_otg_host_data_tx(struct dwc_otg_td * temp, DWC_OTG_READ_4(sc, DOTG_HCCHAR(td->channel)), DWC_OTG_READ_4(sc, DOTG_HCTSIZ(td->channel))); - if (temp & HCINT_NAK) + if (temp & HCINT_NAK) { td->did_nak = 1; + td->did_complete = 1; + } if (temp & HCINT_STALL) { td->error_stall = 1; @@ -1086,8 +1096,7 @@ dwc_otg_host_data_tx(struct dwc_otg_td * return (0); /* complete */ } - if (temp & (HCINT_BBLERR | - HCINT_AHBERR | HCINT_CHHLTD | HCINT_XACTERR)) { + if (temp & (HCINT_BBLERR | HCINT_AHBERR | HCINT_XACTERR)) { td->error_any = 1; return (0); /* complete */ } @@ -1509,8 +1518,29 @@ repeat: uint8_t ep_no; - temp = GRXSTSRD_BCNT_GET( - sc->sc_last_rx_status); + temp = sc->sc_last_rx_status & + GRXSTSRD_PKTSTS_MASK; + + /* non-data messages we simply skip */ + if (temp != GRXSTSRD_STP_DATA && + temp != GRXSTSRD_OUT_DATA) { + if (sc->sc_flags.status_device_mode) { + dwc_otg_common_rx_ack(sc); + goto repeat; + } else if (temp != GRXSTSRD_OUT_COMPLETE && + temp != GRXSTSRH_HALTED) { + dwc_otg_common_rx_ack(sc); + goto repeat; + } + } + + if (temp == GRXSTSRH_HALTED || + temp == GRXSTSRD_OUT_COMPLETE) { + temp = 0; + } else { + temp = GRXSTSRD_BCNT_GET( + sc->sc_last_rx_status); + } ep_no = GRXSTSRD_CHNUM_GET( sc->sc_last_rx_status); @@ -1522,16 +1552,6 @@ repeat: sc->sc_rx_bounce_buffer, (temp + 3) / 4); } - temp = sc->sc_last_rx_status & - GRXSTSRD_PKTSTS_MASK; - - /* non-data messages we simply skip */ - if (temp != GRXSTSRD_STP_DATA && - temp != GRXSTSRD_OUT_DATA) { - dwc_otg_common_rx_ack(sc); - goto repeat; - } - /* check if we should dump the data */ if (!(sc->sc_active_rx_ep & (1U << ep_no))) { dwc_otg_common_rx_ack(sc); @@ -1575,12 +1595,6 @@ repeat: if (sc->sc_last_rx_status == 0) goto repeat; - /* if no host listener - dump data */ - if (sc->sc_flags.status_device_mode == 0) { - dwc_otg_common_rx_ack(sc); - goto repeat; - } - /* disable RX FIFO level interrupt */ sc->sc_irq_mask &= ~GINTSTS_RXFLVL; DWC_OTG_WRITE_4(sc, DOTG_GINTMSK, sc->sc_irq_mask); @@ -1637,6 +1651,8 @@ dwc_otg_interrupt(struct dwc_otg_softc * /* clear left-over interrupts */ for (x = 0; x != sc->sc_host_ch_max; x++) { + if (!(haint & (1 << x))) + continue; /* check if channel is disabled */ if (sc->sc_hcchar[x] == 0) { uint32_t temp; @@ -1845,6 +1861,7 @@ dwc_otg_setup_standard_chain_sub(struct td->short_pkt = temp->short_pkt; td->alt_next = temp->setup_alt_next; td->set_toggle = 0; + td->got_short = 0; td->channel = DWC_OTG_MAX_CHANNELS; } Modified: head/sys/dev/usb/controller/dwc_otg.h ============================================================================== --- head/sys/dev/usb/controller/dwc_otg.h Wed Sep 12 18:18:14 2012 (r240418) +++ head/sys/dev/usb/controller/dwc_otg.h Wed Sep 12 19:15:29 2012 (r240419) @@ -70,6 +70,7 @@ struct dwc_otg_td { uint8_t set_toggle:1; uint8_t did_nak:1; uint8_t did_complete:1; + uint8_t got_short:1; }; struct dwc_otg_std_temp {