* [PATCH 1/3] dma-mapping: Add devm_ interface for dma_map_single() @ 2014-05-17 12:22 Eli Billauer 2014-05-17 12:22 ` [PATCH 2/3] dma-mapping: Add devm_ interface for dma_map_single_attrs() Eli Billauer 2014-05-17 12:22 ` [PATCH 3/3] dma-mapping: pci: Add devm_ interface for pci_map_single Eli Billauer 0 siblings, 2 replies; 3+ messages in thread From: Eli Billauer @ 2014-05-17 12:22 UTC (permalink / raw) To: tj; +Cc: devel, gregkh, bhelgaas, linux-kernel, linux-pci, Eli Billauer dmam_map_single() and dmam_unmap_single() are the managed counterparts for the respective dma_* functions. Note that dmam_map_single() returns zero on failure, and not a value to be handled by dma_mapping_error(): The error check is done by dmam_map_single() to avoid the registration of a mapping that failed. Signed-off-by: Eli Billauer <eli.billauer@gmail.com> --- Documentation/driver-model/devres.txt | 2 + drivers/base/dma-mapping.c | 80 +++++++++++++++++++++++++++++++++ include/linux/dma-mapping.h | 5 ++- 3 files changed, 86 insertions(+), 1 deletions(-) diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index e1a2707..13b8be0 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -266,6 +266,8 @@ DMA dmam_declare_coherent_memory() dmam_pool_create() dmam_pool_destroy() + dmam_map_single() + dmam_unmap_single() 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 0ce39a3..db1c496 100644 --- a/drivers/base/dma-mapping.c +++ b/drivers/base/dma-mapping.c @@ -19,6 +19,7 @@ struct dma_devres { size_t size; void *vaddr; dma_addr_t dma_handle; + enum dma_data_direction direction; }; static void dmam_coherent_release(struct device *dev, void *res) @@ -267,3 +268,82 @@ int dma_common_mmap(struct device *dev, struct vm_area_struct *vma, return ret; } EXPORT_SYMBOL(dma_common_mmap); + +static int dmam_map_match(struct device *dev, void *res, void *match_data) +{ + struct dma_devres *this = res, *match = match_data; + + if (this->dma_handle == match->dma_handle) { + WARN_ON(this->size != match->size || + this->direction != match->direction); + return 1; + } + return 0; +} + +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); +} + +/** + * dmam_map_single - Managed dma_map_single() + * @dev: Device to map DMA region for + * @ptr: Pointer to region + * @size: Size to map + * @direction: The mapping's direction + * + * Managed dma_map_single(). The region mapped using this + * function will be automatically unmapped on driver detach. + * + * RETURNS: + * The DMA handle of the mapped region upon success, 0 otherwise. + */ +dma_addr_t dmam_map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction direction) + +{ + struct dma_devres *dr; + dma_addr_t dma_handle; + + dr = devres_alloc(dmam_map_single_release, sizeof(*dr), GFP_KERNEL); + if (!dr) + return 0; + + dma_handle = dma_map_single(dev, ptr, size, direction); + if (dma_mapping_error(dev, dma_handle)) { + devres_free(dr); + return 0; + } + + dr->vaddr = ptr; + dr->dma_handle = dma_handle; + dr->size = size; + dr->direction = direction; + + devres_add(dev, dr); + + return dma_handle; +} +EXPORT_SYMBOL(dmam_map_single); + +/** + * dmam_unmap_single - Managed dma_unmap_single() + * @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 + * + * Managed dma_unmap_single(). + */ +void dmam_unmap_single(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction direction) +{ + 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); diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index fd4aee2..cdb14a8 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -233,7 +233,10 @@ static inline void dmam_release_declared_memory(struct device *dev) { } #endif /* ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY */ - +dma_addr_t dmam_map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction direction); +void dmam_unmap_single(struct device *dev, dma_addr_t dma_handle, + size_t size, enum dma_data_direction direction); #ifndef CONFIG_HAVE_DMA_ATTRS struct dma_attrs; -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 2/3] dma-mapping: Add devm_ interface for dma_map_single_attrs() 2014-05-17 12:22 [PATCH 1/3] dma-mapping: Add devm_ interface for dma_map_single() Eli Billauer @ 2014-05-17 12:22 ` Eli Billauer 2014-05-17 12:22 ` [PATCH 3/3] dma-mapping: pci: Add devm_ interface for pci_map_single Eli Billauer 1 sibling, 0 replies; 3+ messages in thread From: Eli Billauer @ 2014-05-17 12:22 UTC (permalink / raw) To: tj; +Cc: devel, gregkh, bhelgaas, linux-kernel, linux-pci, Eli Billauer 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@kernel.org> Signed-off-by: Eli Billauer <eli.billauer@gmail.com> --- Documentation/driver-model/devres.txt | 2 + drivers/base/dma-mapping.c | 43 +++++++++++++++++++++-------- include/asm-generic/dma-mapping-common.h | 2 + include/linux/dma-mapping.h | 10 ++++--- 4 files changed, 41 insertions(+), 16 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 db1c496..4e80db1 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,24 +287,29 @@ 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 * - * 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. * * RETURNS: * The DMA handle of the mapped region upon success, 0 otherwise. */ -dma_addr_t dmam_map_single(struct device *dev, void *ptr, size_t size, - enum dma_data_direction direction) +dma_addr_t dmam_map_single_attrs(struct device *dev, void *ptr, size_t size, + enum dma_data_direction direction, + struct dma_attrs *attrs) { struct dma_devres *dr; @@ -312,8 +319,18 @@ dma_addr_t dmam_map_single(struct device *dev, void *ptr, size_t size, if (!dr) return 0; - 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 0; + } + } 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 0; } @@ -327,23 +344,25 @@ dma_addr_t dmam_map_single(struct device *dev, void *ptr, size_t size, return dma_handle; } -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..aaa7c68 100644 --- a/include/asm-generic/dma-mapping-common.h +++ b/include/asm-generic/dma-mapping-common.h @@ -175,6 +175,8 @@ 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) dmam_map_single_attrs(d, a, s, r, NULL) +#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 cdb14a8..ba2a403 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -233,10 +233,12 @@ static inline void dmam_release_declared_memory(struct device *dev) { } #endif /* ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY */ -dma_addr_t dmam_map_single(struct device *dev, void *ptr, size_t size, - enum dma_data_direction direction); -void dmam_unmap_single(struct device *dev, dma_addr_t dma_handle, - size_t size, enum dma_data_direction direction); +dma_addr_t dmam_map_single_attrs(struct device *dev, void *ptr, size_t size, + enum dma_data_direction direction, + struct dma_attrs *attrs); +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 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 3/3] dma-mapping: pci: Add devm_ interface for pci_map_single 2014-05-17 12:22 [PATCH 1/3] dma-mapping: Add devm_ interface for dma_map_single() Eli Billauer 2014-05-17 12:22 ` [PATCH 2/3] dma-mapping: Add devm_ interface for dma_map_single_attrs() Eli Billauer @ 2014-05-17 12:22 ` Eli Billauer 1 sibling, 0 replies; 3+ messages in thread From: Eli Billauer @ 2014-05-17 12:22 UTC (permalink / raw) To: tj; +Cc: devel, gregkh, bhelgaas, linux-kernel, linux-pci, Eli Billauer Signed-off-by: Eli Billauer <eli.billauer@gmail.com> --- Documentation/driver-model/devres.txt | 2 ++ include/asm-generic/pci-dma-compat.h | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 0 deletions(-) diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index 2112a00..fea2c69 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -274,6 +274,8 @@ DMA PCI pcim_enable_device() : after success, all PCI ops become managed pcim_pin_device() : keep PCI device enabled after release + pcim_map_single() + pcim_unmap_single() IOMAP devm_ioport_map() diff --git a/include/asm-generic/pci-dma-compat.h b/include/asm-generic/pci-dma-compat.h index 1437b7d..444e598 100644 --- a/include/asm-generic/pci-dma-compat.h +++ b/include/asm-generic/pci-dma-compat.h @@ -113,4 +113,21 @@ static inline int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) } #endif +/* + * Managed DMA API + */ + +static inline dma_addr_t +pcim_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction) +{ + return dmam_map_single(hwdev == NULL ? NULL : &hwdev->dev, ptr, size, (enum dma_data_direction)direction); +} + +static inline void +pcim_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, + size_t size, int direction) +{ + dmam_unmap_single(hwdev == NULL ? NULL : &hwdev->dev, dma_addr, size, (enum dma_data_direction)direction); +} + #endif -- 1.7.2.3 ^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-05-17 12:22 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-05-17 12:22 [PATCH 1/3] dma-mapping: Add devm_ interface for dma_map_single() Eli Billauer 2014-05-17 12:22 ` [PATCH 2/3] dma-mapping: Add devm_ interface for dma_map_single_attrs() Eli Billauer 2014-05-17 12:22 ` [PATCH 3/3] dma-mapping: pci: Add devm_ interface for pci_map_single Eli Billauer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).