mmc_test.c 25 KB

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