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 c2550980e1
commit 42447ab02f
2 changed files with 47 additions and 0 deletions

View File

@ -29,6 +29,7 @@
#include <linux/idr.h>
#include <linux/notifier.h>
#include <linux/err.h>
#include <linux/scatterlist.h>
static struct kset *iommu_group_kset;
static struct ida iommu_group_ida;
@ -901,6 +902,30 @@ void iommu_domain_window_disable(struct iommu_domain *domain, u32 wnd_nr)
}
EXPORT_SYMBOL_GPL(iommu_domain_window_disable);
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);
static int __init iommu_init(void)
{
iommu_group_kset = kset_create_and_add("iommu_groups",

View File

@ -22,6 +22,7 @@
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/types.h>
#include <linux/scatterlist.h>
#define IOMMU_READ (1)
#define IOMMU_WRITE (2)
@ -92,6 +93,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, dma_addr_t iova);
int (*domain_has_cap)(struct iommu_domain *domain,
unsigned long cap);
@ -135,6 +140,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, dma_addr_t iova);
extern int iommu_domain_has_cap(struct iommu_domain *domain,
unsigned long cap);
@ -268,6 +277,19 @@ static inline void iommu_domain_window_disable(struct iommu_domain *domain,
{
}
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, dma_addr_t iova)
{
return 0;