diff options
-rw-r--r-- | Documentation/dmatest.txt | 15 | ||||
-rw-r--r-- | drivers/dma/dmatest.c | 159 |
2 files changed, 28 insertions, 146 deletions
diff --git a/Documentation/dmatest.txt b/Documentation/dmatest.txt index 132a094c7bc3..a2b5663eae26 100644 --- a/Documentation/dmatest.txt +++ b/Documentation/dmatest.txt | |||
@@ -16,15 +16,16 @@ be built as module or inside kernel. Let's consider those cases. | |||
16 | Part 2 - When dmatest is built as a module... | 16 | Part 2 - When dmatest is built as a module... |
17 | 17 | ||
18 | After mounting debugfs and loading the module, the /sys/kernel/debug/dmatest | 18 | After mounting debugfs and loading the module, the /sys/kernel/debug/dmatest |
19 | folder with nodes will be created. They are the same as module parameters with | 19 | folder with nodes will be created. There are two important files located. First |
20 | addition of the 'run' node that controls run and stop phases of the test. | 20 | is the 'run' node that controls run and stop phases of the test, and the second |
21 | one, 'results', is used to get the test case results. | ||
21 | 22 | ||
22 | Note that in this case test will not run on load automatically. | 23 | Note that in this case test will not run on load automatically. |
23 | 24 | ||
24 | Example of usage: | 25 | Example of usage: |
25 | % echo dma0chan0 > /sys/kernel/debug/dmatest/channel | 26 | % echo dma0chan0 > /sys/module/dmatest/parameters/channel |
26 | % echo 2000 > /sys/kernel/debug/dmatest/timeout | 27 | % echo 2000 > /sys/module/dmatest/parameters/timeout |
27 | % echo 1 > /sys/kernel/debug/dmatest/iterations | 28 | % echo 1 > /sys/module/dmatest/parameters/iterations |
28 | % echo 1 > /sys/kernel/debug/dmatest/run | 29 | % echo 1 > /sys/kernel/debug/dmatest/run |
29 | 30 | ||
30 | Hint: available channel list could be extracted by running the following | 31 | Hint: available channel list could be extracted by running the following |
@@ -55,8 +56,8 @@ for the first performed test. After user gets a control, the test could be | |||
55 | re-run with the same or different parameters. For the details see the above | 56 | re-run with the same or different parameters. For the details see the above |
56 | section "Part 2 - When dmatest is built as a module..." | 57 | section "Part 2 - When dmatest is built as a module..." |
57 | 58 | ||
58 | In both cases the module parameters are used as initial values for the test case. | 59 | In both cases the module parameters are used as the actual values for the test |
59 | You always could check them at run-time by running | 60 | case. You always could check them at run-time by running |
60 | % grep -H . /sys/module/dmatest/parameters/* | 61 | % grep -H . /sys/module/dmatest/parameters/* |
61 | 62 | ||
62 | Part 4 - Gathering the test results | 63 | Part 4 - Gathering the test results |
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index e88ded2c8d2f..91716f404c03 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c | |||
@@ -25,44 +25,46 @@ | |||
25 | #include <linux/seq_file.h> | 25 | #include <linux/seq_file.h> |
26 | 26 | ||
27 | static unsigned int test_buf_size = 16384; | 27 | static unsigned int test_buf_size = 16384; |
28 | module_param(test_buf_size, uint, S_IRUGO); | 28 | module_param(test_buf_size, uint, S_IRUGO | S_IWUSR); |
29 | MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer"); | 29 | MODULE_PARM_DESC(test_buf_size, "Size of the memcpy test buffer"); |
30 | 30 | ||
31 | static char test_channel[20]; | 31 | static char test_channel[20]; |
32 | module_param_string(channel, test_channel, sizeof(test_channel), S_IRUGO); | 32 | module_param_string(channel, test_channel, sizeof(test_channel), |
33 | S_IRUGO | S_IWUSR); | ||
33 | MODULE_PARM_DESC(channel, "Bus ID of the channel to test (default: any)"); | 34 | MODULE_PARM_DESC(channel, "Bus ID of the channel to test (default: any)"); |
34 | 35 | ||
35 | static char test_device[20]; | 36 | static char test_device[20]; |
36 | module_param_string(device, test_device, sizeof(test_device), S_IRUGO); | 37 | module_param_string(device, test_device, sizeof(test_device), |
38 | S_IRUGO | S_IWUSR); | ||
37 | MODULE_PARM_DESC(device, "Bus ID of the DMA Engine to test (default: any)"); | 39 | MODULE_PARM_DESC(device, "Bus ID of the DMA Engine to test (default: any)"); |
38 | 40 | ||
39 | static unsigned int threads_per_chan = 1; | 41 | static unsigned int threads_per_chan = 1; |
40 | module_param(threads_per_chan, uint, S_IRUGO); | 42 | module_param(threads_per_chan, uint, S_IRUGO | S_IWUSR); |
41 | MODULE_PARM_DESC(threads_per_chan, | 43 | MODULE_PARM_DESC(threads_per_chan, |
42 | "Number of threads to start per channel (default: 1)"); | 44 | "Number of threads to start per channel (default: 1)"); |
43 | 45 | ||
44 | static unsigned int max_channels; | 46 | static unsigned int max_channels; |
45 | module_param(max_channels, uint, S_IRUGO); | 47 | module_param(max_channels, uint, S_IRUGO | S_IWUSR); |
46 | MODULE_PARM_DESC(max_channels, | 48 | MODULE_PARM_DESC(max_channels, |
47 | "Maximum number of channels to use (default: all)"); | 49 | "Maximum number of channels to use (default: all)"); |
48 | 50 | ||
49 | static unsigned int iterations; | 51 | static unsigned int iterations; |
50 | module_param(iterations, uint, S_IRUGO); | 52 | module_param(iterations, uint, S_IRUGO | S_IWUSR); |
51 | MODULE_PARM_DESC(iterations, | 53 | MODULE_PARM_DESC(iterations, |
52 | "Iterations before stopping test (default: infinite)"); | 54 | "Iterations before stopping test (default: infinite)"); |
53 | 55 | ||
54 | static unsigned int xor_sources = 3; | 56 | static unsigned int xor_sources = 3; |
55 | module_param(xor_sources, uint, S_IRUGO); | 57 | module_param(xor_sources, uint, S_IRUGO | S_IWUSR); |
56 | MODULE_PARM_DESC(xor_sources, | 58 | MODULE_PARM_DESC(xor_sources, |
57 | "Number of xor source buffers (default: 3)"); | 59 | "Number of xor source buffers (default: 3)"); |
58 | 60 | ||
59 | static unsigned int pq_sources = 3; | 61 | static unsigned int pq_sources = 3; |
60 | module_param(pq_sources, uint, S_IRUGO); | 62 | module_param(pq_sources, uint, S_IRUGO | S_IWUSR); |
61 | MODULE_PARM_DESC(pq_sources, | 63 | MODULE_PARM_DESC(pq_sources, |
62 | "Number of p+q source buffers (default: 3)"); | 64 | "Number of p+q source buffers (default: 3)"); |
63 | 65 | ||
64 | static int timeout = 3000; | 66 | static int timeout = 3000; |
65 | module_param(timeout, uint, S_IRUGO); | 67 | module_param(timeout, uint, S_IRUGO | S_IWUSR); |
66 | MODULE_PARM_DESC(timeout, "Transfer Timeout in msec (default: 3000), " | 68 | MODULE_PARM_DESC(timeout, "Transfer Timeout in msec (default: 3000), " |
67 | "Pass -1 for infinite timeout"); | 69 | "Pass -1 for infinite timeout"); |
68 | 70 | ||
@@ -193,7 +195,6 @@ struct dmatest_info { | |||
193 | 195 | ||
194 | /* debugfs related stuff */ | 196 | /* debugfs related stuff */ |
195 | struct dentry *root; | 197 | struct dentry *root; |
196 | struct dmatest_params dbgfs_params; | ||
197 | 198 | ||
198 | /* Test results */ | 199 | /* Test results */ |
199 | struct list_head results; | 200 | struct list_head results; |
@@ -1007,7 +1008,15 @@ static int __restart_threaded_test(struct dmatest_info *info, bool run) | |||
1007 | result_free(info, NULL); | 1008 | result_free(info, NULL); |
1008 | 1009 | ||
1009 | /* Copy test parameters */ | 1010 | /* Copy test parameters */ |
1010 | memcpy(params, &info->dbgfs_params, sizeof(*params)); | 1011 | params->buf_size = test_buf_size; |
1012 | strlcpy(params->channel, strim(test_channel), sizeof(params->channel)); | ||
1013 | strlcpy(params->device, strim(test_device), sizeof(params->device)); | ||
1014 | params->threads_per_chan = threads_per_chan; | ||
1015 | params->max_channels = max_channels; | ||
1016 | params->iterations = iterations; | ||
1017 | params->xor_sources = xor_sources; | ||
1018 | params->pq_sources = pq_sources; | ||
1019 | params->timeout = timeout; | ||
1011 | 1020 | ||
1012 | /* Run test with new parameters */ | 1021 | /* Run test with new parameters */ |
1013 | return __run_threaded_test(info); | 1022 | return __run_threaded_test(info); |
@@ -1029,71 +1038,6 @@ static bool __is_threaded_test_run(struct dmatest_info *info) | |||
1029 | return false; | 1038 | return false; |
1030 | } | 1039 | } |
1031 | 1040 | ||
1032 | static ssize_t dtf_write_string(void *to, size_t available, loff_t *ppos, | ||
1033 | const void __user *from, size_t count) | ||
1034 | { | ||
1035 | char tmp[20]; | ||
1036 | ssize_t len; | ||
1037 | |||
1038 | len = simple_write_to_buffer(tmp, sizeof(tmp) - 1, ppos, from, count); | ||
1039 | if (len >= 0) { | ||
1040 | tmp[len] = '\0'; | ||
1041 | strlcpy(to, strim(tmp), available); | ||
1042 | } | ||
1043 | |||
1044 | return len; | ||
1045 | } | ||
1046 | |||
1047 | static ssize_t dtf_read_channel(struct file *file, char __user *buf, | ||
1048 | size_t count, loff_t *ppos) | ||
1049 | { | ||
1050 | struct dmatest_info *info = file->private_data; | ||
1051 | return simple_read_from_buffer(buf, count, ppos, | ||
1052 | info->dbgfs_params.channel, | ||
1053 | strlen(info->dbgfs_params.channel)); | ||
1054 | } | ||
1055 | |||
1056 | static ssize_t dtf_write_channel(struct file *file, const char __user *buf, | ||
1057 | size_t size, loff_t *ppos) | ||
1058 | { | ||
1059 | struct dmatest_info *info = file->private_data; | ||
1060 | return dtf_write_string(info->dbgfs_params.channel, | ||
1061 | sizeof(info->dbgfs_params.channel), | ||
1062 | ppos, buf, size); | ||
1063 | } | ||
1064 | |||
1065 | static const struct file_operations dtf_channel_fops = { | ||
1066 | .read = dtf_read_channel, | ||
1067 | .write = dtf_write_channel, | ||
1068 | .open = simple_open, | ||
1069 | .llseek = default_llseek, | ||
1070 | }; | ||
1071 | |||
1072 | static ssize_t dtf_read_device(struct file *file, char __user *buf, | ||
1073 | size_t count, loff_t *ppos) | ||
1074 | { | ||
1075 | struct dmatest_info *info = file->private_data; | ||
1076 | return simple_read_from_buffer(buf, count, ppos, | ||
1077 | info->dbgfs_params.device, | ||
1078 | strlen(info->dbgfs_params.device)); | ||
1079 | } | ||
1080 | |||
1081 | static ssize_t dtf_write_device(struct file *file, const char __user *buf, | ||
1082 | size_t size, loff_t *ppos) | ||
1083 | { | ||
1084 | struct dmatest_info *info = file->private_data; | ||
1085 | return dtf_write_string(info->dbgfs_params.device, | ||
1086 | sizeof(info->dbgfs_params.device), | ||
1087 | ppos, buf, size); | ||
1088 | } | ||
1089 | |||
1090 | static const struct file_operations dtf_device_fops = { | ||
1091 | .read = dtf_read_device, | ||
1092 | .write = dtf_write_device, | ||
1093 | .open = simple_open, | ||
1094 | .llseek = default_llseek, | ||
1095 | }; | ||
1096 | |||
1097 | static ssize_t dtf_read_run(struct file *file, char __user *user_buf, | 1041 | static ssize_t dtf_read_run(struct file *file, char __user *user_buf, |
1098 | size_t count, loff_t *ppos) | 1042 | size_t count, loff_t *ppos) |
1099 | { | 1043 | { |
@@ -1187,7 +1131,6 @@ static const struct file_operations dtf_results_fops = { | |||
1187 | static int dmatest_register_dbgfs(struct dmatest_info *info) | 1131 | static int dmatest_register_dbgfs(struct dmatest_info *info) |
1188 | { | 1132 | { |
1189 | struct dentry *d; | 1133 | struct dentry *d; |
1190 | struct dmatest_params *params = &info->dbgfs_params; | ||
1191 | int ret = -ENOMEM; | 1134 | int ret = -ENOMEM; |
1192 | 1135 | ||
1193 | d = debugfs_create_dir("dmatest", NULL); | 1136 | d = debugfs_create_dir("dmatest", NULL); |
@@ -1198,56 +1141,6 @@ static int dmatest_register_dbgfs(struct dmatest_info *info) | |||
1198 | 1141 | ||
1199 | info->root = d; | 1142 | info->root = d; |
1200 | 1143 | ||
1201 | /* Copy initial values */ | ||
1202 | memcpy(params, &info->params, sizeof(*params)); | ||
1203 | |||
1204 | /* Test parameters */ | ||
1205 | |||
1206 | d = debugfs_create_u32("test_buf_size", S_IWUSR | S_IRUGO, info->root, | ||
1207 | (u32 *)¶ms->buf_size); | ||
1208 | if (IS_ERR_OR_NULL(d)) | ||
1209 | goto err_node; | ||
1210 | |||
1211 | d = debugfs_create_file("channel", S_IRUGO | S_IWUSR, info->root, | ||
1212 | info, &dtf_channel_fops); | ||
1213 | if (IS_ERR_OR_NULL(d)) | ||
1214 | goto err_node; | ||
1215 | |||
1216 | d = debugfs_create_file("device", S_IRUGO | S_IWUSR, info->root, | ||
1217 | info, &dtf_device_fops); | ||
1218 | if (IS_ERR_OR_NULL(d)) | ||
1219 | goto err_node; | ||
1220 | |||
1221 | d = debugfs_create_u32("threads_per_chan", S_IWUSR | S_IRUGO, info->root, | ||
1222 | (u32 *)¶ms->threads_per_chan); | ||
1223 | if (IS_ERR_OR_NULL(d)) | ||
1224 | goto err_node; | ||
1225 | |||
1226 | d = debugfs_create_u32("max_channels", S_IWUSR | S_IRUGO, info->root, | ||
1227 | (u32 *)¶ms->max_channels); | ||
1228 | if (IS_ERR_OR_NULL(d)) | ||
1229 | goto err_node; | ||
1230 | |||
1231 | d = debugfs_create_u32("iterations", S_IWUSR | S_IRUGO, info->root, | ||
1232 | (u32 *)¶ms->iterations); | ||
1233 | if (IS_ERR_OR_NULL(d)) | ||
1234 | goto err_node; | ||
1235 | |||
1236 | d = debugfs_create_u32("xor_sources", S_IWUSR | S_IRUGO, info->root, | ||
1237 | (u32 *)¶ms->xor_sources); | ||
1238 | if (IS_ERR_OR_NULL(d)) | ||
1239 | goto err_node; | ||
1240 | |||
1241 | d = debugfs_create_u32("pq_sources", S_IWUSR | S_IRUGO, info->root, | ||
1242 | (u32 *)¶ms->pq_sources); | ||
1243 | if (IS_ERR_OR_NULL(d)) | ||
1244 | goto err_node; | ||
1245 | |||
1246 | d = debugfs_create_u32("timeout", S_IWUSR | S_IRUGO, info->root, | ||
1247 | (u32 *)¶ms->timeout); | ||
1248 | if (IS_ERR_OR_NULL(d)) | ||
1249 | goto err_node; | ||
1250 | |||
1251 | /* Run or stop threaded test */ | 1144 | /* Run or stop threaded test */ |
1252 | d = debugfs_create_file("run", S_IWUSR | S_IRUGO, info->root, | 1145 | d = debugfs_create_file("run", S_IWUSR | S_IRUGO, info->root, |
1253 | info, &dtf_run_fops); | 1146 | info, &dtf_run_fops); |
@@ -1272,7 +1165,6 @@ err_root: | |||
1272 | static int __init dmatest_init(void) | 1165 | static int __init dmatest_init(void) |
1273 | { | 1166 | { |
1274 | struct dmatest_info *info = &test_info; | 1167 | struct dmatest_info *info = &test_info; |
1275 | struct dmatest_params *params = &info->params; | ||
1276 | int ret; | 1168 | int ret; |
1277 | 1169 | ||
1278 | memset(info, 0, sizeof(*info)); | 1170 | memset(info, 0, sizeof(*info)); |
@@ -1283,17 +1175,6 @@ static int __init dmatest_init(void) | |||
1283 | mutex_init(&info->results_lock); | 1175 | mutex_init(&info->results_lock); |
1284 | INIT_LIST_HEAD(&info->results); | 1176 | INIT_LIST_HEAD(&info->results); |
1285 | 1177 | ||
1286 | /* Set default parameters */ | ||
1287 | params->buf_size = test_buf_size; | ||
1288 | strlcpy(params->channel, test_channel, sizeof(params->channel)); | ||
1289 | strlcpy(params->device, test_device, sizeof(params->device)); | ||
1290 | params->threads_per_chan = threads_per_chan; | ||
1291 | params->max_channels = max_channels; | ||
1292 | params->iterations = iterations; | ||
1293 | params->xor_sources = xor_sources; | ||
1294 | params->pq_sources = pq_sources; | ||
1295 | params->timeout = timeout; | ||
1296 | |||
1297 | ret = dmatest_register_dbgfs(info); | 1178 | ret = dmatest_register_dbgfs(info); |
1298 | if (ret) | 1179 | if (ret) |
1299 | return ret; | 1180 | return ret; |