26 #include <linux/kernel.h>
28 #include <linux/module.h>
45 void *cb_param_orig = submit->
cb_param;
53 for (i = 0; i < src_cnt; i++) {
58 dma_src[xor_src_cnt++] = dma_dest;
64 src_cnt = xor_src_cnt;
67 submit->
flags = flags_orig;
74 if (src_cnt > xor_src_cnt) {
81 submit->
cb_fn = cb_fn_orig;
93 xor_src_cnt, len, dma_flags);
100 dma_async_issue_pending(chan);
110 if (src_cnt > xor_src_cnt) {
112 src_cnt -= xor_src_cnt;
113 src_off += xor_src_cnt;
116 dma_src[--src_off] = dma_dest;
126 do_sync_xor(
struct page *dest,
struct page **src_list,
unsigned int offset,
138 srcs = (
void **) src_list;
141 for (i = 0; i < src_cnt; i++)
144 src_cnt = xor_src_cnt;
151 while (src_cnt > 0) {
154 xor_blocks(xor_src_cnt, len, dest_buf, &srcs[src_off]);
157 src_cnt -= xor_src_cnt;
158 src_off += xor_src_cnt;
161 async_tx_sync_epilog(submit);
201 if (dma_src && chan && is_dma_xor_aligned(chan->
device, offset, 0, len)) {
203 pr_debug(
"%s (async): len: %zu\n", __func__, len);
205 return do_async_xor(chan, dest, src_list, offset, src_cnt, len,
209 pr_debug(
"%s (sync): len: %zu\n", __func__, len);
210 WARN_ONCE(chan,
"%s: no space for dma address conversion\n",
224 do_sync_xor(dest, src_list, offset, src_cnt, len, submit);
231 static int page_is_zero(
struct page *
p,
unsigned int offset,
size_t len)
234 return ((*(
u32 *) a) == 0 &&
235 memcmp(a, a + 4, len - 4) == 0);
240 struct page **src_list,
int src_cnt,
size_t len)
242 #ifdef CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA
270 struct dma_chan *chan = xor_val_chan(submit, dest, src_list, src_cnt, len);
282 if (dma_src && device && src_cnt <= device->max_xor &&
283 is_dma_xor_aligned(device, offset, 0, len)) {
284 unsigned long dma_prep_flags = 0;
287 pr_debug(
"%s: (async) len: %zu\n", __func__, len);
293 for (i = 0; i < src_cnt; i++)
304 dma_async_issue_pending(chan);
306 dma_src, src_cnt, len, result,
315 pr_debug(
"%s: (sync) len: %zu\n", __func__, len);
316 WARN_ONCE(device && src_cnt <= device->max_xor,
317 "%s: no space for dma address conversion\n",
323 tx =
async_xor(dest, src_list, offset, src_cnt, len, submit);
327 *result = !page_is_zero(dest, offset, len) <<
SUM_CHECK_P;
329 async_tx_sync_epilog(submit);
330 submit->
flags = flags_orig;