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>
16 #include <linux/slab.h>
18 #include <linux/scatterlist.h>
22 #define RESULT_UNSUP_HOST 2
23 #define RESULT_UNSUP_CARD 3
25 #define BUFFER_ORDER 2
26 #define BUFFER_SIZE (PAGE_SIZE << BUFFER_ORDER)
28 struct mmc_test_card {
29 struct mmc_card *card;
31 u8 scratch[BUFFER_SIZE];
38 /*******************************************************************/
39 /* General helper functions */
40 /*******************************************************************/
43 * Configure correct block size in card
45 static int mmc_test_set_blksize(struct mmc_test_card *test, unsigned size)
47 struct mmc_command cmd;
50 cmd.opcode = MMC_SET_BLOCKLEN;
52 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
53 ret = mmc_wait_for_cmd(test->card->host, &cmd, 0);
61 * Fill in the mmc_request structure given a set of transfer parameters.
63 static void mmc_test_prepare_mrq(struct mmc_test_card *test,
64 struct mmc_request *mrq, struct scatterlist *sg, unsigned sg_len,
65 unsigned dev_addr, unsigned blocks, unsigned blksz, int write)
67 BUG_ON(!mrq || !mrq->cmd || !mrq->data || !mrq->stop);
70 mrq->cmd->opcode = write ?
71 MMC_WRITE_MULTIPLE_BLOCK : MMC_READ_MULTIPLE_BLOCK;
73 mrq->cmd->opcode = write ?
74 MMC_WRITE_BLOCK : MMC_READ_SINGLE_BLOCK;
77 mrq->cmd->arg = dev_addr;
78 if (!mmc_card_blockaddr(test->card))
81 mrq->cmd->flags = MMC_RSP_R1 | MMC_CMD_ADTC;
86 mrq->stop->opcode = MMC_STOP_TRANSMISSION;
88 mrq->stop->flags = MMC_RSP_R1B | MMC_CMD_AC;
91 mrq->data->blksz = blksz;
92 mrq->data->blocks = blocks;
93 mrq->data->flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
95 mrq->data->sg_len = sg_len;
97 mmc_set_data_timeout(mrq->data, test->card);
101 * Wait for the card to finish the busy state
103 static int mmc_test_wait_busy(struct mmc_test_card *test)
106 struct mmc_command cmd;
110 memset(&cmd, 0, sizeof(struct mmc_command));
112 cmd.opcode = MMC_SEND_STATUS;
113 cmd.arg = test->card->rca << 16;
114 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
116 ret = mmc_wait_for_cmd(test->card->host, &cmd, 0);
120 if (!busy && !(cmd.resp[0] & R1_READY_FOR_DATA)) {
122 printk(KERN_INFO "%s: Warning: Host did not "
123 "wait for busy state to end.\n",
124 mmc_hostname(test->card->host));
126 } while (!(cmd.resp[0] & R1_READY_FOR_DATA));
132 * Transfer a single sector of kernel addressable data
134 static int mmc_test_buffer_transfer(struct mmc_test_card *test,
135 u8 *buffer, unsigned addr, unsigned blksz, int write)
139 struct mmc_request mrq;
140 struct mmc_command cmd;
141 struct mmc_command stop;
142 struct mmc_data data;
144 struct scatterlist sg;
146 memset(&mrq, 0, sizeof(struct mmc_request));
147 memset(&cmd, 0, sizeof(struct mmc_command));
148 memset(&data, 0, sizeof(struct mmc_data));
149 memset(&stop, 0, sizeof(struct mmc_command));
155 sg_init_one(&sg, buffer, blksz);
157 mmc_test_prepare_mrq(test, &mrq, &sg, 1, addr, 1, blksz, write);
159 mmc_wait_for_req(test->card->host, &mrq);
166 ret = mmc_test_wait_busy(test);
173 /*******************************************************************/
174 /* Test preparation and cleanup */
175 /*******************************************************************/
178 * Fill the first couple of sectors of the card with known data
179 * so that bad reads/writes can be detected
181 static int __mmc_test_prepare(struct mmc_test_card *test, int write)
185 ret = mmc_test_set_blksize(test, 512);
190 memset(test->buffer, 0xDF, 512);
192 for (i = 0;i < 512;i++)
196 for (i = 0;i < BUFFER_SIZE / 512;i++) {
197 ret = mmc_test_buffer_transfer(test, test->buffer, i, 512, 1);
205 static int mmc_test_prepare_write(struct mmc_test_card *test)
207 return __mmc_test_prepare(test, 1);
210 static int mmc_test_prepare_read(struct mmc_test_card *test)
212 return __mmc_test_prepare(test, 0);
215 static int mmc_test_cleanup(struct mmc_test_card *test)
219 ret = mmc_test_set_blksize(test, 512);
223 memset(test->buffer, 0, 512);
225 for (i = 0;i < BUFFER_SIZE / 512;i++) {
226 ret = mmc_test_buffer_transfer(test, test->buffer, i, 512, 1);
234 /*******************************************************************/
235 /* Test execution helpers */
236 /*******************************************************************/
239 * Modifies the mmc_request to perform the "short transfer" tests
241 static void mmc_test_prepare_broken_mrq(struct mmc_test_card *test,
242 struct mmc_request *mrq, int write)
244 BUG_ON(!mrq || !mrq->cmd || !mrq->data);
246 if (mrq->data->blocks > 1) {
247 mrq->cmd->opcode = write ?
248 MMC_WRITE_BLOCK : MMC_READ_SINGLE_BLOCK;
251 mrq->cmd->opcode = MMC_SEND_STATUS;
252 mrq->cmd->arg = test->card->rca << 16;
257 * Checks that a normal transfer didn't have any errors
259 static int mmc_test_check_result(struct mmc_test_card *test,
260 struct mmc_request *mrq)
264 BUG_ON(!mrq || !mrq->cmd || !mrq->data);
268 if (!ret && mrq->cmd->error)
269 ret = mrq->cmd->error;
270 if (!ret && mrq->data->error)
271 ret = mrq->data->error;
272 if (!ret && mrq->stop && mrq->stop->error)
273 ret = mrq->stop->error;
274 if (!ret && mrq->data->bytes_xfered !=
275 mrq->data->blocks * mrq->data->blksz)
279 ret = RESULT_UNSUP_HOST;
285 * Checks that a "short transfer" behaved as expected
287 static int mmc_test_check_broken_result(struct mmc_test_card *test,
288 struct mmc_request *mrq)
292 BUG_ON(!mrq || !mrq->cmd || !mrq->data);
296 if (!ret && mrq->cmd->error)
297 ret = mrq->cmd->error;
298 if (!ret && mrq->data->error == 0)
300 if (!ret && mrq->data->error != -ETIMEDOUT)
301 ret = mrq->data->error;
302 if (!ret && mrq->stop && mrq->stop->error)
303 ret = mrq->stop->error;
304 if (mrq->data->blocks > 1) {
305 if (!ret && mrq->data->bytes_xfered > mrq->data->blksz)
308 if (!ret && mrq->data->bytes_xfered > 0)
313 ret = RESULT_UNSUP_HOST;
319 * Tests a basic transfer with certain parameters
321 static int mmc_test_simple_transfer(struct mmc_test_card *test,
322 struct scatterlist *sg, unsigned sg_len, unsigned dev_addr,
323 unsigned blocks, unsigned blksz, int write)
325 struct mmc_request mrq;
326 struct mmc_command cmd;
327 struct mmc_command stop;
328 struct mmc_data data;
330 memset(&mrq, 0, sizeof(struct mmc_request));
331 memset(&cmd, 0, sizeof(struct mmc_command));
332 memset(&data, 0, sizeof(struct mmc_data));
333 memset(&stop, 0, sizeof(struct mmc_command));
339 mmc_test_prepare_mrq(test, &mrq, sg, sg_len, dev_addr,
340 blocks, blksz, write);
342 mmc_wait_for_req(test->card->host, &mrq);
344 mmc_test_wait_busy(test);
346 return mmc_test_check_result(test, &mrq);
350 * Tests a transfer where the card will fail completely or partly
352 static int mmc_test_broken_transfer(struct mmc_test_card *test,
353 unsigned blocks, unsigned blksz, int write)
355 struct mmc_request mrq;
356 struct mmc_command cmd;
357 struct mmc_command stop;
358 struct mmc_data data;
360 struct scatterlist sg;
362 memset(&mrq, 0, sizeof(struct mmc_request));
363 memset(&cmd, 0, sizeof(struct mmc_command));
364 memset(&data, 0, sizeof(struct mmc_data));
365 memset(&stop, 0, sizeof(struct mmc_command));
371 sg_init_one(&sg, test->buffer, blocks * blksz);
373 mmc_test_prepare_mrq(test, &mrq, &sg, 1, 0, blocks, blksz, write);
374 mmc_test_prepare_broken_mrq(test, &mrq, write);
376 mmc_wait_for_req(test->card->host, &mrq);
378 mmc_test_wait_busy(test);
380 return mmc_test_check_broken_result(test, &mrq);
384 * Does a complete transfer test where data is also validated
386 * Note: mmc_test_prepare() must have been done before this call
388 static int mmc_test_transfer(struct mmc_test_card *test,
389 struct scatterlist *sg, unsigned sg_len, unsigned dev_addr,
390 unsigned blocks, unsigned blksz, int write)
396 for (i = 0;i < blocks * blksz;i++)
397 test->scratch[i] = i;
399 memset(test->scratch, 0, BUFFER_SIZE);
401 local_irq_save(flags);
402 sg_copy_from_buffer(sg, sg_len, test->scratch, BUFFER_SIZE);
403 local_irq_restore(flags);
405 ret = mmc_test_set_blksize(test, blksz);
409 ret = mmc_test_simple_transfer(test, sg, sg_len, dev_addr,
410 blocks, blksz, write);
417 ret = mmc_test_set_blksize(test, 512);
421 sectors = (blocks * blksz + 511) / 512;
422 if ((sectors * 512) == (blocks * blksz))
425 if ((sectors * 512) > BUFFER_SIZE)
428 memset(test->buffer, 0, sectors * 512);
430 for (i = 0;i < sectors;i++) {
431 ret = mmc_test_buffer_transfer(test,
432 test->buffer + i * 512,
433 dev_addr + i, 512, 0);
438 for (i = 0;i < blocks * blksz;i++) {
439 if (test->buffer[i] != (u8)i)
443 for (;i < sectors * 512;i++) {
444 if (test->buffer[i] != 0xDF)
448 local_irq_save(flags);
449 sg_copy_to_buffer(sg, sg_len, test->scratch, BUFFER_SIZE);
450 local_irq_restore(flags);
451 for (i = 0;i < blocks * blksz;i++) {
452 if (test->scratch[i] != (u8)i)
460 /*******************************************************************/
462 /*******************************************************************/
464 struct mmc_test_case {
467 int (*prepare)(struct mmc_test_card *);
468 int (*run)(struct mmc_test_card *);
469 int (*cleanup)(struct mmc_test_card *);
472 static int mmc_test_basic_write(struct mmc_test_card *test)
475 struct scatterlist sg;
477 ret = mmc_test_set_blksize(test, 512);
481 sg_init_one(&sg, test->buffer, 512);
483 ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 1);
490 static int mmc_test_basic_read(struct mmc_test_card *test)
493 struct scatterlist sg;
495 ret = mmc_test_set_blksize(test, 512);
499 sg_init_one(&sg, test->buffer, 512);
501 ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 0);
508 static int mmc_test_verify_write(struct mmc_test_card *test)
511 struct scatterlist sg;
513 sg_init_one(&sg, test->buffer, 512);
515 ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1);
522 static int mmc_test_verify_read(struct mmc_test_card *test)
525 struct scatterlist sg;
527 sg_init_one(&sg, test->buffer, 512);
529 ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0);
536 static int mmc_test_multi_write(struct mmc_test_card *test)
540 struct scatterlist sg;
542 if (test->card->host->max_blk_count == 1)
543 return RESULT_UNSUP_HOST;
545 size = PAGE_SIZE * 2;
546 size = min(size, test->card->host->max_req_size);
547 size = min(size, test->card->host->max_seg_size);
548 size = min(size, test->card->host->max_blk_count * 512);
551 return RESULT_UNSUP_HOST;
553 sg_init_one(&sg, test->buffer, size);
555 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1);
562 static int mmc_test_multi_read(struct mmc_test_card *test)
566 struct scatterlist sg;
568 if (test->card->host->max_blk_count == 1)
569 return RESULT_UNSUP_HOST;
571 size = PAGE_SIZE * 2;
572 size = min(size, test->card->host->max_req_size);
573 size = min(size, test->card->host->max_seg_size);
574 size = min(size, test->card->host->max_blk_count * 512);
577 return RESULT_UNSUP_HOST;
579 sg_init_one(&sg, test->buffer, size);
581 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0);
588 static int mmc_test_pow2_write(struct mmc_test_card *test)
591 struct scatterlist sg;
593 if (!test->card->csd.write_partial)
594 return RESULT_UNSUP_CARD;
596 for (i = 1; i < 512;i <<= 1) {
597 sg_init_one(&sg, test->buffer, i);
598 ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 1);
606 static int mmc_test_pow2_read(struct mmc_test_card *test)
609 struct scatterlist sg;
611 if (!test->card->csd.read_partial)
612 return RESULT_UNSUP_CARD;
614 for (i = 1; i < 512;i <<= 1) {
615 sg_init_one(&sg, test->buffer, i);
616 ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 0);
624 static int mmc_test_weird_write(struct mmc_test_card *test)
627 struct scatterlist sg;
629 if (!test->card->csd.write_partial)
630 return RESULT_UNSUP_CARD;
632 for (i = 3; i < 512;i += 7) {
633 sg_init_one(&sg, test->buffer, i);
634 ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 1);
642 static int mmc_test_weird_read(struct mmc_test_card *test)
645 struct scatterlist sg;
647 if (!test->card->csd.read_partial)
648 return RESULT_UNSUP_CARD;
650 for (i = 3; i < 512;i += 7) {
651 sg_init_one(&sg, test->buffer, i);
652 ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 0);
660 static int mmc_test_align_write(struct mmc_test_card *test)
663 struct scatterlist sg;
665 for (i = 1;i < 4;i++) {
666 sg_init_one(&sg, test->buffer + i, 512);
667 ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1);
675 static int mmc_test_align_read(struct mmc_test_card *test)
678 struct scatterlist sg;
680 for (i = 1;i < 4;i++) {
681 sg_init_one(&sg, test->buffer + i, 512);
682 ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0);
690 static int mmc_test_align_multi_write(struct mmc_test_card *test)
694 struct scatterlist sg;
696 if (test->card->host->max_blk_count == 1)
697 return RESULT_UNSUP_HOST;
699 size = PAGE_SIZE * 2;
700 size = min(size, test->card->host->max_req_size);
701 size = min(size, test->card->host->max_seg_size);
702 size = min(size, test->card->host->max_blk_count * 512);
705 return RESULT_UNSUP_HOST;
707 for (i = 1;i < 4;i++) {
708 sg_init_one(&sg, test->buffer + i, size);
709 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1);
717 static int mmc_test_align_multi_read(struct mmc_test_card *test)
721 struct scatterlist sg;
723 if (test->card->host->max_blk_count == 1)
724 return RESULT_UNSUP_HOST;
726 size = PAGE_SIZE * 2;
727 size = min(size, test->card->host->max_req_size);
728 size = min(size, test->card->host->max_seg_size);
729 size = min(size, test->card->host->max_blk_count * 512);
732 return RESULT_UNSUP_HOST;
734 for (i = 1;i < 4;i++) {
735 sg_init_one(&sg, test->buffer + i, size);
736 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0);
744 static int mmc_test_xfersize_write(struct mmc_test_card *test)
748 ret = mmc_test_set_blksize(test, 512);
752 ret = mmc_test_broken_transfer(test, 1, 512, 1);
759 static int mmc_test_xfersize_read(struct mmc_test_card *test)
763 ret = mmc_test_set_blksize(test, 512);
767 ret = mmc_test_broken_transfer(test, 1, 512, 0);
774 static int mmc_test_multi_xfersize_write(struct mmc_test_card *test)
778 if (test->card->host->max_blk_count == 1)
779 return RESULT_UNSUP_HOST;
781 ret = mmc_test_set_blksize(test, 512);
785 ret = mmc_test_broken_transfer(test, 2, 512, 1);
792 static int mmc_test_multi_xfersize_read(struct mmc_test_card *test)
796 if (test->card->host->max_blk_count == 1)
797 return RESULT_UNSUP_HOST;
799 ret = mmc_test_set_blksize(test, 512);
803 ret = mmc_test_broken_transfer(test, 2, 512, 0);
810 #ifdef CONFIG_HIGHMEM
812 static int mmc_test_write_high(struct mmc_test_card *test)
815 struct scatterlist sg;
817 sg_init_table(&sg, 1);
818 sg_set_page(&sg, test->highmem, 512, 0);
820 ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1);
827 static int mmc_test_read_high(struct mmc_test_card *test)
830 struct scatterlist sg;
832 sg_init_table(&sg, 1);
833 sg_set_page(&sg, test->highmem, 512, 0);
835 ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0);
842 static int mmc_test_multi_write_high(struct mmc_test_card *test)
846 struct scatterlist sg;
848 if (test->card->host->max_blk_count == 1)
849 return RESULT_UNSUP_HOST;
851 size = PAGE_SIZE * 2;
852 size = min(size, test->card->host->max_req_size);
853 size = min(size, test->card->host->max_seg_size);
854 size = min(size, test->card->host->max_blk_count * 512);
857 return RESULT_UNSUP_HOST;
859 sg_init_table(&sg, 1);
860 sg_set_page(&sg, test->highmem, size, 0);
862 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1);
869 static int mmc_test_multi_read_high(struct mmc_test_card *test)
873 struct scatterlist sg;
875 if (test->card->host->max_blk_count == 1)
876 return RESULT_UNSUP_HOST;
878 size = PAGE_SIZE * 2;
879 size = min(size, test->card->host->max_req_size);
880 size = min(size, test->card->host->max_seg_size);
881 size = min(size, test->card->host->max_blk_count * 512);
884 return RESULT_UNSUP_HOST;
886 sg_init_table(&sg, 1);
887 sg_set_page(&sg, test->highmem, size, 0);
889 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0);
896 #endif /* CONFIG_HIGHMEM */
898 static const struct mmc_test_case mmc_test_cases[] = {
900 .name = "Basic write (no data verification)",
901 .run = mmc_test_basic_write,
905 .name = "Basic read (no data verification)",
906 .run = mmc_test_basic_read,
910 .name = "Basic write (with data verification)",
911 .prepare = mmc_test_prepare_write,
912 .run = mmc_test_verify_write,
913 .cleanup = mmc_test_cleanup,
917 .name = "Basic read (with data verification)",
918 .prepare = mmc_test_prepare_read,
919 .run = mmc_test_verify_read,
920 .cleanup = mmc_test_cleanup,
924 .name = "Multi-block write",
925 .prepare = mmc_test_prepare_write,
926 .run = mmc_test_multi_write,
927 .cleanup = mmc_test_cleanup,
931 .name = "Multi-block read",
932 .prepare = mmc_test_prepare_read,
933 .run = mmc_test_multi_read,
934 .cleanup = mmc_test_cleanup,
938 .name = "Power of two block writes",
939 .prepare = mmc_test_prepare_write,
940 .run = mmc_test_pow2_write,
941 .cleanup = mmc_test_cleanup,
945 .name = "Power of two block reads",
946 .prepare = mmc_test_prepare_read,
947 .run = mmc_test_pow2_read,
948 .cleanup = mmc_test_cleanup,
952 .name = "Weird sized block writes",
953 .prepare = mmc_test_prepare_write,
954 .run = mmc_test_weird_write,
955 .cleanup = mmc_test_cleanup,
959 .name = "Weird sized block reads",
960 .prepare = mmc_test_prepare_read,
961 .run = mmc_test_weird_read,
962 .cleanup = mmc_test_cleanup,
966 .name = "Badly aligned write",
967 .prepare = mmc_test_prepare_write,
968 .run = mmc_test_align_write,
969 .cleanup = mmc_test_cleanup,
973 .name = "Badly aligned read",
974 .prepare = mmc_test_prepare_read,
975 .run = mmc_test_align_read,
976 .cleanup = mmc_test_cleanup,
980 .name = "Badly aligned multi-block write",
981 .prepare = mmc_test_prepare_write,
982 .run = mmc_test_align_multi_write,
983 .cleanup = mmc_test_cleanup,
987 .name = "Badly aligned multi-block read",
988 .prepare = mmc_test_prepare_read,
989 .run = mmc_test_align_multi_read,
990 .cleanup = mmc_test_cleanup,
994 .name = "Correct xfer_size at write (start failure)",
995 .run = mmc_test_xfersize_write,
999 .name = "Correct xfer_size at read (start failure)",
1000 .run = mmc_test_xfersize_read,
1004 .name = "Correct xfer_size at write (midway failure)",
1005 .run = mmc_test_multi_xfersize_write,
1009 .name = "Correct xfer_size at read (midway failure)",
1010 .run = mmc_test_multi_xfersize_read,
1013 #ifdef CONFIG_HIGHMEM
1016 .name = "Highmem write",
1017 .prepare = mmc_test_prepare_write,
1018 .run = mmc_test_write_high,
1019 .cleanup = mmc_test_cleanup,
1023 .name = "Highmem read",
1024 .prepare = mmc_test_prepare_read,
1025 .run = mmc_test_read_high,
1026 .cleanup = mmc_test_cleanup,
1030 .name = "Multi-block highmem write",
1031 .prepare = mmc_test_prepare_write,
1032 .run = mmc_test_multi_write_high,
1033 .cleanup = mmc_test_cleanup,
1037 .name = "Multi-block highmem read",
1038 .prepare = mmc_test_prepare_read,
1039 .run = mmc_test_multi_read_high,
1040 .cleanup = mmc_test_cleanup,
1043 #endif /* CONFIG_HIGHMEM */
1047 static DEFINE_MUTEX(mmc_test_lock);
1049 static void mmc_test_run(struct mmc_test_card *test, int testcase)
1053 printk(KERN_INFO "%s: Starting tests of card %s...\n",
1054 mmc_hostname(test->card->host), mmc_card_id(test->card));
1056 mmc_claim_host(test->card->host);
1058 for (i = 0;i < ARRAY_SIZE(mmc_test_cases);i++) {
1059 if (testcase && ((i + 1) != testcase))
1062 printk(KERN_INFO "%s: Test case %d. %s...\n",
1063 mmc_hostname(test->card->host), i + 1,
1064 mmc_test_cases[i].name);
1066 if (mmc_test_cases[i].prepare) {
1067 ret = mmc_test_cases[i].prepare(test);
1069 printk(KERN_INFO "%s: Result: Prepare "
1070 "stage failed! (%d)\n",
1071 mmc_hostname(test->card->host),
1077 ret = mmc_test_cases[i].run(test);
1080 printk(KERN_INFO "%s: Result: OK\n",
1081 mmc_hostname(test->card->host));
1084 printk(KERN_INFO "%s: Result: FAILED\n",
1085 mmc_hostname(test->card->host));
1087 case RESULT_UNSUP_HOST:
1088 printk(KERN_INFO "%s: Result: UNSUPPORTED "
1090 mmc_hostname(test->card->host));
1092 case RESULT_UNSUP_CARD:
1093 printk(KERN_INFO "%s: Result: UNSUPPORTED "
1095 mmc_hostname(test->card->host));
1098 printk(KERN_INFO "%s: Result: ERROR (%d)\n",
1099 mmc_hostname(test->card->host), ret);
1102 if (mmc_test_cases[i].cleanup) {
1103 ret = mmc_test_cases[i].cleanup(test);
1105 printk(KERN_INFO "%s: Warning: Cleanup "
1106 "stage failed! (%d)\n",
1107 mmc_hostname(test->card->host),
1113 mmc_release_host(test->card->host);
1115 printk(KERN_INFO "%s: Tests completed.\n",
1116 mmc_hostname(test->card->host));
1119 static ssize_t mmc_test_show(struct device *dev,
1120 struct device_attribute *attr, char *buf)
1122 mutex_lock(&mmc_test_lock);
1123 mutex_unlock(&mmc_test_lock);
1128 static ssize_t mmc_test_store(struct device *dev,
1129 struct device_attribute *attr, const char *buf, size_t count)
1131 struct mmc_card *card;
1132 struct mmc_test_card *test;
1135 card = container_of(dev, struct mmc_card, dev);
1137 testcase = simple_strtol(buf, NULL, 10);
1139 test = kzalloc(sizeof(struct mmc_test_card), GFP_KERNEL);
1145 test->buffer = kzalloc(BUFFER_SIZE, GFP_KERNEL);
1146 #ifdef CONFIG_HIGHMEM
1147 test->highmem = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM, BUFFER_ORDER);
1150 #ifdef CONFIG_HIGHMEM
1151 if (test->buffer && test->highmem) {
1155 mutex_lock(&mmc_test_lock);
1156 mmc_test_run(test, testcase);
1157 mutex_unlock(&mmc_test_lock);
1160 #ifdef CONFIG_HIGHMEM
1161 __free_pages(test->highmem, BUFFER_ORDER);
1163 kfree(test->buffer);
1169 static DEVICE_ATTR(test, S_IWUSR | S_IRUGO, mmc_test_show, mmc_test_store);
1171 static int mmc_test_probe(struct mmc_card *card)
1175 if ((card->type != MMC_TYPE_MMC) && (card->type != MMC_TYPE_SD))
1178 ret = device_create_file(&card->dev, &dev_attr_test);
1182 dev_info(&card->dev, "Card claimed for testing.\n");
1187 static void mmc_test_remove(struct mmc_card *card)
1189 device_remove_file(&card->dev, &dev_attr_test);
1192 static struct mmc_driver mmc_driver = {
1196 .probe = mmc_test_probe,
1197 .remove = mmc_test_remove,
1200 static int __init mmc_test_init(void)
1202 return mmc_register_driver(&mmc_driver);
1205 static void __exit mmc_test_exit(void)
1207 mmc_unregister_driver(&mmc_driver);
1210 module_init(mmc_test_init);
1211 module_exit(mmc_test_exit);
1213 MODULE_LICENSE("GPL");
1214 MODULE_DESCRIPTION("Multimedia Card (MMC) host test driver");
1215 MODULE_AUTHOR("Pierre Ossman");