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