diff mbox

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

Message ID 1299832696-3648-2-git-send-email-lamiaposta71@gmail.com
State Superseded, archived
Headers show

Commit Message

Raffaele Recalcati March 11, 2011, 8:38 a.m. UTC
From: Raffaele Recalcati <raffaele.recalcati@bticino.it>

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

Signed-off-by: Raffaele Recalcati <raffaele.recalcati@bticino.it>
---
It is not clear what should nice to do in case of status error.
Maybe it can happen only in case of hw failure.

 drivers/mmc/mmc.c |   56 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 include/mmc.h     |    4 +++
 2 files changed, 57 insertions(+), 3 deletions(-)

Comments

Hebbar, Gururaja March 11, 2011, 8:57 a.m. UTC | #1
Hi,

On Fri, Mar 11, 2011 at 14:08:14, Raffaele Recalcati wrote:
> From: Raffaele Recalcati <raffaele.recalcati@bticino.it>
> 
[...]
[...]
> @@ -48,6 +48,36 @@ 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;

[...]
[...]

> +	do {
> +		err = mmc_send_cmd(mmc, &cmd, NULL);
> +			break;

Why this break


> +		if (err)
> +			return err;
> +		else if (cmd.response[0] & MMC_STATUS_RDY_FOR_DATA)
> +			break;

[...]
[...]

Regards, 
Gururaja
Raffaele Recalcati March 11, 2011, 9:17 a.m. UTC | #2
Hi Gururaja,

On Fri, Mar 11, 2011 at 9:57 AM, Hebbar, Gururaja
<gururaja.hebbar@ti.com> wrote:
> Hi,
>
> On Fri, Mar 11, 2011 at 14:08:14, Raffaele Recalcati wrote:
>> From: Raffaele Recalcati <raffaele.recalcati@bticino.it>
>>
> [...]
> [...]

it means the lines are ok?

>> @@ -48,6 +48,36 @@ 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;
>
> [...]
> [...]
>
>> +     do {
>> +             err = mmc_send_cmd(mmc, &cmd, NULL);
>> +                     break;
>
> Why this break

Sorry, it is a mistake.
Patch is coming.

>
>
>> +             if (err)
>> +                     return err;
>> +             else if (cmd.response[0] & MMC_STATUS_RDY_FOR_DATA)
>> +                     break;
>
> [...]
> [...]
>
> Regards,
> Gururaja
>

Bye,
Raffaele
diff mbox

Patch

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 6805b33..042653f 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -48,6 +48,36 @@  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);
+			break;
+		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--);
+
+	return 0;
+}
+
 int mmc_set_blocklen(struct mmc *mmc, int len)
 {
 	struct mmc_cmd cmd;
@@ -82,6 +112,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 +152,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 +192,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 +224,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 +407,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 +656,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 +769,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 */