ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / include / asm-ppc / dma-mapping.h
1 /*
2  * This is based on both include/asm-sh/dma-mapping.h and
3  * include/asm-ppc/pci.h
4  */
5 #ifndef __ASM_PPC_DMA_MAPPING_H
6 #define __ASM_PPC_DMA_MAPPING_H
7
8 #include <linux/config.h>
9 /* we implement the API below in terms of the existing PCI one,
10  * so include it */
11 #include <linux/pci.h>
12 /* need struct page definitions */
13 #include <linux/mm.h>
14 #include <linux/device.h>
15 #include <asm/scatterlist.h>
16 #include <asm/io.h>
17
18 #define dma_supported(dev, mask)        (1)
19
20 static inline int dma_set_mask(struct device *dev, u64 dma_mask)
21 {
22         if (!dev->dma_mask || !dma_supported(dev, mask))
23                 return -EIO;
24
25         *dev->dma_mask = dma_mask;
26
27         return 0;
28 }
29
30 static inline void *dma_alloc_coherent(struct device *dev, size_t size,
31                                        dma_addr_t * dma_handle, int flag)
32 {
33 #ifdef CONFIG_PCI
34         if (dev && dev->bus == &pci_bus_type)
35                 return pci_alloc_consistent(to_pci_dev(dev), size, dma_handle);
36 #endif
37
38         return consistent_alloc(flag, size, dma_handle);
39 }
40
41 static inline void
42 dma_free_coherent(struct device *dev, size_t size, void *vaddr,
43                   dma_addr_t dma_handle)
44 {
45 #ifdef CONFIG_PCI
46         if (dev && dev->bus == &pci_bus_type) {
47                 pci_free_consistent(to_pci_dev(dev), size, vaddr, dma_handle);
48                 return;
49         }
50 #endif
51
52         consistent_free(vaddr);
53 }
54
55 static inline dma_addr_t
56 dma_map_single(struct device *dev, void *ptr, size_t size,
57                enum dma_data_direction direction)
58 {
59         BUG_ON(direction == DMA_NONE);
60
61         consistent_sync(ptr, size, direction);
62
63         return virt_to_bus(ptr);
64 }
65
66 /* We do nothing. */
67 #define dma_unmap_single(dev, addr, size, dir)  do { } while (0)
68
69 static inline dma_addr_t
70 dma_map_page(struct device *dev, struct page *page,
71              unsigned long offset, size_t size,
72              enum dma_data_direction direction)
73 {
74         BUG_ON(direction == DMA_NONE);
75         consistent_sync_page(page, offset, size, direction);
76         return (page - mem_map) * PAGE_SIZE + PCI_DRAM_OFFSET + offset;
77 }
78
79 /* We do nothing. */
80 #define dma_unmap_page(dev, addr, size, dir)    do { } while (0)
81
82 static inline int
83 dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
84            enum dma_data_direction direction)
85 {
86         int i;
87
88         BUG_ON(direction == DMA_NONE);
89
90         for (i = 0; i < nents; i++, sg++) {
91                 BUG_ON(!sg->page);
92                 consistent_sync_page(sg->page, sg->offset,
93                                      sg->length, direction);
94                 sg->dma_address = page_to_bus(sg->page) + sg->offset;
95         }
96
97         return nents;
98 }
99
100 /* We don't do anything here. */
101 #define dma_unmap_sg(dev, sg, nents, dir)       do { } while (0)
102
103 static inline void
104 dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
105                         size_t size,
106                         enum dma_data_direction direction)
107 {
108         BUG_ON(direction == DMA_NONE);
109
110         consistent_sync(bus_to_virt(dma_handle), size, direction);
111 }
112
113 static inline void
114 dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
115                            size_t size,
116                            enum dma_data_direction direction)
117 {
118         BUG_ON(direction == DMA_NONE);
119
120         consistent_sync(bus_to_virt(dma_handle), size, direction);
121 }
122
123 static inline void
124 dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
125                     int nelems, enum dma_data_direction direction)
126 {
127         int i;
128
129         BUG_ON(direction == DMA_NONE);
130
131         for (i = 0; i < nelems; i++, sg++)
132                 consistent_sync_page(sg->page, sg->offset,
133                                      sg->length, direction);
134 }
135
136 static inline void
137 dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
138                        int nelems, enum dma_data_direction direction)
139 {
140         int i;
141
142         BUG_ON(direction == DMA_NONE);
143
144         for (i = 0; i < nelems; i++, sg++)
145                 consistent_sync_page(sg->page, sg->offset,
146                                      sg->length, direction);
147 }
148
149 /* Now for the API extensions over the pci_ one */
150
151 #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
152 #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
153 #define dma_is_consistent(d)    (1)
154
155 static inline int dma_get_cache_alignment(void)
156 {
157         /*
158          * Each processor family will define its own L1_CACHE_SHIFT,
159          * L1_CACHE_BYTES wraps to this, so this is always safe.
160          */
161         return L1_CACHE_BYTES;
162 }
163
164 static inline void
165 dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
166                               unsigned long offset, size_t size,
167                               enum dma_data_direction direction)
168 {
169         /* just sync everything, that's all the pci API can do */
170         dma_sync_single_for_cpu(dev, dma_handle, offset + size, direction);
171 }
172
173 static inline void
174 dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
175                                  unsigned long offset, size_t size,
176                                  enum dma_data_direction direction)
177 {
178         /* just sync everything, that's all the pci API can do */
179         dma_sync_single_for_device(dev, dma_handle, offset + size, direction);
180 }
181
182 static inline void dma_cache_sync(void *vaddr, size_t size,
183                                   enum dma_data_direction direction)
184 {
185         consistent_sync(vaddr, size, (int)direction);
186 }
187
188 static inline int dma_mapping_error(dma_addr_t dma_addr)
189 {
190         return 0;
191 }
192
193 #endif                          /* __ASM_PPC_DMA_MAPPING_H */