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