* [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
* [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
* 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
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).