aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/card/mmc_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/card/mmc_test.c')
-rw-r--r--drivers/mmc/card/mmc_test.c569
1 files changed, 376 insertions, 193 deletions
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c
index ffadee549a41..d6b9b486417c 100644
--- a/drivers/mmc/card/mmc_test.c
+++ b/drivers/mmc/card/mmc_test.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/drivers/mmc/card/mmc_test.c 2 * linux/drivers/mmc/card/mmc_test.c
3 * 3 *
4 * Copyright 2007 Pierre Ossman 4 * Copyright 2007-2008 Pierre Ossman
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 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 7 * it under the terms of the GNU General Public License as published by
@@ -26,13 +26,17 @@
26struct mmc_test_card { 26struct mmc_test_card {
27 struct mmc_card *card; 27 struct mmc_card *card;
28 28
29 u8 scratch[BUFFER_SIZE];
29 u8 *buffer; 30 u8 *buffer;
30}; 31};
31 32
32/*******************************************************************/ 33/*******************************************************************/
33/* Helper functions */ 34/* General helper functions */
34/*******************************************************************/ 35/*******************************************************************/
35 36
37/*
38 * Configure correct block size in card
39 */
36static int mmc_test_set_blksize(struct mmc_test_card *test, unsigned size) 40static int mmc_test_set_blksize(struct mmc_test_card *test, unsigned size)
37{ 41{
38 struct mmc_command cmd; 42 struct mmc_command cmd;
@@ -48,117 +52,61 @@ static int mmc_test_set_blksize(struct mmc_test_card *test, unsigned size)
48 return 0; 52 return 0;
49} 53}
50 54
51static int __mmc_test_transfer(struct mmc_test_card *test, int write, 55/*
52 unsigned broken_xfer, u8 *buffer, unsigned addr, 56 * Fill in the mmc_request structure given a set of transfer parameters.
53 unsigned blocks, unsigned blksz) 57 */
58static void mmc_test_prepare_mrq(struct mmc_test_card *test,
59 struct mmc_request *mrq, struct scatterlist *sg, unsigned sg_len,
60 unsigned dev_addr, unsigned blocks, unsigned blksz, int write)
54{ 61{
55 int ret, busy; 62 BUG_ON(!mrq || !mrq->cmd || !mrq->data || !mrq->stop);
56
57 struct mmc_request mrq;
58 struct mmc_command cmd;
59 struct mmc_command stop;
60 struct mmc_data data;
61
62 struct scatterlist sg;
63
64 memset(&mrq, 0, sizeof(struct mmc_request));
65
66 mrq.cmd = &cmd;
67 mrq.data = &data;
68
69 memset(&cmd, 0, sizeof(struct mmc_command));
70 63
71 if (broken_xfer) { 64 if (blocks > 1) {
72 if (blocks > 1) { 65 mrq->cmd->opcode = write ?
73 cmd.opcode = write ? 66 MMC_WRITE_MULTIPLE_BLOCK : MMC_READ_MULTIPLE_BLOCK;
74 MMC_WRITE_BLOCK : MMC_READ_SINGLE_BLOCK;
75 } else {
76 cmd.opcode = MMC_SEND_STATUS;
77 }
78 } else { 67 } else {
79 if (blocks > 1) { 68 mrq->cmd->opcode = write ?
80 cmd.opcode = write ? 69 MMC_WRITE_BLOCK : MMC_READ_SINGLE_BLOCK;
81 MMC_WRITE_MULTIPLE_BLOCK : MMC_READ_MULTIPLE_BLOCK;
82 } else {
83 cmd.opcode = write ?
84 MMC_WRITE_BLOCK : MMC_READ_SINGLE_BLOCK;
85 }
86 } 70 }
87 71
88 if (broken_xfer && blocks == 1) 72 mrq->cmd->arg = dev_addr;
89 cmd.arg = test->card->rca << 16; 73 mrq->cmd->flags = MMC_RSP_R1 | MMC_CMD_ADTC;
90 else
91 cmd.arg = addr;
92 cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
93 74
94 memset(&stop, 0, sizeof(struct mmc_command)); 75 if (blocks == 1)
95 76 mrq->stop = NULL;
96 if (!broken_xfer && (blocks > 1)) { 77 else {
97 stop.opcode = MMC_STOP_TRANSMISSION; 78 mrq->stop->opcode = MMC_STOP_TRANSMISSION;
98 stop.arg = 0; 79 mrq->stop->arg = 0;
99 stop.flags = MMC_RSP_R1B | MMC_CMD_AC; 80 mrq->stop->flags = MMC_RSP_R1B | MMC_CMD_AC;
100
101 mrq.stop = &stop;
102 } 81 }
103 82
104 memset(&data, 0, sizeof(struct mmc_data)); 83 mrq->data->blksz = blksz;
105 84 mrq->data->blocks = blocks;
106 data.blksz = blksz; 85 mrq->data->flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
107 data.blocks = blocks; 86 mrq->data->sg = sg;
108 data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; 87 mrq->data->sg_len = sg_len;
109 data.sg = &sg;
110 data.sg_len = 1;
111
112 sg_init_one(&sg, buffer, blocks * blksz);
113
114 mmc_set_data_timeout(&data, test->card);
115 88
116 mmc_wait_for_req(test->card->host, &mrq); 89 mmc_set_data_timeout(mrq->data, test->card);
117 90}
118 ret = 0;
119
120 if (broken_xfer) {
121 if (!ret && cmd.error)
122 ret = cmd.error;
123 if (!ret && data.error == 0)
124 ret = RESULT_FAIL;
125 if (!ret && data.error != -ETIMEDOUT)
126 ret = data.error;
127 if (!ret && stop.error)
128 ret = stop.error;
129 if (blocks > 1) {
130 if (!ret && data.bytes_xfered > blksz)
131 ret = RESULT_FAIL;
132 } else {
133 if (!ret && data.bytes_xfered > 0)
134 ret = RESULT_FAIL;
135 }
136 } else {
137 if (!ret && cmd.error)
138 ret = cmd.error;
139 if (!ret && data.error)
140 ret = data.error;
141 if (!ret && stop.error)
142 ret = stop.error;
143 if (!ret && data.bytes_xfered != blocks * blksz)
144 ret = RESULT_FAIL;
145 }
146 91
147 if (ret == -EINVAL) 92/*
148 ret = RESULT_UNSUP_HOST; 93 * Wait for the card to finish the busy state
94 */
95static int mmc_test_wait_busy(struct mmc_test_card *test)
96{
97 int ret, busy;
98 struct mmc_command cmd;
149 99
150 busy = 0; 100 busy = 0;
151 do { 101 do {
152 int ret2;
153
154 memset(&cmd, 0, sizeof(struct mmc_command)); 102 memset(&cmd, 0, sizeof(struct mmc_command));
155 103
156 cmd.opcode = MMC_SEND_STATUS; 104 cmd.opcode = MMC_SEND_STATUS;
157 cmd.arg = test->card->rca << 16; 105 cmd.arg = test->card->rca << 16;
158 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 106 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
159 107
160 ret2 = mmc_wait_for_cmd(test->card->host, &cmd, 0); 108 ret = mmc_wait_for_cmd(test->card->host, &cmd, 0);
161 if (ret2) 109 if (ret)
162 break; 110 break;
163 111
164 if (!busy && !(cmd.resp[0] & R1_READY_FOR_DATA)) { 112 if (!busy && !(cmd.resp[0] & R1_READY_FOR_DATA)) {
@@ -172,14 +120,57 @@ static int __mmc_test_transfer(struct mmc_test_card *test, int write,
172 return ret; 120 return ret;
173} 121}
174 122
175static int mmc_test_transfer(struct mmc_test_card *test, int write, 123/*
176 u8 *buffer, unsigned addr, unsigned blocks, unsigned blksz) 124 * Transfer a single sector of kernel addressable data
125 */
126static int mmc_test_buffer_transfer(struct mmc_test_card *test,
127 u8 *buffer, unsigned addr, unsigned blksz, int write)
177{ 128{
178 return __mmc_test_transfer(test, write, 0, buffer, 129 int ret;
179 addr, blocks, blksz); 130
131 struct mmc_request mrq;
132 struct mmc_command cmd;
133 struct mmc_command stop;
134 struct mmc_data data;
135
136 struct scatterlist sg;
137
138 memset(&mrq, 0, sizeof(struct mmc_request));
139 memset(&cmd, 0, sizeof(struct mmc_command));
140 memset(&data, 0, sizeof(struct mmc_data));
141 memset(&stop, 0, sizeof(struct mmc_command));
142
143 mrq.cmd = &cmd;
144 mrq.data = &data;
145 mrq.stop = &stop;
146
147 sg_init_one(&sg, buffer, blksz);
148
149 mmc_test_prepare_mrq(test, &mrq, &sg, 1, addr, 1, blksz, write);
150
151 mmc_wait_for_req(test->card->host, &mrq);
152
153 if (cmd.error)
154 return cmd.error;
155 if (data.error)
156 return data.error;
157
158 ret = mmc_test_wait_busy(test);
159 if (ret)
160 return ret;
161
162 return 0;
180} 163}
181 164
182static int mmc_test_prepare_verify(struct mmc_test_card *test, int write) 165/*******************************************************************/
166/* Test preparation and cleanup */
167/*******************************************************************/
168
169/*
170 * Fill the first couple of sectors of the card with known data
171 * so that bad reads/writes can be detected
172 */
173static int __mmc_test_prepare(struct mmc_test_card *test, int write)
183{ 174{
184 int ret, i; 175 int ret, i;
185 176
@@ -188,15 +179,14 @@ static int mmc_test_prepare_verify(struct mmc_test_card *test, int write)
188 return ret; 179 return ret;
189 180
190 if (write) 181 if (write)
191 memset(test->buffer, 0xDF, BUFFER_SIZE); 182 memset(test->buffer, 0xDF, 512);
192 else { 183 else {
193 for (i = 0;i < BUFFER_SIZE;i++) 184 for (i = 0;i < 512;i++)
194 test->buffer[i] = i; 185 test->buffer[i] = i;
195 } 186 }
196 187
197 for (i = 0;i < BUFFER_SIZE / 512;i++) { 188 for (i = 0;i < BUFFER_SIZE / 512;i++) {
198 ret = mmc_test_transfer(test, 1, test->buffer + i * 512, 189 ret = mmc_test_buffer_transfer(test, test->buffer, i * 512, 512, 1);
199 i * 512, 1, 512);
200 if (ret) 190 if (ret)
201 return ret; 191 return ret;
202 } 192 }
@@ -204,41 +194,218 @@ static int mmc_test_prepare_verify(struct mmc_test_card *test, int write)
204 return 0; 194 return 0;
205} 195}
206 196
207static int mmc_test_prepare_verify_write(struct mmc_test_card *test) 197static int mmc_test_prepare_write(struct mmc_test_card *test)
198{
199 return __mmc_test_prepare(test, 1);
200}
201
202static int mmc_test_prepare_read(struct mmc_test_card *test)
203{
204 return __mmc_test_prepare(test, 0);
205}
206
207static int mmc_test_cleanup(struct mmc_test_card *test)
208{ 208{
209 return mmc_test_prepare_verify(test, 1); 209 int ret, i;
210
211 ret = mmc_test_set_blksize(test, 512);
212 if (ret)
213 return ret;
214
215 memset(test->buffer, 0, 512);
216
217 for (i = 0;i < BUFFER_SIZE / 512;i++) {
218 ret = mmc_test_buffer_transfer(test, test->buffer, i * 512, 512, 1);
219 if (ret)
220 return ret;
221 }
222
223 return 0;
210} 224}
211 225
212static int mmc_test_prepare_verify_read(struct mmc_test_card *test) 226/*******************************************************************/
227/* Test execution helpers */
228/*******************************************************************/
229
230/*
231 * Modifies the mmc_request to perform the "short transfer" tests
232 */
233static void mmc_test_prepare_broken_mrq(struct mmc_test_card *test,
234 struct mmc_request *mrq, int write)
213{ 235{
214 return mmc_test_prepare_verify(test, 0); 236 BUG_ON(!mrq || !mrq->cmd || !mrq->data);
237
238 if (mrq->data->blocks > 1) {
239 mrq->cmd->opcode = write ?
240 MMC_WRITE_BLOCK : MMC_READ_SINGLE_BLOCK;
241 mrq->stop = NULL;
242 } else {
243 mrq->cmd->opcode = MMC_SEND_STATUS;
244 mrq->cmd->arg = test->card->rca << 16;
245 }
215} 246}
216 247
217static int mmc_test_verified_transfer(struct mmc_test_card *test, int write, 248/*
218 u8 *buffer, unsigned addr, unsigned blocks, unsigned blksz) 249 * Checks that a normal transfer didn't have any errors
250 */
251static int mmc_test_check_result(struct mmc_test_card *test,
252 struct mmc_request *mrq)
219{ 253{
220 int ret, i, sectors; 254 int ret;
221 255
222 /* 256 BUG_ON(!mrq || !mrq->cmd || !mrq->data);
223 * It is assumed that the above preparation has been done. 257
224 */ 258 ret = 0;
225 259
226 memset(test->buffer, 0, BUFFER_SIZE); 260 if (!ret && mrq->cmd->error)
261 ret = mrq->cmd->error;
262 if (!ret && mrq->data->error)
263 ret = mrq->data->error;
264 if (!ret && mrq->stop && mrq->stop->error)
265 ret = mrq->stop->error;
266 if (!ret && mrq->data->bytes_xfered !=
267 mrq->data->blocks * mrq->data->blksz)
268 ret = RESULT_FAIL;
269
270 if (ret == -EINVAL)
271 ret = RESULT_UNSUP_HOST;
272
273 return ret;
274}
275
276/*
277 * Checks that a "short transfer" behaved as expected
278 */
279static int mmc_test_check_broken_result(struct mmc_test_card *test,
280 struct mmc_request *mrq)
281{
282 int ret;
283
284 BUG_ON(!mrq || !mrq->cmd || !mrq->data);
285
286 ret = 0;
287
288 if (!ret && mrq->cmd->error)
289 ret = mrq->cmd->error;
290 if (!ret && mrq->data->error == 0)
291 ret = RESULT_FAIL;
292 if (!ret && mrq->data->error != -ETIMEDOUT)
293 ret = mrq->data->error;
294 if (!ret && mrq->stop && mrq->stop->error)
295 ret = mrq->stop->error;
296 if (mrq->data->blocks > 1) {
297 if (!ret && mrq->data->bytes_xfered > mrq->data->blksz)
298 ret = RESULT_FAIL;
299 } else {
300 if (!ret && mrq->data->bytes_xfered > 0)
301 ret = RESULT_FAIL;
302 }
303
304 if (ret == -EINVAL)
305 ret = RESULT_UNSUP_HOST;
306
307 return ret;
308}
309
310/*
311 * Tests a basic transfer with certain parameters
312 */
313static int mmc_test_simple_transfer(struct mmc_test_card *test,
314 struct scatterlist *sg, unsigned sg_len, unsigned dev_addr,
315 unsigned blocks, unsigned blksz, int write)
316{
317 struct mmc_request mrq;
318 struct mmc_command cmd;
319 struct mmc_command stop;
320 struct mmc_data data;
321
322 memset(&mrq, 0, sizeof(struct mmc_request));
323 memset(&cmd, 0, sizeof(struct mmc_command));
324 memset(&data, 0, sizeof(struct mmc_data));
325 memset(&stop, 0, sizeof(struct mmc_command));
326
327 mrq.cmd = &cmd;
328 mrq.data = &data;
329 mrq.stop = &stop;
330
331 mmc_test_prepare_mrq(test, &mrq, sg, sg_len, dev_addr,
332 blocks, blksz, write);
333
334 mmc_wait_for_req(test->card->host, &mrq);
335
336 mmc_test_wait_busy(test);
337
338 return mmc_test_check_result(test, &mrq);
339}
340
341/*
342 * Tests a transfer where the card will fail completely or partly
343 */
344static int mmc_test_broken_transfer(struct mmc_test_card *test,
345 unsigned blocks, unsigned blksz, int write)
346{
347 struct mmc_request mrq;
348 struct mmc_command cmd;
349 struct mmc_command stop;
350 struct mmc_data data;
351
352 struct scatterlist sg;
353
354 memset(&mrq, 0, sizeof(struct mmc_request));
355 memset(&cmd, 0, sizeof(struct mmc_command));
356 memset(&data, 0, sizeof(struct mmc_data));
357 memset(&stop, 0, sizeof(struct mmc_command));
358
359 mrq.cmd = &cmd;
360 mrq.data = &data;
361 mrq.stop = &stop;
362
363 sg_init_one(&sg, test->buffer, blocks * blksz);
364
365 mmc_test_prepare_mrq(test, &mrq, &sg, 1, 0, blocks, blksz, write);
366 mmc_test_prepare_broken_mrq(test, &mrq, write);
367
368 mmc_wait_for_req(test->card->host, &mrq);
369
370 mmc_test_wait_busy(test);
371
372 return mmc_test_check_broken_result(test, &mrq);
373}
374
375/*
376 * Does a complete transfer test where data is also validated
377 *
378 * Note: mmc_test_prepare() must have been done before this call
379 */
380static int mmc_test_transfer(struct mmc_test_card *test,
381 struct scatterlist *sg, unsigned sg_len, unsigned dev_addr,
382 unsigned blocks, unsigned blksz, int write)
383{
384 int ret, i;
385 unsigned long flags;
227 386
228 if (write) { 387 if (write) {
229 for (i = 0;i < blocks * blksz;i++) 388 for (i = 0;i < blocks * blksz;i++)
230 buffer[i] = i; 389 test->scratch[i] = i;
390 } else {
391 memset(test->scratch, 0, BUFFER_SIZE);
231 } 392 }
393 local_irq_save(flags);
394 sg_copy_from_buffer(sg, sg_len, test->scratch, BUFFER_SIZE);
395 local_irq_restore(flags);
232 396
233 ret = mmc_test_set_blksize(test, blksz); 397 ret = mmc_test_set_blksize(test, blksz);
234 if (ret) 398 if (ret)
235 return ret; 399 return ret;
236 400
237 ret = mmc_test_transfer(test, write, buffer, addr, blocks, blksz); 401 ret = mmc_test_simple_transfer(test, sg, sg_len, dev_addr,
402 blocks, blksz, write);
238 if (ret) 403 if (ret)
239 return ret; 404 return ret;
240 405
241 if (write) { 406 if (write) {
407 int sectors;
408
242 ret = mmc_test_set_blksize(test, 512); 409 ret = mmc_test_set_blksize(test, 512);
243 if (ret) 410 if (ret)
244 return ret; 411 return ret;
@@ -253,9 +420,9 @@ static int mmc_test_verified_transfer(struct mmc_test_card *test, int write,
253 memset(test->buffer, 0, sectors * 512); 420 memset(test->buffer, 0, sectors * 512);
254 421
255 for (i = 0;i < sectors;i++) { 422 for (i = 0;i < sectors;i++) {
256 ret = mmc_test_transfer(test, 0, 423 ret = mmc_test_buffer_transfer(test,
257 test->buffer + i * 512, 424 test->buffer + i * 512,
258 addr + i * 512, 1, 512); 425 dev_addr + i * 512, 512, 0);
259 if (ret) 426 if (ret)
260 return ret; 427 return ret;
261 } 428 }
@@ -270,8 +437,11 @@ static int mmc_test_verified_transfer(struct mmc_test_card *test, int write,
270 return RESULT_FAIL; 437 return RESULT_FAIL;
271 } 438 }
272 } else { 439 } else {
440 local_irq_save(flags);
441 sg_copy_to_buffer(sg, sg_len, test->scratch, BUFFER_SIZE);
442 local_irq_restore(flags);
273 for (i = 0;i < blocks * blksz;i++) { 443 for (i = 0;i < blocks * blksz;i++) {
274 if (buffer[i] != (u8)i) 444 if (test->scratch[i] != (u8)i)
275 return RESULT_FAIL; 445 return RESULT_FAIL;
276 } 446 }
277 } 447 }
@@ -279,26 +449,6 @@ static int mmc_test_verified_transfer(struct mmc_test_card *test, int write,
279 return 0; 449 return 0;
280} 450}
281 451
282static int mmc_test_cleanup_verify(struct mmc_test_card *test)
283{
284 int ret, i;
285
286 ret = mmc_test_set_blksize(test, 512);
287 if (ret)
288 return ret;
289
290 memset(test->buffer, 0, BUFFER_SIZE);
291
292 for (i = 0;i < BUFFER_SIZE / 512;i++) {
293 ret = mmc_test_transfer(test, 1, test->buffer + i * 512,
294 i * 512, 1, 512);
295 if (ret)
296 return ret;
297 }
298
299 return 0;
300}
301
302/*******************************************************************/ 452/*******************************************************************/
303/* Tests */ 453/* Tests */
304/*******************************************************************/ 454/*******************************************************************/
@@ -314,12 +464,15 @@ struct mmc_test_case {
314static int mmc_test_basic_write(struct mmc_test_card *test) 464static int mmc_test_basic_write(struct mmc_test_card *test)
315{ 465{
316 int ret; 466 int ret;
467 struct scatterlist sg;
317 468
318 ret = mmc_test_set_blksize(test, 512); 469 ret = mmc_test_set_blksize(test, 512);
319 if (ret) 470 if (ret)
320 return ret; 471 return ret;
321 472
322 ret = mmc_test_transfer(test, 1, test->buffer, 0, 1, 512); 473 sg_init_one(&sg, test->buffer, 512);
474
475 ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 1);
323 if (ret) 476 if (ret)
324 return ret; 477 return ret;
325 478
@@ -329,12 +482,15 @@ static int mmc_test_basic_write(struct mmc_test_card *test)
329static int mmc_test_basic_read(struct mmc_test_card *test) 482static int mmc_test_basic_read(struct mmc_test_card *test)
330{ 483{
331 int ret; 484 int ret;
485 struct scatterlist sg;
332 486
333 ret = mmc_test_set_blksize(test, 512); 487 ret = mmc_test_set_blksize(test, 512);
334 if (ret) 488 if (ret)
335 return ret; 489 return ret;
336 490
337 ret = mmc_test_transfer(test, 0, test->buffer, 0, 1, 512); 491 sg_init_one(&sg, test->buffer, 512);
492
493 ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 1);
338 if (ret) 494 if (ret)
339 return ret; 495 return ret;
340 496
@@ -344,8 +500,11 @@ static int mmc_test_basic_read(struct mmc_test_card *test)
344static int mmc_test_verify_write(struct mmc_test_card *test) 500static int mmc_test_verify_write(struct mmc_test_card *test)
345{ 501{
346 int ret; 502 int ret;
503 struct scatterlist sg;
504
505 sg_init_one(&sg, test->buffer, 512);
347 506
348 ret = mmc_test_verified_transfer(test, 1, test->buffer, 0, 1, 512); 507 ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1);
349 if (ret) 508 if (ret)
350 return ret; 509 return ret;
351 510
@@ -355,8 +514,11 @@ static int mmc_test_verify_write(struct mmc_test_card *test)
355static int mmc_test_verify_read(struct mmc_test_card *test) 514static int mmc_test_verify_read(struct mmc_test_card *test)
356{ 515{
357 int ret; 516 int ret;
517 struct scatterlist sg;
518
519 sg_init_one(&sg, test->buffer, 512);
358 520
359 ret = mmc_test_verified_transfer(test, 0, test->buffer, 0, 1, 512); 521 ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0);
360 if (ret) 522 if (ret)
361 return ret; 523 return ret;
362 524
@@ -367,6 +529,7 @@ static int mmc_test_multi_write(struct mmc_test_card *test)
367{ 529{
368 int ret; 530 int ret;
369 unsigned int size; 531 unsigned int size;
532 struct scatterlist sg;
370 533
371 if (test->card->host->max_blk_count == 1) 534 if (test->card->host->max_blk_count == 1)
372 return RESULT_UNSUP_HOST; 535 return RESULT_UNSUP_HOST;
@@ -379,8 +542,9 @@ static int mmc_test_multi_write(struct mmc_test_card *test)
379 if (size < 1024) 542 if (size < 1024)
380 return RESULT_UNSUP_HOST; 543 return RESULT_UNSUP_HOST;
381 544
382 ret = mmc_test_verified_transfer(test, 1, test->buffer, 0, 545 sg_init_one(&sg, test->buffer, size);
383 size / 512, 512); 546
547 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1);
384 if (ret) 548 if (ret)
385 return ret; 549 return ret;
386 550
@@ -391,6 +555,7 @@ static int mmc_test_multi_read(struct mmc_test_card *test)
391{ 555{
392 int ret; 556 int ret;
393 unsigned int size; 557 unsigned int size;
558 struct scatterlist sg;
394 559
395 if (test->card->host->max_blk_count == 1) 560 if (test->card->host->max_blk_count == 1)
396 return RESULT_UNSUP_HOST; 561 return RESULT_UNSUP_HOST;
@@ -403,8 +568,9 @@ static int mmc_test_multi_read(struct mmc_test_card *test)
403 if (size < 1024) 568 if (size < 1024)
404 return RESULT_UNSUP_HOST; 569 return RESULT_UNSUP_HOST;
405 570
406 ret = mmc_test_verified_transfer(test, 0, test->buffer, 0, 571 sg_init_one(&sg, test->buffer, size);
407 size / 512, 512); 572
573 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0);
408 if (ret) 574 if (ret)
409 return ret; 575 return ret;
410 576
@@ -414,13 +580,14 @@ static int mmc_test_multi_read(struct mmc_test_card *test)
414static int mmc_test_pow2_write(struct mmc_test_card *test) 580static int mmc_test_pow2_write(struct mmc_test_card *test)
415{ 581{
416 int ret, i; 582 int ret, i;
583 struct scatterlist sg;
417 584
418 if (!test->card->csd.write_partial) 585 if (!test->card->csd.write_partial)
419 return RESULT_UNSUP_CARD; 586 return RESULT_UNSUP_CARD;
420 587
421 for (i = 1; i < 512;i <<= 1) { 588 for (i = 1; i < 512;i <<= 1) {
422 ret = mmc_test_verified_transfer(test, 1, 589 sg_init_one(&sg, test->buffer, i);
423 test->buffer, 0, 1, i); 590 ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 1);
424 if (ret) 591 if (ret)
425 return ret; 592 return ret;
426 } 593 }
@@ -431,13 +598,14 @@ static int mmc_test_pow2_write(struct mmc_test_card *test)
431static int mmc_test_pow2_read(struct mmc_test_card *test) 598static int mmc_test_pow2_read(struct mmc_test_card *test)
432{ 599{
433 int ret, i; 600 int ret, i;
601 struct scatterlist sg;
434 602
435 if (!test->card->csd.read_partial) 603 if (!test->card->csd.read_partial)
436 return RESULT_UNSUP_CARD; 604 return RESULT_UNSUP_CARD;
437 605
438 for (i = 1; i < 512;i <<= 1) { 606 for (i = 1; i < 512;i <<= 1) {
439 ret = mmc_test_verified_transfer(test, 0, 607 sg_init_one(&sg, test->buffer, i);
440 test->buffer, 0, 1, i); 608 ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 0);
441 if (ret) 609 if (ret)
442 return ret; 610 return ret;
443 } 611 }
@@ -448,13 +616,14 @@ static int mmc_test_pow2_read(struct mmc_test_card *test)
448static int mmc_test_weird_write(struct mmc_test_card *test) 616static int mmc_test_weird_write(struct mmc_test_card *test)
449{ 617{
450 int ret, i; 618 int ret, i;
619 struct scatterlist sg;
451 620
452 if (!test->card->csd.write_partial) 621 if (!test->card->csd.write_partial)
453 return RESULT_UNSUP_CARD; 622 return RESULT_UNSUP_CARD;
454 623
455 for (i = 3; i < 512;i += 7) { 624 for (i = 3; i < 512;i += 7) {
456 ret = mmc_test_verified_transfer(test, 1, 625 sg_init_one(&sg, test->buffer, i);
457 test->buffer, 0, 1, i); 626 ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 1);
458 if (ret) 627 if (ret)
459 return ret; 628 return ret;
460 } 629 }
@@ -465,13 +634,14 @@ static int mmc_test_weird_write(struct mmc_test_card *test)
465static int mmc_test_weird_read(struct mmc_test_card *test) 634static int mmc_test_weird_read(struct mmc_test_card *test)
466{ 635{
467 int ret, i; 636 int ret, i;
637 struct scatterlist sg;
468 638
469 if (!test->card->csd.read_partial) 639 if (!test->card->csd.read_partial)
470 return RESULT_UNSUP_CARD; 640 return RESULT_UNSUP_CARD;
471 641
472 for (i = 3; i < 512;i += 7) { 642 for (i = 3; i < 512;i += 7) {
473 ret = mmc_test_verified_transfer(test, 0, 643 sg_init_one(&sg, test->buffer, i);
474 test->buffer, 0, 1, i); 644 ret = mmc_test_transfer(test, &sg, 1, 0, 1, i, 0);
475 if (ret) 645 if (ret)
476 return ret; 646 return ret;
477 } 647 }
@@ -482,10 +652,11 @@ static int mmc_test_weird_read(struct mmc_test_card *test)
482static int mmc_test_align_write(struct mmc_test_card *test) 652static int mmc_test_align_write(struct mmc_test_card *test)
483{ 653{
484 int ret, i; 654 int ret, i;
655 struct scatterlist sg;
485 656
486 for (i = 1;i < 4;i++) { 657 for (i = 1;i < 4;i++) {
487 ret = mmc_test_verified_transfer(test, 1, test->buffer + i, 658 sg_init_one(&sg, test->buffer + i, 512);
488 0, 1, 512); 659 ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 1);
489 if (ret) 660 if (ret)
490 return ret; 661 return ret;
491 } 662 }
@@ -496,10 +667,11 @@ static int mmc_test_align_write(struct mmc_test_card *test)
496static int mmc_test_align_read(struct mmc_test_card *test) 667static int mmc_test_align_read(struct mmc_test_card *test)
497{ 668{
498 int ret, i; 669 int ret, i;
670 struct scatterlist sg;
499 671
500 for (i = 1;i < 4;i++) { 672 for (i = 1;i < 4;i++) {
501 ret = mmc_test_verified_transfer(test, 0, test->buffer + i, 673 sg_init_one(&sg, test->buffer + i, 512);
502 0, 1, 512); 674 ret = mmc_test_transfer(test, &sg, 1, 0, 1, 512, 0);
503 if (ret) 675 if (ret)
504 return ret; 676 return ret;
505 } 677 }
@@ -511,6 +683,7 @@ static int mmc_test_align_multi_write(struct mmc_test_card *test)
511{ 683{
512 int ret, i; 684 int ret, i;
513 unsigned int size; 685 unsigned int size;
686 struct scatterlist sg;
514 687
515 if (test->card->host->max_blk_count == 1) 688 if (test->card->host->max_blk_count == 1)
516 return RESULT_UNSUP_HOST; 689 return RESULT_UNSUP_HOST;
@@ -524,8 +697,8 @@ static int mmc_test_align_multi_write(struct mmc_test_card *test)
524 return RESULT_UNSUP_HOST; 697 return RESULT_UNSUP_HOST;
525 698
526 for (i = 1;i < 4;i++) { 699 for (i = 1;i < 4;i++) {
527 ret = mmc_test_verified_transfer(test, 1, test->buffer + i, 700 sg_init_one(&sg, test->buffer + i, size);
528 0, size / 512, 512); 701 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 1);
529 if (ret) 702 if (ret)
530 return ret; 703 return ret;
531 } 704 }
@@ -537,6 +710,7 @@ static int mmc_test_align_multi_read(struct mmc_test_card *test)
537{ 710{
538 int ret, i; 711 int ret, i;
539 unsigned int size; 712 unsigned int size;
713 struct scatterlist sg;
540 714
541 if (test->card->host->max_blk_count == 1) 715 if (test->card->host->max_blk_count == 1)
542 return RESULT_UNSUP_HOST; 716 return RESULT_UNSUP_HOST;
@@ -550,8 +724,8 @@ static int mmc_test_align_multi_read(struct mmc_test_card *test)
550 return RESULT_UNSUP_HOST; 724 return RESULT_UNSUP_HOST;
551 725
552 for (i = 1;i < 4;i++) { 726 for (i = 1;i < 4;i++) {
553 ret = mmc_test_verified_transfer(test, 0, test->buffer + i, 727 sg_init_one(&sg, test->buffer + i, size);
554 0, size / 512, 512); 728 ret = mmc_test_transfer(test, &sg, 1, 0, size/512, 512, 0);
555 if (ret) 729 if (ret)
556 return ret; 730 return ret;
557 } 731 }
@@ -567,7 +741,7 @@ static int mmc_test_xfersize_write(struct mmc_test_card *test)
567 if (ret) 741 if (ret)
568 return ret; 742 return ret;
569 743
570 ret = __mmc_test_transfer(test, 1, 1, test->buffer, 0, 1, 512); 744 ret = mmc_test_broken_transfer(test, 1, 512, 1);
571 if (ret) 745 if (ret)
572 return ret; 746 return ret;
573 747
@@ -582,7 +756,7 @@ static int mmc_test_xfersize_read(struct mmc_test_card *test)
582 if (ret) 756 if (ret)
583 return ret; 757 return ret;
584 758
585 ret = __mmc_test_transfer(test, 0, 1, test->buffer, 0, 1, 512); 759 ret = mmc_test_broken_transfer(test, 1, 512, 0);
586 if (ret) 760 if (ret)
587 return ret; 761 return ret;
588 762
@@ -600,7 +774,7 @@ static int mmc_test_multi_xfersize_write(struct mmc_test_card *test)
600 if (ret) 774 if (ret)
601 return ret; 775 return ret;
602 776
603 ret = __mmc_test_transfer(test, 1, 1, test->buffer, 0, 2, 512); 777 ret = mmc_test_broken_transfer(test, 2, 512, 1);
604 if (ret) 778 if (ret)
605 return ret; 779 return ret;
606 780
@@ -618,7 +792,7 @@ static int mmc_test_multi_xfersize_read(struct mmc_test_card *test)
618 if (ret) 792 if (ret)
619 return ret; 793 return ret;
620 794
621 ret = __mmc_test_transfer(test, 0, 1, test->buffer, 0, 2, 512); 795 ret = mmc_test_broken_transfer(test, 2, 512, 0);
622 if (ret) 796 if (ret)
623 return ret; 797 return ret;
624 798
@@ -638,86 +812,86 @@ static const struct mmc_test_case mmc_test_cases[] = {
638 812
639 { 813 {
640 .name = "Basic write (with data verification)", 814 .name = "Basic write (with data verification)",
641 .prepare = mmc_test_prepare_verify_write, 815 .prepare = mmc_test_prepare_write,
642 .run = mmc_test_verify_write, 816 .run = mmc_test_verify_write,
643 .cleanup = mmc_test_cleanup_verify, 817 .cleanup = mmc_test_cleanup,
644 }, 818 },
645 819
646 { 820 {
647 .name = "Basic read (with data verification)", 821 .name = "Basic read (with data verification)",
648 .prepare = mmc_test_prepare_verify_read, 822 .prepare = mmc_test_prepare_read,
649 .run = mmc_test_verify_read, 823 .run = mmc_test_verify_read,
650 .cleanup = mmc_test_cleanup_verify, 824 .cleanup = mmc_test_cleanup,
651 }, 825 },
652 826
653 { 827 {
654 .name = "Multi-block write", 828 .name = "Multi-block write",
655 .prepare = mmc_test_prepare_verify_write, 829 .prepare = mmc_test_prepare_write,
656 .run = mmc_test_multi_write, 830 .run = mmc_test_multi_write,
657 .cleanup = mmc_test_cleanup_verify, 831 .cleanup = mmc_test_cleanup,
658 }, 832 },
659 833
660 { 834 {
661 .name = "Multi-block read", 835 .name = "Multi-block read",
662 .prepare = mmc_test_prepare_verify_read, 836 .prepare = mmc_test_prepare_read,
663 .run = mmc_test_multi_read, 837 .run = mmc_test_multi_read,
664 .cleanup = mmc_test_cleanup_verify, 838 .cleanup = mmc_test_cleanup,
665 }, 839 },
666 840
667 { 841 {
668 .name = "Power of two block writes", 842 .name = "Power of two block writes",
669 .prepare = mmc_test_prepare_verify_write, 843 .prepare = mmc_test_prepare_write,
670 .run = mmc_test_pow2_write, 844 .run = mmc_test_pow2_write,
671 .cleanup = mmc_test_cleanup_verify, 845 .cleanup = mmc_test_cleanup,
672 }, 846 },
673 847
674 { 848 {
675 .name = "Power of two block reads", 849 .name = "Power of two block reads",
676 .prepare = mmc_test_prepare_verify_read, 850 .prepare = mmc_test_prepare_read,
677 .run = mmc_test_pow2_read, 851 .run = mmc_test_pow2_read,
678 .cleanup = mmc_test_cleanup_verify, 852 .cleanup = mmc_test_cleanup,
679 }, 853 },
680 854
681 { 855 {
682 .name = "Weird sized block writes", 856 .name = "Weird sized block writes",
683 .prepare = mmc_test_prepare_verify_write, 857 .prepare = mmc_test_prepare_write,
684 .run = mmc_test_weird_write, 858 .run = mmc_test_weird_write,
685 .cleanup = mmc_test_cleanup_verify, 859 .cleanup = mmc_test_cleanup,
686 }, 860 },
687 861
688 { 862 {
689 .name = "Weird sized block reads", 863 .name = "Weird sized block reads",
690 .prepare = mmc_test_prepare_verify_read, 864 .prepare = mmc_test_prepare_read,
691 .run = mmc_test_weird_read, 865 .run = mmc_test_weird_read,
692 .cleanup = mmc_test_cleanup_verify, 866 .cleanup = mmc_test_cleanup,
693 }, 867 },
694 868
695 { 869 {
696 .name = "Badly aligned write", 870 .name = "Badly aligned write",
697 .prepare = mmc_test_prepare_verify_write, 871 .prepare = mmc_test_prepare_write,
698 .run = mmc_test_align_write, 872 .run = mmc_test_align_write,
699 .cleanup = mmc_test_cleanup_verify, 873 .cleanup = mmc_test_cleanup,
700 }, 874 },
701 875
702 { 876 {
703 .name = "Badly aligned read", 877 .name = "Badly aligned read",
704 .prepare = mmc_test_prepare_verify_read, 878 .prepare = mmc_test_prepare_read,
705 .run = mmc_test_align_read, 879 .run = mmc_test_align_read,
706 .cleanup = mmc_test_cleanup_verify, 880 .cleanup = mmc_test_cleanup,
707 }, 881 },
708 882
709 { 883 {
710 .name = "Badly aligned multi-block write", 884 .name = "Badly aligned multi-block write",
711 .prepare = mmc_test_prepare_verify_write, 885 .prepare = mmc_test_prepare_write,
712 .run = mmc_test_align_multi_write, 886 .run = mmc_test_align_multi_write,
713 .cleanup = mmc_test_cleanup_verify, 887 .cleanup = mmc_test_cleanup,
714 }, 888 },
715 889
716 { 890 {
717 .name = "Badly aligned multi-block read", 891 .name = "Badly aligned multi-block read",
718 .prepare = mmc_test_prepare_verify_read, 892 .prepare = mmc_test_prepare_read,
719 .run = mmc_test_align_multi_read, 893 .run = mmc_test_align_multi_read,
720 .cleanup = mmc_test_cleanup_verify, 894 .cleanup = mmc_test_cleanup,
721 }, 895 },
722 896
723 { 897 {
@@ -743,7 +917,7 @@ static const struct mmc_test_case mmc_test_cases[] = {
743 917
744static struct mutex mmc_test_lock; 918static struct mutex mmc_test_lock;
745 919
746static void mmc_test_run(struct mmc_test_card *test) 920static void mmc_test_run(struct mmc_test_card *test, int testcase)
747{ 921{
748 int i, ret; 922 int i, ret;
749 923
@@ -753,6 +927,9 @@ static void mmc_test_run(struct mmc_test_card *test)
753 mmc_claim_host(test->card->host); 927 mmc_claim_host(test->card->host);
754 928
755 for (i = 0;i < ARRAY_SIZE(mmc_test_cases);i++) { 929 for (i = 0;i < ARRAY_SIZE(mmc_test_cases);i++) {
930 if (testcase && ((i + 1) != testcase))
931 continue;
932
756 printk(KERN_INFO "%s: Test case %d. %s...\n", 933 printk(KERN_INFO "%s: Test case %d. %s...\n",
757 mmc_hostname(test->card->host), i + 1, 934 mmc_hostname(test->card->host), i + 1,
758 mmc_test_cases[i].name); 935 mmc_test_cases[i].name);
@@ -824,9 +1001,12 @@ static ssize_t mmc_test_store(struct device *dev,
824{ 1001{
825 struct mmc_card *card; 1002 struct mmc_card *card;
826 struct mmc_test_card *test; 1003 struct mmc_test_card *test;
1004 int testcase;
827 1005
828 card = container_of(dev, struct mmc_card, dev); 1006 card = container_of(dev, struct mmc_card, dev);
829 1007
1008 testcase = simple_strtol(buf, NULL, 10);
1009
830 test = kzalloc(sizeof(struct mmc_test_card), GFP_KERNEL); 1010 test = kzalloc(sizeof(struct mmc_test_card), GFP_KERNEL);
831 if (!test) 1011 if (!test)
832 return -ENOMEM; 1012 return -ENOMEM;
@@ -836,7 +1016,7 @@ static ssize_t mmc_test_store(struct device *dev,
836 test->buffer = kzalloc(BUFFER_SIZE, GFP_KERNEL); 1016 test->buffer = kzalloc(BUFFER_SIZE, GFP_KERNEL);
837 if (test->buffer) { 1017 if (test->buffer) {
838 mutex_lock(&mmc_test_lock); 1018 mutex_lock(&mmc_test_lock);
839 mmc_test_run(test); 1019 mmc_test_run(test, testcase);
840 mutex_unlock(&mmc_test_lock); 1020 mutex_unlock(&mmc_test_lock);
841 } 1021 }
842 1022
@@ -852,6 +1032,9 @@ static int mmc_test_probe(struct mmc_card *card)
852{ 1032{
853 int ret; 1033 int ret;
854 1034
1035 if ((card->type != MMC_TYPE_MMC) && (card->type != MMC_TYPE_SD))
1036 return -ENODEV;
1037
855 mutex_init(&mmc_test_lock); 1038 mutex_init(&mmc_test_lock);
856 1039
857 ret = device_create_file(&card->dev, &dev_attr_test); 1040 ret = device_create_file(&card->dev, &dev_attr_test);