David,

I'm not sure I fully catch your points.
Anyway, I agree that code got even more confused and that comments are
not consistent with code anymore.

Why not changing the whole procedure in a cleaner way?
I've put in attachment my proposal
Execution is more linear and without goto statement.
Moreover, it splits the first-last interval and should improve performance.

Best Regards,
Antonio Borneo

On Wed, Mar 10, 2010 at 10:31 AM, David Brownell <davi...@pacbell.net> wrote:
> On Tuesday 09 March 2010, David Brownell wrote:
>
> And tl clarify a bit:
>
>
>> On Monday 08 March 2010, Antonio Borneo wrote:
>> > Cannot protect or unprotect single sector in cfi flash.
>> > When first==last the procedure fails.
>> >
>> > Signed-off-by: Antonio Borneo <borneo.anto...@gmail.com>
>> > ---
>> >  src/flash/nor/core.c |    4 ++--
>> >  1 files changed, 2 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c
>> > index 767006d..8b581b0 100644
>> > --- a/src/flash/nor/core.c
>> > +++ b/src/flash/nor/core.c
>> > @@ -73,7 +73,7 @@ int flash_driver_protect(struct flash_bank *bank, int 
>> > set, int first, int last)
>> >      * speeds at least some things up.
>> >      */
>> >  scan:
>> > -   for (int i = first; i < last; i++) {
>> > +   for (int i = first; i <= last; i++) {
>>
>> OK
>
> ... because "first == last" is an OK loop entry state;
> it was explicitly allowed in the procedure parameter
> checks earlier, indicating that "single sector" case.
>
>
>>
>> >             struct flash_sector *sector = bank->sectors + i;
>> >
>> >             /* Only filter requests to protect the already-protected, or
>> > @@ -108,7 +108,7 @@ scan:
>> >     }
>> >
>> >     /* Single sector, already protected?  Nothing to do! */
>> > -   if (first == last)
>> > +   if (first > last)
>>
>> ... not.  the loop previously maintained the "first <= last" invariant,
>> and should still have done so.  "first > last" is clearly an error case.
>
> ... "clearly" since the procedure parameter checks rejected that error.
> Also,
>
>  - a comment in the loop pointed out the importance of not overrunning
>   the end
>
>  - the comment up top says "first == last" is the "single sector" case
>
> In short, this would add three internal inconsistencies...
>
>>
>>
>> >             return ERROR_OK;
>> >
>> >
>> > --
>> > 1.5.2.2
> _______________________________________________
> Openocd-development mailing list
> Openocd-development@lists.berlios.de
> https://lists.berlios.de/mailman/listinfo/openocd-development
>
From 7896dd208161d0e01157bc4fc957dc75a911e7fd Mon Sep 17 00:00:00 2001
From: Antonio Borneo <borneo.anto...@gmail.com>
Date: Wed, 10 Mar 2010 11:14:13 +0800
Subject: [PATCH] CFI CORE: rewrite flash_driver_protect()

Simpler code to improve maintenance and readability.
Increased performance by skipping sectors that don't need to
modify protection.

Signed-off-by: Antonio Borneo <borneo.anto...@gmail.com>
---
 src/flash/nor/core.c |   68 ++++++++++++++++++-------------------------------
 1 files changed, 25 insertions(+), 43 deletions(-)

diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c
index 8b581b0..d4260c6 100644
--- a/src/flash/nor/core.c
+++ b/src/flash/nor/core.c
@@ -53,9 +53,6 @@ int flash_driver_erase(struct flash_bank *bank, int first, int last)
 
 int flash_driver_protect(struct flash_bank *bank, int set, int first, int last)
 {
-	int retval;
-	bool updated = false;
-
 	/* NOTE: "first == last" means protect just that sector */
 
 	/* callers may not supply illegal parameters ... */
@@ -71,54 +68,39 @@ int flash_driver_protect(struct flash_bank *bank, int set, int first, int last)
 	 * Don't tell drivers to change to the current state...  it's needless,
 	 * and reducing the amount of work to be done (potentially to nothing)
 	 * speeds at least some things up.
+	 *
+	 * Only filter requests to protect the already-protected, or
+	 * to unprotect the already-unprotected.  Changing from the
+	 * unknown state (-1) to a known one is unwise but allowed;
+	 * protection status is best checked first.
 	 */
-scan:
-	for (int i = first; i <= last; i++) {
-		struct flash_sector *sector = bank->sectors + i;
-
-		/* Only filter requests to protect the already-protected, or
-		 * to unprotect the already-unprotected.  Changing from the
-		 * unknown state (-1) to a known one is unwise but allowed;
-		 * protection status is best checked first.
-		 */
-		if (sector->is_protected != set)
+	for (; first <= last ; first++) {
+		int next;
+		int retval;
+
+		/* Skip sectors don't need change protection */
+		if (bank->sectors[first].is_protected == set)
 			continue;
 
-		/* Shrink this range of sectors from the start; don't overrun
-		 * the end.  Also shrink from the end; don't overun the start.
-		 *
-		 * REVISIT we could handle discontiguous regions by issuing
-		 * more than one driver request.  How much would that matter?
-		 */
-		if (i == first) {
-			updated = true;
-			first++;
-		} else if (i == last) {
-			updated = true;
-			last--;
+		for (next = first + 1; next <= last ; next++) {
+			/* Exit when next sector doesn't need change protection */
+			if (bank->sectors[next].is_protected == set)
+				break;
 		}
-	}
-
-	/* updating the range affects the tests in the scan loop above; so
-	 * re-scan, to make sure we didn't miss anything.
-	 */
-	if (updated) {
-		updated = false;
-		goto scan;
-	}
-
-	/* Single sector, already protected?  Nothing to do! */
-	if (first > last)
-		return ERROR_OK;
 
+		retval = bank->driver->protect(bank, set, first, next - 1);
+		if (retval != ERROR_OK)
+		{
+			LOG_ERROR("failed setting protection for areas %d to %d (%d)", first, next - 1, retval);
+			return retval;
+		}
 
-	retval = bank->driver->protect(bank, set, first, last);
-	if (retval != ERROR_OK)
-	{
-		LOG_ERROR("failed setting protection for areas %d to %d (%d)", first, last, retval);
+		/* Reiterate from next chunk.
+		 * Sector 'next' already tested and no need change */
+		first = next;
 	}
 
-	return retval;
+	return ERROR_OK;
 }
 
 int flash_driver_write(struct flash_bank *bank,
-- 
1.5.2.2

_______________________________________________
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to