aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/dmatest.c
diff options
context:
space:
mode:
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>2013-05-23 07:29:53 -0400
committerVinod Koul <vinod.koul@intel.com>2013-06-07 16:43:44 -0400
commitbcc567e3115055a9cc256183d72864f01286be22 (patch)
tree2775e4359ff7d53e8656c07954683135d2e15e0c /drivers/dma/dmatest.c
parent9ecb41bd8cf002fd8f3e063db4df81647ddd623c (diff)
dmatest: do not allow to interrupt ongoing tests
When user interrupts ongoing transfers the dmatest may end up with console lockup, oops, or data mismatch. This patch prevents user to abort any ongoing test. Documentation is updated accordingly. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Reported-by: Will Deacon <will.deacon@arm.com> Tested-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/dma/dmatest.c')
-rw-r--r--drivers/dma/dmatest.c45
1 files changed, 23 insertions, 22 deletions
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index d8ce4ecfef18..e88ded2c8d2f 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -716,8 +716,7 @@ static int dmatest_func(void *data)
716 } 716 }
717 dma_async_issue_pending(chan); 717 dma_async_issue_pending(chan);
718 718
719 wait_event_freezable_timeout(done_wait, 719 wait_event_freezable_timeout(done_wait, done.done,
720 done.done || kthread_should_stop(),
721 msecs_to_jiffies(params->timeout)); 720 msecs_to_jiffies(params->timeout));
722 721
723 status = dma_async_is_tx_complete(chan, cookie, NULL, NULL); 722 status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
@@ -997,7 +996,6 @@ static void stop_threaded_test(struct dmatest_info *info)
997static int __restart_threaded_test(struct dmatest_info *info, bool run) 996static int __restart_threaded_test(struct dmatest_info *info, bool run)
998{ 997{
999 struct dmatest_params *params = &info->params; 998 struct dmatest_params *params = &info->params;
1000 int ret;
1001 999
1002 /* Stop any running test first */ 1000 /* Stop any running test first */
1003 __stop_threaded_test(info); 1001 __stop_threaded_test(info);
@@ -1012,13 +1010,23 @@ static int __restart_threaded_test(struct dmatest_info *info, bool run)
1012 memcpy(params, &info->dbgfs_params, sizeof(*params)); 1010 memcpy(params, &info->dbgfs_params, sizeof(*params));
1013 1011
1014 /* Run test with new parameters */ 1012 /* Run test with new parameters */
1015 ret = __run_threaded_test(info); 1013 return __run_threaded_test(info);
1016 if (ret) { 1014}
1017 __stop_threaded_test(info); 1015
1018 pr_err("dmatest: Can't run test\n"); 1016static bool __is_threaded_test_run(struct dmatest_info *info)
1017{
1018 struct dmatest_chan *dtc;
1019
1020 list_for_each_entry(dtc, &info->channels, node) {
1021 struct dmatest_thread *thread;
1022
1023 list_for_each_entry(thread, &dtc->threads, node) {
1024 if (!thread->done)
1025 return true;
1026 }
1019 } 1027 }
1020 1028
1021 return ret; 1029 return false;
1022} 1030}
1023 1031
1024static ssize_t dtf_write_string(void *to, size_t available, loff_t *ppos, 1032static ssize_t dtf_write_string(void *to, size_t available, loff_t *ppos,
@@ -1091,22 +1099,10 @@ static ssize_t dtf_read_run(struct file *file, char __user *user_buf,
1091{ 1099{
1092 struct dmatest_info *info = file->private_data; 1100 struct dmatest_info *info = file->private_data;
1093 char buf[3]; 1101 char buf[3];
1094 struct dmatest_chan *dtc;
1095 bool alive = false;
1096 1102
1097 mutex_lock(&info->lock); 1103 mutex_lock(&info->lock);
1098 list_for_each_entry(dtc, &info->channels, node) {
1099 struct dmatest_thread *thread;
1100
1101 list_for_each_entry(thread, &dtc->threads, node) {
1102 if (!thread->done) {
1103 alive = true;
1104 break;
1105 }
1106 }
1107 }
1108 1104
1109 if (alive) { 1105 if (__is_threaded_test_run(info)) {
1110 buf[0] = 'Y'; 1106 buf[0] = 'Y';
1111 } else { 1107 } else {
1112 __stop_threaded_test(info); 1108 __stop_threaded_test(info);
@@ -1132,7 +1128,12 @@ static ssize_t dtf_write_run(struct file *file, const char __user *user_buf,
1132 1128
1133 if (strtobool(buf, &bv) == 0) { 1129 if (strtobool(buf, &bv) == 0) {
1134 mutex_lock(&info->lock); 1130 mutex_lock(&info->lock);
1135 ret = __restart_threaded_test(info, bv); 1131
1132 if (__is_threaded_test_run(info))
1133 ret = -EBUSY;
1134 else
1135 ret = __restart_threaded_test(info, bv);
1136
1136 mutex_unlock(&info->lock); 1137 mutex_unlock(&info->lock);
1137 } 1138 }
1138 1139