From 917f69b8b74e0b3283fcd1f2885949847d787d24 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Mon, 5 Jan 2009 23:36:08 +0900 Subject: add dma_mapping_ops for SWIOTLB and SBA IOMMU This is for IA64_HP_ZX1_SWIOTLB. Signed-off-by: FUJITA Tomonori Acked-by: Tony Luck Signed-off-by: Ingo Molnar --- arch/ia64/hp/common/hwsw_iommu.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'arch/ia64/hp/common/hwsw_iommu.c') diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c index 2769dbfd03bf..a40dcdd22eeb 100644 --- a/arch/ia64/hp/common/hwsw_iommu.c +++ b/arch/ia64/hp/common/hwsw_iommu.c @@ -13,8 +13,8 @@ */ #include +#include #include - #include /* swiotlb declarations & definitions: */ @@ -193,3 +193,18 @@ EXPORT_SYMBOL(hwsw_sync_single_for_cpu); EXPORT_SYMBOL(hwsw_sync_single_for_device); EXPORT_SYMBOL(hwsw_sync_sg_for_cpu); EXPORT_SYMBOL(hwsw_sync_sg_for_device); + +struct dma_mapping_ops hwsw_dma_ops = { + .alloc_coherent = hwsw_alloc_coherent, + .free_coherent = hwsw_free_coherent, + .map_single_attrs = hwsw_map_single_attrs, + .unmap_single_attrs = hwsw_unmap_single_attrs, + .map_sg_attrs = hwsw_map_sg_attrs, + .unmap_sg_attrs = hwsw_unmap_sg_attrs, + .sync_single_for_cpu = hwsw_sync_single_for_cpu, + .sync_sg_for_cpu = hwsw_sync_sg_for_cpu, + .sync_single_for_device = hwsw_sync_single_for_device, + .sync_sg_for_device = hwsw_sync_sg_for_device, + .dma_supported_op = hwsw_dma_supported, + .mapping_error = hwsw_dma_mapping_error, +}; -- cgit v1.2.3 From 4d9b977ca674dd40cfc1409a75cb73fca2cee423 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Mon, 5 Jan 2009 23:36:12 +0900 Subject: set up dma_ops appropriately This patch introduces a global pointer, dma_ops, which points to an appropriate dma_mapping_ops that the kernel should use. This is a common way to handle multiple dma_mapping_ops (X86, POWER, and SPARC). dma_ops is set in platform_dma_init. We also set it by hand where machvec_init is callev via subsys_initcall. - IA64_DIG_VTD uses vtd_dma_ops. - IA64_HP_ZX1 uses sba_dma_ops. - IA64_HP_ZX1_SWIOTLB uses hwsw_dma_ops. - IA64_SGI_SN2 uses sn_dma_ops. - The rest use swiotlb_dma_ops. Signed-off-by: FUJITA Tomonori Acked-by: Tony Luck Signed-off-by: Ingo Molnar --- arch/ia64/hp/common/hwsw_iommu.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/ia64/hp/common/hwsw_iommu.c') diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c index a40dcdd22eeb..22145ded58f6 100644 --- a/arch/ia64/hp/common/hwsw_iommu.c +++ b/arch/ia64/hp/common/hwsw_iommu.c @@ -56,9 +56,12 @@ use_swiotlb (struct device *dev) return dev && dev->dma_mask && !hwiommu_dma_supported(dev, *dev->dma_mask); } +struct dma_mapping_ops hwsw_dma_ops; + void __init hwsw_init (void) { + dma_ops = &hwsw_dma_ops; /* default to a smallish 2MB sw I/O TLB */ if (swiotlb_late_init_with_default_size (2 * (1<<20)) != 0) { #ifdef CONFIG_IA64_GENERIC -- cgit v1.2.3 From fad6a029c4afa499dddd8e9ff70264bb977ea7bf Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Mon, 5 Jan 2009 23:36:14 +0900 Subject: remove dma operations in struct ia64_machine_vector We don't need dma operation hooks in struct ia64_machine_vector now. This also removes unused ia64_mv_dma_* typedefs. Signed-off-by: FUJITA Tomonori Acked-by: Tony Luck Signed-off-by: Ingo Molnar --- arch/ia64/hp/common/hwsw_iommu.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'arch/ia64/hp/common/hwsw_iommu.c') diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c index 22145ded58f6..5cf750e1fddc 100644 --- a/arch/ia64/hp/common/hwsw_iommu.c +++ b/arch/ia64/hp/common/hwsw_iommu.c @@ -22,14 +22,18 @@ extern int swiotlb_late_init_with_default_size (size_t size); /* hwiommu declarations & definitions: */ -extern ia64_mv_dma_alloc_coherent sba_alloc_coherent; -extern ia64_mv_dma_free_coherent sba_free_coherent; -extern ia64_mv_dma_map_single_attrs sba_map_single_attrs; -extern ia64_mv_dma_unmap_single_attrs sba_unmap_single_attrs; -extern ia64_mv_dma_map_sg_attrs sba_map_sg_attrs; -extern ia64_mv_dma_unmap_sg_attrs sba_unmap_sg_attrs; -extern ia64_mv_dma_supported sba_dma_supported; -extern ia64_mv_dma_mapping_error sba_dma_mapping_error; +extern void *sba_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t); +extern void sba_free_coherent (struct device *, size_t, void *, dma_addr_t); +extern dma_addr_t sba_map_single_attrs(struct device *, void *, size_t, int, + struct dma_attrs *); +extern void sba_unmap_single_attrs(struct device *, dma_addr_t, size_t, int, + struct dma_attrs *); +extern int sba_map_sg_attrs(struct device *, struct scatterlist *, int, int, + struct dma_attrs *); +extern void sba_unmap_sg_attrs(struct device *, struct scatterlist *, int, int, + struct dma_attrs *); +extern int sba_dma_supported (struct device *, u64); +extern int sba_dma_mapping_error(struct device *, dma_addr_t); #define hwiommu_alloc_coherent sba_alloc_coherent #define hwiommu_free_coherent sba_free_coherent -- cgit v1.2.3 From c7b3aee8af5bd0d73d5779a4ad82a1496771d3ef Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Mon, 5 Jan 2009 23:36:17 +0900 Subject: remove hwsw_dma_ops This removes remove hwsw_dma_ops (and hwsw_* functions). hwsw_dma_get_ops can select swiotlb_dma_ops and sba_dma_ops appropriately. Signed-off-by: FUJITA Tomonori Acked-by: Tony Luck Signed-off-by: Ingo Molnar --- arch/ia64/hp/common/hwsw_iommu.c | 183 +++------------------------------------ 1 file changed, 12 insertions(+), 171 deletions(-) (limited to 'arch/ia64/hp/common/hwsw_iommu.c') diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c index 5cf750e1fddc..e5bbeba77810 100644 --- a/arch/ia64/hp/common/hwsw_iommu.c +++ b/arch/ia64/hp/common/hwsw_iommu.c @@ -17,55 +17,33 @@ #include #include +extern struct dma_mapping_ops sba_dma_ops, swiotlb_dma_ops; + /* swiotlb declarations & definitions: */ extern int swiotlb_late_init_with_default_size (size_t size); -/* hwiommu declarations & definitions: */ - -extern void *sba_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t); -extern void sba_free_coherent (struct device *, size_t, void *, dma_addr_t); -extern dma_addr_t sba_map_single_attrs(struct device *, void *, size_t, int, - struct dma_attrs *); -extern void sba_unmap_single_attrs(struct device *, dma_addr_t, size_t, int, - struct dma_attrs *); -extern int sba_map_sg_attrs(struct device *, struct scatterlist *, int, int, - struct dma_attrs *); -extern void sba_unmap_sg_attrs(struct device *, struct scatterlist *, int, int, - struct dma_attrs *); -extern int sba_dma_supported (struct device *, u64); -extern int sba_dma_mapping_error(struct device *, dma_addr_t); - -#define hwiommu_alloc_coherent sba_alloc_coherent -#define hwiommu_free_coherent sba_free_coherent -#define hwiommu_map_single_attrs sba_map_single_attrs -#define hwiommu_unmap_single_attrs sba_unmap_single_attrs -#define hwiommu_map_sg_attrs sba_map_sg_attrs -#define hwiommu_unmap_sg_attrs sba_unmap_sg_attrs -#define hwiommu_dma_supported sba_dma_supported -#define hwiommu_dma_mapping_error sba_dma_mapping_error -#define hwiommu_sync_single_for_cpu machvec_dma_sync_single -#define hwiommu_sync_sg_for_cpu machvec_dma_sync_sg -#define hwiommu_sync_single_for_device machvec_dma_sync_single -#define hwiommu_sync_sg_for_device machvec_dma_sync_sg - - /* * Note: we need to make the determination of whether or not to use * the sw I/O TLB based purely on the device structure. Anything else * would be unreliable or would be too intrusive. */ -static inline int -use_swiotlb (struct device *dev) +static inline int use_swiotlb(struct device *dev) { - return dev && dev->dma_mask && !hwiommu_dma_supported(dev, *dev->dma_mask); + return dev && dev->dma_mask && + !sba_dma_ops.dma_supported_op(dev, *dev->dma_mask); } -struct dma_mapping_ops hwsw_dma_ops; +struct dma_mapping_ops *hwsw_dma_get_ops(struct device *dev) +{ + if (use_swiotlb(dev)) + return &swiotlb_dma_ops; + return &sba_dma_ops; +} +EXPORT_SYMBOL(hwsw_dma_get_ops); void __init hwsw_init (void) { - dma_ops = &hwsw_dma_ops; /* default to a smallish 2MB sw I/O TLB */ if (swiotlb_late_init_with_default_size (2 * (1<<20)) != 0) { #ifdef CONFIG_IA64_GENERIC @@ -78,140 +56,3 @@ hwsw_init (void) #endif } } - -void * -hwsw_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags) -{ - if (use_swiotlb(dev)) - return swiotlb_alloc_coherent(dev, size, dma_handle, flags); - else - return hwiommu_alloc_coherent(dev, size, dma_handle, flags); -} - -void -hwsw_free_coherent (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle) -{ - if (use_swiotlb(dev)) - swiotlb_free_coherent(dev, size, vaddr, dma_handle); - else - hwiommu_free_coherent(dev, size, vaddr, dma_handle); -} - -dma_addr_t -hwsw_map_single_attrs(struct device *dev, void *addr, size_t size, int dir, - struct dma_attrs *attrs) -{ - if (use_swiotlb(dev)) - return swiotlb_map_single_attrs(dev, addr, size, dir, attrs); - else - return hwiommu_map_single_attrs(dev, addr, size, dir, attrs); -} -EXPORT_SYMBOL(hwsw_map_single_attrs); - -void -hwsw_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, - int dir, struct dma_attrs *attrs) -{ - if (use_swiotlb(dev)) - return swiotlb_unmap_single_attrs(dev, iova, size, dir, attrs); - else - return hwiommu_unmap_single_attrs(dev, iova, size, dir, attrs); -} -EXPORT_SYMBOL(hwsw_unmap_single_attrs); - -int -hwsw_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, - int dir, struct dma_attrs *attrs) -{ - if (use_swiotlb(dev)) - return swiotlb_map_sg_attrs(dev, sglist, nents, dir, attrs); - else - return hwiommu_map_sg_attrs(dev, sglist, nents, dir, attrs); -} -EXPORT_SYMBOL(hwsw_map_sg_attrs); - -void -hwsw_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, - int dir, struct dma_attrs *attrs) -{ - if (use_swiotlb(dev)) - return swiotlb_unmap_sg_attrs(dev, sglist, nents, dir, attrs); - else - return hwiommu_unmap_sg_attrs(dev, sglist, nents, dir, attrs); -} -EXPORT_SYMBOL(hwsw_unmap_sg_attrs); - -void -hwsw_sync_single_for_cpu (struct device *dev, dma_addr_t addr, size_t size, int dir) -{ - if (use_swiotlb(dev)) - swiotlb_sync_single_for_cpu(dev, addr, size, dir); - else - hwiommu_sync_single_for_cpu(dev, addr, size, dir); -} - -void -hwsw_sync_sg_for_cpu (struct device *dev, struct scatterlist *sg, int nelems, int dir) -{ - if (use_swiotlb(dev)) - swiotlb_sync_sg_for_cpu(dev, sg, nelems, dir); - else - hwiommu_sync_sg_for_cpu(dev, sg, nelems, dir); -} - -void -hwsw_sync_single_for_device (struct device *dev, dma_addr_t addr, size_t size, int dir) -{ - if (use_swiotlb(dev)) - swiotlb_sync_single_for_device(dev, addr, size, dir); - else - hwiommu_sync_single_for_device(dev, addr, size, dir); -} - -void -hwsw_sync_sg_for_device (struct device *dev, struct scatterlist *sg, int nelems, int dir) -{ - if (use_swiotlb(dev)) - swiotlb_sync_sg_for_device(dev, sg, nelems, dir); - else - hwiommu_sync_sg_for_device(dev, sg, nelems, dir); -} - -int -hwsw_dma_supported (struct device *dev, u64 mask) -{ - if (hwiommu_dma_supported(dev, mask)) - return 1; - return swiotlb_dma_supported(dev, mask); -} - -int -hwsw_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) -{ - return hwiommu_dma_mapping_error(dev, dma_addr) || - swiotlb_dma_mapping_error(dev, dma_addr); -} - -EXPORT_SYMBOL(hwsw_dma_mapping_error); -EXPORT_SYMBOL(hwsw_dma_supported); -EXPORT_SYMBOL(hwsw_alloc_coherent); -EXPORT_SYMBOL(hwsw_free_coherent); -EXPORT_SYMBOL(hwsw_sync_single_for_cpu); -EXPORT_SYMBOL(hwsw_sync_single_for_device); -EXPORT_SYMBOL(hwsw_sync_sg_for_cpu); -EXPORT_SYMBOL(hwsw_sync_sg_for_device); - -struct dma_mapping_ops hwsw_dma_ops = { - .alloc_coherent = hwsw_alloc_coherent, - .free_coherent = hwsw_free_coherent, - .map_single_attrs = hwsw_map_single_attrs, - .unmap_single_attrs = hwsw_unmap_single_attrs, - .map_sg_attrs = hwsw_map_sg_attrs, - .unmap_sg_attrs = hwsw_unmap_sg_attrs, - .sync_single_for_cpu = hwsw_sync_single_for_cpu, - .sync_sg_for_cpu = hwsw_sync_sg_for_cpu, - .sync_single_for_device = hwsw_sync_single_for_device, - .sync_sg_for_device = hwsw_sync_sg_for_device, - .dma_supported_op = hwsw_dma_supported, - .mapping_error = hwsw_dma_mapping_error, -}; -- cgit v1.2.3 From 160c1d8e40866edfeae7d68816b7005d70acf391 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Mon, 5 Jan 2009 23:59:02 +0900 Subject: x86, ia64: convert to use generic dma_map_ops struct This converts X86 and IA64 to use include/linux/dma-mapping.h. It's a bit large but pretty boring. The major change for X86 is converting 'int dir' to 'enum dma_data_direction dir' in DMA mapping operations. The major changes for IA64 is using map_page and unmap_page instead of map_single and unmap_single. Signed-off-by: FUJITA Tomonori Acked-by: Tony Luck Signed-off-by: Ingo Molnar --- arch/ia64/hp/common/hwsw_iommu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/ia64/hp/common/hwsw_iommu.c') diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c index e5bbeba77810..e4a80d82e3d8 100644 --- a/arch/ia64/hp/common/hwsw_iommu.c +++ b/arch/ia64/hp/common/hwsw_iommu.c @@ -17,7 +17,7 @@ #include #include -extern struct dma_mapping_ops sba_dma_ops, swiotlb_dma_ops; +extern struct dma_map_ops sba_dma_ops, swiotlb_dma_ops; /* swiotlb declarations & definitions: */ extern int swiotlb_late_init_with_default_size (size_t size); @@ -30,10 +30,10 @@ extern int swiotlb_late_init_with_default_size (size_t size); static inline int use_swiotlb(struct device *dev) { return dev && dev->dma_mask && - !sba_dma_ops.dma_supported_op(dev, *dev->dma_mask); + !sba_dma_ops.dma_supported(dev, *dev->dma_mask); } -struct dma_mapping_ops *hwsw_dma_get_ops(struct device *dev) +struct dma_map_ops *hwsw_dma_get_ops(struct device *dev) { if (use_swiotlb(dev)) return &swiotlb_dma_ops; -- cgit v1.2.3