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@xxxxxxxxxxx> Reviewed-by: Mohan Raj Veerasamy <mohanraj.v@xxxxxxxxxxx> --- 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@xxxxxxxxxx>. --- 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