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