aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/ioat_dma.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2008-07-04 03:13:40 -0400
committerDan Williams <dan.j.williams@intel.com>2008-07-08 14:59:12 -0400
commite1d181efb14a93cf263d6c588a5395518edf3294 (patch)
tree1792d1faa7e344401789bbcfad8102d0d93036e2 /drivers/dma/ioat_dma.c
parent848c536a37b8db4e461f14ca15fe29850151c822 (diff)
dmaengine: add DMA_COMPL_SKIP_{SRC,DEST}_UNMAP flags to control dma unmap
In some cases client code may need the dma-driver to skip the unmap of source and/or destination buffers. Setting these flags indicates to the driver to skip the unmap step. In this regard async_xor is currently broken in that it allows the destination buffer to be unmapped while an operation is still in progress, i.e. when the number of sources exceeds the hardware channel's maximum (fixed in a subsequent patch). Acked-by: Saeed Bishara <saeed@marvell.com> Acked-by: Maciej Sosnowski <maciej.sosnowski@intel.com> Acked-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/dma/ioat_dma.c')
-rw-r--r--drivers/dma/ioat_dma.c48
1 files changed, 23 insertions, 25 deletions
diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c
index 90e5b0a28cbf..171cad69f318 100644
--- a/drivers/dma/ioat_dma.c
+++ b/drivers/dma/ioat_dma.c
@@ -757,6 +757,27 @@ static void ioat_dma_cleanup_tasklet(unsigned long data)
757 chan->reg_base + IOAT_CHANCTRL_OFFSET); 757 chan->reg_base + IOAT_CHANCTRL_OFFSET);
758} 758}
759 759
760static void
761ioat_dma_unmap(struct ioat_dma_chan *ioat_chan, struct ioat_desc_sw *desc)
762{
763 /*
764 * yes we are unmapping both _page and _single
765 * alloc'd regions with unmap_page. Is this
766 * *really* that bad?
767 */
768 if (!(desc->async_tx.flags & DMA_COMPL_SKIP_DEST_UNMAP))
769 pci_unmap_page(ioat_chan->device->pdev,
770 pci_unmap_addr(desc, dst),
771 pci_unmap_len(desc, len),
772 PCI_DMA_FROMDEVICE);
773
774 if (!(desc->async_tx.flags & DMA_COMPL_SKIP_SRC_UNMAP))
775 pci_unmap_page(ioat_chan->device->pdev,
776 pci_unmap_addr(desc, src),
777 pci_unmap_len(desc, len),
778 PCI_DMA_TODEVICE);
779}
780
760/** 781/**
761 * ioat_dma_memcpy_cleanup - cleanup up finished descriptors 782 * ioat_dma_memcpy_cleanup - cleanup up finished descriptors
762 * @chan: ioat channel to be cleaned up 783 * @chan: ioat channel to be cleaned up
@@ -817,21 +838,7 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan)
817 */ 838 */
818 if (desc->async_tx.cookie) { 839 if (desc->async_tx.cookie) {
819 cookie = desc->async_tx.cookie; 840 cookie = desc->async_tx.cookie;
820 841 ioat_dma_unmap(ioat_chan, desc);
821 /*
822 * yes we are unmapping both _page and _single
823 * alloc'd regions with unmap_page. Is this
824 * *really* that bad?
825 */
826 pci_unmap_page(ioat_chan->device->pdev,
827 pci_unmap_addr(desc, dst),
828 pci_unmap_len(desc, len),
829 PCI_DMA_FROMDEVICE);
830 pci_unmap_page(ioat_chan->device->pdev,
831 pci_unmap_addr(desc, src),
832 pci_unmap_len(desc, len),
833 PCI_DMA_TODEVICE);
834
835 if (desc->async_tx.callback) { 842 if (desc->async_tx.callback) {
836 desc->async_tx.callback(desc->async_tx.callback_param); 843 desc->async_tx.callback(desc->async_tx.callback_param);
837 desc->async_tx.callback = NULL; 844 desc->async_tx.callback = NULL;
@@ -890,16 +897,7 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan)
890 if (desc->async_tx.cookie) { 897 if (desc->async_tx.cookie) {
891 cookie = desc->async_tx.cookie; 898 cookie = desc->async_tx.cookie;
892 desc->async_tx.cookie = 0; 899 desc->async_tx.cookie = 0;
893 900 ioat_dma_unmap(ioat_chan, desc);
894 pci_unmap_page(ioat_chan->device->pdev,
895 pci_unmap_addr(desc, dst),
896 pci_unmap_len(desc, len),
897 PCI_DMA_FROMDEVICE);
898 pci_unmap_page(ioat_chan->device->pdev,
899 pci_unmap_addr(desc, src),
900 pci_unmap_len(desc, len),
901 PCI_DMA_TODEVICE);
902
903 if (desc->async_tx.callback) { 901 if (desc->async_tx.callback) {
904 desc->async_tx.callback(desc->async_tx.callback_param); 902 desc->async_tx.callback(desc->async_tx.callback_param);
905 desc->async_tx.callback = NULL; 903 desc->async_tx.callback = NULL;