Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.15-rc2 179 lines 4.8 kB view raw
1#ifndef __ASM_SH_DMA_MAPPING_H 2#define __ASM_SH_DMA_MAPPING_H 3 4#include <linux/config.h> 5#include <linux/mm.h> 6#include <asm/scatterlist.h> 7#include <asm/io.h> 8 9extern struct bus_type pci_bus_type; 10 11/* arch/sh/mm/consistent.c */ 12extern void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle); 13extern void consistent_free(void *vaddr, size_t size); 14extern void consistent_sync(void *vaddr, size_t size, int direction); 15 16#define dma_supported(dev, mask) (1) 17 18static inline int dma_set_mask(struct device *dev, u64 mask) 19{ 20 if (!dev->dma_mask || !dma_supported(dev, mask)) 21 return -EIO; 22 23 *dev->dma_mask = mask; 24 25 return 0; 26} 27 28static inline void *dma_alloc_coherent(struct device *dev, size_t size, 29 dma_addr_t *dma_handle, gfp_t flag) 30{ 31 if (sh_mv.mv_consistent_alloc) { 32 void *ret; 33 34 ret = sh_mv.mv_consistent_alloc(dev, size, dma_handle, flag); 35 if (ret != NULL) 36 return ret; 37 } 38 39 return consistent_alloc(flag, size, dma_handle); 40} 41 42static inline void dma_free_coherent(struct device *dev, size_t size, 43 void *vaddr, dma_addr_t dma_handle) 44{ 45 if (sh_mv.mv_consistent_free) { 46 int ret; 47 48 ret = sh_mv.mv_consistent_free(dev, size, vaddr, dma_handle); 49 if (ret == 0) 50 return; 51 } 52 53 consistent_free(vaddr, size); 54} 55 56static inline void dma_cache_sync(void *vaddr, size_t size, 57 enum dma_data_direction dir) 58{ 59 consistent_sync(vaddr, size, (int)dir); 60} 61 62static inline dma_addr_t dma_map_single(struct device *dev, 63 void *ptr, size_t size, 64 enum dma_data_direction dir) 65{ 66#if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT) 67 if (dev->bus == &pci_bus_type) 68 return virt_to_bus(ptr); 69#endif 70 dma_cache_sync(ptr, size, dir); 71 72 return virt_to_bus(ptr); 73} 74 75#define dma_unmap_single(dev, addr, size, dir) do { } while (0) 76 77static inline int dma_map_sg(struct device *dev, struct scatterlist *sg, 78 int nents, enum dma_data_direction dir) 79{ 80 int i; 81 82 for (i = 0; i < nents; i++) { 83#if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT) 84 dma_cache_sync(page_address(sg[i].page) + sg[i].offset, 85 sg[i].length, dir); 86#endif 87 sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset; 88 } 89 90 return nents; 91} 92 93#define dma_unmap_sg(dev, sg, nents, dir) do { } while (0) 94 95static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, 96 unsigned long offset, size_t size, 97 enum dma_data_direction dir) 98{ 99 return dma_map_single(dev, page_address(page) + offset, size, dir); 100} 101 102static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address, 103 size_t size, enum dma_data_direction dir) 104{ 105 dma_unmap_single(dev, dma_address, size, dir); 106} 107 108static inline void dma_sync_single(struct device *dev, dma_addr_t dma_handle, 109 size_t size, enum dma_data_direction dir) 110{ 111#if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT) 112 if (dev->bus == &pci_bus_type) 113 return; 114#endif 115 dma_cache_sync(bus_to_virt(dma_handle), size, dir); 116} 117 118static inline void dma_sync_single_range(struct device *dev, 119 dma_addr_t dma_handle, 120 unsigned long offset, size_t size, 121 enum dma_data_direction dir) 122{ 123#if defined(CONFIG_PCI) && !defined(CONFIG_SH_PCIDMA_NONCOHERENT) 124 if (dev->bus == &pci_bus_type) 125 return; 126#endif 127 dma_cache_sync(bus_to_virt(dma_handle) + offset, size, dir); 128} 129 130static inline void dma_sync_sg(struct device *dev, struct scatterlist *sg, 131 int nelems, enum dma_data_direction dir) 132{ 133 int i; 134 135 for (i = 0; i < nelems; i++) { 136#if !defined(CONFIG_PCI) || defined(CONFIG_SH_PCIDMA_NONCOHERENT) 137 dma_cache_sync(page_address(sg[i].page) + sg[i].offset, 138 sg[i].length, dir); 139#endif 140 sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset; 141 } 142} 143 144static inline void dma_sync_single_for_cpu(struct device *dev, 145 dma_addr_t dma_handle, size_t size, 146 enum dma_data_direction dir) 147 __attribute__ ((alias("dma_sync_single"))); 148 149static inline void dma_sync_single_for_device(struct device *dev, 150 dma_addr_t dma_handle, size_t size, 151 enum dma_data_direction dir) 152 __attribute__ ((alias("dma_sync_single"))); 153 154static inline void dma_sync_sg_for_cpu(struct device *dev, 155 struct scatterlist *sg, int nelems, 156 enum dma_data_direction dir) 157 __attribute__ ((alias("dma_sync_sg"))); 158 159static inline void dma_sync_sg_for_device(struct device *dev, 160 struct scatterlist *sg, int nelems, 161 enum dma_data_direction dir) 162 __attribute__ ((alias("dma_sync_sg"))); 163 164static inline int dma_get_cache_alignment(void) 165{ 166 /* 167 * Each processor family will define its own L1_CACHE_SHIFT, 168 * L1_CACHE_BYTES wraps to this, so this is always safe. 169 */ 170 return L1_CACHE_BYTES; 171} 172 173static inline int dma_mapping_error(dma_addr_t dma_addr) 174{ 175 return dma_addr == 0; 176} 177 178#endif /* __ASM_SH_DMA_MAPPING_H */ 179