mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-15 15:04:27 +08:00
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>
This commit is contained in:
parent
2ccc6d30a0
commit
ff3fcac949
@ -139,6 +139,7 @@ static void cppi41_trans_done(struct cppi41_dma_channel *cppi41_channel)
|
||||
cppi41_channel->channel.actual_len =
|
||||
cppi41_channel->transferred;
|
||||
cppi41_channel->channel.status = MUSB_DMA_STATUS_FREE;
|
||||
cppi41_channel->channel.rx_packet_done = true;
|
||||
musb_dma_completion(musb, hw_ep->epnum, cppi41_channel->is_tx);
|
||||
} else {
|
||||
/* next iteration, reload */
|
||||
@ -450,6 +451,7 @@ static bool cppi41_configure_channel(struct dma_channel *channel,
|
||||
dma_desc->callback = cppi41_dma_callback;
|
||||
dma_desc->callback_param = channel;
|
||||
cppi41_channel->cookie = dma_desc->tx_submit(dma_desc);
|
||||
cppi41_channel->channel.rx_packet_done = false;
|
||||
|
||||
save_rx_toggle(cppi41_channel);
|
||||
dma_async_issue_pending(dc);
|
||||
|
@ -129,6 +129,7 @@ struct dma_channel {
|
||||
size_t actual_len;
|
||||
enum dma_channel_status status;
|
||||
bool desired_mode;
|
||||
bool rx_packet_done;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1737,7 +1737,8 @@ void musb_host_rx(struct musb *musb, u8 epnum)
|
||||
/* 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);
|
||||
|| dma->actual_len < qh->maxpacket
|
||||
|| dma->rx_packet_done);
|
||||
}
|
||||
|
||||
/* send IN token for next packet, without AUTOREQ */
|
||||
|
Loading…
Reference in New Issue
Block a user