On Tuesday 27 September 2011, Mark Salter wrote: > +dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, > + enum dma_data_direction dir) > +{ > + dma_addr_t addr = virt_to_phys(ptr); > + > + BUG_ON(!valid_dma_direction(dir)); > + > + switch (dir) { > + case DMA_FROM_DEVICE: > + L2_cache_block_invalidate(addr, addr + size); > + break; > + case DMA_TO_DEVICE: > + L2_cache_block_writeback(addr, addr + size); > + break; > + case DMA_BIDIRECTIONAL: > + /* > + * If area will be used bidirectionally, syncing will > + * take place manually in the driver. > + */ I think this comment is not strictly correct and you have to do a writeback+invalidate here. When you map an area, it initially belongs to the device, until you either do an unmap or sync_*_for_cpu. > +void dma_unmap_single(struct device *dev, dma_addr_t handle, > + size_t size, enum dma_data_direction dir) > +{ > + /* nothing to do here */ > + debug_dma_unmap_page(dev, handle, size, dir, true); > +} > +EXPORT_SYMBOL(dma_unmap_single); > +void dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, > + size_t size, enum dma_data_direction dir) > +{ > + unsigned long paddr = handle; > + > + BUG_ON(!valid_dma_direction(dir)); > + > + switch (dir) { > + case DMA_FROM_DEVICE: > + L2_cache_block_invalidate(paddr, paddr + size); > + break; > + case DMA_TO_DEVICE: > + L2_cache_block_writeback(paddr, paddr + size); > + break; > + case DMA_BIDIRECTIONAL: > + L2_cache_block_writeback_invalidate(paddr, paddr + size); > + break; > + default: > + break; > + } > + > + debug_dma_sync_single_for_cpu(dev, handle, size, dir); > +} > +EXPORT_SYMBOL(dma_sync_single_for_cpu); Normally, sync_*_for_cpu is the same as unmap regarding the cache. > +void dma_sync_single_for_device(struct device *dev, dma_addr_t handle, > + size_t size, enum dma_data_direction dir) > +{ > + unsigned long paddr = handle; > + > + BUG_ON(!valid_dma_direction(dir)); > + > + /* don't bother invalidating if DMA to device */ > + if (dir != DMA_TO_DEVICE) > + L2_cache_block_invalidate(paddr, paddr + size); > + > + debug_dma_sync_single_for_device(dev, handle, size, dir); > +} > +EXPORT_SYMBOL(dma_sync_single_for_device); And this should do the same as map(). In particular it needs to writeback the cache when direction is TO_DEVICE or BIDIRECTIONAL. Arnd -- To unsubscribe from this list: send the line "unsubscribe linux-arch" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html