All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.