aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Mack <zonque@gmail.com>2014-05-26 08:52:38 -0400
committerFelipe Balbi <balbi@ti.com>2014-06-30 15:26:24 -0400
commitff3fcac949187d98684aaf3f1c35c7cae7712649 (patch)
treece8353d4fb5b51bec3274ad0ad64c70b5db652ec
parent2ccc6d30a0abf3e1a38f264e279428b846712e0f (diff)
usb: musb: introduce dma_channel.rx_packet_done
The musb/cppi41 glue layer is capable of handling transactions that span over more than one USB packet by reloading the DMA descriptors partially. An urb is considered completed when either its transfer buffer has been filled entirely (actual_length == transfer_buffer_length) or if a packet in the stream has less bytes than the endpoint's wMaxPacketSize. Once one of the above conditions is met, musb_dma_completion() is called from cppi41_trans_done(). However, the final decision whether or not to return the urb to its owner is made by the core and its determination of the variable 'done' in musb_host_rx(). This code has currently no way of knowing what the size of the last packet was, and whether or not to give back the urb due to a short read. Fix this by introducing a new boolean flag in 'struct dma_channel', and set it from musb_cppi41.c. If set, it will make the core do what the DMA layer decided and complete the urb. Signed-off-by: Daniel Mack <zonque@gmail.com> Acked-by: George Cherian <george.cherian@ti.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r--drivers/usb/musb/musb_cppi41.c2
-rw-r--r--drivers/usb/musb/musb_dma.h1
-rw-r--r--drivers/usb/musb/musb_host.c3
3 files changed, 5 insertions, 1 deletions
diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c
index 7b8bbf53127e..4187ef1fab29 100644
--- a/drivers/usb/musb/musb_cppi41.c
+++ b/drivers/usb/musb/musb_cppi41.c
@@ -139,6 +139,7 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel)
139 cppi41_channel->channel.actual_len = 139 cppi41_channel->channel.actual_len =
140 cppi41_channel->transferred; 140 cppi41_channel->transferred;
141 cppi41_channel->channel.status = MUSB_DMA_STATUS_FREE; 141 cppi41_channel->channel.status = MUSB_DMA_STATUS_FREE;
142 cppi41_channel->channel.rx_packet_done = true;
142 musb_dma_completion(musb, hw_ep->epnum, cppi41_channel->is_tx); 143 musb_dma_completion(musb, hw_ep->epnum, cppi41_channel->is_tx);
143 } else { 144 } else {
144 /* next iteration, reload */ 145 /* next iteration, reload */
@@ -450,6 +451,7 @@ static bool cppi41_configure_channel(struct dma_channel *channel,
450 dma_desc->callback = cppi41_dma_callback; 451 dma_desc->callback = cppi41_dma_callback;
451 dma_desc->callback_param = channel; 452 dma_desc->callback_param = channel;
452 cppi41_channel->cookie = dma_desc->tx_submit(dma_desc); 453 cppi41_channel->cookie = dma_desc->tx_submit(dma_desc);
454 cppi41_channel->channel.rx_packet_done = false;
453 455
454 save_rx_toggle(cppi41_channel); 456 save_rx_toggle(cppi41_channel);
455 dma_async_issue_pending(dc); 457 dma_async_issue_pending(dc);
diff --git a/drivers/usb/musb/musb_dma.h b/drivers/usb/musb/musb_dma.h
index 1345a4ff041a..1d44faa86252 100644
--- a/drivers/usb/musb/musb_dma.h
+++ b/drivers/usb/musb/musb_dma.h
@@ -129,6 +129,7 @@ struct dma_channel {
129 size_t actual_len; 129 size_t actual_len;
130 enum dma_channel_status status; 130 enum dma_channel_status status;
131 bool desired_mode; 131 bool desired_mode;
132 bool rx_packet_done;
132}; 133};
133 134
134/* 135/*
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 3381fa56db29..88435cd7fe3d 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -1737,7 +1737,8 @@ void musb_host_rx(struct musb *musb, u8 epnum)
1737 /* done if urb buffer is full or short packet is recd */ 1737 /* done if urb buffer is full or short packet is recd */
1738 done = (urb->actual_length + xfer_len >= 1738 done = (urb->actual_length + xfer_len >=
1739 urb->transfer_buffer_length 1739 urb->transfer_buffer_length
1740 || dma->actual_len < qh->maxpacket); 1740 || dma->actual_len < qh->maxpacket
1741 || dma->rx_packet_done);
1741 } 1742 }
1742 1743
1743 /* send IN token for next packet, without AUTOREQ */ 1744 /* send IN token for next packet, without AUTOREQ */