return mmc->send_cmd(mmc, cmd, data);
 }
 
+int mmc_send_status(struct mmc *mmc, int timeout)
+{
+       struct mmc_cmd cmd;
+       int err;
+#ifdef CONFIG_MMC_TRACE
+       int status;
+#endif
+
+       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;
 {
        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",
                        printf("mmc fail to send stop cmd\n");
                        return 0;
                }
+
+               /* Waiting for the ready status */
+               mmc_send_status(mmc, timeout);
        }
 
        return blkcnt;
 {
        struct mmc_cmd cmd;
        struct mmc_data data;
+       int timeout = 1000;
 
        if (blkcnt > 1)
                cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
                        printf("mmc fail to send stop cmd\n");
                        return 0;
                }
+
+               /* Waiting for the ready status */
+               mmc_send_status(mmc, timeout);
        }
 
        return blkcnt;
 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, timeout);
+
+       return ret;
+
 }
 
 int mmc_change_freq(struct mmc *mmc)
        u64 cmult, csize;
        struct mmc_cmd cmd;
        char ext_csd[512];
+       int timeout = 1000;
 
 #ifdef CONFIG_MMC_SPI_CRC_ON
        if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
 
        err = mmc_send_cmd(mmc, &cmd, NULL);
 
+       /* Waiting for the ready status */
+       mmc_send_status(mmc, timeout);
+
        if (err)
                return err;
 
 
 #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 */