| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- From 5ca694dfd981a371e9b18cdd4a89c002ffaccbc5 Mon Sep 17 00:00:00 2001
- From: San Mehat <[email protected]>
- Date: Wed, 3 Dec 2008 10:22:59 -0800
- Subject: [PATCH 099/134] mmc: mmcblk: Add new feature 'CONFIG_MMC_BLOCK_PARANOID_RESUME'
- With this feature enabled, mmcblk will check the card-status before issuing
- a transaction *only* after being resumed. This protectes us from issuing
- transactions before the sdcard is ready (which can occur if the host driver
- deferrs mmc_resume_host() to reduce resume latency)
- Signed-off-by: San Mehat <[email protected]>
- ---
- drivers/mmc/card/Kconfig | 7 +++++++
- drivers/mmc/card/block.c | 3 +++
- drivers/mmc/card/queue.c | 28 ++++++++++++++++++++++++++++
- drivers/mmc/card/queue.h | 3 +++
- 4 files changed, 41 insertions(+), 0 deletions(-)
- --- a/drivers/mmc/card/Kconfig
- +++ b/drivers/mmc/card/Kconfig
- @@ -32,6 +32,13 @@ config MMC_BLOCK_BOUNCE
-
- If unsure, say Y here.
-
- +config MMC_BLOCK_PARANOID_RESUME
- + bool "Check card status on resume"
- + depends on MMC_BLOCK
- + default y
- + help
- + Nohelp
- +
- config SDIO_UART
- tristate "SDIO UART/GPS class support"
- help
- --- a/drivers/mmc/card/block.c
- +++ b/drivers/mmc/card/block.c
- @@ -643,6 +643,9 @@ static int mmc_blk_resume(struct mmc_car
-
- if (md) {
- mmc_blk_set_blksize(md, card);
- +#ifdef CONFIG_MMC_BLOCK_PARANOID_RESUME
- + md->queue.check_status = 1;
- +#endif
- mmc_queue_resume(&md->queue);
- }
- return 0;
- --- a/drivers/mmc/card/queue.c
- +++ b/drivers/mmc/card/queue.c
- @@ -14,7 +14,9 @@
- #include <linux/freezer.h>
- #include <linux/kthread.h>
- #include <linux/scatterlist.h>
- +#include <linux/delay.h>
-
- +#include <linux/mmc/mmc.h>
- #include <linux/mmc/card.h>
- #include <linux/mmc/host.h>
- #include "queue.h"
- @@ -70,7 +72,33 @@ static int mmc_queue_thread(void *d)
- continue;
- }
- set_current_state(TASK_RUNNING);
- +#ifdef CONFIG_MMC_BLOCK_PARANOID_RESUME
- + if (mq->check_status) {
- + struct mmc_command cmd;
-
- + do {
- + int err;
- +
- + cmd.opcode = MMC_SEND_STATUS;
- + cmd.arg = mq->card->rca << 16;
- + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
- +
- + mmc_claim_host(mq->card->host);
- + err = mmc_wait_for_cmd(mq->card->host, &cmd, 5);
- + mmc_release_host(mq->card->host);
- +
- + if (err) {
- + printk(KERN_ERR "%s: failed to get status (%d)\n",
- + __func__, err);
- + msleep(5);
- + continue;
- + }
- + printk(KERN_DEBUG "%s: status 0x%.8x\n", __func__, cmd.resp[0]);
- + } while (!(cmd.resp[0] & R1_READY_FOR_DATA) ||
- + (R1_CURRENT_STATE(cmd.resp[0]) == 7));
- + mq->check_status = 0;
- + }
- +#endif
- mq->issue_fn(mq, req);
- } while (1);
- up(&mq->thread_sem);
- --- a/drivers/mmc/card/queue.h
- +++ b/drivers/mmc/card/queue.h
- @@ -17,6 +17,9 @@ struct mmc_queue {
- char *bounce_buf;
- struct scatterlist *bounce_sg;
- unsigned int bounce_sg_len;
- +#ifdef CONFIG_MMC_BLOCK_PARANOID_RESUME
- + int check_status;
- +#endif
- };
-
- extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *);
|