diff options
-rw-r--r-- | drivers/mmc/card/block.c | 30 | ||||
-rw-r--r-- | drivers/mmc/card/queue.c | 22 | ||||
-rw-r--r-- | drivers/mmc/card/queue.h | 3 | ||||
-rw-r--r-- | drivers/mmc/core/bus.c | 1 | ||||
-rw-r--r-- | drivers/mmc/core/core.c | 121 | ||||
-rw-r--r-- | drivers/mmc/core/core.h | 1 | ||||
-rw-r--r-- | include/linux/mmc/card.h | 12 | ||||
-rw-r--r-- | include/linux/mmc/core.h | 3 | ||||
-rw-r--r-- | include/linux/mmc/host.h | 17 |
9 files changed, 191 insertions, 19 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 21056b9ef0a0..f79b4688e471 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -113,17 +113,6 @@ struct mmc_blk_data { | |||
113 | 113 | ||
114 | static DEFINE_MUTEX(open_lock); | 114 | static DEFINE_MUTEX(open_lock); |
115 | 115 | ||
116 | enum mmc_blk_status { | ||
117 | MMC_BLK_SUCCESS = 0, | ||
118 | MMC_BLK_PARTIAL, | ||
119 | MMC_BLK_CMD_ERR, | ||
120 | MMC_BLK_RETRY, | ||
121 | MMC_BLK_ABORT, | ||
122 | MMC_BLK_DATA_ERR, | ||
123 | MMC_BLK_ECC_ERR, | ||
124 | MMC_BLK_NOMEDIUM, | ||
125 | }; | ||
126 | |||
127 | module_param(perdev_minors, int, 0444); | 116 | module_param(perdev_minors, int, 0444); |
128 | MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device"); | 117 | MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device"); |
129 | 118 | ||
@@ -1364,8 +1353,11 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) | |||
1364 | } else | 1353 | } else |
1365 | areq = NULL; | 1354 | areq = NULL; |
1366 | areq = mmc_start_req(card->host, areq, (int *) &status); | 1355 | areq = mmc_start_req(card->host, areq, (int *) &status); |
1367 | if (!areq) | 1356 | if (!areq) { |
1357 | if (status == MMC_BLK_NEW_REQUEST) | ||
1358 | mq->flags |= MMC_QUEUE_NEW_REQUEST; | ||
1368 | return 0; | 1359 | return 0; |
1360 | } | ||
1369 | 1361 | ||
1370 | mq_rq = container_of(areq, struct mmc_queue_req, mmc_active); | 1362 | mq_rq = container_of(areq, struct mmc_queue_req, mmc_active); |
1371 | brq = &mq_rq->brq; | 1363 | brq = &mq_rq->brq; |
@@ -1438,6 +1430,10 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) | |||
1438 | break; | 1430 | break; |
1439 | case MMC_BLK_NOMEDIUM: | 1431 | case MMC_BLK_NOMEDIUM: |
1440 | goto cmd_abort; | 1432 | goto cmd_abort; |
1433 | default: | ||
1434 | pr_err("%s: Unhandled return value (%d)", | ||
1435 | req->rq_disk->disk_name, status); | ||
1436 | goto cmd_abort; | ||
1441 | } | 1437 | } |
1442 | 1438 | ||
1443 | if (ret) { | 1439 | if (ret) { |
@@ -1472,6 +1468,8 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
1472 | int ret; | 1468 | int ret; |
1473 | struct mmc_blk_data *md = mq->data; | 1469 | struct mmc_blk_data *md = mq->data; |
1474 | struct mmc_card *card = md->queue.card; | 1470 | struct mmc_card *card = md->queue.card; |
1471 | struct mmc_host *host = card->host; | ||
1472 | unsigned long flags; | ||
1475 | 1473 | ||
1476 | if (req && !mq->mqrq_prev->req) | 1474 | if (req && !mq->mqrq_prev->req) |
1477 | /* claim host only for the first request */ | 1475 | /* claim host only for the first request */ |
@@ -1486,6 +1484,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
1486 | goto out; | 1484 | goto out; |
1487 | } | 1485 | } |
1488 | 1486 | ||
1487 | mq->flags &= ~MMC_QUEUE_NEW_REQUEST; | ||
1489 | if (req && req->cmd_flags & REQ_DISCARD) { | 1488 | if (req && req->cmd_flags & REQ_DISCARD) { |
1490 | /* complete ongoing async transfer before issuing discard */ | 1489 | /* complete ongoing async transfer before issuing discard */ |
1491 | if (card->host->areq) | 1490 | if (card->host->areq) |
@@ -1501,11 +1500,16 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
1501 | mmc_blk_issue_rw_rq(mq, NULL); | 1500 | mmc_blk_issue_rw_rq(mq, NULL); |
1502 | ret = mmc_blk_issue_flush(mq, req); | 1501 | ret = mmc_blk_issue_flush(mq, req); |
1503 | } else { | 1502 | } else { |
1503 | if (!req && host->areq) { | ||
1504 | spin_lock_irqsave(&host->context_info.lock, flags); | ||
1505 | host->context_info.is_waiting_last_req = true; | ||
1506 | spin_unlock_irqrestore(&host->context_info.lock, flags); | ||
1507 | } | ||
1504 | ret = mmc_blk_issue_rw_rq(mq, req); | 1508 | ret = mmc_blk_issue_rw_rq(mq, req); |
1505 | } | 1509 | } |
1506 | 1510 | ||
1507 | out: | 1511 | out: |
1508 | if (!req) | 1512 | if (!req && !(mq->flags & MMC_QUEUE_NEW_REQUEST)) |
1509 | /* release host only when there are no more requests */ | 1513 | /* release host only when there are no more requests */ |
1510 | mmc_release_host(card->host); | 1514 | mmc_release_host(card->host); |
1511 | return ret; | 1515 | return ret; |
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index d630d9861e7b..5e0971016ac5 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c | |||
@@ -22,7 +22,6 @@ | |||
22 | 22 | ||
23 | #define MMC_QUEUE_BOUNCESZ 65536 | 23 | #define MMC_QUEUE_BOUNCESZ 65536 |
24 | 24 | ||
25 | #define MMC_QUEUE_SUSPENDED (1 << 0) | ||
26 | 25 | ||
27 | #define MMC_REQ_SPECIAL_MASK (REQ_DISCARD | REQ_FLUSH) | 26 | #define MMC_REQ_SPECIAL_MASK (REQ_DISCARD | REQ_FLUSH) |
28 | 27 | ||
@@ -72,6 +71,10 @@ static int mmc_queue_thread(void *d) | |||
72 | set_current_state(TASK_RUNNING); | 71 | set_current_state(TASK_RUNNING); |
73 | cmd_flags = req ? req->cmd_flags : 0; | 72 | cmd_flags = req ? req->cmd_flags : 0; |
74 | mq->issue_fn(mq, req); | 73 | mq->issue_fn(mq, req); |
74 | if (mq->flags & MMC_QUEUE_NEW_REQUEST) { | ||
75 | mq->flags &= ~MMC_QUEUE_NEW_REQUEST; | ||
76 | continue; /* fetch again */ | ||
77 | } | ||
75 | 78 | ||
76 | /* | 79 | /* |
77 | * Current request becomes previous request | 80 | * Current request becomes previous request |
@@ -113,6 +116,8 @@ static void mmc_request_fn(struct request_queue *q) | |||
113 | { | 116 | { |
114 | struct mmc_queue *mq = q->queuedata; | 117 | struct mmc_queue *mq = q->queuedata; |
115 | struct request *req; | 118 | struct request *req; |
119 | unsigned long flags; | ||
120 | struct mmc_context_info *cntx; | ||
116 | 121 | ||
117 | if (!mq) { | 122 | if (!mq) { |
118 | while ((req = blk_fetch_request(q)) != NULL) { | 123 | while ((req = blk_fetch_request(q)) != NULL) { |
@@ -122,7 +127,20 @@ static void mmc_request_fn(struct request_queue *q) | |||
122 | return; | 127 | return; |
123 | } | 128 | } |
124 | 129 | ||
125 | if (!mq->mqrq_cur->req && !mq->mqrq_prev->req) | 130 | cntx = &mq->card->host->context_info; |
131 | if (!mq->mqrq_cur->req && mq->mqrq_prev->req) { | ||
132 | /* | ||
133 | * New MMC request arrived when MMC thread may be | ||
134 | * blocked on the previous request to be complete | ||
135 | * with no current request fetched | ||
136 | */ | ||
137 | spin_lock_irqsave(&cntx->lock, flags); | ||
138 | if (cntx->is_waiting_last_req) { | ||
139 | cntx->is_new_req = true; | ||
140 | wake_up_interruptible(&cntx->wait); | ||
141 | } | ||
142 | spin_unlock_irqrestore(&cntx->lock, flags); | ||
143 | } else if (!mq->mqrq_cur->req && !mq->mqrq_prev->req) | ||
126 | wake_up_process(mq->thread); | 144 | wake_up_process(mq->thread); |
127 | } | 145 | } |
128 | 146 | ||
diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h index d2a1eb4b9f9f..e20c27b2b8b4 100644 --- a/drivers/mmc/card/queue.h +++ b/drivers/mmc/card/queue.h | |||
@@ -27,6 +27,9 @@ struct mmc_queue { | |||
27 | struct task_struct *thread; | 27 | struct task_struct *thread; |
28 | struct semaphore thread_sem; | 28 | struct semaphore thread_sem; |
29 | unsigned int flags; | 29 | unsigned int flags; |
30 | #define MMC_QUEUE_SUSPENDED (1 << 0) | ||
31 | #define MMC_QUEUE_NEW_REQUEST (1 << 1) | ||
32 | |||
30 | int (*issue_fn)(struct mmc_queue *, struct request *); | 33 | int (*issue_fn)(struct mmc_queue *, struct request *); |
31 | void *data; | 34 | void *data; |
32 | struct request_queue *queue; | 35 | struct request_queue *queue; |
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 420cb6753c1e..e219c97a02a4 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c | |||
@@ -321,6 +321,7 @@ int mmc_add_card(struct mmc_card *card) | |||
321 | #ifdef CONFIG_DEBUG_FS | 321 | #ifdef CONFIG_DEBUG_FS |
322 | mmc_add_card_debugfs(card); | 322 | mmc_add_card_debugfs(card); |
323 | #endif | 323 | #endif |
324 | mmc_init_context_info(card->host); | ||
324 | 325 | ||
325 | ret = device_add(&card->dev); | 326 | ret = device_add(&card->dev); |
326 | if (ret) | 327 | if (ret) |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index aaed7687cf09..8b3a1222e665 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -319,11 +319,44 @@ out: | |||
319 | } | 319 | } |
320 | EXPORT_SYMBOL(mmc_start_bkops); | 320 | EXPORT_SYMBOL(mmc_start_bkops); |
321 | 321 | ||
322 | /* | ||
323 | * mmc_wait_data_done() - done callback for data request | ||
324 | * @mrq: done data request | ||
325 | * | ||
326 | * Wakes up mmc context, passed as a callback to host controller driver | ||
327 | */ | ||
328 | static void mmc_wait_data_done(struct mmc_request *mrq) | ||
329 | { | ||
330 | mrq->host->context_info.is_done_rcv = true; | ||
331 | wake_up_interruptible(&mrq->host->context_info.wait); | ||
332 | } | ||
333 | |||
322 | static void mmc_wait_done(struct mmc_request *mrq) | 334 | static void mmc_wait_done(struct mmc_request *mrq) |
323 | { | 335 | { |
324 | complete(&mrq->completion); | 336 | complete(&mrq->completion); |
325 | } | 337 | } |
326 | 338 | ||
339 | /* | ||
340 | *__mmc_start_data_req() - starts data request | ||
341 | * @host: MMC host to start the request | ||
342 | * @mrq: data request to start | ||
343 | * | ||
344 | * Sets the done callback to be called when request is completed by the card. | ||
345 | * Starts data mmc request execution | ||
346 | */ | ||
347 | static int __mmc_start_data_req(struct mmc_host *host, struct mmc_request *mrq) | ||
348 | { | ||
349 | mrq->done = mmc_wait_data_done; | ||
350 | mrq->host = host; | ||
351 | if (mmc_card_removed(host->card)) { | ||
352 | mrq->cmd->error = -ENOMEDIUM; | ||
353 | return -ENOMEDIUM; | ||
354 | } | ||
355 | mmc_start_request(host, mrq); | ||
356 | |||
357 | return 0; | ||
358 | } | ||
359 | |||
327 | static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq) | 360 | static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq) |
328 | { | 361 | { |
329 | init_completion(&mrq->completion); | 362 | init_completion(&mrq->completion); |
@@ -337,6 +370,62 @@ static int __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq) | |||
337 | return 0; | 370 | return 0; |
338 | } | 371 | } |
339 | 372 | ||
373 | /* | ||
374 | * mmc_wait_for_data_req_done() - wait for request completed | ||
375 | * @host: MMC host to prepare the command. | ||
376 | * @mrq: MMC request to wait for | ||
377 | * | ||
378 | * Blocks MMC context till host controller will ack end of data request | ||
379 | * execution or new request notification arrives from the block layer. | ||
380 | * Handles command retries. | ||
381 | * | ||
382 | * Returns enum mmc_blk_status after checking errors. | ||
383 | */ | ||
384 | static int mmc_wait_for_data_req_done(struct mmc_host *host, | ||
385 | struct mmc_request *mrq, | ||
386 | struct mmc_async_req *next_req) | ||
387 | { | ||
388 | struct mmc_command *cmd; | ||
389 | struct mmc_context_info *context_info = &host->context_info; | ||
390 | int err; | ||
391 | unsigned long flags; | ||
392 | |||
393 | while (1) { | ||
394 | wait_event_interruptible(context_info->wait, | ||
395 | (context_info->is_done_rcv || | ||
396 | context_info->is_new_req)); | ||
397 | spin_lock_irqsave(&context_info->lock, flags); | ||
398 | context_info->is_waiting_last_req = false; | ||
399 | spin_unlock_irqrestore(&context_info->lock, flags); | ||
400 | if (context_info->is_done_rcv) { | ||
401 | context_info->is_done_rcv = false; | ||
402 | context_info->is_new_req = false; | ||
403 | cmd = mrq->cmd; | ||
404 | if (!cmd->error || !cmd->retries || | ||
405 | mmc_card_removed(host->card)) { | ||
406 | err = host->areq->err_check(host->card, | ||
407 | host->areq); | ||
408 | break; /* return err */ | ||
409 | } else { | ||
410 | pr_info("%s: req failed (CMD%u): %d, retrying...\n", | ||
411 | mmc_hostname(host), | ||
412 | cmd->opcode, cmd->error); | ||
413 | cmd->retries--; | ||
414 | cmd->error = 0; | ||
415 | host->ops->request(host, mrq); | ||
416 | continue; /* wait for done/new event again */ | ||
417 | } | ||
418 | } else if (context_info->is_new_req) { | ||
419 | context_info->is_new_req = false; | ||
420 | if (!next_req) { | ||
421 | err = MMC_BLK_NEW_REQUEST; | ||
422 | break; /* return err */ | ||
423 | } | ||
424 | } | ||
425 | } | ||
426 | return err; | ||
427 | } | ||
428 | |||
340 | static void mmc_wait_for_req_done(struct mmc_host *host, | 429 | static void mmc_wait_for_req_done(struct mmc_host *host, |
341 | struct mmc_request *mrq) | 430 | struct mmc_request *mrq) |
342 | { | 431 | { |
@@ -426,8 +515,17 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host, | |||
426 | mmc_pre_req(host, areq->mrq, !host->areq); | 515 | mmc_pre_req(host, areq->mrq, !host->areq); |
427 | 516 | ||
428 | if (host->areq) { | 517 | if (host->areq) { |
429 | mmc_wait_for_req_done(host, host->areq->mrq); | 518 | err = mmc_wait_for_data_req_done(host, host->areq->mrq, |
430 | err = host->areq->err_check(host->card, host->areq); | 519 | areq); |
520 | if (err == MMC_BLK_NEW_REQUEST) { | ||
521 | if (error) | ||
522 | *error = err; | ||
523 | /* | ||
524 | * The previous request was not completed, | ||
525 | * nothing to return | ||
526 | */ | ||
527 | return NULL; | ||
528 | } | ||
431 | /* | 529 | /* |
432 | * Check BKOPS urgency for each R1 response | 530 | * Check BKOPS urgency for each R1 response |
433 | */ | 531 | */ |
@@ -439,7 +537,7 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host, | |||
439 | } | 537 | } |
440 | 538 | ||
441 | if (!err && areq) | 539 | if (!err && areq) |
442 | start_err = __mmc_start_req(host, areq->mrq); | 540 | start_err = __mmc_start_data_req(host, areq->mrq); |
443 | 541 | ||
444 | if (host->areq) | 542 | if (host->areq) |
445 | mmc_post_req(host, host->areq->mrq, 0); | 543 | mmc_post_req(host, host->areq->mrq, 0); |
@@ -2581,6 +2679,23 @@ int mmc_pm_notify(struct notifier_block *notify_block, | |||
2581 | } | 2679 | } |
2582 | #endif | 2680 | #endif |
2583 | 2681 | ||
2682 | /** | ||
2683 | * mmc_init_context_info() - init synchronization context | ||
2684 | * @host: mmc host | ||
2685 | * | ||
2686 | * Init struct context_info needed to implement asynchronous | ||
2687 | * request mechanism, used by mmc core, host driver and mmc requests | ||
2688 | * supplier. | ||
2689 | */ | ||
2690 | void mmc_init_context_info(struct mmc_host *host) | ||
2691 | { | ||
2692 | spin_lock_init(&host->context_info.lock); | ||
2693 | host->context_info.is_new_req = false; | ||
2694 | host->context_info.is_done_rcv = false; | ||
2695 | host->context_info.is_waiting_last_req = false; | ||
2696 | init_waitqueue_head(&host->context_info.wait); | ||
2697 | } | ||
2698 | |||
2584 | static int __init mmc_init(void) | 2699 | static int __init mmc_init(void) |
2585 | { | 2700 | { |
2586 | int ret; | 2701 | int ret; |
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index 3bdafbca354f..0272b3284b5e 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h | |||
@@ -76,5 +76,6 @@ void mmc_remove_host_debugfs(struct mmc_host *host); | |||
76 | void mmc_add_card_debugfs(struct mmc_card *card); | 76 | void mmc_add_card_debugfs(struct mmc_card *card); |
77 | void mmc_remove_card_debugfs(struct mmc_card *card); | 77 | void mmc_remove_card_debugfs(struct mmc_card *card); |
78 | 78 | ||
79 | void mmc_init_context_info(struct mmc_host *host); | ||
79 | #endif | 80 | #endif |
80 | 81 | ||
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 5c69315d60cc..be2500a49925 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h | |||
@@ -187,6 +187,18 @@ struct sdio_func_tuple; | |||
187 | 187 | ||
188 | #define SDIO_MAX_FUNCS 7 | 188 | #define SDIO_MAX_FUNCS 7 |
189 | 189 | ||
190 | enum mmc_blk_status { | ||
191 | MMC_BLK_SUCCESS = 0, | ||
192 | MMC_BLK_PARTIAL, | ||
193 | MMC_BLK_CMD_ERR, | ||
194 | MMC_BLK_RETRY, | ||
195 | MMC_BLK_ABORT, | ||
196 | MMC_BLK_DATA_ERR, | ||
197 | MMC_BLK_ECC_ERR, | ||
198 | MMC_BLK_NOMEDIUM, | ||
199 | MMC_BLK_NEW_REQUEST, | ||
200 | }; | ||
201 | |||
190 | /* The number of MMC physical partitions. These consist of: | 202 | /* The number of MMC physical partitions. These consist of: |
191 | * boot partitions (2), general purpose partitions (4) in MMC v4.4. | 203 | * boot partitions (2), general purpose partitions (4) in MMC v4.4. |
192 | */ | 204 | */ |
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 5bf7c2274fcb..495d1336149c 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h | |||
@@ -120,6 +120,7 @@ struct mmc_data { | |||
120 | s32 host_cookie; /* host private data */ | 120 | s32 host_cookie; /* host private data */ |
121 | }; | 121 | }; |
122 | 122 | ||
123 | struct mmc_host; | ||
123 | struct mmc_request { | 124 | struct mmc_request { |
124 | struct mmc_command *sbc; /* SET_BLOCK_COUNT for multiblock */ | 125 | struct mmc_command *sbc; /* SET_BLOCK_COUNT for multiblock */ |
125 | struct mmc_command *cmd; | 126 | struct mmc_command *cmd; |
@@ -128,9 +129,9 @@ struct mmc_request { | |||
128 | 129 | ||
129 | struct completion completion; | 130 | struct completion completion; |
130 | void (*done)(struct mmc_request *);/* completion function */ | 131 | void (*done)(struct mmc_request *);/* completion function */ |
132 | struct mmc_host *host; | ||
131 | }; | 133 | }; |
132 | 134 | ||
133 | struct mmc_host; | ||
134 | struct mmc_card; | 135 | struct mmc_card; |
135 | struct mmc_async_req; | 136 | struct mmc_async_req; |
136 | 137 | ||
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index c89a1bb87fa5..523d570f58ad 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h | |||
@@ -170,6 +170,22 @@ struct mmc_slot { | |||
170 | void *handler_priv; | 170 | void *handler_priv; |
171 | }; | 171 | }; |
172 | 172 | ||
173 | /** | ||
174 | * mmc_context_info - synchronization details for mmc context | ||
175 | * @is_done_rcv wake up reason was done request | ||
176 | * @is_new_req wake up reason was new request | ||
177 | * @is_waiting_last_req mmc context waiting for single running request | ||
178 | * @wait wait queue | ||
179 | * @lock lock to protect data fields | ||
180 | */ | ||
181 | struct mmc_context_info { | ||
182 | bool is_done_rcv; | ||
183 | bool is_new_req; | ||
184 | bool is_waiting_last_req; | ||
185 | wait_queue_head_t wait; | ||
186 | spinlock_t lock; | ||
187 | }; | ||
188 | |||
173 | struct regulator; | 189 | struct regulator; |
174 | 190 | ||
175 | struct mmc_supply { | 191 | struct mmc_supply { |
@@ -331,6 +347,7 @@ struct mmc_host { | |||
331 | struct dentry *debugfs_root; | 347 | struct dentry *debugfs_root; |
332 | 348 | ||
333 | struct mmc_async_req *areq; /* active async req */ | 349 | struct mmc_async_req *areq; /* active async req */ |
350 | struct mmc_context_info context_info; /* async synchronization info */ | ||
334 | 351 | ||
335 | #ifdef CONFIG_FAIL_MMC_REQUEST | 352 | #ifdef CONFIG_FAIL_MMC_REQUEST |
336 | struct fault_attr fail_mmc_request; | 353 | struct fault_attr fail_mmc_request; |