static inline void unmap_single(struct device *dev, struct safe_buffer *buf, size_t size, enum dma_data_direction dir) { BUG_ON(buf->size != size); BUG_ON(buf->direction != dir); dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n", __func__, buf->ptr, virt_to_dma(dev, buf->ptr), buf->safe, buf->safe_dma_addr); DO_STATS(dev->archdata.dmabounce->bounce_count++); if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) { void *ptr = buf->ptr; dev_dbg(dev, "%s: copy back safe %p to unsafe %p size %d\n", __func__, buf->safe, ptr, size); memcpy(ptr, buf->safe, size); /* * Since we may have written to a page cache page, * we need to ensure that the data will be coherent * with user mappings. */ __cpuc_flush_dcache_area(ptr, size); } free_safe_buffer(dev->archdata.dmabounce, buf); }
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); } }
static inline void unmap_single(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); dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n", __func__, buf->ptr, virt_to_dma(dev, buf->ptr), buf->safe, buf->safe_dma_addr); DO_STATS(dev->archdata.dmabounce->bounce_count++); if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) { void *ptr = buf->ptr; dev_dbg(dev, "%s: copy back safe %p to unsafe %p size %d\n", __func__, buf->safe, ptr, size); memcpy(ptr, buf->safe, size); dmac_clean_range(ptr, ptr + size); outer_clean_range(__pa(ptr), __pa(ptr) + size); } free_safe_buffer(dev->archdata.dmabounce, buf); } }
static inline void unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma_data_direction dir) { struct dmabounce_device_info *device_info = dev->archdata.dmabounce; struct safe_buffer *buf = NULL; /* * Trying to unmap an invalid mapping */ if (dma_mapping_error(dma_addr)) { dev_err(dev, "Trying to unmap invalid mapping\n"); return; } if (device_info) buf = find_safe_buffer(device_info, dma_addr); if (buf) { BUG_ON(buf->size != size); dev_dbg(dev, "%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", __func__, buf->ptr, (void *) virt_to_dma(dev, buf->ptr), buf->safe, (void *) buf->safe_dma_addr); DO_STATS ( device_info->bounce_count++ ); if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) { void *ptr = buf->ptr; dev_dbg(dev, "%s: copy back safe %p to unsafe %p size %d\n", __func__, buf->safe, ptr, size); memcpy(ptr, buf->safe, size); /* * DMA buffers must have the same cache properties * as if they were really used for DMA - which means * data must be written back to RAM. Note that * we don't use dmac_flush_range() here for the * bidirectional case because we know the cache * lines will be coherent with the data written. */ dmac_clean_range(ptr, ptr + size); outer_clean_range(__pa(ptr), __pa(ptr) + size); } free_safe_buffer(device_info, buf); } }
static inline void unmap_single(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__, buf->ptr, virt_to_dma(dev, buf->ptr), buf->safe, buf->safe_dma_addr); DO_STATS(dev->archdata.dmabounce->bounce_count++); if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) { void *ptr = buf->ptr; dev_dbg(dev, "%s: copy back safe %p to unsafe %p size %d\n", __func__, buf->safe, ptr, size); memcpy(ptr, buf->safe, size); /* * DMA buffers must have the same cache properties * as if they were really used for DMA - which means * data must be written back to RAM. Note that * we don't use dmac_flush_range() here for the * bidirectional case because we know the cache * lines will be coherent with the data written. */ dmac_clean_range(ptr, ptr + size); outer_clean_range(__pa(ptr), __pa(ptr) + size); } free_safe_buffer(dev->archdata.dmabounce, buf); } else { __dma_single_dev_to_cpu(dma_to_virt(dev, dma_addr), size, dir); } }