/* * * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. * Copyright (C) 2000-2004 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define NO_KERNEL_MAPPING_DUMMY 0x2222 void *removed_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs) { bool no_kernel_mapping = dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs); bool skip_zeroing = dma_get_attr(DMA_ATTR_SKIP_ZEROING, attrs); unsigned long pfn; unsigned long order = get_order(size); void *addr = NULL; size = PAGE_ALIGN(size); if (!(gfp & __GFP_WAIT)) return NULL; pfn = dma_alloc_from_contiguous(dev, size >> PAGE_SHIFT, order); if (pfn) { if (no_kernel_mapping && skip_zeroing) { *handle = __pfn_to_phys(pfn); return (void *)NO_KERNEL_MAPPING_DUMMY; } addr = ioremap(__pfn_to_phys(pfn), size); if (WARN_ON(!addr)) { dma_release_from_contiguous(dev, pfn, order); } else { if (!skip_zeroing) memset_io(addr, 0, size); if (no_kernel_mapping) { iounmap(addr); addr = (void *)NO_KERNEL_MAPPING_DUMMY; } *handle = __pfn_to_phys(pfn); } } return addr; } int removed_mmap(struct device *dev, struct vm_area_struct *vma, void *cpu_addr, dma_addr_t dma_addr, size_t size, struct dma_attrs *attrs) { return -ENXIO; } void removed_free(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle, struct dma_attrs *attrs) { bool no_kernel_mapping = dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs); if (!no_kernel_mapping) iounmap(cpu_addr); dma_release_from_contiguous(dev, __phys_to_pfn(handle), size >> PAGE_SHIFT); } static dma_addr_t removed_map_page(struct device *dev, struct page *page, unsigned long offset, size_t size, enum dma_data_direction dir, struct dma_attrs *attrs) { return ~(dma_addr_t)0; } static void removed_unmap_page(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir, struct dma_attrs *attrs) { return; } static int removed_map_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, struct dma_attrs *attrs) { return 0; } static void removed_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, struct dma_attrs *attrs) { return; } static void removed_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir) { return; } void removed_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir) { return; } void removed_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir) { return; } void removed_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir) { return; } void *removed_remap(struct device *dev, void *cpu_addr, dma_addr_t handle, size_t size, struct dma_attrs *attrs) { return ioremap(handle, size); } void removed_unremap(struct device *dev, void *remapped_address, size_t size) { iounmap(remapped_address); } struct dma_map_ops removed_dma_ops = { .alloc = removed_alloc, .free = removed_free, .mmap = removed_mmap, .map_page = removed_map_page, .unmap_page = removed_unmap_page, .map_sg = removed_map_sg, .unmap_sg = removed_unmap_sg, .sync_single_for_cpu = removed_sync_single_for_cpu, .sync_single_for_device = removed_sync_single_for_device, .sync_sg_for_cpu = removed_sync_sg_for_cpu, .sync_sg_for_device = removed_sync_sg_for_device, .remap = removed_remap, .unremap = removed_unremap, }; EXPORT_SYMBOL(removed_dma_ops);