linux-mmc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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).