Hello.
Heikki Krogerus wrote:
I only have a few comments at this point:
Signed-off-by: Heikki Krogerus <ext-heikki.krogerus@xxxxxxxxx>
---
drivers/usb/musb/musb_host.c | 69 ++++++++++++++++++++++++++++++++----------
drivers/usb/musb/musb_host.h | 2 +
2 files changed, 55 insertions(+), 16 deletions(-)
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index d72969f..8557e22 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
[...]
@@ -1318,27 +1326,26 @@ void musb_host_rx(struct musb *musb, u8 epnum)
bool iso_err = false;
bool done = false;
u32 status;
+ struct dma_channel *dma = hw_ep->rx_channel;
musb_ep_select(mbase, epnum);
- urb = qtd->urb;
status = 0;
xfer_len = 0;
rx_csr = musb_readw(epio, MUSB_RXCSR);
val = rx_csr;
- if (unlikely(!urb)) {
- /* REVISIT -- THIS SHOULD NEVER HAPPEN ... but, at least
- * usbtest #11 (unlinks) triggers it regularly, sometimes
- * with fifo full. (Only with DMA??)
- */
Why are you removing this comment? Have you fixed what was described?
+ if (list_empty(&qh->qtd_list)) {
+ if (musb_readw(epio, MUSB_RXCOUNT))
+ qh->rx_pending = true;
DBG(3, "BOGUS RX%d ready, csr %04x, count %d\n", epnum, val,
musb_readw(epio, MUSB_RXCOUNT));
- musb_h_flush_rxfifo(hw_ep, MUSB_RXCSR_CLRDATATOG);
return;
}
+ qtd = musb_qh_get_qtd(qh);
+ urb = qtd->urb;
pipe = urb->pipe;
DBG(5, "<== hw %d rxcsr %04x, urb actual %d\n",
@@ -1395,20 +1402,29 @@ 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;
}
- /* 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.
- */
-
- /* FIXME this is _way_ too much in-line logic for Mentor DMA */
This FIXME should have been removed when removing the existing DMA
support, no?
+ if (dma && (rx_csr & MUSB_RXCSR_DMAENAB)) {
+ musb->dma_controller->channel_abort(dma);
- if (urb->status == -EINPROGRESS) {
+ xfer_len = dma->actual_len;
+ done = (urb->actual_length + xfer_len >=
+ urb->transfer_buffer_length);
+ stop_dma(musb, qtd);
+ /* REVISIT the remaining data is left in fifo and musb is
+ * allowed generate the endpoint interrupt for it.
Only "allowed to generate".
+ */
+ } else if (urb->status == -EINPROGRESS) {
/* if no errors, be sure a packet is ready for unloading */
if (unlikely(!(rx_csr & MUSB_RXCSR_RXPKTRDY))) {
status = -EPROTO;
@@ -1425,6 +1441,10 @@ void musb_host_rx(struct musb *musb, u8 epnum)
}
/* we are expecting IN packets */
+ if (is_dma_capable()) {
+ if (start_dma(musb, qtd) == 0)
+ goto finish;
+ }
Why not simply?
if (is_dma_capable() && start_dma(musb, qtd) == 0)
goto finish;
WBR, Sergei
--
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