diff mbox series

[v2] Enhancement to do_status_get() function for detailed Response info

Message ID 20220211120449.195052-1-shankar.ma@samsung.com
State New
Headers show
Series [v2] Enhancement to do_status_get() function for detailed Response info | expand

Commit Message

Shankar Athanikar Feb. 11, 2022, 12:04 p.m. UTC
This enhancement covers detailed status register decoding with 
ERROR/STATUS information when host sends CMD13(with SQS=0)

Signed-off-by: Shankar Athanikar <shankar.ma@samsung.com>
Reviewed-by: Mohan Raj Veerasamy <mohanraj.v@samsung.com>
---
change log V1 -> V2

1. Added #defines for R1 Response device status fields.
2. Code cleanup and addressed Review comments from Ulf
Hansson<ulf.hansson@linaro.org>.
---
 mmc.h      | 22 ++++++++++++++
 mmc_cmds.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 108 insertions(+), 1 deletion(-)

Comments

Ulf Hansson Feb. 17, 2022, 3:38 p.m. UTC | #1
On Fri, 11 Feb 2022 at 14:53, Shankar Athanikar <shankar.ma@samsung.com> wrote:
>
> This enhancement covers detailed status register decoding with
> ERROR/STATUS information when host sends CMD13(with SQS=0)
>
> Signed-off-by: Shankar Athanikar <shankar.ma@samsung.com>
> Reviewed-by: Mohan Raj Veerasamy <mohanraj.v@samsung.com>

Applied to git.kernel.org/pub/scm//utils/mmc/mmc-utils.git master, thanks!

Kind regards
Uffe

> ---
> change log V1 -> V2
>
> 1. Added #defines for R1 Response device status fields.
> 2. Code cleanup and addressed Review comments from Ulf
> Hansson<ulf.hansson@linaro.org>.
> ---
>  mmc.h      | 22 ++++++++++++++
>  mmc_cmds.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 108 insertions(+), 1 deletion(-)
>
> diff --git a/mmc.h b/mmc.h
> index e9766d7..193dfee 100644
> --- a/mmc.h
> +++ b/mmc.h
> @@ -44,6 +44,28 @@
>                                               [1] Discard Enable
>                                               [0] Identify Write Blocks for
>                                               Erase (or TRIM Enable)  R1b */
> +
> +#define R1_OUT_OF_RANGE         (1 << 31)       /* er, c */
> +#define R1_ADDRESS_ERROR        (1 << 30)       /* erx, c */
> +#define R1_BLOCK_LEN_ERROR      (1 << 29)       /* er, c */
> +#define R1_ERASE_SEQ_ERROR      (1 << 28)       /* er, c */
> +#define R1_ERASE_PARAM          (1 << 27)       /* ex, c */
> +#define R1_WP_VIOLATION         (1 << 26)       /* erx, c */
> +#define R1_CARD_IS_LOCKED       (1 << 25)       /* sx, a */
> +#define R1_LOCK_UNLOCK_FAILED   (1 << 24)       /* erx, c */
> +#define R1_COM_CRC_ERROR        (1 << 23)       /* er, b */
> +#define R1_ILLEGAL_COMMAND      (1 << 22)       /* er, b */
> +#define R1_CARD_ECC_FAILED      (1 << 21)       /* ex, c */
> +#define R1_CC_ERROR             (1 << 20)       /* erx, c */
> +#define R1_ERROR                (1 << 19)       /* erx, c */
> +#define R1_CID_CSD_OVERWRITE    (1 << 16)       /* erx, c, CID/CSD overwrite */
> +#define R1_WP_ERASE_SKIP        (1 << 15)       /* sx, c */
> +#define R1_CARD_ECC_DISABLED    (1 << 14)       /* sx, a */
> +#define R1_ERASE_RESET          (1 << 13)       /* sr, c */
> +#define R1_READY_FOR_DATA       (1 << 8)        /* sx, a */
> +#define R1_EXCEPTION_EVENT      (1 << 6)        /* sr, a */
> +#define R1_APP_CMD              (1 << 5)        /* sr, c */
> +
>  /*
>   * EXT_CSD fields
>   */
> diff --git a/mmc_cmds.c b/mmc_cmds.c
> index f024079..94916d2 100644
> --- a/mmc_cmds.c
> +++ b/mmc_cmds.c
> @@ -848,6 +848,8 @@ int do_status_get(int nargs, char **argv)
>         __u32 response;
>         int fd, ret;
>         char *device;
> +       const char *str;
> +       __u8 state;
>
>         if (nargs != 2) {
>                 fprintf(stderr, "Usage: mmc status get </path/to/mmcblkX>\n");
> @@ -869,7 +871,90 @@ int do_status_get(int nargs, char **argv)
>         }
>
>         printf("SEND_STATUS response: 0x%08x\n", response);
>
> +       if (response & R1_OUT_OF_RANGE)
> +               printf("ERROR: ADDRESS_OUT_OF_RANGE\n");
> +       if (response & R1_ADDRESS_ERROR)
> +               printf("ERROR: ADDRESS_MISALIGN\n");
> +       if (response & R1_BLOCK_LEN_ERROR)
> +               printf("ERROR: BLOCK_LEN_ERROR\n");
> +       if (response & R1_ERASE_SEQ_ERROR)
> +               printf("ERROR: ERASE_SEQ_ERROR\n");
> +       if (response & R1_ERASE_PARAM)
> +               printf("ERROR: ERASE_PARAM_ERROR\n");
> +       if (response & R1_WP_VIOLATION)
> +               printf("ERROR: WP_VOILATION\n");
> +       if (response & R1_CARD_IS_LOCKED)
> +               printf("STATUS: DEVICE_IS_LOCKED\n");
> +       if (response & R1_LOCK_UNLOCK_FAILED)
> +               printf("ERROR: LOCK_UNLOCK_IS_FAILED\n");
> +       if (response & R1_COM_CRC_ERROR)
> +               printf("ERROR: COM_CRC_ERROR\n");
> +       if (response & R1_ILLEGAL_COMMAND)
> +               printf("ERROR: ILLEGAL_COMMAND\n");
> +       if (response & R1_CARD_ECC_FAILED)
> +               printf("ERROR: DEVICE_ECC_FAILED\n");
> +       if (response & R1_CC_ERROR)
> +               printf("ERROR: CC_ERROR\n");
> +       if (response & R1_ERROR)
> +               printf("ERROR: ERROR\n");
> +       if (response & R1_CID_CSD_OVERWRITE)
> +               printf("ERROR: CID/CSD OVERWRITE\n");
> +       if (response & R1_WP_ERASE_SKIP)
> +               printf("ERROR: WP_ERASE_SKIP\n");
> +       if (response & R1_ERASE_RESET)
> +               printf("ERROR: ERASE_RESET\n");
> +
> +       state = (response >> 9) & 0xF;
> +       switch (state) {
> +       case 0:
> +               str = "IDLE";
> +               break;
> +       case 1:
> +               str = "READY";
> +               break;
> +       case 2:
> +               str = "IDENT";
> +               break;
> +       case 3:
> +               str = "STDBY";
> +               break;
> +       case 4:
> +               str = "TRANS";
> +               break;
> +       case 5:
> +               str = "DATA";
> +               break;
> +       case 6:
> +               str = "RCV";
> +               break;
> +       case 7:
> +               str = "PRG";
> +               break;
> +       case 8:
> +               str = "DIS";
> +               break;
> +       case 9:
> +               str = "BTST";
> +               break;
> +       case 10:
> +               str = "SLP";
> +               break;
> +       default:
> +               printf("Attention : Device state is INVALID: Kindly check the Response\n");
> +               goto out_free;
> +       }
> +
> +       printf("DEVICE STATE: %s\n", str);
> +       if (response & R1_READY_FOR_DATA)
> +               printf("STATUS: READY_FOR_DATA\n");
> +       if (response & R1_SWITCH_ERROR)
> +               printf("ERROR: SWITCH_ERROR\n");
> +       if (response & R1_EXCEPTION_EVENT)
> +               printf("STATUS: EXCEPTION_EVENT\n");  /* Check EXCEPTION_EVENTS_STATUS fields for further actions */
> +       if (response & R1_APP_CMD)
> +               printf("STATUS: APP_CMD\n");
> +out_free:
>         close(fd);
>         return ret;
>  }
>
> --
> 2.25.1
diff mbox series

Patch

diff --git a/mmc.h b/mmc.h
index e9766d7..193dfee 100644
--- a/mmc.h
+++ b/mmc.h
@@ -44,6 +44,28 @@ 
 					      [1] Discard Enable
 					      [0] Identify Write Blocks for
 					      Erase (or TRIM Enable)  R1b */
+
+#define R1_OUT_OF_RANGE         (1 << 31)       /* er, c */
+#define R1_ADDRESS_ERROR        (1 << 30)       /* erx, c */
+#define R1_BLOCK_LEN_ERROR      (1 << 29)       /* er, c */
+#define R1_ERASE_SEQ_ERROR      (1 << 28)       /* er, c */
+#define R1_ERASE_PARAM          (1 << 27)       /* ex, c */
+#define R1_WP_VIOLATION         (1 << 26)       /* erx, c */
+#define R1_CARD_IS_LOCKED       (1 << 25)       /* sx, a */
+#define R1_LOCK_UNLOCK_FAILED   (1 << 24)       /* erx, c */
+#define R1_COM_CRC_ERROR        (1 << 23)       /* er, b */
+#define R1_ILLEGAL_COMMAND      (1 << 22)       /* er, b */
+#define R1_CARD_ECC_FAILED      (1 << 21)       /* ex, c */
+#define R1_CC_ERROR             (1 << 20)       /* erx, c */
+#define R1_ERROR                (1 << 19)       /* erx, c */
+#define R1_CID_CSD_OVERWRITE    (1 << 16)       /* erx, c, CID/CSD overwrite */
+#define R1_WP_ERASE_SKIP        (1 << 15)       /* sx, c */
+#define R1_CARD_ECC_DISABLED    (1 << 14)       /* sx, a */
+#define R1_ERASE_RESET          (1 << 13)       /* sr, c */
+#define R1_READY_FOR_DATA       (1 << 8)        /* sx, a */
+#define R1_EXCEPTION_EVENT      (1 << 6)        /* sr, a */
+#define R1_APP_CMD              (1 << 5)        /* sr, c */
+
 /*
  * EXT_CSD fields
  */
diff --git a/mmc_cmds.c b/mmc_cmds.c
index f024079..94916d2 100644
--- a/mmc_cmds.c
+++ b/mmc_cmds.c
@@ -848,6 +848,8 @@  int do_status_get(int nargs, char **argv)
 	__u32 response;
 	int fd, ret;
 	char *device;
+	const char *str;
+	__u8 state;
 
 	if (nargs != 2) {
 		fprintf(stderr, "Usage: mmc status get </path/to/mmcblkX>\n");
@@ -869,7 +871,90 @@  int do_status_get(int nargs, char **argv)
 	}
 
 	printf("SEND_STATUS response: 0x%08x\n", response);
 
+	if (response & R1_OUT_OF_RANGE)
+		printf("ERROR: ADDRESS_OUT_OF_RANGE\n");
+	if (response & R1_ADDRESS_ERROR)
+		printf("ERROR: ADDRESS_MISALIGN\n");
+	if (response & R1_BLOCK_LEN_ERROR)
+		printf("ERROR: BLOCK_LEN_ERROR\n");
+	if (response & R1_ERASE_SEQ_ERROR)
+		printf("ERROR: ERASE_SEQ_ERROR\n");
+	if (response & R1_ERASE_PARAM)
+		printf("ERROR: ERASE_PARAM_ERROR\n");
+	if (response & R1_WP_VIOLATION)
+		printf("ERROR: WP_VOILATION\n");
+	if (response & R1_CARD_IS_LOCKED)
+		printf("STATUS: DEVICE_IS_LOCKED\n");
+	if (response & R1_LOCK_UNLOCK_FAILED)
+		printf("ERROR: LOCK_UNLOCK_IS_FAILED\n");
+	if (response & R1_COM_CRC_ERROR)
+		printf("ERROR: COM_CRC_ERROR\n");
+	if (response & R1_ILLEGAL_COMMAND)
+		printf("ERROR: ILLEGAL_COMMAND\n");
+	if (response & R1_CARD_ECC_FAILED)
+		printf("ERROR: DEVICE_ECC_FAILED\n");
+	if (response & R1_CC_ERROR)
+		printf("ERROR: CC_ERROR\n");
+	if (response & R1_ERROR)
+		printf("ERROR: ERROR\n");
+	if (response & R1_CID_CSD_OVERWRITE)
+		printf("ERROR: CID/CSD OVERWRITE\n");
+	if (response & R1_WP_ERASE_SKIP)
+		printf("ERROR: WP_ERASE_SKIP\n");
+	if (response & R1_ERASE_RESET)
+		printf("ERROR: ERASE_RESET\n");
+
+	state = (response >> 9) & 0xF;
+	switch (state) {
+	case 0:
+		str = "IDLE";
+		break;
+	case 1:
+		str = "READY";
+		break;
+	case 2:
+		str = "IDENT";
+		break;
+	case 3:
+		str = "STDBY";
+		break;
+	case 4:
+		str = "TRANS";
+		break;
+	case 5:
+		str = "DATA";
+		break;
+	case 6:
+		str = "RCV";
+		break;
+	case 7:
+		str = "PRG";
+		break;
+	case 8:
+		str = "DIS";
+		break;
+	case 9:
+		str = "BTST";
+		break;
+	case 10:
+		str = "SLP";
+		break;
+	default:
+		printf("Attention : Device state is INVALID: Kindly check the Response\n");
+		goto out_free;
+	}
+
+	printf("DEVICE STATE: %s\n", str);
+	if (response & R1_READY_FOR_DATA)
+		printf("STATUS: READY_FOR_DATA\n");
+	if (response & R1_SWITCH_ERROR)
+		printf("ERROR: SWITCH_ERROR\n");
+	if (response & R1_EXCEPTION_EVENT)
+		printf("STATUS: EXCEPTION_EVENT\n");  /* Check EXCEPTION_EVENTS_STATUS fields for further actions */
+	if (response & R1_APP_CMD)
+		printf("STATUS: APP_CMD\n");
+out_free:
 	close(fd);
 	return ret;
 }