ps3: R.I.P.
[openwrt.git] / target / linux / goldfish / patches-2.6.30 / 0099-mmc-mmcblk-Add-new-feature-CONFIG_MMC_BLOCK_PARAN.patch
1 From 5ca694dfd981a371e9b18cdd4a89c002ffaccbc5 Mon Sep 17 00:00:00 2001
2 From: San Mehat <san@android.com>
3 Date: Wed, 3 Dec 2008 10:22:59 -0800
4 Subject: [PATCH 099/134] mmc: mmcblk: Add new feature 'CONFIG_MMC_BLOCK_PARANOID_RESUME'
5
6   With this feature enabled, mmcblk will check the card-status before issuing
7 a transaction *only* after being resumed. This protectes us from issuing
8 transactions before the sdcard is ready (which can occur if the host driver
9 deferrs mmc_resume_host() to reduce resume latency)
10
11 Signed-off-by: San Mehat <san@android.com>
12 ---
13  drivers/mmc/card/Kconfig |    7 +++++++
14  drivers/mmc/card/block.c |    3 +++
15  drivers/mmc/card/queue.c |   28 ++++++++++++++++++++++++++++
16  drivers/mmc/card/queue.h |    3 +++
17  4 files changed, 41 insertions(+), 0 deletions(-)
18
19 --- a/drivers/mmc/card/Kconfig
20 +++ b/drivers/mmc/card/Kconfig
21 @@ -32,6 +32,13 @@ config MMC_BLOCK_BOUNCE
22  
23           If unsure, say Y here.
24  
25 +config MMC_BLOCK_PARANOID_RESUME
26 +       bool "Check card status on resume"
27 +        depends on MMC_BLOCK
28 +        default y
29 +        help
30 +          Nohelp
31 +
32  config SDIO_UART
33         tristate "SDIO UART/GPS class support"
34         help
35 --- a/drivers/mmc/card/block.c
36 +++ b/drivers/mmc/card/block.c
37 @@ -643,6 +643,9 @@ static int mmc_blk_resume(struct mmc_car
38  
39         if (md) {
40                 mmc_blk_set_blksize(md, card);
41 +#ifdef CONFIG_MMC_BLOCK_PARANOID_RESUME
42 +               md->queue.check_status = 1;
43 +#endif
44                 mmc_queue_resume(&md->queue);
45         }
46         return 0;
47 --- a/drivers/mmc/card/queue.c
48 +++ b/drivers/mmc/card/queue.c
49 @@ -14,7 +14,9 @@
50  #include <linux/freezer.h>
51  #include <linux/kthread.h>
52  #include <linux/scatterlist.h>
53 +#include <linux/delay.h>
54  
55 +#include <linux/mmc/mmc.h>
56  #include <linux/mmc/card.h>
57  #include <linux/mmc/host.h>
58  #include "queue.h"
59 @@ -70,7 +72,33 @@ static int mmc_queue_thread(void *d)
60                         continue;
61                 }
62                 set_current_state(TASK_RUNNING);
63 +#ifdef CONFIG_MMC_BLOCK_PARANOID_RESUME
64 +               if (mq->check_status) {
65 +                       struct mmc_command cmd;
66  
67 +                       do {
68 +                               int err;
69 +
70 +                               cmd.opcode = MMC_SEND_STATUS;
71 +                               cmd.arg = mq->card->rca << 16;
72 +                               cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
73 +
74 +                               mmc_claim_host(mq->card->host);
75 +                               err = mmc_wait_for_cmd(mq->card->host, &cmd, 5);
76 +                               mmc_release_host(mq->card->host);
77 +
78 +                               if (err) {
79 +                                       printk(KERN_ERR "%s: failed to get status (%d)\n",
80 +                                              __func__, err);
81 +                                       msleep(5);
82 +                                       continue;
83 +                               }
84 +                               printk(KERN_DEBUG "%s: status 0x%.8x\n", __func__, cmd.resp[0]);
85 +                       } while (!(cmd.resp[0] & R1_READY_FOR_DATA) ||
86 +                               (R1_CURRENT_STATE(cmd.resp[0]) == 7));
87 +                       mq->check_status = 0;
88 +                }
89 +#endif
90                 mq->issue_fn(mq, req);
91         } while (1);
92         up(&mq->thread_sem);
93 --- a/drivers/mmc/card/queue.h
94 +++ b/drivers/mmc/card/queue.h
95 @@ -17,6 +17,9 @@ struct mmc_queue {
96         char                    *bounce_buf;
97         struct scatterlist      *bounce_sg;
98         unsigned int            bounce_sg_len;
99 +#ifdef CONFIG_MMC_BLOCK_PARANOID_RESUME
100 +       int                     check_status;
101 +#endif
102  };
103  
104  extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *);