From 50b94628aec9b94e2aa6d326c48c896c718d7e46 Mon Sep 17 00:00:00 2001
From: dbrownell <dbrownell@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Date: Tue, 22 Sep 2009 05:39:06 +0000
Subject: Make it easier to erase or protect through to the end of a (NOR)
 flash chip: allow passing "last" as an alias for the number of the last
 sector.

Improve several aspects of error checking while we're at it.

From: Johnny Halfmoon <jhalfmoon@milksnot.com>


git-svn-id: svn://svn.berlios.de/openocd/trunk@2746 b42882b7-edfa-0310-969c-e2dbd0fdcd60
---
 src/flash/flash.c | 111 ++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 75 insertions(+), 36 deletions(-)

(limited to 'src')

diff --git a/src/flash/flash.c b/src/flash/flash.c
index e73dfa70..ef4f342c 100644
--- a/src/flash/flash.c
+++ b/src/flash/flash.c
@@ -559,82 +559,121 @@ static int handle_flash_protect_check_command(struct command_context_s *cmd_ctx,
 	return ERROR_OK;
 }
 
-static int handle_flash_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int flash_check_sector_parameters(struct command_context_s *cmd_ctx,
+		uint32_t first, uint32_t last, uint num_sectors)
+{
+	if (!(first <= last)) {
+		command_print(cmd_ctx, "ERROR: "
+				"first sector must be <= last sector");
+		return ERROR_FAIL;
+	}
+
+	if (!(last <= (num_sectors - 1))) {
+		command_print(cmd_ctx, "ERROR: "
+				"last sector must be <= %d", num_sectors - 1);
+		return ERROR_FAIL;
+	}
+
+	return ERROR_OK;
+}
+
+static int handle_flash_erase_command(struct command_context_s *cmd_ctx,
+		char *cmd, char **args, int argc)
 {
 	if (argc > 2)
 	{
-		int first = strtoul(args[1], NULL, 0);
-		int last = strtoul(args[2], NULL, 0);
+		uint32_t bank_nr;
+		uint32_t first;
+		uint32_t last;
 		int retval;
-		flash_bank_t *p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
-		duration_t duration;
-		char *duration_text;
 
-		duration_start_measure(&duration);
+		if ((retval = parse_u32(args[0], &bank_nr)) != ERROR_OK)
+			return retval;
 
+		flash_bank_t *p = get_flash_bank_by_num(bank_nr);
 		if (!p)
-		{
-			return ERROR_COMMAND_SYNTAX_ERROR;
-		}
+			return ERROR_OK;
 
-		if ((retval = flash_driver_erase(p, first, last)) == ERROR_OK)
-		{
-			if ((retval = duration_stop_measure(&duration, &duration_text)) != ERROR_OK)
-			{
+		if ((retval = parse_u32(args[1], &first)) != ERROR_OK)
+			return retval;
+		if (strcmp(args[2], "last") == 0)
+			last = p->num_sectors - 1;
+		else
+			if ((retval = parse_u32(args[2], &last)) != ERROR_OK)
 				return retval;
-			}
 
-			command_print(cmd_ctx, "erased sectors %i through %i on flash bank %li in %s",
-				first, last, strtoul(args[0], 0, 0), duration_text);
+		if ((retval = flash_check_sector_parameters(cmd_ctx,
+				first, last, p->num_sectors)) != ERROR_OK)
+			return retval;
+
+		duration_t duration;
+		char *duration_text;
+		duration_start_measure(&duration);
+
+		if ((retval = flash_driver_erase(p, first, last)) == ERROR_OK) {
+			if ((retval = duration_stop_measure(&duration,
+						&duration_text)) != ERROR_OK)
+				return retval;
+			command_print(cmd_ctx, "erased sectors %i through %i "
+					"on flash bank %i in %s",
+				first, last, bank_nr, duration_text);
 			free(duration_text);
 		}
 	}
 	else
-	{
 		return ERROR_COMMAND_SYNTAX_ERROR;
-	}
 
 	return ERROR_OK;
 }
 
-static int handle_flash_protect_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+static int handle_flash_protect_command(struct command_context_s *cmd_ctx,
+		char *cmd, char **args, int argc)
 {
 	if (argc > 3)
 	{
-		int first = strtoul(args[1], NULL, 0);
-		int last = strtoul(args[2], NULL, 0);
-		int set;
+		uint32_t bank_nr;
+		uint32_t first;
+		uint32_t last;
 		int retval;
-		flash_bank_t *p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
+		int set;
+
+		if ((retval = parse_u32(args[0], &bank_nr)) != ERROR_OK)
+			return retval;
+
+		flash_bank_t *p = get_flash_bank_by_num(bank_nr);
 		if (!p)
-		{
-			command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
 			return ERROR_OK;
-		}
+
+		if ((retval = parse_u32(args[1], &first)) != ERROR_OK)
+			return retval;
+		if (strcmp(args[2], "last") == 0)
+			last = p->num_sectors - 1;
+		else
+			if ((retval = parse_u32(args[2], &last)) != ERROR_OK)
+				return retval;
 
 		if (strcmp(args[3], "on") == 0)
 			set = 1;
 		else if (strcmp(args[3], "off") == 0)
 			set = 0;
 		else
-		{
 			return ERROR_COMMAND_SYNTAX_ERROR;
-		}
+
+		if ((retval = flash_check_sector_parameters(cmd_ctx,
+				first, last, p->num_sectors)) != ERROR_OK)
+			return retval;
 
 		retval = flash_driver_protect(p, set, first, last);
-		if (retval == ERROR_OK)
-		{
-			command_print(cmd_ctx, "%s protection for sectors %i through %i on flash bank %li",
+		if (retval == ERROR_OK) {
+			command_print(cmd_ctx, "%s protection for sectors %i "
+					"through %i on flash bank %i",
 				(set) ? "set" : "cleared", first,
-				last, strtoul(args[0], 0, 0));
+				last, bank_nr);
 		}
 	}
 	else
-	{
 		return ERROR_COMMAND_SYNTAX_ERROR;
 
-	}
-
 	return ERROR_OK;
 }
 
-- 
cgit v1.2.3