From 9b1a67218d6512a3a746422efa2b6fc016b577e5 Mon Sep 17 00:00:00 2001 From: Rich O Date: Mon, 31 Jul 2023 14:02:02 +0000 Subject: [PATCH] Micron CMD56 Additions --- mmc.c | 6 ++++ mmc_cmds.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ mmc_cmds.h | 4 +++ 3 files changed, 97 insertions(+) diff --git a/mmc.c b/mmc.c index 795b4e3..5da6c1e 100644 --- a/mmc.c +++ b/mmc.c @@ -51,6 +51,12 @@ static struct Command commands[] = { /* * avoid short commands different for the case only */ + { do_PPEU, -1,/*Micron CMD56 Addition */ + "ppeu read", " \n" + "Usage: mmc ppeu read <-d> \n" + "-d\tdump data block", + NULL + }, { do_read_extcsd, -1, "extcsd read", "\n" "Print extcsd data from .", diff --git a/mmc_cmds.c b/mmc_cmds.c index 26bdc38..92b507b 100644 --- a/mmc_cmds.c +++ b/mmc_cmds.c @@ -3239,3 +3239,90 @@ dev_fd_close: exit(1); return 0; } + +/* Micron CMD56 Additions */ +#define CHECK(a, b, c) \ + if (a) \ + { \ + fprintf(stderr, b); \ + c; \ + } + +//PPEU - Percentage of P/E cycles Used +int do_PPEU(int nargs, char **argv) +{ + int cmd56_arg = 0x110005FB; + char data_in[SD_BLOCK_SIZE]; + int fd, ret; + char *device; + + CHECK(!((nargs == 2)||(nargs == 3)), + "Usage: mmc ppeu read <-d> \n", exit(1)); + device = argv[nargs-1]; + fd = open(device, O_RDWR); + + if (fd < 0) { + perror("open"); + exit(1); + } + + //execute CMD56 and get one 512-byte data block + ret = CMD56_data_in(fd, cmd56_arg, data_in); + + if (ret) { + fprintf(stderr, "CMD56 CALL FAILED, %s\n", device); + exit(1); + } + + if (!strcmp("-d", argv[1])) + dump_data_block(data_in); //data block dumping + + /* write data to stdout in CSV format */ + printf("Fixed Filed Header: %02Xh %02Xh %02Xh %02Xh\n", + data_in[0], data_in[1], data_in[2], data_in[3]); + printf("Percentage Step Size: %d\n", data_in[7]); + printf("TLC/QLC Percentage Utilization: %d%%\n", data_in[8]); + printf("SLC Percentage Utilization: %d%%\n", data_in[9]); + return ret; +} + +//CMD56 implementation +int CMD56_data_in(int fd, int cmd56_arg, char *lba_block_data) +{ + int ret = 0; + struct mmc_ioc_cmd idata; + + memset(&idata, 0, sizeof(idata)); + memset(lba_block_data, 0, sizeof(__u8) * 512); + idata.write_flag = 0; + idata.opcode = SD_GEN_CMD; + idata.arg = cmd56_arg; + idata.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; + idata.blksz = SD_BLOCK_SIZE; + idata.blocks = 1; + mmc_ioc_cmd_set_data(idata, lba_block_data); + ret = ioctl(fd, MMC_IOC_CMD, &idata); + + if (ret) + perror("ioctl"); + +return ret; +} + +void dump_data_block(char *lba_block_data) +{ + int count=0; + + printf("CMD56 data block dumping:"); + + while( count < SD_BLOCK_SIZE) { + if(count % 16 == 0) + printf("\n%03d: ", count); + + printf("%02x ", lba_block_data[count]); + count++; +} + + printf("\n"); + return; +} \ No newline at end of file diff --git a/mmc_cmds.h b/mmc_cmds.h index 5f2bef1..e0345f5 100644 --- a/mmc_cmds.h +++ b/mmc_cmds.h @@ -50,3 +50,7 @@ int do_general_cmd_read(int nargs, char **argv); int do_softreset(int nargs, char **argv); int do_preidle(int nargs, char **argv); int do_alt_boot_op(int nargs, char **argv); +/* Micron CMD56 Additions */ +int do_PPEU(int nargs, char **argv); +int CMD56_data_in(int fd, int cmd56_arg, char *lba_block_data); +void dump_data_block(char *lba_block_data); \ No newline at end of file