2 * linux/drivers/mmc/card/mmc_test.c
4 * Copyright 2007-2008 Pierre Ossman
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or (at
9 * your option) any later version.
12 #include <linux/mmc/core.h>
13 #include <linux/mmc/card.h>
14 #include <linux/mmc/host.h>
15 #include <linux/mmc/mmc.h>
17 #include <linux/scatterlist.h>
21 #define RESULT_UNSUP_HOST 2
22 #define RESULT_UNSUP_CARD 3
24 #define BUFFER_ORDER 2
25 #define BUFFER_SIZE (PAGE_SIZE << BUFFER_ORDER)
27 struct mmc_test_card {
28 struct mmc_card *card;
30 u8 scratch[BUFFER_SIZE];
37 /*******************************************************************/
38 /* General helper functions */
39 /*******************************************************************/
42 * Configure correct block size in card
44 static int mmc_test_set_blksize(struct mmc_test_card *test, unsigned size)
46 struct mmc_command cmd;
49 cmd.opcode = MMC_SET_BLOCKLEN;
51 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
52 ret = mmc_wait_for_cmd(test->card->host, &cmd, 0);
60 * Fill in the mmc_request structure given a set of transfer parameters.
62 static void mmc_test_prepare_mrq(struct mmc_test_card *test,
63 struct mmc_request *mrq, struct scatterlist *sg, unsigned sg_len,
64 unsigned dev_addr, unsigned blocks, unsigned blksz, int write)
66 BUG_ON(!mrq || !mrq->cmd || !mrq->data || !mrq->stop);
69 mrq->cmd->opcode = write ?
70 MMC_WRITE_MULTIPLE_BLOCK : MMC_READ_MULTIPLE_BLOCK;
72 mrq->cmd->opcode = write ?
73 MMC_WRITE_BLOCK : MMC_READ_SINGLE_BLOCK;
76 mrq->cmd->arg = dev_addr;
77 mrq->cmd->flags = MMC_RSP_R1 | MMC_CMD_ADTC;
82 mrq->stop->opcode = MMC_STOP_TRANSMISSION;
84 mrq->stop->flags = MMC_RSP_R1B | MMC_CMD_AC;
87 mrq->data->blksz = blksz;
88 mrq->data->blocks = blocks;
89 mrq->data->flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
91 mrq->data->sg_len = sg_len;
93 mmc_set_data_timeout(mrq->data, test->card);
97 * Wait for the card to finish the busy state
99 static int mmc_test_wait_busy(struct mmc_test_card *test)
102 struct mmc_command cmd;
106 memset(&cmd, 0, sizeof(struct mmc_command));
108 cmd.opcode = MMC_SEND_STATUS;
109 cmd.arg = test->card->rca << 16;
110 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
112 ret = mmc_wait_for_cmd(test->card->host, &cmd, 0);
116 if (!busy && !(cmd.resp[0] & R1_READY_FOR_DATA)) {
118 printk(KERN_INFO "%s: Warning: Host did not "
119 "wait for busy state to end.\n",
120 mmc_hostname(test->card->host));
122 } while (!(cmd.resp[0] & R1_READY_FOR_DATA));
128 * Transfer a single sector of kernel addressable data
130 static int mmc_test_buffer_transfer(struct mmc_test_card *test,
131 u8 *buffer, unsigned addr, unsigned blksz, int write)
135 struct mmc_request mrq;
136 struct mmc_command cmd;
137 struct mmc_command stop;
138 struct mmc_data data;
140 struct scatterlist sg;
142 memset(&mrq, 0, sizeof(struct mmc_request));
143 memset(&cmd, 0, sizeof(struct mmc_command));
144 memset(&data, 0, sizeof(struct mmc_data));
145 memset(&stop, 0, sizeof(struct mmc_command));
151 sg_init_one(&sg, buffer, blksz);
153 mmc_test_prepare_mrq(test, &mrq, &sg, 1, addr, 1, blksz, write);
155 mmc_wait_for_req(test->card->host, &mrq);
162 ret = mmc_test_wait_busy(test);
169 /*******************************************************************/
170 /* Test preparation and cleanup */
171 /*******************************************************************/
174 * Fill the first couple of sectors of the card with known data
175 * so that bad reads/writes can be detected
177 static int __mmc_test_prepare(struct mmc_test_card *test, int write)
181 ret = mmc_test_set_blksize(test, 512);
186 memset(test->buffer, 0xDF, 512);
188 for (i = 0;i < 512;i++)
192 for (i = 0;i < BUFFER_SIZE / 512;i++) {
193 ret = mmc_test_buffer_transfer(test, test->buffer, i * 512, 512, 1);
201 static int mmc_test_prepare_write(struct mmc_test_card *test)
203 return __mmc_test_prepare(test, 1);
206 static int mmc_test_prepare_read(struct mmc_test_card *test)
208 return __mmc_test_prepare(test, 0);
211 static int mmc_test_cleanup(struct mmc_test_card *test)
215 ret = mmc_test_set_blksize(test, 512);
219 memset(test->buffer, 0, 512);
221 for (i = 0;i < BUFFER_SIZE / 512;i++) {
222 ret = mmc_test_buffer_transfer(test, test->buffer, i * 512, 512, 1);
230 /*******************************************************************/
231 /* Test execution helpers */
232 /*******************************************************************/
235 * Modifies the mmc_request to perform the "short transfer" tests
237 static void mmc_test_prepare_broken_mrq(struct mmc_test_card *test,
238 struct mmc_request *mrq, int write)
240 BUG_ON(!mrq || !mrq->cmd || !mrq->data);
242 if (mrq->data->blocks > 1) {
243 mrq->cmd->opcode = write ?
244 MMC_WRITE_BLOCK : MMC_READ_SINGLE_BLOCK;
247 mrq->cmd->opcode = MMC_SEND_STATUS;
248 mrq->cmd->arg = test->card->rca << 16;
253 * Checks that a normal transfer didn't have any errors
255 static int mmc_test_check_result(struct mmc_test_card *test,
256 struct mmc_request *mrq)
260 BUG_ON(!mrq || !mrq->cmd || !mrq->data);
264 if (!ret && mrq->cmd->error)
265 ret = mrq->cmd->error;
266 if (!ret && mrq->data->error)
267 ret = mrq->data->error;
268 if (!ret && mrq->stop && mrq->stop->error)
269 ret = mrq->stop->error;
270 if (!ret && mrq->data->bytes_xfered !=
271 mrq->data->blocks * mrq->data->blksz)
275 ret = RESULT_UNSUP_HOST;
281 * Checks that a "short transfer" behaved as expected
283 static int mmc_test_check_broken_result(struct mmc_test_card *test,
284 struct mmc_request *mrq)
288 BUG_ON(!mrq || !mrq->cmd || !mrq->data);
292 if (!ret && mrq->cmd->error)
293 ret = mrq->cmd->error;
294 if (!ret && mrq->data->error == 0)
296 if (!ret && mrq->data->error != -ETIMEDOUT)
297 ret = mrq->data->error;
298 if (!ret && mrq->stop && mrq->stop->error)
299 ret = mrq->stop->error;
300 if (mrq->data->blocks > 1) {
301 if (!ret && mrq->data->bytes_xfered > mrq->data->blksz)
304 if (!ret && mrq->data->bytes_xfered > 0)
309 ret = RESULT_UNSUP_HOST;
315 * Tests a basic transfer with certain parameters
317 static int mmc_test_simple_transfer(struct mmc_test_card *test,
318 struct scatterlist *sg, unsigned sg_len, unsigned dev_addr,
319 unsigned blocks, unsigned blksz, int write)
321 struct mmc_request mrq;
322 struct mmc_command cmd;
323 struct mmc_command stop;
324 struct mmc_data data;
326 memset(&mrq, 0, sizeof(struct mmc_request));
327 memset(&cmd, 0, sizeof(struct mmc_command));
328 memset(&data, 0, sizeof(struct mmc_data));
329 memset(&stop, 0, sizeof(struct mmc_command));
335 mmc_test_prepare_mrq(test, &mrq, sg, sg_len, dev_addr,
336 blocks, blksz, write);
338 mmc_wait_for_req(test->card->host, &mrq);
340 mmc_test_wait_busy(test);
342 return mmc_test_check_result(test, &mrq);
346 * Tests a transfer where the card will fail completely or partly
348 static int mmc_test_broken_transfer(struct mmc_test_card *test,
349 unsigned blocks, unsigned blksz, int write)
351 struct mmc_request mrq;
352 struct mmc_command cmd;
353 struct mmc_command stop;
354 struct mmc_data data;
356 struct scatterlist sg;
358 memset(&mrq, 0, sizeof(struct mmc_request));
359 memset(&cmd, 0, sizeof(struct mmc_command));
360 memset(&data, 0, sizeof(struct mmc_data));
361 memset(&stop, 0, sizeof(struct mmc_command));
367 sg_init_one(&sg, test->buffer, blocks * blksz);
369 mmc_test_prepare_mrq(test, &mrq, &sg, 1, 0, blocks, blksz, write);
370 mmc_test_prepare_broken_mrq(test, &mrq, write);
372 mmc_wait_for_req(test->card->host, &mrq);
374 mmc_test_wait_busy(test);
376 return mmc_test_check_broken_result(test, &mrq);
380 * Does a complete transfer test where data is also validated
382 * Note: mmc_test_prepare() must have been done before this call
384 static int mmc_test_transfer(struct mmc_test_card *test,
385 struct scatterlist *sg, unsigned sg_len, unsigned dev_addr,
386 unsigned blocks, unsigned blksz, int write)
391 BUG_ON(blocks * blksz > BUFFER_SIZE);
394 for (i = 0;i < blocks * blksz;i++)
395 test->scratch[i] = i;
397 memset(test->scratch, 0, blocks * blksz);
399 local_irq_save(flags);
400 sg_copy_from_buffer(sg, sg_len, test->scratch, blocks * blksz);
401 local_irq_restore(flags);
403 ret = mmc_test_set_blksize(test, blksz);
407 ret = mmc_test_simple_transfer(test, sg, sg_len, dev_addr,
408 blocks, blksz, write);
415 ret = mmc_test_set_blksize(test, 512);
419 sectors = (blocks * blksz + 511) / 512;
420 if ((sectors * 512) == (blocks * blksz))
423 if ((sectors * 512) > BUFFER_SIZE)
426 memset(test->buffer, 0, sectors * 512);
428 for (i = 0;i < sectors;i++) {
429 ret = mmc_test_buffer_transfer(test,
430 test->buffer + i * 512,
431 dev_addr + i * 512, 512, 0);
436 for (i = 0;i < blocks * blksz;i++) {
437 if (test->buffer[i] != (u8)i)
441 for (;i < sectors * 512;i++) {
442 if (test->buffer[i] != 0xDF)
446 local_irq_save(flags);
447 sg_copy_to_buffer(sg, sg_len, test->scratch, blocks * blksz);
448 local_irq_restore(flags);
449 for (i = 0;i < blocks * blksz;i++) {
450 if (test->scratch[i] != (u8)i)
458 /*******************************************************************/
460 /*******************************************************************/
462 struct mmc_test_case {
465 int (*prepare)(struct mmc_test_card *);
466 int (*run)(struct mmc_test_card *);
467 int (*cleanup)(struct mmc_test_card *);
470 static int mmc_test_basic_write(struct mmc_test_card *test)
473 struct scatterlist sg;
475 ret = mmc_test_set_blksize(test, 512);
479 sg_init_one(&sg, test->buffer, 512);
481 ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 1);
488 static int mmc_test_basic_read(struct mmc_test_card *test)
491 struct scatterlist sg;
493 ret = mmc_test_set_blksize(test, 512);
497 sg_init_one(&sg, test->buffer, 512);
499 ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 1);
506 static int mmc_test_verify_write(struct mmc_test_card *test)
509 struct scatterlist sg;
511 sg_init_one(&sg, test->buffer, 512);
513 ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1);
520 static int mmc_test_verify_read(struct mmc_test_card *test)
523 struct scatterlist sg;
525 sg_init_one(&sg, test->buffer, 512);
527 ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0);
534 static int mmc_test_multi_write(struct mmc_test_card *test)
538 struct scatterlist sg;
540 if (test->card->host->max_blk_count == 1)
541 return RESULT_UNSUP_HOST;
543 size = PAGE_SIZE * 2;
544 size = min(size, test->card->host->max_req_size);
545 size = min(size, test->card->host->max_seg_size);
546 size = min(size, test->card->host->max_blk_count * 512);
549 return RESULT_UNSUP_HOST;
551 sg_init_one(&sg, test->buffer, size);
553 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1);
560 static int mmc_test_multi_read(struct mmc_test_card *test)
564 struct scatterlist sg;
566 if (test->card->host->max_blk_count == 1)
567 return RESULT_UNSUP_HOST;
569 size = PAGE_SIZE * 2;
570 size = min(size, test->card->host->max_req_size);
571 size = min(size, test->card->host->max_seg_size);
572 size = min(size, test->card->host->max_blk_count * 512);
575 return RESULT_UNSUP_HOST;
577 sg_init_one(&sg, test->buffer, size);
579 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0);
586 static int mmc_test_pow2_write(struct mmc_test_card *test)
589 struct scatterlist sg;
591 if (!test->card->csd.write_partial)
592 return RESULT_UNSUP_CARD;
594 for (i = 1; i < 512;i <<= 1) {
595 sg_init_one(&sg, test->buffer, i);
596 ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 1);
604 static int mmc_test_pow2_read(struct mmc_test_card *test)
607 struct scatterlist sg;
609 if (!test->card->csd.read_partial)
610 return RESULT_UNSUP_CARD;
612 for (i = 1; i < 512;i <<= 1) {
613 sg_init_one(&sg, test->buffer, i);
614 ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 0);
622 static int mmc_test_weird_write(struct mmc_test_card *test)
625 struct scatterlist sg;
627 if (!test->card->csd.write_partial)
628 return RESULT_UNSUP_CARD;
630 for (i = 3; i < 512;i += 7) {
631 sg_init_one(&sg, test->buffer, i);
632 ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 1);
640 static int mmc_test_weird_read(struct mmc_test_card *test)
643 struct scatterlist sg;
645 if (!test->card->csd.read_partial)
646 return RESULT_UNSUP_CARD;
648 for (i = 3; i < 512;i += 7) {
649 sg_init_one(&sg, test->buffer, i);
650 ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 0);
658 static int mmc_test_align_write(struct mmc_test_card *test)
661 struct scatterlist sg;
663 for (i = 1;i < 4;i++) {
664 sg_init_one(&sg, test->buffer + i, 512);
665 ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1);
673 static int mmc_test_align_read(struct mmc_test_card *test)
676 struct scatterlist sg;
678 for (i = 1;i < 4;i++) {
679 sg_init_one(&sg, test->buffer + i, 512);
680 ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0);
688 static int mmc_test_align_multi_write(struct mmc_test_card *test)
692 struct scatterlist sg;
694 if (test->card->host->max_blk_count == 1)
695 return RESULT_UNSUP_HOST;
697 size = PAGE_SIZE * 2;
698 size = min(size, test->card->host->max_req_size);
699 size = min(size, test->card->host->max_seg_size);
700 size = min(size, test->card->host->max_blk_count * 512);
703 return RESULT_UNSUP_HOST;
705 for (i = 1;i < 4;i++) {
706 sg_init_one(&sg, test->buffer + i, size);
707 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1);
715 static int mmc_test_align_multi_read(struct mmc_test_card *test)
719 struct scatterlist sg;
721 if (test->card->host->max_blk_count == 1)
722 return RESULT_UNSUP_HOST;
724 size = PAGE_SIZE * 2;
725 size = min(size, test->card->host->max_req_size);
726 size = min(size, test->card->host->max_seg_size);
727 size = min(size, test->card->host->max_blk_count * 512);
730 return RESULT_UNSUP_HOST;
732 for (i = 1;i < 4;i++) {
733 sg_init_one(&sg, test->buffer + i, size);
734 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0);
742 static int mmc_test_xfersize_write(struct mmc_test_card *test)
746 ret = mmc_test_set_blksize(test, 512);
750 ret = mmc_test_broken_transfer(test, 1, 512, 1);
757 static int mmc_test_xfersize_read(struct mmc_test_card *test)
761 ret = mmc_test_set_blksize(test, 512);
765 ret = mmc_test_broken_transfer(test, 1, 512, 0);
772 static int mmc_test_multi_xfersize_write(struct mmc_test_card *test)
776 if (test->card->host->max_blk_count == 1)
777 return RESULT_UNSUP_HOST;
779 ret = mmc_test_set_blksize(test, 512);
783 ret = mmc_test_broken_transfer(test, 2, 512, 1);
790 static int mmc_test_multi_xfersize_read(struct mmc_test_card *test)
794 if (test->card->host->max_blk_count == 1)
795 return RESULT_UNSUP_HOST;
797 ret = mmc_test_set_blksize(test, 512);
801 ret = mmc_test_broken_transfer(test, 2, 512, 0);
808 static int mmc_test_bigsg_write(struct mmc_test_card *test)
812 struct scatterlist sg;
814 if (test->card->host->max_blk_count == 1)
815 return RESULT_UNSUP_HOST;
817 size = PAGE_SIZE * 2;
818 size = min(size, test->card->host->max_req_size);
819 size = min(size, test->card->host->max_seg_size);
820 size = min(size, test->card->host->max_blk_count * 512);
822 memset(test->buffer, 0, BUFFER_SIZE);
825 return RESULT_UNSUP_HOST;
827 sg_init_table(&sg, 1);
828 sg_init_one(&sg, test->buffer, BUFFER_SIZE);
830 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1);
837 static int mmc_test_bigsg_read(struct mmc_test_card *test)
841 struct scatterlist sg;
843 if (test->card->host->max_blk_count == 1)
844 return RESULT_UNSUP_HOST;
846 size = PAGE_SIZE * 2;
847 size = min(size, test->card->host->max_req_size);
848 size = min(size, test->card->host->max_seg_size);
849 size = min(size, test->card->host->max_blk_count * 512);
852 return RESULT_UNSUP_HOST;
854 memset(test->buffer, 0xCD, BUFFER_SIZE);
856 sg_init_table(&sg, 1);
857 sg_init_one(&sg, test->buffer, BUFFER_SIZE);
858 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0);
862 /* mmc_test_transfer() doesn't check for read overflows */
863 for (i = size;i < BUFFER_SIZE;i++) {
864 if (test->buffer[i] != 0xCD)
871 #ifdef CONFIG_HIGHMEM
873 static int mmc_test_write_high(struct mmc_test_card *test)
876 struct scatterlist sg;
878 sg_init_table(&sg, 1);
879 sg_set_page(&sg, test->highmem, 512, 0);
881 ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1);
888 static int mmc_test_read_high(struct mmc_test_card *test)
891 struct scatterlist sg;
893 sg_init_table(&sg, 1);
894 sg_set_page(&sg, test->highmem, 512, 0);
896 ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0);
903 static int mmc_test_multi_write_high(struct mmc_test_card *test)
907 struct scatterlist sg;
909 if (test->card->host->max_blk_count == 1)
910 return RESULT_UNSUP_HOST;
912 size = PAGE_SIZE * 2;
913 size = min(size, test->card->host->max_req_size);
914 size = min(size, test->card->host->max_seg_size);
915 size = min(size, test->card->host->max_blk_count * 512);
918 return RESULT_UNSUP_HOST;
920 sg_init_table(&sg, 1);
921 sg_set_page(&sg, test->highmem, size, 0);
923 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1);
930 static int mmc_test_multi_read_high(struct mmc_test_card *test)
934 struct scatterlist sg;
936 if (test->card->host->max_blk_count == 1)
937 return RESULT_UNSUP_HOST;
939 size = PAGE_SIZE * 2;
940 size = min(size, test->card->host->max_req_size);
941 size = min(size, test->card->host->max_seg_size);
942 size = min(size, test->card->host->max_blk_count * 512);
945 return RESULT_UNSUP_HOST;
947 sg_init_table(&sg, 1);
948 sg_set_page(&sg, test->highmem, size, 0);
950 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0);
957 #endif /* CONFIG_HIGHMEM */
959 static const struct mmc_test_case mmc_test_cases[] = {
961 .name = "Basic write (no data verification)",
962 .run = mmc_test_basic_write,
966 .name = "Basic read (no data verification)",
967 .run = mmc_test_basic_read,
971 .name = "Basic write (with data verification)",
972 .prepare = mmc_test_prepare_write,
973 .run = mmc_test_verify_write,
974 .cleanup = mmc_test_cleanup,
978 .name = "Basic read (with data verification)",
979 .prepare = mmc_test_prepare_read,
980 .run = mmc_test_verify_read,
981 .cleanup = mmc_test_cleanup,
985 .name = "Multi-block write",
986 .prepare = mmc_test_prepare_write,
987 .run = mmc_test_multi_write,
988 .cleanup = mmc_test_cleanup,
992 .name = "Multi-block read",
993 .prepare = mmc_test_prepare_read,
994 .run = mmc_test_multi_read,
995 .cleanup = mmc_test_cleanup,
999 .name = "Power of two block writes",
1000 .prepare = mmc_test_prepare_write,
1001 .run = mmc_test_pow2_write,
1002 .cleanup = mmc_test_cleanup,
1006 .name = "Power of two block reads",
1007 .prepare = mmc_test_prepare_read,
1008 .run = mmc_test_pow2_read,
1009 .cleanup = mmc_test_cleanup,
1013 .name = "Weird sized block writes",
1014 .prepare = mmc_test_prepare_write,
1015 .run = mmc_test_weird_write,
1016 .cleanup = mmc_test_cleanup,
1020 .name = "Weird sized block reads",
1021 .prepare = mmc_test_prepare_read,
1022 .run = mmc_test_weird_read,
1023 .cleanup = mmc_test_cleanup,
1027 .name = "Badly aligned write",
1028 .prepare = mmc_test_prepare_write,
1029 .run = mmc_test_align_write,
1030 .cleanup = mmc_test_cleanup,
1034 .name = "Badly aligned read",
1035 .prepare = mmc_test_prepare_read,
1036 .run = mmc_test_align_read,
1037 .cleanup = mmc_test_cleanup,
1041 .name = "Badly aligned multi-block write",
1042 .prepare = mmc_test_prepare_write,
1043 .run = mmc_test_align_multi_write,
1044 .cleanup = mmc_test_cleanup,
1048 .name = "Badly aligned multi-block read",
1049 .prepare = mmc_test_prepare_read,
1050 .run = mmc_test_align_multi_read,
1051 .cleanup = mmc_test_cleanup,
1055 .name = "Correct xfer_size at write (start failure)",
1056 .run = mmc_test_xfersize_write,
1060 .name = "Correct xfer_size at read (start failure)",
1061 .run = mmc_test_xfersize_read,
1065 .name = "Correct xfer_size at write (midway failure)",
1066 .run = mmc_test_multi_xfersize_write,
1070 .name = "Correct xfer_size at read (midway failure)",
1071 .run = mmc_test_multi_xfersize_read,
1075 .name = "Over-sized SG list write",
1076 .prepare = mmc_test_prepare_write,
1077 .run = mmc_test_bigsg_write,
1078 .cleanup = mmc_test_cleanup,
1082 .name = "Over-sized SG list read",
1083 .prepare = mmc_test_prepare_read,
1084 .run = mmc_test_bigsg_read,
1085 .cleanup = mmc_test_cleanup,
1088 #ifdef CONFIG_HIGHMEM
1091 .name = "Highmem write",
1092 .prepare = mmc_test_prepare_write,
1093 .run = mmc_test_write_high,
1094 .cleanup = mmc_test_cleanup,
1098 .name = "Highmem read",
1099 .prepare = mmc_test_prepare_read,
1100 .run = mmc_test_read_high,
1101 .cleanup = mmc_test_cleanup,
1105 .name = "Multi-block highmem write",
1106 .prepare = mmc_test_prepare_write,
1107 .run = mmc_test_multi_write_high,
1108 .cleanup = mmc_test_cleanup,
1112 .name = "Multi-block highmem read",
1113 .prepare = mmc_test_prepare_read,
1114 .run = mmc_test_multi_read_high,
1115 .cleanup = mmc_test_cleanup,
1118 #endif /* CONFIG_HIGHMEM */
1122 static struct mutex mmc_test_lock;
1124 static void mmc_test_run(struct mmc_test_card *test, int testcase)
1128 printk(KERN_INFO "%s: Starting tests of card %s...\n",
1129 mmc_hostname(test->card->host), mmc_card_id(test->card));
1131 mmc_claim_host(test->card->host);
1133 for (i = 0;i < ARRAY_SIZE(mmc_test_cases);i++) {
1134 if (testcase && ((i + 1) != testcase))
1137 printk(KERN_INFO "%s: Test case %d. %s...\n",
1138 mmc_hostname(test->card->host), i + 1,
1139 mmc_test_cases[i].name);
1141 if (mmc_test_cases[i].prepare) {
1142 ret = mmc_test_cases[i].prepare(test);
1144 printk(KERN_INFO "%s: Result: Prepare "
1145 "stage failed! (%d)\n",
1146 mmc_hostname(test->card->host),
1152 ret = mmc_test_cases[i].run(test);
1155 printk(KERN_INFO "%s: Result: OK\n",
1156 mmc_hostname(test->card->host));
1159 printk(KERN_INFO "%s: Result: FAILED\n",
1160 mmc_hostname(test->card->host));
1162 case RESULT_UNSUP_HOST:
1163 printk(KERN_INFO "%s: Result: UNSUPPORTED "
1165 mmc_hostname(test->card->host));
1167 case RESULT_UNSUP_CARD:
1168 printk(KERN_INFO "%s: Result: UNSUPPORTED "
1170 mmc_hostname(test->card->host));
1173 printk(KERN_INFO "%s: Result: ERROR (%d)\n",
1174 mmc_hostname(test->card->host), ret);
1177 if (mmc_test_cases[i].cleanup) {
1178 ret = mmc_test_cases[i].cleanup(test);
1180 printk(KERN_INFO "%s: Warning: Cleanup "
1181 "stage failed! (%d)\n",
1182 mmc_hostname(test->card->host),
1188 mmc_release_host(test->card->host);
1190 printk(KERN_INFO "%s: Tests completed.\n",
1191 mmc_hostname(test->card->host));
1194 static ssize_t mmc_test_show(struct device *dev,
1195 struct device_attribute *attr, char *buf)
1197 mutex_lock(&mmc_test_lock);
1198 mutex_unlock(&mmc_test_lock);
1203 static ssize_t mmc_test_store(struct device *dev,
1204 struct device_attribute *attr, const char *buf, size_t count)
1206 struct mmc_card *card;
1207 struct mmc_test_card *test;
1210 card = container_of(dev, struct mmc_card, dev);
1212 testcase = simple_strtol(buf, NULL, 10);
1214 test = kzalloc(sizeof(struct mmc_test_card), GFP_KERNEL);
1220 test->buffer = kzalloc(BUFFER_SIZE, GFP_KERNEL);
1221 #ifdef CONFIG_HIGHMEM
1222 test->highmem = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM, BUFFER_ORDER);
1225 #ifdef CONFIG_HIGHMEM
1226 if (test->buffer && test->highmem) {
1230 mutex_lock(&mmc_test_lock);
1231 mmc_test_run(test, testcase);
1232 mutex_unlock(&mmc_test_lock);
1235 #ifdef CONFIG_HIGHMEM
1236 __free_pages(test->highmem, BUFFER_ORDER);
1238 kfree(test->buffer);
1244 static DEVICE_ATTR(test, S_IWUSR | S_IRUGO, mmc_test_show, mmc_test_store);
1246 static int mmc_test_probe(struct mmc_card *card)
1250 if ((card->type != MMC_TYPE_MMC) && (card->type != MMC_TYPE_SD))
1253 mutex_init(&mmc_test_lock);
1255 ret = device_create_file(&card->dev, &dev_attr_test);
1259 dev_info(&card->dev, "Card claimed for testing.\n");
1264 static void mmc_test_remove(struct mmc_card *card)
1266 device_remove_file(&card->dev, &dev_attr_test);
1269 static struct mmc_driver mmc_driver = {
1273 .probe = mmc_test_probe,
1274 .remove = mmc_test_remove,
1277 static int __init mmc_test_init(void)
1279 return mmc_register_driver(&mmc_driver);
1282 static void __exit mmc_test_exit(void)
1284 mmc_unregister_driver(&mmc_driver);
1287 module_init(mmc_test_init);
1288 module_exit(mmc_test_exit);
1290 MODULE_LICENSE("GPL");
1291 MODULE_DESCRIPTION("Multimedia Card (MMC) host test driver");
1292 MODULE_AUTHOR("Pierre Ossman");