Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Copyright (C) 2004 IBM Corporation | |
3 | * | |
4 | * Implements the generic device dma API for ppc64. Handles | |
5 | * the pci and vio busses | |
6 | */ | |
7 | ||
8 | #include <linux/device.h> | |
9 | #include <linux/dma-mapping.h> | |
10 | /* Include the busses we support */ | |
11 | #include <linux/pci.h> | |
12 | #include <asm/vio.h> | |
d7a30103 | 13 | #include <asm/ibmebus.h> |
1da177e4 LT |
14 | #include <asm/scatterlist.h> |
15 | #include <asm/bug.h> | |
16 | ||
17 | static struct dma_mapping_ops *get_dma_ops(struct device *dev) | |
18 | { | |
145d01e4 | 19 | #ifdef CONFIG_PCI |
1da177e4 LT |
20 | if (dev->bus == &pci_bus_type) |
21 | return &pci_dma_ops; | |
145d01e4 | 22 | #endif |
1da177e4 LT |
23 | #ifdef CONFIG_IBMVIO |
24 | if (dev->bus == &vio_bus_type) | |
25 | return &vio_dma_ops; | |
d7a30103 HS |
26 | #endif |
27 | #ifdef CONFIG_IBMEBUS | |
28 | if (dev->bus == &ibmebus_bus_type) | |
29 | return &ibmebus_dma_ops; | |
1da177e4 LT |
30 | #endif |
31 | return NULL; | |
32 | } | |
33 | ||
34 | int dma_supported(struct device *dev, u64 mask) | |
35 | { | |
36 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | |
37 | ||
38 | if (dma_ops) | |
39 | return dma_ops->dma_supported(dev, mask); | |
40 | BUG(); | |
41 | return 0; | |
42 | } | |
43 | EXPORT_SYMBOL(dma_supported); | |
44 | ||
45 | int dma_set_mask(struct device *dev, u64 dma_mask) | |
46 | { | |
145d01e4 | 47 | #ifdef CONFIG_PCI |
1da177e4 LT |
48 | if (dev->bus == &pci_bus_type) |
49 | return pci_set_dma_mask(to_pci_dev(dev), dma_mask); | |
145d01e4 | 50 | #endif |
1da177e4 LT |
51 | #ifdef CONFIG_IBMVIO |
52 | if (dev->bus == &vio_bus_type) | |
53 | return -EIO; | |
54 | #endif /* CONFIG_IBMVIO */ | |
d7a30103 HS |
55 | #ifdef CONFIG_IBMEBUS |
56 | if (dev->bus == &ibmebus_bus_type) | |
57 | return -EIO; | |
58 | #endif | |
1da177e4 LT |
59 | BUG(); |
60 | return 0; | |
61 | } | |
62 | EXPORT_SYMBOL(dma_set_mask); | |
63 | ||
64 | void *dma_alloc_coherent(struct device *dev, size_t size, | |
dd0fc66f | 65 | dma_addr_t *dma_handle, gfp_t flag) |
1da177e4 LT |
66 | { |
67 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | |
68 | ||
69 | if (dma_ops) | |
70 | return dma_ops->alloc_coherent(dev, size, dma_handle, flag); | |
71 | BUG(); | |
72 | return NULL; | |
73 | } | |
74 | EXPORT_SYMBOL(dma_alloc_coherent); | |
75 | ||
76 | void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, | |
77 | dma_addr_t dma_handle) | |
78 | { | |
79 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | |
80 | ||
81 | if (dma_ops) | |
82 | dma_ops->free_coherent(dev, size, cpu_addr, dma_handle); | |
83 | else | |
84 | BUG(); | |
85 | } | |
86 | EXPORT_SYMBOL(dma_free_coherent); | |
87 | ||
88 | dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, size_t size, | |
89 | enum dma_data_direction direction) | |
90 | { | |
91 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | |
92 | ||
93 | if (dma_ops) | |
94 | return dma_ops->map_single(dev, cpu_addr, size, direction); | |
95 | BUG(); | |
96 | return (dma_addr_t)0; | |
97 | } | |
98 | EXPORT_SYMBOL(dma_map_single); | |
99 | ||
100 | void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, | |
101 | enum dma_data_direction direction) | |
102 | { | |
103 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | |
104 | ||
105 | if (dma_ops) | |
106 | dma_ops->unmap_single(dev, dma_addr, size, direction); | |
107 | else | |
108 | BUG(); | |
109 | } | |
110 | EXPORT_SYMBOL(dma_unmap_single); | |
111 | ||
112 | dma_addr_t dma_map_page(struct device *dev, struct page *page, | |
113 | unsigned long offset, size_t size, | |
114 | enum dma_data_direction direction) | |
115 | { | |
116 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | |
117 | ||
118 | if (dma_ops) | |
119 | return dma_ops->map_single(dev, | |
120 | (page_address(page) + offset), size, direction); | |
121 | BUG(); | |
122 | return (dma_addr_t)0; | |
123 | } | |
124 | EXPORT_SYMBOL(dma_map_page); | |
125 | ||
126 | void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, | |
127 | enum dma_data_direction direction) | |
128 | { | |
129 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | |
130 | ||
131 | if (dma_ops) | |
132 | dma_ops->unmap_single(dev, dma_address, size, direction); | |
133 | else | |
134 | BUG(); | |
135 | } | |
136 | EXPORT_SYMBOL(dma_unmap_page); | |
137 | ||
138 | int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, | |
139 | enum dma_data_direction direction) | |
140 | { | |
141 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | |
142 | ||
143 | if (dma_ops) | |
144 | return dma_ops->map_sg(dev, sg, nents, direction); | |
145 | BUG(); | |
146 | return 0; | |
147 | } | |
148 | EXPORT_SYMBOL(dma_map_sg); | |
149 | ||
150 | void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, | |
151 | enum dma_data_direction direction) | |
152 | { | |
153 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | |
154 | ||
155 | if (dma_ops) | |
156 | dma_ops->unmap_sg(dev, sg, nhwentries, direction); | |
157 | else | |
158 | BUG(); | |
159 | } | |
160 | EXPORT_SYMBOL(dma_unmap_sg); |