blob: bad5eb8d791797a39453f646eb348d8cea675dc4 [file] [log] [blame]
Tatyana Brokhman09b010d2012-10-09 13:50:56 +02001/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14/* MMC block test */
15
16#include <linux/module.h>
17#include <linux/blkdev.h>
18#include <linux/debugfs.h>
19#include <linux/mmc/card.h>
20#include <linux/mmc/host.h>
21#include <linux/delay.h>
22#include <linux/test-iosched.h>
23#include "queue.h"
24
25#define MODULE_NAME "mmc_block_test"
26#define TEST_MAX_SECTOR_RANGE (600*1024*1024) /* 600 MB */
27#define TEST_MAX_BIOS_PER_REQ 120
28#define CMD23_PACKED_BIT (1 << 30)
29#define LARGE_PRIME_1 1103515367
30#define LARGE_PRIME_2 35757
31#define PACKED_HDR_VER_MASK 0x000000FF
32#define PACKED_HDR_RW_MASK 0x0000FF00
33#define PACKED_HDR_NUM_REQS_MASK 0x00FF0000
34#define PACKED_HDR_BITS_16_TO_29_SET 0x3FFF0000
35
36#define test_pr_debug(fmt, args...) pr_debug("%s: "fmt"\n", MODULE_NAME, args)
37#define test_pr_info(fmt, args...) pr_info("%s: "fmt"\n", MODULE_NAME, args)
38#define test_pr_err(fmt, args...) pr_err("%s: "fmt"\n", MODULE_NAME, args)
39
40enum is_random {
41 NON_RANDOM_TEST,
42 RANDOM_TEST,
43};
44
45enum mmc_block_test_testcases {
46 /* Start of send write packing test group */
47 SEND_WRITE_PACKING_MIN_TESTCASE,
48 TEST_STOP_DUE_TO_READ = SEND_WRITE_PACKING_MIN_TESTCASE,
49 TEST_STOP_DUE_TO_READ_AFTER_MAX_REQS,
50 TEST_STOP_DUE_TO_FLUSH,
51 TEST_STOP_DUE_TO_FLUSH_AFTER_MAX_REQS,
52 TEST_STOP_DUE_TO_EMPTY_QUEUE,
53 TEST_STOP_DUE_TO_MAX_REQ_NUM,
54 TEST_STOP_DUE_TO_THRESHOLD,
55 SEND_WRITE_PACKING_MAX_TESTCASE = TEST_STOP_DUE_TO_THRESHOLD,
56
57 /* Start of err check test group */
58 ERR_CHECK_MIN_TESTCASE,
59 TEST_RET_ABORT = ERR_CHECK_MIN_TESTCASE,
60 TEST_RET_PARTIAL_FOLLOWED_BY_SUCCESS,
61 TEST_RET_PARTIAL_FOLLOWED_BY_ABORT,
62 TEST_RET_PARTIAL_MULTIPLE_UNTIL_SUCCESS,
63 TEST_RET_PARTIAL_MAX_FAIL_IDX,
64 TEST_RET_RETRY,
65 TEST_RET_CMD_ERR,
66 TEST_RET_DATA_ERR,
67 ERR_CHECK_MAX_TESTCASE = TEST_RET_DATA_ERR,
68
69 /* Start of send invalid test group */
70 INVALID_CMD_MIN_TESTCASE,
71 TEST_HDR_INVALID_VERSION = INVALID_CMD_MIN_TESTCASE,
72 TEST_HDR_WRONG_WRITE_CODE,
73 TEST_HDR_INVALID_RW_CODE,
74 TEST_HDR_DIFFERENT_ADDRESSES,
75 TEST_HDR_REQ_NUM_SMALLER_THAN_ACTUAL,
76 TEST_HDR_REQ_NUM_LARGER_THAN_ACTUAL,
77 TEST_HDR_CMD23_PACKED_BIT_SET,
78 TEST_CMD23_MAX_PACKED_WRITES,
79 TEST_CMD23_ZERO_PACKED_WRITES,
80 TEST_CMD23_PACKED_BIT_UNSET,
81 TEST_CMD23_REL_WR_BIT_SET,
82 TEST_CMD23_BITS_16TO29_SET,
83 TEST_CMD23_HDR_BLK_NOT_IN_COUNT,
84 INVALID_CMD_MAX_TESTCASE = TEST_CMD23_HDR_BLK_NOT_IN_COUNT,
85};
86
87enum mmc_block_test_group {
88 TEST_NO_GROUP,
89 TEST_GENERAL_GROUP,
90 TEST_SEND_WRITE_PACKING_GROUP,
91 TEST_ERR_CHECK_GROUP,
92 TEST_SEND_INVALID_GROUP,
93};
94
95struct mmc_block_test_debug {
96 struct dentry *send_write_packing_test;
97 struct dentry *err_check_test;
98 struct dentry *send_invalid_packed_test;
99 struct dentry *random_test_seed;
100};
101
102struct mmc_block_test_data {
103 /* The number of write requests that the test will issue */
104 int num_requests;
105 /* The expected write packing statistics for the current test */
106 struct mmc_wr_pack_stats exp_packed_stats;
107 /*
108 * A user-defined seed for random choices of number of bios written in
109 * a request, and of number of requests issued in a test
110 * This field is randomly updated after each use
111 */
112 unsigned int random_test_seed;
113 /* A retry counter used in err_check tests */
114 int err_check_counter;
115 /* Can be one of the values of enum test_group */
116 enum mmc_block_test_group test_group;
117 /*
118 * Indicates if the current testcase is running with random values of
119 * num_requests and num_bios (in each request)
120 */
121 int is_random;
122 /* Data structure for debugfs dentrys */
123 struct mmc_block_test_debug debug;
124 /*
125 * Data structure containing individual test information, including
126 * self-defined specific data
127 */
128 struct test_info test_info;
129 /* mmc block device test */
130 struct blk_dev_test_type bdt;
131};
132
133static struct mmc_block_test_data *mbtd;
134
135/*
136 * A callback assigned to the packed_test_fn field.
137 * Called from block layer in mmc_blk_packed_hdr_wrq_prep.
138 * Here we alter the packed header or CMD23 in order to send an invalid
139 * packed command to the card.
140 */
141static void test_invalid_packed_cmd(struct request_queue *q,
142 struct mmc_queue_req *mqrq)
143{
144 struct mmc_queue *mq = q->queuedata;
145 u32 *packed_cmd_hdr = mqrq->packed_cmd_hdr;
146 struct request *req = mqrq->req;
147 struct request *second_rq;
148 struct test_request *test_rq;
149 struct mmc_blk_request *brq = &mqrq->brq;
150 int num_requests;
151 int max_packed_reqs;
152
153 if (!mq) {
154 test_pr_err("%s: NULL mq", __func__);
155 return;
156 }
157
158 test_rq = (struct test_request *)req->elv.priv[0];
159 if (!test_rq) {
160 test_pr_err("%s: NULL test_rq", __func__);
161 return;
162 }
163 max_packed_reqs = mq->card->ext_csd.max_packed_writes;
164
165 switch (mbtd->test_info.testcase) {
166 case TEST_HDR_INVALID_VERSION:
167 test_pr_info("%s: set invalid header version", __func__);
168 /* Put 0 in header version field (1 byte, offset 0 in header) */
169 packed_cmd_hdr[0] = packed_cmd_hdr[0] & ~PACKED_HDR_VER_MASK;
170 break;
171 case TEST_HDR_WRONG_WRITE_CODE:
172 test_pr_info("%s: wrong write code", __func__);
173 /* Set R/W field with R value (1 byte, offset 1 in header) */
174 packed_cmd_hdr[0] = packed_cmd_hdr[0] & ~PACKED_HDR_RW_MASK;
175 packed_cmd_hdr[0] = packed_cmd_hdr[0] | 0x00000100;
176 break;
177 case TEST_HDR_INVALID_RW_CODE:
178 test_pr_info("%s: invalid r/w code", __func__);
179 /* Set R/W field with invalid value */
180 packed_cmd_hdr[0] = packed_cmd_hdr[0] & ~PACKED_HDR_RW_MASK;
181 packed_cmd_hdr[0] = packed_cmd_hdr[0] | 0x00000400;
182 break;
183 case TEST_HDR_DIFFERENT_ADDRESSES:
184 test_pr_info("%s: different addresses", __func__);
185 second_rq = list_entry(req->queuelist.next, struct request,
186 queuelist);
187 test_pr_info("%s: test_rq->sector=%ld, second_rq->sector=%ld",
188 __func__, (long)req->__sector,
189 (long)second_rq->__sector);
190 /*
191 * Put start sector of second write request in the first write
192 * request's cmd25 argument in the packed header
193 */
194 packed_cmd_hdr[3] = second_rq->__sector;
195 break;
196 case TEST_HDR_REQ_NUM_SMALLER_THAN_ACTUAL:
197 test_pr_info("%s: request num smaller than actual" , __func__);
198 num_requests = (packed_cmd_hdr[0] & PACKED_HDR_NUM_REQS_MASK)
199 >> 16;
200 /* num of entries is decremented by 1 */
201 num_requests = (num_requests - 1) << 16;
202 /*
203 * Set number of requests field in packed write header to be
204 * smaller than the actual number (1 byte, offset 2 in header)
205 */
206 packed_cmd_hdr[0] = (packed_cmd_hdr[0] &
207 ~PACKED_HDR_NUM_REQS_MASK) + num_requests;
208 break;
209 case TEST_HDR_REQ_NUM_LARGER_THAN_ACTUAL:
210 test_pr_info("%s: request num larger than actual" , __func__);
211 num_requests = (packed_cmd_hdr[0] & PACKED_HDR_NUM_REQS_MASK)
212 >> 16;
213 /* num of entries is incremented by 1 */
214 num_requests = (num_requests + 1) << 16;
215 /*
216 * Set number of requests field in packed write header to be
217 * larger than the actual number (1 byte, offset 2 in header).
218 */
219 packed_cmd_hdr[0] = (packed_cmd_hdr[0] &
220 ~PACKED_HDR_NUM_REQS_MASK) + num_requests;
221 break;
222 case TEST_HDR_CMD23_PACKED_BIT_SET:
223 test_pr_info("%s: header CMD23 packed bit set" , __func__);
224 /*
225 * Set packed bit (bit 30) in cmd23 argument of first and second
226 * write requests in packed write header.
227 * These are located at bytes 2 and 4 in packed write header
228 */
229 packed_cmd_hdr[2] = packed_cmd_hdr[2] | CMD23_PACKED_BIT;
230 packed_cmd_hdr[4] = packed_cmd_hdr[4] | CMD23_PACKED_BIT;
231 break;
232 case TEST_CMD23_MAX_PACKED_WRITES:
233 test_pr_info("%s: CMD23 request num > max_packed_reqs",
234 __func__);
235 /*
236 * Set the individual packed cmd23 request num to
237 * max_packed_reqs + 1
238 */
239 brq->sbc.arg = MMC_CMD23_ARG_PACKED | (max_packed_reqs + 1);
240 break;
241 case TEST_CMD23_ZERO_PACKED_WRITES:
242 test_pr_info("%s: CMD23 request num = 0", __func__);
243 /* Set the individual packed cmd23 request num to zero */
244 brq->sbc.arg = MMC_CMD23_ARG_PACKED;
245 break;
246 case TEST_CMD23_PACKED_BIT_UNSET:
247 test_pr_info("%s: CMD23 packed bit unset", __func__);
248 /*
249 * Set the individual packed cmd23 packed bit to 0,
250 * although there is a packed write request
251 */
252 brq->sbc.arg &= ~CMD23_PACKED_BIT;
253 break;
254 case TEST_CMD23_REL_WR_BIT_SET:
255 test_pr_info("%s: CMD23 REL WR bit set", __func__);
256 /* Set the individual packed cmd23 reliable write bit */
257 brq->sbc.arg = MMC_CMD23_ARG_PACKED | MMC_CMD23_ARG_REL_WR;
258 break;
259 case TEST_CMD23_BITS_16TO29_SET:
260 test_pr_info("%s: CMD23 bits [16-29] set", __func__);
261 brq->sbc.arg = MMC_CMD23_ARG_PACKED |
262 PACKED_HDR_BITS_16_TO_29_SET;
263 break;
264 case TEST_CMD23_HDR_BLK_NOT_IN_COUNT:
265 test_pr_info("%s: CMD23 hdr not in block count", __func__);
266 brq->sbc.arg = MMC_CMD23_ARG_PACKED |
267 ((rq_data_dir(req) == READ) ? 0 : mqrq->packed_blocks);
268 break;
269 default:
270 test_pr_err("%s: unexpected testcase %d",
271 __func__, mbtd->test_info.testcase);
272 break;
273 }
274}
275
276/*
277 * A callback assigned to the err_check_fn field of the mmc_request by the
278 * MMC/card/block layer.
279 * Called upon request completion by the MMC/core layer.
280 * Here we emulate an error return value from the card.
281 */
282static int test_err_check(struct mmc_card *card, struct mmc_async_req *areq)
283{
284 struct mmc_queue_req *mq_rq = container_of(areq, struct mmc_queue_req,
285 mmc_active);
286 struct request_queue *req_q = test_iosched_get_req_queue();
287 struct mmc_queue *mq;
288 int max_packed_reqs;
289 int ret = 0;
290
291 if (req_q)
292 mq = req_q->queuedata;
293 else {
294 test_pr_err("%s: NULL request_queue", __func__);
295 return 0;
296 }
297
298 if (!mq) {
299 test_pr_err("%s: %s: NULL mq", __func__,
300 mmc_hostname(card->host));
301 return 0;
302 }
303
304 max_packed_reqs = mq->card->ext_csd.max_packed_writes;
305
306 if (!mq_rq) {
307 test_pr_err("%s: %s: NULL mq_rq", __func__,
308 mmc_hostname(card->host));
309 return 0;
310 }
311
312 switch (mbtd->test_info.testcase) {
313 case TEST_RET_ABORT:
314 test_pr_info("%s: return abort", __func__);
315 ret = MMC_BLK_ABORT;
316 break;
317 case TEST_RET_PARTIAL_FOLLOWED_BY_SUCCESS:
318 test_pr_info("%s: return partial followed by success",
319 __func__);
320 /*
321 * Since in this testcase num_requests is always >= 2,
322 * we can be sure that packed_fail_idx is always >= 1
323 */
324 mq_rq->packed_fail_idx = (mbtd->num_requests / 2);
325 test_pr_info("%s: packed_fail_idx = %d"
326 , __func__, mq_rq->packed_fail_idx);
327 mq->err_check_fn = NULL;
328 ret = MMC_BLK_PARTIAL;
329 break;
330 case TEST_RET_PARTIAL_FOLLOWED_BY_ABORT:
331 if (!mbtd->err_check_counter) {
332 test_pr_info("%s: return partial followed by abort",
333 __func__);
334 mbtd->err_check_counter++;
335 /*
336 * Since in this testcase num_requests is always >= 3,
337 * we have that packed_fail_idx is always >= 1
338 */
339 mq_rq->packed_fail_idx = (mbtd->num_requests / 2);
340 test_pr_info("%s: packed_fail_idx = %d"
341 , __func__, mq_rq->packed_fail_idx);
342 ret = MMC_BLK_PARTIAL;
343 break;
344 }
345 mbtd->err_check_counter = 0;
346 mq->err_check_fn = NULL;
347 ret = MMC_BLK_ABORT;
348 break;
349 case TEST_RET_PARTIAL_MULTIPLE_UNTIL_SUCCESS:
350 test_pr_info("%s: return partial multiple until success",
351 __func__);
352 if (++mbtd->err_check_counter >= (mbtd->num_requests)) {
353 mq->err_check_fn = NULL;
354 mbtd->err_check_counter = 0;
355 ret = MMC_BLK_PARTIAL;
356 break;
357 }
358 mq_rq->packed_fail_idx = 1;
359 ret = MMC_BLK_PARTIAL;
360 break;
361 case TEST_RET_PARTIAL_MAX_FAIL_IDX:
362 test_pr_info("%s: return partial max fail_idx", __func__);
363 mq_rq->packed_fail_idx = max_packed_reqs - 1;
364 mq->err_check_fn = NULL;
365 ret = MMC_BLK_PARTIAL;
366 break;
367 case TEST_RET_RETRY:
368 test_pr_info("%s: return retry", __func__);
369 ret = MMC_BLK_RETRY;
370 break;
371 case TEST_RET_CMD_ERR:
372 test_pr_info("%s: return cmd err", __func__);
373 ret = MMC_BLK_CMD_ERR;
374 break;
375 case TEST_RET_DATA_ERR:
376 test_pr_info("%s: return data err", __func__);
377 ret = MMC_BLK_DATA_ERR;
378 break;
379 default:
380 test_pr_err("%s: unexpected testcase %d",
381 __func__, mbtd->test_info.testcase);
382 }
383
384 return ret;
385}
386
387/*
388 * This is a specific implementation for the get_test_case_str_fn function
389 * pointer in the test_info data structure. Given a valid test_data instance,
390 * the function returns a string resembling the test name, based on the testcase
391 */
392static char *get_test_case_str(struct test_data *td)
393{
394 if (!td) {
395 test_pr_err("%s: NULL td", __func__);
396 return NULL;
397 }
398
399 switch (td->test_info.testcase) {
400 case TEST_STOP_DUE_TO_FLUSH:
401 return "Test stop due to flush";
402 case TEST_STOP_DUE_TO_FLUSH_AFTER_MAX_REQS:
403 return "Test stop due to flush after max-1 reqs";
404 case TEST_STOP_DUE_TO_READ:
405 return "Test stop due to read";
406 case TEST_STOP_DUE_TO_READ_AFTER_MAX_REQS:
407 return "Test stop due to read after max-1 reqs";
408 case TEST_STOP_DUE_TO_EMPTY_QUEUE:
409 return "Test stop due to empty queue";
410 case TEST_STOP_DUE_TO_MAX_REQ_NUM:
411 return "Test stop due to max req num";
412 case TEST_STOP_DUE_TO_THRESHOLD:
413 return "Test stop due to exceeding threshold";
414 case TEST_RET_ABORT:
415 return "Test err_check return abort";
416 case TEST_RET_PARTIAL_FOLLOWED_BY_SUCCESS:
417 return "Test err_check return partial followed by success";
418 case TEST_RET_PARTIAL_FOLLOWED_BY_ABORT:
419 return "Test err_check return partial followed by abort";
420 case TEST_RET_PARTIAL_MULTIPLE_UNTIL_SUCCESS:
421 return "Test err_check return partial multiple until success";
422 case TEST_RET_PARTIAL_MAX_FAIL_IDX:
423 return "Test err_check return partial max fail index";
424 case TEST_RET_RETRY:
425 return "Test err_check return retry";
426 case TEST_RET_CMD_ERR:
427 return "Test err_check return cmd error";
428 case TEST_RET_DATA_ERR:
429 return "Test err_check return data error";
430 case TEST_HDR_INVALID_VERSION:
431 return "Test invalid - wrong header version";
432 case TEST_HDR_WRONG_WRITE_CODE:
433 return "Test invalid - wrong write code";
434 case TEST_HDR_INVALID_RW_CODE:
435 return "Test invalid - wrong R/W code";
436 case TEST_HDR_DIFFERENT_ADDRESSES:
437 return "Test invalid - header different addresses";
438 case TEST_HDR_REQ_NUM_SMALLER_THAN_ACTUAL:
439 return "Test invalid - header req num smaller than actual";
440 case TEST_HDR_REQ_NUM_LARGER_THAN_ACTUAL:
441 return "Test invalid - header req num larger than actual";
442 case TEST_HDR_CMD23_PACKED_BIT_SET:
443 return "Test invalid - header cmd23 packed bit set";
444 case TEST_CMD23_MAX_PACKED_WRITES:
445 return "Test invalid - cmd23 max packed writes";
446 case TEST_CMD23_ZERO_PACKED_WRITES:
447 return "Test invalid - cmd23 zero packed writes";
448 case TEST_CMD23_PACKED_BIT_UNSET:
449 return "Test invalid - cmd23 packed bit unset";
450 case TEST_CMD23_REL_WR_BIT_SET:
451 return "Test invalid - cmd23 rel wr bit set";
452 case TEST_CMD23_BITS_16TO29_SET:
453 return "Test invalid - cmd23 bits [16-29] set";
454 case TEST_CMD23_HDR_BLK_NOT_IN_COUNT:
455 return "Test invalid - cmd23 header block not in count";
456 default:
457 return "Unknown testcase";
458 }
459
460 return NULL;
461}
462
463/*
464 * Compare individual testcase's statistics to the expected statistics:
465 * Compare stop reason and number of packing events
466 */
467static int check_wr_packing_statistics(struct test_data *td)
468{
469 struct mmc_wr_pack_stats *mmc_packed_stats;
470 struct mmc_queue *mq = td->req_q->queuedata;
471 int max_packed_reqs = mq->card->ext_csd.max_packed_writes;
472 int i;
473 struct mmc_card *card = mq->card;
474 struct mmc_wr_pack_stats expected_stats;
475 int *stop_reason;
476 int ret = 0;
477
478 if (!mq) {
479 test_pr_err("%s: NULL mq", __func__);
480 return -EINVAL;
481 }
482
483 expected_stats = mbtd->exp_packed_stats;
484
485 mmc_packed_stats = mmc_blk_get_packed_statistics(card);
486 if (!mmc_packed_stats) {
487 test_pr_err("%s: NULL mmc_packed_stats", __func__);
488 return -EINVAL;
489 }
490
491 if (!mmc_packed_stats->packing_events) {
492 test_pr_err("%s: NULL packing_events", __func__);
493 return -EINVAL;
494 }
495
496 spin_lock(&mmc_packed_stats->lock);
497
498 if (!mmc_packed_stats->enabled) {
499 test_pr_err("%s write packing statistics are not enabled",
500 __func__);
501 ret = -EINVAL;
502 goto exit_err;
503 }
504
505 stop_reason = mmc_packed_stats->pack_stop_reason;
506
507 for (i = 1 ; i <= max_packed_reqs ; ++i) {
508 if (mmc_packed_stats->packing_events[i] !=
509 expected_stats.packing_events[i]) {
510 test_pr_err(
511 "%s: Wrong pack stats in index %d, got %d, expected %d",
512 __func__, i, mmc_packed_stats->packing_events[i],
513 expected_stats.packing_events[i]);
514 if (td->fs_wr_reqs_during_test)
515 goto cancel_round;
516 ret = -EINVAL;
517 goto exit_err;
518 }
519 }
520
521 if (mmc_packed_stats->pack_stop_reason[EXCEEDS_SEGMENTS] !=
522 expected_stats.pack_stop_reason[EXCEEDS_SEGMENTS]) {
523 test_pr_err(
524 "%s: Wrong pack stop reason EXCEEDS_SEGMENTS %d, expected %d",
525 __func__, stop_reason[EXCEEDS_SEGMENTS],
526 expected_stats.pack_stop_reason[EXCEEDS_SEGMENTS]);
527 if (td->fs_wr_reqs_during_test)
528 goto cancel_round;
529 ret = -EINVAL;
530 goto exit_err;
531 }
532
533 if (mmc_packed_stats->pack_stop_reason[EXCEEDS_SECTORS] !=
534 expected_stats.pack_stop_reason[EXCEEDS_SECTORS]) {
535 test_pr_err(
536 "%s: Wrong pack stop reason EXCEEDS_SECTORS %d, expected %d",
537 __func__, stop_reason[EXCEEDS_SECTORS],
538 expected_stats.pack_stop_reason[EXCEEDS_SECTORS]);
539 if (td->fs_wr_reqs_during_test)
540 goto cancel_round;
541 ret = -EINVAL;
542 goto exit_err;
543 }
544
545 if (mmc_packed_stats->pack_stop_reason[WRONG_DATA_DIR] !=
546 expected_stats.pack_stop_reason[WRONG_DATA_DIR]) {
547 test_pr_err(
548 "%s: Wrong pack stop reason WRONG_DATA_DIR %d, expected %d",
549 __func__, stop_reason[WRONG_DATA_DIR],
550 expected_stats.pack_stop_reason[WRONG_DATA_DIR]);
551 if (td->fs_wr_reqs_during_test)
552 goto cancel_round;
553 ret = -EINVAL;
554 goto exit_err;
555 }
556
557 if (mmc_packed_stats->pack_stop_reason[FLUSH_OR_DISCARD] !=
558 expected_stats.pack_stop_reason[FLUSH_OR_DISCARD]) {
559 test_pr_err(
560 "%s: Wrong pack stop reason FLUSH_OR_DISCARD %d, expected %d",
561 __func__, stop_reason[FLUSH_OR_DISCARD],
562 expected_stats.pack_stop_reason[FLUSH_OR_DISCARD]);
563 if (td->fs_wr_reqs_during_test)
564 goto cancel_round;
565 ret = -EINVAL;
566 goto exit_err;
567 }
568
569 if (mmc_packed_stats->pack_stop_reason[EMPTY_QUEUE] !=
570 expected_stats.pack_stop_reason[EMPTY_QUEUE]) {
571 test_pr_err(
572 "%s: Wrong pack stop reason EMPTY_QUEUE %d, expected %d",
573 __func__, stop_reason[EMPTY_QUEUE],
574 expected_stats.pack_stop_reason[EMPTY_QUEUE]);
575 if (td->fs_wr_reqs_during_test)
576 goto cancel_round;
577 ret = -EINVAL;
578 goto exit_err;
579 }
580
581 if (mmc_packed_stats->pack_stop_reason[REL_WRITE] !=
582 expected_stats.pack_stop_reason[REL_WRITE]) {
583 test_pr_err(
584 "%s: Wrong pack stop reason REL_WRITE %d, expected %d",
585 __func__, stop_reason[REL_WRITE],
586 expected_stats.pack_stop_reason[REL_WRITE]);
587 if (td->fs_wr_reqs_during_test)
588 goto cancel_round;
589 ret = -EINVAL;
590 goto exit_err;
591 }
592
593exit_err:
594 spin_unlock(&mmc_packed_stats->lock);
595 if (ret && mmc_packed_stats->enabled)
596 print_mmc_packing_stats(card);
597 return ret;
598cancel_round:
599 spin_unlock(&mmc_packed_stats->lock);
600 test_iosched_set_ignore_round(true);
601 return 0;
602}
603
604/*
605 * Pseudo-randomly choose a seed based on the last seed, and update it in
606 * seed_number. then return seed_number (mod max_val), or min_val.
607 */
608static unsigned int pseudo_random_seed(unsigned int *seed_number,
609 unsigned int min_val,
610 unsigned int max_val)
611{
612 int ret = 0;
613
614 if (!seed_number)
615 return 0;
616
617 *seed_number = ((unsigned int)(((unsigned long)*seed_number *
618 (unsigned long)LARGE_PRIME_1) + LARGE_PRIME_2));
619 ret = (unsigned int)((*seed_number) % max_val);
620
621 return (ret > min_val ? ret : min_val);
622}
623
624/*
625 * Given a pseudo-random seed, find a pseudo-random num_of_bios.
626 * Make sure that num_of_bios is not larger than TEST_MAX_SECTOR_RANGE
627 */
628static void pseudo_rnd_num_of_bios(unsigned int *num_bios_seed,
629 unsigned int *num_of_bios)
630{
631 do {
632 *num_of_bios = pseudo_random_seed(num_bios_seed, 1,
633 TEST_MAX_BIOS_PER_REQ);
634 if (!(*num_of_bios))
635 *num_of_bios = 1;
636 } while ((*num_of_bios) * BIO_U32_SIZE * 4 > TEST_MAX_SECTOR_RANGE);
637}
638
639/* Add a single read request to the given td's request queue */
640static int prepare_request_add_read(struct test_data *td)
641{
642 int ret;
643 int start_sec;
644
645 if (td)
646 start_sec = td->start_sector;
647 else {
648 test_pr_err("%s: NULL td", __func__);
649 return 0;
650 }
651
652 test_pr_info("%s: Adding a read request, first req_id=%d", __func__,
653 td->wr_rd_next_req_id);
654
655 ret = test_iosched_add_wr_rd_test_req(0, READ, start_sec, 2,
656 TEST_PATTERN_5A, NULL);
657 if (ret) {
658 test_pr_err("%s: failed to add a read request", __func__);
659 return ret;
660 }
661
662 return 0;
663}
664
665/* Add a single flush request to the given td's request queue */
666static int prepare_request_add_flush(struct test_data *td)
667{
668 int ret;
669
670 if (!td) {
671 test_pr_err("%s: NULL td", __func__);
672 return 0;
673 }
674
675 test_pr_info("%s: Adding a flush request, first req_id=%d", __func__,
676 td->unique_next_req_id);
677 ret = test_iosched_add_unique_test_req(0, REQ_UNIQUE_FLUSH,
678 0, 0, NULL);
679 if (ret) {
680 test_pr_err("%s: failed to add a flush request", __func__);
681 return ret;
682 }
683
684 return ret;
685}
686
687/*
688 * Add num_requets amount of write requests to the given td's request queue.
689 * If random test mode is chosen we pseudo-randomly choose the number of bios
690 * for each write request, otherwise add between 1 to 5 bio per request.
691 */
692static int prepare_request_add_write_reqs(struct test_data *td,
693 int num_requests, int is_err_expected,
694 int is_random)
695{
696 int i;
697 unsigned int start_sec;
698 int num_bios;
699 int ret = 0;
700 unsigned int *bio_seed = &mbtd->random_test_seed;
701
702 if (td)
703 start_sec = td->start_sector;
704 else {
705 test_pr_err("%s: NULL td", __func__);
706 return ret;
707 }
708
709 test_pr_info("%s: Adding %d write requests, first req_id=%d", __func__,
710 num_requests, td->wr_rd_next_req_id);
711
712 for (i = 1 ; i <= num_requests ; i++) {
713 start_sec = td->start_sector + 4096 * td->num_of_write_bios;
714 if (is_random)
715 pseudo_rnd_num_of_bios(bio_seed, &num_bios);
716 else
717 /*
718 * For the non-random case, give num_bios a value
719 * between 1 and 5, to keep a small number of BIOs
720 */
721 num_bios = (i%5)+1;
722
723 ret = test_iosched_add_wr_rd_test_req(is_err_expected, WRITE,
724 start_sec, num_bios, TEST_PATTERN_5A, NULL);
725
726 if (ret) {
727 test_pr_err("%s: failed to add a write request",
728 __func__);
729 return ret;
730 }
731 }
732 return 0;
733}
734
735/*
736 * Prepare the write, read and flush requests for a generic packed commands
737 * testcase
738 */
739static int prepare_packed_requests(struct test_data *td, int is_err_expected,
740 int num_requests, int is_random)
741{
742 int ret = 0;
743 struct mmc_queue *mq;
744 int max_packed_reqs;
745 struct request_queue *req_q;
746
747 if (!td) {
748 pr_err("%s: NULL td", __func__);
749 return -EINVAL;
750 }
751
752 req_q = td->req_q;
753
754 if (!req_q) {
755 pr_err("%s: NULL request queue", __func__);
756 return -EINVAL;
757 }
758
759 mq = req_q->queuedata;
760 if (!mq) {
761 test_pr_err("%s: NULL mq", __func__);
762 return -EINVAL;
763 }
764
765 max_packed_reqs = mq->card->ext_csd.max_packed_writes;
766
767 if (mbtd->random_test_seed <= 0) {
768 mbtd->random_test_seed =
769 (unsigned int)(get_jiffies_64() & 0xFFFF);
770 test_pr_info("%s: got seed from jiffies %d",
771 __func__, mbtd->random_test_seed);
772 }
773
774 mmc_blk_init_packed_statistics(mq->card);
775
776 ret = prepare_request_add_write_reqs(td, num_requests, is_err_expected,
777 is_random);
778 if (ret)
779 return ret;
780
781 /* Avoid memory corruption in upcoming stats set */
782 if (td->test_info.testcase == TEST_STOP_DUE_TO_THRESHOLD)
783 num_requests--;
784
785 memset((void *)mbtd->exp_packed_stats.pack_stop_reason, 0,
786 sizeof(mbtd->exp_packed_stats.pack_stop_reason));
787 memset(mbtd->exp_packed_stats.packing_events, 0,
788 (max_packed_reqs + 1) * sizeof(u32));
789 if (num_requests <= max_packed_reqs)
790 mbtd->exp_packed_stats.packing_events[num_requests] = 1;
791
792 switch (td->test_info.testcase) {
793 case TEST_STOP_DUE_TO_FLUSH:
794 case TEST_STOP_DUE_TO_FLUSH_AFTER_MAX_REQS:
795 ret = prepare_request_add_flush(td);
796 if (ret)
797 return ret;
798
799 mbtd->exp_packed_stats.pack_stop_reason[FLUSH_OR_DISCARD] = 1;
800 break;
801 case TEST_STOP_DUE_TO_READ:
802 case TEST_STOP_DUE_TO_READ_AFTER_MAX_REQS:
803 ret = prepare_request_add_read(td);
804 if (ret)
805 return ret;
806
807 mbtd->exp_packed_stats.pack_stop_reason[WRONG_DATA_DIR] = 1;
808 break;
809 case TEST_STOP_DUE_TO_THRESHOLD:
810 mbtd->exp_packed_stats.packing_events[num_requests] = 1;
811 mbtd->exp_packed_stats.packing_events[1] = 1;
812 mbtd->exp_packed_stats.pack_stop_reason[THRESHOLD] = 1;
813 mbtd->exp_packed_stats.pack_stop_reason[EMPTY_QUEUE] = 1;
814 break;
815 case TEST_STOP_DUE_TO_MAX_REQ_NUM:
816 case TEST_RET_PARTIAL_MAX_FAIL_IDX:
817 mbtd->exp_packed_stats.pack_stop_reason[THRESHOLD] = 1;
818 break;
819 default:
820 mbtd->exp_packed_stats.pack_stop_reason[EMPTY_QUEUE] = 1;
821 }
822 mbtd->num_requests = num_requests;
823
824 return 0;
825}
826
827/*
828 * Prepare requests for the TEST_RET_PARTIAL_FOLLOWED_BY_ABORT testcase.
829 * In this testcase we have mixed error expectations from different
830 * write requests, hence the special prepare function.
831 */
832static int prepare_partial_followed_by_abort(struct test_data *td,
833 int num_requests)
834{
835 int i, start_address;
836 int is_err_expected = 0;
837 int ret = 0;
838 struct mmc_queue *mq = test_iosched_get_req_queue()->queuedata;
839 int max_packed_reqs;
840
841 if (!mq) {
842 test_pr_err("%s: NULL mq", __func__);
843 return -EINVAL;
844 }
845
846 max_packed_reqs = mq->card->ext_csd.max_packed_writes;
847
848 mmc_blk_init_packed_statistics(mq->card);
849
850 for (i = 1 ; i <= num_requests ; i++) {
851 if (i > (num_requests / 2))
852 is_err_expected = 1;
853
854 start_address = td->start_sector + 4096*td->num_of_write_bios;
855 ret = test_iosched_add_wr_rd_test_req(is_err_expected, WRITE,
856 start_address, (i%5)+1, TEST_PATTERN_5A, NULL);
857 if (ret) {
858 test_pr_err("%s: failed to add a write request",
859 __func__);
860 return ret;
861 }
862 }
863
864 memset((void *)&mbtd->exp_packed_stats.pack_stop_reason, 0,
865 sizeof(mbtd->exp_packed_stats.pack_stop_reason));
866 memset(mbtd->exp_packed_stats.packing_events, 0,
867 (max_packed_reqs + 1) * sizeof(u32));
868 mbtd->exp_packed_stats.packing_events[num_requests] = 1;
869 mbtd->exp_packed_stats.pack_stop_reason[EMPTY_QUEUE] = 1;
870
871 mbtd->num_requests = num_requests;
872
873 return ret;
874}
875
876/*
877 * Get number of write requests for current testcase. If random test mode was
878 * chosen, pseudo-randomly choose the number of requests, otherwise set to
879 * two less than the packing threshold.
880 */
881static int get_num_requests(struct test_data *td)
882{
883 int *seed = &mbtd->random_test_seed;
884 struct request_queue *req_q;
885 struct mmc_queue *mq;
886 int max_num_requests;
887 int num_requests;
888 int min_num_requests = 2;
889 int is_random = mbtd->is_random;
890
891 req_q = test_iosched_get_req_queue();
892 if (req_q)
893 mq = req_q->queuedata;
894 else {
895 test_pr_err("%s: NULL request queue", __func__);
896 return 0;
897 }
898
899 if (!mq) {
900 test_pr_err("%s: NULL mq", __func__);
901 return -EINVAL;
902 }
903
904 max_num_requests = mq->card->ext_csd.max_packed_writes;
905 num_requests = max_num_requests - 2;
906
907 if (is_random) {
908 if (td->test_info.testcase ==
909 TEST_RET_PARTIAL_FOLLOWED_BY_ABORT)
910 min_num_requests = 3;
911
912 num_requests = pseudo_random_seed(seed, min_num_requests,
913 max_num_requests - 1);
914 }
915
916 return num_requests;
917}
918
919/*
920 * An implementation for the prepare_test_fn pointer in the test_info
921 * data structure. According to the testcase we add the right number of requests
922 * and decide if an error is expected or not.
923 */
924static int prepare_test(struct test_data *td)
925{
926 struct mmc_queue *mq = test_iosched_get_req_queue()->queuedata;
927 int max_num_requests;
928 int num_requests = 0;
929 int ret = 0;
930 int is_random = mbtd->is_random;
931
932 if (!mq) {
933 test_pr_err("%s: NULL mq", __func__);
934 return -EINVAL;
935 }
936
937 max_num_requests = mq->card->ext_csd.max_packed_writes;
938
939 if (is_random && mbtd->random_test_seed == 0) {
940 mbtd->random_test_seed =
941 (unsigned int)(get_jiffies_64() & 0xFFFF);
942 test_pr_info("%s: got seed from jiffies %d",
943 __func__, mbtd->random_test_seed);
944 }
945
946 num_requests = get_num_requests(td);
947
948 if (mbtd->test_group == TEST_SEND_INVALID_GROUP)
949 mq->packed_test_fn =
950 test_invalid_packed_cmd;
951
952 if (mbtd->test_group == TEST_ERR_CHECK_GROUP)
953 mq->err_check_fn = test_err_check;
954
955 switch (td->test_info.testcase) {
956 case TEST_STOP_DUE_TO_FLUSH:
957 case TEST_STOP_DUE_TO_READ:
958 case TEST_RET_PARTIAL_FOLLOWED_BY_SUCCESS:
959 case TEST_RET_PARTIAL_MULTIPLE_UNTIL_SUCCESS:
960 case TEST_STOP_DUE_TO_EMPTY_QUEUE:
961 case TEST_CMD23_PACKED_BIT_UNSET:
962 ret = prepare_packed_requests(td, 0, num_requests, is_random);
963 break;
964 case TEST_STOP_DUE_TO_FLUSH_AFTER_MAX_REQS:
965 case TEST_STOP_DUE_TO_READ_AFTER_MAX_REQS:
966 ret = prepare_packed_requests(td, 0, max_num_requests - 1,
967 is_random);
968 break;
969 case TEST_RET_PARTIAL_FOLLOWED_BY_ABORT:
970 ret = prepare_partial_followed_by_abort(td, num_requests);
971 break;
972 case TEST_STOP_DUE_TO_MAX_REQ_NUM:
973 case TEST_RET_PARTIAL_MAX_FAIL_IDX:
974 ret = prepare_packed_requests(td, 0, max_num_requests,
975 is_random);
976 break;
977 case TEST_STOP_DUE_TO_THRESHOLD:
978 ret = prepare_packed_requests(td, 0, max_num_requests + 1,
979 is_random);
980 break;
981 case TEST_RET_ABORT:
982 case TEST_RET_RETRY:
983 case TEST_RET_CMD_ERR:
984 case TEST_RET_DATA_ERR:
985 case TEST_HDR_INVALID_VERSION:
986 case TEST_HDR_WRONG_WRITE_CODE:
987 case TEST_HDR_INVALID_RW_CODE:
988 case TEST_HDR_DIFFERENT_ADDRESSES:
989 case TEST_HDR_REQ_NUM_SMALLER_THAN_ACTUAL:
990 case TEST_HDR_REQ_NUM_LARGER_THAN_ACTUAL:
991 case TEST_CMD23_MAX_PACKED_WRITES:
992 case TEST_CMD23_ZERO_PACKED_WRITES:
993 case TEST_CMD23_REL_WR_BIT_SET:
994 case TEST_CMD23_BITS_16TO29_SET:
995 case TEST_CMD23_HDR_BLK_NOT_IN_COUNT:
996 case TEST_HDR_CMD23_PACKED_BIT_SET:
997 ret = prepare_packed_requests(td, 1, num_requests, is_random);
998 break;
999 default:
1000 test_pr_info("%s: Invalid test case...", __func__);
1001 return -EINVAL;
1002 }
1003
1004 return ret;
1005}
1006
1007/*
1008 * An implementation for the post_test_fn in the test_info data structure.
1009 * In our case we just reset the function pointers in the mmc_queue in order for
1010 * the FS to be able to dispatch it's requests correctly after the test is
1011 * finished.
1012 */
1013static int post_test(struct test_data *td)
1014{
1015 struct mmc_queue *mq;
1016
1017 if (!td)
1018 return -EINVAL;
1019
1020 mq = td->req_q->queuedata;
1021
1022 if (!mq) {
1023 test_pr_err("%s: NULL mq", __func__);
1024 return -EINVAL;
1025 }
1026
1027 mq->packed_test_fn = NULL;
1028 mq->err_check_fn = NULL;
1029
1030 return 0;
1031}
1032
1033/*
1034 * This function checks, based on the current test's test_group, that the
1035 * packed commands capability and control are set right. In addition, we check
1036 * if the card supports the packed command feature.
1037 */
1038static int validate_packed_commands_settings(void)
1039{
1040 struct request_queue *req_q;
1041 struct mmc_queue *mq;
1042 int max_num_requests;
1043 struct mmc_host *host;
1044
1045 req_q = test_iosched_get_req_queue();
1046 if (!req_q) {
1047 test_pr_err("%s: test_iosched_get_req_queue failed", __func__);
1048 test_iosched_set_test_result(TEST_FAILED);
1049 return -EINVAL;
1050 }
1051
1052 mq = req_q->queuedata;
1053 if (!mq) {
1054 test_pr_err("%s: NULL mq", __func__);
1055 return -EINVAL;
1056 }
1057
1058 max_num_requests = mq->card->ext_csd.max_packed_writes;
1059 host = mq->card->host;
1060
1061 if (!(host->caps2 && MMC_CAP2_PACKED_WR)) {
1062 test_pr_err("%s: Packed Write capability disabled, exit test",
1063 __func__);
1064 test_iosched_set_test_result(TEST_NOT_SUPPORTED);
1065 return -EINVAL;
1066 }
1067
1068 if (max_num_requests == 0) {
1069 test_pr_err(
1070 "%s: no write packing support, ext_csd.max_packed_writes=%d",
1071 __func__, mq->card->ext_csd.max_packed_writes);
1072 test_iosched_set_test_result(TEST_NOT_SUPPORTED);
1073 return -EINVAL;
1074 }
1075
1076 test_pr_info("%s: max number of packed requests supported is %d ",
1077 __func__, max_num_requests);
1078
1079 switch (mbtd->test_group) {
1080 case TEST_SEND_WRITE_PACKING_GROUP:
1081 case TEST_ERR_CHECK_GROUP:
1082 case TEST_SEND_INVALID_GROUP:
1083 /* disable the packing control */
1084 host->caps2 &= ~MMC_CAP2_PACKED_WR_CONTROL;
1085 break;
1086 default:
1087 break;
1088 }
1089
1090 return 0;
1091}
1092
1093static bool message_repeat;
1094static int test_open(struct inode *inode, struct file *file)
1095{
1096 file->private_data = inode->i_private;
1097 message_repeat = 1;
1098 return 0;
1099}
1100
1101/* send_packing TEST */
1102static ssize_t send_write_packing_test_write(struct file *file,
1103 const char __user *buf,
1104 size_t count,
1105 loff_t *ppos)
1106{
1107 int ret = 0;
1108 int i = 0;
1109 int number = -1;
1110 int j = 0;
1111
1112 test_pr_info("%s: -- send_write_packing TEST --", __func__);
1113
1114 sscanf(buf, "%d", &number);
1115
1116 if (number <= 0)
1117 number = 1;
1118
1119
1120 mbtd->test_group = TEST_SEND_WRITE_PACKING_GROUP;
1121
1122 if (validate_packed_commands_settings())
1123 return count;
1124
1125 if (mbtd->random_test_seed > 0)
1126 test_pr_info("%s: Test seed: %d", __func__,
1127 mbtd->random_test_seed);
1128
1129 memset(&mbtd->test_info, 0, sizeof(struct test_info));
1130
1131 mbtd->test_info.data = mbtd;
1132 mbtd->test_info.prepare_test_fn = prepare_test;
1133 mbtd->test_info.check_test_result_fn = check_wr_packing_statistics;
1134 mbtd->test_info.get_test_case_str_fn = get_test_case_str;
1135 mbtd->test_info.post_test_fn = post_test;
1136
1137 for (i = 0 ; i < number ; ++i) {
1138 test_pr_info("%s: Cycle # %d / %d", __func__, i+1, number);
1139 test_pr_info("%s: ====================", __func__);
1140
1141 for (j = SEND_WRITE_PACKING_MIN_TESTCASE ;
1142 j <= SEND_WRITE_PACKING_MAX_TESTCASE ; j++) {
1143
1144 mbtd->test_info.testcase = j;
1145 mbtd->is_random = RANDOM_TEST;
1146 ret = test_iosched_start_test(&mbtd->test_info);
1147 if (ret)
1148 break;
1149 /* Allow FS requests to be dispatched */
1150 msleep(1000);
1151 mbtd->test_info.testcase = j;
1152 mbtd->is_random = NON_RANDOM_TEST;
1153 ret = test_iosched_start_test(&mbtd->test_info);
1154 if (ret)
1155 break;
1156 /* Allow FS requests to be dispatched */
1157 msleep(1000);
1158 }
1159 }
1160
1161 test_pr_info("%s: Completed all the test cases.", __func__);
1162
1163 return count;
1164}
1165
1166static ssize_t send_write_packing_test_read(struct file *file,
1167 char __user *buffer,
1168 size_t count,
1169 loff_t *offset)
1170{
1171 memset((void *)buffer, 0, count);
1172
1173 snprintf(buffer, count,
1174 "\nsend_write_packing_test\n"
1175 "=========\n"
1176 "Description:\n"
1177 "This test checks the following scenarios\n"
1178 "- Pack due to FLUSH message\n"
1179 "- Pack due to FLUSH after threshold writes\n"
1180 "- Pack due to READ message\n"
1181 "- Pack due to READ after threshold writes\n"
1182 "- Pack due to empty queue\n"
1183 "- Pack due to threshold writes\n"
1184 "- Pack due to one over threshold writes\n");
1185
1186 if (message_repeat == 1) {
1187 message_repeat = 0;
1188 return strnlen(buffer, count);
1189 } else {
1190 return 0;
1191 }
1192}
1193
1194const struct file_operations send_write_packing_test_ops = {
1195 .open = test_open,
1196 .write = send_write_packing_test_write,
1197 .read = send_write_packing_test_read,
1198};
1199
1200/* err_check TEST */
1201static ssize_t err_check_test_write(struct file *file,
1202 const char __user *buf,
1203 size_t count,
1204 loff_t *ppos)
1205{
1206 int ret = 0;
1207 int i = 0;
1208 int number = -1;
1209 int j = 0;
1210
1211 test_pr_info("%s: -- err_check TEST --", __func__);
1212
1213 sscanf(buf, "%d", &number);
1214
1215 if (number <= 0)
1216 number = 1;
1217
1218 mbtd->test_group = TEST_ERR_CHECK_GROUP;
1219
1220 if (validate_packed_commands_settings())
1221 return count;
1222
1223 if (mbtd->random_test_seed > 0)
1224 test_pr_info("%s: Test seed: %d", __func__,
1225 mbtd->random_test_seed);
1226
1227 memset(&mbtd->test_info, 0, sizeof(struct test_info));
1228
1229 mbtd->test_info.data = mbtd;
1230 mbtd->test_info.prepare_test_fn = prepare_test;
1231 mbtd->test_info.check_test_result_fn = check_wr_packing_statistics;
1232 mbtd->test_info.get_test_case_str_fn = get_test_case_str;
1233 mbtd->test_info.post_test_fn = post_test;
1234
1235 for (i = 0 ; i < number ; ++i) {
1236 test_pr_info("%s: Cycle # %d / %d", __func__, i+1, number);
1237 test_pr_info("%s: ====================", __func__);
1238
1239 for (j = ERR_CHECK_MIN_TESTCASE;
1240 j <= ERR_CHECK_MAX_TESTCASE ; j++) {
1241 mbtd->test_info.testcase = j;
1242 mbtd->is_random = RANDOM_TEST;
1243 ret = test_iosched_start_test(&mbtd->test_info);
1244 if (ret)
1245 break;
1246 /* Allow FS requests to be dispatched */
1247 msleep(1000);
1248 mbtd->test_info.testcase = j;
1249 mbtd->is_random = NON_RANDOM_TEST;
1250 ret = test_iosched_start_test(&mbtd->test_info);
1251 if (ret)
1252 break;
1253 /* Allow FS requests to be dispatched */
1254 msleep(1000);
1255 }
1256 }
1257
1258 test_pr_info("%s: Completed all the test cases.", __func__);
1259
1260 return count;
1261}
1262
1263static ssize_t err_check_test_read(struct file *file,
1264 char __user *buffer,
1265 size_t count,
1266 loff_t *offset)
1267{
1268 memset((void *)buffer, 0, count);
1269
1270 snprintf(buffer, count,
1271 "\nerr_check_TEST\n"
1272 "=========\n"
1273 "Description:\n"
1274 "This test checks the following scenarios\n"
1275 "- Return ABORT\n"
1276 "- Return PARTIAL followed by success\n"
1277 "- Return PARTIAL followed by abort\n"
1278 "- Return PARTIAL multiple times until success\n"
1279 "- Return PARTIAL with fail index = threshold\n"
1280 "- Return RETRY\n"
1281 "- Return CMD_ERR\n"
1282 "- Return DATA_ERR\n");
1283
1284 if (message_repeat == 1) {
1285 message_repeat = 0;
1286 return strnlen(buffer, count);
1287 } else {
1288 return 0;
1289 }
1290}
1291
1292const struct file_operations err_check_test_ops = {
1293 .open = test_open,
1294 .write = err_check_test_write,
1295 .read = err_check_test_read,
1296};
1297
1298/* send_invalid_packed TEST */
1299static ssize_t send_invalid_packed_test_write(struct file *file,
1300 const char __user *buf,
1301 size_t count,
1302 loff_t *ppos)
1303{
1304 int ret = 0;
1305 int i = 0;
1306 int number = -1;
1307 int j = 0;
1308 int num_of_failures = 0;
1309
1310 test_pr_info("%s: -- send_invalid_packed TEST --", __func__);
1311
1312 sscanf(buf, "%d", &number);
1313
1314 if (number <= 0)
1315 number = 1;
1316
1317 mbtd->test_group = TEST_SEND_INVALID_GROUP;
1318
1319 if (validate_packed_commands_settings())
1320 return count;
1321
1322 if (mbtd->random_test_seed > 0)
1323 test_pr_info("%s: Test seed: %d", __func__,
1324 mbtd->random_test_seed);
1325
1326 memset(&mbtd->test_info, 0, sizeof(struct test_info));
1327
1328 mbtd->test_info.data = mbtd;
1329 mbtd->test_info.prepare_test_fn = prepare_test;
1330 mbtd->test_info.check_test_result_fn = check_wr_packing_statistics;
1331 mbtd->test_info.get_test_case_str_fn = get_test_case_str;
1332 mbtd->test_info.post_test_fn = post_test;
1333
1334 for (i = 0 ; i < number ; ++i) {
1335 test_pr_info("%s: Cycle # %d / %d", __func__, i+1, number);
1336 test_pr_info("%s: ====================", __func__);
1337
1338 for (j = INVALID_CMD_MIN_TESTCASE;
1339 j <= INVALID_CMD_MAX_TESTCASE ; j++) {
1340
1341 mbtd->test_info.testcase = j;
1342 mbtd->is_random = RANDOM_TEST;
1343 ret = test_iosched_start_test(&mbtd->test_info);
1344 if (ret)
1345 num_of_failures++;
1346 /* Allow FS requests to be dispatched */
1347 msleep(1000);
1348
1349 mbtd->test_info.testcase = j;
1350 mbtd->is_random = NON_RANDOM_TEST;
1351 ret = test_iosched_start_test(&mbtd->test_info);
1352 if (ret)
1353 num_of_failures++;
1354 /* Allow FS requests to be dispatched */
1355 msleep(1000);
1356 }
1357 }
1358
1359 test_pr_info("%s: Completed all the test cases.", __func__);
1360
1361 if (num_of_failures > 0) {
1362 test_iosched_set_test_result(TEST_FAILED);
1363 test_pr_err(
1364 "There were %d failures during the test, TEST FAILED",
1365 num_of_failures);
1366 }
1367 return count;
1368}
1369
1370static ssize_t send_invalid_packed_test_read(struct file *file,
1371 char __user *buffer,
1372 size_t count,
1373 loff_t *offset)
1374{
1375 memset((void *)buffer, 0, count);
1376
1377 snprintf(buffer, count,
1378 "\nsend_invalid_packed_TEST\n"
1379 "=========\n"
1380 "Description:\n"
1381 "This test checks the following scenarios\n"
1382 "- Send an invalid header version\n"
1383 "- Send the wrong write code\n"
1384 "- Send an invalid R/W code\n"
1385 "- Send wrong start address in header\n"
1386 "- Send header with block_count smaller than actual\n"
1387 "- Send header with block_count larger than actual\n"
1388 "- Send header CMD23 packed bit set\n"
1389 "- Send CMD23 with block count over threshold\n"
1390 "- Send CMD23 with block_count equals zero\n"
1391 "- Send CMD23 packed bit unset\n"
1392 "- Send CMD23 reliable write bit set\n"
1393 "- Send CMD23 bits [16-29] set\n"
1394 "- Send CMD23 header block not in block_count\n");
1395
1396 if (message_repeat == 1) {
1397 message_repeat = 0;
1398 return strnlen(buffer, count);
1399 } else {
1400 return 0;
1401 }
1402}
1403
1404const struct file_operations send_invalid_packed_test_ops = {
1405 .open = test_open,
1406 .write = send_invalid_packed_test_write,
1407 .read = send_invalid_packed_test_read,
1408};
1409
1410static void mmc_block_test_debugfs_cleanup(void)
1411{
1412 debugfs_remove(mbtd->debug.random_test_seed);
1413 debugfs_remove(mbtd->debug.send_write_packing_test);
1414 debugfs_remove(mbtd->debug.err_check_test);
1415 debugfs_remove(mbtd->debug.send_invalid_packed_test);
1416}
1417
1418static int mmc_block_test_debugfs_init(void)
1419{
1420 struct dentry *utils_root, *tests_root;
1421
1422 utils_root = test_iosched_get_debugfs_utils_root();
1423 tests_root = test_iosched_get_debugfs_tests_root();
1424
1425 if (!utils_root || !tests_root)
1426 return -EINVAL;
1427
1428 mbtd->debug.random_test_seed = debugfs_create_u32(
1429 "random_test_seed",
1430 S_IRUGO | S_IWUGO,
1431 utils_root,
1432 &mbtd->random_test_seed);
1433
1434 if (!mbtd->debug.random_test_seed)
1435 goto err_nomem;
1436
1437 mbtd->debug.send_write_packing_test =
1438 debugfs_create_file("send_write_packing_test",
1439 S_IRUGO | S_IWUGO,
1440 tests_root,
1441 NULL,
1442 &send_write_packing_test_ops);
1443
1444 if (!mbtd->debug.send_write_packing_test)
1445 goto err_nomem;
1446
1447 mbtd->debug.err_check_test =
1448 debugfs_create_file("err_check_test",
1449 S_IRUGO | S_IWUGO,
1450 tests_root,
1451 NULL,
1452 &err_check_test_ops);
1453
1454 if (!mbtd->debug.err_check_test)
1455 goto err_nomem;
1456
1457 mbtd->debug.send_invalid_packed_test =
1458 debugfs_create_file("send_invalid_packed_test",
1459 S_IRUGO | S_IWUGO,
1460 tests_root,
1461 NULL,
1462 &send_invalid_packed_test_ops);
1463
1464 if (!mbtd->debug.send_invalid_packed_test)
1465 goto err_nomem;
1466
1467 return 0;
1468
1469err_nomem:
1470 mmc_block_test_debugfs_cleanup();
1471 return -ENOMEM;
1472}
1473
1474static void mmc_block_test_probe(void)
1475{
1476 struct request_queue *q = test_iosched_get_req_queue();
1477 struct mmc_queue *mq;
1478 int max_packed_reqs;
1479
1480 if (!q) {
1481 test_pr_err("%s: NULL request queue", __func__);
1482 return;
1483 }
1484
1485 mq = q->queuedata;
1486 if (!mq) {
1487 test_pr_err("%s: NULL mq", __func__);
1488 return;
1489 }
1490
1491 max_packed_reqs = mq->card->ext_csd.max_packed_writes;
1492 mbtd->exp_packed_stats.packing_events =
1493 kzalloc((max_packed_reqs + 1) *
1494 sizeof(*mbtd->exp_packed_stats.packing_events),
1495 GFP_KERNEL);
1496
1497 mmc_block_test_debugfs_init();
1498}
1499
1500static void mmc_block_test_remove(void)
1501{
1502 mmc_block_test_debugfs_cleanup();
1503}
1504
1505static int __init mmc_block_test_init(void)
1506{
1507 mbtd = kzalloc(sizeof(struct mmc_block_test_data), GFP_KERNEL);
1508 if (!mbtd) {
1509 test_pr_err("%s: failed to allocate mmc_block_test_data",
1510 __func__);
1511 return -ENODEV;
1512 }
1513
1514 mbtd->bdt.init_fn = mmc_block_test_probe;
1515 mbtd->bdt.exit_fn = mmc_block_test_remove;
1516 INIT_LIST_HEAD(&mbtd->bdt.list);
1517 test_iosched_register(&mbtd->bdt);
1518
1519 return 0;
1520}
1521
1522static void __exit mmc_block_test_exit(void)
1523{
1524 test_iosched_unregister(&mbtd->bdt);
1525 kfree(mbtd);
1526}
1527
1528module_init(mmc_block_test_init);
1529module_exit(mmc_block_test_exit);
1530
1531MODULE_LICENSE("GPL v2");
1532MODULE_DESCRIPTION("MMC block test");