diff options
author | Vinod Koul <vinod.koul@intel.com> | 2013-11-16 01:24:17 -0500 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2013-11-16 01:32:36 -0500 |
commit | df12a3178d340319b1955be6b973a4eb84aff754 (patch) | |
tree | 2b9c68f8a6c299d1e5a4026c60117b5c00d46008 /drivers/dma/iop-adma.c | |
parent | 2f986ec6fa57a5dcf77f19f5f0d44b1f680a100f (diff) | |
parent | 82a1402eaee5dab1f3ab2d5aa4c316451374c5af (diff) |
Merge commit 'dmaengine-3.13-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/djbw/dmaengine
Pull dmaengine changes from Dan
1/ Bartlomiej and Dan finalized a rework of the dma address unmap
implementation.
2/ In the course of testing 1/ a collection of enhancements to dmatest
fell out. Notably basic performance statistics, and fixed / enhanced
test control through new module parameters 'run', 'wait', 'noverify',
and 'verbose'. Thanks to Andriy and Linus for their review.
3/ Testing the raid related corner cases of 1/ triggered bugs in the
recently added 16-source operation support in the ioatdma driver.
4/ Some minor fixes / cleanups to mv_xor and ioatdma.
Conflicts:
drivers/dma/dmatest.c
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma/iop-adma.c')
-rw-r--r-- | drivers/dma/iop-adma.c | 97 |
1 files changed, 3 insertions, 94 deletions
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c index 408fe6be15f4..c56137bc3868 100644 --- a/drivers/dma/iop-adma.c +++ b/drivers/dma/iop-adma.c | |||
@@ -61,80 +61,6 @@ static void iop_adma_free_slots(struct iop_adma_desc_slot *slot) | |||
61 | } | 61 | } |
62 | } | 62 | } |
63 | 63 | ||
64 | static void | ||
65 | iop_desc_unmap(struct iop_adma_chan *iop_chan, struct iop_adma_desc_slot *desc) | ||
66 | { | ||
67 | struct dma_async_tx_descriptor *tx = &desc->async_tx; | ||
68 | struct iop_adma_desc_slot *unmap = desc->group_head; | ||
69 | struct device *dev = &iop_chan->device->pdev->dev; | ||
70 | u32 len = unmap->unmap_len; | ||
71 | enum dma_ctrl_flags flags = tx->flags; | ||
72 | u32 src_cnt; | ||
73 | dma_addr_t addr; | ||
74 | dma_addr_t dest; | ||
75 | |||
76 | src_cnt = unmap->unmap_src_cnt; | ||
77 | dest = iop_desc_get_dest_addr(unmap, iop_chan); | ||
78 | if (!(flags & DMA_COMPL_SKIP_DEST_UNMAP)) { | ||
79 | enum dma_data_direction dir; | ||
80 | |||
81 | if (src_cnt > 1) /* is xor? */ | ||
82 | dir = DMA_BIDIRECTIONAL; | ||
83 | else | ||
84 | dir = DMA_FROM_DEVICE; | ||
85 | |||
86 | dma_unmap_page(dev, dest, len, dir); | ||
87 | } | ||
88 | |||
89 | if (!(flags & DMA_COMPL_SKIP_SRC_UNMAP)) { | ||
90 | while (src_cnt--) { | ||
91 | addr = iop_desc_get_src_addr(unmap, iop_chan, src_cnt); | ||
92 | if (addr == dest) | ||
93 | continue; | ||
94 | dma_unmap_page(dev, addr, len, DMA_TO_DEVICE); | ||
95 | } | ||
96 | } | ||
97 | desc->group_head = NULL; | ||
98 | } | ||
99 | |||
100 | static void | ||
101 | iop_desc_unmap_pq(struct iop_adma_chan *iop_chan, struct iop_adma_desc_slot *desc) | ||
102 | { | ||
103 | struct dma_async_tx_descriptor *tx = &desc->async_tx; | ||
104 | struct iop_adma_desc_slot *unmap = desc->group_head; | ||
105 | struct device *dev = &iop_chan->device->pdev->dev; | ||
106 | u32 len = unmap->unmap_len; | ||
107 | enum dma_ctrl_flags flags = tx->flags; | ||
108 | u32 src_cnt = unmap->unmap_src_cnt; | ||
109 | dma_addr_t pdest = iop_desc_get_dest_addr(unmap, iop_chan); | ||
110 | dma_addr_t qdest = iop_desc_get_qdest_addr(unmap, iop_chan); | ||
111 | int i; | ||
112 | |||
113 | if (tx->flags & DMA_PREP_CONTINUE) | ||
114 | src_cnt -= 3; | ||
115 | |||
116 | if (!(flags & DMA_COMPL_SKIP_DEST_UNMAP) && !desc->pq_check_result) { | ||
117 | dma_unmap_page(dev, pdest, len, DMA_BIDIRECTIONAL); | ||
118 | dma_unmap_page(dev, qdest, len, DMA_BIDIRECTIONAL); | ||
119 | } | ||
120 | |||
121 | if (!(flags & DMA_COMPL_SKIP_SRC_UNMAP)) { | ||
122 | dma_addr_t addr; | ||
123 | |||
124 | for (i = 0; i < src_cnt; i++) { | ||
125 | addr = iop_desc_get_src_addr(unmap, iop_chan, i); | ||
126 | dma_unmap_page(dev, addr, len, DMA_TO_DEVICE); | ||
127 | } | ||
128 | if (desc->pq_check_result) { | ||
129 | dma_unmap_page(dev, pdest, len, DMA_TO_DEVICE); | ||
130 | dma_unmap_page(dev, qdest, len, DMA_TO_DEVICE); | ||
131 | } | ||
132 | } | ||
133 | |||
134 | desc->group_head = NULL; | ||
135 | } | ||
136 | |||
137 | |||
138 | static dma_cookie_t | 64 | static dma_cookie_t |
139 | iop_adma_run_tx_complete_actions(struct iop_adma_desc_slot *desc, | 65 | iop_adma_run_tx_complete_actions(struct iop_adma_desc_slot *desc, |
140 | struct iop_adma_chan *iop_chan, dma_cookie_t cookie) | 66 | struct iop_adma_chan *iop_chan, dma_cookie_t cookie) |
@@ -152,15 +78,9 @@ iop_adma_run_tx_complete_actions(struct iop_adma_desc_slot *desc, | |||
152 | if (tx->callback) | 78 | if (tx->callback) |
153 | tx->callback(tx->callback_param); | 79 | tx->callback(tx->callback_param); |
154 | 80 | ||
155 | /* unmap dma addresses | 81 | dma_descriptor_unmap(tx); |
156 | * (unmap_single vs unmap_page?) | 82 | if (desc->group_head) |
157 | */ | 83 | desc->group_head = NULL; |
158 | if (desc->group_head && desc->unmap_len) { | ||
159 | if (iop_desc_is_pq(desc)) | ||
160 | iop_desc_unmap_pq(iop_chan, desc); | ||
161 | else | ||
162 | iop_desc_unmap(iop_chan, desc); | ||
163 | } | ||
164 | } | 84 | } |
165 | 85 | ||
166 | /* run dependent operations */ | 86 | /* run dependent operations */ |
@@ -591,7 +511,6 @@ iop_adma_prep_dma_interrupt(struct dma_chan *chan, unsigned long flags) | |||
591 | if (sw_desc) { | 511 | if (sw_desc) { |
592 | grp_start = sw_desc->group_head; | 512 | grp_start = sw_desc->group_head; |
593 | iop_desc_init_interrupt(grp_start, iop_chan); | 513 | iop_desc_init_interrupt(grp_start, iop_chan); |
594 | grp_start->unmap_len = 0; | ||
595 | sw_desc->async_tx.flags = flags; | 514 | sw_desc->async_tx.flags = flags; |
596 | } | 515 | } |
597 | spin_unlock_bh(&iop_chan->lock); | 516 | spin_unlock_bh(&iop_chan->lock); |
@@ -623,8 +542,6 @@ iop_adma_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dma_dest, | |||
623 | iop_desc_set_byte_count(grp_start, iop_chan, len); | 542 | iop_desc_set_byte_count(grp_start, iop_chan, len); |
624 | iop_desc_set_dest_addr(grp_start, iop_chan, dma_dest); | 543 | iop_desc_set_dest_addr(grp_start, iop_chan, dma_dest); |
625 | iop_desc_set_memcpy_src_addr(grp_start, dma_src); | 544 | iop_desc_set_memcpy_src_addr(grp_start, dma_src); |
626 | sw_desc->unmap_src_cnt = 1; | ||
627 | sw_desc->unmap_len = len; | ||
628 | sw_desc->async_tx.flags = flags; | 545 | sw_desc->async_tx.flags = flags; |
629 | } | 546 | } |
630 | spin_unlock_bh(&iop_chan->lock); | 547 | spin_unlock_bh(&iop_chan->lock); |
@@ -657,8 +574,6 @@ iop_adma_prep_dma_xor(struct dma_chan *chan, dma_addr_t dma_dest, | |||
657 | iop_desc_init_xor(grp_start, src_cnt, flags); | 574 | iop_desc_init_xor(grp_start, src_cnt, flags); |
658 | iop_desc_set_byte_count(grp_start, iop_chan, len); | 575 | iop_desc_set_byte_count(grp_start, iop_chan, len); |
659 | iop_desc_set_dest_addr(grp_start, iop_chan, dma_dest); | 576 | iop_desc_set_dest_addr(grp_start, iop_chan, dma_dest); |
660 | sw_desc->unmap_src_cnt = src_cnt; | ||
661 | sw_desc->unmap_len = len; | ||
662 | sw_desc->async_tx.flags = flags; | 577 | sw_desc->async_tx.flags = flags; |
663 | while (src_cnt--) | 578 | while (src_cnt--) |
664 | iop_desc_set_xor_src_addr(grp_start, src_cnt, | 579 | iop_desc_set_xor_src_addr(grp_start, src_cnt, |
@@ -694,8 +609,6 @@ iop_adma_prep_dma_xor_val(struct dma_chan *chan, dma_addr_t *dma_src, | |||
694 | grp_start->xor_check_result = result; | 609 | grp_start->xor_check_result = result; |
695 | pr_debug("\t%s: grp_start->xor_check_result: %p\n", | 610 | pr_debug("\t%s: grp_start->xor_check_result: %p\n", |
696 | __func__, grp_start->xor_check_result); | 611 | __func__, grp_start->xor_check_result); |
697 | sw_desc->unmap_src_cnt = src_cnt; | ||
698 | sw_desc->unmap_len = len; | ||
699 | sw_desc->async_tx.flags = flags; | 612 | sw_desc->async_tx.flags = flags; |
700 | while (src_cnt--) | 613 | while (src_cnt--) |
701 | iop_desc_set_zero_sum_src_addr(grp_start, src_cnt, | 614 | iop_desc_set_zero_sum_src_addr(grp_start, src_cnt, |
@@ -748,8 +661,6 @@ iop_adma_prep_dma_pq(struct dma_chan *chan, dma_addr_t *dst, dma_addr_t *src, | |||
748 | dst[0] = dst[1] & 0x7; | 661 | dst[0] = dst[1] & 0x7; |
749 | 662 | ||
750 | iop_desc_set_pq_addr(g, dst); | 663 | iop_desc_set_pq_addr(g, dst); |
751 | sw_desc->unmap_src_cnt = src_cnt; | ||
752 | sw_desc->unmap_len = len; | ||
753 | sw_desc->async_tx.flags = flags; | 664 | sw_desc->async_tx.flags = flags; |
754 | for (i = 0; i < src_cnt; i++) | 665 | for (i = 0; i < src_cnt; i++) |
755 | iop_desc_set_pq_src_addr(g, i, src[i], scf[i]); | 666 | iop_desc_set_pq_src_addr(g, i, src[i], scf[i]); |
@@ -804,8 +715,6 @@ iop_adma_prep_dma_pq_val(struct dma_chan *chan, dma_addr_t *pq, dma_addr_t *src, | |||
804 | g->pq_check_result = pqres; | 715 | g->pq_check_result = pqres; |
805 | pr_debug("\t%s: g->pq_check_result: %p\n", | 716 | pr_debug("\t%s: g->pq_check_result: %p\n", |
806 | __func__, g->pq_check_result); | 717 | __func__, g->pq_check_result); |
807 | sw_desc->unmap_src_cnt = src_cnt+2; | ||
808 | sw_desc->unmap_len = len; | ||
809 | sw_desc->async_tx.flags = flags; | 718 | sw_desc->async_tx.flags = flags; |
810 | while (src_cnt--) | 719 | while (src_cnt--) |
811 | iop_desc_set_pq_zero_sum_src_addr(g, src_cnt, | 720 | iop_desc_set_pq_zero_sum_src_addr(g, src_cnt, |