mmc_test.c 25 KB

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