mmc_test.c 27 KB

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