diff mbox

[U-Boot,RFC,1/3,v4] mmc: checking status after commands with R1b response

Message ID 1299844874-7605-2-git-send-email-lamiaposta71@gmail.com
State Accepted
Delegated to: Andy Fleming
Headers show

Commit Message

Raffaele Recalcati March 11, 2011, 12:01 p.m. UTC
From: Raffaele Recalcati <raffaele.recalcati@bticino.it>

It is recommended to check card status after these kind of commands.
This is done using CMD13 (SEND_STATUS) JEDEC command until
the card is ready.
In case of error the card status field is displayed.

Signed-off-by: Raffaele Recalcati <raffaele.recalcati@bticino.it>
---
 drivers/mmc/mmc.c |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 include/mmc.h     |    4 +++
 2 files changed, 61 insertions(+), 3 deletions(-)

Comments

Lei Wen March 11, 2011, 12:18 p.m. UTC | #1
On Fri, Mar 11, 2011 at 8:01 PM, Raffaele Recalcati
<lamiaposta71@gmail.com> wrote:
> From: Raffaele Recalcati <raffaele.recalcati@bticino.it>
>
> It is recommended to check card status after these kind of commands.
> This is done using CMD13 (SEND_STATUS) JEDEC command until
> the card is ready.
> In case of error the card status field is displayed.
>
> Signed-off-by: Raffaele Recalcati <raffaele.recalcati@bticino.it>
> ---
>  drivers/mmc/mmc.c |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++--
>  include/mmc.h     |    4 +++
>  2 files changed, 61 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> index 6805b33..fc1792a 100644
> --- a/drivers/mmc/mmc.c
> +++ b/drivers/mmc/mmc.c
> @@ -48,6 +48,40 @@ int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
>        return mmc->send_cmd(mmc, cmd, data);
>  }
>
> +int mmc_send_status(struct mmc *mmc, int timeout)
> +{
> +       struct mmc_cmd cmd;
> +       int err;
> +       int status;
> +
> +       cmd.cmdidx = MMC_CMD_SEND_STATUS;
> +       cmd.resp_type = MMC_RSP_R1;
> +       cmd.cmdarg = 0;
> +       cmd.flags = 0;
> +
> +       do {
> +               err = mmc_send_cmd(mmc, &cmd, NULL);
> +               if (err)
> +                       return err;
> +               else if (cmd.response[0] & MMC_STATUS_RDY_FOR_DATA)
> +                       break;
> +
> +               udelay(1000);
> +
> +               if (cmd.response[0] & MMC_STATUS_MASK) {
> +                       printf("Status Error: 0x%08X\n", cmd.response[0]);
> +                       return COMM_ERR;
> +               }
> +       } while (timeout--);
> +
> +       if (!timeout) {
> +               printf("Timeout waiting card ready\n");
> +               return TIMEOUT;
> +       }
> +
> +       return 0;
> +}
> +
>  int mmc_set_blocklen(struct mmc *mmc, int len)
>  {
>        struct mmc_cmd cmd;
> @@ -82,6 +116,7 @@ mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src)
>  {
>        struct mmc_cmd cmd;
>        struct mmc_data data;
> +       int timeout = 1000;
>
>        if ((start + blkcnt) > mmc->block_dev.lba) {
>                printf("MMC: block number 0x%lx exceeds max(0x%lx)\n",
> @@ -121,6 +156,9 @@ mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src)
>                        printf("mmc fail to send stop cmd\n");
>                        return 0;
>                }
> +
> +               /* Waiting for the ready status */
> +               mmc_send_status(mmc, 1000);
>        }
>
>        return blkcnt;
> @@ -158,6 +196,7 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt)
>  {
>        struct mmc_cmd cmd;
>        struct mmc_data data;
> +       int timeout = 1000;
>
>        if (blkcnt > 1)
>                cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
> @@ -189,6 +228,9 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt)
>                        printf("mmc fail to send stop cmd\n");
>                        return 0;
>                }
> +
> +               /* Waiting for the ready status */
> +               mmc_send_status(mmc, 1000);
>        }
>
>        return blkcnt;
> @@ -369,15 +411,23 @@ int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd)
>  int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
>  {
>        struct mmc_cmd cmd;
> +       int timeout = 1000;
> +       int ret;
>
>        cmd.cmdidx = MMC_CMD_SWITCH;
>        cmd.resp_type = MMC_RSP_R1b;
>        cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
> -               (index << 16) |
> -               (value << 8);
> +                                (index << 16) |
> +                                (value << 8);
>        cmd.flags = 0;
>
> -       return mmc_send_cmd(mmc, &cmd, NULL);
> +       ret = mmc_send_cmd(mmc, &cmd, NULL);
> +
> +       /* Waiting for the ready status */
> +       mmc_send_status(mmc, 1000);
> +
> +       return ret;
> +
>  }
>
>  int mmc_change_freq(struct mmc *mmc)
> @@ -610,6 +660,7 @@ int mmc_startup(struct mmc *mmc)
>        u64 cmult, csize;
>        struct mmc_cmd cmd;
>        char ext_csd[512];
> +       int timeout = 1000;
>
>        /* Put the Card in Identify Mode */
>        cmd.cmdidx = MMC_CMD_ALL_SEND_CID;
> @@ -722,6 +773,9 @@ int mmc_startup(struct mmc *mmc)
>        cmd.flags = 0;
>        err = mmc_send_cmd(mmc, &cmd, NULL);
>
> +       /* Waiting for the ready status */
> +       mmc_send_status(mmc, 1000);
> +
>        if (err)
>                return err;
>
> diff --git a/include/mmc.h b/include/mmc.h
> index fcd0fd1..4ee8e1c 100644
> --- a/include/mmc.h
> +++ b/include/mmc.h
> @@ -94,6 +94,10 @@
>  #define OCR_BUSY       0x80000000
>  #define OCR_HCS                0x40000000
>
> +#define MMC_STATUS_MASK                (~0x0206BF7F)
> +#define MMC_STATUS_RDY_FOR_DATA (1<<8)
> +#define MMC_STATUS_CURR_STATE  (0xf<<9)
> +
>  #define MMC_VDD_165_195                0x00000080      /* VDD voltage 1.65 - 1.95 */
>  #define MMC_VDD_20_21          0x00000100      /* VDD voltage 2.0 ~ 2.1 */
>  #define MMC_VDD_21_22          0x00000200      /* VDD voltage 2.1 ~ 2.2 */
> --
> 1.7.0.4
>

Works fine on Pantheon board. (armv5)
Tested-by:Lei Wen <leiwen@marvell.com>

Best regards,
Lei
Marek Vasut Aug. 6, 2011, 12:07 p.m. UTC | #2
On Friday, March 11, 2011 01:18:15 PM Lei Wen wrote:
> On Fri, Mar 11, 2011 at 8:01 PM, Raffaele Recalcati
> 
> <lamiaposta71@gmail.com> wrote:
> > From: Raffaele Recalcati <raffaele.recalcati@bticino.it>
> > 
> > It is recommended to check card status after these kind of commands.
> > This is done using CMD13 (SEND_STATUS) JEDEC command until
> > the card is ready.
> > In case of error the card status field is displayed.
> > 
> > Signed-off-by: Raffaele Recalcati <raffaele.recalcati@bticino.it>
> > ---
> >  drivers/mmc/mmc.c |   60
> > ++++++++++++++++++++++++++++++++++++++++++++++++++-- include/mmc.h     |
> >    4 +++
> >  2 files changed, 61 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
> > index 6805b33..fc1792a 100644
> > --- a/drivers/mmc/mmc.c
> > +++ b/drivers/mmc/mmc.c
> > @@ -48,6 +48,40 @@ int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
> > struct mmc_data *data) return mmc->send_cmd(mmc, cmd, data);
> >  }
> > 
> > +int mmc_send_status(struct mmc *mmc, int timeout)
> > +{
> > +       struct mmc_cmd cmd;
> > +       int err;
> > +       int status;
> > +
> > +       cmd.cmdidx = MMC_CMD_SEND_STATUS;
> > +       cmd.resp_type = MMC_RSP_R1;
> > +       cmd.cmdarg = 0;
> > +       cmd.flags = 0;
> > +
> > +       do {
> > +               err = mmc_send_cmd(mmc, &cmd, NULL);
> > +               if (err)
> > +                       return err;
> > +               else if (cmd.response[0] & MMC_STATUS_RDY_FOR_DATA)
> > +                       break;
> > +
> > +               udelay(1000);
> > +
> > +               if (cmd.response[0] & MMC_STATUS_MASK) {
> > +                       printf("Status Error: 0x%08X\n",
> > cmd.response[0]); +                       return COMM_ERR;
> > +               }
> > +       } while (timeout--);
> > +
> > +       if (!timeout) {
> > +               printf("Timeout waiting card ready\n");
> > +               return TIMEOUT;
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> >  int mmc_set_blocklen(struct mmc *mmc, int len)
> >  {
> >        struct mmc_cmd cmd;
> > @@ -82,6 +116,7 @@ mmc_write_blocks(struct mmc *mmc, ulong start,
> > lbaint_t blkcnt, const void*src) {
> >        struct mmc_cmd cmd;
> >        struct mmc_data data;
> > +       int timeout = 1000;
> > 
> >        if ((start + blkcnt) > mmc->block_dev.lba) {
> >                printf("MMC: block number 0x%lx exceeds max(0x%lx)\n",
> > @@ -121,6 +156,9 @@ mmc_write_blocks(struct mmc *mmc, ulong start,
> > lbaint_t blkcnt, const void*src) printf("mmc fail to send stop cmd\n");
> >                        return 0;
> >                }
> > +
> > +               /* Waiting for the ready status */
> > +               mmc_send_status(mmc, 1000);
> >        }
> > 
> >        return blkcnt;
> > @@ -158,6 +196,7 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong
> > start, lbaint_t blkcnt) {
> >        struct mmc_cmd cmd;
> >        struct mmc_data data;
> > +       int timeout = 1000;
> > 
> >        if (blkcnt > 1)
> >                cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
> > @@ -189,6 +228,9 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong
> > start, lbaint_t blkcnt) printf("mmc fail to send stop cmd\n");
> >                        return 0;
> >                }
> > +
> > +               /* Waiting for the ready status */
> > +               mmc_send_status(mmc, 1000);
> >        }
> > 
> >        return blkcnt;
> > @@ -369,15 +411,23 @@ int mmc_send_ext_csd(struct mmc *mmc, char
> > *ext_csd) int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
> >  {
> >        struct mmc_cmd cmd;
> > +       int timeout = 1000;
> > +       int ret;
> > 
> >        cmd.cmdidx = MMC_CMD_SWITCH;
> >        cmd.resp_type = MMC_RSP_R1b;
> >        cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
> > -               (index << 16) |
> > -               (value << 8);
> > +                                (index << 16) |
> > +                                (value << 8);
> >        cmd.flags = 0;
> > 
> > -       return mmc_send_cmd(mmc, &cmd, NULL);
> > +       ret = mmc_send_cmd(mmc, &cmd, NULL);
> > +
> > +       /* Waiting for the ready status */
> > +       mmc_send_status(mmc, 1000);
> > +
> > +       return ret;
> > +
> >  }
> > 
> >  int mmc_change_freq(struct mmc *mmc)
> > @@ -610,6 +660,7 @@ int mmc_startup(struct mmc *mmc)
> >        u64 cmult, csize;
> >        struct mmc_cmd cmd;
> >        char ext_csd[512];
> > +       int timeout = 1000;
> > 
> >        /* Put the Card in Identify Mode */
> >        cmd.cmdidx = MMC_CMD_ALL_SEND_CID;
> > @@ -722,6 +773,9 @@ int mmc_startup(struct mmc *mmc)
> >        cmd.flags = 0;
> >        err = mmc_send_cmd(mmc, &cmd, NULL);
> > 
> > +       /* Waiting for the ready status */
> > +       mmc_send_status(mmc, 1000);
> > +
> >        if (err)
> >                return err;
> > 
> > diff --git a/include/mmc.h b/include/mmc.h
> > index fcd0fd1..4ee8e1c 100644
> > --- a/include/mmc.h
> > +++ b/include/mmc.h
> > @@ -94,6 +94,10 @@
> >  #define OCR_BUSY       0x80000000
> >  #define OCR_HCS                0x40000000
> > 
> > +#define MMC_STATUS_MASK                (~0x0206BF7F)
> > +#define MMC_STATUS_RDY_FOR_DATA (1<<8)
> > +#define MMC_STATUS_CURR_STATE  (0xf<<9)
> > +
> >  #define MMC_VDD_165_195                0x00000080      /* VDD voltage
> > 1.65 - 1.95 */ #define MMC_VDD_20_21          0x00000100      /* VDD
> > voltage 2.0 ~ 2.1 */ #define MMC_VDD_21_22          0x00000200      /*
> > VDD voltage 2.1 ~ 2.2 */ --
> > 1.7.0.4
> 
> Works fine on Pantheon board. (armv5)
> Tested-by:Lei Wen <leiwen@marvell.com>

Hi,

have you tested this with cards operating in SPI mode ?

> 
> Best regards,
> Lei
> _______________________________________________
> U-Boot mailing list
> U-Boot@lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
Lei Wen Aug. 6, 2011, 12:18 p.m. UTC | #3
On Sat, Aug 6, 2011 at 8:07 PM, Marek Vasut <marek.vasut@gmail.com> wrote:
> On Friday, March 11, 2011 01:18:15 PM Lei Wen wrote:
>> On Fri, Mar 11, 2011 at 8:01 PM, Raffaele Recalcati
>>
>> <lamiaposta71@gmail.com> wrote:
>> > From: Raffaele Recalcati <raffaele.recalcati@bticino.it>
>> >
>> > It is recommended to check card status after these kind of commands.
>> > This is done using CMD13 (SEND_STATUS) JEDEC command until
>> > the card is ready.
>> > In case of error the card status field is displayed.
>> >
>> > Signed-off-by: Raffaele Recalcati <raffaele.recalcati@bticino.it>
>> > ---
>> >  drivers/mmc/mmc.c |   60
>> > ++++++++++++++++++++++++++++++++++++++++++++++++++-- include/mmc.h     |
>> >    4 +++
>> >  2 files changed, 61 insertions(+), 3 deletions(-)
>> >
>> > diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
>> > index 6805b33..fc1792a 100644
>> > --- a/drivers/mmc/mmc.c
>> > +++ b/drivers/mmc/mmc.c
>> > @@ -48,6 +48,40 @@ int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
>> > struct mmc_data *data) return mmc->send_cmd(mmc, cmd, data);
>> >  }
>> >
>> > +int mmc_send_status(struct mmc *mmc, int timeout)
>> > +{
>> > +       struct mmc_cmd cmd;
>> > +       int err;
>> > +       int status;
>> > +
>> > +       cmd.cmdidx = MMC_CMD_SEND_STATUS;
>> > +       cmd.resp_type = MMC_RSP_R1;
>> > +       cmd.cmdarg = 0;
>> > +       cmd.flags = 0;
>> > +
>> > +       do {
>> > +               err = mmc_send_cmd(mmc, &cmd, NULL);
>> > +               if (err)
>> > +                       return err;
>> > +               else if (cmd.response[0] & MMC_STATUS_RDY_FOR_DATA)
>> > +                       break;
>> > +
>> > +               udelay(1000);
>> > +
>> > +               if (cmd.response[0] & MMC_STATUS_MASK) {
>> > +                       printf("Status Error: 0x%08X\n",
>> > cmd.response[0]); +                       return COMM_ERR;
>> > +               }
>> > +       } while (timeout--);
>> > +
>> > +       if (!timeout) {
>> > +               printf("Timeout waiting card ready\n");
>> > +               return TIMEOUT;
>> > +       }
>> > +
>> > +       return 0;
>> > +}
>> > +
>> >  int mmc_set_blocklen(struct mmc *mmc, int len)
>> >  {
>> >        struct mmc_cmd cmd;
>> > @@ -82,6 +116,7 @@ mmc_write_blocks(struct mmc *mmc, ulong start,
>> > lbaint_t blkcnt, const void*src) {
>> >        struct mmc_cmd cmd;
>> >        struct mmc_data data;
>> > +       int timeout = 1000;
>> >
>> >        if ((start + blkcnt) > mmc->block_dev.lba) {
>> >                printf("MMC: block number 0x%lx exceeds max(0x%lx)\n",
>> > @@ -121,6 +156,9 @@ mmc_write_blocks(struct mmc *mmc, ulong start,
>> > lbaint_t blkcnt, const void*src) printf("mmc fail to send stop cmd\n");
>> >                        return 0;
>> >                }
>> > +
>> > +               /* Waiting for the ready status */
>> > +               mmc_send_status(mmc, 1000);
>> >        }
>> >
>> >        return blkcnt;
>> > @@ -158,6 +196,7 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong
>> > start, lbaint_t blkcnt) {
>> >        struct mmc_cmd cmd;
>> >        struct mmc_data data;
>> > +       int timeout = 1000;
>> >
>> >        if (blkcnt > 1)
>> >                cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
>> > @@ -189,6 +228,9 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong
>> > start, lbaint_t blkcnt) printf("mmc fail to send stop cmd\n");
>> >                        return 0;
>> >                }
>> > +
>> > +               /* Waiting for the ready status */
>> > +               mmc_send_status(mmc, 1000);
>> >        }
>> >
>> >        return blkcnt;
>> > @@ -369,15 +411,23 @@ int mmc_send_ext_csd(struct mmc *mmc, char
>> > *ext_csd) int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
>> >  {
>> >        struct mmc_cmd cmd;
>> > +       int timeout = 1000;
>> > +       int ret;
>> >
>> >        cmd.cmdidx = MMC_CMD_SWITCH;
>> >        cmd.resp_type = MMC_RSP_R1b;
>> >        cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
>> > -               (index << 16) |
>> > -               (value << 8);
>> > +                                (index << 16) |
>> > +                                (value << 8);
>> >        cmd.flags = 0;
>> >
>> > -       return mmc_send_cmd(mmc, &cmd, NULL);
>> > +       ret = mmc_send_cmd(mmc, &cmd, NULL);
>> > +
>> > +       /* Waiting for the ready status */
>> > +       mmc_send_status(mmc, 1000);
>> > +
>> > +       return ret;
>> > +
>> >  }
>> >
>> >  int mmc_change_freq(struct mmc *mmc)
>> > @@ -610,6 +660,7 @@ int mmc_startup(struct mmc *mmc)
>> >        u64 cmult, csize;
>> >        struct mmc_cmd cmd;
>> >        char ext_csd[512];
>> > +       int timeout = 1000;
>> >
>> >        /* Put the Card in Identify Mode */
>> >        cmd.cmdidx = MMC_CMD_ALL_SEND_CID;
>> > @@ -722,6 +773,9 @@ int mmc_startup(struct mmc *mmc)
>> >        cmd.flags = 0;
>> >        err = mmc_send_cmd(mmc, &cmd, NULL);
>> >
>> > +       /* Waiting for the ready status */
>> > +       mmc_send_status(mmc, 1000);
>> > +
>> >        if (err)
>> >                return err;
>> >
>> > diff --git a/include/mmc.h b/include/mmc.h
>> > index fcd0fd1..4ee8e1c 100644
>> > --- a/include/mmc.h
>> > +++ b/include/mmc.h
>> > @@ -94,6 +94,10 @@
>> >  #define OCR_BUSY       0x80000000
>> >  #define OCR_HCS                0x40000000
>> >
>> > +#define MMC_STATUS_MASK                (~0x0206BF7F)
>> > +#define MMC_STATUS_RDY_FOR_DATA (1<<8)
>> > +#define MMC_STATUS_CURR_STATE  (0xf<<9)
>> > +
>> >  #define MMC_VDD_165_195                0x00000080      /* VDD voltage
>> > 1.65 - 1.95 */ #define MMC_VDD_20_21          0x00000100      /* VDD
>> > voltage 2.0 ~ 2.1 */ #define MMC_VDD_21_22          0x00000200      /*
>> > VDD voltage 2.1 ~ 2.2 */ --
>> > 1.7.0.4
>>
>> Works fine on Pantheon board. (armv5)
>> Tested-by:Lei Wen <leiwen@marvell.com>
>
> Hi,
>
> have you tested this with cards operating in SPI mode ?
>

no... I just test with normal sd and emmc card...

Best regards,
Lei
diff mbox

Patch

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 6805b33..fc1792a 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -48,6 +48,40 @@  int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 	return mmc->send_cmd(mmc, cmd, data);
 }
 
+int mmc_send_status(struct mmc *mmc, int timeout)
+{
+	struct mmc_cmd cmd;
+	int err;
+	int status;
+
+	cmd.cmdidx = MMC_CMD_SEND_STATUS;
+	cmd.resp_type = MMC_RSP_R1;
+	cmd.cmdarg = 0;
+	cmd.flags = 0;
+
+	do {
+		err = mmc_send_cmd(mmc, &cmd, NULL);
+		if (err)
+			return err;
+		else if (cmd.response[0] & MMC_STATUS_RDY_FOR_DATA)
+			break;
+
+		udelay(1000);
+
+		if (cmd.response[0] & MMC_STATUS_MASK) {
+			printf("Status Error: 0x%08X\n", cmd.response[0]);
+			return COMM_ERR;
+		}
+	} while (timeout--);
+
+	if (!timeout) {
+		printf("Timeout waiting card ready\n");
+		return TIMEOUT;
+	}
+
+	return 0;
+}
+
 int mmc_set_blocklen(struct mmc *mmc, int len)
 {
 	struct mmc_cmd cmd;
@@ -82,6 +116,7 @@  mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src)
 {
 	struct mmc_cmd cmd;
 	struct mmc_data data;
+	int timeout = 1000;
 
 	if ((start + blkcnt) > mmc->block_dev.lba) {
 		printf("MMC: block number 0x%lx exceeds max(0x%lx)\n",
@@ -121,6 +156,9 @@  mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src)
 			printf("mmc fail to send stop cmd\n");
 			return 0;
 		}
+
+		/* Waiting for the ready status */
+		mmc_send_status(mmc, 1000);
 	}
 
 	return blkcnt;
@@ -158,6 +196,7 @@  int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt)
 {
 	struct mmc_cmd cmd;
 	struct mmc_data data;
+	int timeout = 1000;
 
 	if (blkcnt > 1)
 		cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
@@ -189,6 +228,9 @@  int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt)
 			printf("mmc fail to send stop cmd\n");
 			return 0;
 		}
+
+		/* Waiting for the ready status */
+		mmc_send_status(mmc, 1000);
 	}
 
 	return blkcnt;
@@ -369,15 +411,23 @@  int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd)
 int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
 {
 	struct mmc_cmd cmd;
+	int timeout = 1000;
+	int ret;
 
 	cmd.cmdidx = MMC_CMD_SWITCH;
 	cmd.resp_type = MMC_RSP_R1b;
 	cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
-		(index << 16) |
-		(value << 8);
+				 (index << 16) |
+				 (value << 8);
 	cmd.flags = 0;
 
-	return mmc_send_cmd(mmc, &cmd, NULL);
+	ret = mmc_send_cmd(mmc, &cmd, NULL);
+
+	/* Waiting for the ready status */
+	mmc_send_status(mmc, 1000);
+
+	return ret;
+
 }
 
 int mmc_change_freq(struct mmc *mmc)
@@ -610,6 +660,7 @@  int mmc_startup(struct mmc *mmc)
 	u64 cmult, csize;
 	struct mmc_cmd cmd;
 	char ext_csd[512];
+	int timeout = 1000;
 
 	/* Put the Card in Identify Mode */
 	cmd.cmdidx = MMC_CMD_ALL_SEND_CID;
@@ -722,6 +773,9 @@  int mmc_startup(struct mmc *mmc)
 	cmd.flags = 0;
 	err = mmc_send_cmd(mmc, &cmd, NULL);
 
+	/* Waiting for the ready status */
+	mmc_send_status(mmc, 1000);
+
 	if (err)
 		return err;
 
diff --git a/include/mmc.h b/include/mmc.h
index fcd0fd1..4ee8e1c 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -94,6 +94,10 @@ 
 #define OCR_BUSY	0x80000000
 #define OCR_HCS		0x40000000
 
+#define MMC_STATUS_MASK		(~0x0206BF7F)
+#define MMC_STATUS_RDY_FOR_DATA (1<<8)
+#define MMC_STATUS_CURR_STATE	(0xf<<9)
+
 #define MMC_VDD_165_195		0x00000080	/* VDD voltage 1.65 - 1.95 */
 #define MMC_VDD_20_21		0x00000100	/* VDD voltage 2.0 ~ 2.1 */
 #define MMC_VDD_21_22		0x00000200	/* VDD voltage 2.1 ~ 2.2 */