aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/inftlcore.c
diff options
context:
space:
mode:
authorDaniel Rosenthal <danielrosenthal@acm.org>2008-10-05 17:43:10 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2008-10-08 06:26:38 -0400
commit63fd7f30f328f99956d3c774d17219c3c8d54131 (patch)
treed99fed43f643798b44052335af41ca5803250d17 /drivers/mtd/inftlcore.c
parentf324277cf70ad284dd99acf5ac5101e32bc8c55b (diff)
[MTD] [INFTL] Fix infinite loop in INFTL_foldchain
When iterating over a chain in reverse (oldest block first), this patch correctly marks the PUtable[] entry of the second to last erase block of a chain as BLOCK_NIL, regardless of whether or not it can format the last block successfully. Before, the second to last block was only marked as pointing to BLOCK_NIL if INFTL_formatblock() succeeded on the last block of the chain, which could potentially result in an infinite loop if the block was worn out and refused to format. Signed-off-by: Daniel Rosenthal <danielrosenthal@acm.org> Acked-by: Greg Ungerer <gerg@snapgear.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/inftlcore.c')
-rw-r--r--drivers/mtd/inftlcore.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c
index c4f9d3378b24..50ce13887f63 100644
--- a/drivers/mtd/inftlcore.c
+++ b/drivers/mtd/inftlcore.c
@@ -388,6 +388,10 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
388 if (thisEUN == targetEUN) 388 if (thisEUN == targetEUN)
389 break; 389 break;
390 390
391 /* Unlink the last block from the chain. */
392 inftl->PUtable[prevEUN] = BLOCK_NIL;
393
394 /* Now try to erase it. */
391 if (INFTL_formatblock(inftl, thisEUN) < 0) { 395 if (INFTL_formatblock(inftl, thisEUN) < 0) {
392 /* 396 /*
393 * Could not erase : mark block as reserved. 397 * Could not erase : mark block as reserved.
@@ -396,7 +400,6 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
396 } else { 400 } else {
397 /* Correctly erased : mark it as free */ 401 /* Correctly erased : mark it as free */
398 inftl->PUtable[thisEUN] = BLOCK_FREE; 402 inftl->PUtable[thisEUN] = BLOCK_FREE;
399 inftl->PUtable[prevEUN] = BLOCK_NIL;
400 inftl->numfreeEUNs++; 403 inftl->numfreeEUNs++;
401 } 404 }
402 } 405 }