Title: [5824] trunk/drivers/usb/musb: Workaround for DMA mode 1 data corruption anomaly.
- Revision
- 5824
- Author
- cooloney
- Date
- 2008-12-05 03:27:48 -0600 (Fri, 05 Dec 2008)
Log Message
Workaround for DMA mode 1 data corruption anomaly.
Since this anomaly is not announce offically, I just follow the draft
to add this workaround.
Data corruption when using USB DMA mode 1. (Issue manager 17-01-0105)
DMA mode 1 allows large size transfers to generate a single interrupt
at the end of the entire transfer. The transfer is split up in packets
of length specified in the Maximum Packet Size field for that endpoint.
If the transfer size is not an integer multiple of the Maximum Packet
Size, a short packet will be present at the end of the transfer.
Under certain conditions this packet may be corrupted in the USB FIFO.
Workaround:
Use DMA mode 1 to transfer (n* Maximum Packet Size) and schedule DMA
mode 0 to transfer the short packet.
As an example if your transfer size is 33168 bytes and Maximum Packet
Size equals 512, schedule [33168 - (33168 mod 512)] in DMA mode 1 and
the remainder (33168 mod 512) in DMA mode 0.
Applies to Revisions: 0.0, 0.1 and 0.2 (BF54x)
Modified Paths
Diff
Modified: trunk/drivers/usb/musb/musb_gadget.c (5823 => 5824)
--- trunk/drivers/usb/musb/musb_gadget.c 2008-12-05 05:57:24 UTC (rev 5823)
+++ trunk/drivers/usb/musb/musb_gadget.c 2008-12-05 09:27:48 UTC (rev 5824)
@@ -312,7 +312,13 @@
use_dma = use_dma && c->channel_program(
musb_ep->dma, musb_ep->packet_sz,
musb_ep->dma->desired_mode,
- request->dma, request_size);
+ request->dma,
+ (musb_ep->dma->desired_mode == 0)
+ ? request_size
+ : (request_size -
+ (request_size %
+ musb_ep->packet_sz)));
+
if (use_dma) {
if (musb_ep->dma->desired_mode == 0) {
/* ASSERT: DMAENAB is clear */
@@ -673,7 +679,11 @@
channel->desired_mode,
request->dma
+ request->actual,
- transfer_size);
+ (musb_ep->dma->desired_mode == 0)
+ ? transfer_size
+ : (transfer_size -
+ (transfer_size %
+ musb_ep->packet_sz)));
}
if (use_dma)
Modified: trunk/drivers/usb/musb/musb_host.c (5823 => 5824)
--- trunk/drivers/usb/musb/musb_host.c 2008-12-05 05:57:24 UTC (rev 5823)
+++ trunk/drivers/usb/musb/musb_host.c 2008-12-05 09:27:48 UTC (rev 5824)
@@ -783,7 +783,11 @@
dma_channel, packet_sz,
dma_channel->desired_mode,
urb->transfer_dma,
- qh->segsize);
+ (dma_channel->desired_mode == 0)
+ ? qh->segsize
+ : (qh->segsize -
+ (qh->segsize %
+ qh->maxpacket)));
if (dma_ok) {
load_count = 0;
} else {
@@ -1619,7 +1623,9 @@
+ urb->actual_length,
(dma->desired_mode == 0)
? rx_count
- : urb->transfer_buffer_length);
+ : (urb->transfer_buffer_length -
+ (urb->transfer_buffer_length %
+ qh->maxpacket)));
if (!ret) {
c->channel_release(dma);
_______________________________________________
Linux-kernel-commits mailing list
[email protected]
http://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits