static void arm_dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, size_t size, enum dma_data_direction dir) { unsigned int offset = handle & (PAGE_SIZE - 1); struct page *page = pfn_to_page(dma_to_pfn(dev, handle-offset)); __dma_page_dev_to_cpu(page, offset, size, dir); }
static inline void unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir) { struct safe_buffer *buf = find_safe_buffer_dev(dev, dma_addr, "unmap"); if (buf) { BUG_ON(buf->size != size); BUG_ON(buf->direction != dir); BUG_ON(!buf->page); BUG_ON(buf->ptr); dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n", __func__, page_address(buf->page), page_to_dma(dev, buf->page), buf->safe, buf->safe_dma_addr); DO_STATS(dev->archdata.dmabounce->bounce_count++); if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) { void *ptr; ptr = kmap_atomic(buf->page, KM_BOUNCE_READ) + buf->offset; memcpy(ptr, buf->safe, size); __cpuc_flush_dcache_area(ptr, size); kunmap_atomic(ptr - buf->offset, KM_BOUNCE_READ); } free_safe_buffer(dev->archdata.dmabounce, buf); } else { __dma_page_dev_to_cpu(dma_to_page(dev, dma_addr), dma_addr & ~PAGE_MASK, size, dir); } }
/** * arm_dma_unmap_page - unmap a buffer previously mapped through dma_map_page() * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices * @handle: DMA address of buffer * @size: size of buffer (same as passed to dma_map_page) * @dir: DMA transfer direction (same as passed to dma_map_page) * * Unmap a page streaming mode DMA translation. The handle and size * must match what was provided in the previous dma_map_page() call. * All other usages are undefined. * * After this call, reads by the CPU to the buffer are guaranteed to see * whatever the device wrote there. */ static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size, enum dma_data_direction dir, struct dma_attrs *attrs) { if (!arch_is_coherent()) __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)), handle & ~PAGE_MASK, size, dir); }
/** * arm_dma_unmap_page - unmap a buffer previously mapped through dma_map_page() * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices * @handle: DMA address of buffer * @size: size of buffer (same as passed to dma_map_page) * @dir: DMA transfer direction (same as passed to dma_map_page) * * Unmap a page streaming mode DMA translation. The handle and size * must match what was provided in the previous dma_map_page() call. * All other usages are undefined. * * After this call, reads by the CPU to the buffer are guaranteed to see * whatever the device wrote there. */ static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size, enum dma_data_direction dir, struct dma_attrs *attrs) { if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)), handle & ~PAGE_MASK, size, dir); }
/* * see if a mapped address was really a "safe" buffer and if so, copy * the data from the safe buffer back to the unsafe buffer and free up * the safe buffer. (basically return things back to the way they * should be) */ void __dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir) { struct safe_buffer *buf; dev_dbg(dev, "%s(dma=%#x,size=%d,dir=%x)\n", __func__, dma_addr, size, dir); buf = find_safe_buffer_dev(dev, dma_addr, __func__); if (!buf) { __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, dma_addr)), dma_addr & ~PAGE_MASK, size, dir); return; } unmap_single(dev, buf, size, dir); }