*** empty log message ***
authorcharles <charles>
Tue, 20 May 2003 22:30:35 +0000 (22:30 +0000)
committercharles <charles>
Tue, 20 May 2003 22:30:35 +0000 (22:30 +0000)
Documentation/yaffs_boot.html
Makefile
direct/Makefile
direct/dtest.c
snMakefile [deleted file]
wince/sources
yaffs_ecc.c [new file with mode: 0644]
yaffs_ecc.h [new file with mode: 0644]
yaffs_guts.c

index 6591a556ca242eb74adb3c685dcd2aeedb7db4b0..50f18a4e38a7e023941f9f1522dd45ebfa3d9fe7 100644 (file)
@@ -7,7 +7,7 @@
        <META NAME="AUTHOR" CONTENT=" ">
        <META NAME="CREATED" CONTENT="20021129;9042700">
        <META NAME="CHANGEDBY" CONTENT=" ">
        <META NAME="AUTHOR" CONTENT=" ">
        <META NAME="CREATED" CONTENT="20021129;9042700">
        <META NAME="CHANGEDBY" CONTENT=" ">
-       <META NAME="CHANGED" CONTENT="20030121;16061100">
+       <META NAME="CHANGED" CONTENT="20030508;6083900">
 </HEAD>
 <BODY>
 <H1>Example YAFFS Bootloader</H1>
 </HEAD>
 <BODY>
 <H1>Example YAFFS Bootloader</H1>
@@ -21,7 +21,7 @@ integration and configuration.</P>
 <UL>
        <LI><P>yaffs_flashif.c NAND integration functions (to be completed
        by integrator).</P>
 <UL>
        <LI><P>yaffs_flashif.c NAND integration functions (to be completed
        by integrator).</P>
-       <LI><P>nand_ecc.c: The ECC algorithms.</P>
+       <LI><P>yaffs_ecc.c: The ECC algorithms.</P>
        <LI><P>yboot.c: Bootloader code to provide a file as a stream of
        bytes in the bootloader.</P>
 </UL>
        <LI><P>yboot.c: Bootloader code to provide a file as a stream of
        bytes in the bootloader.</P>
 </UL>
@@ -37,7 +37,7 @@ the boot process.</P>
 <P>As shown here the bootloader is initialised, then provides the
 boot file as a stream of bytes. It is simple enough to provide the
 data in other formats.</P>
 <P>As shown here the bootloader is initialised, then provides the
 boot file as a stream of bytes. It is simple enough to provide the
 data in other formats.</P>
-<P>$Id: yaffs_boot.html,v 1.1 2003-01-21 03:34:12 charles Exp $</P>
+<P>$Id: yaffs_boot.html,v 1.2 2003-05-20 22:30:36 charles Exp $</P>
 <P><BR><BR>
 </P>
 <P><BR><BR>
 <P><BR><BR>
 </P>
 <P><BR><BR>
index 8a1b6fe26e0f3a65d1294d03ed2fb6b2b06acb1a..69ca8178443976c7d9855ab7932901b0f7d2f676 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,7 @@
 # it under the terms of the GNU General Public License version 2 as
 # published by the Free Software Foundation.
 #
 # it under the terms of the GNU General Public License version 2 as
 # published by the Free Software Foundation.
 #
-# $Id: Makefile,v 1.10 2003-03-11 05:16:53 charles Exp $
+# $Id: Makefile,v 1.11 2003-05-20 22:30:35 charles Exp $
 #
 
 ## Change or override  KERNELDIR to your kernel
 #
 
 ## Change or override  KERNELDIR to your kernel
@@ -57,6 +57,13 @@ USE_MTD = -DCONFIG_YAFFS_MTD_ENABLED
 
 USE_NANDECC = -DCONFIG_YAFFS_USE_NANDECC
 
 
 USE_NANDECC = -DCONFIG_YAFFS_USE_NANDECC
 
+# CONFIG_YAFFS_ECC_WRONG_ORDER
+# This makes yaffs_ecc.c use the same ecc byte order as
+# Steven Hill's nand_ecc.c. If not set, then you get the
+# same ecc byte order as SmartMedia.
+
+#USE_WRONGECC = -DCONFIG_YAFFS_ECC_WRONG_ORDER
+
 # CONFIG_YAFFS_USE_GENERIC_RW
 # Use generic_read/generic_write for reading/writing files. This enables the use of the Linux
 # file caching layer.
 # CONFIG_YAFFS_USE_GENERIC_RW
 # Use generic_read/generic_write for reading/writing files. This enables the use of the Linux
 # file caching layer.
@@ -69,7 +76,7 @@ USE_GENERIC_RW = -DCONFIG_YAFFS_USE_GENERIC_RW
 # When the flash is scanned, two file sizes are constructed:
 # * The size taken from the object header for the file.
 # * The size figured out by scanning the data chunks.
 # When the flash is scanned, two file sizes are constructed:
 # * The size taken from the object header for the file.
 # * The size figured out by scanning the data chunks.
-# If this option is enabled, then the object header size is ued, otherwise the scanned size is used.
+# If this option is enabled, then the object header size is used, otherwise the scanned size is used.
 # Suggest leaving this disabled.
 
 #USE_HEADER_FILE_SIZE = -DCONFIG_YAFFS_USE_HEADER_FILE_SIZE
 # Suggest leaving this disabled.
 
 #USE_HEADER_FILE_SIZE = -DCONFIG_YAFFS_USE_HEADER_FILE_SIZE
@@ -98,13 +105,13 @@ ENABLE_SHORT_NAMES_IN_RAM = -DCONFIG_SHORT_NAMES_IN_RAM
 # End of configuration options.
 
 YAFFS_CONFIGS = $(USE_RAM_FOR_TEST) $(USE_MTD) $(USE_GENERIC_RW) $(USE_HEADER_FILE_SIZE) $(IGNORE_CHUNK_ERASED) $(IGNORE_WRITE_VERIFY) \
 # End of configuration options.
 
 YAFFS_CONFIGS = $(USE_RAM_FOR_TEST) $(USE_MTD) $(USE_GENERIC_RW) $(USE_HEADER_FILE_SIZE) $(IGNORE_CHUNK_ERASED) $(IGNORE_WRITE_VERIFY) \
-                $(ENABLE_SHORT_NAMES_IN_RAM) $(USE_NANDECC) $(USE_OLD_MTD)
+                $(ENABLE_SHORT_NAMES_IN_RAM) $(USE_NANDECC) $(USE_OLD_MTD) $(USE_WRONGECC)
 
 
 CFLAGS = -D__KERNEL__ -DMODULE $(YAFFS_CONFIGS)  -I$(KERNELDIR)/include -O2 -Wall
 
 
 
 
 CFLAGS = -D__KERNEL__ -DMODULE $(YAFFS_CONFIGS)  -I$(KERNELDIR)/include -O2 -Wall
 
 
-OBJS = yaffs_fs.o yaffs_guts.o yaffs_ramem.o yaffs_mtdif.o nand_ecc.o
+OBJS = yaffs_fs.o yaffs_guts.o yaffs_ramem.o yaffs_mtdif.o yaffs_ecc.o
 
 
 all: yaffs.o
 
 
 all: yaffs.o
index 22a18cda7312258be51cbbab772cf2b9b5268805..a1c6840629ef2e8cb3b792c6d9b1986ee9faf0d6 100644 (file)
 #
 # NB Warning this Makefile does not include header dependencies.
 #
 #
 # NB Warning this Makefile does not include header dependencies.
 #
-# $Id: Makefile,v 1.1 2003-01-21 03:32:17 charles Exp $
+# $Id: Makefile,v 1.2 2003-05-20 22:30:36 charles Exp $
 
 CFLAGS =    -Wall -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -g
 #CFLAGS+=   -Wshadow -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Wmissing-declarations
 #CFLAGS+=   -Wmissing-prototypes -Wredundant-decls -Wnested-externs -Winline
 
 
 
 CFLAGS =    -Wall -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -g
 #CFLAGS+=   -Wshadow -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Wmissing-declarations
 #CFLAGS+=   -Wmissing-prototypes -Wredundant-decls -Wnested-externs -Winline
 
 
-DIRECTTESTOBJS = dtest.o nand_ecc.o yaffscfg.o yaffs_fileem.o yaffsfs.o yaffs_ramdisk.o yaffs_guts.o
+DIRECTTESTOBJS = dtest.o yaffs_ecc.o yaffscfg.o yaffs_fileem.o yaffsfs.o yaffs_ramdisk.o yaffs_guts.o
 
 BOOTTESTOBJS = bootldtst.o yboot.o yaffs_fileem.o nand_ecc.o
 
 ALLOBJS =  dtest.o nand_ecc.o yaffscfg.o yaffs_fileem.o yaffsfs.o yaffs_ramdisk.o bootldtst.o yboot.o 
 
 
 BOOTTESTOBJS = bootldtst.o yboot.o yaffs_fileem.o nand_ecc.o
 
 ALLOBJS =  dtest.o nand_ecc.o yaffscfg.o yaffs_fileem.o yaffsfs.o yaffs_ramdisk.o bootldtst.o yboot.o 
 
-SYMLINKS = devextras.h nand_ecc.c yaffs_guts.c yaffs_guts.h yaffsinterface.h yportenv.h
+SYMLINKS = devextras.h yaffs_ecc.c yaffs_ecc.h yaffs_guts.c yaffs_guts.h yaffsinterface.h yportenv.h
 
 all: directtest boottest
 
 
 all: directtest boottest
 
index 6f32cb53d81ac028a86c20f00f08ae4df32de1db..9051c234fbb4c2820ef8380c6dfdacc875ef53d9 100644 (file)
@@ -64,6 +64,7 @@ void fill_disk(char *path,int nfiles)
        int h;
        int n;
        int result;
        int h;
        int n;
        int result;
+       int f;
        
        char str[50];
        
        
        char str[50];
        
@@ -77,7 +78,7 @@ void fill_disk(char *path,int nfiles)
                
                while ((result = yaffs_write(h,xx,600)) == 600)
                {
                
                while ((result = yaffs_write(h,xx,600)) == 600)
                {
-                       //printf(".");
+                       f = yaffs_freespace("/boot");
                }
                result = yaffs_close(h);
                printf(" close %d\n",result);
                }
                result = yaffs_close(h);
                printf(" close %d\n",result);
@@ -660,6 +661,19 @@ int cache_bypass_bug_test(void)
 }
 
 
 }
 
 
+int free_space_check(void)
+{
+       int f;
+       
+               yaffs_StartUp();
+               yaffs_mount("/boot");
+           fill_disk("/boot/",2);
+           f = yaffs_freespace("/boot");
+           
+           printf("%d free when disk full\n",f);           
+           return 1;
+}
+
 
 int main(int argc, char *argv[])
 {
 
 int main(int argc, char *argv[])
 {
@@ -667,6 +681,8 @@ int main(int argc, char *argv[])
        
        //return cache_read_test();
        
        
        //return cache_read_test();
        
-       return cache_bypass_bug_test();
+       //return cache_bypass_bug_test();
+       
+       return free_space_check();
        
 }
        
 }
diff --git a/snMakefile b/snMakefile
deleted file mode 100644 (file)
index cbd34df..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-#########################################################
-# Makefile auto generated by Cygnus Source Navigator.
-# Target: yaffsdev_disk Date: Dec 18 2002 Time: 04:44:42 PM
-#
-
-
-.SUFFIXES: .cc .class .java .cxx .C .cpp .o .c .l .y
-
-
-VPATH = /opt/yaffs/.
-
-
-YACC = bison
-LEX = flex
-JAVA = gcj
-CC = gcc
-CPP = g++
-YACC_FLAGS =      
-LEX_FLAGS =      
-JAVA_FLAGS =      
-CC_FLAGS =  -g  -Wall  -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_SHORT_OP_CACHE -DYAFFS_PARANOID -DYAFFS_FILEEM
-CPP_FLAGS =      
-YACC_INCLUDES = 
-LEX_INCLUDES = 
-JAVA_INCLUDES = 
-CC_INCLUDES = 
-CPP_INCLUDES = 
-YACC_DEFINES = 
-LEX_DEFINES = 
-JAVA_DEFINES = 
-CC_DEFINES = 
-CPP_DEFINES = 
-yaffsdev_disk_LIBS = 
-LINKER = gcc
-LINKER_FLAGS = 
-LINKER_ENTRY = 
-yaffsdev_disk_OBJECTS = nand_ecc.o yaffs_fileem.o yaffs_guts.o yaffsdev.o
-
-all: yaffsdev
-
-yaffsdev: $(yaffsdev_disk_OBJECTS)
-       $(LINKER) -o yaffsdev $(LINKER_ENTRY) $(LINKER_FLAGS) $(yaffsdev_disk_OBJECTS) $(yaffsdev_disk_LIBS)
-
-.y.c:
-       $(YACC) $< $(YACC_FLAGS) $(YACC_DEFINES) $(YACC_INCLUDES)
-
-
-.l.c:
-       $(LEX) -t $< > $@ $(LEX_FLAGS) $(LEX_DEFINES) $(LEX_INCLUDES)
-
-
-.java.o:
-       $(JAVA) -c $< $(JAVA_FLAGS) $(JAVA_DEFINES) $(JAVA_INCLUDES)
-.class:
-       $(JAVA) -c $< $(JAVA_FLAGS) $(JAVA_DEFINES) $(JAVA_INCLUDES)
-
-
-.c.o:
-       $(CC) -c $< $(CC_FLAGS) $(CC_DEFINES) $(CC_INCLUDES)
-
-
-.cpp.o:
-       $(CPP) -c $< $(CPP_FLAGS) $(CPP_DEFINES) $(CPP_INCLUDES)
-.C.o:
-       $(CPP) -c $< $(CPP_FLAGS) $(CPP_DEFINES) $(CPP_INCLUDES)
-.cc.o:
-       $(CPP) -c $< $(CPP_FLAGS) $(CPP_DEFINES) $(CPP_INCLUDES)
-.cxx.o:
-       $(CPP) -c $< $(CPP_FLAGS) $(CPP_DEFINES) $(CPP_INCLUDES)
-
-
-nand_ecc.o: /opt/yaffs/yportenv.h
-yaffs_fileem.o: /opt/yaffs/yaffs_fileem.h /opt/yaffs/yaffs_guts.h /opt/yaffs/yaffsinterface.h
-yaffs_guts.o: /opt/yaffs/yaffs_guts.h /opt/yaffs/yaffsinterface.h /opt/yaffs/yportenv.h
-yaffsdev.o: /opt/yaffs/yaffs_fileem.h /opt/yaffs/yaffs_guts.h /opt/yaffs/yaffs_nandemul.h /opt/yaffs/yaffsinterface.h /opt/yaffs/yportenv.h
-
-clean:
-       rm -f *.o
-       rm -f yaffsdev
-
index 2706a6d56302da0667b869733427d8012a095439..e2f0c9ef7fe8c9eec81ed4c818bfdf603e0d078a 100644 (file)
@@ -1,45 +1,45 @@
-!IF 0\r
-\r
- YAFFS: Yet another FFS. A NAND-flash specific file system.\r
-; SOURCES: The FSD layer for the WinCE version of YAFFS.\r
-;\r
-; Copyright (C) 2002 Trimble Navigation Limited.  All rights reserved.\r
-;\r
-; Created by Charles Manning <charles.manning@trimble.co.nz>\r
-;\r
-; This program is free software; you can redistribute it and/or modify\r
-; it under the terms of the GNU General Public License version 2 as\r
-; published by the Free Software Foundation.\r
-; This program is distributed in the hope that it will be useful, but \r
-;\r
-; WITHOUT ANY WARRANTY; without even the implied warranty of \r
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General \r
-; Public License for more details. You should have received a copy of the\r
-; GNU General Public License along with this program; if not, write to the \r
-; Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\r
-;\r
-; $Id: sources,v 1.2 2003-01-31 00:52:53 charles Exp $\r
-\r
-\r
-\r
-!ENDIF\r
-\r
-!if "$(ODO_NODISPLAY)" == "1"\r
-SKIPBUILD=1\r
-!endif\r
-\r
-RELEASETYPE=PLATFORM\r
-\r
-TARGETNAME=YFSD\r
-TARGETTYPE=DYNLINK\r
-TARGETLIBS=                                             \\r
-    $(_PUBLICROOT)\COMMON\OAK\lib\arm\Sa1100\ce\retail\fsdmgr.lib \\r
-    $(_COMMONSDKROOT)\lib\$(_CPUINDPATH)\coredll.lib    \\r
-\r
-CDEFINES=  $(CDEFINES) -DCONFIG_YAFFS_WINCE -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM \r
-\r
-\r
-SOURCES=  yaffs_guts.c nand_ecc.c yaffsfsd.c ynandif.c \r
-\r
-    \r
-\r
+!IF 0
+
+ YAFFS: Yet another FFS. A NAND-flash specific file system.
+; SOURCES: The FSD layer for the WinCE version of YAFFS.
+;
+; Copyright (C) 2002 Trimble Navigation Limited.  All rights reserved.
+;
+; Created by Charles Manning <charles.manning@trimble.co.nz>
+;
+; This program is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License version 2 as
+; published by the Free Software Foundation.
+; This program is distributed in the hope that it will be useful, but 
+;
+; WITHOUT ANY WARRANTY; without even the implied warranty of 
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 
+; Public License for more details. You should have received a copy of the
+; GNU General Public License along with this program; if not, write to the 
+; Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+;
+; $Id: sources,v 1.3 2003-05-20 22:30:36 charles Exp $
+
+
+
+!ENDIF
+
+!if "$(ODO_NODISPLAY)" == "1"
+SKIPBUILD=1
+!endif
+
+RELEASETYPE=PLATFORM
+
+TARGETNAME=YFSD
+TARGETTYPE=DYNLINK
+TARGETLIBS=                                             \
+    $(_PUBLICROOT)\COMMON\OAK\lib\arm\Sa1100\ce\retail\fsdmgr.lib \
+    $(_COMMONSDKROOT)\lib\$(_CPUINDPATH)\coredll.lib    \
+
+CDEFINES=  $(CDEFINES) -DCONFIG_YAFFS_WINCE -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM 
+
+
+SOURCES=  yaffs_guts.c yaffs_ecc.c yaffsfsd.c ynandif.c 
+
+    
+
diff --git a/yaffs_ecc.c b/yaffs_ecc.c
new file mode 100644 (file)
index 0000000..1420da2
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * YAFFS: Yet another FFS. A NAND-flash specific file system. 
+ *
+ * yaffs_ecc.c: ECC generation/correction algorithms.
+ *
+ * Copyright (C) 2002 Aleph One Ltd.
+ *
+ * Created by Charles Manning <charles@aleph1.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+ /*
+ * This code implements the ECC algorithm used in SmartMedia.
+ *
+ * The ECC comprises 22 bits of parity information and is stuffed into 3 bytes. 
+ * The two unused bit are set to 1.
+ * The ECC can correct single bit errors in a 256-byte page of data. Thus, two such ECC 
+ * blocks are used on a 512-byte NAND page.
+ *
+ */
+
+// Table generated by gen-ecc.c
+// Using a table means we do not have to calculate p1..p4 and p1'..p4'
+// for each byte of data. These are instead provided in a table in bits7..2.
+// Bit 0 of each entry indicates whether the entry has an odd or even parity, and therefore
+// this bytes influence on the line parity.
+
+const char *yaffs_ecc_c_version = "$Id: yaffs_ecc.c,v 1.1 2003-05-20 22:32:24 charles Exp $";
+
+
+#include "yaffs_ecc.h"
+
+static const unsigned char column_parity_table[] = {
+0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69, 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00, 
+0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc, 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95, 
+0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0, 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99, 
+0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65, 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c, 
+0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc, 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5, 
+0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59, 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30, 
+0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55, 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c, 
+0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0, 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9, 
+0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0, 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9, 
+0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55, 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c, 
+0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59, 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30, 
+0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc, 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5, 
+0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65, 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c, 
+0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0, 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99, 
+0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc, 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95, 
+0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69, 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00, 
+};
+
+
+static int yaffs_CountBits(unsigned char x)
+{
+       int r = 0;
+       while(x)
+       {
+               if(x & 1) r++;
+               x >>= 1;
+       }
+       return r;
+}
+
+void yaffs_ECCCalculate(const unsigned char *data,unsigned char *ecc)
+{
+       unsigned int i;
+       
+       unsigned char col_parity = 0;
+       unsigned char line_parity = 0;
+       unsigned char line_parity_prime = 0;
+       unsigned char t;
+       unsigned char b;
+       
+       for(i = 0; i < 256; i++)
+       {
+               b = column_parity_table[*data++];
+               col_parity ^= b;
+
+               if(b & 0x01) // odd number of bits in the byte
+               {
+                       line_parity ^= i;
+                       line_parity_prime ^= ~i;
+               }
+               
+       }
+       
+       ecc[2] = (~col_parity) | 0x03;
+       
+       t = 0;
+       if(line_parity       & 0x80) t |= 0x80;
+       if(line_parity_prime & 0x80) t |= 0x40;
+       if(line_parity       & 0x40) t |= 0x20;
+       if(line_parity_prime & 0x40) t |= 0x10;
+       if(line_parity       & 0x20) t |= 0x08;
+       if(line_parity_prime & 0x20) t |= 0x04;
+       if(line_parity       & 0x10) t |= 0x02;
+       if(line_parity_prime & 0x10) t |= 0x01;
+       ecc[1] = ~t;
+       
+       t = 0;
+       if(line_parity       & 0x08) t |= 0x80;
+       if(line_parity_prime & 0x08) t |= 0x40;
+       if(line_parity       & 0x04) t |= 0x20;
+       if(line_parity_prime & 0x04) t |= 0x10;
+       if(line_parity       & 0x02) t |= 0x08;
+       if(line_parity_prime & 0x02) t |= 0x04;
+       if(line_parity       & 0x01) t |= 0x02;
+       if(line_parity_prime & 0x01) t |= 0x01;
+       ecc[0] = ~t;
+
+#if CONFIG_YAFFS_ECC_WRONG_ORDER
+       // Swap the bytes into the wrong order
+       t = ecc[0];
+       ecc[0] = ecc[1];
+       ecc[1] = t;
+#endif 
+}
+
+int yaffs_ECCCorrect(unsigned char *data, unsigned char *read_ecc, const unsigned char *test_ecc)
+{
+       unsigned char d0, d1, d2; // deltas 
+
+       d0 = read_ecc[0] ^ test_ecc[0];
+       d1 = read_ecc[1] ^ test_ecc[1];
+       d2 = read_ecc[2] ^ test_ecc[2];
+       
+       
+       
+       if((d0 | d1 | d2) == 0)
+       {
+               // no error
+               return 0;
+       }
+       
+       if( ((d0 ^ (d0 >> 1)) & 0x55) == 0x55 &&
+           ((d1 ^ (d1 >> 1)) & 0x55) == 0x55 &&
+           ((d2 ^ (d2 >> 1)) & 0x54) == 0x54)
+       {
+               // Single bit (recoverable) error in data
+
+               unsigned byte;
+               unsigned bit;
+
+#if CONFIG_YAFFS_ECC_WRONG_ORDER
+               // swap the bytes to correct for the wrong order
+               unsigned char t;
+               
+               t = d0;
+               d0 = d1;
+               d1 = t;
+#endif
+               
+               bit = byte = 0;
+               
+               
+               if(d1 & 0x80) byte |= 0x80;
+               if(d1 & 0x20) byte |= 0x40;
+               if(d1 & 0x08) byte |= 0x20;
+               if(d1 & 0x02) byte |= 0x10;
+               if(d0 & 0x80) byte |= 0x08;
+               if(d0 & 0x20) byte |= 0x04;
+               if(d0 & 0x08) byte |= 0x02;
+               if(d0 & 0x02) byte |= 0x01;
+
+               if(d2 & 0x80) bit |= 0x04;
+               if(d2 & 0x20) bit |= 0x02;
+               if(d2 & 0x08) bit |= 0x01;
+
+               data[byte] ^= (1 << bit);
+               
+               return 1;
+       }
+       
+       if((yaffs_CountBits(d0)+yaffs_CountBits(d1)+yaffs_CountBits(d2)) == 1)
+       {
+               // Reccoverable error in ecc
+               
+               read_ecc[0] = test_ecc[0];
+               read_ecc[1] = test_ecc[1];
+               read_ecc[2] = test_ecc[2];
+               
+               return 1;
+       }
+       
+       // Unrecoverable error
+       
+       return -1;
+           
+
+}
diff --git a/yaffs_ecc.h b/yaffs_ecc.h
new file mode 100644 (file)
index 0000000..e511737
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * YAFFS: Yet another FFS. A NAND-flash specific file system. 
+ *
+ * yaffs_ecc.c: ECC generation/correction algorithms.
+ *
+ * Copyright (C) 2002 Aleph One Ltd.
+ *
+ * Created by Charles Manning <charles@aleph1.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+ /*
+ * This code implements the ECC algorithm used in SmartMedia.
+ *
+ * The ECC comprises 22 bits of parity information and is stuffed into 3 bytes. 
+ * The two unused bit are set to 1.
+ * The ECC can correct single bit errors in a 256-byte page of data. Thus, two such ECC 
+ * blocks are used on a 512-byte NAND page.
+ *
+ */
+
+#ifndef __YAFFS_ECC_H__
+#define __YAFFS_ECC_H__
+void yaffs_ECCCalculate(const unsigned char *data,unsigned char *ecc);
+int yaffs_ECCCorrect(unsigned char *data, unsigned char *read_ecc, const unsigned char *test_ecc);
+#endif
index d82da3fc9bec225fc1975c573552d1d8e73ec4e3..5784d7956cc63d008c4df3045968e0839c90f70a 100644 (file)
  */
  //yaffs_guts.c
 
  */
  //yaffs_guts.c
 
-const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.24 2003-04-03 17:58:56 charles Exp $";
+const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.25 2003-05-20 22:30:35 charles Exp $";
 
 #include "yportenv.h"
 
 #include "yaffsinterface.h"
 #include "yaffs_guts.h"
 
 
 #include "yportenv.h"
 
 #include "yaffsinterface.h"
 #include "yaffs_guts.h"
 
-
-
-
 #define YAFFS_PASSIVE_GC_CHUNKS 2
 
 #define YAFFS_PASSIVE_GC_CHUNKS 2
 
+#if 0
+// Use Steven Hill's ECC struff instead
 // External functions for ECC on data
 void nand_calculate_ecc (const u_char *dat, u_char *ecc_code);
 int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc);
 // External functions for ECC on data
 void nand_calculate_ecc (const u_char *dat, u_char *ecc_code);
 int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc);
-
+#define yaffs_ECCCalculate(data,ecc) nand_calculate_ecc(data,ecc)
+#define yaffs_ECCCorrect(data,read_ecc,calc_ecc) nand_correct_ecc(data,read_ecc,calc_ecc)
+#else
+#include "yaffs_ecc.h"
+#endif
 
 // countBits is a quick way of counting the number of bits in a byte.
 // ie. countBits[n] holds the number of 1 bits in a byte with the value n.
 
 // countBits is a quick way of counting the number of bits in a byte.
 // ie. countBits[n] holds the number of 1 bits in a byte with the value n.
@@ -239,10 +242,10 @@ int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,
                int eccResult1,eccResult2;
                __u8 calcEcc[3];
                 
                int eccResult1,eccResult2;
                __u8 calcEcc[3];
                 
-                       nand_calculate_ecc(data,calcEcc);
-                       eccResult1 = nand_correct_data (data,spare->ecc1, calcEcc);
-                       nand_calculate_ecc(&data[256],calcEcc);
-                       eccResult2 = nand_correct_data (&data[256],spare->ecc2, calcEcc);
+                       yaffs_ECCCalculate(data,calcEcc);
+                       eccResult1 = yaffs_ECCCorrect (data,spare->ecc1, calcEcc);
+                       yaffs_ECCCalculate(&data[256],calcEcc);
+                       eccResult2 = yaffs_ECCCorrect(&data[256],spare->ecc2, calcEcc);
 
                        if(eccResult1>0)
                        {
 
                        if(eccResult1>0)
                        {
@@ -582,8 +585,8 @@ void yaffs_SetObjectName(yaffs_Object *obj, const char *name)
 
 void yaffs_CalcECC(const __u8 *data, yaffs_Spare *spare)
 {
 
 void yaffs_CalcECC(const __u8 *data, yaffs_Spare *spare)
 {
-       nand_calculate_ecc (data , spare->ecc1);
-       nand_calculate_ecc (&data[256] , spare->ecc2);
+       yaffs_ECCCalculate(data , spare->ecc1);
+       yaffs_ECCCalculate(&data[256] , spare->ecc2);
 }
 
 void yaffs_CalcTagsECC(yaffs_Tags *tags)
 }
 
 void yaffs_CalcTagsECC(yaffs_Tags *tags)
@@ -3620,7 +3623,7 @@ int yaffs_ResizeFile(yaffs_Object *in, int newSize)
                        // using yaffs_DeleteChunk
 
                        chunkId = yaffs_FindAndDeleteChunkInFile(in,i,NULL);
                        // using yaffs_DeleteChunk
 
                        chunkId = yaffs_FindAndDeleteChunkInFile(in,i,NULL);
-                       if(chunkId <= 0 || chunkId >= (dev->endBlock * 32))
+                       if(chunkId < (dev->startBlock * 32) || chunkId >= ((dev->endBlock+1) * 32))
                        {
                                //T(("Found daft chunkId %d for %d\n",chunkId,i));
                        }
                        {
                                //T(("Found daft chunkId %d for %d\n",chunkId,i));
                        }
@@ -4825,6 +4828,7 @@ int  yaffs_GetNumberOfFreeChunks(yaffs_Device *dev)
        int nFree;
        int pending;
        int b;
        int nFree;
        int pending;
        int b;
+       int nDirtyCacheChunks=0;
        
        yaffs_BlockInfo *blk;
        
        
        yaffs_BlockInfo *blk;
        
@@ -4872,6 +4876,20 @@ int  yaffs_GetNumberOfFreeChunks(yaffs_Device *dev)
 
        nFree += pending;
        
 
        nFree += pending;
        
+       // Now count the number of dirty chunks in the cache and subtract those
+       
+       {
+               int i;
+               for(i = 0; i < dev->nShortOpCaches; i++)
+               {
+                       if(dev->srCache[i].dirty) nDirtyCacheChunks++;
+               }
+       }
+       
+       nFree -= nDirtyCacheChunks;
+       
+       nFree -= ((dev->nReservedBlocks + 1) * dev->nChunksPerBlock);
+       
        if(nFree < 0) nFree = 0;
 
        return nFree;   
        if(nFree < 0) nFree = 0;
 
        return nFree;