diff options
author | Dan Williams <dan.j.williams@intel.com> | 2009-09-08 20:42:29 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2009-09-08 20:42:29 -0400 |
commit | f9dd2134374c8de6b911e2b8652c6c9622eaa658 (patch) | |
tree | c1b8f8d622941606b9e7247ab31d811ba4295011 /drivers/dma/dmaengine.c | |
parent | 4b652f0db3be891c7b76b109c3b55003b920fc96 (diff) | |
parent | 07a3b417dc3d00802bd7b4874c3e811f0b015a7d (diff) |
Merge branch 'md-raid6-accel' into ioat3.2
Conflicts:
include/linux/dmaengine.h
Diffstat (limited to 'drivers/dma/dmaengine.c')
-rw-r--r-- | drivers/dma/dmaengine.c | 53 |
1 files changed, 16 insertions, 37 deletions
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 5a87384ea4ff..96598479eece 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c | |||
@@ -644,8 +644,12 @@ int dma_async_device_register(struct dma_device *device) | |||
644 | !device->device_prep_dma_memcpy); | 644 | !device->device_prep_dma_memcpy); |
645 | BUG_ON(dma_has_cap(DMA_XOR, device->cap_mask) && | 645 | BUG_ON(dma_has_cap(DMA_XOR, device->cap_mask) && |
646 | !device->device_prep_dma_xor); | 646 | !device->device_prep_dma_xor); |
647 | BUG_ON(dma_has_cap(DMA_ZERO_SUM, device->cap_mask) && | 647 | BUG_ON(dma_has_cap(DMA_XOR_VAL, device->cap_mask) && |
648 | !device->device_prep_dma_zero_sum); | 648 | !device->device_prep_dma_xor_val); |
649 | BUG_ON(dma_has_cap(DMA_PQ, device->cap_mask) && | ||
650 | !device->device_prep_dma_pq); | ||
651 | BUG_ON(dma_has_cap(DMA_PQ_VAL, device->cap_mask) && | ||
652 | !device->device_prep_dma_pq_val); | ||
649 | BUG_ON(dma_has_cap(DMA_MEMSET, device->cap_mask) && | 653 | BUG_ON(dma_has_cap(DMA_MEMSET, device->cap_mask) && |
650 | !device->device_prep_dma_memset); | 654 | !device->device_prep_dma_memset); |
651 | BUG_ON(dma_has_cap(DMA_INTERRUPT, device->cap_mask) && | 655 | BUG_ON(dma_has_cap(DMA_INTERRUPT, device->cap_mask) && |
@@ -939,49 +943,24 @@ EXPORT_SYMBOL(dma_async_tx_descriptor_init); | |||
939 | 943 | ||
940 | /* dma_wait_for_async_tx - spin wait for a transaction to complete | 944 | /* dma_wait_for_async_tx - spin wait for a transaction to complete |
941 | * @tx: in-flight transaction to wait on | 945 | * @tx: in-flight transaction to wait on |
942 | * | ||
943 | * This routine assumes that tx was obtained from a call to async_memcpy, | ||
944 | * async_xor, async_memset, etc which ensures that tx is "in-flight" (prepped | ||
945 | * and submitted). Walking the parent chain is only meant to cover for DMA | ||
946 | * drivers that do not implement the DMA_INTERRUPT capability and may race with | ||
947 | * the driver's descriptor cleanup routine. | ||
948 | */ | 946 | */ |
949 | enum dma_status | 947 | enum dma_status |
950 | dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx) | 948 | dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx) |
951 | { | 949 | { |
952 | enum dma_status status; | 950 | unsigned long dma_sync_wait_timeout = jiffies + msecs_to_jiffies(5000); |
953 | struct dma_async_tx_descriptor *iter; | ||
954 | struct dma_async_tx_descriptor *parent; | ||
955 | 951 | ||
956 | if (!tx) | 952 | if (!tx) |
957 | return DMA_SUCCESS; | 953 | return DMA_SUCCESS; |
958 | 954 | ||
959 | WARN_ONCE(tx->parent, "%s: speculatively walking dependency chain for" | 955 | while (tx->cookie == -EBUSY) { |
960 | " %s\n", __func__, dma_chan_name(tx->chan)); | 956 | if (time_after_eq(jiffies, dma_sync_wait_timeout)) { |
961 | 957 | pr_err("%s timeout waiting for descriptor submission\n", | |
962 | /* poll through the dependency chain, return when tx is complete */ | 958 | __func__); |
963 | do { | 959 | return DMA_ERROR; |
964 | iter = tx; | 960 | } |
965 | 961 | cpu_relax(); | |
966 | /* find the root of the unsubmitted dependency chain */ | 962 | } |
967 | do { | 963 | return dma_sync_wait(tx->chan, tx->cookie); |
968 | parent = iter->parent; | ||
969 | if (!parent) | ||
970 | break; | ||
971 | else | ||
972 | iter = parent; | ||
973 | } while (parent); | ||
974 | |||
975 | /* there is a small window for ->parent == NULL and | ||
976 | * ->cookie == -EBUSY | ||
977 | */ | ||
978 | while (iter->cookie == -EBUSY) | ||
979 | cpu_relax(); | ||
980 | |||
981 | status = dma_sync_wait(iter->chan, iter->cookie); | ||
982 | } while (status == DMA_IN_PROGRESS || (iter != tx)); | ||
983 | |||
984 | return status; | ||
985 | } | 964 | } |
986 | EXPORT_SYMBOL_GPL(dma_wait_for_async_tx); | 965 | EXPORT_SYMBOL_GPL(dma_wait_for_async_tx); |
987 | 966 | ||