RE: [RFC/PATCH 1/5] usb: musb: host: remove dma support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Balbi,
        I am working on enhancing the DMA implementation in the MUSB module.  This is expected to extend the queuing functionality into the DMA engine implementation.  Currently the urb queuing is limited to MUSB code.

        DMA engines on DMxxx devices support this capability and this would help in significantly enhancing performance on these and other platforms that have such a capability.

        I would circulate a RFC on this after I come back from my vacation.  I hope we can review it early.

Regards
swami

-----Original Message-----
From: linux-usb-owner@xxxxxxxxxxxxxxx [mailto:linux-usb-owner@xxxxxxxxxxxxxxx] On Behalf Of Heikki Krogerus
Sent: Friday, December 18, 2009 6:01 PM
To: linux-usb@xxxxxxxxxxxxxxx
Cc: felipe.balbi@xxxxxxxxx; dbrownell@xxxxxxxxxxxxxxxxxxxxx; ext-heikki.krogerus@xxxxxxxxx
Subject: [RFC/PATCH 1/5] usb: musb: host: remove dma support

From: Felipe Balbi <felipe.balbi@xxxxxxxxx>

we will rewrite everything from scratch. The old code was
so buggy anyways.

Signed-off-by: Felipe Balbi <felipe.balbi@xxxxxxxxx>
---
 drivers/usb/musb/musb_host.c |  520 +----------------------------------------
 1 files changed, 13 insertions(+), 507 deletions(-)

diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 74c4c36..e2d1eb2 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -169,18 +169,6 @@ static inline void musb_h_tx_start(struct musb_hw_ep *ep)

 }

-static inline void musb_h_tx_dma_start(struct musb_hw_ep *ep)
-{
-       u16     txcsr;
-
-       /* NOTE: no locks here; caller should lock and select EP */
-       txcsr = musb_readw(ep->regs, MUSB_TXCSR);
-       txcsr |= MUSB_TXCSR_DMAENAB | MUSB_TXCSR_H_WZC_BITS;
-       if (is_cppi_enabled())
-               txcsr |= MUSB_TXCSR_DMAMODE;
-       musb_writew(ep->regs, MUSB_TXCSR, txcsr);
-}
-
 static void musb_ep_set_qh(struct musb_hw_ep *ep, int is_in, struct musb_qh *qh)
 {
        if (is_in != 0 || ep->is_shared_fifo)
@@ -285,13 +273,9 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh)
                break;
        default:
 start:
-               DBG(4, "Start TX%d %s\n", epnum,
-                       hw_ep->tx_channel ? "dma" : "pio");
+               DBG(4, "Start TX%d %s\n", epnum, "pio");

-               if (!hw_ep->tx_channel)
-                       musb_h_tx_start(hw_ep);
-               else if (is_cppi_enabled() || tusb_dma_omap())
-                       musb_h_tx_dma_start(hw_ep);
+               musb_h_tx_start(hw_ep);
        }
 }

@@ -611,62 +595,6 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep)
        ep->rx_reinit = 0;
 }

-static bool musb_tx_dma_program(struct dma_controller *dma,
-               struct musb_hw_ep *hw_ep, struct musb_qh *qh,
-               struct urb *urb, u32 offset, u32 length)
-{
-       struct dma_channel      *channel = hw_ep->tx_channel;
-       void __iomem            *epio = hw_ep->regs;
-       u16                     pkt_size = qh->maxpacket;
-       u16                     csr;
-       u8                      mode;
-
-#ifdef CONFIG_USB_INVENTRA_DMA
-       if (length > channel->max_len)
-               length = channel->max_len;
-
-       csr = musb_readw(epio, MUSB_TXCSR);
-       if (length > pkt_size) {
-               mode = 1;
-               csr |= MUSB_TXCSR_DMAMODE | MUSB_TXCSR_DMAENAB;
-               /* autoset shouldn't be set in high bandwidth */
-               if (qh->hb_mult == 1)
-                       csr |= MUSB_TXCSR_AUTOSET;
-       } else {
-               mode = 0;
-               csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAMODE);
-               csr |= MUSB_TXCSR_DMAENAB; /* against programmer's guide */
-       }
-       channel->desired_mode = mode;
-       musb_writew(epio, MUSB_TXCSR, csr);
-#else
-       if (!is_cppi_enabled() && !tusb_dma_omap())
-               return false;
-
-       channel->actual_len = 0;
-
-       /*
-        * TX uses "RNDIS" mode automatically but needs help
-        * to identify the zero-length-final-packet case.
-        */
-       mode = (urb->transfer_flags & URB_ZERO_PACKET) ? 1 : 0;
-#endif
-
-       qh->segsize = length;
-
-       if (!dma->channel_program(channel, pkt_size, mode,
-                       urb->transfer_dma + offset, length)) {
-               dma->channel_release(channel);
-               hw_ep->tx_channel = NULL;
-
-               csr = musb_readw(epio, MUSB_TXCSR);
-               csr &= ~(MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAENAB);
-               musb_writew(epio, MUSB_TXCSR, csr | MUSB_TXCSR_H_WZC_BITS);
-               return false;
-       }
-       return true;
-}
-
 /*
  * Program an HDRC endpoint as per the given URB
  * Context: irqs blocked, controller lock held
@@ -675,9 +603,6 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
                        struct urb *urb, int is_out,
                        u8 *buf, u32 offset, u32 len)
 {
-       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;
@@ -694,21 +619,6 @@ static void musb_ep_program(struct musb *musb, u8 epnum,

        musb_ep_select(mbase, epnum);

-       /* candidate for DMA? */
-       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)
-                               hw_ep->tx_channel = dma_channel;
-                       else
-                               hw_ep->rx_channel = dma_channel;
-               }
-       } else
-               dma_channel = NULL;
-
        /* make sure we clear DMAEnab, autoSet bits from previous run */

        /* OUT/transmit/EP0 or IN/receive? */
@@ -764,7 +674,7 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
                        musb_write_txfunaddr(mbase, epnum, qh->addr_reg);
                        musb_write_txhubaddr(mbase, epnum, qh->h_addr_reg);
                        musb_write_txhubport(mbase, epnum, qh->h_port_reg);
-/* FIXME if !epnum, do the same for RX ... */
+                       /* FIXME if !epnum, do the same for RX ... */
                } else
                        musb_writeb(mbase, MUSB_FADDR, qh->addr_reg);

@@ -793,10 +703,6 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
                else
                        load_count = min((u32) packet_sz, len);

-               if (dma_channel && musb_tx_dma_program(dma_controller,
-                                       hw_ep, qh, urb, offset, len))
-                       load_count = 0;
-
                if (load_count) {
                        /* PIO to load FIFO */
                        qh->segsize = load_count;
@@ -835,38 +741,6 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
                        csr &= MUSB_RXCSR_DISNYET;
                }

-               /* kick things off */
-
-               if ((is_cppi_enabled() || tusb_dma_omap()) && dma_channel) {
-                       /* candidate for DMA */
-                       if (dma_channel) {
-                               dma_channel->actual_len = 0L;
-                               qh->segsize = len;
-
-                               /* AUTOREQ is in a DMA register */
-                               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.
-                                */
-                               dma_ok = dma_controller->channel_program(
-                                               dma_channel, packet_sz,
-                                               !(urb->transfer_flags
-                                                       & URB_SHORT_NOT_OK),
-                                               urb->transfer_dma + offset,
-                                               qh->segsize);
-                               if (!dma_ok) {
-                                       dma_controller->channel_release(
-                                                       dma_channel);
-                                       hw_ep->rx_channel = NULL;
-                                       dma_channel = NULL;
-                               } else
-                                       csr |= MUSB_RXCSR_DMAENAB;
-                       }
-               }
-
                csr |= MUSB_RXCSR_H_REQPKT;
                DBG(7, "RXCSR%d := %04x\n", epnum, csr);
                musb_writew(hw_ep->regs, MUSB_RXCSR, csr);
@@ -1076,22 +950,6 @@ done:
 }


-#ifdef CONFIG_USB_INVENTRA_DMA
-
-/* Host side TX (OUT) using Mentor DMA works as follows:
-       submit_urb ->
-               - if queue was empty, Program Endpoint
-               - ... which starts DMA to fifo in mode 1 or 0
-
-       DMA Isr (transfer complete) -> TxAvail()
-               - Stop DMA (~DmaEnab)   (<--- Alert ... currently happens
-                                       only in musb_cleanup_urb)
-               - TxPktRdy has to be set in mode 0 or for
-                       short packets in mode 1.
-*/
-
-#endif
-
 /* Service a Tx-Available or dma completion irq for the endpoint */
 void musb_host_tx(struct musb *musb, u8 epnum)
 {
@@ -1106,7 +964,6 @@ void musb_host_tx(struct musb *musb, u8 epnum)
        struct urb              *urb = next_urb(qh);
        u32                     status = 0;
        void __iomem            *mbase = musb->mregs;
-       struct dma_channel      *dma;

        musb_ep_select(mbase, epnum);
        tx_csr = musb_readw(epio, MUSB_TXCSR);
@@ -1118,9 +975,7 @@ void musb_host_tx(struct musb *musb, u8 epnum)
        }

        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" : "");
+       DBG(4, "OUT/TX%d end, csr %04x\n", epnum, tx_csr);

        /* check for errors */
        if (tx_csr & MUSB_TXCSR_H_RXSTALL) {
@@ -1155,11 +1010,6 @@ void musb_host_tx(struct musb *musb, u8 epnum)
        }

        if (status) {
-               if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
-                       dma->status = MUSB_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.
                 */
@@ -1180,78 +1030,8 @@ void musb_host_tx(struct musb *musb, u8 epnum)
                done = true;
        }

-       /* second cppi case */
-       if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
-               DBG(4, "extra TX%d ready, csr %04x\n", epnum, tx_csr);
-               return;
-       }
-
-       if (is_dma_capable() && dma && !status) {
-               /*
-                * DMA has completed.  But if we're using DMA mode 1 (multi
-                * packet DMA), we need a terminal TXPKTRDY interrupt before
-                * we can consider this transfer completed, lest we trash
-                * its last packet when writing the next URB's data.  So we
-                * switch back to mode 0 to get that interrupt; we'll come
-                * back here once it happens.
-                */
-               if (tx_csr & MUSB_TXCSR_DMAMODE) {
-                       /*
-                        * We shouldn't clear DMAMODE with DMAENAB set; so
-                        * clear them in a safe order.  That should be OK
-                        * once TXPKTRDY has been set (and I've never seen
-                        * it being 0 at this moment -- DMA interrupt latency
-                        * is significant) but if it hasn't been then we have
-                        * no choice but to stop being polite and ignore the
-                        * programmer's guide... :-)
-                        *
-                        * Note that we must write TXCSR with TXPKTRDY cleared
-                        * in order not to re-trigger the packet send (this bit
-                        * can't be cleared by CPU), and there's another caveat:
-                        * TXPKTRDY may be set shortly and then cleared in the
-                        * double-buffered FIFO mode, so we do an extra TXCSR
-                        * read for debouncing...
-                        */
-                       tx_csr &= musb_readw(epio, MUSB_TXCSR);
-                       if (tx_csr & MUSB_TXCSR_TXPKTRDY) {
-                               tx_csr &= ~(MUSB_TXCSR_DMAENAB |
-                                           MUSB_TXCSR_TXPKTRDY);
-                               musb_writew(epio, MUSB_TXCSR,
-                                           tx_csr | MUSB_TXCSR_H_WZC_BITS);
-                       }
-                       tx_csr &= ~(MUSB_TXCSR_DMAMODE |
-                                   MUSB_TXCSR_TXPKTRDY);
-                       musb_writew(epio, MUSB_TXCSR,
-                                   tx_csr | MUSB_TXCSR_H_WZC_BITS);
-
-                       /*
-                        * There is no guarantee that we'll get an interrupt
-                        * after clearing DMAMODE as we might have done this
-                        * too late (after TXPKTRDY was cleared by controller).
-                        * Re-read TXCSR as we have spoiled its previous value.
-                        */
-                       tx_csr = musb_readw(epio, MUSB_TXCSR);
-               }
-
-               /*
-                * We may get here from a DMA completion or TXPKTRDY interrupt.
-                * In any case, we must check the FIFO status here and bail out
-                * only if the FIFO still has data -- that should prevent the
-                * "missed" TXPKTRDY interrupts and deal with double-buffered
-                * FIFO mode too...
-                */
-               if (tx_csr & (MUSB_TXCSR_FIFONOTEMPTY | MUSB_TXCSR_TXPKTRDY)) {
-                       DBG(2, "DMA complete but packet still in FIFO, "
-                           "CSR %04x\n", tx_csr);
-                       return;
-               }
-       }
-
-       if (!status || dma || usb_pipeisoc(pipe)) {
-               if (dma)
-                       length = dma->actual_len;
-               else
-                       length = qh->segsize;
+       if (!status || usb_pipeisoc(pipe)) {
+               length = qh->segsize;
                qh->offset += length;

                if (usb_pipeisoc(pipe)) {
@@ -1267,8 +1047,6 @@ void musb_host_tx(struct musb *musb, u8 epnum)
                                offset = d->offset;
                                length = d->length;
                        }
-               } else if (dma) {
-                       done = true;
                } else {
                        /* see if we need to send more data, or ZLP */
                        if (qh->segsize < qh->maxpacket)
@@ -1299,13 +1077,6 @@ void musb_host_tx(struct musb *musb, u8 epnum)
                urb->actual_length = qh->offset;
                musb_advance_schedule(musb, urb, hw_ep, USB_DIR_OUT);
                return;
-       } else  if (usb_pipeisoc(pipe) && dma) {
-               if (musb_tx_dma_program(musb->dma_controller, hw_ep, qh, urb,
-                               offset, length)) {
-                       if (is_cppi_enabled() || tusb_dma_omap())
-                               musb_h_tx_dma_start(hw_ep);
-                       return;
-               }
        } else  if (tx_csr & MUSB_TXCSR_DMAENAB) {
                DBG(1, "not complete, but DMA enabled?\n");
                return;
@@ -1329,51 +1100,11 @@ void musb_host_tx(struct musb *musb, u8 epnum)
 }


-#ifdef CONFIG_USB_INVENTRA_DMA
-
-/* Host side RX (IN) using Mentor DMA works as follows:
-       submit_urb ->
-               - if queue was empty, ProgramEndpoint
-               - first IN token is sent out (by setting ReqPkt)
-       LinuxIsr -> RxReady()
-       /\      => first packet is received
-       |       - Set in mode 0 (DmaEnab, ~ReqPkt)
-       |               -> DMA Isr (transfer complete) -> RxReady()
-       |                   - Ack receive (~RxPktRdy), turn off DMA (~DmaEnab)
-       |                   - if urb not complete, send next IN token (ReqPkt)
-       |                          |            else complete urb.
-       |                          |
-       ---------------------------
- *
- * Nuances of mode 1:
- *     For short packets, no ack (+RxPktRdy) is sent automatically
- *     (even if AutoClear is ON)
- *     For full packets, ack (~RxPktRdy) and next IN token (+ReqPkt) is sent
- *     automatically => major problem, as collecting the next packet becomes
- *     difficult. Hence mode 1 is not used.
- *
- * REVISIT
- *     All we care about at this driver level is that
- *       (a) all URBs terminate with REQPKT cleared and fifo(s) empty;
- *       (b) termination conditions are: short RX, or buffer full;
- *       (c) fault modes include
- *           - iff URB_SHORT_NOT_OK, short RX status is -EREMOTEIO.
- *             (and that endpoint's dma queue stops immediately)
- *           - overflow (full, PLUS more bytes in the terminal packet)
- *
- *     So for example, usb-storage sets URB_SHORT_NOT_OK, and would
- *     thus be a great candidate for using mode 1 ... for all but the
- *     last packet of one URB's transfer.
- */
-
-#endif
-
 /* Schedule next QH from musb->in_bulk and move the current qh to
  * the end; avoids starvation for other endpoints.
  */
 static void musb_bulk_rx_nak_timeout(struct musb *musb, struct musb_hw_ep *ep)
 {
-       struct dma_channel      *dma;
        struct urb              *urb;
        void __iomem            *mbase = musb->mregs;
        void __iomem            *epio = ep->regs;
@@ -1381,7 +1112,6 @@ static void musb_bulk_rx_nak_timeout(struct musb *musb, struct musb_hw_ep *ep)
        u16                     rx_csr;

        musb_ep_select(mbase, ep->epnum);
-       dma = is_dma_capable() ? ep->rx_channel : NULL;

        /* clear nak timeout bit */
        rx_csr = musb_readw(epio, MUSB_RXCSR);
@@ -1392,12 +1122,6 @@ static void musb_bulk_rx_nak_timeout(struct musb *musb, struct musb_hw_ep *ep)
        cur_qh = first_qh(&musb->in_bulk);
        if (cur_qh) {
                urb = next_urb(cur_qh);
-               if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
-                       dma->status = MUSB_DMA_STATUS_CORE_ABORT;
-                       musb->dma_controller->channel_abort(dma);
-                       urb->actual_length += dma->actual_len;
-                       dma->actual_len = 0L;
-               }
                musb_save_toggle(cur_qh, 1, urb);

                /* move cur_qh to end of queue */
@@ -1429,12 +1153,10 @@ void musb_host_rx(struct musb *musb, u8 epnum)
        bool                    iso_err = false;
        bool                    done = false;
        u32                     status;
-       struct dma_channel      *dma;

        musb_ep_select(mbase, epnum);

        urb = next_urb(qh);
-       dma = is_dma_capable() ? hw_ep->rx_channel : NULL;
        status = 0;
        xfer_len = 0;

@@ -1454,9 +1176,8 @@ void musb_host_rx(struct musb *musb, u8 epnum)

        pipe = urb->pipe;

-       DBG(5, "<== hw %d rxcsr %04x, urb actual %d (+dma %zu)\n",
-               epnum, rx_csr, urb->actual_length,
-               dma ? dma->actual_len : 0);
+       DBG(5, "<== hw %d rxcsr %04x, urb actual %d\n",
+               epnum, rx_csr, urb->actual_length);

        /* check for errors, concurrent stall & unlink is not really
         * handled yet! */
@@ -1510,24 +1231,12 @@ void musb_host_rx(struct musb *musb, u8 epnum)

        /* faults abort the transfer */
        if (status) {
-               /* clean up dma and collect transfer count */
-               if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
-                       dma->status = MUSB_DMA_STATUS_CORE_ABORT;
-                       (void) musb->dma_controller->channel_abort(dma);
-                       xfer_len = dma->actual_len;
-               }
                musb_h_flush_rxfifo(hw_ep, MUSB_RXCSR_CLRDATATOG);
                musb_writeb(epio, MUSB_RXINTERVAL, 0);
                done = true;
                goto finish;
        }

-       if (unlikely(dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY)) {
-               /* SHOULD NEVER HAPPEN ... but at least DaVinci has done it */
-               ERR("RX%d dma busy, csr %04x\n", epnum, rx_csr);
-               goto finish;
-       }
-
        /* thorough shutdown for now ... given more precise fault handling
         * and better queueing support, we might keep a DMA pipeline going
         * while processing this irq for earlier completions.
@@ -1535,78 +1244,7 @@ void musb_host_rx(struct musb *musb, u8 epnum)

        /* FIXME this is _way_ too much in-line logic for Mentor DMA */

-#ifndef CONFIG_USB_INVENTRA_DMA
-       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) == MUSB_DMA_STATUS_BUSY) {
-                       dma->status = MUSB_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 %zu%s\n", epnum, rx_csr,
-                               xfer_len, dma ? ", dma" : "");
-               rx_csr &= ~MUSB_RXCSR_H_REQPKT;
-
-               musb_ep_select(mbase, epnum);
-               musb_writew(epio, MUSB_RXCSR,
-                               MUSB_RXCSR_H_WZC_BITS | rx_csr);
-       }
-#endif
-       if (dma && (rx_csr & MUSB_RXCSR_DMAENAB)) {
-               xfer_len = dma->actual_len;
-
-               val &= ~(MUSB_RXCSR_DMAENAB
-                       | MUSB_RXCSR_H_AUTOREQ
-                       | MUSB_RXCSR_AUTOCLEAR
-                       | MUSB_RXCSR_RXPKTRDY);
-               musb_writew(hw_ep->regs, MUSB_RXCSR, val);
-
-#ifdef CONFIG_USB_INVENTRA_DMA
-               if (usb_pipeisoc(pipe)) {
-                       struct usb_iso_packet_descriptor *d;
-
-                       d = urb->iso_frame_desc + qh->iso_idx;
-                       d->actual_length = xfer_len;
-
-                       /* even if there was an error, we did the dma
-                        * for iso_frame_desc->length
-                        */
-                       if (d->status != EILSEQ && d->status != -EOVERFLOW)
-                               d->status = 0;
-
-                       if (++qh->iso_idx >= urb->number_of_packets)
-                               done = true;
-                       else
-                               done = false;
-
-               } else  {
-               /* 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);
-               }
-
-               /* send IN token for next packet, without AUTOREQ */
-               if (!done) {
-                       val |= MUSB_RXCSR_H_REQPKT;
-                       musb_writew(epio, MUSB_RXCSR,
-                               MUSB_RXCSR_H_WZC_BITS | val);
-               }
-
-               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
-               done = true;
-#endif
-       } else if (urb->status == -EINPROGRESS) {
+       if (urb->status == -EINPROGRESS) {
                /* if no errors, be sure a packet is ready for unloading */
                if (unlikely(!(rx_csr & MUSB_RXCSR_RXPKTRDY))) {
                        status = -EPROTO;
@@ -1614,7 +1252,7 @@ void musb_host_rx(struct musb *musb, u8 epnum)

                        /* FIXME this is another "SHOULD NEVER HAPPEN" */

-/* SCRUB (RX) */
+                       /* SCRUB (RX) */
                        /* do the proper sequence to abort the transfer */
                        musb_ep_select(mbase, epnum);
                        val &= ~MUSB_RXCSR_H_REQPKT;
@@ -1623,127 +1261,9 @@ void musb_host_rx(struct musb *musb, u8 epnum)
                }

                /* we are expecting IN packets */
-#ifdef CONFIG_USB_INVENTRA_DMA
-               if (dma) {
-                       struct dma_controller   *c;
-                       u16                     rx_count;
-                       int                     ret, length;
-                       dma_addr_t              buf;
-
-                       rx_count = musb_readw(epio, MUSB_RXCOUNT);
-
-                       DBG(2, "RX%d count %d, buffer 0x%x len %d/%d\n",
-                                       epnum, rx_count,
-                                       urb->transfer_dma
-                                               + urb->actual_length,
-                                       qh->offset,
-                                       urb->transfer_buffer_length);
-
-                       c = musb->dma_controller;
-
-                       if (usb_pipeisoc(pipe)) {
-                               int d_status = 0;
-                               struct usb_iso_packet_descriptor *d;
-
-                               d = urb->iso_frame_desc + qh->iso_idx;
-
-                               if (iso_err) {
-                                       d_status = -EILSEQ;
-                                       urb->error_count++;
-                               }
-                               if (rx_count > d->length) {
-                                       if (d_status == 0) {
-                                               d_status = -EOVERFLOW;
-                                               urb->error_count++;
-                                       }
-                                       DBG(2, "** OVERFLOW %d into %d\n",\
-                                           rx_count, d->length);
-
-                                       length = d->length;
-                               } else
-                                       length = rx_count;
-                               d->status = d_status;
-                               buf = urb->transfer_dma + d->offset;
-                       } else {
-                               length = rx_count;
-                               buf = urb->transfer_dma +
-                                               urb->actual_length;
-                       }
-
-                       dma->desired_mode = 0;
-#ifdef USE_MODE1
-                       /* because of the issue below, mode 1 will
-                        * only rarely behave with correct semantics.
-                        */
-                       if ((urb->transfer_flags &
-                                               URB_SHORT_NOT_OK)
-                               && (urb->transfer_buffer_length -
-                                               urb->actual_length)
-                                       > qh->maxpacket)
-                               dma->desired_mode = 1;
-                       if (rx_count < hw_ep->max_packet_sz_rx) {
-                               length = rx_count;
-                               dma->bDesiredMode = 0;
-                       } else {
-                               length = urb->transfer_buffer_length;
-                       }
-#endif
-
-/* Disadvantage of using mode 1:
- *     It's basically usable only for mass storage class; essentially all
- *     other protocols also terminate transfers on short packets.
- *
- * Details:
- *     An extra IN token is sent at the end of the transfer (due to AUTOREQ)
- *     If you try to use mode 1 for (transfer_buffer_length - 512), and try
- *     to use the extra IN token to grab the last packet using mode 0, then
- *     the problem is that you cannot be sure when the device will send the
- *     last packet and RxPktRdy set. Sometimes the packet is recd too soon
- *     such that it gets lost when RxCSR is re-set at the end of the mode 1
- *     transfer, while sometimes it is recd just a little late so that if you
- *     try to configure for mode 0 soon after the mode 1 transfer is
- *     completed, you will find rxcount 0. Okay, so you might think why not
- *     wait for an interrupt when the pkt is recd. Well, you won't get any!
- */
-
-                       val = musb_readw(epio, MUSB_RXCSR);
-                       val &= ~MUSB_RXCSR_H_REQPKT;
-
-                       if (dma->desired_mode == 0)
-                               val &= ~MUSB_RXCSR_H_AUTOREQ;
-                       else
-                               val |= MUSB_RXCSR_H_AUTOREQ;
-                       val |= MUSB_RXCSR_DMAENAB;
-
-                       /* autoclear shouldn't be set in high bandwidth */
-                       if (qh->hb_mult == 1)
-                               val |= MUSB_RXCSR_AUTOCLEAR;
-
-                       musb_writew(epio, MUSB_RXCSR,
-                               MUSB_RXCSR_H_WZC_BITS | val);
-
-                       /* REVISIT if when actual_length != 0,
-                        * transfer_buffer_length needs to be
-                        * adjusted first...
-                        */
-                       ret = c->channel_program(
-                               dma, qh->maxpacket,
-                               dma->desired_mode, buf, length);
-
-                       if (!ret) {
-                               c->channel_release(dma);
-                               hw_ep->rx_channel = NULL;
-                               dma = NULL;
-                               /* REVISIT reset CSR */
-                       }
-               }
-#endif /* Mentor DMA */
-
-               if (!dma) {
-                       done = musb_host_packet_rx(musb, urb,
-                                       epnum, iso_err);
-                       DBG(6, "read %spacket\n", done ? "last " : "");
-               }
+               done = musb_host_packet_rx(musb, urb,
+                               epnum, iso_err);
+               DBG(6, "read %spacket\n", done ? "last " : "");
        }

 finish:
@@ -2053,20 +1573,6 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh)

        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->dma_controller->channel_abort(dma);
-                       DBG(status ? 1 : 3,
-                               "abort %cX%d DMA for urb %p --> %d\n",
-                               is_in ? 'R' : 'T', ep->epnum,
-                               urb, status);
-                       urb->actual_length += dma->actual_len;
-               }
-       }
-
        /* turn off DMA requests, discard state, stop polling ... */
        if (is_in) {
                /* giveback saves bulk toggle */
--
1.5.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux