linux-mmc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] cross-compiling, SEND_STATUS, pretty-printing and enhanced user area
@ 2013-05-30 21:12 Ben Gardiner
  2013-05-30 21:12 ` [PATCH 1/8] allow environment and command-line supplied make vars Ben Gardiner
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Ben Gardiner @ 2013-05-30 21:12 UTC (permalink / raw)
  To: cjb; +Cc: linux-mmc

This series builds on top of f74dfe23cd00894aa9f235374468e05acb793e17.

It introduces:
 * some Makefile changes to make cross-compiling easier
 * SEND_STATUS
 * 'pretty'-printing sizes of some fields in KiB
 * setting the OTP enhanced user area parameters

available also https://github.com/BenGardiner/mmc-utils/commits/features/enh-programming
if it helps.

Ben Gardiner (8):
  allow environment and command-line supplied make vars
  extract definitions for EXT_CSD register EXT_CSD_PARTITIONING_SUPPORT
  extract definitions for EXT_CSD register PARTITION_SETTING_COMPLETED
    and pretty-print
  Support SEND_STATUS command
  fix printing ENH_START_ADDR
  report if card is block-addressed and effect on ENH_START_ADDR
  print KiB sizes for some fields
  support setting the OTP enhanced user area parameters

 Makefile   |   10 +-
 mmc.c      |   10 ++
 mmc.h      |   20 ++++
 mmc_cmds.c |  307 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 mmc_cmds.h |    2 +
 5 files changed, 328 insertions(+), 21 deletions(-)

--
1.7.3.5


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/8] allow environment and command-line supplied make vars
  2013-05-30 21:12 [PATCH 0/8] cross-compiling, SEND_STATUS, pretty-printing and enhanced user area Ben Gardiner
@ 2013-05-30 21:12 ` Ben Gardiner
  2013-05-30 21:12 ` [PATCH 2/8] extract definitions for EXT_CSD register EXT_CSD_PARTITIONING_SUPPORT Ben Gardiner
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ben Gardiner @ 2013-05-30 21:12 UTC (permalink / raw)
  To: cjb; +Cc: linux-mmc

Most useful when cross-compiling.

Signed-off-by: Ben Gardiner <bengardiner@nanometrics.ca>
---
 Makefile |   10 ++++++----
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/Makefile b/Makefile
index f03f131..ae846e2 100644
--- a/Makefile
+++ b/Makefile
@@ -1,12 +1,14 @@
-CC = gcc
+CC ?= gcc
 AM_CFLAGS = -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2
-CFLAGS = -g -O2
+CFLAGS ?= -g -O2
 objects = mmc.o mmc_cmds.o
 
-CHECKFLAGS= -Wall -Werror -Wuninitialized -Wundef
+CHECKFLAGS = -Wall -Werror -Wuninitialized -Wundef
 
 DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
 
+override CFLAGS := $(CHECKFLAGS) $(AM_CFLAGS) $(CFLAGS)
+
 INSTALL = install
 prefix ?= /usr/local
 bindir = $(prefix)/bin
@@ -26,7 +28,7 @@ all: $(progs) manpages
 ifdef C
 	$(check) $<
 endif
-	$(CC) $(CHECKFLAGS) $(AM_CFLAGS) $(DEPFLAGS) $(CFLAGS) -c $<
+	$(CC) $(CPPFLAGS) $(CFLAGS) $(DEPFLAGS) -c $<
 
 mmc: $(objects)
 	$(CC) $(CFLAGS) -o $@ $(objects) $(LDFLAGS) $(LIBS)
-- 
1.7.3.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/8] extract definitions for EXT_CSD register EXT_CSD_PARTITIONING_SUPPORT
  2013-05-30 21:12 [PATCH 0/8] cross-compiling, SEND_STATUS, pretty-printing and enhanced user area Ben Gardiner
  2013-05-30 21:12 ` [PATCH 1/8] allow environment and command-line supplied make vars Ben Gardiner
@ 2013-05-30 21:12 ` Ben Gardiner
  2013-05-30 21:12 ` [PATCH 3/8] extract definitions for EXT_CSD register PARTITION_SETTING_COMPLETED and pretty-print Ben Gardiner
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ben Gardiner @ 2013-05-30 21:12 UTC (permalink / raw)
  To: cjb; +Cc: linux-mmc

Signed-off-by: Ben Gardiner <bengardiner@nanometrics.ca>
---
 mmc.h      |    3 +++
 mmc_cmds.c |    6 +++---
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/mmc.h b/mmc.h
index c863751..47ef8ea 100644
--- a/mmc.h
+++ b/mmc.h
@@ -40,6 +40,7 @@
 #define EXT_CSD_WR_REL_PARAM		166
 #define EXT_CSD_BKOPS_EN		163	/* R/W */
 #define EXT_CSD_RST_N_FUNCTION		162	/* R/W */
+#define EXT_CSD_PARTITIONING_SUPPORT	160	/* RO */
 #define EXT_CSD_NATIVE_SECTOR_SIZE	63 /* R */
 #define EXT_CSD_USE_NATIVE_SECTOR	62 /* R/W */
 #define EXT_CSD_DATA_SECTOR_SIZE	61 /* R */
@@ -79,6 +80,8 @@
 #define EXT_CSD_PART_CONFIG_ACC_BOOT1	  (0x2)
 #define EXT_CSD_PART_CONFIG_ACC_USER_AREA (0x7)
 #define EXT_CSD_PART_CONFIG_ACC_ACK	  (0x40)
+#define EXT_CSD_PARTITIONING_EN		(1<<0)
+#define EXT_CSD_ENH_ATTRIBUTE_EN	(1<<1)
 
 /* From kernel linux/mmc/core.h */
 #define MMC_RSP_PRESENT	(1 << 0)
diff --git a/mmc_cmds.c b/mmc_cmds.c
index b407f65..8cf6e89 100644
--- a/mmc_cmds.c
+++ b/mmc_cmds.c
@@ -670,14 +670,14 @@ int do_read_extcsd(int nargs, char **argv)
 		printf("H/W reset function"
 			" [RST_N_FUNCTION]: 0x%02x\n", ext_csd[162]);
 		printf("HPI management [HPI_MGMT]: 0x%02x\n", ext_csd[161]);
-		reg = ext_csd[160];
+		reg = ext_csd[EXT_CSD_PARTITIONING_SUPPORT];
 		printf("Partitioning Support [PARTITIONING_SUPPORT]: 0x%02x\n",
 			reg);
-		if (reg & 0x1)
+		if (reg & EXT_CSD_PARTITIONING_EN)
 			printf(" Device support partitioning feature\n");
 		else
 			printf(" Device NOT support partitioning feature\n");
-		if (reg & 0x2)
+		if (reg & EXT_CSD_ENH_ATTRIBUTE_EN)
 			printf(" Device can have enhanced tech.\n");
 		else
 			printf(" Device cannot have enhanced tech.\n");
-- 
1.7.3.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/8] extract definitions for EXT_CSD register PARTITION_SETTING_COMPLETED and pretty-print
  2013-05-30 21:12 [PATCH 0/8] cross-compiling, SEND_STATUS, pretty-printing and enhanced user area Ben Gardiner
  2013-05-30 21:12 ` [PATCH 1/8] allow environment and command-line supplied make vars Ben Gardiner
  2013-05-30 21:12 ` [PATCH 2/8] extract definitions for EXT_CSD register EXT_CSD_PARTITIONING_SUPPORT Ben Gardiner
@ 2013-05-30 21:12 ` Ben Gardiner
  2013-05-30 21:12 ` [PATCH 4/8] Support SEND_STATUS command Ben Gardiner
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ben Gardiner @ 2013-05-30 21:12 UTC (permalink / raw)
  To: cjb; +Cc: linux-mmc

Signed-off-by: Ben Gardiner <bengardiner@nanometrics.ca>
---
 mmc.h      |    1 +
 mmc_cmds.c |    8 +++++++-
 2 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/mmc.h b/mmc.h
index 47ef8ea..3420d7b 100644
--- a/mmc.h
+++ b/mmc.h
@@ -41,6 +41,7 @@
 #define EXT_CSD_BKOPS_EN		163	/* R/W */
 #define EXT_CSD_RST_N_FUNCTION		162	/* R/W */
 #define EXT_CSD_PARTITIONING_SUPPORT	160	/* RO */
+#define EXT_CSD_PARTITION_SETTING_COMPLETED	155	/* R/W */
 #define EXT_CSD_NATIVE_SECTOR_SIZE	63 /* R */
 #define EXT_CSD_USE_NATIVE_SECTOR	62 /* R/W */
 #define EXT_CSD_DATA_SECTOR_SIZE	61 /* R */
diff --git a/mmc_cmds.c b/mmc_cmds.c
index 8cf6e89..dd7498e 100644
--- a/mmc_cmds.c
+++ b/mmc_cmds.c
@@ -687,9 +687,15 @@ int do_read_extcsd(int nargs, char **argv)
 			    ext_csd[157]);
 		printf("Partitions attribute [PARTITIONS_ATTRIBUTE]: 0x%02x\n",
 			ext_csd[156]);
+		reg = ext_csd[EXT_CSD_PARTITION_SETTING_COMPLETED];
 		printf("Partitioning Setting"
 			" [PARTITION_SETTING_COMPLETED]: 0x%02x\n",
-			ext_csd[155]);
+			reg);
+		if(reg)
+			printf(" Device partition setting complete\n");
+		else
+			printf(" Device partition setting NOT complete\n");
+
 		printf("General Purpose Partition Size\n"
 			" [GP_SIZE_MULT_4]: 0x%06x\n", (ext_csd[154] << 16) |
 			(ext_csd[153] << 8) | ext_csd[152]);
-- 
1.7.3.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/8] Support SEND_STATUS command
  2013-05-30 21:12 [PATCH 0/8] cross-compiling, SEND_STATUS, pretty-printing and enhanced user area Ben Gardiner
                   ` (2 preceding siblings ...)
  2013-05-30 21:12 ` [PATCH 3/8] extract definitions for EXT_CSD register PARTITION_SETTING_COMPLETED and pretty-print Ben Gardiner
@ 2013-05-30 21:12 ` Ben Gardiner
  2013-05-30 21:12 ` [PATCH 5/8] fix printing ENH_START_ADDR Ben Gardiner
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ben Gardiner @ 2013-05-30 21:12 UTC (permalink / raw)
  To: cjb; +Cc: linux-mmc

mmc status get </path/to/mmcblkX>

Signed-off-by: Ben Gardiner <bengardiner@nanometrics.ca>
---
 mmc.c      |    5 +++++
 mmc.h      |    2 ++
 mmc_cmds.c |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 mmc_cmds.h |    1 +
 4 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/mmc.c b/mmc.c
index a2de863..c22ce9e 100644
--- a/mmc.c
+++ b/mmc.c
@@ -70,6 +70,11 @@ static struct Command commands[] = {
 		"Set the eMMC data sector size to 4KB by disabling emulation on\n<device>.",
 	  NULL
 	},
+	{ do_status_get, -1,
+	  "status get", "<device>\n"
+	  "Print the response to STATUS_SEND (CMD13).",
+	  NULL
+	},
 	{ do_write_boot_en, -3,
 	  "bootpart enable", "<boot_partition> " "<send_ack> " "<device>\n"
 		"Enable the boot partition for the <device>.\nTo receive acknowledgment of boot from the card set <send_ack>\nto 1, else set it to 0.",
diff --git a/mmc.h b/mmc.h
index 3420d7b..3577f42 100644
--- a/mmc.h
+++ b/mmc.h
@@ -24,6 +24,8 @@
 /* From kernel linux/mmc/mmc.h */
 #define MMC_SWITCH		6	/* ac	[31:0] See below	R1b */
 #define MMC_SEND_EXT_CSD	8	/* adtc				R1  */
+#define MMC_SEND_STATUS		13	/* ac   [31:16] RCA        R1  */
+#define R1_SWITCH_ERROR   (1 << 7)  /* sx, c */
 #define MMC_SWITCH_MODE_WRITE_BYTE	0x03	/* Set target to value */
 
 /*
diff --git a/mmc_cmds.c b/mmc_cmds.c
index dd7498e..a2ccc1d 100644
--- a/mmc_cmds.c
+++ b/mmc_cmds.c
@@ -72,6 +72,25 @@ int write_extcsd_value(int fd, __u8 index, __u8 value)
 	return ret;
 }
 
+int send_status(int fd, __u32 *response)
+{
+	int ret = 0;
+	struct mmc_ioc_cmd idata;
+
+	memset(&idata, 0, sizeof(idata));
+	idata.opcode = MMC_SEND_STATUS;
+	idata.arg = (1 << 16);
+	idata.flags = MMC_RSP_R1 | MMC_CMD_AC;
+
+	ret = ioctl(fd, MMC_IOC_CMD, &idata);
+	if (ret)
+	perror("ioctl");
+
+	*response = idata.response[0];
+
+	return ret;
+}
+
 void print_writeprotect_status(__u8 *ext_csd)
 {
 	__u8 reg;
@@ -377,6 +396,34 @@ int do_write_bkops_en(int nargs, char **argv)
 	return ret;
 }
 
+int do_status_get(int nargs, char **argv)
+{
+	__u32 response;
+	int fd, ret;
+	char *device;
+
+	CHECK(nargs != 2, "Usage: mmc status get </path/to/mmcblkX>\n",
+		exit(1));
+
+	device = argv[1];
+
+	fd = open(device, O_RDWR);
+	if (fd < 0) {
+		perror("open");
+		exit(1);
+	}
+
+	ret = send_status(fd, &response);
+	if (ret) {
+		fprintf(stderr, "Could not read response to SEND_STATUS from %s\n", device);
+		exit(1);
+	}
+
+	printf("SEND_STATUS response: 0x%08x\n", response);
+
+	return ret;
+}
+
 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 e52d622..3a754bf 100644
--- a/mmc_cmds.h
+++ b/mmc_cmds.h
@@ -24,3 +24,4 @@ int do_write_boot_en(int nargs, char **argv);
 int do_write_bkops_en(int nargs, char **argv);
 int do_hwreset_en(int nargs, char **argv);
 int do_hwreset_dis(int nargs, char **argv);
+int do_status_get(int nargs, char **argv);
-- 
1.7.3.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/8] fix printing ENH_START_ADDR
  2013-05-30 21:12 [PATCH 0/8] cross-compiling, SEND_STATUS, pretty-printing and enhanced user area Ben Gardiner
                   ` (3 preceding siblings ...)
  2013-05-30 21:12 ` [PATCH 4/8] Support SEND_STATUS command Ben Gardiner
@ 2013-05-30 21:12 ` Ben Gardiner
  2013-05-30 21:12 ` [PATCH 6/8] report if card is block-addressed and effect on ENH_START_ADDR Ben Gardiner
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ben Gardiner @ 2013-05-30 21:12 UTC (permalink / raw)
  To: cjb; +Cc: linux-mmc

The enhanced user area start field is 4 bytes long
according to the eMMC 4.41 spec.

Signed-off-by: Ben Gardiner <bengardiner@nanometrics.ca>
---
 mmc.h      |    4 ++++
 mmc_cmds.c |    8 ++++++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/mmc.h b/mmc.h
index 3577f42..fa46c3a 100644
--- a/mmc.h
+++ b/mmc.h
@@ -44,6 +44,10 @@
 #define EXT_CSD_RST_N_FUNCTION		162	/* R/W */
 #define EXT_CSD_PARTITIONING_SUPPORT	160	/* RO */
 #define EXT_CSD_PARTITION_SETTING_COMPLETED	155	/* R/W */
+#define EXT_CSD_ENH_START_ADDR_3	139
+#define EXT_CSD_ENH_START_ADDR_2	138
+#define EXT_CSD_ENH_START_ADDR_1	137
+#define EXT_CSD_ENH_START_ADDR_0	136
 #define EXT_CSD_NATIVE_SECTOR_SIZE	63 /* R */
 #define EXT_CSD_USE_NATIVE_SECTOR	62 /* R/W */
 #define EXT_CSD_DATA_SECTOR_SIZE	61 /* R */
diff --git a/mmc_cmds.c b/mmc_cmds.c
index a2ccc1d..21d5b4f 100644
--- a/mmc_cmds.c
+++ b/mmc_cmds.c
@@ -756,9 +756,13 @@ int do_read_extcsd(int nargs, char **argv)
 		printf("Enhanced User Data Area Size"
 			" [ENH_SIZE_MULT]: 0x%06x\n", (ext_csd[142] << 16) |
 			(ext_csd[141] << 8) | ext_csd[140]);
+
+		reg =	(ext_csd[EXT_CSD_ENH_START_ADDR_3] << 24) |
+			(ext_csd[EXT_CSD_ENH_START_ADDR_2] << 16) |
+			(ext_csd[EXT_CSD_ENH_START_ADDR_1] << 8) |
+			ext_csd[EXT_CSD_ENH_START_ADDR_0];
 		printf("Enhanced User Data Start Address"
-			" [ENH_START_ADDR]: 0x%06x\n", (ext_csd[139] << 16) |
-			   (ext_csd[138] << 8) | ext_csd[137]);
+			" [ENH_START_ADDR]: 0x%06x\n", reg);
 
 		/* A441]: reserved [135] */
 		printf("Bad Block Management mode"
-- 
1.7.3.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 6/8] report if card is block-addressed and effect on ENH_START_ADDR
  2013-05-30 21:12 [PATCH 0/8] cross-compiling, SEND_STATUS, pretty-printing and enhanced user area Ben Gardiner
                   ` (4 preceding siblings ...)
  2013-05-30 21:12 ` [PATCH 5/8] fix printing ENH_START_ADDR Ben Gardiner
@ 2013-05-30 21:12 ` Ben Gardiner
  2013-05-30 21:12 ` [PATCH 7/8] print KiB sizes for some fields Ben Gardiner
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Ben Gardiner @ 2013-05-30 21:12 UTC (permalink / raw)
  To: cjb; +Cc: linux-mmc

Signed-off-by: Ben Gardiner <bengardiner@nanometrics.ca>
---
 mmc.h      |    4 ++++
 mmc_cmds.c |   28 +++++++++++++++++++++++++---
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/mmc.h b/mmc.h
index fa46c3a..bedde31 100644
--- a/mmc.h
+++ b/mmc.h
@@ -35,6 +35,10 @@
 #define EXT_CSD_HPI_FEATURE		503
 #define EXT_CSD_BKOPS_SUPPORT		502	/* RO */
 #define EXT_CSD_BOOT_INFO		228	/* R/W */
+#define EXT_CSD_SEC_COUNT_3		215
+#define EXT_CSD_SEC_COUNT_2		214
+#define EXT_CSD_SEC_COUNT_1		213
+#define EXT_CSD_SEC_COUNT_0		212
 #define EXT_CSD_PART_SWITCH_TIME	199
 #define EXT_CSD_BOOT_CFG		179
 #define EXT_CSD_PART_CONFIG		179
diff --git a/mmc_cmds.c b/mmc_cmds.c
index 21d5b4f..149c904 100644
--- a/mmc_cmds.c
+++ b/mmc_cmds.c
@@ -424,6 +424,21 @@ int do_status_get(int nargs, char **argv)
 	return ret;
 }
 
+unsigned int get_sector_count(__u8 *ext_csd)
+{
+	return (ext_csd[EXT_CSD_SEC_COUNT_3] << 24) |
+	(ext_csd[EXT_CSD_SEC_COUNT_2] << 16) |
+	(ext_csd[EXT_CSD_SEC_COUNT_1] << 8)  |
+	ext_csd[EXT_CSD_SEC_COUNT_0];
+}
+
+int is_blockaddresed(__u8 *ext_csd)
+{
+	unsigned int sectors = get_sector_count(ext_csd);
+
+	return (sectors > (2u * 1024 * 1024 * 1024) / 512);
+}
+
 int do_read_extcsd(int nargs, char **argv)
 {
 	__u8 ext_csd[512], ext_csd_rev, reg;
@@ -591,9 +606,14 @@ int do_read_extcsd(int nargs, char **argv)
 	/* A441/A43: reserved [218] */
 	printf("Sleep/awake timeout [S_A_TIMEOUT: 0x%02x]\n", ext_csd[217]);
 	/* A441/A43: reserved [216] */
-	printf("Sector Count [SEC_COUNT: 0x%08x]\n", (ext_csd[215] << 24) |
-		      (ext_csd[214] << 16) | (ext_csd[213] << 8)  |
-		      ext_csd[212]);
+
+	unsigned int sectors =	get_sector_count(ext_csd);
+	printf("Sector Count [SEC_COUNT: 0x%08x]\n", sectors);
+	if (is_blockaddresed(ext_csd))
+		printf(" Device is block-addressed\n");
+	else
+		printf(" Device is NOT block-addressed\n");
+
 	/* A441/A43: reserved [211] */
 	printf("Minimum Write Performance for 8bit:\n");
 	printf(" [MIN_PERF_W_8_52: 0x%02x]\n", ext_csd[210]);
@@ -763,6 +783,8 @@ int do_read_extcsd(int nargs, char **argv)
 			ext_csd[EXT_CSD_ENH_START_ADDR_0];
 		printf("Enhanced User Data Start Address"
 			" [ENH_START_ADDR]: 0x%06x\n", reg);
+		printf(" i.e. %lu bytes offset\n", (is_blockaddresed(ext_csd) ?
+				1l : 512l) * reg);
 
 		/* A441]: reserved [135] */
 		printf("Bad Block Management mode"
-- 
1.7.3.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 7/8] print KiB sizes for some fields
  2013-05-30 21:12 [PATCH 0/8] cross-compiling, SEND_STATUS, pretty-printing and enhanced user area Ben Gardiner
                   ` (5 preceding siblings ...)
  2013-05-30 21:12 ` [PATCH 6/8] report if card is block-addressed and effect on ENH_START_ADDR Ben Gardiner
@ 2013-05-30 21:12 ` Ben Gardiner
  2013-05-30 21:12 ` [PATCH 8/8] support setting the OTP enhanced user area parameters Ben Gardiner
  2013-06-27 15:11 ` [PATCH 0/8] cross-compiling, SEND_STATUS, pretty-printing and enhanced user area Chris Ball
  8 siblings, 0 replies; 10+ messages in thread
From: Ben Gardiner @ 2013-05-30 21:12 UTC (permalink / raw)
  To: cjb; +Cc: linux-mmc

Signed-off-by: Ben Gardiner <bengardiner@nanometrics.ca>
---
 mmc.h      |    3 +++
 mmc_cmds.c |   40 ++++++++++++++++++++++++++++++++++------
 2 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/mmc.h b/mmc.h
index bedde31..5385e0e 100644
--- a/mmc.h
+++ b/mmc.h
@@ -48,6 +48,9 @@
 #define EXT_CSD_RST_N_FUNCTION		162	/* R/W */
 #define EXT_CSD_PARTITIONING_SUPPORT	160	/* RO */
 #define EXT_CSD_PARTITION_SETTING_COMPLETED	155	/* R/W */
+#define EXT_CSD_ENH_SIZE_MULT_2		142
+#define EXT_CSD_ENH_SIZE_MULT_1		141
+#define EXT_CSD_ENH_SIZE_MULT_0		140
 #define EXT_CSD_ENH_START_ADDR_3	139
 #define EXT_CSD_ENH_START_ADDR_2	138
 #define EXT_CSD_ENH_START_ADDR_1	137
diff --git a/mmc_cmds.c b/mmc_cmds.c
index 149c904..37bb211 100644
--- a/mmc_cmds.c
+++ b/mmc_cmds.c
@@ -439,6 +439,16 @@ int is_blockaddresed(__u8 *ext_csd)
 	return (sectors > (2u * 1024 * 1024 * 1024) / 512);
 }
 
+unsigned int get_hc_wp_grp_size(__u8 *ext_csd)
+{
+	return ext_csd[221];
+}
+
+unsigned int get_hc_erase_grp_size(__u8 *ext_csd)
+{
+	return ext_csd[224];
+}
+
 int do_read_extcsd(int nargs, char **argv)
 {
 	__u8 ext_csd[512], ext_csd_rev, reg;
@@ -593,14 +603,22 @@ int do_read_extcsd(int nargs, char **argv)
 	/* A441/A43: reserved [227] */
 	printf("Boot partition size [BOOT_SIZE_MULTI: 0x%02x]\n", ext_csd[226]);
 	printf("Access size [ACC_SIZE: 0x%02x]\n", ext_csd[225]);
+
+	reg = get_hc_erase_grp_size(ext_csd);
 	printf("High-capacity erase unit size [HC_ERASE_GRP_SIZE: 0x%02x]\n",
-		ext_csd[224]);
+		reg);
+	printf(" i.e. %u KiB\n", 512 * reg);
+
 	printf("High-capacity erase timeout [ERASE_TIMEOUT_MULT: 0x%02x]\n",
 		ext_csd[223]);
 	printf("Reliable write sector count [REL_WR_SEC_C: 0x%02x]\n",
 		ext_csd[222]);
+
+	reg = get_hc_wp_grp_size(ext_csd);
 	printf("High-capacity W protect group size [HC_WP_GRP_SIZE: 0x%02x]\n",
-		ext_csd[221]);
+		reg);
+	printf(" i.e. %lu KiB\n", 512l * get_hc_erase_grp_size(ext_csd) * reg);
+
 	printf("Sleep current (VCC) [S_C_VCC: 0x%02x]\n", ext_csd[220]);
 	printf("Sleep current (VCCQ) [S_C_VCCQ: 0x%02x]\n", ext_csd[219]);
 	/* A441/A43: reserved [218] */
@@ -749,9 +767,14 @@ int do_read_extcsd(int nargs, char **argv)
 		else
 			printf(" Device cannot have enhanced tech.\n");
 
+		reg = (ext_csd[159] << 16) | (ext_csd[158] << 8) |
+			ext_csd[157];
 		printf("Max Enhanced Area Size [MAX_ENH_SIZE_MULT]: 0x%06x\n",
-			   (ext_csd[159] << 16) | (ext_csd[158] << 8) |
-			    ext_csd[157]);
+			   reg);
+		unsigned int wp_sz = get_hc_wp_grp_size(ext_csd);
+		unsigned int erase_sz = get_hc_erase_grp_size(ext_csd);
+		printf(" i.e. %lu KiB\n", 512l * reg * wp_sz * erase_sz);
+
 		printf("Partitions attribute [PARTITIONS_ATTRIBUTE]: 0x%02x\n",
 			ext_csd[156]);
 		reg = ext_csd[EXT_CSD_PARTITION_SETTING_COMPLETED];
@@ -773,9 +796,14 @@ int do_read_extcsd(int nargs, char **argv)
 		printf(" [GP_SIZE_MULT_1]: 0x%06x\n", (ext_csd[145] << 16) |
 			   (ext_csd[144] << 8) | ext_csd[143]);
 
+		reg =	(ext_csd[EXT_CSD_ENH_SIZE_MULT_2] << 16) |
+			(ext_csd[EXT_CSD_ENH_SIZE_MULT_1] << 8) |
+			ext_csd[EXT_CSD_ENH_SIZE_MULT_0];
 		printf("Enhanced User Data Area Size"
-			" [ENH_SIZE_MULT]: 0x%06x\n", (ext_csd[142] << 16) |
-			(ext_csd[141] << 8) | ext_csd[140]);
+			" [ENH_SIZE_MULT]: 0x%06x\n", reg);
+		printf(" i.e. %lu KiB\n", 512l * reg *
+		       get_hc_erase_grp_size(ext_csd) *
+		       get_hc_wp_grp_size(ext_csd));
 
 		reg =	(ext_csd[EXT_CSD_ENH_START_ADDR_3] << 24) |
 			(ext_csd[EXT_CSD_ENH_START_ADDR_2] << 16) |
-- 
1.7.3.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 8/8] support setting the OTP enhanced user area parameters
  2013-05-30 21:12 [PATCH 0/8] cross-compiling, SEND_STATUS, pretty-printing and enhanced user area Ben Gardiner
                   ` (6 preceding siblings ...)
  2013-05-30 21:12 ` [PATCH 7/8] print KiB sizes for some fields Ben Gardiner
@ 2013-05-30 21:12 ` Ben Gardiner
  2013-06-27 15:11 ` [PATCH 0/8] cross-compiling, SEND_STATUS, pretty-printing and enhanced user area Chris Ball
  8 siblings, 0 replies; 10+ messages in thread
From: Ben Gardiner @ 2013-05-30 21:12 UTC (permalink / raw)
  To: cjb; +Cc: linux-mmc

Signed-off-by: Ben Gardiner <bengardiner@nanometrics.ca>
---
 mmc.c      |    5 ++
 mmc.h      |    3 +
 mmc_cmds.c |  170 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 mmc_cmds.h |    1 +
 4 files changed, 177 insertions(+), 2 deletions(-)

diff --git a/mmc.c b/mmc.c
index c22ce9e..30e3ce0 100644
--- a/mmc.c
+++ b/mmc.c
@@ -70,6 +70,11 @@ static struct Command commands[] = {
 		"Set the eMMC data sector size to 4KB by disabling emulation on\n<device>.",
 	  NULL
 	},
+	{ do_enh_area_set, -4,
+	  "enh_area set", "<-y|-n> " "<start KiB> " "<length KiB> " "<device>\n"
+		"Enable the enhanced user area for the <device>. Dry-run only unless -y is passed.",
+	  NULL
+	},
 	{ do_status_get, -1,
 	  "status get", "<device>\n"
 	  "Print the response to STATUS_SEND (CMD13).",
diff --git a/mmc.h b/mmc.h
index 5385e0e..f16bd89 100644
--- a/mmc.h
+++ b/mmc.h
@@ -42,11 +42,13 @@
 #define EXT_CSD_PART_SWITCH_TIME	199
 #define EXT_CSD_BOOT_CFG		179
 #define EXT_CSD_PART_CONFIG		179
+#define EXT_CSD_ERASE_GROUP_DEF		175
 #define EXT_CSD_BOOT_WP			173
 #define EXT_CSD_WR_REL_PARAM		166
 #define EXT_CSD_BKOPS_EN		163	/* R/W */
 #define EXT_CSD_RST_N_FUNCTION		162	/* R/W */
 #define EXT_CSD_PARTITIONING_SUPPORT	160	/* RO */
+#define EXT_CSD_PARTITIONS_ATTRIBUTE	156	/* R/W */
 #define EXT_CSD_PARTITION_SETTING_COMPLETED	155	/* R/W */
 #define EXT_CSD_ENH_SIZE_MULT_2		142
 #define EXT_CSD_ENH_SIZE_MULT_1		141
@@ -96,6 +98,7 @@
 #define EXT_CSD_PART_CONFIG_ACC_ACK	  (0x40)
 #define EXT_CSD_PARTITIONING_EN		(1<<0)
 #define EXT_CSD_ENH_ATTRIBUTE_EN	(1<<1)
+#define EXT_CSD_ENH_USR		(1<<0)
 
 /* From kernel linux/mmc/core.h */
 #define MMC_RSP_PRESENT	(1 << 0)
diff --git a/mmc_cmds.c b/mmc_cmds.c
index 37bb211..6993ac4 100644
--- a/mmc_cmds.c
+++ b/mmc_cmds.c
@@ -449,6 +449,172 @@ unsigned int get_hc_erase_grp_size(__u8 *ext_csd)
 	return ext_csd[224];
 }
 
+int do_enh_area_set(int nargs, char **argv)
+{
+	__u8 value;
+	__u8 ext_csd[512];
+	int fd, ret;
+	char *device;
+	int dry_run = 1;
+	unsigned int start_kib, length_kib, enh_start_addr, enh_size_mult;
+	unsigned long align;
+
+	CHECK(nargs != 5, "Usage: mmc enh_area set <-y|-n> <start KiB> <length KiB> "
+			  "</path/to/mmcblkX>\n", exit(1));
+
+	if (!strcmp("-y", argv[1]))
+		dry_run = 0;
+
+	start_kib = strtol(argv[2], NULL, 10);
+	length_kib = strtol(argv[3], NULL, 10);
+	device = argv[4];
+
+	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 ENH_ATTRIBUTE_EN */
+	if (!(ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & EXT_CSD_ENH_ATTRIBUTE_EN))
+	{
+		printf(" Device cannot have enhanced tech.\n");
+		exit(1);
+	}
+
+	/* assert not PARTITION_SETTING_COMPLETED */
+	if (ext_csd[EXT_CSD_PARTITION_SETTING_COMPLETED])
+	{
+		printf(" Device is already partitioned\n");
+		exit(1);
+	}
+
+	align = 512l * get_hc_wp_grp_size(ext_csd) * get_hc_erase_grp_size(ext_csd);
+
+	enh_size_mult = (length_kib + align/2l) / align;
+
+	enh_start_addr = start_kib * 1024 / (is_blockaddresed(ext_csd) ? 512 : 1);
+	enh_start_addr /= align;
+	enh_start_addr *= align;
+
+	/* set EXT_CSD_ERASE_GROUP_DEF bit 0 */
+	ret = write_extcsd_value(fd, EXT_CSD_ERASE_GROUP_DEF, 0x1);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x1 to "
+			"EXT_CSD[%d] in %s\n",
+			EXT_CSD_ERASE_GROUP_DEF, device);
+		exit(1);
+	}
+
+	/* write to ENH_START_ADDR and ENH_SIZE_MULT and PARTITIONS_ATTRIBUTE's ENH_USR bit */
+	value = (enh_start_addr >> 24) & 0xff;
+	ret = write_extcsd_value(fd, EXT_CSD_ENH_START_ADDR_3, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to "
+			"EXT_CSD[%d] in %s\n", value,
+			EXT_CSD_ENH_START_ADDR_3, device);
+		exit(1);
+	}
+	value = (enh_start_addr >> 16) & 0xff;
+	ret = write_extcsd_value(fd, EXT_CSD_ENH_START_ADDR_2, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to "
+			"EXT_CSD[%d] in %s\n", value,
+			EXT_CSD_ENH_START_ADDR_2, device);
+		exit(1);
+	}
+	value = (enh_start_addr >> 8) & 0xff;
+	ret = write_extcsd_value(fd, EXT_CSD_ENH_START_ADDR_1, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to "
+			"EXT_CSD[%d] in %s\n", value,
+			EXT_CSD_ENH_START_ADDR_1, device);
+		exit(1);
+	}
+	value = enh_start_addr & 0xff;
+	ret = write_extcsd_value(fd, EXT_CSD_ENH_START_ADDR_0, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to "
+			"EXT_CSD[%d] in %s\n", value,
+			EXT_CSD_ENH_START_ADDR_0, device);
+		exit(1);
+	}
+
+	value = (enh_size_mult >> 16) & 0xff;
+	ret = write_extcsd_value(fd, EXT_CSD_ENH_SIZE_MULT_2, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to "
+			"EXT_CSD[%d] in %s\n", value,
+			EXT_CSD_ENH_SIZE_MULT_2, device);
+		exit(1);
+	}
+	value = (enh_size_mult >> 8) & 0xff;
+	ret = write_extcsd_value(fd, EXT_CSD_ENH_SIZE_MULT_1, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to "
+			"EXT_CSD[%d] in %s\n", value,
+			EXT_CSD_ENH_SIZE_MULT_1, device);
+		exit(1);
+	}
+	value = enh_size_mult & 0xff;
+	ret = write_extcsd_value(fd, EXT_CSD_ENH_SIZE_MULT_0, value);
+	if (ret) {
+		fprintf(stderr, "Could not write 0x%02x to "
+			"EXT_CSD[%d] in %s\n", value,
+			EXT_CSD_ENH_SIZE_MULT_0, device);
+		exit(1);
+	}
+
+	ret = write_extcsd_value(fd, EXT_CSD_PARTITIONS_ATTRIBUTE, EXT_CSD_ENH_USR);
+	if (ret) {
+		fprintf(stderr, "Could not write EXT_CSD_ENH_USR to "
+			"EXT_CSD[%d] in %s\n",
+			EXT_CSD_PARTITIONS_ATTRIBUTE, device);
+		exit(1);
+	}
+
+	if (dry_run)
+	{
+		fprintf(stderr, "NOT setting PARTITION_SETTING_COMPLETED\n");
+		exit(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);
+		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;
+}
+
 int do_read_extcsd(int nargs, char **argv)
 {
 	__u8 ext_csd[512], ext_csd_rev, reg;
@@ -733,7 +899,7 @@ int do_read_extcsd(int nargs, char **argv)
 	printf("Boot bus Conditions [BOOT_BUS_CONDITIONS: 0x%02x]\n",
 		ext_csd[177]);
 	printf("High-density erase group definition"
-		" [ERASE_GROUP_DEF: 0x%02x]\n", ext_csd[175]);
+		" [ERASE_GROUP_DEF: 0x%02x]\n", ext_csd[EXT_CSD_ERASE_GROUP_DEF]);
 
 	print_writeprotect_status(ext_csd);
 
@@ -776,7 +942,7 @@ int do_read_extcsd(int nargs, char **argv)
 		printf(" i.e. %lu KiB\n", 512l * reg * wp_sz * erase_sz);
 
 		printf("Partitions attribute [PARTITIONS_ATTRIBUTE]: 0x%02x\n",
-			ext_csd[156]);
+			ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE]);
 		reg = ext_csd[EXT_CSD_PARTITION_SETTING_COMPLETED];
 		printf("Partitioning Setting"
 			" [PARTITION_SETTING_COMPLETED]: 0x%02x\n",
diff --git a/mmc_cmds.h b/mmc_cmds.h
index 3a754bf..bb1a9ca 100644
--- a/mmc_cmds.h
+++ b/mmc_cmds.h
@@ -25,3 +25,4 @@ int do_write_bkops_en(int nargs, char **argv);
 int do_hwreset_en(int nargs, char **argv);
 int do_hwreset_dis(int nargs, char **argv);
 int do_status_get(int nargs, char **argv);
+int do_enh_area_set(int nargs, char **argv);
-- 
1.7.3.5


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/8] cross-compiling, SEND_STATUS, pretty-printing and enhanced user area
  2013-05-30 21:12 [PATCH 0/8] cross-compiling, SEND_STATUS, pretty-printing and enhanced user area Ben Gardiner
                   ` (7 preceding siblings ...)
  2013-05-30 21:12 ` [PATCH 8/8] support setting the OTP enhanced user area parameters Ben Gardiner
@ 2013-06-27 15:11 ` Chris Ball
  8 siblings, 0 replies; 10+ messages in thread
From: Chris Ball @ 2013-06-27 15:11 UTC (permalink / raw)
  To: Ben Gardiner; +Cc: linux-mmc

Hi Ben,

On Thu, May 30 2013, Ben Gardiner wrote:
> This series builds on top of f74dfe23cd00894aa9f235374468e05acb793e17.
>
> It introduces:
>  * some Makefile changes to make cross-compiling easier
>  * SEND_STATUS
>  * 'pretty'-printing sizes of some fields in KiB
>  * setting the OTP enhanced user area parameters

Thanks for doing this!  I've pushed the whole patchset to mmc-utils,
after adding an extra warning about the OTP fuse in the usage message.

- Chris.
-- 
Chris Ball   <cjb@laptop.org>   <http://printf.net/>
One Laptop Per Child

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2013-06-27 15:11 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-05-30 21:12 [PATCH 0/8] cross-compiling, SEND_STATUS, pretty-printing and enhanced user area Ben Gardiner
2013-05-30 21:12 ` [PATCH 1/8] allow environment and command-line supplied make vars Ben Gardiner
2013-05-30 21:12 ` [PATCH 2/8] extract definitions for EXT_CSD register EXT_CSD_PARTITIONING_SUPPORT Ben Gardiner
2013-05-30 21:12 ` [PATCH 3/8] extract definitions for EXT_CSD register PARTITION_SETTING_COMPLETED and pretty-print Ben Gardiner
2013-05-30 21:12 ` [PATCH 4/8] Support SEND_STATUS command Ben Gardiner
2013-05-30 21:12 ` [PATCH 5/8] fix printing ENH_START_ADDR Ben Gardiner
2013-05-30 21:12 ` [PATCH 6/8] report if card is block-addressed and effect on ENH_START_ADDR Ben Gardiner
2013-05-30 21:12 ` [PATCH 7/8] print KiB sizes for some fields Ben Gardiner
2013-05-30 21:12 ` [PATCH 8/8] support setting the OTP enhanced user area parameters Ben Gardiner
2013-06-27 15:11 ` [PATCH 0/8] cross-compiling, SEND_STATUS, pretty-printing and enhanced user area 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).