drivers: iommu: Add map/unmap range ops

Add IOMMU ops functions to allow mapping and unmapping
whole ranges of address space based on a scatterlist.

Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
This commit is contained in:
Stepan Moskovchenko
2011-08-11 19:32:27 -07:00
committed by Stephen Boyd
parent 9263fbdb9c
commit 7a9d3fc77f
2 changed files with 47 additions and 0 deletions

View File

@@ -26,6 +26,7 @@
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/iommu.h>
#include <linux/scatterlist.h>
static ssize_t show_iommu_group(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -333,6 +334,30 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)
}
EXPORT_SYMBOL_GPL(iommu_unmap);
int iommu_map_range(struct iommu_domain *domain, unsigned int iova,
struct scatterlist *sg, unsigned int len, int prot)
{
if (unlikely(domain->ops->map_range == NULL))
return -ENODEV;
BUG_ON(iova & (~PAGE_MASK));
return domain->ops->map_range(domain, iova, sg, len, prot);
}
EXPORT_SYMBOL_GPL(iommu_map_range);
int iommu_unmap_range(struct iommu_domain *domain, unsigned int iova,
unsigned int len)
{
if (unlikely(domain->ops->unmap_range == NULL))
return -ENODEV;
BUG_ON(iova & (~PAGE_MASK));
return domain->ops->unmap_range(domain, iova, len);
}
EXPORT_SYMBOL_GPL(iommu_unmap_range);
int iommu_device_group(struct device *dev, unsigned int *groupid)
{
if (iommu_present(dev->bus) && dev->bus->iommu_ops->device_group)

View File

@@ -20,6 +20,7 @@
#define __LINUX_IOMMU_H
#include <linux/errno.h>
#include <linux/scatterlist.h>
#define IOMMU_READ (1)
#define IOMMU_WRITE (2)
@@ -70,6 +71,10 @@ struct iommu_ops {
phys_addr_t paddr, size_t size, int prot);
size_t (*unmap)(struct iommu_domain *domain, unsigned long iova,
size_t size);
int (*map_range)(struct iommu_domain *domain, unsigned int iova,
struct scatterlist *sg, unsigned int len, int prot);
int (*unmap_range)(struct iommu_domain *domain, unsigned int iova,
unsigned int len);
phys_addr_t (*iova_to_phys)(struct iommu_domain *domain,
unsigned long iova);
int (*domain_has_cap)(struct iommu_domain *domain,
@@ -90,6 +95,10 @@ extern int iommu_map(struct iommu_domain *domain, unsigned long iova,
phys_addr_t paddr, size_t size, int prot);
extern size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova,
size_t size);
extern int iommu_map_range(struct iommu_domain *domain, unsigned int iova,
struct scatterlist *sg, unsigned int len, int prot);
extern int iommu_unmap_range(struct iommu_domain *domain, unsigned int iova,
unsigned int len);
extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,
unsigned long iova);
extern int iommu_domain_has_cap(struct iommu_domain *domain,
@@ -178,6 +187,19 @@ static inline int iommu_unmap(struct iommu_domain *domain, unsigned long iova,
return -ENODEV;
}
static inline int iommu_map_range(struct iommu_domain *domain,
unsigned int iova, struct scatterlist *sg,
unsigned int len, int prot)
{
return -ENODEV;
}
static inline int iommu_unmap_range(struct iommu_domain *domain,
unsigned int iova, unsigned int len)
{
return -ENODEV;
}
static inline phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,
unsigned long iova)
{