@@ -237,6 +237,13 @@ static struct Command commands[] = {
"secure-trim1 | secure-trim2 | trim \n",
NULL
},
+ { do_general_cmd_read, -2,
+ "gen_cmd read", "<arg> <device>\n"
+ "Send GEN_CMD (CMD56) with specific <arg> to <device> to read vendor\n"
+ "specific data. <arg> must be 32 bits length hex number prefixed with 0x/0X.\n\n"
+ "NOTE!: Because this option is only used to read, the bit0 in <arg> must be 1",
+ NULL
+ },
{ 0, 0, 0, 0 }
};
@@ -41,6 +41,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 */
@@ -2981,3 +2981,55 @@ out:
return ret;
#endif
}
+
+int do_general_cmd_read(int nargs, char **argv)
+{
+ int dev_fd;
+ __u8 buf[512];
+ __u32 arg;
+ char *device;
+ char *endptr;
+ int ret = -EINVAL, i;
+ struct mmc_ioc_cmd idata;
+
+ if (nargs != 3) {
+ fprintf(stderr, "Usage: gen_cmd read <arg> </path/to/mmcblkX>\n");
+ exit(1);
+ }
+
+ device = argv[2];
+ dev_fd = open(device, O_RDWR);
+ if (dev_fd < 0) {
+ perror("device open failed");
+ exit(1);
+ }
+ arg = strtol(argv[1], &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;
+}
@@ -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);