mirror of https://github.com/hak5/openwrt.git
105 lines
2.9 KiB
Diff
105 lines
2.9 KiB
Diff
From 5ca694dfd981a371e9b18cdd4a89c002ffaccbc5 Mon Sep 17 00:00:00 2001
|
|
From: San Mehat <san@android.com>
|
|
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 <san@android.com>
|
|
---
|
|
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 *);
|