Commit 2e05ea5c authored by Christoph Hellwig's avatar Christoph Hellwig

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.

Fixes: 7f0fee24 ("dma-mapping: merge dma_unmap_page_attrs and dma_unmap_single_attrs")
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Tested-by: default avatarLABBE Corentin <clabbe.montjoie@gmail.com>
parent 96d4f267
...@@ -35,13 +35,12 @@ extern void debug_dma_map_single(struct device *dev, const void *addr, ...@@ -35,13 +35,12 @@ extern void debug_dma_map_single(struct device *dev, const void *addr,
extern void debug_dma_map_page(struct device *dev, struct page *page, extern void debug_dma_map_page(struct device *dev, struct page *page,
size_t offset, size_t size, size_t offset, size_t size,
int direction, dma_addr_t dma_addr, int direction, dma_addr_t dma_addr);
bool map_single);
extern void debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr); extern void debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
extern void debug_dma_unmap_page(struct device *dev, dma_addr_t addr, extern void debug_dma_unmap_page(struct device *dev, dma_addr_t addr,
size_t size, int direction, bool map_single); size_t size, int direction);
extern void debug_dma_map_sg(struct device *dev, struct scatterlist *sg, extern void debug_dma_map_sg(struct device *dev, struct scatterlist *sg,
int nents, int mapped_ents, int direction); int nents, int mapped_ents, int direction);
...@@ -95,8 +94,7 @@ static inline void debug_dma_map_single(struct device *dev, const void *addr, ...@@ -95,8 +94,7 @@ static inline void debug_dma_map_single(struct device *dev, const void *addr,
static inline void debug_dma_map_page(struct device *dev, struct page *page, static inline void debug_dma_map_page(struct device *dev, struct page *page,
size_t offset, size_t size, size_t offset, size_t size,
int direction, dma_addr_t dma_addr, int direction, dma_addr_t dma_addr)
bool map_single)
{ {
} }
...@@ -106,8 +104,7 @@ static inline void debug_dma_mapping_error(struct device *dev, ...@@ -106,8 +104,7 @@ static inline void debug_dma_mapping_error(struct device *dev,
} }
static inline void debug_dma_unmap_page(struct device *dev, dma_addr_t addr, static inline void debug_dma_unmap_page(struct device *dev, dma_addr_t addr,
size_t size, int direction, size_t size, int direction)
bool map_single)
{ {
} }
......
...@@ -284,32 +284,25 @@ static inline void dma_direct_sync_sg_for_cpu(struct device *dev, ...@@ -284,32 +284,25 @@ static inline void dma_direct_sync_sg_for_cpu(struct device *dev,
} }
#endif #endif
static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr, static inline dma_addr_t dma_map_page_attrs(struct device *dev,
size_t size, struct page *page, size_t offset, size_t size,
enum dma_data_direction dir, enum dma_data_direction dir, unsigned long attrs)
unsigned long attrs)
{ {
const struct dma_map_ops *ops = get_dma_ops(dev); const struct dma_map_ops *ops = get_dma_ops(dev);
dma_addr_t addr; dma_addr_t addr;
BUG_ON(!valid_dma_direction(dir)); BUG_ON(!valid_dma_direction(dir));
debug_dma_map_single(dev, ptr, size);
if (dma_is_direct(ops)) if (dma_is_direct(ops))
addr = dma_direct_map_page(dev, virt_to_page(ptr), addr = dma_direct_map_page(dev, page, offset, size, dir, attrs);
offset_in_page(ptr), size, dir, attrs);
else else
addr = ops->map_page(dev, virt_to_page(ptr), addr = ops->map_page(dev, page, offset, size, dir, attrs);
offset_in_page(ptr), size, dir, attrs); debug_dma_map_page(dev, page, offset, size, dir, addr);
debug_dma_map_page(dev, virt_to_page(ptr),
offset_in_page(ptr), size,
dir, addr, true);
return addr; return addr;
} }
static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr, static inline void dma_unmap_page_attrs(struct device *dev, dma_addr_t addr,
size_t size, size_t size, enum dma_data_direction dir, unsigned long attrs)
enum dma_data_direction dir,
unsigned long attrs)
{ {
const struct dma_map_ops *ops = get_dma_ops(dev); const struct dma_map_ops *ops = get_dma_ops(dev);
...@@ -318,13 +311,7 @@ static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr, ...@@ -318,13 +311,7 @@ static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
dma_direct_unmap_page(dev, addr, size, dir, attrs); dma_direct_unmap_page(dev, addr, size, dir, attrs);
else if (ops->unmap_page) else if (ops->unmap_page)
ops->unmap_page(dev, addr, size, dir, attrs); ops->unmap_page(dev, addr, size, dir, attrs);
debug_dma_unmap_page(dev, addr, size, dir, true); debug_dma_unmap_page(dev, addr, size, dir);
}
static inline void dma_unmap_page_attrs(struct device *dev, dma_addr_t addr,
size_t size, enum dma_data_direction dir, unsigned long attrs)
{
return dma_unmap_single_attrs(dev, addr, size, dir, attrs);
} }
/* /*
...@@ -363,25 +350,6 @@ static inline void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg ...@@ -363,25 +350,6 @@ static inline void dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sg
ops->unmap_sg(dev, sg, nents, dir, attrs); ops->unmap_sg(dev, sg, nents, dir, attrs);
} }
static inline dma_addr_t dma_map_page_attrs(struct device *dev,
struct page *page,
size_t offset, size_t size,
enum dma_data_direction dir,
unsigned long attrs)
{
const struct dma_map_ops *ops = get_dma_ops(dev);
dma_addr_t addr;
BUG_ON(!valid_dma_direction(dir));
if (dma_is_direct(ops))
addr = dma_direct_map_page(dev, page, offset, size, dir, attrs);
else
addr = ops->map_page(dev, page, offset, size, dir, attrs);
debug_dma_map_page(dev, page, offset, size, dir, addr, false);
return addr;
}
static inline dma_addr_t dma_map_resource(struct device *dev, static inline dma_addr_t dma_map_resource(struct device *dev,
phys_addr_t phys_addr, phys_addr_t phys_addr,
size_t size, size_t size,
...@@ -488,6 +456,20 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, ...@@ -488,6 +456,20 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
} }
static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
size_t size, enum dma_data_direction dir, unsigned long attrs)
{
debug_dma_map_single(dev, ptr, size);
return dma_map_page_attrs(dev, virt_to_page(ptr), offset_in_page(ptr),
size, dir, attrs);
}
static inline void dma_unmap_single_attrs(struct device *dev, dma_addr_t addr,
size_t size, enum dma_data_direction dir, unsigned long attrs)
{
return dma_unmap_page_attrs(dev, addr, size, dir, attrs);
}
#define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, 0) #define dma_map_single(d, a, s, r) dma_map_single_attrs(d, a, s, r, 0)
#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, 0) #define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, 0)
#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, 0) #define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, 0)
......
...@@ -49,7 +49,6 @@ ...@@ -49,7 +49,6 @@
enum { enum {
dma_debug_single, dma_debug_single,
dma_debug_page,
dma_debug_sg, dma_debug_sg,
dma_debug_coherent, dma_debug_coherent,
dma_debug_resource, dma_debug_resource,
...@@ -1300,8 +1299,7 @@ void debug_dma_map_single(struct device *dev, const void *addr, ...@@ -1300,8 +1299,7 @@ void debug_dma_map_single(struct device *dev, const void *addr,
EXPORT_SYMBOL(debug_dma_map_single); EXPORT_SYMBOL(debug_dma_map_single);
void debug_dma_map_page(struct device *dev, struct page *page, size_t offset, void debug_dma_map_page(struct device *dev, struct page *page, size_t offset,
size_t size, int direction, dma_addr_t dma_addr, size_t size, int direction, dma_addr_t dma_addr)
bool map_single)
{ {
struct dma_debug_entry *entry; struct dma_debug_entry *entry;
...@@ -1316,7 +1314,7 @@ void debug_dma_map_page(struct device *dev, struct page *page, size_t offset, ...@@ -1316,7 +1314,7 @@ void debug_dma_map_page(struct device *dev, struct page *page, size_t offset,
return; return;
entry->dev = dev; entry->dev = dev;
entry->type = dma_debug_page; entry->type = dma_debug_single;
entry->pfn = page_to_pfn(page); entry->pfn = page_to_pfn(page);
entry->offset = offset, entry->offset = offset,
entry->dev_addr = dma_addr; entry->dev_addr = dma_addr;
...@@ -1324,9 +1322,6 @@ void debug_dma_map_page(struct device *dev, struct page *page, size_t offset, ...@@ -1324,9 +1322,6 @@ void debug_dma_map_page(struct device *dev, struct page *page, size_t offset,
entry->direction = direction; entry->direction = direction;
entry->map_err_type = MAP_ERR_NOT_CHECKED; entry->map_err_type = MAP_ERR_NOT_CHECKED;
if (map_single)
entry->type = dma_debug_single;
check_for_stack(dev, page, offset); check_for_stack(dev, page, offset);
if (!PageHighMem(page)) { if (!PageHighMem(page)) {
...@@ -1378,10 +1373,10 @@ void debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) ...@@ -1378,10 +1373,10 @@ void debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
EXPORT_SYMBOL(debug_dma_mapping_error); EXPORT_SYMBOL(debug_dma_mapping_error);
void debug_dma_unmap_page(struct device *dev, dma_addr_t addr, void debug_dma_unmap_page(struct device *dev, dma_addr_t addr,
size_t size, int direction, bool map_single) size_t size, int direction)
{ {
struct dma_debug_entry ref = { struct dma_debug_entry ref = {
.type = dma_debug_page, .type = dma_debug_single,
.dev = dev, .dev = dev,
.dev_addr = addr, .dev_addr = addr,
.size = size, .size = size,
...@@ -1390,10 +1385,6 @@ void debug_dma_unmap_page(struct device *dev, dma_addr_t addr, ...@@ -1390,10 +1385,6 @@ void debug_dma_unmap_page(struct device *dev, dma_addr_t addr,
if (unlikely(dma_debug_disabled())) if (unlikely(dma_debug_disabled()))
return; return;
if (map_single)
ref.type = dma_debug_single;
check_unmap(&ref); check_unmap(&ref);
} }
EXPORT_SYMBOL(debug_dma_unmap_page); EXPORT_SYMBOL(debug_dma_unmap_page);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment