diff options
Diffstat (limited to 'drivers/dma')
-rw-r--r-- | drivers/dma/dmatest.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index 224acf478fec..a27c0fb1bc11 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c | |||
@@ -196,6 +196,11 @@ static unsigned int dmatest_verify(u8 **bufs, unsigned int start, | |||
196 | return error_count; | 196 | return error_count; |
197 | } | 197 | } |
198 | 198 | ||
199 | static void dmatest_callback(void *completion) | ||
200 | { | ||
201 | complete(completion); | ||
202 | } | ||
203 | |||
199 | /* | 204 | /* |
200 | * This function repeatedly tests DMA transfers of various lengths and | 205 | * This function repeatedly tests DMA transfers of various lengths and |
201 | * offsets for a given operation type until it is told to exit by | 206 | * offsets for a given operation type until it is told to exit by |
@@ -261,13 +266,17 @@ static int dmatest_func(void *data) | |||
261 | } | 266 | } |
262 | thread->dsts[i] = NULL; | 267 | thread->dsts[i] = NULL; |
263 | 268 | ||
264 | flags = DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP; | 269 | set_user_nice(current, 10); |
270 | |||
271 | flags = DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP | DMA_PREP_INTERRUPT; | ||
265 | 272 | ||
266 | while (!kthread_should_stop()) { | 273 | while (!kthread_should_stop()) { |
267 | struct dma_device *dev = chan->device; | 274 | struct dma_device *dev = chan->device; |
268 | struct dma_async_tx_descriptor *tx = NULL; | 275 | struct dma_async_tx_descriptor *tx = NULL; |
269 | dma_addr_t dma_srcs[src_cnt]; | 276 | dma_addr_t dma_srcs[src_cnt]; |
270 | dma_addr_t dma_dsts[dst_cnt]; | 277 | dma_addr_t dma_dsts[dst_cnt]; |
278 | struct completion cmp; | ||
279 | unsigned long tmo = msecs_to_jiffies(3000); | ||
271 | 280 | ||
272 | total_tests++; | 281 | total_tests++; |
273 | 282 | ||
@@ -318,7 +327,10 @@ static int dmatest_func(void *data) | |||
318 | failed_tests++; | 327 | failed_tests++; |
319 | continue; | 328 | continue; |
320 | } | 329 | } |
321 | tx->callback = NULL; | 330 | |
331 | init_completion(&cmp); | ||
332 | tx->callback = dmatest_callback; | ||
333 | tx->callback_param = &cmp; | ||
322 | cookie = tx->tx_submit(tx); | 334 | cookie = tx->tx_submit(tx); |
323 | 335 | ||
324 | if (dma_submit_error(cookie)) { | 336 | if (dma_submit_error(cookie)) { |
@@ -332,18 +344,23 @@ static int dmatest_func(void *data) | |||
332 | } | 344 | } |
333 | dma_async_issue_pending(chan); | 345 | dma_async_issue_pending(chan); |
334 | 346 | ||
335 | do { | 347 | tmo = wait_for_completion_timeout(&cmp, tmo); |
336 | msleep(1); | 348 | status = dma_async_is_tx_complete(chan, cookie, NULL, NULL); |
337 | status = dma_async_is_tx_complete( | ||
338 | chan, cookie, NULL, NULL); | ||
339 | } while (status == DMA_IN_PROGRESS); | ||
340 | 349 | ||
341 | if (status == DMA_ERROR) { | 350 | if (tmo == 0) { |
342 | pr_warning("%s: #%u: error during copy\n", | 351 | pr_warning("%s: #%u: test timed out\n", |
343 | thread_name, total_tests - 1); | 352 | thread_name, total_tests - 1); |
353 | failed_tests++; | ||
354 | continue; | ||
355 | } else if (status != DMA_SUCCESS) { | ||
356 | pr_warning("%s: #%u: got completion callback," | ||
357 | " but status is \'%s\'\n", | ||
358 | thread_name, total_tests - 1, | ||
359 | status == DMA_ERROR ? "error" : "in progress"); | ||
344 | failed_tests++; | 360 | failed_tests++; |
345 | continue; | 361 | continue; |
346 | } | 362 | } |
363 | |||
347 | /* Unmap by myself (see DMA_COMPL_SKIP_DEST_UNMAP above) */ | 364 | /* Unmap by myself (see DMA_COMPL_SKIP_DEST_UNMAP above) */ |
348 | for (i = 0; i < dst_cnt; i++) | 365 | for (i = 0; i < dst_cnt; i++) |
349 | dma_unmap_single(dev->dev, dma_dsts[i], test_buf_size, | 366 | dma_unmap_single(dev->dev, dma_dsts[i], test_buf_size, |