16 #include <linux/module.h>
18 #include <linux/random.h>
19 #include <linux/slab.h>
20 #include <linux/wait.h>
22 static unsigned int test_buf_size = 16384;
26 static char test_channel[20];
30 static char test_device[20];
34 static unsigned int threads_per_chan = 1;
37 "Number of threads to start per channel (default: 1)");
39 static unsigned int max_channels;
42 "Maximum number of channels to use (default: all)");
44 static unsigned int iterations;
47 "Iterations before stopping test (default: infinite)");
49 static unsigned int xor_sources = 3;
52 "Number of xor source buffers (default: 3)");
54 static unsigned int pq_sources = 3;
57 "Number of p+q source buffers (default: 3)");
62 "Pass -1 for infinite timeout");
75 #define PATTERN_SRC 0x80
76 #define PATTERN_DST 0x00
77 #define PATTERN_COPY 0x40
78 #define PATTERN_OVERWRITE 0x20
79 #define PATTERN_COUNT_MASK 0x1f
101 static unsigned int nr_channels;
103 static bool dmatest_match_channel(
struct dma_chan *
chan)
105 if (test_channel[0] ==
'\0')
107 return strcmp(dma_chan_name(chan), test_channel) == 0;
112 if (test_device[0] ==
'\0')
114 return strcmp(dev_name(device->
dev), test_device) == 0;
117 static unsigned long dmatest_random(
void)
125 static void dmatest_init_srcs(
u8 **
bufs,
unsigned int start,
unsigned int len)
130 for (; (buf = *
bufs); bufs++) {
131 for (i = 0; i <
start; i++)
133 for ( ; i < start + len; i++)
135 | (~i & PATTERN_COUNT_MASK);
136 for ( ; i < test_buf_size; i++)
142 static void dmatest_init_dsts(
u8 **bufs,
unsigned int start,
unsigned int len)
147 for (; (buf = *
bufs); bufs++) {
148 for (i = 0; i <
start; i++)
150 for ( ; i < start + len; i++)
152 | (~i & PATTERN_COUNT_MASK);
153 for ( ; i < test_buf_size; i++)
159 unsigned int counter,
bool is_srcbuf)
167 " Expected %02x, got %02x\n",
168 thread_name, index, expected, actual);
172 " Expected %02x, got %02x\n",
173 thread_name, index, expected, actual);
176 " Expected %02x, got %02x\n",
177 thread_name, index, expected, actual);
180 " Expected %02x, got %02x\n",
181 thread_name, index, expected, actual);
184 static unsigned int dmatest_verify(
u8 **bufs,
unsigned int start,
185 unsigned int end,
unsigned int counter,
u8 pattern,
189 unsigned int error_count = 0;
193 unsigned int counter_orig =
counter;
195 for (; (buf = *
bufs); bufs++) {
196 counter = counter_orig;
197 for (i = start; i <
end; i++) {
200 if (actual != expected) {
201 if (error_count < 32)
202 dmatest_mismatch(actual, pattern, i,
210 if (error_count > 32)
212 current->comm, error_count - 32);
223 static void dmatest_callback(
void *
arg)
245 static int dmatest_func(
void *
data)
252 unsigned int src_off, dst_off, len;
253 unsigned int error_count;
254 unsigned int failed_tests = 0;
255 unsigned int total_tests = 0;
259 u8 pq_coefs[pq_sources + 1];
273 src_cnt = dst_cnt = 1;
275 src_cnt = xor_sources | 1;
278 src_cnt = pq_sources | 1;
280 for (i = 0; i < src_cnt; i++)
288 for (i = 0; i < src_cnt; i++) {
290 if (!thread->
srcs[i])
298 for (i = 0; i < dst_cnt; i++) {
300 if (!thread->
dsts[i])
315 && !(iterations && total_tests >= iterations)) {
332 if (1 << align > test_buf_size) {
333 pr_err(
"%u-byte buffer too small for %d-byte alignment\n",
334 test_buf_size, 1 << align);
338 len = dmatest_random() % test_buf_size + 1;
339 len = (len >>
align) << align;
342 src_off = dmatest_random() % (test_buf_size - len + 1);
343 dst_off = dmatest_random() % (test_buf_size - len + 1);
345 src_off = (src_off >>
align) << align;
346 dst_off = (dst_off >>
align) << align;
348 dmatest_init_srcs(thread->
srcs, src_off, len);
349 dmatest_init_dsts(thread->
dsts, dst_off, len);
351 for (i = 0; i < src_cnt; i++) {
352 u8 *buf = thread->
srcs[
i] + src_off;
358 for (i = 0; i < dst_cnt; i++) {
367 dma_dsts[0] + dst_off,
372 dma_dsts[0] + dst_off,
378 for (i = 0; i < dst_cnt; i++)
379 dma_pq[i] = dma_dsts[i] + dst_off;
386 for (i = 0; i < src_cnt; i++)
389 for (i = 0; i < dst_cnt; i++)
393 pr_warning(
"%s: #%u: prep error with src_off=0x%x "
394 "dst_off=0x%x len=0x%x\n",
395 thread_name, total_tests - 1,
396 src_off, dst_off, len);
408 pr_warning(
"%s: #%u: submit error %d with src_off=0x%x "
409 "dst_off=0x%x len=0x%x\n",
410 thread_name, total_tests - 1, cookie,
411 src_off, dst_off, len);
416 dma_async_issue_pending(chan);
421 status = dma_async_is_tx_complete(chan, cookie,
NULL,
NULL);
433 thread_name, total_tests - 1);
437 pr_warning(
"%s: #%u: got completion callback,"
438 " but status is \'%s\'\n",
439 thread_name, total_tests - 1,
440 status ==
DMA_ERROR ?
"error" :
"in progress");
446 for (i = 0; i < dst_cnt; i++)
452 pr_debug(
"%s: verifying source buffer...\n", thread_name);
453 error_count += dmatest_verify(thread->
srcs, 0, src_off,
455 error_count += dmatest_verify(thread->
srcs, src_off,
456 src_off + len, src_off,
458 error_count += dmatest_verify(thread->
srcs, src_off + len,
459 test_buf_size, src_off + len,
462 pr_debug(
"%s: verifying dest buffer...\n",
464 error_count += dmatest_verify(thread->
dsts, 0, dst_off,
466 error_count += dmatest_verify(thread->
dsts, dst_off,
467 dst_off + len, src_off,
469 error_count += dmatest_verify(thread->
dsts, dst_off + len,
470 test_buf_size, dst_off + len,
475 "src_off=0x%x dst_off=0x%x len=0x%x\n",
476 thread_name, total_tests - 1, error_count,
477 src_off, dst_off, len);
481 "src_off=0x%x dst_off=0x%x len=0x%x\n",
482 thread_name, total_tests - 1,
483 src_off, dst_off, len);
488 for (i = 0; thread->
dsts[
i]; i++)
493 for (i = 0; thread->
srcs[
i]; i++)
498 pr_notice(
"%s: terminating after %u tests, %u failures (status %d)\n",
499 thread_name, total_tests, failed_tests, ret);
512 static void dmatest_cleanup_channel(
struct dmatest_chan *dtc)
520 pr_debug(
"dmatest: thread %s exited with status %d\n",
521 thread->
task->comm, ret);
548 for (i = 0; i < threads_per_chan; i++) {
551 pr_warning(
"dmatest: No memory for %s-%s%u\n",
552 dma_chan_name(chan), op, i);
560 dma_chan_name(chan), op, i);
561 if (IS_ERR(thread->
task)) {
562 pr_warning(
"dmatest: Failed to run thread %s-%s%u\n",
563 dma_chan_name(chan), op, i);
576 static int dmatest_add_channel(
struct dma_chan *chan)
580 unsigned int thread_count = 0;
585 pr_warning(
"dmatest: No memory for %s\n", dma_chan_name(chan));
594 thread_count += cnt > 0 ? cnt : 0;
597 cnt = dmatest_add_threads(dtc,
DMA_XOR);
598 thread_count += cnt > 0 ? cnt : 0;
601 cnt = dmatest_add_threads(dtc,
DMA_PQ);
602 thread_count += cnt > 0 ? cnt : 0;
605 pr_info(
"dmatest: Started %u threads using %s\n",
606 thread_count, dma_chan_name(chan));
616 if (!dmatest_match_channel(chan) || !dmatest_match_device(chan->
device))
622 static int __init dmatest_init(
void)
633 err = dmatest_add_channel(chan);
640 if (max_channels && nr_channels >= max_channels)
649 static void __exit dmatest_exit(
void)
657 dmatest_cleanup_channel(dtc);
658 pr_debug(
"dmatest: dropped channel %s\n",
659 dma_chan_name(chan));