musb: handling Blackfin anomaly 05000450

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



the musb ip on blackfin parts has an anomaly with DMA mode 1 transmits
where if the transfer is not a multiple of the maximum packet size,
the last short packet might be corrupted.  to work around this issue,
we transfer the full sized packets using dma mode 1 and then use dma
mode 0 for the last short packet.

so in common code:
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -672,7 +672,10 @@ static bool musb_tx_dma_program(struct dma_controller *dma,
    wmb();

    if (!dma->channel_program(channel, pkt_size, mode,
-           urb->transfer_dma + offset, length)) {
+           urb->transfer_dma + offset,
+           (channel->desired_mode == 0) ? length :
+               length - (length % qh->maxpacket)))
+   {
        dma->channel_release(channel);
        hw_ep->tx_channel = NULL;

@@ -1750,7 +1753,10 @@ void musb_host_rx(struct musb *musb, u8 epnum)
             */
            ret = c->channel_program(
                dma, qh->maxpacket,
-               dma->desired_mode, buf, length);
+               dma->desired_mode, buf,
+               (dma->desired_mode == 0)
+               ? length
+               : length - (length % qh->maxpacket));

            if (!ret) {
                c->channel_release(dma);

any ideas on how to get this workaround merged ?  another idea i had
was that we could add a hook to the top of dma_channel_program to let
targets muck with the arguments ... the Blackfin code would just need
to do something like this at the start of the func:
+   if (musb_channel->transmit && channel->desired_mode == 1)
+       len = len - (len % packet_sz);
-mike
--
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


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux