diff options
Diffstat (limited to 'arch/ia64/hp/common/sba_iommu.c')
-rw-r--r-- | arch/ia64/hp/common/sba_iommu.c | 79 |
1 files changed, 56 insertions, 23 deletions
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index 6d5e6c5630e3..56ceb68eb99d 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/bitops.h> /* hweight64() */ | 36 | #include <linux/bitops.h> /* hweight64() */ |
37 | #include <linux/crash_dump.h> | 37 | #include <linux/crash_dump.h> |
38 | #include <linux/iommu-helper.h> | 38 | #include <linux/iommu-helper.h> |
39 | #include <linux/dma-mapping.h> | ||
39 | 40 | ||
40 | #include <asm/delay.h> /* ia64_get_itc() */ | 41 | #include <asm/delay.h> /* ia64_get_itc() */ |
41 | #include <asm/io.h> | 42 | #include <asm/io.h> |
@@ -908,11 +909,13 @@ sba_mark_invalid(struct ioc *ioc, dma_addr_t iova, size_t byte_cnt) | |||
908 | * | 909 | * |
909 | * See Documentation/PCI/PCI-DMA-mapping.txt | 910 | * See Documentation/PCI/PCI-DMA-mapping.txt |
910 | */ | 911 | */ |
911 | dma_addr_t | 912 | static dma_addr_t sba_map_page(struct device *dev, struct page *page, |
912 | sba_map_single_attrs(struct device *dev, void *addr, size_t size, int dir, | 913 | unsigned long poff, size_t size, |
913 | struct dma_attrs *attrs) | 914 | enum dma_data_direction dir, |
915 | struct dma_attrs *attrs) | ||
914 | { | 916 | { |
915 | struct ioc *ioc; | 917 | struct ioc *ioc; |
918 | void *addr = page_address(page) + poff; | ||
916 | dma_addr_t iovp; | 919 | dma_addr_t iovp; |
917 | dma_addr_t offset; | 920 | dma_addr_t offset; |
918 | u64 *pdir_start; | 921 | u64 *pdir_start; |
@@ -990,7 +993,14 @@ sba_map_single_attrs(struct device *dev, void *addr, size_t size, int dir, | |||
990 | #endif | 993 | #endif |
991 | return SBA_IOVA(ioc, iovp, offset); | 994 | return SBA_IOVA(ioc, iovp, offset); |
992 | } | 995 | } |
993 | EXPORT_SYMBOL(sba_map_single_attrs); | 996 | |
997 | static dma_addr_t sba_map_single_attrs(struct device *dev, void *addr, | ||
998 | size_t size, enum dma_data_direction dir, | ||
999 | struct dma_attrs *attrs) | ||
1000 | { | ||
1001 | return sba_map_page(dev, virt_to_page(addr), | ||
1002 | (unsigned long)addr & ~PAGE_MASK, size, dir, attrs); | ||
1003 | } | ||
994 | 1004 | ||
995 | #ifdef ENABLE_MARK_CLEAN | 1005 | #ifdef ENABLE_MARK_CLEAN |
996 | static SBA_INLINE void | 1006 | static SBA_INLINE void |
@@ -1026,8 +1036,8 @@ sba_mark_clean(struct ioc *ioc, dma_addr_t iova, size_t size) | |||
1026 | * | 1036 | * |
1027 | * See Documentation/PCI/PCI-DMA-mapping.txt | 1037 | * See Documentation/PCI/PCI-DMA-mapping.txt |
1028 | */ | 1038 | */ |
1029 | void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, | 1039 | static void sba_unmap_page(struct device *dev, dma_addr_t iova, size_t size, |
1030 | int dir, struct dma_attrs *attrs) | 1040 | enum dma_data_direction dir, struct dma_attrs *attrs) |
1031 | { | 1041 | { |
1032 | struct ioc *ioc; | 1042 | struct ioc *ioc; |
1033 | #if DELAYED_RESOURCE_CNT > 0 | 1043 | #if DELAYED_RESOURCE_CNT > 0 |
@@ -1094,7 +1104,12 @@ void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, | |||
1094 | spin_unlock_irqrestore(&ioc->res_lock, flags); | 1104 | spin_unlock_irqrestore(&ioc->res_lock, flags); |
1095 | #endif /* DELAYED_RESOURCE_CNT == 0 */ | 1105 | #endif /* DELAYED_RESOURCE_CNT == 0 */ |
1096 | } | 1106 | } |
1097 | EXPORT_SYMBOL(sba_unmap_single_attrs); | 1107 | |
1108 | void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, | ||
1109 | enum dma_data_direction dir, struct dma_attrs *attrs) | ||
1110 | { | ||
1111 | sba_unmap_page(dev, iova, size, dir, attrs); | ||
1112 | } | ||
1098 | 1113 | ||
1099 | /** | 1114 | /** |
1100 | * sba_alloc_coherent - allocate/map shared mem for DMA | 1115 | * sba_alloc_coherent - allocate/map shared mem for DMA |
@@ -1104,7 +1119,7 @@ EXPORT_SYMBOL(sba_unmap_single_attrs); | |||
1104 | * | 1119 | * |
1105 | * See Documentation/PCI/PCI-DMA-mapping.txt | 1120 | * See Documentation/PCI/PCI-DMA-mapping.txt |
1106 | */ | 1121 | */ |
1107 | void * | 1122 | static void * |
1108 | sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags) | 1123 | sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags) |
1109 | { | 1124 | { |
1110 | struct ioc *ioc; | 1125 | struct ioc *ioc; |
@@ -1167,7 +1182,8 @@ sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp | |||
1167 | * | 1182 | * |
1168 | * See Documentation/PCI/PCI-DMA-mapping.txt | 1183 | * See Documentation/PCI/PCI-DMA-mapping.txt |
1169 | */ | 1184 | */ |
1170 | void sba_free_coherent (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle) | 1185 | static void sba_free_coherent (struct device *dev, size_t size, void *vaddr, |
1186 | dma_addr_t dma_handle) | ||
1171 | { | 1187 | { |
1172 | sba_unmap_single_attrs(dev, dma_handle, size, 0, NULL); | 1188 | sba_unmap_single_attrs(dev, dma_handle, size, 0, NULL); |
1173 | free_pages((unsigned long) vaddr, get_order(size)); | 1189 | free_pages((unsigned long) vaddr, get_order(size)); |
@@ -1422,8 +1438,9 @@ sba_coalesce_chunks(struct ioc *ioc, struct device *dev, | |||
1422 | * | 1438 | * |
1423 | * See Documentation/PCI/PCI-DMA-mapping.txt | 1439 | * See Documentation/PCI/PCI-DMA-mapping.txt |
1424 | */ | 1440 | */ |
1425 | int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, | 1441 | static int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist, |
1426 | int dir, struct dma_attrs *attrs) | 1442 | int nents, enum dma_data_direction dir, |
1443 | struct dma_attrs *attrs) | ||
1427 | { | 1444 | { |
1428 | struct ioc *ioc; | 1445 | struct ioc *ioc; |
1429 | int coalesced, filled = 0; | 1446 | int coalesced, filled = 0; |
@@ -1502,7 +1519,6 @@ int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, | |||
1502 | 1519 | ||
1503 | return filled; | 1520 | return filled; |
1504 | } | 1521 | } |
1505 | EXPORT_SYMBOL(sba_map_sg_attrs); | ||
1506 | 1522 | ||
1507 | /** | 1523 | /** |
1508 | * sba_unmap_sg_attrs - unmap Scatter/Gather list | 1524 | * sba_unmap_sg_attrs - unmap Scatter/Gather list |
@@ -1514,8 +1530,9 @@ EXPORT_SYMBOL(sba_map_sg_attrs); | |||
1514 | * | 1530 | * |
1515 | * See Documentation/PCI/PCI-DMA-mapping.txt | 1531 | * See Documentation/PCI/PCI-DMA-mapping.txt |
1516 | */ | 1532 | */ |
1517 | void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, | 1533 | static void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, |
1518 | int nents, int dir, struct dma_attrs *attrs) | 1534 | int nents, enum dma_data_direction dir, |
1535 | struct dma_attrs *attrs) | ||
1519 | { | 1536 | { |
1520 | #ifdef ASSERT_PDIR_SANITY | 1537 | #ifdef ASSERT_PDIR_SANITY |
1521 | struct ioc *ioc; | 1538 | struct ioc *ioc; |
@@ -1551,7 +1568,6 @@ void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, | |||
1551 | #endif | 1568 | #endif |
1552 | 1569 | ||
1553 | } | 1570 | } |
1554 | EXPORT_SYMBOL(sba_unmap_sg_attrs); | ||
1555 | 1571 | ||
1556 | /************************************************************** | 1572 | /************************************************************** |
1557 | * | 1573 | * |
@@ -2064,6 +2080,8 @@ static struct acpi_driver acpi_sba_ioc_driver = { | |||
2064 | }, | 2080 | }, |
2065 | }; | 2081 | }; |
2066 | 2082 | ||
2083 | extern struct dma_map_ops swiotlb_dma_ops; | ||
2084 | |||
2067 | static int __init | 2085 | static int __init |
2068 | sba_init(void) | 2086 | sba_init(void) |
2069 | { | 2087 | { |
@@ -2077,6 +2095,7 @@ sba_init(void) | |||
2077 | * a successful kdump kernel boot is to use the swiotlb. | 2095 | * a successful kdump kernel boot is to use the swiotlb. |
2078 | */ | 2096 | */ |
2079 | if (is_kdump_kernel()) { | 2097 | if (is_kdump_kernel()) { |
2098 | dma_ops = &swiotlb_dma_ops; | ||
2080 | if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0) | 2099 | if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0) |
2081 | panic("Unable to initialize software I/O TLB:" | 2100 | panic("Unable to initialize software I/O TLB:" |
2082 | " Try machvec=dig boot option"); | 2101 | " Try machvec=dig boot option"); |
@@ -2092,6 +2111,7 @@ sba_init(void) | |||
2092 | * If we didn't find something sba_iommu can claim, we | 2111 | * If we didn't find something sba_iommu can claim, we |
2093 | * need to setup the swiotlb and switch to the dig machvec. | 2112 | * need to setup the swiotlb and switch to the dig machvec. |
2094 | */ | 2113 | */ |
2114 | dma_ops = &swiotlb_dma_ops; | ||
2095 | if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0) | 2115 | if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0) |
2096 | panic("Unable to find SBA IOMMU or initialize " | 2116 | panic("Unable to find SBA IOMMU or initialize " |
2097 | "software I/O TLB: Try machvec=dig boot option"); | 2117 | "software I/O TLB: Try machvec=dig boot option"); |
@@ -2138,15 +2158,13 @@ nosbagart(char *str) | |||
2138 | return 1; | 2158 | return 1; |
2139 | } | 2159 | } |
2140 | 2160 | ||
2141 | int | 2161 | static int sba_dma_supported (struct device *dev, u64 mask) |
2142 | sba_dma_supported (struct device *dev, u64 mask) | ||
2143 | { | 2162 | { |
2144 | /* make sure it's at least 32bit capable */ | 2163 | /* make sure it's at least 32bit capable */ |
2145 | return ((mask & 0xFFFFFFFFUL) == 0xFFFFFFFFUL); | 2164 | return ((mask & 0xFFFFFFFFUL) == 0xFFFFFFFFUL); |
2146 | } | 2165 | } |
2147 | 2166 | ||
2148 | int | 2167 | static int sba_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) |
2149 | sba_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | ||
2150 | { | 2168 | { |
2151 | return 0; | 2169 | return 0; |
2152 | } | 2170 | } |
@@ -2176,7 +2194,22 @@ sba_page_override(char *str) | |||
2176 | 2194 | ||
2177 | __setup("sbapagesize=",sba_page_override); | 2195 | __setup("sbapagesize=",sba_page_override); |
2178 | 2196 | ||
2179 | EXPORT_SYMBOL(sba_dma_mapping_error); | 2197 | struct dma_map_ops sba_dma_ops = { |
2180 | EXPORT_SYMBOL(sba_dma_supported); | 2198 | .alloc_coherent = sba_alloc_coherent, |
2181 | EXPORT_SYMBOL(sba_alloc_coherent); | 2199 | .free_coherent = sba_free_coherent, |
2182 | EXPORT_SYMBOL(sba_free_coherent); | 2200 | .map_page = sba_map_page, |
2201 | .unmap_page = sba_unmap_page, | ||
2202 | .map_sg = sba_map_sg_attrs, | ||
2203 | .unmap_sg = sba_unmap_sg_attrs, | ||
2204 | .sync_single_for_cpu = machvec_dma_sync_single, | ||
2205 | .sync_sg_for_cpu = machvec_dma_sync_sg, | ||
2206 | .sync_single_for_device = machvec_dma_sync_single, | ||
2207 | .sync_sg_for_device = machvec_dma_sync_sg, | ||
2208 | .dma_supported = sba_dma_supported, | ||
2209 | .mapping_error = sba_dma_mapping_error, | ||
2210 | }; | ||
2211 | |||
2212 | void sba_dma_init(void) | ||
2213 | { | ||
2214 | dma_ops = &sba_dma_ops; | ||
2215 | } | ||