Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dma/ia64: update ia64 machvecs, swiotlb.c

Change all ia64 machvecs to use the new dma_*map*_attrs() interfaces.
Implement the old dma_*map_*() interfaces in terms of the corresponding new
interfaces. For ia64/sn, make use of one dma attribute,
DMA_ATTR_WRITE_BARRIER. Introduce swiotlb_*map*_attrs() functions.

Signed-off-by: Arthur Kepner <akepner@sgi.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Jesse Barnes <jbarnes@virtuousgeek.org>
Cc: Jes Sorensen <jes@sgi.com>
Cc: Randy Dunlap <randy.dunlap@oracle.com>
Cc: Roland Dreier <rdreier@cisco.com>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Cc: David Miller <davem@davemloft.net>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Grant Grundler <grundler@parisc-linux.org>
Cc: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Arthur Kepner and committed by
Linus Torvalds
309df0c5 a75b0a2f

+249 -133
+32 -29
arch/ia64/hp/common/hwsw_iommu.c
··· 20 20 extern int swiotlb_late_init_with_default_size (size_t size); 21 21 extern ia64_mv_dma_alloc_coherent swiotlb_alloc_coherent; 22 22 extern ia64_mv_dma_free_coherent swiotlb_free_coherent; 23 - extern ia64_mv_dma_map_single swiotlb_map_single; 24 - extern ia64_mv_dma_unmap_single swiotlb_unmap_single; 25 - extern ia64_mv_dma_map_sg swiotlb_map_sg; 26 - extern ia64_mv_dma_unmap_sg swiotlb_unmap_sg; 23 + extern ia64_mv_dma_map_single_attrs swiotlb_map_single_attrs; 24 + extern ia64_mv_dma_unmap_single_attrs swiotlb_unmap_single_attrs; 25 + extern ia64_mv_dma_map_sg_attrs swiotlb_map_sg_attrs; 26 + extern ia64_mv_dma_unmap_sg_attrs swiotlb_unmap_sg_attrs; 27 27 extern ia64_mv_dma_supported swiotlb_dma_supported; 28 28 extern ia64_mv_dma_mapping_error swiotlb_dma_mapping_error; 29 29 ··· 31 31 32 32 extern ia64_mv_dma_alloc_coherent sba_alloc_coherent; 33 33 extern ia64_mv_dma_free_coherent sba_free_coherent; 34 - extern ia64_mv_dma_map_single sba_map_single; 35 - extern ia64_mv_dma_unmap_single sba_unmap_single; 36 - extern ia64_mv_dma_map_sg sba_map_sg; 37 - extern ia64_mv_dma_unmap_sg sba_unmap_sg; 34 + extern ia64_mv_dma_map_single_attrs sba_map_single_attrs; 35 + extern ia64_mv_dma_unmap_single_attrs sba_unmap_single_attrs; 36 + extern ia64_mv_dma_map_sg_attrs sba_map_sg_attrs; 37 + extern ia64_mv_dma_unmap_sg_attrs sba_unmap_sg_attrs; 38 38 extern ia64_mv_dma_supported sba_dma_supported; 39 39 extern ia64_mv_dma_mapping_error sba_dma_mapping_error; 40 40 41 41 #define hwiommu_alloc_coherent sba_alloc_coherent 42 42 #define hwiommu_free_coherent sba_free_coherent 43 - #define hwiommu_map_single sba_map_single 44 - #define hwiommu_unmap_single sba_unmap_single 45 - #define hwiommu_map_sg sba_map_sg 46 - #define hwiommu_unmap_sg sba_unmap_sg 43 + #define hwiommu_map_single_attrs sba_map_single_attrs 44 + #define hwiommu_unmap_single_attrs sba_unmap_single_attrs 45 + #define hwiommu_map_sg_attrs sba_map_sg_attrs 46 + #define hwiommu_unmap_sg_attrs sba_unmap_sg_attrs 47 47 #define hwiommu_dma_supported sba_dma_supported 48 48 #define hwiommu_dma_mapping_error sba_dma_mapping_error 49 49 #define hwiommu_sync_single_for_cpu machvec_dma_sync_single ··· 98 98 } 99 99 100 100 dma_addr_t 101 - hwsw_map_single (struct device *dev, void *addr, size_t size, int dir) 101 + hwsw_map_single_attrs(struct device *dev, void *addr, size_t size, int dir, 102 + struct dma_attrs *attrs) 102 103 { 103 104 if (use_swiotlb(dev)) 104 - return swiotlb_map_single(dev, addr, size, dir); 105 + return swiotlb_map_single_attrs(dev, addr, size, dir, attrs); 105 106 else 106 - return hwiommu_map_single(dev, addr, size, dir); 107 + return hwiommu_map_single_attrs(dev, addr, size, dir, attrs); 107 108 } 109 + EXPORT_SYMBOL(hwsw_map_single_attrs); 108 110 109 111 void 110 - hwsw_unmap_single (struct device *dev, dma_addr_t iova, size_t size, int dir) 112 + hwsw_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, 113 + int dir, struct dma_attrs *attrs) 111 114 { 112 115 if (use_swiotlb(dev)) 113 - return swiotlb_unmap_single(dev, iova, size, dir); 116 + return swiotlb_unmap_single_attrs(dev, iova, size, dir, attrs); 114 117 else 115 - return hwiommu_unmap_single(dev, iova, size, dir); 118 + return hwiommu_unmap_single_attrs(dev, iova, size, dir, attrs); 116 119 } 117 - 120 + EXPORT_SYMBOL(hwsw_unmap_single_attrs); 118 121 119 122 int 120 - hwsw_map_sg (struct device *dev, struct scatterlist *sglist, int nents, int dir) 123 + hwsw_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, 124 + int dir, struct dma_attrs *attrs) 121 125 { 122 126 if (use_swiotlb(dev)) 123 - return swiotlb_map_sg(dev, sglist, nents, dir); 127 + return swiotlb_map_sg_attrs(dev, sglist, nents, dir, attrs); 124 128 else 125 - return hwiommu_map_sg(dev, sglist, nents, dir); 129 + return hwiommu_map_sg_attrs(dev, sglist, nents, dir, attrs); 126 130 } 131 + EXPORT_SYMBOL(hwsw_map_sg_attrs); 127 132 128 133 void 129 - hwsw_unmap_sg (struct device *dev, struct scatterlist *sglist, int nents, int dir) 134 + hwsw_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, 135 + int dir, struct dma_attrs *attrs) 130 136 { 131 137 if (use_swiotlb(dev)) 132 - return swiotlb_unmap_sg(dev, sglist, nents, dir); 138 + return swiotlb_unmap_sg_attrs(dev, sglist, nents, dir, attrs); 133 139 else 134 - return hwiommu_unmap_sg(dev, sglist, nents, dir); 140 + return hwiommu_unmap_sg_attrs(dev, sglist, nents, dir, attrs); 135 141 } 142 + EXPORT_SYMBOL(hwsw_unmap_sg_attrs); 136 143 137 144 void 138 145 hwsw_sync_single_for_cpu (struct device *dev, dma_addr_t addr, size_t size, int dir) ··· 192 185 } 193 186 194 187 EXPORT_SYMBOL(hwsw_dma_mapping_error); 195 - EXPORT_SYMBOL(hwsw_map_single); 196 - EXPORT_SYMBOL(hwsw_unmap_single); 197 - EXPORT_SYMBOL(hwsw_map_sg); 198 - EXPORT_SYMBOL(hwsw_unmap_sg); 199 188 EXPORT_SYMBOL(hwsw_dma_supported); 200 189 EXPORT_SYMBOL(hwsw_alloc_coherent); 201 190 EXPORT_SYMBOL(hwsw_free_coherent);
+37 -27
arch/ia64/hp/common/sba_iommu.c
··· 899 899 } 900 900 901 901 /** 902 - * sba_map_single - map one buffer and return IOVA for DMA 902 + * sba_map_single_attrs - map one buffer and return IOVA for DMA 903 903 * @dev: instance of PCI owned by the driver that's asking. 904 904 * @addr: driver buffer to map. 905 905 * @size: number of bytes to map in driver buffer. 906 906 * @dir: R/W or both. 907 + * @attrs: optional dma attributes 907 908 * 908 909 * See Documentation/DMA-mapping.txt 909 910 */ 910 911 dma_addr_t 911 - sba_map_single(struct device *dev, void *addr, size_t size, int dir) 912 + sba_map_single_attrs(struct device *dev, void *addr, size_t size, int dir, 913 + struct dma_attrs *attrs) 912 914 { 913 915 struct ioc *ioc; 914 916 dma_addr_t iovp; ··· 934 932 ** Device is bit capable of DMA'ing to the buffer... 935 933 ** just return the PCI address of ptr 936 934 */ 937 - DBG_BYPASS("sba_map_single() bypass mask/addr: 0x%lx/0x%lx\n", 935 + DBG_BYPASS("sba_map_single_attrs() bypass mask/addr: " 936 + "0x%lx/0x%lx\n", 938 937 to_pci_dev(dev)->dma_mask, pci_addr); 939 938 return pci_addr; 940 939 } ··· 956 953 957 954 #ifdef ASSERT_PDIR_SANITY 958 955 spin_lock_irqsave(&ioc->res_lock, flags); 959 - if (sba_check_pdir(ioc,"Check before sba_map_single()")) 956 + if (sba_check_pdir(ioc,"Check before sba_map_single_attrs()")) 960 957 panic("Sanity check failed"); 961 958 spin_unlock_irqrestore(&ioc->res_lock, flags); 962 959 #endif ··· 985 982 /* form complete address */ 986 983 #ifdef ASSERT_PDIR_SANITY 987 984 spin_lock_irqsave(&ioc->res_lock, flags); 988 - sba_check_pdir(ioc,"Check after sba_map_single()"); 985 + sba_check_pdir(ioc,"Check after sba_map_single_attrs()"); 989 986 spin_unlock_irqrestore(&ioc->res_lock, flags); 990 987 #endif 991 988 return SBA_IOVA(ioc, iovp, offset); 992 989 } 990 + EXPORT_SYMBOL(sba_map_single_attrs); 993 991 994 992 #ifdef ENABLE_MARK_CLEAN 995 993 static SBA_INLINE void ··· 1017 1013 #endif 1018 1014 1019 1015 /** 1020 - * sba_unmap_single - unmap one IOVA and free resources 1016 + * sba_unmap_single_attrs - unmap one IOVA and free resources 1021 1017 * @dev: instance of PCI owned by the driver that's asking. 1022 1018 * @iova: IOVA of driver buffer previously mapped. 1023 1019 * @size: number of bytes mapped in driver buffer. 1024 1020 * @dir: R/W or both. 1021 + * @attrs: optional dma attributes 1025 1022 * 1026 1023 * See Documentation/DMA-mapping.txt 1027 1024 */ 1028 - void sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size, int dir) 1025 + void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, 1026 + int dir, struct dma_attrs *attrs) 1029 1027 { 1030 1028 struct ioc *ioc; 1031 1029 #if DELAYED_RESOURCE_CNT > 0 ··· 1044 1038 /* 1045 1039 ** Address does not fall w/in IOVA, must be bypassing 1046 1040 */ 1047 - DBG_BYPASS("sba_unmap_single() bypass addr: 0x%lx\n", iova); 1041 + DBG_BYPASS("sba_unmap_single_atttrs() bypass addr: 0x%lx\n", 1042 + iova); 1048 1043 1049 1044 #ifdef ENABLE_MARK_CLEAN 1050 1045 if (dir == DMA_FROM_DEVICE) { ··· 1094 1087 spin_unlock_irqrestore(&ioc->res_lock, flags); 1095 1088 #endif /* DELAYED_RESOURCE_CNT == 0 */ 1096 1089 } 1097 - 1090 + EXPORT_SYMBOL(sba_unmap_single_attrs); 1098 1091 1099 1092 /** 1100 1093 * sba_alloc_coherent - allocate/map shared mem for DMA ··· 1151 1144 * If device can't bypass or bypass is disabled, pass the 32bit fake 1152 1145 * device to map single to get an iova mapping. 1153 1146 */ 1154 - *dma_handle = sba_map_single(&ioc->sac_only_dev->dev, addr, size, 0); 1147 + *dma_handle = sba_map_single_attrs(&ioc->sac_only_dev->dev, addr, 1148 + size, 0, NULL); 1155 1149 1156 1150 return addr; 1157 1151 } ··· 1169 1161 */ 1170 1162 void sba_free_coherent (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle) 1171 1163 { 1172 - sba_unmap_single(dev, dma_handle, size, 0); 1164 + sba_unmap_single_attrs(dev, dma_handle, size, 0, NULL); 1173 1165 free_pages((unsigned long) vaddr, get_order(size)); 1174 1166 } 1175 1167 ··· 1418 1410 * @sglist: array of buffer/length pairs 1419 1411 * @nents: number of entries in list 1420 1412 * @dir: R/W or both. 1413 + * @attrs: optional dma attributes 1421 1414 * 1422 1415 * See Documentation/DMA-mapping.txt 1423 1416 */ 1424 - int sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, int dir) 1417 + int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, 1418 + int dir, struct dma_attrs *attrs) 1425 1419 { 1426 1420 struct ioc *ioc; 1427 1421 int coalesced, filled = 0; ··· 1451 1441 /* Fast path single entry scatterlists. */ 1452 1442 if (nents == 1) { 1453 1443 sglist->dma_length = sglist->length; 1454 - sglist->dma_address = sba_map_single(dev, sba_sg_address(sglist), sglist->length, dir); 1444 + sglist->dma_address = sba_map_single_attrs(dev, sba_sg_address(sglist), sglist->length, dir, attrs); 1455 1445 return 1; 1456 1446 } 1457 1447 1458 1448 #ifdef ASSERT_PDIR_SANITY 1459 1449 spin_lock_irqsave(&ioc->res_lock, flags); 1460 - if (sba_check_pdir(ioc,"Check before sba_map_sg()")) 1450 + if (sba_check_pdir(ioc,"Check before sba_map_sg_attrs()")) 1461 1451 { 1462 1452 sba_dump_sg(ioc, sglist, nents); 1463 - panic("Check before sba_map_sg()"); 1453 + panic("Check before sba_map_sg_attrs()"); 1464 1454 } 1465 1455 spin_unlock_irqrestore(&ioc->res_lock, flags); 1466 1456 #endif ··· 1489 1479 1490 1480 #ifdef ASSERT_PDIR_SANITY 1491 1481 spin_lock_irqsave(&ioc->res_lock, flags); 1492 - if (sba_check_pdir(ioc,"Check after sba_map_sg()")) 1482 + if (sba_check_pdir(ioc,"Check after sba_map_sg_attrs()")) 1493 1483 { 1494 1484 sba_dump_sg(ioc, sglist, nents); 1495 - panic("Check after sba_map_sg()\n"); 1485 + panic("Check after sba_map_sg_attrs()\n"); 1496 1486 } 1497 1487 spin_unlock_irqrestore(&ioc->res_lock, flags); 1498 1488 #endif ··· 1502 1492 1503 1493 return filled; 1504 1494 } 1505 - 1495 + EXPORT_SYMBOL(sba_map_sg_attrs); 1506 1496 1507 1497 /** 1508 - * sba_unmap_sg - unmap Scatter/Gather list 1498 + * sba_unmap_sg_attrs - unmap Scatter/Gather list 1509 1499 * @dev: instance of PCI owned by the driver that's asking. 1510 1500 * @sglist: array of buffer/length pairs 1511 1501 * @nents: number of entries in list 1512 1502 * @dir: R/W or both. 1503 + * @attrs: optional dma attributes 1513 1504 * 1514 1505 * See Documentation/DMA-mapping.txt 1515 1506 */ 1516 - void sba_unmap_sg (struct device *dev, struct scatterlist *sglist, int nents, int dir) 1507 + void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, 1508 + int nents, int dir, struct dma_attrs *attrs) 1517 1509 { 1518 1510 #ifdef ASSERT_PDIR_SANITY 1519 1511 struct ioc *ioc; ··· 1530 1518 ASSERT(ioc); 1531 1519 1532 1520 spin_lock_irqsave(&ioc->res_lock, flags); 1533 - sba_check_pdir(ioc,"Check before sba_unmap_sg()"); 1521 + sba_check_pdir(ioc,"Check before sba_unmap_sg_attrs()"); 1534 1522 spin_unlock_irqrestore(&ioc->res_lock, flags); 1535 1523 #endif 1536 1524 1537 1525 while (nents && sglist->dma_length) { 1538 1526 1539 - sba_unmap_single(dev, sglist->dma_address, sglist->dma_length, dir); 1527 + sba_unmap_single_attrs(dev, sglist->dma_address, 1528 + sglist->dma_length, dir, attrs); 1540 1529 sglist = sg_next(sglist); 1541 1530 nents--; 1542 1531 } ··· 1546 1533 1547 1534 #ifdef ASSERT_PDIR_SANITY 1548 1535 spin_lock_irqsave(&ioc->res_lock, flags); 1549 - sba_check_pdir(ioc,"Check after sba_unmap_sg()"); 1536 + sba_check_pdir(ioc,"Check after sba_unmap_sg_attrs()"); 1550 1537 spin_unlock_irqrestore(&ioc->res_lock, flags); 1551 1538 #endif 1552 1539 1553 1540 } 1541 + EXPORT_SYMBOL(sba_unmap_sg_attrs); 1554 1542 1555 1543 /************************************************************** 1556 1544 * ··· 2180 2166 __setup("sbapagesize=",sba_page_override); 2181 2167 2182 2168 EXPORT_SYMBOL(sba_dma_mapping_error); 2183 - EXPORT_SYMBOL(sba_map_single); 2184 - EXPORT_SYMBOL(sba_unmap_single); 2185 - EXPORT_SYMBOL(sba_map_sg); 2186 - EXPORT_SYMBOL(sba_unmap_sg); 2187 2169 EXPORT_SYMBOL(sba_dma_supported); 2188 2170 EXPORT_SYMBOL(sba_alloc_coherent); 2189 2171 EXPORT_SYMBOL(sba_free_coherent);
+60 -21
arch/ia64/sn/pci/pci_dma.c
··· 10 10 */ 11 11 12 12 #include <linux/module.h> 13 + #include <linux/dma-attrs.h> 13 14 #include <asm/dma.h> 14 15 #include <asm/sn/intr.h> 15 16 #include <asm/sn/pcibus_provider_defs.h> ··· 150 149 EXPORT_SYMBOL(sn_dma_free_coherent); 151 150 152 151 /** 153 - * sn_dma_map_single - map a single page for DMA 152 + * sn_dma_map_single_attrs - map a single page for DMA 154 153 * @dev: device to map for 155 154 * @cpu_addr: kernel virtual address of the region to map 156 155 * @size: size of the region 157 156 * @direction: DMA direction 157 + * @attrs: optional dma attributes 158 158 * 159 159 * Map the region pointed to by @cpu_addr for DMA and return the 160 160 * DMA address. ··· 165 163 * no way of saving the dmamap handle from the alloc to later free 166 164 * (which is pretty much unacceptable). 167 165 * 166 + * mappings with the DMA_ATTR_WRITE_BARRIER get mapped with 167 + * dma_map_consistent() so that writes force a flush of pending DMA. 168 + * (See "SGI Altix Architecture Considerations for Linux Device Drivers", 169 + * Document Number: 007-4763-001) 170 + * 168 171 * TODO: simplify our interface; 169 172 * figure out how to save dmamap handle so can use two step. 170 173 */ 171 - dma_addr_t sn_dma_map_single(struct device *dev, void *cpu_addr, size_t size, 172 - int direction) 174 + dma_addr_t sn_dma_map_single_attrs(struct device *dev, void *cpu_addr, 175 + size_t size, int direction, 176 + struct dma_attrs *attrs) 173 177 { 174 178 dma_addr_t dma_addr; 175 179 unsigned long phys_addr; 176 180 struct pci_dev *pdev = to_pci_dev(dev); 177 181 struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); 182 + int dmabarr; 183 + 184 + dmabarr = dma_get_attr(DMA_ATTR_WRITE_BARRIER, attrs); 178 185 179 186 BUG_ON(dev->bus != &pci_bus_type); 180 187 181 188 phys_addr = __pa(cpu_addr); 182 - dma_addr = provider->dma_map(pdev, phys_addr, size, SN_DMA_ADDR_PHYS); 189 + if (dmabarr) 190 + dma_addr = provider->dma_map_consistent(pdev, phys_addr, 191 + size, SN_DMA_ADDR_PHYS); 192 + else 193 + dma_addr = provider->dma_map(pdev, phys_addr, size, 194 + SN_DMA_ADDR_PHYS); 195 + 183 196 if (!dma_addr) { 184 197 printk(KERN_ERR "%s: out of ATEs\n", __func__); 185 198 return 0; 186 199 } 187 200 return dma_addr; 188 201 } 189 - EXPORT_SYMBOL(sn_dma_map_single); 202 + EXPORT_SYMBOL(sn_dma_map_single_attrs); 190 203 191 204 /** 192 - * sn_dma_unmap_single - unamp a DMA mapped page 205 + * sn_dma_unmap_single_attrs - unamp a DMA mapped page 193 206 * @dev: device to sync 194 207 * @dma_addr: DMA address to sync 195 208 * @size: size of region 196 209 * @direction: DMA direction 210 + * @attrs: optional dma attributes 197 211 * 198 212 * This routine is supposed to sync the DMA region specified 199 213 * by @dma_handle into the coherence domain. On SN, we're always cache 200 214 * coherent, so we just need to free any ATEs associated with this mapping. 201 215 */ 202 - void sn_dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, 203 - int direction) 216 + void sn_dma_unmap_single_attrs(struct device *dev, dma_addr_t dma_addr, 217 + size_t size, int direction, 218 + struct dma_attrs *attrs) 204 219 { 205 220 struct pci_dev *pdev = to_pci_dev(dev); 206 221 struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); ··· 226 207 227 208 provider->dma_unmap(pdev, dma_addr, direction); 228 209 } 229 - EXPORT_SYMBOL(sn_dma_unmap_single); 210 + EXPORT_SYMBOL(sn_dma_unmap_single_attrs); 230 211 231 212 /** 232 - * sn_dma_unmap_sg - unmap a DMA scatterlist 213 + * sn_dma_unmap_sg_attrs - unmap a DMA scatterlist 233 214 * @dev: device to unmap 234 215 * @sg: scatterlist to unmap 235 216 * @nhwentries: number of scatterlist entries 236 217 * @direction: DMA direction 218 + * @attrs: optional dma attributes 237 219 * 238 220 * Unmap a set of streaming mode DMA translations. 239 221 */ 240 - void sn_dma_unmap_sg(struct device *dev, struct scatterlist *sgl, 241 - int nhwentries, int direction) 222 + void sn_dma_unmap_sg_attrs(struct device *dev, struct scatterlist *sgl, 223 + int nhwentries, int direction, 224 + struct dma_attrs *attrs) 242 225 { 243 226 int i; 244 227 struct pci_dev *pdev = to_pci_dev(dev); ··· 255 234 sg->dma_length = 0; 256 235 } 257 236 } 258 - EXPORT_SYMBOL(sn_dma_unmap_sg); 237 + EXPORT_SYMBOL(sn_dma_unmap_sg_attrs); 259 238 260 239 /** 261 - * sn_dma_map_sg - map a scatterlist for DMA 240 + * sn_dma_map_sg_attrs - map a scatterlist for DMA 262 241 * @dev: device to map for 263 242 * @sg: scatterlist to map 264 243 * @nhwentries: number of entries 265 244 * @direction: direction of the DMA transaction 245 + * @attrs: optional dma attributes 246 + * 247 + * mappings with the DMA_ATTR_WRITE_BARRIER get mapped with 248 + * dma_map_consistent() so that writes force a flush of pending DMA. 249 + * (See "SGI Altix Architecture Considerations for Linux Device Drivers", 250 + * Document Number: 007-4763-001) 266 251 * 267 252 * Maps each entry of @sg for DMA. 268 253 */ 269 - int sn_dma_map_sg(struct device *dev, struct scatterlist *sgl, int nhwentries, 270 - int direction) 254 + int sn_dma_map_sg_attrs(struct device *dev, struct scatterlist *sgl, 255 + int nhwentries, int direction, struct dma_attrs *attrs) 271 256 { 272 257 unsigned long phys_addr; 273 258 struct scatterlist *saved_sg = sgl, *sg; 274 259 struct pci_dev *pdev = to_pci_dev(dev); 275 260 struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); 276 261 int i; 262 + int dmabarr; 263 + 264 + dmabarr = dma_get_attr(DMA_ATTR_WRITE_BARRIER, attrs); 277 265 278 266 BUG_ON(dev->bus != &pci_bus_type); 279 267 ··· 290 260 * Setup a DMA address for each entry in the scatterlist. 291 261 */ 292 262 for_each_sg(sgl, sg, nhwentries, i) { 263 + dma_addr_t dma_addr; 293 264 phys_addr = SG_ENT_PHYS_ADDRESS(sg); 294 - sg->dma_address = provider->dma_map(pdev, 295 - phys_addr, sg->length, 296 - SN_DMA_ADDR_PHYS); 265 + if (dmabarr) 266 + dma_addr = provider->dma_map_consistent(pdev, 267 + phys_addr, 268 + sg->length, 269 + SN_DMA_ADDR_PHYS); 270 + else 271 + dma_addr = provider->dma_map(pdev, phys_addr, 272 + sg->length, 273 + SN_DMA_ADDR_PHYS); 297 274 275 + sg->dma_address = dma_addr; 298 276 if (!sg->dma_address) { 299 277 printk(KERN_ERR "%s: out of ATEs\n", __func__); 300 278 ··· 310 272 * Free any successfully allocated entries. 311 273 */ 312 274 if (i > 0) 313 - sn_dma_unmap_sg(dev, saved_sg, i, direction); 275 + sn_dma_unmap_sg_attrs(dev, saved_sg, i, 276 + direction, attrs); 314 277 return 0; 315 278 } 316 279 ··· 320 281 321 282 return nhwentries; 322 283 } 323 - EXPORT_SYMBOL(sn_dma_map_sg); 284 + EXPORT_SYMBOL(sn_dma_map_sg_attrs); 324 285 325 286 void sn_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, 326 287 size_t size, int direction)
+24 -4
include/asm-ia64/dma-mapping.h
··· 23 23 { 24 24 dma_free_coherent(dev, size, cpu_addr, dma_handle); 25 25 } 26 - #define dma_map_single platform_dma_map_single 27 - #define dma_map_sg platform_dma_map_sg 28 - #define dma_unmap_single platform_dma_unmap_single 29 - #define dma_unmap_sg platform_dma_unmap_sg 26 + #define dma_map_single_attrs platform_dma_map_single_attrs 27 + static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, 28 + size_t size, int dir) 29 + { 30 + return dma_map_single_attrs(dev, cpu_addr, size, dir, NULL); 31 + } 32 + #define dma_map_sg_attrs platform_dma_map_sg_attrs 33 + static inline int dma_map_sg(struct device *dev, struct scatterlist *sgl, 34 + int nents, int dir) 35 + { 36 + return dma_map_sg_attrs(dev, sgl, nents, dir, NULL); 37 + } 38 + #define dma_unmap_single_attrs platform_dma_unmap_single_attrs 39 + static inline void dma_unmap_single(struct device *dev, dma_addr_t cpu_addr, 40 + size_t size, int dir) 41 + { 42 + return dma_unmap_single_attrs(dev, cpu_addr, size, dir, NULL); 43 + } 44 + #define dma_unmap_sg_attrs platform_dma_unmap_sg_attrs 45 + static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sgl, 46 + int nents, int dir) 47 + { 48 + return dma_unmap_sg_attrs(dev, sgl, nents, dir, NULL); 49 + } 30 50 #define dma_sync_single_for_cpu platform_dma_sync_single_for_cpu 31 51 #define dma_sync_sg_for_cpu platform_dma_sync_sg_for_cpu 32 52 #define dma_sync_single_for_device platform_dma_sync_single_for_device
+30 -20
include/asm-ia64/machvec.h
··· 22 22 struct task_struct; 23 23 struct pci_dev; 24 24 struct msi_desc; 25 + struct dma_attrs; 25 26 26 27 typedef void ia64_mv_setup_t (char **); 27 28 typedef void ia64_mv_cpu_init_t (void); ··· 56 55 typedef void ia64_mv_dma_sync_sg_for_device (struct device *, struct scatterlist *, int, int); 57 56 typedef int ia64_mv_dma_mapping_error (dma_addr_t dma_addr); 58 57 typedef int ia64_mv_dma_supported (struct device *, u64); 58 + 59 + typedef dma_addr_t ia64_mv_dma_map_single_attrs (struct device *, void *, size_t, int, struct dma_attrs *); 60 + typedef void ia64_mv_dma_unmap_single_attrs (struct device *, dma_addr_t, size_t, int, struct dma_attrs *); 61 + typedef int ia64_mv_dma_map_sg_attrs (struct device *, struct scatterlist *, int, int, struct dma_attrs *); 62 + typedef void ia64_mv_dma_unmap_sg_attrs (struct device *, struct scatterlist *, int, int, struct dma_attrs *); 59 63 60 64 /* 61 65 * WARNING: The legacy I/O space is _architected_. Platforms are ··· 142 136 # define platform_dma_init ia64_mv.dma_init 143 137 # define platform_dma_alloc_coherent ia64_mv.dma_alloc_coherent 144 138 # define platform_dma_free_coherent ia64_mv.dma_free_coherent 145 - # define platform_dma_map_single ia64_mv.dma_map_single 146 - # define platform_dma_unmap_single ia64_mv.dma_unmap_single 147 - # define platform_dma_map_sg ia64_mv.dma_map_sg 148 - # define platform_dma_unmap_sg ia64_mv.dma_unmap_sg 139 + # define platform_dma_map_single_attrs ia64_mv.dma_map_single_attrs 140 + # define platform_dma_unmap_single_attrs ia64_mv.dma_unmap_single_attrs 141 + # define platform_dma_map_sg_attrs ia64_mv.dma_map_sg_attrs 142 + # define platform_dma_unmap_sg_attrs ia64_mv.dma_unmap_sg_attrs 149 143 # define platform_dma_sync_single_for_cpu ia64_mv.dma_sync_single_for_cpu 150 144 # define platform_dma_sync_sg_for_cpu ia64_mv.dma_sync_sg_for_cpu 151 145 # define platform_dma_sync_single_for_device ia64_mv.dma_sync_single_for_device ··· 196 190 ia64_mv_dma_init *dma_init; 197 191 ia64_mv_dma_alloc_coherent *dma_alloc_coherent; 198 192 ia64_mv_dma_free_coherent *dma_free_coherent; 199 - ia64_mv_dma_map_single *dma_map_single; 200 - ia64_mv_dma_unmap_single *dma_unmap_single; 201 - ia64_mv_dma_map_sg *dma_map_sg; 202 - ia64_mv_dma_unmap_sg *dma_unmap_sg; 193 + ia64_mv_dma_map_single_attrs *dma_map_single_attrs; 194 + ia64_mv_dma_unmap_single_attrs *dma_unmap_single_attrs; 195 + ia64_mv_dma_map_sg_attrs *dma_map_sg_attrs; 196 + ia64_mv_dma_unmap_sg_attrs *dma_unmap_sg_attrs; 203 197 ia64_mv_dma_sync_single_for_cpu *dma_sync_single_for_cpu; 204 198 ia64_mv_dma_sync_sg_for_cpu *dma_sync_sg_for_cpu; 205 199 ia64_mv_dma_sync_single_for_device *dma_sync_single_for_device; ··· 246 240 platform_dma_init, \ 247 241 platform_dma_alloc_coherent, \ 248 242 platform_dma_free_coherent, \ 249 - platform_dma_map_single, \ 250 - platform_dma_unmap_single, \ 251 - platform_dma_map_sg, \ 252 - platform_dma_unmap_sg, \ 243 + platform_dma_map_single_attrs, \ 244 + platform_dma_unmap_single_attrs, \ 245 + platform_dma_map_sg_attrs, \ 246 + platform_dma_unmap_sg_attrs, \ 253 247 platform_dma_sync_single_for_cpu, \ 254 248 platform_dma_sync_sg_for_cpu, \ 255 249 platform_dma_sync_single_for_device, \ ··· 298 292 extern ia64_mv_dma_alloc_coherent swiotlb_alloc_coherent; 299 293 extern ia64_mv_dma_free_coherent swiotlb_free_coherent; 300 294 extern ia64_mv_dma_map_single swiotlb_map_single; 295 + extern ia64_mv_dma_map_single_attrs swiotlb_map_single_attrs; 301 296 extern ia64_mv_dma_unmap_single swiotlb_unmap_single; 297 + extern ia64_mv_dma_unmap_single_attrs swiotlb_unmap_single_attrs; 302 298 extern ia64_mv_dma_map_sg swiotlb_map_sg; 299 + extern ia64_mv_dma_map_sg_attrs swiotlb_map_sg_attrs; 303 300 extern ia64_mv_dma_unmap_sg swiotlb_unmap_sg; 301 + extern ia64_mv_dma_unmap_sg_attrs swiotlb_unmap_sg_attrs; 304 302 extern ia64_mv_dma_sync_single_for_cpu swiotlb_sync_single_for_cpu; 305 303 extern ia64_mv_dma_sync_sg_for_cpu swiotlb_sync_sg_for_cpu; 306 304 extern ia64_mv_dma_sync_single_for_device swiotlb_sync_single_for_device; ··· 350 340 #ifndef platform_dma_free_coherent 351 341 # define platform_dma_free_coherent swiotlb_free_coherent 352 342 #endif 353 - #ifndef platform_dma_map_single 354 - # define platform_dma_map_single swiotlb_map_single 343 + #ifndef platform_dma_map_single_attrs 344 + # define platform_dma_map_single_attrs swiotlb_map_single_attrs 355 345 #endif 356 - #ifndef platform_dma_unmap_single 357 - # define platform_dma_unmap_single swiotlb_unmap_single 346 + #ifndef platform_dma_unmap_single_attrs 347 + # define platform_dma_unmap_single_attrs swiotlb_unmap_single_attrs 358 348 #endif 359 - #ifndef platform_dma_map_sg 360 - # define platform_dma_map_sg swiotlb_map_sg 349 + #ifndef platform_dma_map_sg_attrs 350 + # define platform_dma_map_sg_attrs swiotlb_map_sg_attrs 361 351 #endif 362 - #ifndef platform_dma_unmap_sg 363 - # define platform_dma_unmap_sg swiotlb_unmap_sg 352 + #ifndef platform_dma_unmap_sg_attrs 353 + # define platform_dma_unmap_sg_attrs swiotlb_unmap_sg_attrs 364 354 #endif 365 355 #ifndef platform_dma_sync_single_for_cpu 366 356 # define platform_dma_sync_single_for_cpu swiotlb_sync_single_for_cpu
+8 -8
include/asm-ia64/machvec_hpzx1.h
··· 4 4 extern ia64_mv_setup_t dig_setup; 5 5 extern ia64_mv_dma_alloc_coherent sba_alloc_coherent; 6 6 extern ia64_mv_dma_free_coherent sba_free_coherent; 7 - extern ia64_mv_dma_map_single sba_map_single; 8 - extern ia64_mv_dma_unmap_single sba_unmap_single; 9 - extern ia64_mv_dma_map_sg sba_map_sg; 10 - extern ia64_mv_dma_unmap_sg sba_unmap_sg; 7 + extern ia64_mv_dma_map_single_attrs sba_map_single_attrs; 8 + extern ia64_mv_dma_unmap_single_attrs sba_unmap_single_attrs; 9 + extern ia64_mv_dma_map_sg_attrs sba_map_sg_attrs; 10 + extern ia64_mv_dma_unmap_sg_attrs sba_unmap_sg_attrs; 11 11 extern ia64_mv_dma_supported sba_dma_supported; 12 12 extern ia64_mv_dma_mapping_error sba_dma_mapping_error; 13 13 ··· 23 23 #define platform_dma_init machvec_noop 24 24 #define platform_dma_alloc_coherent sba_alloc_coherent 25 25 #define platform_dma_free_coherent sba_free_coherent 26 - #define platform_dma_map_single sba_map_single 27 - #define platform_dma_unmap_single sba_unmap_single 28 - #define platform_dma_map_sg sba_map_sg 29 - #define platform_dma_unmap_sg sba_unmap_sg 26 + #define platform_dma_map_single_attrs sba_map_single_attrs 27 + #define platform_dma_unmap_single_attrs sba_unmap_single_attrs 28 + #define platform_dma_map_sg_attrs sba_map_sg_attrs 29 + #define platform_dma_unmap_sg_attrs sba_unmap_sg_attrs 30 30 #define platform_dma_sync_single_for_cpu machvec_dma_sync_single 31 31 #define platform_dma_sync_sg_for_cpu machvec_dma_sync_sg 32 32 #define platform_dma_sync_single_for_device machvec_dma_sync_single
+8 -8
include/asm-ia64/machvec_hpzx1_swiotlb.h
··· 4 4 extern ia64_mv_setup_t dig_setup; 5 5 extern ia64_mv_dma_alloc_coherent hwsw_alloc_coherent; 6 6 extern ia64_mv_dma_free_coherent hwsw_free_coherent; 7 - extern ia64_mv_dma_map_single hwsw_map_single; 8 - extern ia64_mv_dma_unmap_single hwsw_unmap_single; 9 - extern ia64_mv_dma_map_sg hwsw_map_sg; 10 - extern ia64_mv_dma_unmap_sg hwsw_unmap_sg; 7 + extern ia64_mv_dma_map_single_attrs hwsw_map_single_attrs; 8 + extern ia64_mv_dma_unmap_single_attrs hwsw_unmap_single_attrs; 9 + extern ia64_mv_dma_map_sg_attrs hwsw_map_sg_attrs; 10 + extern ia64_mv_dma_unmap_sg_attrs hwsw_unmap_sg_attrs; 11 11 extern ia64_mv_dma_supported hwsw_dma_supported; 12 12 extern ia64_mv_dma_mapping_error hwsw_dma_mapping_error; 13 13 extern ia64_mv_dma_sync_single_for_cpu hwsw_sync_single_for_cpu; ··· 28 28 #define platform_dma_init machvec_noop 29 29 #define platform_dma_alloc_coherent hwsw_alloc_coherent 30 30 #define platform_dma_free_coherent hwsw_free_coherent 31 - #define platform_dma_map_single hwsw_map_single 32 - #define platform_dma_unmap_single hwsw_unmap_single 33 - #define platform_dma_map_sg hwsw_map_sg 34 - #define platform_dma_unmap_sg hwsw_unmap_sg 31 + #define platform_dma_map_single_attrs hwsw_map_single_attrs 32 + #define platform_dma_unmap_single_attrs hwsw_unmap_single_attrs 33 + #define platform_dma_map_sg_attrs hwsw_map_sg_attrs 34 + #define platform_dma_unmap_sg_attrs hwsw_unmap_sg_attrs 35 35 #define platform_dma_supported hwsw_dma_supported 36 36 #define platform_dma_mapping_error hwsw_dma_mapping_error 37 37 #define platform_dma_sync_single_for_cpu hwsw_sync_single_for_cpu
+8 -8
include/asm-ia64/machvec_sn2.h
··· 57 57 extern ia64_mv_readq_t __sn_readq_relaxed; 58 58 extern ia64_mv_dma_alloc_coherent sn_dma_alloc_coherent; 59 59 extern ia64_mv_dma_free_coherent sn_dma_free_coherent; 60 - extern ia64_mv_dma_map_single sn_dma_map_single; 61 - extern ia64_mv_dma_unmap_single sn_dma_unmap_single; 62 - extern ia64_mv_dma_map_sg sn_dma_map_sg; 63 - extern ia64_mv_dma_unmap_sg sn_dma_unmap_sg; 60 + extern ia64_mv_dma_map_single_attrs sn_dma_map_single_attrs; 61 + extern ia64_mv_dma_unmap_single_attrs sn_dma_unmap_single_attrs; 62 + extern ia64_mv_dma_map_sg_attrs sn_dma_map_sg_attrs; 63 + extern ia64_mv_dma_unmap_sg_attrs sn_dma_unmap_sg_attrs; 64 64 extern ia64_mv_dma_sync_single_for_cpu sn_dma_sync_single_for_cpu; 65 65 extern ia64_mv_dma_sync_sg_for_cpu sn_dma_sync_sg_for_cpu; 66 66 extern ia64_mv_dma_sync_single_for_device sn_dma_sync_single_for_device; ··· 113 113 #define platform_dma_init machvec_noop 114 114 #define platform_dma_alloc_coherent sn_dma_alloc_coherent 115 115 #define platform_dma_free_coherent sn_dma_free_coherent 116 - #define platform_dma_map_single sn_dma_map_single 117 - #define platform_dma_unmap_single sn_dma_unmap_single 118 - #define platform_dma_map_sg sn_dma_map_sg 119 - #define platform_dma_unmap_sg sn_dma_unmap_sg 116 + #define platform_dma_map_single_attrs sn_dma_map_single_attrs 117 + #define platform_dma_unmap_single_attrs sn_dma_unmap_single_attrs 118 + #define platform_dma_map_sg_attrs sn_dma_map_sg_attrs 119 + #define platform_dma_unmap_sg_attrs sn_dma_unmap_sg_attrs 120 120 #define platform_dma_sync_single_for_cpu sn_dma_sync_single_for_cpu 121 121 #define platform_dma_sync_sg_for_cpu sn_dma_sync_sg_for_cpu 122 122 #define platform_dma_sync_single_for_device sn_dma_sync_single_for_device
+42 -8
lib/swiotlb.c
··· 555 555 * either swiotlb_unmap_single or swiotlb_dma_sync_single is performed. 556 556 */ 557 557 dma_addr_t 558 - swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir) 558 + swiotlb_map_single_attrs(struct device *hwdev, void *ptr, size_t size, 559 + int dir, struct dma_attrs *attrs) 559 560 { 560 561 dma_addr_t dev_addr = virt_to_bus(ptr); 561 562 void *map; ··· 589 588 590 589 return dev_addr; 591 590 } 591 + EXPORT_SYMBOL(swiotlb_map_single_attrs); 592 + 593 + dma_addr_t 594 + swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir) 595 + { 596 + return swiotlb_map_single_attrs(hwdev, ptr, size, dir, NULL); 597 + } 592 598 593 599 /* 594 600 * Unmap a single streaming mode DMA translation. The dma_addr and size must ··· 606 598 * whatever the device wrote there. 607 599 */ 608 600 void 609 - swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size, 610 - int dir) 601 + swiotlb_unmap_single_attrs(struct device *hwdev, dma_addr_t dev_addr, 602 + size_t size, int dir, struct dma_attrs *attrs) 611 603 { 612 604 char *dma_addr = bus_to_virt(dev_addr); 613 605 ··· 617 609 else if (dir == DMA_FROM_DEVICE) 618 610 dma_mark_clean(dma_addr, size); 619 611 } 612 + EXPORT_SYMBOL(swiotlb_unmap_single_attrs); 620 613 614 + void 615 + swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, size_t size, 616 + int dir) 617 + { 618 + return swiotlb_unmap_single_attrs(hwdev, dev_addr, size, dir, NULL); 619 + } 621 620 /* 622 621 * Make physical memory consistent for a single streaming mode DMA translation 623 622 * after a transfer. ··· 695 680 SYNC_FOR_DEVICE); 696 681 } 697 682 683 + void swiotlb_unmap_sg_attrs(struct device *, struct scatterlist *, int, int, 684 + struct dma_attrs *); 698 685 /* 699 686 * Map a set of buffers described by scatterlist in streaming mode for DMA. 700 687 * This is the scatter-gather version of the above swiotlb_map_single ··· 714 697 * same here. 715 698 */ 716 699 int 717 - swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems, 718 - int dir) 700 + swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems, 701 + int dir, struct dma_attrs *attrs) 719 702 { 720 703 struct scatterlist *sg; 721 704 void *addr; ··· 733 716 /* Don't panic here, we expect map_sg users 734 717 to do proper error handling. */ 735 718 swiotlb_full(hwdev, sg->length, dir, 0); 736 - swiotlb_unmap_sg(hwdev, sgl, i, dir); 719 + swiotlb_unmap_sg_attrs(hwdev, sgl, i, dir, 720 + attrs); 737 721 sgl[0].dma_length = 0; 738 722 return 0; 739 723 } ··· 745 727 } 746 728 return nelems; 747 729 } 730 + EXPORT_SYMBOL(swiotlb_map_sg_attrs); 731 + 732 + int 733 + swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems, 734 + int dir) 735 + { 736 + return swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, NULL); 737 + } 748 738 749 739 /* 750 740 * Unmap a set of streaming mode DMA translations. Again, cpu read rules 751 741 * concerning calls here are the same as for swiotlb_unmap_single() above. 752 742 */ 753 743 void 754 - swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nelems, 755 - int dir) 744 + swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl, 745 + int nelems, int dir, struct dma_attrs *attrs) 756 746 { 757 747 struct scatterlist *sg; 758 748 int i; ··· 774 748 else if (dir == DMA_FROM_DEVICE) 775 749 dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); 776 750 } 751 + } 752 + EXPORT_SYMBOL(swiotlb_unmap_sg_attrs); 753 + 754 + void 755 + swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nelems, 756 + int dir) 757 + { 758 + return swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, NULL); 777 759 } 778 760 779 761 /*