History

dma-mapping: implement dma_map_single_attrs using dma_map_page_attrs

And also switch the way we implement the unmap side around to stay consistent. This ensures dma-debug works again because it records which function we used for mapping to ensure it is also used for unmapping, and also reduces further code duplication. Last but not least this also officially allows calling dma_sync_single_* for mappings created using dma_map_page, which is perfectly fine given that the sync calls only take a dma_addr_t, but not a virtual address or struct page.

Christoph Hellwig committed 7 years ago

Commit 2e05ea51 parent 96d4f263 files · +32 −62Browse files

Showing the changes to include/linux (2 of 3 files). Show all

Unified · Split

2 files
  1. include/linux/dma-debug.h +4 −7
  2. include/linux/dma-mapping.h +24 −42
include/linux/dma-debug.h+4−7
@@ -35,13 +35,12 @@ extern void debug_dma_map_single(struct device *dev, const void *addr, · 34 unmodified lines
35 35
36extern void debug_dma_map_page(struct device *dev, struct page *page,36extern void debug_dma_map_page(struct device *dev, struct page *page,
37 size_t offset, size_t size,37 size_t offset, size_t size,
38 int direction, dma_addr_t dma_addr,38 int direction, dma_addr_t dma_addr);
39 bool map_single);
40 39
41extern void debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr);40extern void debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
42 41
43extern void debug_dma_unmap_page(struct device *dev, dma_addr_t addr,42extern void debug_dma_unmap_page(struct device *dev, dma_addr_t addr,
44 size_t size, int direction, bool map_single);43 size_t size, int direction);
45 44
46extern void debug_dma_map_sg(struct device *dev, struct scatterlist *sg,45extern void debug_dma_map_sg(struct device *dev, struct scatterlist *sg,
47 int nents, int mapped_ents, int direction);46 int nents, int mapped_ents, int direction);
@@ -95,8 +94,7 @@ static inline void debug_dma_map_single(struct device *dev, const void *addr, · 47 unmodified lines
95 94
96static inline void debug_dma_map_page(struct device *dev, struct page *page,95static inline void debug_dma_map_page(struct device *dev, struct page *page,
97 size_t offset, size_t size,96 size_t offset, size_t size,
98 int direction, dma_addr_t dma_addr,97 int direction, dma_addr_t dma_addr)
99 bool map_single)
100{98{
101}99}
102 100
@@ -106,8 +104,7 @@ static inline void debug_dma_mapping_error(struct device *dev, · 3 unmodified lines
106}104}
107 105
108static inline void debug_dma_unmap_page(struct device *dev, dma_addr_t addr,106static inline void debug_dma_unmap_page(struct device *dev, dma_addr_t addr,
109 size_t size, int direction,107 size_t size, int direction)
110 bool map_single)
111{108{
112}109}
113 110
include/linux/dma-mapping.h+24−42
@@ -284,32 +284,25 @@ static inline void dma_direct_sync_sg_for_cpu(struct device *dev, · 283 unmodified lines
284}284}
285#endif285#endif
286 286
287static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,287static inline dma_addr_t dma_map_page_attrs(struct device *dev,
288 size_t size,288 struct page *page, size_t offset, size_t size,
289 enum dma_data_direction dir,289 enum dma_data_direction dir, unsigned long attrs)
290 unsigned long attrs)
291{290{
292 const struct dma_map_ops *ops = get_dma_ops(dev);291 const struct dma_map_ops *ops = get_dma_ops(dev);
293 dma_addr_t addr;292 dma_addr_t addr;
294 293
295 BUG_ON(!valid_dma_direction(dir));294 BUG_ON(!valid_dma_direction(dir));
296 debug_dma_map_single(dev, ptr, size);
297 if (dma_is_direct(ops))295 if (dma_is_direct(ops))
298 addr = dma_direct_map_page(dev, virt_to_page(ptr),296 addr = dma_direct_map_page(dev, page, offset, size, dir, attrs);
299 offset_in_page(ptr), size, dir, attrs);
300 else297 else
301 addr = ops->map_page(dev, virt_to_page(ptr),298 addr = ops->map_page(dev, page, offset, size, dir, attrs);
302 offset_in_page(ptr), size, dir, attrs);299 debug_dma_map_page(dev, page, offset, size, dir, addr);
303 debug_dma_map_page(dev, virt_to_page(ptr),300
304 offset_in_page(ptr), size,
305 dir, addr, true);
306 return addr;301 return addr;
307}302}
308 303
309static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,304static inline void dma_unmap_page_attrs(struct device *dev, dma_addr_t addr,
310 size_t size,305 size_t size, enum dma_data_direction dir, unsigned long attrs)
311 enum dma_data_direction dir,
312 unsigned long attrs)
313{306{
314 const struct dma_map_ops *ops = get_dma_ops(dev);307 const struct dma_map_ops *ops = get_dma_ops(dev);
315 308
@@ -318,13 +311,7 @@ static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr, · 2 unmodified lines
318 dma_direct_unmap_page(dev, addr, size, dir, attrs);311 dma_direct_unmap_page(dev, addr, size, dir, attrs);
319 else if (ops->unmap_page)312 else if (ops->unmap_page)
320 ops->unmap_page(dev, addr, size, dir, attrs);313 ops->unmap_page(dev, addr, size, dir, attrs);
321 debug_dma_unmap_page(dev, addr, size, dir, true);314 debug_dma_unmap_page(dev, addr, size, dir);
322}
323
324static inline void dma_unmap_page_attrs(struct device *dev, dma_addr_t addr,
325 size_t size, enum dma_data_direction dir, unsigned long attrs)
326{
327 return dma_unmap_single_attrs(dev, addr, size, dir, attrs);
328}315}
329 316
330/*317/*
@@ -363,25 +350,6 @@ static inline void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg · 32 unmodified lines
363 ops->unmap_sg(dev, sg, nents, dir, attrs);350 ops->unmap_sg(dev, sg, nents, dir, attrs);
364}351}
365 352
366static inline dma_addr_t dma_map_page_attrs(struct device *dev,
367 struct page *page,
368 size_t offset, size_t size,
369 enum dma_data_direction dir,
370 unsigned long attrs)
371{
372 const struct dma_map_ops *ops = get_dma_ops(dev);
373 dma_addr_t addr;
374
375 BUG_ON(!valid_dma_direction(dir));
376 if (dma_is_direct(ops))
377 addr = dma_direct_map_page(dev, page, offset, size, dir, attrs);
378 else
379 addr = ops->map_page(dev, page, offset, size, dir, attrs);
380 debug_dma_map_page(dev, page, offset, size, dir, addr, false);
381
382 return addr;
383}
384
385static inline dma_addr_t dma_map_resource(struct device *dev,353static inline dma_addr_t dma_map_resource(struct device *dev,
386 phys_addr_t phys_addr,354 phys_addr_t phys_addr,
387 size_t size,355 size_t size,
@@ -488,6 +456,20 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, · 100 unmodified lines
488 456
489}457}
490 458
459static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
460 size_t size, enum dma_data_direction dir, unsigned long attrs)
461{
462 debug_dma_map_single(dev, ptr, size);
463 return dma_map_page_attrs(dev, virt_to_page(ptr), offset_in_page(ptr),
464 size, dir, attrs);
465}
466
467static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
468 size_t size, enum dma_data_direction dir, unsigned long attrs)
469{
470 return dma_unmap_page_attrs(dev, addr, size, dir, attrs);
471}
472
491#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, 0)473#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, 0)
492#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, 0)474#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, 0)
493#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, 0)475#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, 0)