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
)
392 for (i
= 0;i
< blocks
* blksz
;i
++)
393 test
->scratch
[i
] = i
;
395 memset(test
->scratch
, 0, BUFFER_SIZE
);
397 local_irq_save(flags
);
398 sg_copy_from_buffer(sg
, sg_len
, test
->scratch
, BUFFER_SIZE
);
399 local_irq_restore(flags
);
401 ret
= mmc_test_set_blksize(test
, blksz
);
405 ret
= mmc_test_simple_transfer(test
, sg
, sg_len
, dev_addr
,
406 blocks
, blksz
, write
);
413 ret
= mmc_test_set_blksize(test
, 512);
417 sectors
= (blocks
* blksz
+ 511) / 512;
418 if ((sectors
* 512) == (blocks
* blksz
))
421 if ((sectors
* 512) > BUFFER_SIZE
)
424 memset(test
->buffer
, 0, sectors
* 512);
426 for (i
= 0;i
< sectors
;i
++) {
427 ret
= mmc_test_buffer_transfer(test
,
428 test
->buffer
+ i
* 512,
429 dev_addr
+ i
* 512, 512, 0);
434 for (i
= 0;i
< blocks
* blksz
;i
++) {
435 if (test
->buffer
[i
] != (u8
)i
)
439 for (;i
< sectors
* 512;i
++) {
440 if (test
->buffer
[i
] != 0xDF)
444 local_irq_save(flags
);
445 sg_copy_to_buffer(sg
, sg_len
, test
->scratch
, BUFFER_SIZE
);
446 local_irq_restore(flags
);
447 for (i
= 0;i
< blocks
* blksz
;i
++) {
448 if (test
->scratch
[i
] != (u8
)i
)
456 /*******************************************************************/
458 /*******************************************************************/
460 struct mmc_test_case
{
463 int (*prepare
)(struct mmc_test_card
*);
464 int (*run
)(struct mmc_test_card
*);
465 int (*cleanup
)(struct mmc_test_card
*);
468 static int mmc_test_basic_write(struct mmc_test_card
*test
)
471 struct scatterlist sg
;
473 ret
= mmc_test_set_blksize(test
, 512);
477 sg_init_one(&sg
, test
->buffer
, 512);
479 ret
= mmc_test_simple_transfer(test
, &sg
, 1, 0, 1, 512, 1);
486 static int mmc_test_basic_read(struct mmc_test_card
*test
)
489 struct scatterlist sg
;
491 ret
= mmc_test_set_blksize(test
, 512);
495 sg_init_one(&sg
, test
->buffer
, 512);
497 ret
= mmc_test_simple_transfer(test
, &sg
, 1, 0, 1, 512, 0);
504 static int mmc_test_verify_write(struct mmc_test_card
*test
)
507 struct scatterlist sg
;
509 sg_init_one(&sg
, test
->buffer
, 512);
511 ret
= mmc_test_transfer(test
, &sg
, 1, 0, 1, 512, 1);
518 static int mmc_test_verify_read(struct mmc_test_card
*test
)
521 struct scatterlist sg
;
523 sg_init_one(&sg
, test
->buffer
, 512);
525 ret
= mmc_test_transfer(test
, &sg
, 1, 0, 1, 512, 0);
532 static int mmc_test_multi_write(struct mmc_test_card
*test
)
536 struct scatterlist sg
;
538 if (test
->card
->host
->max_blk_count
== 1)
539 return RESULT_UNSUP_HOST
;
541 size
= PAGE_SIZE
* 2;
542 size
= min(size
, test
->card
->host
->max_req_size
);
543 size
= min(size
, test
->card
->host
->max_seg_size
);
544 size
= min(size
, test
->card
->host
->max_blk_count
* 512);
547 return RESULT_UNSUP_HOST
;
549 sg_init_one(&sg
, test
->buffer
, size
);
551 ret
= mmc_test_transfer(test
, &sg
, 1, 0, size
/512, 512, 1);
558 static int mmc_test_multi_read(struct mmc_test_card
*test
)
562 struct scatterlist sg
;
564 if (test
->card
->host
->max_blk_count
== 1)
565 return RESULT_UNSUP_HOST
;
567 size
= PAGE_SIZE
* 2;
568 size
= min(size
, test
->card
->host
->max_req_size
);
569 size
= min(size
, test
->card
->host
->max_seg_size
);
570 size
= min(size
, test
->card
->host
->max_blk_count
* 512);
573 return RESULT_UNSUP_HOST
;
575 sg_init_one(&sg
, test
->buffer
, size
);
577 ret
= mmc_test_transfer(test
, &sg
, 1, 0, size
/512, 512, 0);
584 static int mmc_test_pow2_write(struct mmc_test_card
*test
)
587 struct scatterlist sg
;
589 if (!test
->card
->csd
.write_partial
)
590 return RESULT_UNSUP_CARD
;
592 for (i
= 1; i
< 512;i
<<= 1) {
593 sg_init_one(&sg
, test
->buffer
, i
);
594 ret
= mmc_test_transfer(test
, &sg
, 1, 0, 1, i
, 1);
602 static int mmc_test_pow2_read(struct mmc_test_card
*test
)
605 struct scatterlist sg
;
607 if (!test
->card
->csd
.read_partial
)
608 return RESULT_UNSUP_CARD
;
610 for (i
= 1; i
< 512;i
<<= 1) {
611 sg_init_one(&sg
, test
->buffer
, i
);
612 ret
= mmc_test_transfer(test
, &sg
, 1, 0, 1, i
, 0);
620 static int mmc_test_weird_write(struct mmc_test_card
*test
)
623 struct scatterlist sg
;
625 if (!test
->card
->csd
.write_partial
)
626 return RESULT_UNSUP_CARD
;
628 for (i
= 3; i
< 512;i
+= 7) {
629 sg_init_one(&sg
, test
->buffer
, i
);
630 ret
= mmc_test_transfer(test
, &sg
, 1, 0, 1, i
, 1);
638 static int mmc_test_weird_read(struct mmc_test_card
*test
)
641 struct scatterlist sg
;
643 if (!test
->card
->csd
.read_partial
)
644 return RESULT_UNSUP_CARD
;
646 for (i
= 3; i
< 512;i
+= 7) {
647 sg_init_one(&sg
, test
->buffer
, i
);
648 ret
= mmc_test_transfer(test
, &sg
, 1, 0, 1, i
, 0);
656 static int mmc_test_align_write(struct mmc_test_card
*test
)
659 struct scatterlist sg
;
661 for (i
= 1;i
< 4;i
++) {
662 sg_init_one(&sg
, test
->buffer
+ i
, 512);
663 ret
= mmc_test_transfer(test
, &sg
, 1, 0, 1, 512, 1);
671 static int mmc_test_align_read(struct mmc_test_card
*test
)
674 struct scatterlist sg
;
676 for (i
= 1;i
< 4;i
++) {
677 sg_init_one(&sg
, test
->buffer
+ i
, 512);
678 ret
= mmc_test_transfer(test
, &sg
, 1, 0, 1, 512, 0);
686 static int mmc_test_align_multi_write(struct mmc_test_card
*test
)
690 struct scatterlist sg
;
692 if (test
->card
->host
->max_blk_count
== 1)
693 return RESULT_UNSUP_HOST
;
695 size
= PAGE_SIZE
* 2;
696 size
= min(size
, test
->card
->host
->max_req_size
);
697 size
= min(size
, test
->card
->host
->max_seg_size
);
698 size
= min(size
, test
->card
->host
->max_blk_count
* 512);
701 return RESULT_UNSUP_HOST
;
703 for (i
= 1;i
< 4;i
++) {
704 sg_init_one(&sg
, test
->buffer
+ i
, size
);
705 ret
= mmc_test_transfer(test
, &sg
, 1, 0, size
/512, 512, 1);
713 static int mmc_test_align_multi_read(struct mmc_test_card
*test
)
717 struct scatterlist sg
;
719 if (test
->card
->host
->max_blk_count
== 1)
720 return RESULT_UNSUP_HOST
;
722 size
= PAGE_SIZE
* 2;
723 size
= min(size
, test
->card
->host
->max_req_size
);
724 size
= min(size
, test
->card
->host
->max_seg_size
);
725 size
= min(size
, test
->card
->host
->max_blk_count
* 512);
728 return RESULT_UNSUP_HOST
;
730 for (i
= 1;i
< 4;i
++) {
731 sg_init_one(&sg
, test
->buffer
+ i
, size
);
732 ret
= mmc_test_transfer(test
, &sg
, 1, 0, size
/512, 512, 0);
740 static int mmc_test_xfersize_write(struct mmc_test_card
*test
)
744 ret
= mmc_test_set_blksize(test
, 512);
748 ret
= mmc_test_broken_transfer(test
, 1, 512, 1);
755 static int mmc_test_xfersize_read(struct mmc_test_card
*test
)
759 ret
= mmc_test_set_blksize(test
, 512);
763 ret
= mmc_test_broken_transfer(test
, 1, 512, 0);
770 static int mmc_test_multi_xfersize_write(struct mmc_test_card
*test
)
774 if (test
->card
->host
->max_blk_count
== 1)
775 return RESULT_UNSUP_HOST
;
777 ret
= mmc_test_set_blksize(test
, 512);
781 ret
= mmc_test_broken_transfer(test
, 2, 512, 1);
788 static int mmc_test_multi_xfersize_read(struct mmc_test_card
*test
)
792 if (test
->card
->host
->max_blk_count
== 1)
793 return RESULT_UNSUP_HOST
;
795 ret
= mmc_test_set_blksize(test
, 512);
799 ret
= mmc_test_broken_transfer(test
, 2, 512, 0);
806 #ifdef CONFIG_HIGHMEM
808 static int mmc_test_write_high(struct mmc_test_card
*test
)
811 struct scatterlist sg
;
813 sg_init_table(&sg
, 1);
814 sg_set_page(&sg
, test
->highmem
, 512, 0);
816 ret
= mmc_test_transfer(test
, &sg
, 1, 0, 1, 512, 1);
823 static int mmc_test_read_high(struct mmc_test_card
*test
)
826 struct scatterlist sg
;
828 sg_init_table(&sg
, 1);
829 sg_set_page(&sg
, test
->highmem
, 512, 0);
831 ret
= mmc_test_transfer(test
, &sg
, 1, 0, 1, 512, 0);
838 static int mmc_test_multi_write_high(struct mmc_test_card
*test
)
842 struct scatterlist sg
;
844 if (test
->card
->host
->max_blk_count
== 1)
845 return RESULT_UNSUP_HOST
;
847 size
= PAGE_SIZE
* 2;
848 size
= min(size
, test
->card
->host
->max_req_size
);
849 size
= min(size
, test
->card
->host
->max_seg_size
);
850 size
= min(size
, test
->card
->host
->max_blk_count
* 512);
853 return RESULT_UNSUP_HOST
;
855 sg_init_table(&sg
, 1);
856 sg_set_page(&sg
, test
->highmem
, size
, 0);
858 ret
= mmc_test_transfer(test
, &sg
, 1, 0, size
/512, 512, 1);
865 static int mmc_test_multi_read_high(struct mmc_test_card
*test
)
869 struct scatterlist sg
;
871 if (test
->card
->host
->max_blk_count
== 1)
872 return RESULT_UNSUP_HOST
;
874 size
= PAGE_SIZE
* 2;
875 size
= min(size
, test
->card
->host
->max_req_size
);
876 size
= min(size
, test
->card
->host
->max_seg_size
);
877 size
= min(size
, test
->card
->host
->max_blk_count
* 512);
880 return RESULT_UNSUP_HOST
;
882 sg_init_table(&sg
, 1);
883 sg_set_page(&sg
, test
->highmem
, size
, 0);
885 ret
= mmc_test_transfer(test
, &sg
, 1, 0, size
/512, 512, 0);
892 #endif /* CONFIG_HIGHMEM */
894 static const struct mmc_test_case mmc_test_cases
[] = {
896 .name
= "Basic write (no data verification)",
897 .run
= mmc_test_basic_write
,
901 .name
= "Basic read (no data verification)",
902 .run
= mmc_test_basic_read
,
906 .name
= "Basic write (with data verification)",
907 .prepare
= mmc_test_prepare_write
,
908 .run
= mmc_test_verify_write
,
909 .cleanup
= mmc_test_cleanup
,
913 .name
= "Basic read (with data verification)",
914 .prepare
= mmc_test_prepare_read
,
915 .run
= mmc_test_verify_read
,
916 .cleanup
= mmc_test_cleanup
,
920 .name
= "Multi-block write",
921 .prepare
= mmc_test_prepare_write
,
922 .run
= mmc_test_multi_write
,
923 .cleanup
= mmc_test_cleanup
,
927 .name
= "Multi-block read",
928 .prepare
= mmc_test_prepare_read
,
929 .run
= mmc_test_multi_read
,
930 .cleanup
= mmc_test_cleanup
,
934 .name
= "Power of two block writes",
935 .prepare
= mmc_test_prepare_write
,
936 .run
= mmc_test_pow2_write
,
937 .cleanup
= mmc_test_cleanup
,
941 .name
= "Power of two block reads",
942 .prepare
= mmc_test_prepare_read
,
943 .run
= mmc_test_pow2_read
,
944 .cleanup
= mmc_test_cleanup
,
948 .name
= "Weird sized block writes",
949 .prepare
= mmc_test_prepare_write
,
950 .run
= mmc_test_weird_write
,
951 .cleanup
= mmc_test_cleanup
,
955 .name
= "Weird sized block reads",
956 .prepare
= mmc_test_prepare_read
,
957 .run
= mmc_test_weird_read
,
958 .cleanup
= mmc_test_cleanup
,
962 .name
= "Badly aligned write",
963 .prepare
= mmc_test_prepare_write
,
964 .run
= mmc_test_align_write
,
965 .cleanup
= mmc_test_cleanup
,
969 .name
= "Badly aligned read",
970 .prepare
= mmc_test_prepare_read
,
971 .run
= mmc_test_align_read
,
972 .cleanup
= mmc_test_cleanup
,
976 .name
= "Badly aligned multi-block write",
977 .prepare
= mmc_test_prepare_write
,
978 .run
= mmc_test_align_multi_write
,
979 .cleanup
= mmc_test_cleanup
,
983 .name
= "Badly aligned multi-block read",
984 .prepare
= mmc_test_prepare_read
,
985 .run
= mmc_test_align_multi_read
,
986 .cleanup
= mmc_test_cleanup
,
990 .name
= "Correct xfer_size at write (start failure)",
991 .run
= mmc_test_xfersize_write
,
995 .name
= "Correct xfer_size at read (start failure)",
996 .run
= mmc_test_xfersize_read
,
1000 .name
= "Correct xfer_size at write (midway failure)",
1001 .run
= mmc_test_multi_xfersize_write
,
1005 .name
= "Correct xfer_size at read (midway failure)",
1006 .run
= mmc_test_multi_xfersize_read
,
1009 #ifdef CONFIG_HIGHMEM
1012 .name
= "Highmem write",
1013 .prepare
= mmc_test_prepare_write
,
1014 .run
= mmc_test_write_high
,
1015 .cleanup
= mmc_test_cleanup
,
1019 .name
= "Highmem read",
1020 .prepare
= mmc_test_prepare_read
,
1021 .run
= mmc_test_read_high
,
1022 .cleanup
= mmc_test_cleanup
,
1026 .name
= "Multi-block highmem write",
1027 .prepare
= mmc_test_prepare_write
,
1028 .run
= mmc_test_multi_write_high
,
1029 .cleanup
= mmc_test_cleanup
,
1033 .name
= "Multi-block highmem read",
1034 .prepare
= mmc_test_prepare_read
,
1035 .run
= mmc_test_multi_read_high
,
1036 .cleanup
= mmc_test_cleanup
,
1039 #endif /* CONFIG_HIGHMEM */
1043 static DEFINE_MUTEX(mmc_test_lock
);
1045 static void mmc_test_run(struct mmc_test_card
*test
, int testcase
)
1049 printk(KERN_INFO
"%s: Starting tests of card %s...\n",
1050 mmc_hostname(test
->card
->host
), mmc_card_id(test
->card
));
1052 mmc_claim_host(test
->card
->host
);
1054 for (i
= 0;i
< ARRAY_SIZE(mmc_test_cases
);i
++) {
1055 if (testcase
&& ((i
+ 1) != testcase
))
1058 printk(KERN_INFO
"%s: Test case %d. %s...\n",
1059 mmc_hostname(test
->card
->host
), i
+ 1,
1060 mmc_test_cases
[i
].name
);
1062 if (mmc_test_cases
[i
].prepare
) {
1063 ret
= mmc_test_cases
[i
].prepare(test
);
1065 printk(KERN_INFO
"%s: Result: Prepare "
1066 "stage failed! (%d)\n",
1067 mmc_hostname(test
->card
->host
),
1073 ret
= mmc_test_cases
[i
].run(test
);
1076 printk(KERN_INFO
"%s: Result: OK\n",
1077 mmc_hostname(test
->card
->host
));
1080 printk(KERN_INFO
"%s: Result: FAILED\n",
1081 mmc_hostname(test
->card
->host
));
1083 case RESULT_UNSUP_HOST
:
1084 printk(KERN_INFO
"%s: Result: UNSUPPORTED "
1086 mmc_hostname(test
->card
->host
));
1088 case RESULT_UNSUP_CARD
:
1089 printk(KERN_INFO
"%s: Result: UNSUPPORTED "
1091 mmc_hostname(test
->card
->host
));
1094 printk(KERN_INFO
"%s: Result: ERROR (%d)\n",
1095 mmc_hostname(test
->card
->host
), ret
);
1098 if (mmc_test_cases
[i
].cleanup
) {
1099 ret
= mmc_test_cases
[i
].cleanup(test
);
1101 printk(KERN_INFO
"%s: Warning: Cleanup "
1102 "stage failed! (%d)\n",
1103 mmc_hostname(test
->card
->host
),
1109 mmc_release_host(test
->card
->host
);
1111 printk(KERN_INFO
"%s: Tests completed.\n",
1112 mmc_hostname(test
->card
->host
));
1115 static ssize_t
mmc_test_show(struct device
*dev
,
1116 struct device_attribute
*attr
, char *buf
)
1118 mutex_lock(&mmc_test_lock
);
1119 mutex_unlock(&mmc_test_lock
);
1124 static ssize_t
mmc_test_store(struct device
*dev
,
1125 struct device_attribute
*attr
, const char *buf
, size_t count
)
1127 struct mmc_card
*card
;
1128 struct mmc_test_card
*test
;
1131 card
= container_of(dev
, struct mmc_card
, dev
);
1133 testcase
= simple_strtol(buf
, NULL
, 10);
1135 test
= kzalloc(sizeof(struct mmc_test_card
), GFP_KERNEL
);
1141 test
->buffer
= kzalloc(BUFFER_SIZE
, GFP_KERNEL
);
1142 #ifdef CONFIG_HIGHMEM
1143 test
->highmem
= alloc_pages(GFP_KERNEL
| __GFP_HIGHMEM
, BUFFER_ORDER
);
1146 #ifdef CONFIG_HIGHMEM
1147 if (test
->buffer
&& test
->highmem
) {
1151 mutex_lock(&mmc_test_lock
);
1152 mmc_test_run(test
, testcase
);
1153 mutex_unlock(&mmc_test_lock
);
1156 #ifdef CONFIG_HIGHMEM
1157 __free_pages(test
->highmem
, BUFFER_ORDER
);
1159 kfree(test
->buffer
);
1165 static DEVICE_ATTR(test
, S_IWUSR
| S_IRUGO
, mmc_test_show
, mmc_test_store
);
1167 static int mmc_test_probe(struct mmc_card
*card
)
1171 if ((card
->type
!= MMC_TYPE_MMC
) && (card
->type
!= MMC_TYPE_SD
))
1174 ret
= device_create_file(&card
->dev
, &dev_attr_test
);
1178 dev_info(&card
->dev
, "Card claimed for testing.\n");
1183 static void mmc_test_remove(struct mmc_card
*card
)
1185 device_remove_file(&card
->dev
, &dev_attr_test
);
1188 static struct mmc_driver mmc_driver
= {
1192 .probe
= mmc_test_probe
,
1193 .remove
= mmc_test_remove
,
1196 static int __init
mmc_test_init(void)
1198 return mmc_register_driver(&mmc_driver
);
1201 static void __exit
mmc_test_exit(void)
1203 mmc_unregister_driver(&mmc_driver
);
1206 module_init(mmc_test_init
);
1207 module_exit(mmc_test_exit
);
1209 MODULE_LICENSE("GPL");
1210 MODULE_DESCRIPTION("Multimedia Card (MMC) host test driver");
1211 MODULE_AUTHOR("Pierre Ossman");