diff options
author | Ben Gardiner <ben.l.gardiner@gmail.com> | 2013-09-19 11:14:29 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2013-09-25 22:12:00 -0400 |
commit | 196d0d29588867bed50cd28b8f03cbbb5e0e6608 (patch) | |
tree | 8ec673333e28634909cd1744fce20a074ba3c8e9 | |
parent | 4da1c0dc8bb295993d05beebc0a6132af9713322 (diff) | |
download | mmc-utils-196d0d29588867bed50cd28b8f03cbbb5e0e6608.tar.gz |
support setting the OTP write reliability settings
Signed-off-by: Ben Gardiner <ben.l.gardiner@gmail.com>
Signed-off-by: Chris Ball <cjb@laptop.org>
-rw-r--r-- | mmc.c | 5 | ||||
-rw-r--r-- | mmc_cmds.c | 62 | ||||
-rw-r--r-- | mmc_cmds.h | 1 |
3 files changed, 68 insertions, 0 deletions
@@ -75,6 +75,11 @@ static struct Command commands[] = { "Enable the enhanced user area for the <device>.\nDry-run only unless -y is passed.\nNOTE! This is a one-time programmable (unreversible) change.", NULL }, + { do_write_reliability_set, -2, + "write_reliability set", "<-y|-n> " "<partition> " "<device>\n" + "Enable write reliability per partition for the <device>.\nDry-run only unless -y is passed.\nNOTE! This is a one-time programmable (unreversible) change.", + NULL + }, { do_status_get, -1, "status get", "<device>\n" "Print the response to STATUS_SEND (CMD13).", @@ -632,6 +632,68 @@ int do_enh_area_set(int nargs, char **argv) return 0; } +int do_write_reliability_set(int nargs, char **argv) +{ + __u8 value; + __u8 ext_csd[512]; + int fd, ret; + + int dry_run = 1; + int partition; + char *device; + + CHECK(nargs != 4, "Usage: mmc write_reliability set <-y|-n> " + "<partition> </path/to/mmcblkX>\n", exit(1)); + + if (!strcmp("-y", argv[1])) + dry_run = 0; + + partition = strtol(argv[2], NULL, 10); + device = argv[3]; + + fd = open(device, O_RDWR); + if (fd < 0) { + perror("open"); + exit(1); + } + + ret = read_extcsd(fd, ext_csd); + if (ret) { + fprintf(stderr, "Could not read EXT_CSD from %s\n", device); + exit(1); + } + + /* assert not PARTITION_SETTING_COMPLETED */ + if (ext_csd[EXT_CSD_PARTITION_SETTING_COMPLETED]) + { + printf(" Device is already partitioned\n"); + exit(1); + } + + /* assert HS_CTRL_REL */ + if (!(ext_csd[EXT_CSD_WR_REL_PARAM] & HS_CTRL_REL)) { + printf("Cannot set write reliability parameters, WR_REL_SET is " + "read-only\n"); + exit(1); + } + + value = ext_csd[EXT_CSD_WR_REL_SET] | (1<<partition); + ret = write_extcsd_value(fd, EXT_CSD_WR_REL_SET, value); + if (ret) { + fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] in %s\n", + value, EXT_CSD_WR_REL_SET, device); + exit(1); + } + + printf("Done setting EXT_CSD_WR_REL_SET to 0x%02x on %s\n", + value, device); + + if (!set_partitioning_setting_completed(dry_run, device, fd)) + exit(1); + + return 0; +} + int do_read_extcsd(int nargs, char **argv) { __u8 ext_csd[512], ext_csd_rev, reg; @@ -27,3 +27,4 @@ int do_hwreset_dis(int nargs, char **argv); int do_sanitize(int nargs, char **argv); int do_status_get(int nargs, char **argv); int do_enh_area_set(int nargs, char **argv); +int do_write_reliability_set(int nargs, char **argv); |