diff options
author | Bin Liu <b-liu@ti.com> | 2014-08-12 15:18:43 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2014-09-03 10:15:56 -0400 |
commit | 9267edaf8cd7b0ef2cd7785c677fe792c077b6ab (patch) | |
tree | af2a1a8b232c7e7a3c5ade8aba73c5b96374d0a8 | |
parent | 69e273c0b0a3c337a521d083374c918dc52c666f (diff) |
usb: musb: cppi41: fix not transmitting zero length packet issue
CPPI TX does not transmit ZLP for TX transfers which
- transfer size is multiple of EP packet size,
- and URB_ZERO_PACKET is set in urb->transfer_flags.
The fix is transmitting the ZLP using PIO mode after the CPPI TX is
done.
Validated using the following usbtest write case in MUSB host mode.
# testusb -t1 -c1
Signed-off-by: Bin Liu <b-liu@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r-- | drivers/usb/musb/musb_cppi41.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index 47ae6455d073..3ee133f675ab 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c | |||
@@ -39,6 +39,7 @@ struct cppi41_dma_channel { | |||
39 | u32 transferred; | 39 | u32 transferred; |
40 | u32 packet_sz; | 40 | u32 packet_sz; |
41 | struct list_head tx_check; | 41 | struct list_head tx_check; |
42 | int tx_zlp; | ||
42 | }; | 43 | }; |
43 | 44 | ||
44 | #define MUSB_DMA_NUM_CHANNELS 15 | 45 | #define MUSB_DMA_NUM_CHANNELS 15 |
@@ -122,6 +123,8 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) | |||
122 | { | 123 | { |
123 | struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; | 124 | struct musb_hw_ep *hw_ep = cppi41_channel->hw_ep; |
124 | struct musb *musb = hw_ep->musb; | 125 | struct musb *musb = hw_ep->musb; |
126 | void __iomem *epio = hw_ep->regs; | ||
127 | u16 csr; | ||
125 | 128 | ||
126 | if (!cppi41_channel->prog_len || | 129 | if (!cppi41_channel->prog_len || |
127 | (cppi41_channel->channel.status == MUSB_DMA_STATUS_FREE)) { | 130 | (cppi41_channel->channel.status == MUSB_DMA_STATUS_FREE)) { |
@@ -131,15 +134,24 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel) | |||
131 | cppi41_channel->transferred; | 134 | cppi41_channel->transferred; |
132 | cppi41_channel->channel.status = MUSB_DMA_STATUS_FREE; | 135 | cppi41_channel->channel.status = MUSB_DMA_STATUS_FREE; |
133 | cppi41_channel->channel.rx_packet_done = true; | 136 | cppi41_channel->channel.rx_packet_done = true; |
137 | |||
138 | /* | ||
139 | * transmit ZLP using PIO mode for transfers which size is | ||
140 | * multiple of EP packet size. | ||
141 | */ | ||
142 | if (cppi41_channel->tx_zlp && (cppi41_channel->transferred % | ||
143 | cppi41_channel->packet_sz) == 0) { | ||
144 | musb_ep_select(musb->mregs, hw_ep->epnum); | ||
145 | csr = MUSB_TXCSR_MODE | MUSB_TXCSR_TXPKTRDY; | ||
146 | musb_writew(epio, MUSB_TXCSR, csr); | ||
147 | } | ||
134 | musb_dma_completion(musb, hw_ep->epnum, cppi41_channel->is_tx); | 148 | musb_dma_completion(musb, hw_ep->epnum, cppi41_channel->is_tx); |
135 | } else { | 149 | } else { |
136 | /* next iteration, reload */ | 150 | /* next iteration, reload */ |
137 | struct dma_chan *dc = cppi41_channel->dc; | 151 | struct dma_chan *dc = cppi41_channel->dc; |
138 | struct dma_async_tx_descriptor *dma_desc; | 152 | struct dma_async_tx_descriptor *dma_desc; |
139 | enum dma_transfer_direction direction; | 153 | enum dma_transfer_direction direction; |
140 | u16 csr; | ||
141 | u32 remain_bytes; | 154 | u32 remain_bytes; |
142 | void __iomem *epio = cppi41_channel->hw_ep->regs; | ||
143 | 155 | ||
144 | cppi41_channel->buf_addr += cppi41_channel->packet_sz; | 156 | cppi41_channel->buf_addr += cppi41_channel->packet_sz; |
145 | 157 | ||
@@ -363,6 +375,7 @@ static bool cppi41_configure_channel(struct dma_channel *channel, | |||
363 | cppi41_channel->total_len = len; | 375 | cppi41_channel->total_len = len; |
364 | cppi41_channel->transferred = 0; | 376 | cppi41_channel->transferred = 0; |
365 | cppi41_channel->packet_sz = packet_sz; | 377 | cppi41_channel->packet_sz = packet_sz; |
378 | cppi41_channel->tx_zlp = (cppi41_channel->is_tx && mode) ? 1 : 0; | ||
366 | 379 | ||
367 | /* | 380 | /* |
368 | * Due to AM335x' Advisory 1.0.13 we are not allowed to transfer more | 381 | * Due to AM335x' Advisory 1.0.13 we are not allowed to transfer more |