]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/mmc/card/mmc_test.c
d6b9b486417cc702acb18bba2fd413baedf592d9
[linux-2.6-omap-h63xx.git] / drivers / mmc / card / mmc_test.c
1 /*
2  *  linux/drivers/mmc/card/mmc_test.c
3  *
4  *  Copyright 2007-2008 Pierre Ossman
5  *
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.
10  */
11
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
17 #include <linux/scatterlist.h>
18
19 #define RESULT_OK               0
20 #define RESULT_FAIL             1
21 #define RESULT_UNSUP_HOST       2
22 #define RESULT_UNSUP_CARD       3
23
24 #define BUFFER_SIZE     (PAGE_SIZE * 4)
25
26 struct mmc_test_card {
27         struct mmc_card *card;
28
29         u8              scratch[BUFFER_SIZE];
30         u8              *buffer;
31 };
32
33 /*******************************************************************/
34 /*  General helper functions                                       */
35 /*******************************************************************/
36
37 /*
38  * Configure correct block size in card
39  */
40 static int mmc_test_set_blksize(struct mmc_test_card *test, unsigned size)
41 {
42         struct mmc_command cmd;
43         int ret;
44
45         cmd.opcode = MMC_SET_BLOCKLEN;
46         cmd.arg = size;
47         cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
48         ret = mmc_wait_for_cmd(test->card->host, &cmd, 0);
49         if (ret)
50                 return ret;
51
52         return 0;
53 }
54
55 /*
56  * Fill in the mmc_request structure given a set of transfer parameters.
57  */
58 static void mmc_test_prepare_mrq(struct mmc_test_card *test,
59         struct mmc_request *mrq, struct scatterlist *sg, unsigned sg_len,
60         unsigned dev_addr, unsigned blocks, unsigned blksz, int write)
61 {
62         BUG_ON(!mrq || !mrq->cmd || !mrq->data || !mrq->stop);
63
64         if (blocks > 1) {
65                 mrq->cmd->opcode = write ?
66                         MMC_WRITE_MULTIPLE_BLOCK : MMC_READ_MULTIPLE_BLOCK;
67         } else {
68                 mrq->cmd->opcode = write ?
69                         MMC_WRITE_BLOCK : MMC_READ_SINGLE_BLOCK;
70         }
71
72         mrq->cmd->arg = dev_addr;
73         mrq->cmd->flags = MMC_RSP_R1 | MMC_CMD_ADTC;
74
75         if (blocks == 1)
76                 mrq->stop = NULL;
77         else {
78                 mrq->stop->opcode = MMC_STOP_TRANSMISSION;
79                 mrq->stop->arg = 0;
80                 mrq->stop->flags = MMC_RSP_R1B | MMC_CMD_AC;
81         }
82
83         mrq->data->blksz = blksz;
84         mrq->data->blocks = blocks;
85         mrq->data->flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
86         mrq->data->sg = sg;
87         mrq->data->sg_len = sg_len;
88
89         mmc_set_data_timeout(mrq->data, test->card);
90 }
91
92 /*
93  * Wait for the card to finish the busy state
94  */
95 static int mmc_test_wait_busy(struct mmc_test_card *test)
96 {
97         int ret, busy;
98         struct mmc_command cmd;
99
100         busy = 0;
101         do {
102                 memset(&cmd, 0, sizeof(struct mmc_command));
103
104                 cmd.opcode = MMC_SEND_STATUS;
105                 cmd.arg = test->card->rca << 16;
106                 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
107
108                 ret = mmc_wait_for_cmd(test->card->host, &cmd, 0);
109                 if (ret)
110                         break;
111
112                 if (!busy && !(cmd.resp[0] & R1_READY_FOR_DATA)) {
113                         busy = 1;
114                         printk(KERN_INFO "%s: Warning: Host did not "
115                                 "wait for busy state to end.\n",
116                                 mmc_hostname(test->card->host));
117                 }
118         } while (!(cmd.resp[0] & R1_READY_FOR_DATA));
119
120         return ret;
121 }
122
123 /*
124  * Transfer a single sector of kernel addressable data
125  */
126 static int mmc_test_buffer_transfer(struct mmc_test_card *test,
127         u8 *buffer, unsigned addr, unsigned blksz, int write)
128 {
129         int ret;
130
131         struct mmc_request mrq;
132         struct mmc_command cmd;
133         struct mmc_command stop;
134         struct mmc_data data;
135
136         struct scatterlist sg;
137
138         memset(&mrq, 0, sizeof(struct mmc_request));
139         memset(&cmd, 0, sizeof(struct mmc_command));
140         memset(&data, 0, sizeof(struct mmc_data));
141         memset(&stop, 0, sizeof(struct mmc_command));
142
143         mrq.cmd = &cmd;
144         mrq.data = &data;
145         mrq.stop = &stop;
146
147         sg_init_one(&sg, buffer, blksz);
148
149         mmc_test_prepare_mrq(test, &mrq, &sg, 1, addr, 1, blksz, write);
150
151         mmc_wait_for_req(test->card->host, &mrq);
152
153         if (cmd.error)
154                 return cmd.error;
155         if (data.error)
156                 return data.error;
157
158         ret = mmc_test_wait_busy(test);
159         if (ret)
160                 return ret;
161
162         return 0;
163 }
164
165 /*******************************************************************/
166 /*  Test preparation and cleanup                                   */
167 /*******************************************************************/
168
169 /*
170  * Fill the first couple of sectors of the card with known data
171  * so that bad reads/writes can be detected
172  */
173 static int __mmc_test_prepare(struct mmc_test_card *test, int write)
174 {
175         int ret, i;
176
177         ret = mmc_test_set_blksize(test, 512);
178         if (ret)
179                 return ret;
180
181         if (write)
182                 memset(test->buffer, 0xDF, 512);
183         else {
184                 for (i = 0;i < 512;i++)
185                         test->buffer[i] = i;
186         }
187
188         for (i = 0;i < BUFFER_SIZE / 512;i++) {
189                 ret = mmc_test_buffer_transfer(test, test->buffer, i * 512, 512, 1);
190                 if (ret)
191                         return ret;
192         }
193
194         return 0;
195 }
196
197 static int mmc_test_prepare_write(struct mmc_test_card *test)
198 {
199         return __mmc_test_prepare(test, 1);
200 }
201
202 static int mmc_test_prepare_read(struct mmc_test_card *test)
203 {
204         return __mmc_test_prepare(test, 0);
205 }
206
207 static int mmc_test_cleanup(struct mmc_test_card *test)
208 {
209         int ret, i;
210
211         ret = mmc_test_set_blksize(test, 512);
212         if (ret)
213                 return ret;
214
215         memset(test->buffer, 0, 512);
216
217         for (i = 0;i < BUFFER_SIZE / 512;i++) {
218                 ret = mmc_test_buffer_transfer(test, test->buffer, i * 512, 512, 1);
219                 if (ret)
220                         return ret;
221         }
222
223         return 0;
224 }
225
226 /*******************************************************************/
227 /*  Test execution helpers                                         */
228 /*******************************************************************/
229
230 /*
231  * Modifies the mmc_request to perform the "short transfer" tests
232  */
233 static void mmc_test_prepare_broken_mrq(struct mmc_test_card *test,
234         struct mmc_request *mrq, int write)
235 {
236         BUG_ON(!mrq || !mrq->cmd || !mrq->data);
237
238         if (mrq->data->blocks > 1) {
239                 mrq->cmd->opcode = write ?
240                         MMC_WRITE_BLOCK : MMC_READ_SINGLE_BLOCK;
241                 mrq->stop = NULL;
242         } else {
243                 mrq->cmd->opcode = MMC_SEND_STATUS;
244                 mrq->cmd->arg = test->card->rca << 16;
245         }
246 }
247
248 /*
249  * Checks that a normal transfer didn't have any errors
250  */
251 static int mmc_test_check_result(struct mmc_test_card *test,
252         struct mmc_request *mrq)
253 {
254         int ret;
255
256         BUG_ON(!mrq || !mrq->cmd || !mrq->data);
257
258         ret = 0;
259
260         if (!ret && mrq->cmd->error)
261                 ret = mrq->cmd->error;
262         if (!ret && mrq->data->error)
263                 ret = mrq->data->error;
264         if (!ret && mrq->stop && mrq->stop->error)
265                 ret = mrq->stop->error;
266         if (!ret && mrq->data->bytes_xfered !=
267                 mrq->data->blocks * mrq->data->blksz)
268                 ret = RESULT_FAIL;
269
270         if (ret == -EINVAL)
271                 ret = RESULT_UNSUP_HOST;
272
273         return ret;
274 }
275
276 /*
277  * Checks that a "short transfer" behaved as expected
278  */
279 static int mmc_test_check_broken_result(struct mmc_test_card *test,
280         struct mmc_request *mrq)
281 {
282         int ret;
283
284         BUG_ON(!mrq || !mrq->cmd || !mrq->data);
285
286         ret = 0;
287
288         if (!ret && mrq->cmd->error)
289                 ret = mrq->cmd->error;
290         if (!ret && mrq->data->error == 0)
291                 ret = RESULT_FAIL;
292         if (!ret && mrq->data->error != -ETIMEDOUT)
293                 ret = mrq->data->error;
294         if (!ret && mrq->stop && mrq->stop->error)
295                 ret = mrq->stop->error;
296         if (mrq->data->blocks > 1) {
297                 if (!ret && mrq->data->bytes_xfered > mrq->data->blksz)
298                         ret = RESULT_FAIL;
299         } else {
300                 if (!ret && mrq->data->bytes_xfered > 0)
301                         ret = RESULT_FAIL;
302         }
303
304         if (ret == -EINVAL)
305                 ret = RESULT_UNSUP_HOST;
306
307         return ret;
308 }
309
310 /*
311  * Tests a basic transfer with certain parameters
312  */
313 static int mmc_test_simple_transfer(struct mmc_test_card *test,
314         struct scatterlist *sg, unsigned sg_len, unsigned dev_addr,
315         unsigned blocks, unsigned blksz, int write)
316 {
317         struct mmc_request mrq;
318         struct mmc_command cmd;
319         struct mmc_command stop;
320         struct mmc_data data;
321
322         memset(&mrq, 0, sizeof(struct mmc_request));
323         memset(&cmd, 0, sizeof(struct mmc_command));
324         memset(&data, 0, sizeof(struct mmc_data));
325         memset(&stop, 0, sizeof(struct mmc_command));
326
327         mrq.cmd = &cmd;
328         mrq.data = &data;
329         mrq.stop = &stop;
330
331         mmc_test_prepare_mrq(test, &mrq, sg, sg_len, dev_addr,
332                 blocks, blksz, write);
333
334         mmc_wait_for_req(test->card->host, &mrq);
335
336         mmc_test_wait_busy(test);
337
338         return mmc_test_check_result(test, &mrq);
339 }
340
341 /*
342  * Tests a transfer where the card will fail completely or partly
343  */
344 static int mmc_test_broken_transfer(struct mmc_test_card *test,
345         unsigned blocks, unsigned blksz, int write)
346 {
347         struct mmc_request mrq;
348         struct mmc_command cmd;
349         struct mmc_command stop;
350         struct mmc_data data;
351
352         struct scatterlist sg;
353
354         memset(&mrq, 0, sizeof(struct mmc_request));
355         memset(&cmd, 0, sizeof(struct mmc_command));
356         memset(&data, 0, sizeof(struct mmc_data));
357         memset(&stop, 0, sizeof(struct mmc_command));
358
359         mrq.cmd = &cmd;
360         mrq.data = &data;
361         mrq.stop = &stop;
362
363         sg_init_one(&sg, test->buffer, blocks * blksz);
364
365         mmc_test_prepare_mrq(test, &mrq, &sg, 1, 0, blocks, blksz, write);
366         mmc_test_prepare_broken_mrq(test, &mrq, write);
367
368         mmc_wait_for_req(test->card->host, &mrq);
369
370         mmc_test_wait_busy(test);
371
372         return mmc_test_check_broken_result(test, &mrq);
373 }
374
375 /*
376  * Does a complete transfer test where data is also validated
377  *
378  * Note: mmc_test_prepare() must have been done before this call
379  */
380 static int mmc_test_transfer(struct mmc_test_card *test,
381         struct scatterlist *sg, unsigned sg_len, unsigned dev_addr,
382         unsigned blocks, unsigned blksz, int write)
383 {
384         int ret, i;
385         unsigned long flags;
386
387         if (write) {
388                 for (i = 0;i < blocks * blksz;i++)
389                         test->scratch[i] = i;
390         } else {
391                 memset(test->scratch, 0, BUFFER_SIZE);
392         }
393         local_irq_save(flags);
394         sg_copy_from_buffer(sg, sg_len, test->scratch, BUFFER_SIZE);
395         local_irq_restore(flags);
396
397         ret = mmc_test_set_blksize(test, blksz);
398         if (ret)
399                 return ret;
400
401         ret = mmc_test_simple_transfer(test, sg, sg_len, dev_addr,
402                 blocks, blksz, write);
403         if (ret)
404                 return ret;
405
406         if (write) {
407                 int sectors;
408
409                 ret = mmc_test_set_blksize(test, 512);
410                 if (ret)
411                         return ret;
412
413                 sectors = (blocks * blksz + 511) / 512;
414                 if ((sectors * 512) == (blocks * blksz))
415                         sectors++;
416
417                 if ((sectors * 512) > BUFFER_SIZE)
418                         return -EINVAL;
419
420                 memset(test->buffer, 0, sectors * 512);
421
422                 for (i = 0;i < sectors;i++) {
423                         ret = mmc_test_buffer_transfer(test,
424                                 test->buffer + i * 512,
425                                 dev_addr + i * 512, 512, 0);
426                         if (ret)
427                                 return ret;
428                 }
429
430                 for (i = 0;i < blocks * blksz;i++) {
431                         if (test->buffer[i] != (u8)i)
432                                 return RESULT_FAIL;
433                 }
434
435                 for (;i < sectors * 512;i++) {
436                         if (test->buffer[i] != 0xDF)
437                                 return RESULT_FAIL;
438                 }
439         } else {
440                 local_irq_save(flags);
441                 sg_copy_to_buffer(sg, sg_len, test->scratch, BUFFER_SIZE);
442                 local_irq_restore(flags);
443                 for (i = 0;i < blocks * blksz;i++) {
444                         if (test->scratch[i] != (u8)i)
445                                 return RESULT_FAIL;
446                 }
447         }
448
449         return 0;
450 }
451
452 /*******************************************************************/
453 /*  Tests                                                          */
454 /*******************************************************************/
455
456 struct mmc_test_case {
457         const char *name;
458
459         int (*prepare)(struct mmc_test_card *);
460         int (*run)(struct mmc_test_card *);
461         int (*cleanup)(struct mmc_test_card *);
462 };
463
464 static int mmc_test_basic_write(struct mmc_test_card *test)
465 {
466         int ret;
467         struct scatterlist sg;
468
469         ret = mmc_test_set_blksize(test, 512);
470         if (ret)
471                 return ret;
472
473         sg_init_one(&sg, test->buffer, 512);
474
475         ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 1);
476         if (ret)
477                 return ret;
478
479         return 0;
480 }
481
482 static int mmc_test_basic_read(struct mmc_test_card *test)
483 {
484         int ret;
485         struct scatterlist sg;
486
487         ret = mmc_test_set_blksize(test, 512);
488         if (ret)
489                 return ret;
490
491         sg_init_one(&sg, test->buffer, 512);
492
493         ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 1);
494         if (ret)
495                 return ret;
496
497         return 0;
498 }
499
500 static int mmc_test_verify_write(struct mmc_test_card *test)
501 {
502         int ret;
503         struct scatterlist sg;
504
505         sg_init_one(&sg, test->buffer, 512);
506
507         ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1);
508         if (ret)
509                 return ret;
510
511         return 0;
512 }
513
514 static int mmc_test_verify_read(struct mmc_test_card *test)
515 {
516         int ret;
517         struct scatterlist sg;
518
519         sg_init_one(&sg, test->buffer, 512);
520
521         ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0);
522         if (ret)
523                 return ret;
524
525         return 0;
526 }
527
528 static int mmc_test_multi_write(struct mmc_test_card *test)
529 {
530         int ret;
531         unsigned int size;
532         struct scatterlist sg;
533
534         if (test->card->host->max_blk_count == 1)
535                 return RESULT_UNSUP_HOST;
536
537         size = PAGE_SIZE * 2;
538         size = min(size, test->card->host->max_req_size);
539         size = min(size, test->card->host->max_seg_size);
540         size = min(size, test->card->host->max_blk_count * 512);
541
542         if (size < 1024)
543                 return RESULT_UNSUP_HOST;
544
545         sg_init_one(&sg, test->buffer, size);
546
547         ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1);
548         if (ret)
549                 return ret;
550
551         return 0;
552 }
553
554 static int mmc_test_multi_read(struct mmc_test_card *test)
555 {
556         int ret;
557         unsigned int size;
558         struct scatterlist sg;
559
560         if (test->card->host->max_blk_count == 1)
561                 return RESULT_UNSUP_HOST;
562
563         size = PAGE_SIZE * 2;
564         size = min(size, test->card->host->max_req_size);
565         size = min(size, test->card->host->max_seg_size);
566         size = min(size, test->card->host->max_blk_count * 512);
567
568         if (size < 1024)
569                 return RESULT_UNSUP_HOST;
570
571         sg_init_one(&sg, test->buffer, size);
572
573         ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0);
574         if (ret)
575                 return ret;
576
577         return 0;
578 }
579
580 static int mmc_test_pow2_write(struct mmc_test_card *test)
581 {
582         int ret, i;
583         struct scatterlist sg;
584
585         if (!test->card->csd.write_partial)
586                 return RESULT_UNSUP_CARD;
587
588         for (i = 1; i < 512;i <<= 1) {
589                 sg_init_one(&sg, test->buffer, i);
590                 ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 1);
591                 if (ret)
592                         return ret;
593         }
594
595         return 0;
596 }
597
598 static int mmc_test_pow2_read(struct mmc_test_card *test)
599 {
600         int ret, i;
601         struct scatterlist sg;
602
603         if (!test->card->csd.read_partial)
604                 return RESULT_UNSUP_CARD;
605
606         for (i = 1; i < 512;i <<= 1) {
607                 sg_init_one(&sg, test->buffer, i);
608                 ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 0);
609                 if (ret)
610                         return ret;
611         }
612
613         return 0;
614 }
615
616 static int mmc_test_weird_write(struct mmc_test_card *test)
617 {
618         int ret, i;
619         struct scatterlist sg;
620
621         if (!test->card->csd.write_partial)
622                 return RESULT_UNSUP_CARD;
623
624         for (i = 3; i < 512;i += 7) {
625                 sg_init_one(&sg, test->buffer, i);
626                 ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 1);
627                 if (ret)
628                         return ret;
629         }
630
631         return 0;
632 }
633
634 static int mmc_test_weird_read(struct mmc_test_card *test)
635 {
636         int ret, i;
637         struct scatterlist sg;
638
639         if (!test->card->csd.read_partial)
640                 return RESULT_UNSUP_CARD;
641
642         for (i = 3; i < 512;i += 7) {
643                 sg_init_one(&sg, test->buffer, i);
644                 ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 0);
645                 if (ret)
646                         return ret;
647         }
648
649         return 0;
650 }
651
652 static int mmc_test_align_write(struct mmc_test_card *test)
653 {
654         int ret, i;
655         struct scatterlist sg;
656
657         for (i = 1;i < 4;i++) {
658                 sg_init_one(&sg, test->buffer + i, 512);
659                 ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1);
660                 if (ret)
661                         return ret;
662         }
663
664         return 0;
665 }
666
667 static int mmc_test_align_read(struct mmc_test_card *test)
668 {
669         int ret, i;
670         struct scatterlist sg;
671
672         for (i = 1;i < 4;i++) {
673                 sg_init_one(&sg, test->buffer + i, 512);
674                 ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0);
675                 if (ret)
676                         return ret;
677         }
678
679         return 0;
680 }
681
682 static int mmc_test_align_multi_write(struct mmc_test_card *test)
683 {
684         int ret, i;
685         unsigned int size;
686         struct scatterlist sg;
687
688         if (test->card->host->max_blk_count == 1)
689                 return RESULT_UNSUP_HOST;
690
691         size = PAGE_SIZE * 2;
692         size = min(size, test->card->host->max_req_size);
693         size = min(size, test->card->host->max_seg_size);
694         size = min(size, test->card->host->max_blk_count * 512);
695
696         if (size < 1024)
697                 return RESULT_UNSUP_HOST;
698
699         for (i = 1;i < 4;i++) {
700                 sg_init_one(&sg, test->buffer + i, size);
701                 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1);
702                 if (ret)
703                         return ret;
704         }
705
706         return 0;
707 }
708
709 static int mmc_test_align_multi_read(struct mmc_test_card *test)
710 {
711         int ret, i;
712         unsigned int size;
713         struct scatterlist sg;
714
715         if (test->card->host->max_blk_count == 1)
716                 return RESULT_UNSUP_HOST;
717
718         size = PAGE_SIZE * 2;
719         size = min(size, test->card->host->max_req_size);
720         size = min(size, test->card->host->max_seg_size);
721         size = min(size, test->card->host->max_blk_count * 512);
722
723         if (size < 1024)
724                 return RESULT_UNSUP_HOST;
725
726         for (i = 1;i < 4;i++) {
727                 sg_init_one(&sg, test->buffer + i, size);
728                 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0);
729                 if (ret)
730                         return ret;
731         }
732
733         return 0;
734 }
735
736 static int mmc_test_xfersize_write(struct mmc_test_card *test)
737 {
738         int ret;
739
740         ret = mmc_test_set_blksize(test, 512);
741         if (ret)
742                 return ret;
743
744         ret = mmc_test_broken_transfer(test, 1, 512, 1);
745         if (ret)
746                 return ret;
747
748         return 0;
749 }
750
751 static int mmc_test_xfersize_read(struct mmc_test_card *test)
752 {
753         int ret;
754
755         ret = mmc_test_set_blksize(test, 512);
756         if (ret)
757                 return ret;
758
759         ret = mmc_test_broken_transfer(test, 1, 512, 0);
760         if (ret)
761                 return ret;
762
763         return 0;
764 }
765
766 static int mmc_test_multi_xfersize_write(struct mmc_test_card *test)
767 {
768         int ret;
769
770         if (test->card->host->max_blk_count == 1)
771                 return RESULT_UNSUP_HOST;
772
773         ret = mmc_test_set_blksize(test, 512);
774         if (ret)
775                 return ret;
776
777         ret = mmc_test_broken_transfer(test, 2, 512, 1);
778         if (ret)
779                 return ret;
780
781         return 0;
782 }
783
784 static int mmc_test_multi_xfersize_read(struct mmc_test_card *test)
785 {
786         int ret;
787
788         if (test->card->host->max_blk_count == 1)
789                 return RESULT_UNSUP_HOST;
790
791         ret = mmc_test_set_blksize(test, 512);
792         if (ret)
793                 return ret;
794
795         ret = mmc_test_broken_transfer(test, 2, 512, 0);
796         if (ret)
797                 return ret;
798
799         return 0;
800 }
801
802 static const struct mmc_test_case mmc_test_cases[] = {
803         {
804                 .name = "Basic write (no data verification)",
805                 .run = mmc_test_basic_write,
806         },
807
808         {
809                 .name = "Basic read (no data verification)",
810                 .run = mmc_test_basic_read,
811         },
812
813         {
814                 .name = "Basic write (with data verification)",
815                 .prepare = mmc_test_prepare_write,
816                 .run = mmc_test_verify_write,
817                 .cleanup = mmc_test_cleanup,
818         },
819
820         {
821                 .name = "Basic read (with data verification)",
822                 .prepare = mmc_test_prepare_read,
823                 .run = mmc_test_verify_read,
824                 .cleanup = mmc_test_cleanup,
825         },
826
827         {
828                 .name = "Multi-block write",
829                 .prepare = mmc_test_prepare_write,
830                 .run = mmc_test_multi_write,
831                 .cleanup = mmc_test_cleanup,
832         },
833
834         {
835                 .name = "Multi-block read",
836                 .prepare = mmc_test_prepare_read,
837                 .run = mmc_test_multi_read,
838                 .cleanup = mmc_test_cleanup,
839         },
840
841         {
842                 .name = "Power of two block writes",
843                 .prepare = mmc_test_prepare_write,
844                 .run = mmc_test_pow2_write,
845                 .cleanup = mmc_test_cleanup,
846         },
847
848         {
849                 .name = "Power of two block reads",
850                 .prepare = mmc_test_prepare_read,
851                 .run = mmc_test_pow2_read,
852                 .cleanup = mmc_test_cleanup,
853         },
854
855         {
856                 .name = "Weird sized block writes",
857                 .prepare = mmc_test_prepare_write,
858                 .run = mmc_test_weird_write,
859                 .cleanup = mmc_test_cleanup,
860         },
861
862         {
863                 .name = "Weird sized block reads",
864                 .prepare = mmc_test_prepare_read,
865                 .run = mmc_test_weird_read,
866                 .cleanup = mmc_test_cleanup,
867         },
868
869         {
870                 .name = "Badly aligned write",
871                 .prepare = mmc_test_prepare_write,
872                 .run = mmc_test_align_write,
873                 .cleanup = mmc_test_cleanup,
874         },
875
876         {
877                 .name = "Badly aligned read",
878                 .prepare = mmc_test_prepare_read,
879                 .run = mmc_test_align_read,
880                 .cleanup = mmc_test_cleanup,
881         },
882
883         {
884                 .name = "Badly aligned multi-block write",
885                 .prepare = mmc_test_prepare_write,
886                 .run = mmc_test_align_multi_write,
887                 .cleanup = mmc_test_cleanup,
888         },
889
890         {
891                 .name = "Badly aligned multi-block read",
892                 .prepare = mmc_test_prepare_read,
893                 .run = mmc_test_align_multi_read,
894                 .cleanup = mmc_test_cleanup,
895         },
896
897         {
898                 .name = "Correct xfer_size at write (start failure)",
899                 .run = mmc_test_xfersize_write,
900         },
901
902         {
903                 .name = "Correct xfer_size at read (start failure)",
904                 .run = mmc_test_xfersize_read,
905         },
906
907         {
908                 .name = "Correct xfer_size at write (midway failure)",
909                 .run = mmc_test_multi_xfersize_write,
910         },
911
912         {
913                 .name = "Correct xfer_size at read (midway failure)",
914                 .run = mmc_test_multi_xfersize_read,
915         },
916 };
917
918 static struct mutex mmc_test_lock;
919
920 static void mmc_test_run(struct mmc_test_card *test, int testcase)
921 {
922         int i, ret;
923
924         printk(KERN_INFO "%s: Starting tests of card %s...\n",
925                 mmc_hostname(test->card->host), mmc_card_id(test->card));
926
927         mmc_claim_host(test->card->host);
928
929         for (i = 0;i < ARRAY_SIZE(mmc_test_cases);i++) {
930                 if (testcase && ((i + 1) != testcase))
931                         continue;
932
933                 printk(KERN_INFO "%s: Test case %d. %s...\n",
934                         mmc_hostname(test->card->host), i + 1,
935                         mmc_test_cases[i].name);
936
937                 if (mmc_test_cases[i].prepare) {
938                         ret = mmc_test_cases[i].prepare(test);
939                         if (ret) {
940                                 printk(KERN_INFO "%s: Result: Prepare "
941                                         "stage failed! (%d)\n",
942                                         mmc_hostname(test->card->host),
943                                         ret);
944                                 continue;
945                         }
946                 }
947
948                 ret = mmc_test_cases[i].run(test);
949                 switch (ret) {
950                 case RESULT_OK:
951                         printk(KERN_INFO "%s: Result: OK\n",
952                                 mmc_hostname(test->card->host));
953                         break;
954                 case RESULT_FAIL:
955                         printk(KERN_INFO "%s: Result: FAILED\n",
956                                 mmc_hostname(test->card->host));
957                         break;
958                 case RESULT_UNSUP_HOST:
959                         printk(KERN_INFO "%s: Result: UNSUPPORTED "
960                                 "(by host)\n",
961                                 mmc_hostname(test->card->host));
962                         break;
963                 case RESULT_UNSUP_CARD:
964                         printk(KERN_INFO "%s: Result: UNSUPPORTED "
965                                 "(by card)\n",
966                                 mmc_hostname(test->card->host));
967                         break;
968                 default:
969                         printk(KERN_INFO "%s: Result: ERROR (%d)\n",
970                                 mmc_hostname(test->card->host), ret);
971                 }
972
973                 if (mmc_test_cases[i].cleanup) {
974                         ret = mmc_test_cases[i].cleanup(test);
975                         if (ret) {
976                                 printk(KERN_INFO "%s: Warning: Cleanup "
977                                         "stage failed! (%d)\n",
978                                         mmc_hostname(test->card->host),
979                                         ret);
980                         }
981                 }
982         }
983
984         mmc_release_host(test->card->host);
985
986         printk(KERN_INFO "%s: Tests completed.\n",
987                 mmc_hostname(test->card->host));
988 }
989
990 static ssize_t mmc_test_show(struct device *dev,
991         struct device_attribute *attr, char *buf)
992 {
993         mutex_lock(&mmc_test_lock);
994         mutex_unlock(&mmc_test_lock);
995
996         return 0;
997 }
998
999 static ssize_t mmc_test_store(struct device *dev,
1000         struct device_attribute *attr, const char *buf, size_t count)
1001 {
1002         struct mmc_card *card;
1003         struct mmc_test_card *test;
1004         int testcase;
1005
1006         card = container_of(dev, struct mmc_card, dev);
1007
1008         testcase = simple_strtol(buf, NULL, 10);
1009
1010         test = kzalloc(sizeof(struct mmc_test_card), GFP_KERNEL);
1011         if (!test)
1012                 return -ENOMEM;
1013
1014         test->card = card;
1015
1016         test->buffer = kzalloc(BUFFER_SIZE, GFP_KERNEL);
1017         if (test->buffer) {
1018                 mutex_lock(&mmc_test_lock);
1019                 mmc_test_run(test, testcase);
1020                 mutex_unlock(&mmc_test_lock);
1021         }
1022
1023         kfree(test->buffer);
1024         kfree(test);
1025
1026         return count;
1027 }
1028
1029 static DEVICE_ATTR(test, S_IWUSR | S_IRUGO, mmc_test_show, mmc_test_store);
1030
1031 static int mmc_test_probe(struct mmc_card *card)
1032 {
1033         int ret;
1034
1035         if ((card->type != MMC_TYPE_MMC) && (card->type != MMC_TYPE_SD))
1036                 return -ENODEV;
1037
1038         mutex_init(&mmc_test_lock);
1039
1040         ret = device_create_file(&card->dev, &dev_attr_test);
1041         if (ret)
1042                 return ret;
1043
1044         return 0;
1045 }
1046
1047 static void mmc_test_remove(struct mmc_card *card)
1048 {
1049         device_remove_file(&card->dev, &dev_attr_test);
1050 }
1051
1052 static struct mmc_driver mmc_driver = {
1053         .drv            = {
1054                 .name   = "mmc_test",
1055         },
1056         .probe          = mmc_test_probe,
1057         .remove         = mmc_test_remove,
1058 };
1059
1060 static int __init mmc_test_init(void)
1061 {
1062         return mmc_register_driver(&mmc_driver);
1063 }
1064
1065 static void __exit mmc_test_exit(void)
1066 {
1067         mmc_unregister_driver(&mmc_driver);
1068 }
1069
1070 module_init(mmc_test_init);
1071 module_exit(mmc_test_exit);
1072
1073 MODULE_LICENSE("GPL");
1074 MODULE_DESCRIPTION("Multimedia Card (MMC) host test driver");
1075 MODULE_AUTHOR("Pierre Ossman");