* [PATCH 0/3] Write-reliability settings support @ 2013-09-19 15:14 Ben Gardiner 2013-09-19 15:14 ` [PATCH 1/3] extract PARTITION_SETTING_COMPLETE function Ben Gardiner ` (3 more replies) 0 siblings, 4 replies; 6+ messages in thread From: Ben Gardiner @ 2013-09-19 15:14 UTC (permalink / raw) To: cjb; +Cc: linux-mmc This series builds on top of d91d3698c6464a83b7c301eb84da109f9f94b54c It introduces * an extracted function for setting the PARTITION_SETTING_COMPLETE bit * a command for setting the write-reliability bits * pretty-printing the write-reliability bits from EXTCSD registers available also https://github.com/BenGardiner/mmc-utils/tree/features/reliable-write if it helps. Ben Gardiner (3): extract PARTITION_SETTING_COMPLETE function pretty print write reliability settings support setting the OTP write reliability settings mmc.c | 5 +++ mmc.h | 1 + mmc_cmds.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------- mmc_cmds.h | 1 + 4 files changed, 129 insertions(+), 21 deletions(-) -- 1.8.1.2 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/3] extract PARTITION_SETTING_COMPLETE function 2013-09-19 15:14 [PATCH 0/3] Write-reliability settings support Ben Gardiner @ 2013-09-19 15:14 ` Ben Gardiner 2015-02-26 18:50 ` Andrew Dyer 2013-09-19 15:14 ` [PATCH 2/3] pretty print write reliability settings Ben Gardiner ` (2 subsequent siblings) 3 siblings, 1 reply; 6+ messages in thread From: Ben Gardiner @ 2013-09-19 15:14 UTC (permalink / raw) To: cjb; +Cc: linux-mmc Extract a function which sets the OTP PARTITION_SETTING_COMPLETE bit; once this bit is set there are many other parameters in EXT_CSD which can no longer be set. Multiple OTP partition settings can be achieved by calling 'set' commands with '-n' on all except for the last. Signed-off-by: Ben Gardiner <ben.l.gardiner@gmail.com> --- mmc_cmds.c | 77 ++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 30 deletions(-) diff --git a/mmc_cmds.c b/mmc_cmds.c index ba4f9cf..5ea19ac 100644 --- a/mmc_cmds.c +++ b/mmc_cmds.c @@ -449,6 +449,51 @@ unsigned int get_hc_erase_grp_size(__u8 *ext_csd) return ext_csd[224]; } +int set_partitioning_setting_completed(int dry_run, const char * const device, + int fd) +{ + int ret; + + if (dry_run) { + fprintf(stderr, "NOT setting PARTITION_SETTING_COMPLETED\n"); + fprintf(stderr, "These changes will not take effect neither " + "now nor after a power cycle\n"); + return 1; + } + + fprintf(stderr, "setting OTP PARTITION_SETTING_COMPLETED!\n"); + ret = write_extcsd_value(fd, EXT_CSD_PARTITION_SETTING_COMPLETED, 0x1); + if (ret) { + fprintf(stderr, "Could not write 0x1 to " + "EXT_CSD[%d] in %s\n", + EXT_CSD_PARTITION_SETTING_COMPLETED, device); + return 1; + } + + __u32 response; + ret = send_status(fd, &response); + if (ret) { + fprintf(stderr, "Could not get response to SEND_STATUS " + "from %s\n", device); + return 1; + } + + if (response & R1_SWITCH_ERROR) { + fprintf(stderr, "Setting OTP PARTITION_SETTING_COMPLETED " + "failed on %s\n", device); + return 1; + } + + fprintf(stderr, "Setting OTP PARTITION_SETTING_COMPLETED on " + "%s SUCCESS\n", device); + fprintf(stderr, "Device power cycle needed for settings to " + "take effect.\n" + "Confirm that PARTITION_SETTING_COMPLETED bit is set " + "using 'extcsd read' after power cycle\n"); + + return 0; +} + int do_enh_area_set(int nargs, char **argv) { __u8 value; @@ -579,38 +624,10 @@ int do_enh_area_set(int nargs, char **argv) exit(1); } - if (dry_run) - { - fprintf(stderr, "NOT setting PARTITION_SETTING_COMPLETED\n"); - exit(1); - } + printf("Done setting ENH_USR area on %s\n", device); - fprintf(stderr, "setting OTP PARTITION_SETTING_COMPLETED!\n"); - ret = write_extcsd_value(fd, EXT_CSD_PARTITION_SETTING_COMPLETED, 0x1); - if (ret) { - fprintf(stderr, "Could not write 0x1 to " - "EXT_CSD[%d] in %s\n", - EXT_CSD_PARTITION_SETTING_COMPLETED, device); + if (!set_partitioning_setting_completed(dry_run, device, fd)) exit(1); - } - - __u32 response; - ret = send_status(fd, &response); - if (ret) { - fprintf(stderr, "Could not get response to SEND_STATUS from %s\n", device); - exit(1); - } - - if (response & R1_SWITCH_ERROR) - { - fprintf(stderr, "Setting ENH_USR area failed on %s\n", device); - exit(1); - } - - fprintf(stderr, "Setting ENH_USR area on %s SUCCESS\n", device); - fprintf(stderr, "Device power cycle needed for settings to take effect.\n" - "Confirm that PARTITION_SETTING_COMPLETED bit is set using 'extcsd read'" - "after power cycle\n"); return 0; } -- 1.8.1.2 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] extract PARTITION_SETTING_COMPLETE function 2013-09-19 15:14 ` [PATCH 1/3] extract PARTITION_SETTING_COMPLETE function Ben Gardiner @ 2015-02-26 18:50 ` Andrew Dyer 0 siblings, 0 replies; 6+ messages in thread From: Andrew Dyer @ 2015-02-26 18:50 UTC (permalink / raw) To: linux-mmc Ben Gardiner <ben.l.gardiner <at> gmail.com> writes: > > Extract a function which sets the OTP PARTITION_SETTING_COMPLETE > bit; once this bit is set there are many other parameters in > EXT_CSD which can no longer be set. > > Multiple OTP partition settings can be achieved by calling 'set' > commands with '-n' on all except for the last. > > Signed-off-by: Ben Gardiner <ben.l.gardiner <at> gmail.com> > --- > mmc_cmds.c | 77 ++++++++++++++++++++++++++++++++++++++--------------- --------- > 1 file changed, 47 insertions(+), 30 deletions(-) > > diff --git a/mmc_cmds.c b/mmc_cmds.c > index ba4f9cf..5ea19ac 100644 > --- a/mmc_cmds.c > +++ b/mmc_cmds.c > <at> <at> -449,6 +449,51 <at> <at> unsigned int get_hc_erase_grp_size(__u8 *ext_csd) > return ext_csd[224]; > } > > +int set_partitioning_setting_completed(int dry_run, const char * const device, > + int fd) > +{ > + int ret; > + > + if (dry_run) { > + fprintf(stderr, "NOT setting PARTITION_SETTING_COMPLETED\n"); > + fprintf(stderr, "These changes will not take effect neither " > + "now nor after a power cycle\n"); > + return 1; > + } > + > + fprintf(stderr, "setting OTP PARTITION_SETTING_COMPLETED!\n"); > + ret = write_extcsd_value(fd, EXT_CSD_PARTITION_SETTING_COMPLETED, 0x1); > + if (ret) { > + fprintf(stderr, "Could not write 0x1 to " > + "EXT_CSD[%d] in %s\n", > + EXT_CSD_PARTITION_SETTING_COMPLETED, device); > + return 1; > + } > + > + __u32 response; > + ret = send_status(fd, &response); > + if (ret) { > + fprintf(stderr, "Could not get response to SEND_STATUS " > + "from %s\n", device); > + return 1; > + } > + > + if (response & R1_SWITCH_ERROR) { > + fprintf(stderr, "Setting OTP PARTITION_SETTING_COMPLETED " > + "failed on %s\n", device); > + return 1; > + } > + > + fprintf(stderr, "Setting OTP PARTITION_SETTING_COMPLETED on " > + "%s SUCCESS\n", device); > + fprintf(stderr, "Device power cycle needed for settings to " > + "take effect.\n" > + "Confirm that PARTITION_SETTING_COMPLETED bit is set " > + "using 'extcsd read' after power cycle\n"); > + > + return 0; > +} > + > int do_enh_area_set(int nargs, char **argv) > { > __u8 value; > <at> <at> -579,38 +624,10 <at> <at> int do_enh_area_set(int nargs, char **argv) > exit(1); > } > > - if (dry_run) > - { > - fprintf(stderr, "NOT setting PARTITION_SETTING_COMPLETED\n"); > - exit(1); > - } > + printf("Done setting ENH_USR area on %s\n", device); > > - fprintf(stderr, "setting OTP PARTITION_SETTING_COMPLETED!\n"); > - ret = write_extcsd_value(fd, EXT_CSD_PARTITION_SETTING_COMPLETED, 0x1); > - if (ret) { > - fprintf(stderr, "Could not write 0x1 to " > - "EXT_CSD[%d] in %s\n", > - EXT_CSD_PARTITION_SETTING_COMPLETED, device); > + if (!set_partitioning_setting_completed(dry_run, device, fd)) > exit(1); > - } > - > - __u32 response; > - ret = send_status(fd, &response); > - if (ret) { > - fprintf(stderr, "Could not get response to SEND_STATUS from %s\n", device); > - exit(1); > - } > - > - if (response & R1_SWITCH_ERROR) > - { > - fprintf(stderr, "Setting ENH_USR area failed on %s\n", device); > - exit(1); > - } > - > - fprintf(stderr, "Setting ENH_USR area on %s SUCCESS\n", device); > - fprintf(stderr, "Device power cycle needed for settings to take effect.\n" > - "Confirm that PARTITION_SETTING_COMPLETED bit is set using 'extcsd read'" > - "after power cycle\n"); > > return 0; > } The program return code looks wrong with this patch. If I do mmc write_reliability set -n 0 /dev/mmcblk0; echo $? mmc write_reliability set -y 0 /dev/mmcblk0; echo $? the first instance returns a 0, the second a 1. The following change fixes this by changing set_partitioning_setting completed() to only return one on an error and removing the inversions in the if tests. mmc_cmds.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mmc_cmds.c b/mmc_cmds.c index cea943f..c4efffe 100644 --- a/mmc_cmds.c +++ b/mmc_cmds.c @@ -462,7 +462,7 @@ int set_partitioning_setting_completed(int dry_run, const char * const device, fprintf(stderr, "NOT setting PARTITION_SETTING_COMPLETED\n"); fprintf(stderr, "These changes will not take effect neither " "now nor after a power cycle\n"); - return 1; + return 0; } fprintf(stderr, "setting OTP PARTITION_SETTING_COMPLETED!\n"); @@ -630,7 +630,7 @@ int do_enh_area_set(int nargs, char **argv) printf("Done setting ENH_USR area on %s\n", device); - if (!set_partitioning_setting_completed(dry_run, device, fd)) + if (set_partitioning_setting_completed(dry_run, device, fd)) exit(1); return 0; @@ -692,7 +692,7 @@ int do_write_reliability_set(int nargs, char **argv) 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)) + if (set_partitioning_setting_completed(dry_run, device, fd)) exit(1); return 0; -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/3] pretty print write reliability settings 2013-09-19 15:14 [PATCH 0/3] Write-reliability settings support Ben Gardiner 2013-09-19 15:14 ` [PATCH 1/3] extract PARTITION_SETTING_COMPLETE function Ben Gardiner @ 2013-09-19 15:14 ` Ben Gardiner 2013-09-19 15:14 ` [PATCH 3/3] support setting the OTP " Ben Gardiner 2013-09-26 2:18 ` [PATCH 0/3] Write-reliability settings support Chris Ball 3 siblings, 0 replies; 6+ messages in thread From: Ben Gardiner @ 2013-09-19 15:14 UTC (permalink / raw) To: cjb; +Cc: linux-mmc Signed-off-by: Ben Gardiner <ben.l.gardiner@gmail.com> --- mmc.h | 1 + mmc_cmds.c | 26 ++++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/mmc.h b/mmc.h index ad07b44..72baab8 100644 --- a/mmc.h +++ b/mmc.h @@ -46,6 +46,7 @@ #define EXT_CSD_PART_CONFIG 179 #define EXT_CSD_ERASE_GROUP_DEF 175 #define EXT_CSD_BOOT_WP 173 +#define EXT_CSD_WR_REL_SET 167 #define EXT_CSD_WR_REL_PARAM 166 #define EXT_CSD_SANITIZE_START 165 #define EXT_CSD_BKOPS_EN 163 /* R/W */ diff --git a/mmc_cmds.c b/mmc_cmds.c index 5ea19ac..7874b23 100644 --- a/mmc_cmds.c +++ b/mmc_cmds.c @@ -917,10 +917,32 @@ int do_read_extcsd(int nargs, char **argv) /* A441]: reserved [170] */ printf("FW configuration [FW_CONFIG]: 0x%02x\n", ext_csd[169]); printf("RPMB Size [RPMB_SIZE_MULT]: 0x%02x\n", ext_csd[168]); + + reg = ext_csd[EXT_CSD_WR_REL_SET]; + const char * const fast = "existing data is at risk if a power " + "failure occurs during a write operation"; + const char * const reliable = "the device protects existing " + "data if a power failure occurs during a write " + "operation"; printf("Write reliability setting register" - " [WR_REL_SET]: 0x%02x\n", ext_csd[167]); + " [WR_REL_SET]: 0x%02x\n", reg); + + printf(" user area: %s\n", reg & (1<<0) ? reliable : fast); + int i; + for (i = 1; i <= 4; i++) { + printf(" partition %d: %s\n", i, + reg & (1<<i) ? reliable : fast); + } + + reg = ext_csd[EXT_CSD_WR_REL_PARAM]; printf("Write reliability parameter register" - " [WR_REL_PARAM]: 0x%02x\n", ext_csd[166]); + " [WR_REL_PARAM]: 0x%02x\n", reg); + if (reg & 0x01) + printf(" Device supports writing EXT_CSD_WR_REL_SET\n"); + if (reg & 0x04) + printf(" Device supports the enhanced def. of reliable " + "write\n"); + /* sanitize_start ext_csd[165]]: not readable * bkops_start ext_csd[164]]: only writable */ printf("Enable background operations handshake" -- 1.8.1.2 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/3] support setting the OTP write reliability settings 2013-09-19 15:14 [PATCH 0/3] Write-reliability settings support Ben Gardiner 2013-09-19 15:14 ` [PATCH 1/3] extract PARTITION_SETTING_COMPLETE function Ben Gardiner 2013-09-19 15:14 ` [PATCH 2/3] pretty print write reliability settings Ben Gardiner @ 2013-09-19 15:14 ` Ben Gardiner 2013-09-26 2:18 ` [PATCH 0/3] Write-reliability settings support Chris Ball 3 siblings, 0 replies; 6+ messages in thread From: Ben Gardiner @ 2013-09-19 15:14 UTC (permalink / raw) To: cjb; +Cc: linux-mmc Signed-off-by: Ben Gardiner <ben.l.gardiner@gmail.com> --- mmc.c | 5 +++++ mmc_cmds.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mmc_cmds.h | 1 + 3 files changed, 68 insertions(+) diff --git a/mmc.c b/mmc.c index 725b842..926e92f 100644 --- a/mmc.c +++ b/mmc.c @@ -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).", diff --git a/mmc_cmds.c b/mmc_cmds.c index 7874b23..079f322 100644 --- a/mmc_cmds.c +++ b/mmc_cmds.c @@ -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; diff --git a/mmc_cmds.h b/mmc_cmds.h index fa347f5..f06cc10 100644 --- a/mmc_cmds.h +++ b/mmc_cmds.h @@ -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); -- 1.8.1.2 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 0/3] Write-reliability settings support 2013-09-19 15:14 [PATCH 0/3] Write-reliability settings support Ben Gardiner ` (2 preceding siblings ...) 2013-09-19 15:14 ` [PATCH 3/3] support setting the OTP " Ben Gardiner @ 2013-09-26 2:18 ` Chris Ball 3 siblings, 0 replies; 6+ messages in thread From: Chris Ball @ 2013-09-26 2:18 UTC (permalink / raw) To: Ben Gardiner; +Cc: linux-mmc Hi Ben, On Thu, Sep 19 2013, Ben Gardiner wrote: > This series builds on top of > d91d3698c6464a83b7c301eb84da109f9f94b54c > > It introduces > * an extracted function for setting the PARTITION_SETTING_COMPLETE bit > * a command for setting the write-reliability bits > * pretty-printing the write-reliability bits from EXTCSD registers > > available also https://github.com/BenGardiner/mmc-utils/tree/features/reliable-write > if it helps. > > Ben Gardiner (3): > extract PARTITION_SETTING_COMPLETE function > pretty print write reliability settings > support setting the OTP write reliability settings > > mmc.c | 5 +++ > mmc.h | 1 + > mmc_cmds.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------- > mmc_cmds.h | 1 + > 4 files changed, 129 insertions(+), 21 deletions(-) I've pushed all three patches to mmc-utils now. Thanks! - Chris. -- Chris Ball <cjb@laptop.org> <http://printf.net/> ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2015-02-26 18:55 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-09-19 15:14 [PATCH 0/3] Write-reliability settings support Ben Gardiner 2013-09-19 15:14 ` [PATCH 1/3] extract PARTITION_SETTING_COMPLETE function Ben Gardiner 2015-02-26 18:50 ` Andrew Dyer 2013-09-19 15:14 ` [PATCH 2/3] pretty print write reliability settings Ben Gardiner 2013-09-19 15:14 ` [PATCH 3/3] support setting the OTP " Ben Gardiner 2013-09-26 2:18 ` [PATCH 0/3] Write-reliability settings support Chris Ball
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).