On Sat, Jul 04, 2009 at 11:41:46PM +0800, Ming Lei wrote: >> dma_map_*() can invalidate cache lines, so dma_unmap_*() may do nothing. >> But if someone accesses the dma buffer during dma transfer, you may >> get the inconsistent result. >You missed an important statement: accessing the dma buffer during a dma transfer >is not permitted without an intervening call to the dma_sync_* functions. > >DMA buffers have the idea of "ownership" - they initially start off being owned >by the CPU. Upon dma_map_*(), ownership transfers to the DMA agent, and remains there >until either a dma_unmap_*() or dma_sync_single_for_cpu(). >In the case of dma_sync_single_for_cpu(), it can only be given back to the DMA agent >using dma_sync_single_for_device(). > >The important point from the above is that _only_ the current owner may access the >buffer. So, if you've mapped a buffer, accessing the buffer subsequently without a >call to dma_sync_single_for_cpu() is illegal. That is right, I don't think in our case the buffer is being accessed during DMA transfer. In drivers/usb/core/config.c, function usb_get_descriptor calls usb_control_msg to submit URB, and that is a blocking call, it wouldn't return until DMA to RAM is finished. As Alan pointed out, if dma_map_single() invalidates cache lines for IN URB, nothing special needs to be done on URB completion. But the fact that a call to dma_cache_maint before CPU accessing the buffer makes the inconsistency problem go away is leading me to the dma_cache_maint function itself, is it possible that, under certain condition, dma_cache_maint fails to invalidate the cache lines? Because of the random nature of this problem, calling dma_cache_maint the second time just happened to help. Any idea how to check for dma_cache_maint failures? Fei -- 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