Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.30 227 lines 5.8 kB view raw
1/* dma.c: PCI and SBUS DMA accessors for 32-bit sparc. 2 * 3 * Copyright (C) 2008 David S. Miller <davem@davemloft.net> 4 */ 5 6#include <linux/kernel.h> 7#include <linux/module.h> 8#include <linux/dma-mapping.h> 9#include <linux/scatterlist.h> 10#include <linux/mm.h> 11 12#ifdef CONFIG_PCI 13#include <linux/pci.h> 14#endif 15 16#include "dma.h" 17 18int dma_supported(struct device *dev, u64 mask) 19{ 20#ifdef CONFIG_PCI 21 if (dev->bus == &pci_bus_type) 22 return pci_dma_supported(to_pci_dev(dev), mask); 23#endif 24 return 0; 25} 26EXPORT_SYMBOL(dma_supported); 27 28int dma_set_mask(struct device *dev, u64 dma_mask) 29{ 30#ifdef CONFIG_PCI 31 if (dev->bus == &pci_bus_type) 32 return pci_set_dma_mask(to_pci_dev(dev), dma_mask); 33#endif 34 return -EOPNOTSUPP; 35} 36EXPORT_SYMBOL(dma_set_mask); 37 38void *dma_alloc_coherent(struct device *dev, size_t size, 39 dma_addr_t *dma_handle, gfp_t flag) 40{ 41#ifdef CONFIG_PCI 42 if (dev->bus == &pci_bus_type) 43 return pci_alloc_consistent(to_pci_dev(dev), size, dma_handle); 44#endif 45 return sbus_alloc_consistent(dev, size, dma_handle); 46} 47EXPORT_SYMBOL(dma_alloc_coherent); 48 49void dma_free_coherent(struct device *dev, size_t size, 50 void *cpu_addr, dma_addr_t dma_handle) 51{ 52#ifdef CONFIG_PCI 53 if (dev->bus == &pci_bus_type) { 54 pci_free_consistent(to_pci_dev(dev), size, 55 cpu_addr, dma_handle); 56 return; 57 } 58#endif 59 sbus_free_consistent(dev, size, cpu_addr, dma_handle); 60} 61EXPORT_SYMBOL(dma_free_coherent); 62 63dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, 64 size_t size, enum dma_data_direction direction) 65{ 66#ifdef CONFIG_PCI 67 if (dev->bus == &pci_bus_type) 68 return pci_map_single(to_pci_dev(dev), cpu_addr, 69 size, (int)direction); 70#endif 71 return sbus_map_single(dev, cpu_addr, size, (int)direction); 72} 73EXPORT_SYMBOL(dma_map_single); 74 75void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, 76 size_t size, 77 enum dma_data_direction direction) 78{ 79#ifdef CONFIG_PCI 80 if (dev->bus == &pci_bus_type) { 81 pci_unmap_single(to_pci_dev(dev), dma_addr, 82 size, (int)direction); 83 return; 84 } 85#endif 86 sbus_unmap_single(dev, dma_addr, size, (int)direction); 87} 88EXPORT_SYMBOL(dma_unmap_single); 89 90dma_addr_t dma_map_page(struct device *dev, struct page *page, 91 unsigned long offset, size_t size, 92 enum dma_data_direction direction) 93{ 94#ifdef CONFIG_PCI 95 if (dev->bus == &pci_bus_type) 96 return pci_map_page(to_pci_dev(dev), page, offset, 97 size, (int)direction); 98#endif 99 return sbus_map_single(dev, page_address(page) + offset, 100 size, (int)direction); 101} 102EXPORT_SYMBOL(dma_map_page); 103 104void dma_unmap_page(struct device *dev, dma_addr_t dma_address, 105 size_t size, enum dma_data_direction direction) 106{ 107#ifdef CONFIG_PCI 108 if (dev->bus == &pci_bus_type) { 109 pci_unmap_page(to_pci_dev(dev), dma_address, 110 size, (int)direction); 111 return; 112 } 113#endif 114 sbus_unmap_single(dev, dma_address, size, (int)direction); 115} 116EXPORT_SYMBOL(dma_unmap_page); 117 118int dma_map_sg(struct device *dev, struct scatterlist *sg, 119 int nents, enum dma_data_direction direction) 120{ 121#ifdef CONFIG_PCI 122 if (dev->bus == &pci_bus_type) 123 return pci_map_sg(to_pci_dev(dev), sg, nents, (int)direction); 124#endif 125 return sbus_map_sg(dev, sg, nents, direction); 126} 127EXPORT_SYMBOL(dma_map_sg); 128 129void dma_unmap_sg(struct device *dev, struct scatterlist *sg, 130 int nents, enum dma_data_direction direction) 131{ 132#ifdef CONFIG_PCI 133 if (dev->bus == &pci_bus_type) { 134 pci_unmap_sg(to_pci_dev(dev), sg, nents, (int)direction); 135 return; 136 } 137#endif 138 sbus_unmap_sg(dev, sg, nents, (int)direction); 139} 140EXPORT_SYMBOL(dma_unmap_sg); 141 142void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, 143 size_t size, enum dma_data_direction direction) 144{ 145#ifdef CONFIG_PCI 146 if (dev->bus == &pci_bus_type) { 147 pci_dma_sync_single_for_cpu(to_pci_dev(dev), dma_handle, 148 size, (int)direction); 149 return; 150 } 151#endif 152 sbus_dma_sync_single_for_cpu(dev, dma_handle, size, (int) direction); 153} 154EXPORT_SYMBOL(dma_sync_single_for_cpu); 155 156void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, 157 size_t size, enum dma_data_direction direction) 158{ 159#ifdef CONFIG_PCI 160 if (dev->bus == &pci_bus_type) { 161 pci_dma_sync_single_for_device(to_pci_dev(dev), dma_handle, 162 size, (int)direction); 163 return; 164 } 165#endif 166 sbus_dma_sync_single_for_device(dev, dma_handle, size, (int) direction); 167} 168EXPORT_SYMBOL(dma_sync_single_for_device); 169 170void dma_sync_single_range_for_cpu(struct device *dev, 171 dma_addr_t dma_handle, 172 unsigned long offset, 173 size_t size, 174 enum dma_data_direction direction) 175{ 176 dma_sync_single_for_cpu(dev, dma_handle+offset, size, direction); 177} 178EXPORT_SYMBOL(dma_sync_single_range_for_cpu); 179 180void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle, 181 unsigned long offset, size_t size, 182 enum dma_data_direction direction) 183{ 184 dma_sync_single_for_device(dev, dma_handle+offset, size, direction); 185} 186EXPORT_SYMBOL(dma_sync_single_range_for_device); 187 188void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, 189 int nelems, enum dma_data_direction direction) 190{ 191#ifdef CONFIG_PCI 192 if (dev->bus == &pci_bus_type) { 193 pci_dma_sync_sg_for_cpu(to_pci_dev(dev), sg, 194 nelems, (int)direction); 195 return; 196 } 197#endif 198 BUG(); 199} 200EXPORT_SYMBOL(dma_sync_sg_for_cpu); 201 202void dma_sync_sg_for_device(struct device *dev, 203 struct scatterlist *sg, int nelems, 204 enum dma_data_direction direction) 205{ 206#ifdef CONFIG_PCI 207 if (dev->bus == &pci_bus_type) { 208 pci_dma_sync_sg_for_device(to_pci_dev(dev), sg, 209 nelems, (int)direction); 210 return; 211 } 212#endif 213 BUG(); 214} 215EXPORT_SYMBOL(dma_sync_sg_for_device); 216 217int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) 218{ 219 return (dma_addr == DMA_ERROR_CODE); 220} 221EXPORT_SYMBOL(dma_mapping_error); 222 223int dma_get_cache_alignment(void) 224{ 225 return 32; 226} 227EXPORT_SYMBOL(dma_get_cache_alignment);