changeset 3384:1229083b0af1

cdl/nand.cdl src/nand.c utils/erasenand.c: Create CYGSEM_IO_NAND_ALLOW_ERASE_WORNBAD.
author Ross Younger <wry@ecoscentric.com>
date Sat, 21 Jun 2014 22:52:44 +1200
parents 060772fa9bb3
children 631d86e5d620
files packages/io/nand/current/ChangeLog packages/io/nand/current/cdl/nand.cdl packages/io/nand/current/src/nand.c packages/io/nand/current/utils/erasenand.c
diffstat 4 files changed, 35 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/packages/io/nand/current/ChangeLog
+++ b/packages/io/nand/current/ChangeLog
@@ -2,6 +2,10 @@ 2014-08-11  Ross Younger  <wry@ecoscentr
 
 	* nand.c nand_bbt.c nand_synth.c: Make build with recent gcc
 
+2014-06-21  Ross Younger  <wry@ecoscentric.com>
+    * cdl/nand.cdl src/nand.c utils/erasenand.c: Create
+	CYGSEM_IO_NAND_ALLOW_ERASE_WORNBAD.
+
 2014-06-14  Ross Younger  <wry@ecoscentric.com>
     * tests/nand_rwbenchmark.c: Fix infinite loop when all
 	blocks are marked bad.
--- a/packages/io/nand/current/cdl/nand.cdl
+++ b/packages/io/nand/current/cdl/nand.cdl
@@ -182,7 +182,7 @@ cdl_package CYGPKG_IO_NAND {
 			writes to NAND devices."
 	}
 
-	cdl_option CYGSEM_IO_NAND_USE_BBT {
+	cdl_component CYGSEM_IO_NAND_USE_BBT {
 		display			"NAND layer uses bad-block tables"
 		flavor			bool
 		default_value	1
@@ -191,6 +191,15 @@ cdl_package CYGPKG_IO_NAND {
             a Bad Block Table to keep track of blocks marked bad
             at the factory and any bad blocks which may develop during
             the life of the device.  This is strongly recommended."
+
+		cdl_option    CYGSEM_IO_NAND_ALLOW_ERASE_WORNBAD {
+			flavor      bool
+			default_value 0
+			display     "Allow worn-bad blocks to be erased"
+			description "Normally, if a block is marked as worn-bad
+				in the Bad Block Table, it cannot be read, written
+				or erased. This option allows such blocks to be erased."
+		}
 	}
 
     cdl_option CYGNUM_NAND_PAGEBUFFER {
--- a/packages/io/nand/current/src/nand.c
+++ b/packages/io/nand/current/src/nand.c
@@ -667,7 +667,7 @@ int cyg_nandp_erase_block(cyg_nand_parti
 #else
     PARTITION_CHECK(prt);
     cyg_nand_device *dev = prt->dev;
-    int rv;
+    int rv, state;
     DEV_INIT_CHECK(dev);
     cyg_nand_block_addr blk = BLOCK_P_TO_D(prt, pblk);
 
@@ -677,7 +677,12 @@ int cyg_nandp_erase_block(cyg_nand_parti
 
     EG(valid_block_addr(prt, blk));
 #ifdef CYGSEM_IO_NAND_USE_BBT
-    if (cyg_nand_bbti_query(dev, blk) != CYG_NAND_BBT_OK) {
+	state = cyg_nand_bbti_query(dev, blk);
+    if ( (state != CYG_NAND_BBT_OK)
+#ifdef CYGSEM_IO_NAND_ALLOW_ERASE_WORNBAD
+			 && (state != CYG_NAND_BBT_WORNBAD)
+#endif
+			) {
         NAND_CHATTER(1,dev,"Asked to erase bad block %u\n", blk);
         EG(-EINVAL);
     }
--- a/packages/io/nand/current/utils/erasenand.c
+++ b/packages/io/nand/current/utils/erasenand.c
@@ -80,6 +80,15 @@ void cyg_user_start(void)
 
     int progmod = (prt->last - prt->first + 1) / 73 + 1;
 
+#if 0 // Used for testing during development
+	{
+		int stx = cyg_nandp_bbt_markbad(prt, 42);
+		if (stx<0) {
+			diag_printf("mark bad 42 error %d\n", stx);
+		}
+	}
+#endif
+
     for (blk=0; blk < CYG_NAND_PARTITION_NBLOCKS(prt); blk++) {
 #ifdef CYGSEM_IO_NAND_USE_BBT
         int st = cyg_nandp_bbt_query(prt, blk);
@@ -92,12 +101,17 @@ void cyg_user_start(void)
         const char *msg = 0;
         switch(st) {
             case CYG_NAND_BBT_OK:
+#ifdef CYGSEM_IO_NAND_ALLOW_ERASE_WORNBAD
+            case CYG_NAND_BBT_WORNBAD:
+#endif
                 rv = cyg_nandp_erase_block(prt, blk);
                 if (rv != 0)
                     diag_printf("Block %d: error %d\n", blk, -rv);
                 break;
+#ifndef CYGSEM_IO_NAND_ALLOW_ERASE_WORNBAD
             case CYG_NAND_BBT_WORNBAD:
                 msg="worn bad"; break;
+#endif
             case CYG_NAND_BBT_FACTORY_BAD:
                 msg="factory bad"; break;