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