X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=drivers%2Fusb%2Fmusb%2Fmusb_host.c;h=8804b4b09c8c9523eb88399fc123ae39f4c4726a;hb=ba0b10bc99dacbbbd8711ac36dccadf0100afa80;hp=ef473e9c9fd1d5ee9989ba674f721350141f9441;hpb=68a37991fe438a5ec061e49278917e9f75e36931;p=linux-2.6-omap-h63xx.git diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index ef473e9c9fd..8804b4b09c8 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -1,36 +1,36 @@ -/****************************************************************** +/* + * MUSB OTG driver host support + * * Copyright 2005 Mentor Graphics Corporation * Copyright (C) 2005-2006 by Texas Instruments - * Copyright (C) 2006 by Nokia Corporation - * - * This file is part of the Inventra Controller Driver for Linux. + * Copyright (C) 2006-2007 Nokia Corporation * - * The Inventra Controller Driver for Linux is free software; you - * can redistribute it and/or modify it under the terms of the GNU - * General Public License version 2 as published by the Free Software - * Foundation. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. * - * The Inventra Controller Driver for Linux is distributed in - * the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - * License for more details. + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with The Inventra Controller Driver for Linux ; if not, - * write to the Free Software Foundation, Inc., 59 Temple Place, - * Suite 330, Boston, MA 02111-1307 USA + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA * - * ANY DOWNLOAD, USE, REPRODUCTION, MODIFICATION OR DISTRIBUTION - * OF THIS DRIVER INDICATES YOUR COMPLETE AND UNCONDITIONAL ACCEPTANCE - * OF THOSE TERMS.THIS DRIVER IS PROVIDED "AS IS" AND MENTOR GRAPHICS - * MAKES NO WARRANTIES, EXPRESS OR IMPLIED, RELATED TO THIS DRIVER. - * MENTOR GRAPHICS SPECIFICALLY DISCLAIMS ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY; FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT. MENTOR GRAPHICS DOES NOT PROVIDE SUPPORT - * SERVICES OR UPDATES FOR THIS DRIVER, EVEN IF YOU ARE A MENTOR - * GRAPHICS SUPPORT CUSTOMER. - ******************************************************************/ + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ #include #include @@ -103,26 +103,49 @@ /*************************** Forwards ***************************/ -static void musb_ep_program(struct musb *pThis, u8 bEnd, - struct urb *pUrb, unsigned int nOut, - u8 * pBuffer, u32 dwLength); +static void musb_ep_program(struct musb *musb, u8 epnum, + struct urb *urb, unsigned int nOut, + u8 * buf, u32 len); + +/* + * Clear TX fifo. Needed to avoid BABBLE errors. + */ +static inline void musb_h_tx_flush_fifo(struct musb_hw_ep *ep) +{ + void __iomem *epio = ep->regs; + u16 csr; + int retries = 1000; + + csr = musb_readw(epio, MUSB_TXCSR); + while (csr & MUSB_TXCSR_FIFONOTEMPTY) { + DBG(5, "Host TX FIFONOTEMPTY csr: %02x\n", csr); + csr |= MUSB_TXCSR_FLUSHFIFO; + musb_writew(epio, MUSB_TXCSR, csr); + csr = musb_readw(epio, MUSB_TXCSR); + if (retries-- < 1) { + ERR("Could not flush host TX fifo: csr: %04x\n", csr); + return; + } + mdelay(1); + } +} /* * Start transmit. Caller is responsible for locking shared resources. - * pThis must be locked. + * musb must be locked. */ static inline void musb_h_tx_start(struct musb_hw_ep *ep) { u16 txcsr; /* NOTE: no locks here; caller should lock and select EP */ - if (ep->bLocalEnd) { - txcsr = musb_readw(ep->regs, MGC_O_HDRC_TXCSR); - txcsr |= MGC_M_TXCSR_TXPKTRDY | MGC_M_TXCSR_H_WZC_BITS; - musb_writew(ep->regs, MGC_O_HDRC_TXCSR, txcsr); + if (ep->epnum) { + txcsr = musb_readw(ep->regs, MUSB_TXCSR); + txcsr |= MUSB_TXCSR_TXPKTRDY | MUSB_TXCSR_H_WZC_BITS; + musb_writew(ep->regs, MUSB_TXCSR, txcsr); } else { - txcsr = MGC_M_CSR0_H_SETUPPKT | MGC_M_CSR0_TXPKTRDY; - musb_writew(ep->regs, MGC_O_HDRC_CSR0, txcsr); + txcsr = MUSB_CSR0_H_SETUPPKT | MUSB_CSR0_TXPKTRDY; + musb_writew(ep->regs, MUSB_CSR0, txcsr); } } @@ -132,9 +155,9 @@ static inline void cppi_host_txdma_start(struct musb_hw_ep *ep) u16 txcsr; /* NOTE: no locks here; caller should lock and select EP */ - txcsr = musb_readw(ep->regs, MGC_O_HDRC_TXCSR); - txcsr |= MGC_M_TXCSR_DMAENAB | MGC_M_TXCSR_H_WZC_BITS; - musb_writew(ep->regs, MGC_O_HDRC_TXCSR, txcsr); + txcsr = musb_readw(ep->regs, MUSB_TXCSR); + txcsr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_H_WZC_BITS; + musb_writew(ep->regs, MUSB_TXCSR, txcsr); } /* @@ -147,14 +170,14 @@ static void musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) { u16 wFrame; - u32 dwLength; - void *pBuffer; - void __iomem *pBase = musb->pRegs; + u32 len; + void *buf; + void __iomem *mbase = musb->mregs; struct urb *urb = next_urb(qh); - struct musb_hw_ep *pEnd = qh->hw_ep; - unsigned nPipe = urb->pipe; - u8 bAddress = usb_pipedevice(nPipe); - int bEnd = pEnd->bLocalEnd; + struct musb_hw_ep *hw_ep = qh->hw_ep; + unsigned pipe = urb->pipe; + u8 address = usb_pipedevice(pipe); + int epnum = hw_ep->epnum; /* initialize software qh state */ qh->offset = 0; @@ -165,24 +188,24 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) case USB_ENDPOINT_XFER_CONTROL: /* control transfers always start with SETUP */ is_in = 0; - pEnd->out_qh = qh; - musb->bEnd0Stage = MGC_END0_START; - pBuffer = urb->setup_packet; - dwLength = 8; + hw_ep->out_qh = qh; + musb->ep0_stage = MGC_END0_START; + buf = urb->setup_packet; + len = 8; break; case USB_ENDPOINT_XFER_ISOC: qh->iso_idx = 0; qh->frame = 0; - pBuffer = urb->transfer_buffer + urb->iso_frame_desc[0].offset; - dwLength = urb->iso_frame_desc[0].length; + buf = urb->transfer_buffer + urb->iso_frame_desc[0].offset; + len = urb->iso_frame_desc[0].length; break; default: /* bulk, interrupt */ - pBuffer = urb->transfer_buffer; - dwLength = urb->transfer_buffer_length; + buf = urb->transfer_buffer; + len = urb->transfer_buffer_length; } DBG(4, "qh %p urb %p dev%d ep%d%s%s, hw_ep %d, %p/%d\n", - qh, urb, bAddress, qh->epnum, + qh, urb, address, qh->epnum, is_in ? "in" : "out", ({char *s; switch (qh->type) { case USB_ENDPOINT_XFER_CONTROL: s = ""; break; @@ -190,14 +213,14 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) case USB_ENDPOINT_XFER_ISOC: s = "-iso"; break; default: s = "-intr"; break; }; s;}), - bEnd, pBuffer, dwLength); + epnum, buf, len); /* Configure endpoint */ - if (is_in || pEnd->bIsSharedFifo) - pEnd->in_qh = qh; + if (is_in || hw_ep->is_shared_fifo) + hw_ep->in_qh = qh; else - pEnd->out_qh = qh; - musb_ep_program(musb, bEnd, urb, !is_in, pBuffer, dwLength); + hw_ep->out_qh = qh; + musb_ep_program(musb, epnum, urb, !is_in, buf, len); /* transmit may have more work: start it when it is time */ if (is_in) @@ -209,7 +232,7 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) case USB_ENDPOINT_XFER_INT: DBG(3, "check whether there's still time for periodic Tx\n"); qh->iso_idx = 0; - wFrame = musb_readw(pBase, MGC_O_HDRC_FRAME); + wFrame = musb_readw(mbase, MUSB_FRAME); /* FIXME this doesn't implement that scheduling policy ... * or handle framecounter wrapping */ @@ -223,29 +246,29 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) } else { qh->frame = urb->start_frame; /* enable SOF interrupt so we can count down */ -DBG(1,"SOF for %d\n", bEnd); +DBG(1,"SOF for %d\n", epnum); #if 1 // ifndef CONFIG_ARCH_DAVINCI - musb_writeb(pBase, MGC_O_HDRC_INTRUSBE, 0xff); + musb_writeb(mbase, MUSB_INTRUSBE, 0xff); #endif } break; default: start: - DBG(4, "Start TX%d %s\n", bEnd, - pEnd->tx_channel ? "dma" : "pio"); + DBG(4, "Start TX%d %s\n", epnum, + hw_ep->tx_channel ? "dma" : "pio"); - if (!pEnd->tx_channel) - musb_h_tx_start(pEnd); - else if (is_cppi_enabled()) - cppi_host_txdma_start(pEnd); + if (!hw_ep->tx_channel) + musb_h_tx_start(hw_ep); + else if (is_cppi_enabled() || tusb_dma_omap()) + cppi_host_txdma_start(hw_ep); } } /* caller owns controller lock, irqs are blocked */ static void __musb_giveback(struct musb *musb, struct urb *urb, int status) -__releases(musb->Lock) -__acquires(musb->Lock) +__releases(musb->lock) +__acquires(musb->lock) { if ((urb->transfer_flags & URB_SHORT_NOT_OK) && (urb->actual_length < urb->transfer_buffer_length) @@ -282,9 +305,9 @@ __acquires(musb->Lock) urb->actual_length, urb->transfer_buffer_length ); - spin_unlock(&musb->Lock); + spin_unlock(&musb->lock); usb_hcd_giveback_urb(musb_to_hcd(musb), urb); - spin_lock(&musb->Lock); + spin_lock(&musb->lock); } /* for bulk/interrupt endpoints only */ @@ -299,20 +322,20 @@ static inline void musb_save_toggle(struct musb_hw_ep *ep, int is_in, struct urb * problems getting toggle correct. */ - if (is_in || ep->bIsSharedFifo) + if (is_in || ep->is_shared_fifo) qh = ep->in_qh; else qh = ep->out_qh; if (!is_in) { - csr = musb_readw(epio, MGC_O_HDRC_TXCSR); + csr = musb_readw(epio, MUSB_TXCSR); usb_settoggle(udev, qh->epnum, 1, - (csr & MGC_M_TXCSR_H_DATATOGGLE) + (csr & MUSB_TXCSR_H_DATATOGGLE) ? 1 : 0); } else { - csr = musb_readw(epio, MGC_O_HDRC_RXCSR); + csr = musb_readw(epio, MUSB_RXCSR); usb_settoggle(udev, qh->epnum, 0, - (csr & MGC_M_RXCSR_H_DATATOGGLE) + (csr & MUSB_RXCSR_H_DATATOGGLE) ? 1 : 0); } } @@ -326,7 +349,7 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status) struct musb *musb = ep->musb; int ready = qh->is_ready; - if (ep->bIsSharedFifo) + if (ep->is_shared_fifo) is_in = 1; else is_in = usb_pipein(urb->pipe); @@ -359,7 +382,7 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status) ep->tx_reinit = 1; /* clobber old pointers to this qh */ - if (is_in || ep->bIsSharedFifo) + if (is_in || ep->is_shared_fifo) ep->in_qh = NULL; else ep->out_qh = NULL; @@ -373,7 +396,7 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status) * de-allocated if it's tracked and allocated; * and where we'd update the schedule tree... */ - musb->periodic[ep->bLocalEnd] = NULL; + musb->periodic[ep->epnum] = NULL; kfree(qh); qh = NULL; break; @@ -401,37 +424,22 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status) * Context: caller owns controller lock, irqs are blocked */ static void -musb_advance_schedule(struct musb *pThis, struct urb *urb, - struct musb_hw_ep *pEnd, int is_in) +musb_advance_schedule(struct musb *musb, struct urb *urb, + struct musb_hw_ep *hw_ep, int is_in) { struct musb_qh *qh; - if (is_in || pEnd->bIsSharedFifo) - qh = pEnd->in_qh; + if (is_in || hw_ep->is_shared_fifo) + qh = hw_ep->in_qh; else - qh = pEnd->out_qh; + qh = hw_ep->out_qh; qh = musb_giveback(qh, urb, 0); -#ifdef CONFIG_USB_INVENTRA_DMA - /* REVISIT udelay reportedly works around issues in unmodified - * Mentor RTL before v1.5, where it doesn't disable the pull-up - * resisters in high speed mode. That causes signal reflection - * and errors because inter packet IDLE time vanishes. - * - * Yes, this delay makes DMA-OUT a bit slower than PIO. But - * without it, some devices are unusable. But there seem to be - * other issues too, at least on DaVinci; the delay improves - * some full speed cases, and being DMA-coupled is strange... - */ - if (is_dma_capable() && !is_in && pEnd->tx_channel) - udelay(15); /* 10 usec ~= 1x 512byte packet */ -#endif - if (qh && qh->is_ready && !list_empty(&qh->hep->urb_list)) { DBG(4, "... next ep%d %cX urb %p\n", - pEnd->bLocalEnd, is_in ? 'R' : 'T', + hw_ep->epnum, is_in ? 'R' : 'T', next_urb(qh)); - musb_start_urb(pThis, is_in, qh); + musb_start_urb(musb, is_in, qh); } } @@ -441,111 +449,114 @@ static inline u16 musb_h_flush_rxfifo(struct musb_hw_ep *hw_ep, u16 csr) * ignore dma (various models), * leave toggle alone (may not have been saved yet) */ - csr |= MGC_M_RXCSR_FLUSHFIFO | MGC_M_RXCSR_RXPKTRDY; - csr &= ~( MGC_M_RXCSR_H_REQPKT - | MGC_M_RXCSR_H_AUTOREQ - | MGC_M_RXCSR_AUTOCLEAR + csr |= MUSB_RXCSR_FLUSHFIFO | MUSB_RXCSR_RXPKTRDY; + csr &= ~( MUSB_RXCSR_H_REQPKT + | MUSB_RXCSR_H_AUTOREQ + | MUSB_RXCSR_AUTOCLEAR ); /* write 2x to allow double buffering */ - musb_writew(hw_ep->regs, MGC_O_HDRC_RXCSR, csr); - musb_writew(hw_ep->regs, MGC_O_HDRC_RXCSR, csr); + musb_writew(hw_ep->regs, MUSB_RXCSR, csr); + musb_writew(hw_ep->regs, MUSB_RXCSR, csr); /* flush writebuffer */ - return musb_readw(hw_ep->regs, MGC_O_HDRC_RXCSR); + return musb_readw(hw_ep->regs, MUSB_RXCSR); } /* * PIO RX for a packet (or part of it). */ -static u8 musb_host_packet_rx(struct musb *pThis, struct urb *pUrb, - u8 bEnd, u8 bIsochError) +static u8 musb_host_packet_rx(struct musb *musb, struct urb *urb, + u8 epnum, u8 iso_err) { - u16 wRxCount; - u8 *pBuffer; - u16 wCsr; - u8 bDone = FALSE; + u16 rx_count; + u8 *buf; + u16 csr; + u8 done = FALSE; u32 length; int do_flush = 0; - struct musb_hw_ep *pEnd = pThis->aLocalEnd + bEnd; - void __iomem *epio = pEnd->regs; - struct musb_qh *qh = pEnd->in_qh; - int nPipe = pUrb->pipe; - void *buffer = pUrb->transfer_buffer; - - // MGC_SelectEnd(pBase, bEnd); - wRxCount = musb_readw(epio, MGC_O_HDRC_RXCOUNT); + struct musb_hw_ep *hw_ep = musb->endpoints + epnum; + void __iomem *epio = hw_ep->regs; + struct musb_qh *qh = hw_ep->in_qh; + int pipe = urb->pipe; + void *buffer = urb->transfer_buffer; + + // musb_ep_select(mbase, epnum); + rx_count = musb_readw(epio, MUSB_RXCOUNT); + DBG(3, "RX%d count %d, buffer %p len %d/%d\n", epnum, rx_count, + urb->transfer_buffer, qh->offset, + urb->transfer_buffer_length); /* unload FIFO */ - if (usb_pipeisoc(nPipe)) { + if (usb_pipeisoc(pipe)) { int status = 0; struct usb_iso_packet_descriptor *d; - if (bIsochError) { + if (iso_err) { status = -EILSEQ; - pUrb->error_count++; + urb->error_count++; } - d = pUrb->iso_frame_desc + qh->iso_idx; - pBuffer = buffer + d->offset; + d = urb->iso_frame_desc + qh->iso_idx; + buf = buffer + d->offset; length = d->length; - if (wRxCount > length) { + if (rx_count > length) { if (status == 0) { status = -EOVERFLOW; - pUrb->error_count++; + urb->error_count++; } - DBG(2, "** OVERFLOW %d into %d\n", wRxCount, length); + DBG(2, "** OVERFLOW %d into %d\n", rx_count, length); do_flush = 1; } else - length = wRxCount; - pUrb->actual_length += length; + length = rx_count; + urb->actual_length += length; d->actual_length = length; d->status = status; /* see if we are done */ - bDone = (++qh->iso_idx >= pUrb->number_of_packets); + done = (++qh->iso_idx >= urb->number_of_packets); } else { /* non-isoch */ - pBuffer = buffer + qh->offset; - length = pUrb->transfer_buffer_length - qh->offset; - if (wRxCount > length) { - if (pUrb->status == -EINPROGRESS) - pUrb->status = -EOVERFLOW; - DBG(2, "** OVERFLOW %d into %d\n", wRxCount, length); + buf = buffer + qh->offset; + length = urb->transfer_buffer_length - qh->offset; + if (rx_count > length) { + if (urb->status == -EINPROGRESS) + urb->status = -EOVERFLOW; + DBG(2, "** OVERFLOW %d into %d\n", rx_count, length); do_flush = 1; } else - length = wRxCount; - pUrb->actual_length += length; + length = rx_count; + urb->actual_length += length; qh->offset += length; /* see if we are done */ - bDone = (pUrb->actual_length == pUrb->transfer_buffer_length) - || (wRxCount < qh->maxpacket) - || (pUrb->status != -EINPROGRESS); - if (bDone - && (pUrb->status == -EINPROGRESS) - && (pUrb->transfer_flags & URB_SHORT_NOT_OK) - && (pUrb->actual_length - < pUrb->transfer_buffer_length)) - pUrb->status = -EREMOTEIO; + done = (urb->actual_length == urb->transfer_buffer_length) + || (rx_count < qh->maxpacket) + || (urb->status != -EINPROGRESS); + if (done + && (urb->status == -EINPROGRESS) + && (urb->transfer_flags & URB_SHORT_NOT_OK) + && (urb->actual_length + < urb->transfer_buffer_length)) + urb->status = -EREMOTEIO; } - musb_read_fifo(pEnd, length, pBuffer); + musb_read_fifo(hw_ep, length, buf); - wCsr = musb_readw(epio, MGC_O_HDRC_RXCSR); - wCsr |= MGC_M_RXCSR_H_WZC_BITS; + csr = musb_readw(epio, MUSB_RXCSR); + csr |= MUSB_RXCSR_H_WZC_BITS; if (unlikely(do_flush)) - musb_h_flush_rxfifo(pEnd, wCsr); + musb_h_flush_rxfifo(hw_ep, csr); else { /* REVISIT this assumes AUTOCLEAR is never set */ - wCsr &= ~(MGC_M_RXCSR_RXPKTRDY | MGC_M_RXCSR_H_REQPKT); - if (!bDone) - wCsr |= MGC_M_RXCSR_H_REQPKT; - musb_writew(epio, MGC_O_HDRC_RXCSR, wCsr); + csr &= ~(MUSB_RXCSR_RXPKTRDY | MUSB_RXCSR_H_REQPKT); + if (!done) + csr |= MUSB_RXCSR_H_REQPKT; + musb_writew(epio, MUSB_RXCSR, csr); } - return bDone; + return done; } /* we don't always need to reinit a given side of an endpoint... @@ -567,47 +578,42 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep) */ /* if programmed for Tx, put it in RX mode */ - if (ep->bIsSharedFifo) { - csr = musb_readw(ep->regs, MGC_O_HDRC_TXCSR); - if (csr & MGC_M_TXCSR_MODE) { - if (csr & MGC_M_TXCSR_FIFONOTEMPTY) { - /* this shouldn't happen; irq?? */ - ERR("shared fifo not empty?\n"); - musb_writew(ep->regs, MGC_O_HDRC_TXCSR, - MGC_M_TXCSR_FLUSHFIFO); - musb_writew(ep->regs, MGC_O_HDRC_TXCSR, - MGC_M_TXCSR_FRCDATATOG); - } + if (ep->is_shared_fifo) { + csr = musb_readw(ep->regs, MUSB_TXCSR); + if (csr & MUSB_TXCSR_MODE) { + musb_h_tx_flush_fifo(ep); + musb_writew(ep->regs, MUSB_TXCSR, + MUSB_TXCSR_FRCDATATOG); } /* clear mode (and everything else) to enable Rx */ - musb_writew(ep->regs, MGC_O_HDRC_TXCSR, 0); + musb_writew(ep->regs, MUSB_TXCSR, 0); /* scrub all previous state, clearing toggle */ } else { - csr = musb_readw(ep->regs, MGC_O_HDRC_RXCSR); - if (csr & MGC_M_RXCSR_RXPKTRDY) - WARN("rx%d, packet/%d ready?\n", ep->bLocalEnd, - musb_readw(ep->regs, MGC_O_HDRC_RXCOUNT)); + csr = musb_readw(ep->regs, MUSB_RXCSR); + if (csr & MUSB_RXCSR_RXPKTRDY) + WARN("rx%d, packet/%d ready?\n", ep->epnum, + musb_readw(ep->regs, MUSB_RXCOUNT)); - musb_h_flush_rxfifo(ep, MGC_M_RXCSR_CLRDATATOG); + musb_h_flush_rxfifo(ep, MUSB_RXCSR_CLRDATATOG); } /* target addr and (for multipoint) hub addr/port */ - if (musb->bIsMultipoint) { - musb_writeb(ep->target_regs, MGC_O_HDRC_RXFUNCADDR, + if (musb->is_multipoint) { + musb_writeb(ep->target_regs, MUSB_RXFUNCADDR, qh->addr_reg); - musb_writeb(ep->target_regs, MGC_O_HDRC_RXHUBADDR, + musb_writeb(ep->target_regs, MUSB_RXHUBADDR, qh->h_addr_reg); - musb_writeb(ep->target_regs, MGC_O_HDRC_RXHUBPORT, + musb_writeb(ep->target_regs, MUSB_RXHUBPORT, qh->h_port_reg); } else - musb_writeb(musb->pRegs, MGC_O_HDRC_FADDR, qh->addr_reg); + musb_writeb(musb->mregs, MUSB_FADDR, qh->addr_reg); /* protocol/endpoint, interval/NAKlimit, i/o size */ - musb_writeb(ep->regs, MGC_O_HDRC_RXTYPE, qh->type_reg); - musb_writeb(ep->regs, MGC_O_HDRC_RXINTERVAL, qh->intv_reg); + musb_writeb(ep->regs, MUSB_RXTYPE, qh->type_reg); + musb_writeb(ep->regs, MUSB_RXINTERVAL, qh->intv_reg); /* NOTE: bulk combining rewrites high bits of maxpacket */ - musb_writew(ep->regs, MGC_O_HDRC_RXMAXP, qh->maxpacket); + musb_writew(ep->regs, MUSB_RXMAXP, qh->maxpacket); ep->rx_reinit = 0; } @@ -617,227 +623,225 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep) * Program an HDRC endpoint as per the given URB * Context: irqs blocked, controller lock held */ -static void musb_ep_program(struct musb *pThis, u8 bEnd, - struct urb *pUrb, unsigned int is_out, - u8 * pBuffer, u32 dwLength) +static void musb_ep_program(struct musb *musb, u8 epnum, + struct urb *urb, unsigned int is_out, + u8 * buf, u32 len) { - struct dma_controller *pDmaController; - struct dma_channel *pDmaChannel; - u8 bDmaOk; - void __iomem *pBase = pThis->pRegs; - struct musb_hw_ep *pEnd = pThis->aLocalEnd + bEnd; - void __iomem *epio = pEnd->regs; + struct dma_controller *dma_controller; + struct dma_channel *dma_channel; + u8 dma_ok; + void __iomem *mbase = musb->mregs; + struct musb_hw_ep *hw_ep = musb->endpoints + epnum; + void __iomem *epio = hw_ep->regs; struct musb_qh *qh; - u16 wPacketSize; + u16 packet_sz; - if (!is_out || pEnd->bIsSharedFifo) - qh = pEnd->in_qh; + if (!is_out || hw_ep->is_shared_fifo) + qh = hw_ep->in_qh; else - qh = pEnd->out_qh; + qh = hw_ep->out_qh; - wPacketSize = qh->maxpacket; + packet_sz = qh->maxpacket; DBG(3, "%s hw%d urb %p spd%d dev%d ep%d%s " "h_addr%02x h_port%02x bytes %d\n", is_out ? "-->" : "<--", - bEnd, pUrb, pUrb->dev->speed, + epnum, urb, urb->dev->speed, qh->addr_reg, qh->epnum, is_out ? "out" : "in", qh->h_addr_reg, qh->h_port_reg, - dwLength); + len); - MGC_SelectEnd(pBase, bEnd); + musb_ep_select(mbase, epnum); /* candidate for DMA? */ - pDmaController = pThis->pDmaController; - if (is_dma_capable() && bEnd && pDmaController) { - pDmaChannel = is_out ? pEnd->tx_channel : pEnd->rx_channel; - if (!pDmaChannel) { - pDmaChannel = pDmaController->channel_alloc( - pDmaController, pEnd, is_out); + dma_controller = musb->dma_controller; + if (is_dma_capable() && epnum && dma_controller) { + dma_channel = is_out ? hw_ep->tx_channel : hw_ep->rx_channel; + if (!dma_channel) { + dma_channel = dma_controller->channel_alloc( + dma_controller, hw_ep, is_out); if (is_out) - pEnd->tx_channel = pDmaChannel; + hw_ep->tx_channel = dma_channel; else - pEnd->rx_channel = pDmaChannel; + hw_ep->rx_channel = dma_channel; } } else - pDmaChannel = NULL; + dma_channel = NULL; /* make sure we clear DMAEnab, autoSet bits from previous run */ /* OUT/transmit/EP0 or IN/receive? */ if (is_out) { - u16 wCsr; - u16 wIntrTxE; - u16 wLoadCount; + u16 csr; + u16 int_txe; + u16 load_count; - wCsr = musb_readw(epio, MGC_O_HDRC_TXCSR); + csr = musb_readw(epio, MUSB_TXCSR); /* disable interrupt in case we flush */ - wIntrTxE = musb_readw(pBase, MGC_O_HDRC_INTRTXE); - musb_writew(pBase, MGC_O_HDRC_INTRTXE, wIntrTxE & ~(1 << bEnd)); + int_txe = musb_readw(mbase, MUSB_INTRTXE); + musb_writew(mbase, MUSB_INTRTXE, int_txe & ~(1 << epnum)); /* general endpoint setup */ - if (bEnd) { - u16 csr = wCsr; + if (epnum) { + u16 csr = csr; /* ASSERT: TXCSR_DMAENAB was already cleared */ /* flush all old state, set default */ - if (csr & MGC_M_TXCSR_FIFONOTEMPTY) - csr |= MGC_M_TXCSR_FLUSHFIFO; - csr &= ~(MGC_M_TXCSR_H_NAKTIMEOUT - | MGC_M_TXCSR_DMAMODE - | MGC_M_TXCSR_FRCDATATOG - | MGC_M_TXCSR_H_RXSTALL - | MGC_M_TXCSR_H_ERROR - | MGC_M_TXCSR_FIFONOTEMPTY - | MGC_M_TXCSR_TXPKTRDY + musb_h_tx_flush_fifo(hw_ep); + csr &= ~(MUSB_TXCSR_H_NAKTIMEOUT + | MUSB_TXCSR_DMAMODE + | MUSB_TXCSR_FRCDATATOG + | MUSB_TXCSR_H_RXSTALL + | MUSB_TXCSR_H_ERROR + | MUSB_TXCSR_TXPKTRDY ); - csr |= MGC_M_TXCSR_MODE; + csr |= MUSB_TXCSR_MODE; - if (usb_gettoggle(pUrb->dev, + if (usb_gettoggle(urb->dev, qh->epnum, 1)) - csr |= MGC_M_TXCSR_H_WR_DATATOGGLE - | MGC_M_TXCSR_H_DATATOGGLE; + csr |= MUSB_TXCSR_H_WR_DATATOGGLE + | MUSB_TXCSR_H_DATATOGGLE; else - csr |= MGC_M_TXCSR_CLRDATATOG; + csr |= MUSB_TXCSR_CLRDATATOG; /* twice in case of double packet buffering */ - musb_writew(epio, MGC_O_HDRC_TXCSR, csr); + musb_writew(epio, MUSB_TXCSR, csr); /* REVISIT may need to clear FLUSHFIFO ... */ - musb_writew(epio, MGC_O_HDRC_TXCSR, csr); - wCsr = musb_readw(epio, MGC_O_HDRC_TXCSR); + musb_writew(epio, MUSB_TXCSR, csr); + csr = musb_readw(epio, MUSB_TXCSR); } else { /* endpoint 0: just flush */ - musb_writew(epio, MGC_O_HDRC_CSR0, - wCsr | MGC_M_CSR0_FLUSHFIFO); - musb_writew(epio, MGC_O_HDRC_CSR0, - wCsr | MGC_M_CSR0_FLUSHFIFO); + musb_writew(epio, MUSB_CSR0, + csr | MUSB_CSR0_FLUSHFIFO); + musb_writew(epio, MUSB_CSR0, + csr | MUSB_CSR0_FLUSHFIFO); } /* target addr and (for multipoint) hub addr/port */ - if (pThis->bIsMultipoint) { - musb_writeb(pBase, - MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXFUNCADDR), + if (musb->is_multipoint) { + musb_writeb(mbase, + MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR), qh->addr_reg); - musb_writeb(pBase, - MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBADDR), + musb_writeb(mbase, + MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR), qh->h_addr_reg); - musb_writeb(pBase, - MGC_BUSCTL_OFFSET(bEnd, MGC_O_HDRC_TXHUBPORT), + musb_writeb(mbase, + MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT), qh->h_port_reg); -/* FIXME if !bEnd, do the same for RX ... */ +/* FIXME if !epnum, do the same for RX ... */ } else - musb_writeb(pBase, MGC_O_HDRC_FADDR, qh->addr_reg); + musb_writeb(mbase, MUSB_FADDR, qh->addr_reg); /* protocol/endpoint/interval/NAKlimit */ - if (bEnd) { - musb_writeb(epio, MGC_O_HDRC_TXTYPE, qh->type_reg); - if (can_bulk_split(pThis, qh->type)) - musb_writew(epio, MGC_O_HDRC_TXMAXP, - wPacketSize - | ((pEnd->wMaxPacketSizeTx / - wPacketSize) - 1) << 11); + if (epnum) { + musb_writeb(epio, MUSB_TXTYPE, qh->type_reg); + if (can_bulk_split(musb, qh->type)) + musb_writew(epio, MUSB_TXMAXP, + packet_sz + | ((hw_ep->max_packet_sz_tx / + packet_sz) - 1) << 11); else - musb_writew(epio, MGC_O_HDRC_TXMAXP, - wPacketSize); - musb_writeb(epio, MGC_O_HDRC_TXINTERVAL, qh->intv_reg); + musb_writew(epio, MUSB_TXMAXP, + packet_sz); + musb_writeb(epio, MUSB_TXINTERVAL, qh->intv_reg); } else { - musb_writeb(epio, MGC_O_HDRC_NAKLIMIT0, qh->intv_reg); - if (pThis->bIsMultipoint) - musb_writeb(epio, MGC_O_HDRC_TYPE0, + musb_writeb(epio, MUSB_NAKLIMIT0, qh->intv_reg); + if (musb->is_multipoint) + musb_writeb(epio, MUSB_TYPE0, qh->type_reg); } - if (can_bulk_split(pThis, qh->type)) - wLoadCount = min((u32) pEnd->wMaxPacketSizeTx, - dwLength); + if (can_bulk_split(musb, qh->type)) + load_count = min((u32) hw_ep->max_packet_sz_tx, + len); else - wLoadCount = min((u32) wPacketSize, dwLength); + load_count = min((u32) packet_sz, len); #ifdef CONFIG_USB_INVENTRA_DMA - if (pDmaChannel) { + if (dma_channel) { /* clear previous state */ - wCsr = musb_readw(epio, MGC_O_HDRC_TXCSR); - wCsr &= ~(MGC_M_TXCSR_AUTOSET - | MGC_M_TXCSR_DMAMODE - | MGC_M_TXCSR_DMAENAB); - wCsr |= MGC_M_TXCSR_MODE; - musb_writew(epio, MGC_O_HDRC_TXCSR, - wCsr | MGC_M_TXCSR_MODE); - - qh->segsize = min(dwLength, pDmaChannel->dwMaxLength); - - if (qh->segsize <= wPacketSize) - pDmaChannel->bDesiredMode = 0; + csr = musb_readw(epio, MUSB_TXCSR); + csr &= ~(MUSB_TXCSR_AUTOSET + | MUSB_TXCSR_DMAMODE + | MUSB_TXCSR_DMAENAB); + csr |= MUSB_TXCSR_MODE; + musb_writew(epio, MUSB_TXCSR, + csr | MUSB_TXCSR_MODE); + + qh->segsize = min(len, dma_channel->max_len); + + if (qh->segsize <= packet_sz) + dma_channel->desired_mode = 0; else - pDmaChannel->bDesiredMode = 1; + dma_channel->desired_mode = 1; - if (pDmaChannel->bDesiredMode == 0) { - wCsr &= ~(MGC_M_TXCSR_AUTOSET - | MGC_M_TXCSR_DMAMODE); - wCsr |= (MGC_M_TXCSR_DMAENAB); + if (dma_channel->desired_mode == 0) { + csr &= ~(MUSB_TXCSR_AUTOSET + | MUSB_TXCSR_DMAMODE); + csr |= (MUSB_TXCSR_DMAENAB); // against programming guide } else - wCsr |= (MGC_M_TXCSR_AUTOSET - | MGC_M_TXCSR_DMAENAB - | MGC_M_TXCSR_DMAMODE); + csr |= (MUSB_TXCSR_AUTOSET + | MUSB_TXCSR_DMAENAB + | MUSB_TXCSR_DMAMODE); - musb_writew(epio, MGC_O_HDRC_TXCSR, wCsr); + musb_writew(epio, MUSB_TXCSR, csr); - bDmaOk = pDmaController->channel_program( - pDmaChannel, wPacketSize, - pDmaChannel->bDesiredMode, - pUrb->transfer_dma, + dma_ok = dma_controller->channel_program( + dma_channel, packet_sz, + dma_channel->desired_mode, + urb->transfer_dma, qh->segsize); - if (bDmaOk) { - wLoadCount = 0; + if (dma_ok) { + load_count = 0; } else { - pDmaController->channel_release(pDmaChannel); + dma_controller->channel_release(dma_channel); if (is_out) - pEnd->tx_channel = NULL; + hw_ep->tx_channel = NULL; else - pEnd->rx_channel = NULL; - pDmaChannel = NULL; + hw_ep->rx_channel = NULL; + dma_channel = NULL; } } #endif /* candidate for DMA */ - if (is_cppi_enabled() && pDmaChannel) { + if ((is_cppi_enabled() || tusb_dma_omap()) && dma_channel) { /* program endpoint CSRs first, then setup DMA. * assume CPPI setup succeeds. * defer enabling dma. */ - wCsr = musb_readw(epio, MGC_O_HDRC_TXCSR); - wCsr &= ~(MGC_M_TXCSR_AUTOSET - | MGC_M_TXCSR_DMAMODE - | MGC_M_TXCSR_DMAENAB); - wCsr |= MGC_M_TXCSR_MODE; - musb_writew(epio, MGC_O_HDRC_TXCSR, - wCsr | MGC_M_TXCSR_MODE); + csr = musb_readw(epio, MUSB_TXCSR); + csr &= ~(MUSB_TXCSR_AUTOSET + | MUSB_TXCSR_DMAMODE + | MUSB_TXCSR_DMAENAB); + csr |= MUSB_TXCSR_MODE; + musb_writew(epio, MUSB_TXCSR, + csr | MUSB_TXCSR_MODE); - pDmaChannel->dwActualLength = 0L; - qh->segsize = dwLength; + dma_channel->actual_len = 0L; + qh->segsize = len; /* TX uses "rndis" mode automatically, but needs help * to identify the zero-length-final-packet case. */ - bDmaOk = pDmaController->channel_program( - pDmaChannel, wPacketSize, - (pUrb->transfer_flags + dma_ok = dma_controller->channel_program( + dma_channel, packet_sz, + (urb->transfer_flags & URB_ZERO_PACKET) == URB_ZERO_PACKET, - pUrb->transfer_dma, + urb->transfer_dma, qh->segsize); - if (bDmaOk) { - wLoadCount = 0; + if (dma_ok) { + load_count = 0; } else { - pDmaController->channel_release(pDmaChannel); - pDmaChannel = pEnd->tx_channel = NULL; + dma_controller->channel_release(dma_channel); + dma_channel = hw_ep->tx_channel = NULL; /* REVISIT there's an error path here that * needs handling: can't do dma, but @@ -846,90 +850,90 @@ static void musb_ep_program(struct musb *pThis, u8 bEnd, } } - if (wLoadCount) { + if (load_count) { /* ASSERT: TXCSR_DMAENAB was already cleared */ /* PIO to load FIFO */ - qh->segsize = wLoadCount; - musb_write_fifo(pEnd, wLoadCount, pBuffer); - wCsr = musb_readw(epio, MGC_O_HDRC_TXCSR); - wCsr &= ~(MGC_M_TXCSR_DMAENAB - | MGC_M_TXCSR_DMAMODE - | MGC_M_TXCSR_AUTOSET); + qh->segsize = load_count; + musb_write_fifo(hw_ep, load_count, buf); + csr = musb_readw(epio, MUSB_TXCSR); + csr &= ~(MUSB_TXCSR_DMAENAB + | MUSB_TXCSR_DMAMODE + | MUSB_TXCSR_AUTOSET); /* write CSR */ - wCsr |= MGC_M_TXCSR_MODE; + csr |= MUSB_TXCSR_MODE; - if (bEnd) - musb_writew(epio, MGC_O_HDRC_TXCSR, wCsr); + if (epnum) + musb_writew(epio, MUSB_TXCSR, csr); } /* re-enable interrupt */ - musb_writew(pBase, MGC_O_HDRC_INTRTXE, wIntrTxE); + musb_writew(mbase, MUSB_INTRTXE, int_txe); /* IN/receive */ } else { u16 csr; - if (pEnd->rx_reinit) { - musb_rx_reinit(pThis, qh, pEnd); + if (hw_ep->rx_reinit) { + musb_rx_reinit(musb, qh, hw_ep); /* init new state: toggle and NYET, maybe DMA later */ - if (usb_gettoggle(pUrb->dev, qh->epnum, 0)) - csr = MGC_M_RXCSR_H_WR_DATATOGGLE - | MGC_M_RXCSR_H_DATATOGGLE; + if (usb_gettoggle(urb->dev, qh->epnum, 0)) + csr = MUSB_RXCSR_H_WR_DATATOGGLE + | MUSB_RXCSR_H_DATATOGGLE; else csr = 0; if (qh->type == USB_ENDPOINT_XFER_INT) - csr |= MGC_M_RXCSR_DISNYET; + csr |= MUSB_RXCSR_DISNYET; } else { - csr = musb_readw(pEnd->regs, MGC_O_HDRC_RXCSR); + csr = musb_readw(hw_ep->regs, MUSB_RXCSR); - if (csr & (MGC_M_RXCSR_RXPKTRDY - | MGC_M_RXCSR_DMAENAB - | MGC_M_RXCSR_H_REQPKT)) + if (csr & (MUSB_RXCSR_RXPKTRDY + | MUSB_RXCSR_DMAENAB + | MUSB_RXCSR_H_REQPKT)) ERR("broken !rx_reinit, ep%d csr %04x\n", - pEnd->bLocalEnd, csr); + hw_ep->epnum, csr); /* scrub any stale state, leaving toggle alone */ - csr &= MGC_M_RXCSR_DISNYET; + csr &= MUSB_RXCSR_DISNYET; } /* kick things off */ - if (is_cppi_enabled()) { + if ((is_cppi_enabled() || tusb_dma_omap()) && dma_channel) { /* candidate for DMA */ - if (pDmaChannel) { - pDmaChannel->dwActualLength = 0L; - qh->segsize = dwLength; + if (dma_channel) { + dma_channel->actual_len = 0L; + qh->segsize = len; /* AUTOREQ is in a DMA register */ - musb_writew(pEnd->regs, MGC_O_HDRC_RXCSR, csr); - csr = musb_readw(pEnd->regs, - MGC_O_HDRC_RXCSR); + musb_writew(hw_ep->regs, MUSB_RXCSR, csr); + csr = musb_readw(hw_ep->regs, + MUSB_RXCSR); /* unless caller treats short rx transfers as * errors, we dare not queue multiple transfers. */ - bDmaOk = pDmaController->channel_program( - pDmaChannel, wPacketSize, - !(pUrb->transfer_flags + dma_ok = dma_controller->channel_program( + dma_channel, packet_sz, + !(urb->transfer_flags & URB_SHORT_NOT_OK), - pUrb->transfer_dma, + urb->transfer_dma, qh->segsize); - if (!bDmaOk) { - pDmaController->channel_release( - pDmaChannel); - pDmaChannel = pEnd->rx_channel = NULL; + if (!dma_ok) { + dma_controller->channel_release( + dma_channel); + dma_channel = hw_ep->rx_channel = NULL; } else - csr |= MGC_M_RXCSR_DMAENAB; + csr |= MUSB_RXCSR_DMAENAB; } } - csr |= MGC_M_RXCSR_H_REQPKT; - DBG(7, "RXCSR%d := %04x\n", bEnd, csr); - musb_writew(pEnd->regs, MGC_O_HDRC_RXCSR, csr); - csr = musb_readw(pEnd->regs, MGC_O_HDRC_RXCSR); + csr |= MUSB_RXCSR_H_REQPKT; + DBG(7, "RXCSR%d := %04x\n", epnum, csr); + musb_writew(hw_ep->regs, MUSB_RXCSR, csr); + csr = musb_readw(hw_ep->regs, MUSB_RXCSR); } } @@ -938,70 +942,70 @@ static void musb_ep_program(struct musb *pThis, u8 bEnd, * Service the default endpoint (ep0) as host. * Return TRUE until it's time to start the status stage. */ -static int musb_h_ep0_continue(struct musb *pThis, - u16 wCount, struct urb *pUrb) +static int musb_h_ep0_continue(struct musb *musb, + u16 len, struct urb *urb) { int bMore = FALSE; - u8 *pFifoDest = NULL; - u16 wFifoCount = 0; - struct musb_hw_ep *pEnd = pThis->control_ep; - struct musb_qh *qh = pEnd->in_qh; - struct usb_ctrlrequest *pRequest; + u8 *fifo_dest = NULL; + u16 fifo_count = 0; + struct musb_hw_ep *hw_ep = musb->control_ep; + struct musb_qh *qh = hw_ep->in_qh; + struct usb_ctrlrequest *request; - switch (pThis->bEnd0Stage) { + switch (musb->ep0_stage) { case MGC_END0_IN: - pFifoDest = pUrb->transfer_buffer + pUrb->actual_length; - wFifoCount = min(wCount, ((u16) (pUrb->transfer_buffer_length - - pUrb->actual_length))); - if (wFifoCount < wCount) - pUrb->status = -EOVERFLOW; + fifo_dest = urb->transfer_buffer + urb->actual_length; + fifo_count = min(len, ((u16) (urb->transfer_buffer_length + - urb->actual_length))); + if (fifo_count < len) + urb->status = -EOVERFLOW; - musb_read_fifo(pEnd, wFifoCount, pFifoDest); + musb_read_fifo(hw_ep, fifo_count, fifo_dest); - pUrb->actual_length += wFifoCount; - if (wCount < qh->maxpacket) { + urb->actual_length += fifo_count; + if (len < qh->maxpacket) { /* always terminate on short read; it's * rarely reported as an error. */ - } else if (pUrb->actual_length < - pUrb->transfer_buffer_length) + } else if (urb->actual_length < + urb->transfer_buffer_length) bMore = TRUE; break; case MGC_END0_START: - pRequest = (struct usb_ctrlrequest *) pUrb->setup_packet; + request = (struct usb_ctrlrequest *) urb->setup_packet; - if (!pRequest->wLength) { + if (!request->wLength) { DBG(4, "start no-DATA\n"); break; - } else if (pRequest->bRequestType & USB_DIR_IN) { + } else if (request->bRequestType & USB_DIR_IN) { DBG(4, "start IN-DATA\n"); - pThis->bEnd0Stage = MGC_END0_IN; + musb->ep0_stage = MGC_END0_IN; bMore = TRUE; break; } else { DBG(4, "start OUT-DATA\n"); - pThis->bEnd0Stage = MGC_END0_OUT; + musb->ep0_stage = MGC_END0_OUT; bMore = TRUE; } /* FALLTHROUGH */ case MGC_END0_OUT: - wFifoCount = min(qh->maxpacket, ((u16) - (pUrb->transfer_buffer_length - - pUrb->actual_length))); + fifo_count = min(qh->maxpacket, ((u16) + (urb->transfer_buffer_length + - urb->actual_length))); - if (wFifoCount) { - pFifoDest = (u8 *) (pUrb->transfer_buffer - + pUrb->actual_length); + if (fifo_count) { + fifo_dest = (u8 *) (urb->transfer_buffer + + urb->actual_length); DBG(3, "Sending %d bytes to %p\n", - wFifoCount, pFifoDest); - musb_write_fifo(pEnd, wFifoCount, pFifoDest); + fifo_count, fifo_dest); + musb_write_fifo(hw_ep, fifo_count, fifo_dest); - pUrb->actual_length += wFifoCount; + urb->actual_length += fifo_count; bMore = TRUE; } break; default: - ERR("bogus ep0 stage %d\n", pThis->bEnd0Stage); + ERR("bogus ep0 stage %d\n", musb->ep0_stage); break; } @@ -1014,46 +1018,46 @@ static int musb_h_ep0_continue(struct musb *pThis, * * called with controller irqlocked */ -irqreturn_t musb_h_ep0_irq(struct musb *pThis) +irqreturn_t musb_h_ep0_irq(struct musb *musb) { - struct urb *pUrb; - u16 wCsrVal, wCount; + struct urb *urb; + u16 csr, len; int status = 0; - void __iomem *pBase = pThis->pRegs; - struct musb_hw_ep *pEnd = pThis->control_ep; - void __iomem *epio = pEnd->regs; - struct musb_qh *qh = pEnd->in_qh; + void __iomem *mbase = musb->mregs; + struct musb_hw_ep *hw_ep = musb->control_ep; + void __iomem *epio = hw_ep->regs; + struct musb_qh *qh = hw_ep->in_qh; u8 bComplete = FALSE; irqreturn_t retval = IRQ_NONE; /* ep0 only has one queue, "in" */ - pUrb = next_urb(qh); + urb = next_urb(qh); - MGC_SelectEnd(pBase, 0); - wCsrVal = musb_readw(epio, MGC_O_HDRC_CSR0); - wCount = (wCsrVal & MGC_M_CSR0_RXPKTRDY) - ? musb_readb(epio, MGC_O_HDRC_COUNT0) + musb_ep_select(mbase, 0); + csr = musb_readw(epio, MUSB_CSR0); + len = (csr & MUSB_CSR0_RXPKTRDY) + ? musb_readb(epio, MUSB_COUNT0) : 0; DBG(4, "<== csr0 %04x, qh %p, count %d, urb %p, stage %d\n", - wCsrVal, qh, wCount, pUrb, pThis->bEnd0Stage); + csr, qh, len, urb, musb->ep0_stage); /* if we just did status stage, we are done */ - if (MGC_END0_STATUS == pThis->bEnd0Stage) { + if (MGC_END0_STATUS == musb->ep0_stage) { retval = IRQ_HANDLED; bComplete = TRUE; } /* prepare status */ - if (wCsrVal & MGC_M_CSR0_H_RXSTALL) { + if (csr & MUSB_CSR0_H_RXSTALL) { DBG(6, "STALLING ENDPOINT\n"); status = -EPIPE; - } else if (wCsrVal & MGC_M_CSR0_H_ERROR) { - DBG(2, "no response, csr0 %04x\n", wCsrVal); + } else if (csr & MUSB_CSR0_H_ERROR) { + DBG(2, "no response, csr0 %04x\n", csr); status = -EPROTO; - } else if (wCsrVal & MGC_M_CSR0_H_NAKTIMEOUT) { + } else if (csr & MUSB_CSR0_H_NAKTIMEOUT) { DBG(2, "control NAK timeout\n"); /* NOTE: this code path would be a good place to PAUSE a @@ -1063,79 +1067,79 @@ irqreturn_t musb_h_ep0_irq(struct musb *pThis) * if (qh->ring.next != &musb->control), then * we have a candidate... NAKing is *NOT* an error */ - musb_writew(epio, MGC_O_HDRC_CSR0, 0); + musb_writew(epio, MUSB_CSR0, 0); retval = IRQ_HANDLED; } if (status) { DBG(6, "aborting\n"); retval = IRQ_HANDLED; - if (pUrb) - pUrb->status = status; + if (urb) + urb->status = status; bComplete = TRUE; /* use the proper sequence to abort the transfer */ - if (wCsrVal & MGC_M_CSR0_H_REQPKT) { - wCsrVal &= ~MGC_M_CSR0_H_REQPKT; - musb_writew(epio, MGC_O_HDRC_CSR0, wCsrVal); - wCsrVal &= ~MGC_M_CSR0_H_NAKTIMEOUT; - musb_writew(epio, MGC_O_HDRC_CSR0, wCsrVal); + if (csr & MUSB_CSR0_H_REQPKT) { + csr &= ~MUSB_CSR0_H_REQPKT; + musb_writew(epio, MUSB_CSR0, csr); + csr &= ~MUSB_CSR0_H_NAKTIMEOUT; + musb_writew(epio, MUSB_CSR0, csr); } else { - wCsrVal |= MGC_M_CSR0_FLUSHFIFO; - musb_writew(epio, MGC_O_HDRC_CSR0, wCsrVal); - musb_writew(epio, MGC_O_HDRC_CSR0, wCsrVal); - wCsrVal &= ~MGC_M_CSR0_H_NAKTIMEOUT; - musb_writew(epio, MGC_O_HDRC_CSR0, wCsrVal); + csr |= MUSB_CSR0_FLUSHFIFO; + musb_writew(epio, MUSB_CSR0, csr); + musb_writew(epio, MUSB_CSR0, csr); + csr &= ~MUSB_CSR0_H_NAKTIMEOUT; + musb_writew(epio, MUSB_CSR0, csr); } - musb_writeb(epio, MGC_O_HDRC_NAKLIMIT0, 0); + musb_writeb(epio, MUSB_NAKLIMIT0, 0); /* clear it */ - musb_writew(epio, MGC_O_HDRC_CSR0, 0); + musb_writew(epio, MUSB_CSR0, 0); } - if (unlikely(!pUrb)) { + if (unlikely(!urb)) { /* stop endpoint since we have no place for its data, this * SHOULD NEVER HAPPEN! */ ERR("no URB for end 0\n"); - musb_writew(epio, MGC_O_HDRC_CSR0, MGC_M_CSR0_FLUSHFIFO); - musb_writew(epio, MGC_O_HDRC_CSR0, MGC_M_CSR0_FLUSHFIFO); - musb_writew(epio, MGC_O_HDRC_CSR0, 0); + musb_writew(epio, MUSB_CSR0, MUSB_CSR0_FLUSHFIFO); + musb_writew(epio, MUSB_CSR0, MUSB_CSR0_FLUSHFIFO); + musb_writew(epio, MUSB_CSR0, 0); goto done; } if (!bComplete) { /* call common logic and prepare response */ - if (musb_h_ep0_continue(pThis, wCount, pUrb)) { + if (musb_h_ep0_continue(musb, len, urb)) { /* more packets required */ - wCsrVal = (MGC_END0_IN == pThis->bEnd0Stage) - ? MGC_M_CSR0_H_REQPKT : MGC_M_CSR0_TXPKTRDY; + csr = (MGC_END0_IN == musb->ep0_stage) + ? MUSB_CSR0_H_REQPKT : MUSB_CSR0_TXPKTRDY; } else { /* data transfer complete; perform status phase */ - if (usb_pipeout(pUrb->pipe) - || !pUrb->transfer_buffer_length) - wCsrVal = MGC_M_CSR0_H_STATUSPKT - | MGC_M_CSR0_H_REQPKT; + if (usb_pipeout(urb->pipe) + || !urb->transfer_buffer_length) + csr = MUSB_CSR0_H_STATUSPKT + | MUSB_CSR0_H_REQPKT; else - wCsrVal = MGC_M_CSR0_H_STATUSPKT - | MGC_M_CSR0_TXPKTRDY; + csr = MUSB_CSR0_H_STATUSPKT + | MUSB_CSR0_TXPKTRDY; /* flag status stage */ - pThis->bEnd0Stage = MGC_END0_STATUS; + musb->ep0_stage = MGC_END0_STATUS; - DBG(5, "ep0 STATUS, csr %04x\n", wCsrVal); + DBG(5, "ep0 STATUS, csr %04x\n", csr); } - musb_writew(epio, MGC_O_HDRC_CSR0, wCsrVal); + musb_writew(epio, MUSB_CSR0, csr); retval = IRQ_HANDLED; } else - pThis->bEnd0Stage = MGC_END0_IDLE; + musb->ep0_stage = MGC_END0_IDLE; /* call completion handler if done */ if (bComplete) - musb_advance_schedule(pThis, pUrb, pEnd, 1); + musb_advance_schedule(musb, urb, hw_ep, 1); done: return retval; } @@ -1158,53 +1162,53 @@ done: #endif /* Service a Tx-Available or dma completion irq for the endpoint */ -void musb_host_tx(struct musb *pThis, u8 bEnd) +void musb_host_tx(struct musb *musb, u8 epnum) { - int nPipe; - u8 bDone = FALSE; - u16 wTxCsrVal; + int pipe; + u8 done = FALSE; + u16 tx_csr; size_t wLength = 0; - u8 *pBuffer = NULL; - struct urb *pUrb; - struct musb_hw_ep *pEnd = pThis->aLocalEnd + bEnd; - void __iomem *epio = pEnd->regs; - struct musb_qh *qh = pEnd->out_qh; + u8 *buf = NULL; + struct urb *urb; + struct musb_hw_ep *hw_ep = musb->endpoints + epnum; + void __iomem *epio = hw_ep->regs; + struct musb_qh *qh = hw_ep->out_qh; u32 status = 0; - void __iomem *pBase = pThis->pRegs; + void __iomem *mbase = musb->mregs; struct dma_channel *dma; - pUrb = next_urb(qh); + urb = next_urb(qh); - MGC_SelectEnd(pBase, bEnd); - wTxCsrVal = musb_readw(epio, MGC_O_HDRC_TXCSR); + musb_ep_select(mbase, epnum); + tx_csr = musb_readw(epio, MUSB_TXCSR); /* with CPPI, DMA sometimes triggers "extra" irqs */ - if (!pUrb) { - DBG(4, "extra TX%d ready, csr %04x\n", bEnd, wTxCsrVal); + if (!urb) { + DBG(4, "extra TX%d ready, csr %04x\n", epnum, tx_csr); goto finish; } - nPipe = pUrb->pipe; - dma = is_dma_capable() ? pEnd->tx_channel : NULL; - DBG(4, "OUT/TX%d end, csr %04x%s\n", bEnd, wTxCsrVal, + pipe = urb->pipe; + dma = is_dma_capable() ? hw_ep->tx_channel : NULL; + DBG(4, "OUT/TX%d end, csr %04x%s\n", epnum, tx_csr, dma ? ", dma" : ""); /* check for errors */ - if (wTxCsrVal & MGC_M_TXCSR_H_RXSTALL) { + if (tx_csr & MUSB_TXCSR_H_RXSTALL) { /* dma was disabled, fifo flushed */ - DBG(3, "TX end %d stall\n", bEnd); + DBG(3, "TX end %d stall\n", epnum); /* stall; record URB status */ status = -EPIPE; - } else if (wTxCsrVal & MGC_M_TXCSR_H_ERROR) { + } else if (tx_csr & MUSB_TXCSR_H_ERROR) { /* (NON-ISO) dma was disabled, fifo flushed */ - DBG(3, "TX 3strikes on ep=%d\n", bEnd); + DBG(3, "TX 3strikes on ep=%d\n", epnum); status = -ETIMEDOUT; - } else if (wTxCsrVal & MGC_M_TXCSR_H_NAKTIMEOUT) { - DBG(6, "TX end=%d device not responding\n", bEnd); + } else if (tx_csr & MUSB_TXCSR_H_NAKTIMEOUT) { + DBG(6, "TX end=%d device not responding\n", epnum); /* NOTE: this code path would be a good place to PAUSE a * transfer, if there's some other (nonperiodic) tx urb @@ -1213,97 +1217,80 @@ void musb_host_tx(struct musb *pThis, u8 bEnd) * if (bulk && qh->ring.next != &musb->out_bulk), then * we have a candidate... NAKing is *NOT* an error */ - MGC_SelectEnd(pBase, bEnd); - musb_writew(epio, MGC_O_HDRC_CSR0, - MGC_M_TXCSR_H_WZC_BITS - | MGC_M_TXCSR_TXPKTRDY); + musb_ep_select(mbase, epnum); + musb_writew(epio, MUSB_CSR0, + MUSB_TXCSR_H_WZC_BITS + | MUSB_TXCSR_TXPKTRDY); goto finish; } if (status) { if (dma_channel_status(dma) == MGC_DMA_STATUS_BUSY) { - dma->bStatus = MGC_DMA_STATUS_CORE_ABORT; - (void) pThis->pDmaController->channel_abort(dma); + dma->status = MGC_DMA_STATUS_CORE_ABORT; + (void) musb->dma_controller->channel_abort(dma); } /* do the proper sequence to abort the transfer in the * usb core; the dma engine should already be stopped. */ -// SCRUB (TX) - if (wTxCsrVal & MGC_M_TXCSR_FIFONOTEMPTY) - wTxCsrVal |= MGC_M_TXCSR_FLUSHFIFO; - wTxCsrVal &= ~(MGC_M_TXCSR_FIFONOTEMPTY - | MGC_M_TXCSR_AUTOSET - | MGC_M_TXCSR_DMAENAB - | MGC_M_TXCSR_H_ERROR - | MGC_M_TXCSR_H_RXSTALL - | MGC_M_TXCSR_H_NAKTIMEOUT + musb_h_tx_flush_fifo(hw_ep); + tx_csr &= ~(MUSB_TXCSR_AUTOSET + | MUSB_TXCSR_DMAENAB + | MUSB_TXCSR_H_ERROR + | MUSB_TXCSR_H_RXSTALL + | MUSB_TXCSR_H_NAKTIMEOUT ); - MGC_SelectEnd(pBase, bEnd); - musb_writew(epio, MGC_O_HDRC_TXCSR, wTxCsrVal); + musb_ep_select(mbase, epnum); + musb_writew(epio, MUSB_TXCSR, tx_csr); /* REVISIT may need to clear FLUSHFIFO ... */ - musb_writew(epio, MGC_O_HDRC_TXCSR, wTxCsrVal); - musb_writeb(epio, MGC_O_HDRC_TXINTERVAL, 0); + musb_writew(epio, MUSB_TXCSR, tx_csr); + musb_writeb(epio, MUSB_TXINTERVAL, 0); - bDone = TRUE; + done = TRUE; } /* second cppi case */ if (dma_channel_status(dma) == MGC_DMA_STATUS_BUSY) { - DBG(4, "extra TX%d ready, csr %04x\n", bEnd, wTxCsrVal); + DBG(4, "extra TX%d ready, csr %04x\n", epnum, tx_csr); goto finish; } /* REVISIT this looks wrong... */ - if (!status || dma || usb_pipeisoc(nPipe)) { - -#ifdef CONFIG_USB_INVENTRA_DMA - /* mode 0 or last short packet) - * REVISIT how about ZLP? - */ - if ((dma->bDesiredMode == 0) - || (dma->dwActualLength - & (qh->maxpacket - 1))) { - /* Send out the packet first ... */ - MGC_SelectEnd(pBase, bEnd); - musb_writew(epio, MGC_O_HDRC_TXCSR, - MGC_M_TXCSR_TXPKTRDY); - } -#endif + if (!status || dma || usb_pipeisoc(pipe)) { if (dma) - wLength = dma->dwActualLength; + wLength = dma->actual_len; else wLength = qh->segsize; qh->offset += wLength; - if (usb_pipeisoc(nPipe)) { + if (usb_pipeisoc(pipe)) { struct usb_iso_packet_descriptor *d; - d = pUrb->iso_frame_desc + qh->iso_idx; + d = urb->iso_frame_desc + qh->iso_idx; d->actual_length = qh->segsize; - if (++qh->iso_idx >= pUrb->number_of_packets) { - bDone = TRUE; + if (++qh->iso_idx >= urb->number_of_packets) { + done = TRUE; } else if (!dma) { d++; - pBuffer = pUrb->transfer_buffer + d->offset; + buf = urb->transfer_buffer + d->offset; wLength = d->length; } } else if (dma) { - bDone = TRUE; + done = TRUE; } else { /* see if we need to send more data, or ZLP */ if (qh->segsize < qh->maxpacket) - bDone = TRUE; - else if (qh->offset == pUrb->transfer_buffer_length - && !(pUrb-> transfer_flags + done = TRUE; + else if (qh->offset == urb->transfer_buffer_length + && !(urb-> transfer_flags & URB_ZERO_PACKET)) - bDone = TRUE; - if (!bDone) { - pBuffer = pUrb->transfer_buffer + done = TRUE; + if (!done) { + buf = urb->transfer_buffer + qh->offset; - wLength = pUrb->transfer_buffer_length + wLength = urb->transfer_buffer_length - qh->offset; } } @@ -1312,33 +1299,33 @@ void musb_host_tx(struct musb *pThis, u8 bEnd) /* urb->status != -EINPROGRESS means request has been faulted, * so we must abort this transfer after cleanup */ - if (pUrb->status != -EINPROGRESS) { - bDone = TRUE; + if (urb->status != -EINPROGRESS) { + done = TRUE; if (status == 0) - status = pUrb->status; + status = urb->status; } - if (bDone) { + if (done) { /* set status */ - pUrb->status = status; - pUrb->actual_length = qh->offset; - musb_advance_schedule(pThis, pUrb, pEnd, USB_DIR_OUT); + urb->status = status; + urb->actual_length = qh->offset; + musb_advance_schedule(musb, urb, hw_ep, USB_DIR_OUT); - } else if (!(wTxCsrVal & MGC_M_TXCSR_DMAENAB)) { - // WARN_ON(!pBuffer); + } else if (!(tx_csr & MUSB_TXCSR_DMAENAB)) { + // WARN_ON(!buf); - /* REVISIT: some docs say that when pEnd->tx_double_buffered, + /* REVISIT: some docs say that when hw_ep->tx_double_buffered, * (and presumably, fifo is not half-full) we should write TWO * packets before updating TXCSR ... other docs disagree ... */ /* PIO: start next packet in this URB */ wLength = min(qh->maxpacket, (u16) wLength); - musb_write_fifo(pEnd, wLength, pBuffer); + musb_write_fifo(hw_ep, wLength, buf); qh->segsize = wLength; - MGC_SelectEnd(pBase, bEnd); - musb_writew(epio, MGC_O_HDRC_TXCSR, - MGC_M_TXCSR_H_WZC_BITS | MGC_M_TXCSR_TXPKTRDY); + musb_ep_select(mbase, epnum); + musb_writew(epio, MUSB_TXCSR, + MUSB_TXCSR_H_WZC_BITS | MUSB_TXCSR_TXPKTRDY); } else DBG(1, "not complete, but dma enabled?\n"); @@ -1390,62 +1377,62 @@ finish: * Service an RX interrupt for the given IN endpoint; docs cover bulk, iso, * and high-bandwidth IN transfer cases. */ -void musb_host_rx(struct musb *pThis, u8 bEnd) +void musb_host_rx(struct musb *musb, u8 epnum) { - struct urb *pUrb; - struct musb_hw_ep *pEnd = pThis->aLocalEnd + bEnd; - void __iomem *epio = pEnd->regs; - struct musb_qh *qh = pEnd->in_qh; + struct urb *urb; + struct musb_hw_ep *hw_ep = musb->endpoints + epnum; + void __iomem *epio = hw_ep->regs; + struct musb_qh *qh = hw_ep->in_qh; size_t xfer_len; - void __iomem *pBase = pThis->pRegs; - int nPipe; - u16 wRxCsrVal, wVal; - u8 bIsochError = FALSE; - u8 bDone = FALSE; + void __iomem *mbase = musb->mregs; + int pipe; + u16 rx_csr, wVal; + u8 iso_err = FALSE; + u8 done = FALSE; u32 status; struct dma_channel *dma; - MGC_SelectEnd(pBase, bEnd); + musb_ep_select(mbase, epnum); - pUrb = next_urb(qh); - dma = is_dma_capable() ? pEnd->rx_channel : NULL; + urb = next_urb(qh); + dma = is_dma_capable() ? hw_ep->rx_channel : NULL; status = 0; xfer_len = 0; - wVal = wRxCsrVal = musb_readw(epio, MGC_O_HDRC_RXCSR); + wVal = rx_csr = musb_readw(epio, MUSB_RXCSR); - if (unlikely(!pUrb)) { + if (unlikely(!urb)) { /* REVISIT -- THIS SHOULD NEVER HAPPEN ... but, at least * usbtest #11 (unlinks) triggers it regularly, sometimes * with fifo full. (Only with DMA??) */ - DBG(3, "BOGUS RX%d ready, csr %04x, count %d\n", bEnd, wVal, - musb_readw(epio, MGC_O_HDRC_RXCOUNT)); - musb_h_flush_rxfifo(pEnd, MGC_M_RXCSR_CLRDATATOG); + DBG(3, "BOGUS RX%d ready, csr %04x, count %d\n", epnum, wVal, + musb_readw(epio, MUSB_RXCOUNT)); + musb_h_flush_rxfifo(hw_ep, MUSB_RXCSR_CLRDATATOG); return; } - nPipe = pUrb->pipe; + pipe = urb->pipe; DBG(5, "<== hw %d rxcsr %04x, urb actual %d (+dma %zd)\n", - bEnd, wRxCsrVal, pUrb->actual_length, - dma ? dma->dwActualLength : 0); + epnum, rx_csr, urb->actual_length, + dma ? dma->actual_len : 0); /* check for errors, concurrent stall & unlink is not really * handled yet! */ - if (wRxCsrVal & MGC_M_RXCSR_H_RXSTALL) { - DBG(3, "RX end %d STALL\n", bEnd); + if (rx_csr & MUSB_RXCSR_H_RXSTALL) { + DBG(3, "RX end %d STALL\n", epnum); /* stall; record URB status */ status = -EPIPE; - } else if (wRxCsrVal & MGC_M_RXCSR_H_ERROR) { - DBG(3, "end %d RX proto error\n", bEnd); + } else if (rx_csr & MUSB_RXCSR_H_ERROR) { + DBG(3, "end %d RX proto error\n", epnum); status = -EPROTO; - musb_writeb(epio, MGC_O_HDRC_RXINTERVAL, 0); + musb_writeb(epio, MUSB_RXINTERVAL, 0); - } else if (wRxCsrVal & MGC_M_RXCSR_DATAERROR) { + } else if (rx_csr & MUSB_RXCSR_DATAERROR) { if (USB_ENDPOINT_XFER_ISOC != qh->type) { /* NOTE this code path would be a good place to PAUSE a @@ -1455,17 +1442,17 @@ void musb_host_rx(struct musb *pThis, u8 bEnd) * if (bulk && qh->ring.next != &musb->in_bulk), then * we have a candidate... NAKing is *NOT* an error */ - DBG(6, "RX end %d NAK timeout\n", bEnd); - MGC_SelectEnd(pBase, bEnd); - musb_writew(epio, MGC_O_HDRC_RXCSR, - MGC_M_RXCSR_H_WZC_BITS - | MGC_M_RXCSR_H_REQPKT); + DBG(6, "RX end %d NAK timeout\n", epnum); + musb_ep_select(mbase, epnum); + musb_writew(epio, MUSB_RXCSR, + MUSB_RXCSR_H_WZC_BITS + | MUSB_RXCSR_H_REQPKT); goto finish; } else { - DBG(4, "RX end %d ISO data error\n", bEnd); + DBG(4, "RX end %d ISO data error\n", epnum); /* packet error reported later */ - bIsochError = TRUE; + iso_err = TRUE; } } @@ -1473,19 +1460,19 @@ void musb_host_rx(struct musb *pThis, u8 bEnd) if (status) { /* clean up dma and collect transfer count */ if (dma_channel_status(dma) == MGC_DMA_STATUS_BUSY) { - dma->bStatus = MGC_DMA_STATUS_CORE_ABORT; - (void) pThis->pDmaController->channel_abort(dma); - xfer_len = dma->dwActualLength; + dma->status = MGC_DMA_STATUS_CORE_ABORT; + (void) musb->dma_controller->channel_abort(dma); + xfer_len = dma->actual_len; } - musb_h_flush_rxfifo(pEnd, 0); - musb_writeb(epio, MGC_O_HDRC_RXINTERVAL, 0); - bDone = TRUE; + musb_h_flush_rxfifo(hw_ep, 0); + musb_writeb(epio, MUSB_RXINTERVAL, 0); + done = TRUE; goto finish; } if (unlikely(dma_channel_status(dma) == MGC_DMA_STATUS_BUSY)) { /* SHOULD NEVER HAPPEN ... but at least DaVinci has done it */ - ERR("RX%d dma busy, csr %04x\n", bEnd, wRxCsrVal); + ERR("RX%d dma busy, csr %04x\n", epnum, rx_csr); goto finish; } @@ -1497,62 +1484,60 @@ void musb_host_rx(struct musb *pThis, u8 bEnd) /* FIXME this is _way_ too much in-line logic for Mentor DMA */ #ifndef CONFIG_USB_INVENTRA_DMA - if (wRxCsrVal & MGC_M_RXCSR_H_REQPKT) { + if (rx_csr & MUSB_RXCSR_H_REQPKT) { /* REVISIT this happened for a while on some short reads... * the cleanup still needs investigation... looks bad... * and also duplicates dma cleanup code above ... plus, * shouldn't this be the "half full" double buffer case? */ if (dma_channel_status(dma) == MGC_DMA_STATUS_BUSY) { - dma->bStatus = MGC_DMA_STATUS_CORE_ABORT; - (void) pThis->pDmaController->channel_abort(dma); - xfer_len = dma->dwActualLength; - bDone = TRUE; + dma->status = MGC_DMA_STATUS_CORE_ABORT; + (void) musb->dma_controller->channel_abort(dma); + xfer_len = dma->actual_len; + done = TRUE; } - DBG(2, "RXCSR%d %04x, reqpkt, len %zd%s\n", bEnd, wRxCsrVal, + DBG(2, "RXCSR%d %04x, reqpkt, len %zd%s\n", epnum, rx_csr, xfer_len, dma ? ", dma" : ""); - wRxCsrVal &= ~MGC_M_RXCSR_H_REQPKT; + rx_csr &= ~MUSB_RXCSR_H_REQPKT; - MGC_SelectEnd(pBase, bEnd); - musb_writew(epio, MGC_O_HDRC_RXCSR, - MGC_M_RXCSR_H_WZC_BITS | wRxCsrVal); + musb_ep_select(mbase, epnum); + musb_writew(epio, MUSB_RXCSR, + MUSB_RXCSR_H_WZC_BITS | rx_csr); } #endif - if (dma && (wRxCsrVal & MGC_M_RXCSR_DMAENAB)) { - xfer_len = dma->dwActualLength; + if (dma && (rx_csr & MUSB_RXCSR_DMAENAB)) { + xfer_len = dma->actual_len; - wVal &= ~(MGC_M_RXCSR_DMAENAB - | MGC_M_RXCSR_H_AUTOREQ - | MGC_M_RXCSR_AUTOCLEAR - | MGC_M_RXCSR_RXPKTRDY); - musb_writew(pEnd->regs, MGC_O_HDRC_RXCSR, wVal); + wVal &= ~(MUSB_RXCSR_DMAENAB + | MUSB_RXCSR_H_AUTOREQ + | MUSB_RXCSR_AUTOCLEAR + | MUSB_RXCSR_RXPKTRDY); + musb_writew(hw_ep->regs, MUSB_RXCSR, wVal); #ifdef CONFIG_USB_INVENTRA_DMA - pUrb->actual_length += xfer_len; - qh->offset += xfer_len; - - /* bDone if pUrb buffer is full or short packet is recd */ - bDone = (pUrb->actual_length >= pUrb->transfer_buffer_length) - || (dma->dwActualLength & (qh->maxpacket - 1)); + /* done if urb buffer is full or short packet is recd */ + done = ((urb->actual_length + xfer_len) >= + urb->transfer_buffer_length) + || (dma->actual_len & (qh->maxpacket - 1)); /* send IN token for next packet, without AUTOREQ */ - if (!bDone) { - wVal |= MGC_M_RXCSR_H_REQPKT; - musb_writew(epio, MGC_O_HDRC_RXCSR, - MGC_M_RXCSR_H_WZC_BITS | wVal); + if (!done) { + wVal |= MUSB_RXCSR_H_REQPKT; + musb_writew(epio, MUSB_RXCSR, + MUSB_RXCSR_H_WZC_BITS | wVal); } - DBG(4, "ep %d dma %s, rxcsr %04x, rxcount %d\n", bEnd, - bDone ? "off" : "reset", - musb_readw(epio, MGC_O_HDRC_RXCSR), - musb_readw(epio, MGC_O_HDRC_RXCOUNT)); + DBG(4, "ep %d dma %s, rxcsr %04x, rxcount %d\n", epnum, + done ? "off" : "reset", + musb_readw(epio, MUSB_RXCSR), + musb_readw(epio, MUSB_RXCOUNT)); #else - bDone = TRUE; + done = TRUE; #endif - } else if (pUrb->status == -EINPROGRESS) { + } else if (urb->status == -EINPROGRESS) { /* if no errors, be sure a packet is ready for unloading */ - if (unlikely(!(wRxCsrVal & MGC_M_RXCSR_RXPKTRDY))) { + if (unlikely(!(rx_csr & MUSB_RXCSR_RXPKTRDY))) { status = -EPROTO; ERR("Rx interrupt with no errors or packet!\n"); @@ -1560,9 +1545,9 @@ void musb_host_rx(struct musb *pThis, u8 bEnd) // SCRUB (RX) /* do the proper sequence to abort the transfer */ - MGC_SelectEnd(pBase, bEnd); - wVal &= ~MGC_M_RXCSR_H_REQPKT; - musb_writew(epio, MGC_O_HDRC_RXCSR, wVal); + musb_ep_select(mbase, epnum); + wVal &= ~MUSB_RXCSR_H_REQPKT; + musb_writew(epio, MUSB_RXCSR, wVal); goto finish; } @@ -1570,31 +1555,31 @@ void musb_host_rx(struct musb *pThis, u8 bEnd) #ifdef CONFIG_USB_INVENTRA_DMA if (dma) { struct dma_controller *c; - u16 wRxCount; + u16 rx_count; int status; - wRxCount = musb_readw(epio, MGC_O_HDRC_RXCOUNT); + rx_count = musb_readw(epio, MUSB_RXCOUNT); DBG(2, "RX%d count %d, buffer 0x%x len %d/%d\n", - bEnd, wRxCount, - pUrb->transfer_dma - + pUrb->actual_length, + epnum, rx_count, + urb->transfer_dma + + urb->actual_length, qh->offset, - pUrb->transfer_buffer_length); + urb->transfer_buffer_length); - c = pThis->pDmaController; + c = musb->dma_controller; - dma->bDesiredMode = 0; + dma->desired_mode = 0; #ifdef USE_MODE1 /* because of the issue below, mode 1 will * only rarely behave with correct semantics. */ - if ((pUrb->transfer_flags & + if ((urb->transfer_flags & URB_SHORT_NOT_OK) - && (pUrb->transfer_buffer_length - - pUrb->actual_length) + && (urb->transfer_buffer_length - + urb->actual_length) > qh->maxpacket) - dma->bDesiredMode = 1; + dma->desired_mode = 1; #endif /* Disadvantage of using mode 1: @@ -1614,17 +1599,17 @@ void musb_host_rx(struct musb *pThis, u8 bEnd) * wait for an interrupt when the pkt is recd. Well, you won't get any! */ - wVal = musb_readw(epio, MGC_O_HDRC_RXCSR); - wVal &= ~MGC_M_RXCSR_H_REQPKT; + wVal = musb_readw(epio, MUSB_RXCSR); + wVal &= ~MUSB_RXCSR_H_REQPKT; - if (dma->bDesiredMode == 0) - wVal &= ~MGC_M_RXCSR_H_AUTOREQ; + if (dma->desired_mode == 0) + wVal &= ~MUSB_RXCSR_H_AUTOREQ; else - wVal |= MGC_M_RXCSR_H_AUTOREQ; - wVal |= MGC_M_RXCSR_AUTOCLEAR | MGC_M_RXCSR_DMAENAB; + wVal |= MUSB_RXCSR_H_AUTOREQ; + wVal |= MUSB_RXCSR_AUTOCLEAR | MUSB_RXCSR_DMAENAB; - musb_writew(epio, MGC_O_HDRC_RXCSR, - MGC_M_RXCSR_H_WZC_BITS | wVal); + musb_writew(epio, MUSB_RXCSR, + MUSB_RXCSR_H_WZC_BITS | wVal); /* REVISIT if when actual_length != 0, * transfer_buffer_length needs to be @@ -1632,35 +1617,35 @@ void musb_host_rx(struct musb *pThis, u8 bEnd) */ status = c->channel_program( dma, qh->maxpacket, - dma->bDesiredMode, - pUrb->transfer_dma - + pUrb->actual_length, - (dma->bDesiredMode == 0) - ? wRxCount - : pUrb->transfer_buffer_length); + dma->desired_mode, + urb->transfer_dma + + urb->actual_length, + (dma->desired_mode == 0) + ? rx_count + : urb->transfer_buffer_length); if (!status) { c->channel_release(dma); - dma = pEnd->rx_channel = NULL; + dma = hw_ep->rx_channel = NULL; /* REVISIT reset CSR */ } } #endif /* Mentor DMA */ if (!dma) { - bDone = musb_host_packet_rx(pThis, pUrb, - bEnd, bIsochError); - DBG(6, "read %spacket\n", bDone ? "last " : ""); + done = musb_host_packet_rx(musb, urb, + epnum, iso_err); + DBG(6, "read %spacket\n", done ? "last " : ""); } } finish: - pUrb->actual_length += xfer_len; + urb->actual_length += xfer_len; qh->offset += xfer_len; - if (bDone) { - if (pUrb->status == -EINPROGRESS) - pUrb->status = status; - musb_advance_schedule(pThis, pUrb, pEnd, USB_DIR_IN); + if (done) { + if (urb->status == -EINPROGRESS) + urb->status = status; + musb_advance_schedule(musb, urb, hw_ep, USB_DIR_IN); } } @@ -1721,19 +1706,19 @@ static int musb_schedule( wBestDiff = 4096; nBestEnd = -1; - for (nEnd = 1; nEnd < musb->bEndCount; nEnd++) { + for (nEnd = 1; nEnd < musb->nr_endpoints; nEnd++) { int diff; if (musb->periodic[nEnd]) continue; - hw_ep = &musb->aLocalEnd[nEnd]; + hw_ep = &musb->endpoints[nEnd]; if (hw_ep == musb->bulk_ep) continue; if (is_in) - diff = hw_ep->wMaxPacketSizeRx - qh->maxpacket; + diff = hw_ep->max_packet_sz_rx - qh->maxpacket; else - diff = hw_ep->wMaxPacketSizeTx - qh->maxpacket; + diff = hw_ep->max_packet_sz_tx - qh->maxpacket; if (diff > 0 && wBestDiff > diff) { wBestDiff = diff; @@ -1744,7 +1729,7 @@ static int musb_schedule( return -ENOSPC; idle = 1; - hw_ep = musb->aLocalEnd + nBestEnd; + hw_ep = musb->endpoints + nBestEnd; musb->periodic[nBestEnd] = qh; DBG(4, "qh %p periodic slot %d\n", qh, nBestEnd); success: @@ -1848,7 +1833,7 @@ static int musb_urb_enqueue( * transfer scheduling logic to try some other qh, e.g. try * for 2 msec first: * - * interval = (USB_SPEED_HIGH == pUrb->dev->speed) ? 16 : 2; + * interval = (USB_SPEED_HIGH == urb->dev->speed) ? 16 : 2; * * The downside of disabling this is that transfer scheduling * gets VERY unfair for nonperiodic transfers; a misbehaving @@ -1865,7 +1850,7 @@ static int musb_urb_enqueue( qh->intv_reg = interval; /* precompute addressing for external hub/tt ports */ - if (musb->bIsMultipoint) { + if (musb->is_multipoint) { struct usb_device *parent = urb->dev->parent; if (parent != hcd->self.root_hub) { @@ -1883,7 +1868,7 @@ static int musb_urb_enqueue( * until we get real dma queues (with an entry for each urb/buffer), * we only have work to do in the former case. */ - spin_lock_irqsave(&musb->Lock, flags); + spin_lock_irqsave(&musb->lock, flags); if (hep->hcpriv) { /* some concurrent activity submitted another urb to hep... * odd, rare, error prone, but legal. @@ -1900,7 +1885,7 @@ static int musb_urb_enqueue( * musb_start_urb(), but otherwise only konicawc cares ... */ } - spin_unlock_irqrestore(&musb->Lock, flags); + spin_unlock_irqrestore(&musb->lock, flags); done: if (status != 0) @@ -1918,24 +1903,24 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh, int is_in) { struct musb_hw_ep *ep = qh->hw_ep; void __iomem *epio = ep->regs; - unsigned hw_end = ep->bLocalEnd; - void __iomem *regs = ep->musb->pRegs; + unsigned hw_end = ep->epnum; + void __iomem *regs = ep->musb->mregs; u16 csr; int status = 0; - MGC_SelectEnd(regs, hw_end); + musb_ep_select(regs, hw_end); if (is_dma_capable()) { struct dma_channel *dma; dma = is_in ? ep->rx_channel : ep->tx_channel; if (dma) { - status = ep->musb->pDmaController->channel_abort(dma); + status = ep->musb->dma_controller->channel_abort(dma); DBG(status ? 1 : 3, "abort %cX%d DMA for urb %p --> %d\n", - is_in ? 'R' : 'T', ep->bLocalEnd, + is_in ? 'R' : 'T', ep->epnum, urb, status); - urb->actual_length += dma->dwActualLength; + urb->actual_length += dma->actual_len; } } @@ -1949,22 +1934,20 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh, int is_in) * clearing that status is platform-specific... */ } else { -// SCRUB (TX) - csr = musb_readw(epio, MGC_O_HDRC_TXCSR); - if (csr & MGC_M_TXCSR_FIFONOTEMPTY) - csr |= MGC_M_TXCSR_FLUSHFIFO; - csr &= ~( MGC_M_TXCSR_AUTOSET - | MGC_M_TXCSR_DMAENAB - | MGC_M_TXCSR_H_RXSTALL - | MGC_M_TXCSR_H_NAKTIMEOUT - | MGC_M_TXCSR_H_ERROR - | MGC_M_TXCSR_FIFONOTEMPTY + musb_h_tx_flush_fifo(ep); + csr = musb_readw(epio, MUSB_TXCSR); + csr &= ~( MUSB_TXCSR_AUTOSET + | MUSB_TXCSR_DMAENAB + | MUSB_TXCSR_H_RXSTALL + | MUSB_TXCSR_H_NAKTIMEOUT + | MUSB_TXCSR_H_ERROR + | MUSB_TXCSR_TXPKTRDY ); - musb_writew(epio, MGC_O_HDRC_TXCSR, csr); + musb_writew(epio, MUSB_TXCSR, csr); /* REVISIT may need to clear FLUSHFIFO ... */ - musb_writew(epio, MGC_O_HDRC_TXCSR, csr); + musb_writew(epio, MUSB_TXCSR, csr); /* flush cpu writebuffer */ - csr = musb_readw(epio, MGC_O_HDRC_TXCSR); + csr = musb_readw(epio, MUSB_TXCSR); } if (status == 0) musb_advance_schedule(ep->musb, urb, ep, is_in); @@ -1985,7 +1968,7 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) usb_pipeendpoint(urb->pipe), usb_pipein(urb->pipe) ? "in" : "out"); - spin_lock_irqsave(&musb->Lock, flags); + spin_lock_irqsave(&musb->lock, flags); /* make sure the urb is still queued and not completed */ spin_lock(&urb->lock); @@ -2002,6 +1985,14 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) } } spin_unlock(&urb->lock); + + /* already completed */ + if (!qh) { + status = 0; + goto done; + } + + /* still queued but not found on the list */ if (status) goto done; @@ -2048,7 +2039,7 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) } else status = musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN); done: - spin_unlock_irqrestore(&musb->Lock, flags); + spin_unlock_irqrestore(&musb->lock, flags); return status; } @@ -2067,7 +2058,7 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) if (!qh) return; - spin_lock_irqsave(&musb->Lock, flags); + spin_lock_irqsave(&musb->lock, flags); switch (qh->type) { case USB_ENDPOINT_XFER_CONTROL: @@ -2109,14 +2100,14 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) list_for_each_entry_safe_from(urb, tmp, &hep->urb_list, urb_list) musb_giveback(qh, urb, -ESHUTDOWN); - spin_unlock_irqrestore(&musb->Lock, flags); + spin_unlock_irqrestore(&musb->lock, flags); } static int musb_h_get_frame_number(struct usb_hcd *hcd) { struct musb *musb = hcd_to_musb(hcd); - return musb_readw(musb->pRegs, MGC_O_HDRC_FRAME); + return musb_readw(musb->mregs, MUSB_FRAME); } static int musb_h_start(struct usb_hcd *hcd)