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");