diff --git a/mmc.c b/mmc.c index eb2638b..6c56387 100644 --- a/mmc.c +++ b/mmc.c @@ -237,6 +237,14 @@ static struct Command commands[] = { "secure-trim1 | secure-trim2 | trim \n", NULL }, + { do_general_cmd_read, -1, + "gen_cmd read", " [arg]\n" + "Send GEN_CMD (CMD56) to read vendor-specific format/meaning data from \n\n" + "NOTE!: [arg] is optional and defaults to 0x1. If [arg] is specified, then [arg]\n" + "must be a 32-bit hexadecimal number, prefixed with 0x/0X. And bit0 in [arg] must\n" + "be 1.", + NULL + }, { 0, 0, 0, 0 } }; diff --git a/mmc.h b/mmc.h index 0796532..daff62c 100644 --- a/mmc.h +++ b/mmc.h @@ -42,6 +42,8 @@ [1] Discard Enable [0] Identify Write Blocks for Erase (or TRIM Enable) R1b */ +#define MMC_GEN_CMD 56 /* adtc [31:1] stuff bits. + [0]: RD/WR1 R1 */ #define R1_OUT_OF_RANGE (1 << 31) /* er, c */ #define R1_ADDRESS_ERROR (1 << 30) /* erx, c */ diff --git a/mmc_cmds.c b/mmc_cmds.c index 49d3e32..bb0f022 100644 --- a/mmc_cmds.c +++ b/mmc_cmds.c @@ -2981,3 +2981,60 @@ out: return ret; #endif } + +int do_general_cmd_read(int nargs, char **argv) +{ + int dev_fd; + char *device; + char *endptr; + __u8 buf[512]; + __u32 arg = 0x01; + int ret = -EINVAL, i; + struct mmc_ioc_cmd idata; + + if (nargs != 2 && nargs != 3) { + fprintf(stderr, "Usage: gen_cmd read [arg]\n"); + exit(1); + } + + device = argv[1]; + dev_fd = open(device, O_RDWR); + if (dev_fd < 0) { + perror("device open failed"); + exit(1); + } + + /* arg is specified */ + if (nargs == 3) { + arg = strtol(argv[2], &endptr, 16); + if (errno != 0 || *endptr != '\0' || !(arg & 0x1)) { + fprintf(stderr, "Wrong ARG, it should be Hex number and bit0 must be 1\n"); + goto out; + } + } + + memset(&idata, 0, sizeof(idata)); + idata.write_flag = 0; + idata.opcode = MMC_GEN_CMD; + idata.arg = arg; + idata.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; + idata.blksz = 512; + idata.blocks = 1; + mmc_ioc_cmd_set_data(idata, buf); + + ret = ioctl(dev_fd, MMC_IOC_CMD, &idata); + if (ret) { + perror("ioctl"); + goto out; + } + + printf("Data:\n"); + for (i = 0; i < 512; i++) { + printf("%2x ", buf[i]); + if ((i + 1) % 16 == 0) + printf("\n"); + } +out: + close(dev_fd); + return ret; +} diff --git a/mmc_cmds.h b/mmc_cmds.h index 8331ab2..0f7c004 100644 --- a/mmc_cmds.h +++ b/mmc_cmds.h @@ -46,3 +46,4 @@ int do_read_scr(int argc, char **argv); int do_read_cid(int argc, char **argv); int do_read_csd(int argc, char **argv); int do_erase(int nargs, char **argv); +int do_general_cmd_read(int nargs, char **argv);