[PATCH v2 2/4] dma-mapping: Add devm_ interface for dma_map_single_attrs()

From: Eli Billauer
Date: Sun Jun 01 2014 - 03:11:12 EST


dmam_map_single_attrs() and dmam_unmap_single_attrs() replace the non-*_attrs
functions, which are implemented as defines instead.

The case of a non-NULL @attrs parameter has not been tested.

Suggested-by: Tejun Heo <tj@xxxxxxxxxx>
Signed-off-by: Eli Billauer <eli.billauer@xxxxxxxxx>
---
Documentation/driver-model/devres.txt | 2 +
drivers/base/dma-mapping.c | 46 +++++++++++++++++++++--------
include/asm-generic/dma-mapping-common.h | 3 ++
include/linux/dma-mapping.h | 12 ++++---
4 files changed, 45 insertions(+), 18 deletions(-)

diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index 13b8be0..2112a00 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -268,6 +268,8 @@ DMA
dmam_pool_destroy()
dmam_map_single()
dmam_unmap_single()
+ dmam_map_single_attrs()
+ dmam_unmap_single_attrs()

PCI
pcim_enable_device() : after success, all PCI ops become managed
diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
index f76ea0f..b24ae17 100644
--- a/drivers/base/dma-mapping.c
+++ b/drivers/base/dma-mapping.c
@@ -11,6 +11,7 @@
#include <linux/export.h>
#include <linux/gfp.h>
#include <asm-generic/dma-coherent.h>
+#include <linux/slab.h>

/*
* Managed DMA API
@@ -20,6 +21,7 @@ struct dma_devres {
void *vaddr;
dma_addr_t dma_handle;
enum dma_data_direction direction;
+ struct dma_attrs *attrs;
};

static void dmam_coherent_release(struct device *dev, void *res)
@@ -285,18 +287,22 @@ static void dmam_map_single_release(struct device *dev, void *res)
{
struct dma_devres *this = res;

- dma_unmap_single(dev, this->dma_handle, this->size, this->direction);
+ dma_unmap_single_attrs(dev, this->dma_handle, this->size,
+ this->direction, this->attrs);
+
+ kfree(this->attrs);
}

/**
- * dmam_map_single - Managed dma_map_single()
+ * dmam_map_single_attrs - Managed dma_map_single_attrs()
* @dev: Device to map DMA region for
* @ptr: Pointer to region
* @size: Size to map
* @direction: The mapping's direction
+ * @attrs: Attributes associated with the DMA mapping
* @ret_dma_handle: Pointer to return the value of the DMA handle
*
- * Managed dma_map_single(). The region mapped using this
+ * Managed dma_map_single_attrs(). The region mapped using this
* function will be automatically unmapped on driver detach.
*
* RETURNED VALUE:
@@ -304,9 +310,11 @@ static void dmam_map_single_release(struct device *dev, void *res)
* -EIO if the DMA mapping failed
* -ENOMEM on failure to allocate memory for internal data structure
*/
-int dmam_map_single(struct device *dev, void *ptr, size_t size,
- enum dma_data_direction direction,
- dma_addr_t *ret_dma_handle)
+
+int dmam_map_single_attrs(struct device *dev, void *ptr, size_t size,
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs,
+ dma_addr_t *ret_dma_handle)

{
struct dma_devres *dr;
@@ -316,8 +324,18 @@ int dmam_map_single(struct device *dev, void *ptr, size_t size,
if (!dr)
return -ENOMEM;

- dma_handle = dma_map_single(dev, ptr, size, direction);
+ if (attrs) {
+ dr->attrs = kmemdup(attrs, sizeof(*attrs), GFP_KERNEL);
+ if (!dr->attrs) {
+ devres_free(dr);
+ return -ENOMEM;
+ }
+ } else
+ dr->attrs = NULL;
+
+ dma_handle = dma_map_single_attrs(dev, ptr, size, direction, attrs);
if (dma_mapping_error(dev, dma_handle)) {
+ kfree(dr->attrs);
devres_free(dr);
return -EIO;
}
@@ -333,23 +351,25 @@ int dmam_map_single(struct device *dev, void *ptr, size_t size,

return 0; /* Success */
}
-EXPORT_SYMBOL(dmam_map_single);
+EXPORT_SYMBOL(dmam_map_single_attrs);

/**
- * dmam_unmap_single - Managed dma_unmap_single()
+ * dmam_unmap_single_attrs - Managed dma_unmap_single_attrs()
* @dev: Device to map DMA region for
* @dma_handle: DMA handle of the region to unmap
* @size: Size to unmap
* @direction: The mapping's direction
+ * @attrs: Attributes associated with the DMA mapping.
*
- * Managed dma_unmap_single().
+ * Managed dma_unmap_single_attrs().
*/
-void dmam_unmap_single(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction direction)
+void dmam_unmap_single_attrs(struct device *dev, dma_addr_t dma_handle,
+ size_t size, enum dma_data_direction direction,
+ struct dma_attrs *attrs)
{
struct dma_devres match_data = { size, NULL, dma_handle, direction };

WARN_ON(devres_release(dev, dmam_map_single_release, dmam_map_match,
&match_data));
}
-EXPORT_SYMBOL(dmam_unmap_single);
+EXPORT_SYMBOL(dmam_unmap_single_attrs);
diff --git a/include/asm-generic/dma-mapping-common.h b/include/asm-generic/dma-mapping-common.h
index de8bf89..1af27b3 100644
--- a/include/asm-generic/dma-mapping-common.h
+++ b/include/asm-generic/dma-mapping-common.h
@@ -175,6 +175,9 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
#define dma_unmap_single(d, a, s, r) dma_unmap_single_attrs(d, a, s, r, NULL)
#define dma_map_sg(d, s, n, r) dma_map_sg_attrs(d, s, n, r, NULL)
#define dma_unmap_sg(d, s, n, r) dma_unmap_sg_attrs(d, s, n, r, NULL)
+#define dmam_map_single(d, a, s, r, p) \
+ dmam_map_single_attrs(d, a, s, r, NULL, p)
+#define dmam_unmap_single(d, a, s, r) dmam_unmap_single_attrs(d, a, s, r, NULL)

extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
void *cpu_addr, dma_addr_t dma_addr, size_t size);
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index cad63de..4ca9134 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -233,11 +233,13 @@ static inline void dmam_release_declared_memory(struct device *dev)
{
}
#endif /* ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY */
-int dmam_map_single(struct device *dev, void *ptr, size_t size,
- enum dma_data_direction direction,
- dma_addr_t *ret_dma_handle);
-void dmam_unmap_single(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction direction);
+int dmam_map_single_attrs(struct device *dev, void *ptr, size_t size,
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs,
+ dma_addr_t *ret_dma_handle);
+void dmam_unmap_single_attrs(struct device *dev, dma_addr_t dma_handle,
+ size_t size, enum dma_data_direction direction,
+ struct dma_attrs *attrs);
#ifndef CONFIG_HAVE_DMA_ATTRS
struct dma_attrs;

--
1.7.2.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/