Skip to content

Commit

Permalink
dmaengine: add DMA_COMPL_SKIP_{SRC,DEST}_UNMAP flags to control dma u…
Browse files Browse the repository at this point in the history
…nmap

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>
  • Loading branch information
Dan Williams committed Jul 8, 2008
1 parent 848c536 commit e1d181e
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 42 deletions.
48 changes: 23 additions & 25 deletions drivers/dma/ioat_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,27 @@ static void ioat_dma_cleanup_tasklet(unsigned long data)
chan->reg_base + IOAT_CHANCTRL_OFFSET);
}

static void
ioat_dma_unmap(struct ioat_dma_chan *ioat_chan, struct ioat_desc_sw *desc)
{
/*
* yes we are unmapping both _page and _single
* alloc'd regions with unmap_page. Is this
* *really* that bad?
*/
if (!(desc->async_tx.flags & DMA_COMPL_SKIP_DEST_UNMAP))
pci_unmap_page(ioat_chan->device->pdev,
pci_unmap_addr(desc, dst),
pci_unmap_len(desc, len),
PCI_DMA_FROMDEVICE);

if (!(desc->async_tx.flags & DMA_COMPL_SKIP_SRC_UNMAP))
pci_unmap_page(ioat_chan->device->pdev,
pci_unmap_addr(desc, src),
pci_unmap_len(desc, len),
PCI_DMA_TODEVICE);
}

/**
* ioat_dma_memcpy_cleanup - cleanup up finished descriptors
* @chan: ioat channel to be cleaned up
Expand Down Expand Up @@ -817,21 +838,7 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan)
*/
if (desc->async_tx.cookie) {
cookie = desc->async_tx.cookie;

/*
* yes we are unmapping both _page and _single
* alloc'd regions with unmap_page. Is this
* *really* that bad?
*/
pci_unmap_page(ioat_chan->device->pdev,
pci_unmap_addr(desc, dst),
pci_unmap_len(desc, len),
PCI_DMA_FROMDEVICE);
pci_unmap_page(ioat_chan->device->pdev,
pci_unmap_addr(desc, src),
pci_unmap_len(desc, len),
PCI_DMA_TODEVICE);

ioat_dma_unmap(ioat_chan, desc);
if (desc->async_tx.callback) {
desc->async_tx.callback(desc->async_tx.callback_param);
desc->async_tx.callback = NULL;
Expand Down Expand Up @@ -890,16 +897,7 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan)
if (desc->async_tx.cookie) {
cookie = desc->async_tx.cookie;
desc->async_tx.cookie = 0;

pci_unmap_page(ioat_chan->device->pdev,
pci_unmap_addr(desc, dst),
pci_unmap_len(desc, len),
PCI_DMA_FROMDEVICE);
pci_unmap_page(ioat_chan->device->pdev,
pci_unmap_addr(desc, src),
pci_unmap_len(desc, len),
PCI_DMA_TODEVICE);

ioat_dma_unmap(ioat_chan, desc);
if (desc->async_tx.callback) {
desc->async_tx.callback(desc->async_tx.callback_param);
desc->async_tx.callback = NULL;
Expand Down
29 changes: 18 additions & 11 deletions drivers/dma/iop-adma.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,24 @@ iop_adma_run_tx_complete_actions(struct iop_adma_desc_slot *desc,
struct device *dev =
&iop_chan->device->pdev->dev;
u32 len = unmap->unmap_len;
u32 src_cnt = unmap->unmap_src_cnt;
dma_addr_t addr = iop_desc_get_dest_addr(unmap,
iop_chan);

dma_unmap_page(dev, addr, len, DMA_FROM_DEVICE);
while (src_cnt--) {
addr = iop_desc_get_src_addr(unmap,
iop_chan,
src_cnt);
dma_unmap_page(dev, addr, len,
DMA_TO_DEVICE);
enum dma_ctrl_flags flags = desc->async_tx.flags;
u32 src_cnt;
dma_addr_t addr;

if (!(flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
addr = iop_desc_get_dest_addr(unmap, iop_chan);
dma_unmap_page(dev, addr, len, DMA_FROM_DEVICE);
}

if (!(flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
src_cnt = unmap->unmap_src_cnt;
while (src_cnt--) {
addr = iop_desc_get_src_addr(unmap,
iop_chan,
src_cnt);
dma_unmap_page(dev, addr, len,
DMA_TO_DEVICE);
}
}
desc->group_head = NULL;
}
Expand Down
22 changes: 16 additions & 6 deletions drivers/dma/mv_xor.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,13 +308,23 @@ mv_xor_run_tx_complete_actions(struct mv_xor_desc_slot *desc,
struct device *dev =
&mv_chan->device->pdev->dev;
u32 len = unmap->unmap_len;
u32 src_cnt = unmap->unmap_src_cnt;
dma_addr_t addr = mv_desc_get_dest_addr(unmap);
enum dma_ctrl_flags flags = desc->async_tx.flags;
u32 src_cnt;
dma_addr_t addr;

dma_unmap_page(dev, addr, len, DMA_FROM_DEVICE);
while (src_cnt--) {
addr = mv_desc_get_src_addr(unmap, src_cnt);
dma_unmap_page(dev, addr, len, DMA_TO_DEVICE);
if (!(flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
addr = mv_desc_get_dest_addr(unmap);
dma_unmap_page(dev, addr, len, DMA_FROM_DEVICE);
}

if (!(flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
src_cnt = unmap->unmap_src_cnt;
while (src_cnt--) {
addr = mv_desc_get_src_addr(unmap,
src_cnt);
dma_unmap_page(dev, addr, len,
DMA_TO_DEVICE);
}
}
desc->group_head = NULL;
}
Expand Down
4 changes: 4 additions & 0 deletions include/linux/dmaengine.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,14 @@ enum dma_transaction_type {
* @DMA_CTRL_ACK - the descriptor cannot be reused until the client
* acknowledges receipt, i.e. has has a chance to establish any
* dependency chains
* @DMA_COMPL_SKIP_SRC_UNMAP - set to disable dma-unmapping the source buffer(s)
* @DMA_COMPL_SKIP_DEST_UNMAP - set to disable dma-unmapping the destination(s)
*/
enum dma_ctrl_flags {
DMA_PREP_INTERRUPT = (1 << 0),
DMA_CTRL_ACK = (1 << 1),
DMA_COMPL_SKIP_SRC_UNMAP = (1 << 2),
DMA_COMPL_SKIP_DEST_UNMAP = (1 << 3),
};

/**
Expand Down

0 comments on commit e1d181e

Please sign in to comment.