···11/*22 * Dynamic DMA mapping support.33 *44- * This implementation is for IA-64 platforms that do not support44+ * This implementation is for IA-64 and EM64T platforms that do not support55 * I/O TLBs (aka DMA address translation hardware).66 * Copyright (C) 2000 Asit Mallick <Asit.K.Mallick@intel.com>77 * Copyright (C) 2000 Goutham Rao <goutham.rao@intel.com>···1111 * 03/05/07 davidm Switch from PCI-DMA to generic device DMA API.1212 * 00/12/13 davidm Rename to swiotlb.c and add mark_clean() to avoid1313 * unnecessary i-cache flushing.1414- * 04/07/.. ak Better overflow handling. Assorted fixes.1414+ * 04/07/.. ak Better overflow handling. Assorted fixes.1515+ * 05/09/10 linville Add support for syncing ranges, support syncing for1616+ * DMA_BIDIRECTIONAL mappings, miscellaneous cleanup.1517 */16181719#include <linux/cache.h>2020+#include <linux/dma-mapping.h>1821#include <linux/mm.h>1922#include <linux/module.h>2020-#include <linux/pci.h>2123#include <linux/spinlock.h>2224#include <linux/string.h>2325#include <linux/types.h>2426#include <linux/ctype.h>25272628#include <asm/io.h>2727-#include <asm/pci.h>2829#include <asm/dma.h>3030+#include <asm/scatterlist.h>29313032#include <linux/init.h>3133#include <linux/bootmem.h>···5957 * allocate a contiguous 1MB, we're probably in trouble anyway.6058 */6159#define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT)6060+6161+/*6262+ * Enumeration for sync targets6363+ */6464+enum dma_sync_target {6565+ SYNC_FOR_CPU = 0,6666+ SYNC_FOR_DEVICE = 1,6767+};62686369int swiotlb_force;6470···127117128118/*129119 * Statically reserve bounce buffer space and initialize bounce buffer data130130- * structures for the software IO TLB used to implement the PCI DMA API.120120+ * structures for the software IO TLB used to implement the DMA API.131121 */132122void133123swiotlb_init_with_default_size (size_t default_size)···407397}408398409399static void410410-sync_single(struct device *hwdev, char *dma_addr, size_t size, int dir)400400+sync_single(struct device *hwdev, char *dma_addr, size_t size,401401+ int dir, int target)411402{412403 int index = (dma_addr - io_tlb_start) >> IO_TLB_SHIFT;413404 char *buffer = io_tlb_orig_addr[index];414405415415- /*416416- * bounce... copy the data back into/from the original buffer417417- * XXX How do you handle DMA_BIDIRECTIONAL here ?418418- */419419- if (dir == DMA_FROM_DEVICE)420420- memcpy(buffer, dma_addr, size);421421- else if (dir == DMA_TO_DEVICE)422422- memcpy(dma_addr, buffer, size);423423- else406406+ switch (target) {407407+ case SYNC_FOR_CPU:408408+ if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL))409409+ memcpy(buffer, dma_addr, size);410410+ else if (dir != DMA_TO_DEVICE)411411+ BUG();412412+ break;413413+ case SYNC_FOR_DEVICE:414414+ if (likely(dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL))415415+ memcpy(dma_addr, buffer, size);416416+ else if (dir != DMA_FROM_DEVICE)417417+ BUG();418418+ break;419419+ default:424420 BUG();421421+ }425422}426423427424void *···502485 /*503486 * Ran out of IOMMU space for this operation. This is very bad.504487 * Unfortunately the drivers cannot handle this operation properly.505505- * unless they check for pci_dma_mapping_error (most don't)488488+ * unless they check for dma_mapping_error (most don't)506489 * When the mapping is small enough return a static buffer to limit507490 * the damage, or panic when the transfer is too big.508491 */509509- printk(KERN_ERR "PCI-DMA: Out of SW-IOMMU space for %lu bytes at "492492+ printk(KERN_ERR "DMA: Out of SW-IOMMU space for %lu bytes at "510493 "device %s\n", size, dev ? dev->bus_id : "?");511494512495 if (size > io_tlb_overflow && do_panic) {513513- if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL)514514- panic("PCI-DMA: Memory would be corrupted\n");515515- if (dir == PCI_DMA_TODEVICE || dir == PCI_DMA_BIDIRECTIONAL)516516- panic("PCI-DMA: Random memory would be DMAed\n");496496+ if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)497497+ panic("DMA: Memory would be corrupted\n");498498+ if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)499499+ panic("DMA: Random memory would be DMAed\n");517500 }518501}519502520503/*521504 * Map a single buffer of the indicated size for DMA in streaming mode. The522522- * PCI address to use is returned.505505+ * physical address to use is returned.523506 *524507 * Once the device is given the dma address, the device owns this memory until525508 * either swiotlb_unmap_single or swiotlb_dma_sync_single is performed.···606589 * after a transfer.607590 *608591 * If you perform a swiotlb_map_single() but wish to interrogate the buffer609609- * using the cpu, yet do not wish to teardown the PCI dma mapping, you must610610- * call this function before doing so. At the next point you give the PCI dma592592+ * using the cpu, yet do not wish to teardown the dma mapping, you must593593+ * call this function before doing so. At the next point you give the dma611594 * address back to the card, you must first perform a612595 * swiotlb_dma_sync_for_device, and then the device again owns the buffer613596 */614614-void615615-swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,616616- size_t size, int dir)597597+static inline void598598+swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr,599599+ size_t size, int dir, int target)617600{618601 char *dma_addr = phys_to_virt(dev_addr);619602620603 if (dir == DMA_NONE)621604 BUG();622605 if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end)623623- sync_single(hwdev, dma_addr, size, dir);606606+ sync_single(hwdev, dma_addr, size, dir, target);624607 else if (dir == DMA_FROM_DEVICE)625608 mark_clean(dma_addr, size);609609+}610610+611611+void612612+swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,613613+ size_t size, int dir)614614+{615615+ swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_CPU);626616}627617628618void629619swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr,630620 size_t size, int dir)631621{632632- char *dma_addr = phys_to_virt(dev_addr);622622+ swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_DEVICE);623623+}624624+625625+/*626626+ * Same as above, but for a sub-range of the mapping.627627+ */628628+static inline void629629+swiotlb_sync_single_range(struct device *hwdev, dma_addr_t dev_addr,630630+ unsigned long offset, size_t size,631631+ int dir, int target)632632+{633633+ char *dma_addr = phys_to_virt(dev_addr) + offset;633634634635 if (dir == DMA_NONE)635636 BUG();636637 if (dma_addr >= io_tlb_start && dma_addr < io_tlb_end)637637- sync_single(hwdev, dma_addr, size, dir);638638+ sync_single(hwdev, dma_addr, size, dir, target);638639 else if (dir == DMA_FROM_DEVICE)639640 mark_clean(dma_addr, size);641641+}642642+643643+void644644+swiotlb_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dev_addr,645645+ unsigned long offset, size_t size, int dir)646646+{647647+ swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir,648648+ SYNC_FOR_CPU);649649+}650650+651651+void652652+swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr,653653+ unsigned long offset, size_t size, int dir)654654+{655655+ swiotlb_sync_single_range(hwdev, dev_addr, offset, size, dir,656656+ SYNC_FOR_DEVICE);640657}641658642659/*···747696 * The same as swiotlb_sync_single_* but for a scatter-gather list, same rules748697 * and usage.749698 */750750-void751751-swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,752752- int nelems, int dir)699699+static inline void700700+swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sg,701701+ int nelems, int dir, int target)753702{754703 int i;755704···759708 for (i = 0; i < nelems; i++, sg++)760709 if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))761710 sync_single(hwdev, (void *) sg->dma_address,762762- sg->dma_length, dir);711711+ sg->dma_length, dir, target);712712+}713713+714714+void715715+swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,716716+ int nelems, int dir)717717+{718718+ swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_CPU);763719}764720765721void766722swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,767723 int nelems, int dir)768724{769769- int i;770770-771771- if (dir == DMA_NONE)772772- BUG();773773-774774- for (i = 0; i < nelems; i++, sg++)775775- if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))776776- sync_single(hwdev, (void *) sg->dma_address,777777- sg->dma_length, dir);725725+ swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_DEVICE);778726}779727780728int···783733}784734785735/*786786- * Return whether the given PCI device DMA address mask can be supported736736+ * Return whether the given device DMA address mask can be supported787737 * properly. For example, if your device can only drive the low 24-bits788788- * during PCI bus mastering, then you would pass 0x00ffffff as the mask to738738+ * during bus mastering, then you would pass 0x00ffffff as the mask to789739 * this function.790740 */791741int···801751EXPORT_SYMBOL(swiotlb_unmap_sg);802752EXPORT_SYMBOL(swiotlb_sync_single_for_cpu);803753EXPORT_SYMBOL(swiotlb_sync_single_for_device);754754+EXPORT_SYMBOL_GPL(swiotlb_sync_single_range_for_cpu);755755+EXPORT_SYMBOL_GPL(swiotlb_sync_single_range_for_device);804756EXPORT_SYMBOL(swiotlb_sync_sg_for_cpu);805757EXPORT_SYMBOL(swiotlb_sync_sg_for_device);806758EXPORT_SYMBOL(swiotlb_dma_mapping_error);