diff options
Diffstat (limited to 'arch/arm/mm/dma-mapping.c')
| -rw-r--r-- | arch/arm/mm/dma-mapping.c | 91 |
1 files changed, 40 insertions, 51 deletions
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index f6b6bfa88ecf..f61a5707823a 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
| @@ -158,13 +158,49 @@ struct dma_map_ops arm_coherent_dma_ops = { | |||
| 158 | }; | 158 | }; |
| 159 | EXPORT_SYMBOL(arm_coherent_dma_ops); | 159 | EXPORT_SYMBOL(arm_coherent_dma_ops); |
| 160 | 160 | ||
| 161 | static int __dma_supported(struct device *dev, u64 mask, bool warn) | ||
| 162 | { | ||
| 163 | unsigned long max_dma_pfn; | ||
| 164 | |||
| 165 | /* | ||
| 166 | * If the mask allows for more memory than we can address, | ||
| 167 | * and we actually have that much memory, then we must | ||
| 168 | * indicate that DMA to this device is not supported. | ||
| 169 | */ | ||
| 170 | if (sizeof(mask) != sizeof(dma_addr_t) && | ||
| 171 | mask > (dma_addr_t)~0 && | ||
| 172 | dma_to_pfn(dev, ~0) < max_pfn) { | ||
| 173 | if (warn) { | ||
| 174 | dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n", | ||
| 175 | mask); | ||
| 176 | dev_warn(dev, "Driver did not use or check the return value from dma_set_coherent_mask()?\n"); | ||
| 177 | } | ||
| 178 | return 0; | ||
| 179 | } | ||
| 180 | |||
| 181 | max_dma_pfn = min(max_pfn, arm_dma_pfn_limit); | ||
| 182 | |||
| 183 | /* | ||
| 184 | * Translate the device's DMA mask to a PFN limit. This | ||
| 185 | * PFN number includes the page which we can DMA to. | ||
| 186 | */ | ||
| 187 | if (dma_to_pfn(dev, mask) < max_dma_pfn) { | ||
| 188 | if (warn) | ||
| 189 | dev_warn(dev, "Coherent DMA mask %#llx (pfn %#lx-%#lx) covers a smaller range of system memory than the DMA zone pfn 0x0-%#lx\n", | ||
| 190 | mask, | ||
| 191 | dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1, | ||
| 192 | max_dma_pfn + 1); | ||
| 193 | return 0; | ||
| 194 | } | ||
| 195 | |||
| 196 | return 1; | ||
| 197 | } | ||
| 198 | |||
| 161 | static u64 get_coherent_dma_mask(struct device *dev) | 199 | static u64 get_coherent_dma_mask(struct device *dev) |
| 162 | { | 200 | { |
| 163 | u64 mask = (u64)DMA_BIT_MASK(32); | 201 | u64 mask = (u64)DMA_BIT_MASK(32); |
| 164 | 202 | ||
| 165 | if (dev) { | 203 | if (dev) { |
| 166 | unsigned long max_dma_pfn; | ||
| 167 | |||
| 168 | mask = dev->coherent_dma_mask; | 204 | mask = dev->coherent_dma_mask; |
| 169 | 205 | ||
| 170 | /* | 206 | /* |
| @@ -176,34 +212,8 @@ static u64 get_coherent_dma_mask(struct device *dev) | |||
| 176 | return 0; | 212 | return 0; |
| 177 | } | 213 | } |
| 178 | 214 | ||
| 179 | max_dma_pfn = min(max_pfn, arm_dma_pfn_limit); | 215 | if (!__dma_supported(dev, mask, true)) |
| 180 | |||
| 181 | /* | ||
| 182 | * If the mask allows for more memory than we can address, | ||
| 183 | * and we actually have that much memory, then fail the | ||
| 184 | * allocation. | ||
| 185 | */ | ||
| 186 | if (sizeof(mask) != sizeof(dma_addr_t) && | ||
| 187 | mask > (dma_addr_t)~0 && | ||
| 188 | dma_to_pfn(dev, ~0) > max_dma_pfn) { | ||
| 189 | dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n", | ||
| 190 | mask); | ||
| 191 | dev_warn(dev, "Driver did not use or check the return value from dma_set_coherent_mask()?\n"); | ||
| 192 | return 0; | ||
| 193 | } | ||
| 194 | |||
| 195 | /* | ||
| 196 | * Now check that the mask, when translated to a PFN, | ||
| 197 | * fits within the allowable addresses which we can | ||
| 198 | * allocate. | ||
| 199 | */ | ||
| 200 | if (dma_to_pfn(dev, mask) < max_dma_pfn) { | ||
| 201 | dev_warn(dev, "Coherent DMA mask %#llx (pfn %#lx-%#lx) covers a smaller range of system memory than the DMA zone pfn 0x0-%#lx\n", | ||
| 202 | mask, | ||
| 203 | dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1, | ||
| 204 | arm_dma_pfn_limit + 1); | ||
| 205 | return 0; | 216 | return 0; |
| 206 | } | ||
| 207 | } | 217 | } |
| 208 | 218 | ||
| 209 | return mask; | 219 | return mask; |
| @@ -1032,28 +1042,7 @@ void arm_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, | |||
| 1032 | */ | 1042 | */ |
| 1033 | int dma_supported(struct device *dev, u64 mask) | 1043 | int dma_supported(struct device *dev, u64 mask) |
| 1034 | { | 1044 | { |
| 1035 | unsigned long limit; | 1045 | return __dma_supported(dev, mask, false); |
| 1036 | |||
| 1037 | /* | ||
| 1038 | * If the mask allows for more memory than we can address, | ||
| 1039 | * and we actually have that much memory, then we must | ||
| 1040 | * indicate that DMA to this device is not supported. | ||
| 1041 | */ | ||
| 1042 | if (sizeof(mask) != sizeof(dma_addr_t) && | ||
| 1043 | mask > (dma_addr_t)~0 && | ||
| 1044 | dma_to_pfn(dev, ~0) > arm_dma_pfn_limit) | ||
| 1045 | return 0; | ||
| 1046 | |||
| 1047 | /* | ||
| 1048 | * Translate the device's DMA mask to a PFN limit. This | ||
| 1049 | * PFN number includes the page which we can DMA to. | ||
| 1050 | */ | ||
| 1051 | limit = dma_to_pfn(dev, mask); | ||
| 1052 | |||
| 1053 | if (limit < arm_dma_pfn_limit) | ||
| 1054 | return 0; | ||
| 1055 | |||
| 1056 | return 1; | ||
| 1057 | } | 1046 | } |
| 1058 | EXPORT_SYMBOL(dma_supported); | 1047 | EXPORT_SYMBOL(dma_supported); |
| 1059 | 1048 | ||
