Merge branch 'master' of ssh://www.aleph1.co.uk/home/aleph1/git/yaffs2
authorCharles Manning <cdhmanning@gmail.com>
Tue, 13 Nov 2012 18:16:47 +0000 (07:16 +1300)
committerCharles Manning <cdhmanning@gmail.com>
Tue, 13 Nov 2012 18:16:47 +0000 (07:16 +1300)
89 files changed:
Makefile
Makefile.kernel
direct/README.txt [new file with mode: 0644]
direct/basic-test/Makefile [deleted file]
direct/basic-test/yaffs_fileem2k.c [deleted file]
direct/basic-test/yaffs_fileem2k.h [deleted file]
direct/basic-test/yaffscfg2k.c [deleted file]
direct/basic-test/ynorsim.c [deleted file]
direct/handle_common.sh
direct/python/Makefile [deleted file]
direct/test-framework/FrameworkRules.mk [moved from direct/tests/Makefile with 71% similarity]
direct/test-framework/basic-tests/Makefile [new file with mode: 0644]
direct/test-framework/basic-tests/dtest.c [moved from direct/basic-test/dtest.c with 100% similarity]
direct/test-framework/python/Makefile [new file with mode: 0644]
direct/test-framework/python/README.txt [moved from direct/python/README.txt with 100% similarity]
direct/test-framework/python/README_yaffs_browser_py.txt [moved from direct/python/README_yaffs_browser_py.txt with 100% similarity]
direct/test-framework/python/README_yaffs_import_py.txt [moved from direct/python/README_yaffs_import_py.txt with 100% similarity]
direct/test-framework/python/examples.py [moved from direct/python/examples.py with 100% similarity]
direct/test-framework/python/yaffs_browser.py [moved from direct/python/yaffs_browser.py with 100% similarity]
direct/test-framework/python/yaffs_importer.py [moved from direct/python/yaffs_importer.py with 100% similarity]
direct/test-framework/python/yaffs_python_helper.c [moved from direct/python/yaffs_python_helper.c with 100% similarity]
direct/test-framework/python/yaffsfs.py [moved from direct/python/yaffsfs.py with 100% similarity]
direct/test-framework/tests/Makefile [new file with mode: 0644]
direct/test-framework/tests/README [moved from direct/tests/README with 100% similarity]
direct/test-framework/tests/fuzzer.c [moved from direct/tests/fuzzer.c with 100% similarity]
direct/test-framework/tests/init_fw_update_test_m18.sh [new file with mode: 0755]
direct/test-framework/tests/init_fw_update_test_nand.sh [moved from direct/tests/init_fw_update_test_nand.sh with 100% similarity]
direct/test-framework/tests/init_fw_update_test_nor.sh [moved from direct/tests/init_fw_update_test_nor.sh with 79% similarity]
direct/test-framework/tests/launch_tests.sh [moved from direct/tests/launch_tests.sh with 76% similarity]
direct/test-framework/tests/manage_m18_test.sh [new file with mode: 0755]
direct/test-framework/tests/manage_nand_test.sh [moved from direct/tests/manage_nand_test.sh with 100% similarity]
direct/test-framework/tests/manage_nor_test.sh [moved from direct/tests/manage_nor_test.sh with 100% similarity]
direct/test-framework/tests/nor_stress.c [moved from direct/tests/nor_stress.c with 97% similarity]
direct/test-framework/tests/nor_stress.h [moved from direct/tests/nor_stress.h with 100% similarity]
direct/test-framework/tests/run_fuzz_test_nand.sh [moved from direct/tests/run_fuzz_test_nand.sh with 100% similarity]
direct/test-framework/tests/run_fw_update_test_m18.sh [new file with mode: 0755]
direct/test-framework/tests/run_fw_update_test_nand.sh [moved from direct/tests/run_fw_update_test_nand.sh with 100% similarity]
direct/test-framework/tests/run_fw_update_test_nor.sh [moved from direct/tests/run_fw_update_test_nor.sh with 92% similarity]
direct/test-framework/tests/yaffs_fsx.c [moved from direct/tests/yaffs_fsx.c with 100% similarity]
direct/test-framework/tests/yaffs_fsx.h [moved from direct/tests/yaffs_fsx.h with 100% similarity]
direct/test-framework/tests/yaffs_test.c [moved from direct/tests/yaffs_test.c with 100% similarity]
direct/test-framework/yaffs_fileem.c [moved from direct/basic-test/yaffs_fileem.c with 97% similarity]
direct/test-framework/yaffs_fileem2k.c [new file with mode: 0644]
direct/test-framework/yaffs_fileem2k.h [new file with mode: 0644]
direct/test-framework/yaffs_m18_drv.c [moved from direct/basic-test/yaffs_norif1.c with 53% similarity]
direct/test-framework/yaffs_m18_drv.h [new file with mode: 0644]
direct/test-framework/yaffs_nor_drv.c [new file with mode: 0644]
direct/test-framework/yaffs_nor_drv.h [new file with mode: 0644]
direct/test-framework/yaffs_osglue.c [moved from direct/basic-test/yaffs_osglue.c with 94% similarity]
direct/test-framework/yaffs_ramdisk.c [moved from direct/basic-test/yaffs_ramdisk.c with 97% similarity]
direct/test-framework/yaffs_ramdisk.h [moved from direct/basic-test/yaffs_ramdisk.h with 100% similarity]
direct/test-framework/yaffs_ramem2k.c [moved from direct/basic-test/yaffs_ramem2k.c with 98% similarity]
direct/test-framework/yaffscfg.c [moved from direct/basic-test/yaffscfg.c with 100% similarity]
direct/test-framework/yaffscfg2k.c [new file with mode: 0644]
direct/test-framework/yaffsnewcfg.c [moved from direct/basic-test/yaffsnewcfg.c with 100% similarity]
direct/test-framework/ynorsim.c [new file with mode: 0644]
direct/test-framework/ynorsim.h [moved from direct/basic-test/yaffs_norif1.h with 53% similarity]
direct/test-framework/yramsim.c [moved from direct/basic-test/yramsim.c with 100% similarity]
direct/test-framework/yramsim.h [moved from direct/basic-test/yramsim.h with 100% similarity]
direct/timothy_tests/quick_tests/quick_tests.h
direct/u-boot/common/cmd_yaffs2.c
direct/u-boot/fs/yaffs2/yaffs_mtdif.c
direct/u-boot/fs/yaffs2/yaffs_uboot_glue.c
direct/u-boot/fs/yaffs2/yaffs_uboot_glue.h [new file with mode: 0644]
direct/yaffs_osglue.h
direct/yaffsfs.c
patch-ker.sh
yaffs_checkptrw.c
yaffs_guts.c
yaffs_guts.h
yaffs_linux.h
yaffs_mtdif.c [deleted file]
yaffs_mtdif.h
yaffs_mtdif1.h [deleted file]
yaffs_mtdif1_multi.c [deleted file]
yaffs_mtdif1_single.c [deleted file]
yaffs_mtdif2.h [deleted file]
yaffs_mtdif2_multi.c [deleted file]
yaffs_mtdif2_single.c [deleted file]
yaffs_mtdif_multi.c [new file with mode: 0644]
yaffs_mtdif_single.c [new file with mode: 0644]
yaffs_nand.c
yaffs_nand.h
yaffs_tagscompat.c
yaffs_tagscompat.h
yaffs_tagsmarshall.c [new file with mode: 0644]
yaffs_tagsmarshall.h [moved from direct/basic-test/ynorsim.h with 64% similarity]
yaffs_vfs_multi.c
yaffs_vfs_single.c

index 6722182858b5c8022474288cdc6d0a77334d56de..a34645895253a0555b3053923ed7bd8b80ded1ee 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -27,11 +27,12 @@ ifneq ($(KERNELRELEASE),)
 
        obj-m := $(YAFFS_O)
 
-       yaffs2-objs := yaffs_mtdif.o yaffs_mtdif2_single.o
-       yaffs2-objs += yaffs_mtdif1_single.o yaffs_packedtags1.o
+       yaffs2-objs := yaffs_mtdif_single.o
+       yaffs2-objs += yaffs_packedtags1.o
        yaffs2-objs += yaffs_ecc.o yaffs_vfs_single.o yaffs_guts.o
        yaffs2-objs += yaffs_packedtags2.o
        yaffs2-objs += yaffs_tagscompat.o
+       yaffs2-objs += yaffs_tagsmarshall.o
        yaffs2-objs += yaffs_checkptrw.o yaffs_nand.o
        yaffs2-objs += yaffs_checkptrw.o yaffs_nand.o yaffs_nameval.o
        yaffs2-objs += yaffs_allocator.o yaffs_bitmap.o yaffs_attribs.o
@@ -40,11 +41,12 @@ ifneq ($(KERNELRELEASE),)
        yaffs2-objs += yaffs_verify.o
        yaffs2-objs += yaffs_summary.o
 
-       yaffs2multi-objs := yaffs_mtdif.o yaffs_mtdif2_multi.o
-       yaffs2multi-objs += yaffs_mtdif1_multi.o yaffs_packedtags1.o
+       yaffs2multi-objs := yaffs_mtdif_multi.o
+       yaffs2multi-objs += yaffs_packedtags1.o
        yaffs2multi-objs += yaffs_ecc.o yaffs_vfs_multi.o yaffs_guts.o
        yaffs2multi-objs += yaffs_packedtags2.o
        yaffs2multi-objs += yaffs_tagscompat.o
+       yaffs2multi-objs += yaffs_tagsmarshall.o
        yaffs2multi-objs += yaffs_checkptrw.o yaffs_nand.o
        yaffs2multi-objs += yaffs_checkptrw.o yaffs_nand.o yaffs_nameval.o
        yaffs2multi-objs += yaffs_allocator.o yaffs_bitmap.o yaffs_attribs.o
index 6a8729c4b09440a84925c02f3ea72e1cc32cf55d..f9a9fb1bfdd405c71941422d8b026f2ac018427b 100644 (file)
@@ -6,8 +6,8 @@ obj-$(CONFIG_YAFFS_FS) += yaffs.o
 
 yaffs-y := yaffs_ecc.o yaffs_vfs.o yaffs_guts.o yaffs_checkptrw.o
 yaffs-y += yaffs_packedtags1.o yaffs_packedtags2.o yaffs_nand.o
-yaffs-y += yaffs_tagscompat.o
-yaffs-y += yaffs_mtdif.o yaffs_mtdif1.o yaffs_mtdif2.o
+yaffs-y += yaffs_tagscompat.o yaffs_tagsmarshall.o
+yaffs-y += yaffs_mtdif.o
 yaffs-y += yaffs_nameval.o yaffs_attribs.o
 yaffs-y += yaffs_allocator.o
 yaffs-y += yaffs_yaffs1.o
diff --git a/direct/README.txt b/direct/README.txt
new file mode 100644 (file)
index 0000000..2884681
--- /dev/null
@@ -0,0 +1,17 @@
+New Handling for Yaffs Core Code in Yaffs Direct
+
+In the past, the Yaffs core code was joined into the Yaffs direct code by
+means of symbolic links. This had to be changed when some Linux
+kernel-friendly changes were made.
+
+Now, the Yaffs core code needs to be slightly modified before use in Yaffs
+Direct. This is accomplished by a script that copies the code intto the
+Yaffs Direct "workspace" while using sed to modify some of the function 
+names etc. For example, strlen() is changed to yaffs_strlen() to allow these
+functions to be twaeked for use with unicode.
+
+This is accomplished by the script called handle_common.sh.
+
+cd yaffs2/direct
+./handle_common.sh copy
+
diff --git a/direct/basic-test/Makefile b/direct/basic-test/Makefile
deleted file mode 100644 (file)
index 026c0b8..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-# Makefile for YAFFS direct test
-#
-#
-# YAFFS: Yet another Flash File System. A NAND-flash specific file system.
-#
-# Copyright (C) 2003-2010 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.
-#
-# NB Warning this Makefile does not include header dependencies.
-#
-# $Id: Makefile,v 1.24 2010-02-17 02:18:57 charles Exp $
-
-#EXTRA_COMPILE_FLAGS = -DYAFFS_IGNORE_TAGS_ECC
-
-CFLAGS =      -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_YAFFS2 -D CONFIG_YAFFS_DEFINES_TYPES
-CFLAGS +=     -DCONFIG_YAFFS_PROVIDE_DEFS -DCONFIG_YAFFSFS_PROVIDE_VALUES -DNO_Y_INLINE
-CFLAGS +=    -Wall -g $(EXTRA_COMPILE_FLAGS) -Werror=strict-aliasing 
-#CFLAGS +=    -fno-strict-aliasing
-CFLAGS +=    -O0
-#CFLAGS +=    -DVALGRIND_TEST
-#CFLAGS +=     -DCONFIG_YAFFS_CASE_INSENSITIVE
-
-CFLAGS+=   -Wshadow -Werror=pointer-arith -Werror=write-strings
-CFLAGS+=   -Werror=strict-prototypes -Werror=missing-parameter-type
-CFLAGS+=   -Werror=redundant-decls -Werror=nested-externs -Winline
-CFLAGS+=   -Werror=undef
-
-CFLAGS+=   -DCONFIG_YAFFS_USE_PTHREADS -lpthread
-
-
-COMMONTESTOBJS = yaffscfg2k.o yaffs_osglue.o yaffs_hweight.o \
-                yaffs_ecc.o yaffs_fileem.o yaffs_fileem2k.o yaffsfs.o yaffs_guts.o \
-                yaffs_packedtags1.o yaffs_ramdisk.o yaffs_ramem2k.o \
-                yaffs_tagscompat.o yaffs_packedtags2.o yaffs_nand.o \
-                yaffs_checkptrw.o  yaffs_qsort.o\
-                yaffs_nameval.o yaffs_attribs.o \
-                yaffs_norif1.o  ynorsim.o \
-                yaffs_allocator.o \
-                yaffs_bitmap.o \
-                yaffs_yaffs1.o \
-                yaffs_yaffs2.o \
-                yaffs_verify.o \
-                yaffs_summary.o
-
-#               yaffs_checkptrwtest.o\
-
-
-YAFFSDIRECTSYMLINKS = \
-          yaffs_ecc.c yaffs_ecc.h yaffs_guts.c yaffs_guts.h \
-          yaffs_tagscompat.c yaffs_tagscompat.h \
-          yaffs_packedtags1.c yaffs_packedtags1.h yaffs_packedtags2.c yaffs_packedtags2.h \
-          yaffs_nand.c yaffs_nand.h yaffs_getblockinfo.h \
-          yaffs_checkptrw.h yaffs_checkptrw.c \
-          yaffs_nameval.c yaffs_nameval.h \
-          yaffs_trace.h yaffs_attribs.h \
-          yaffs_allocator.c yaffs_allocator.h \
-          yaffs_yaffs1.c yaffs_yaffs1.h \
-          yaffs_yaffs2.c yaffs_yaffs2.h \
-          yaffs_bitmap.c yaffs_bitmap.h \
-          yaffs_verify.c yaffs_verify.h \
-          yaffs_summary.c yaffs_summary.h \
-         yaffsfs.c yaffs_flashif.h yaffs_flashif2.h\
-          yaffsfs.h yaffs_osglue.h ydirectenv.h \
-          yaffscfg.h yaffs_list.h \
-          yaffs_qsort.c yportenv.h yaffs_attribs.c \
-          yaffs_nandif.c yaffs_nandif.h yaffs_nandemul2k.h \
-          yaffs_hweight.h yaffs_hweight.c \
-
-
-
-DIRECTTESTOBJS = $(COMMONTESTOBJS) dtest.o
-
-BOOTTESTOBJS = bootldtst.o yboot.o yaffs_fileem.o nand_ecc.o
-
-ALLOBJS = $(sort $(DIRECTTESTOBJS) $(YAFFSTESTOBJS))
-
-TARGETS = directtest2k
-
-all: $(TARGETS)
-
-$(ALLOBJS): %.o: %.c
-       gcc -c $(CFLAGS) -o $@ $<
-
-
-$(YAFFSDIRECTSYMLINKS):
-       ln -s ../$@ $@
-
-
-directtest2k: $(YAFFSDIRECTSYMLINKS) $(DIRECTTESTOBJS)
-       gcc -o $@ $(DIRECTTESTOBJS)
-
-yaffs_test: $(YAFFSDIRECTSYMLINKS) $(YAFFSTESTOBJS)
-       gcc -o $@ $(YAFFSTESTOBJS)
-
-
-boottest: $(YAFFSDIRECTSYMLINKS) $(BOOTTESTOBJS)
-       gcc -o $@ $(BOOTTESTOBJS)
-
-
-clean:
-       rm -f $(TARGETS) $(ALLOBJS) core $(YAFFSDIRECTSYMLINKS)
diff --git a/direct/basic-test/yaffs_fileem2k.c b/direct/basic-test/yaffs_fileem2k.c
deleted file mode 100644 (file)
index 836d1f7..0000000
+++ /dev/null
@@ -1,602 +0,0 @@
-/*
- * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
- *
- * Copyright (C) 2002-2011 Aleph One Ltd.
- *   for Toby Churchill Ltd and Brightstar Engineering
- *
- * 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 provides a YAFFS nand emulation on a file for emulating 2kB pages.
- * This is only intended as test code to test persistence etc.
- */
-
-const char *yaffs_flashif2_c_version = "$Id: yaffs_fileem2k.c,v 1.24 2010-02-18 01:18:04 charles Exp $";
-
-
-#include "yportenv.h"
-#include "yaffs_trace.h"
-
-#include "yaffs_flashif2.h"
-#include "yaffs_guts.h"
-#include "yaffs_fileem2k.h"
-#include "yaffs_packedtags2.h"
-
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h> 
-
-
-
-#define REPORT_ERROR 0
-
-typedef struct 
-{
-       u8 data[PAGE_SIZE]; // Data + spare
-} yflash_Page;
-
-typedef struct
-{
-       yflash_Page page[PAGES_PER_BLOCK]; // The pages in the block
-       
-} yflash_Block;
-
-
-
-#define MAX_HANDLES 20
-#define BLOCKS_PER_HANDLE (32*8)
-
-typedef struct
-{
-       int handle[MAX_HANDLES];
-       int nBlocks;
-} yflash_Device;
-
-static yflash_Device filedisk;
-
-int yaffs_test_partial_write = 0;
-
-extern int random_seed;
-extern int simulate_power_failure;
-static int remaining_ops;
-static int nops_so_far;
-
-int ops_multiplier;
-
-
-static void yflash2_MaybePowerFail(unsigned int nand_chunk, int failPoint)
-{
-
-   nops_so_far++;
-   
-   
-   remaining_ops--;
-   if(simulate_power_failure &&
-      remaining_ops < 1){
-       printf("Simulated power failure after %d operations\n",nops_so_far);
-       printf("  power failed on nand_chunk %d, at fail point %d\n",
-                               nand_chunk, failPoint);
-       exit(0);
-  }
-}
-
-
-
-
-
-static u8 localBuffer[PAGE_SIZE];
-
-static char *NToName(char *buf,int n)
-{
-       sprintf(buf,"emfile-2k-%d",n);
-       return buf;
-}
-
-static char dummyBuffer[BLOCK_SIZE];
-
-static int GetBlockFileHandle(int n)
-{
-       int h;
-       int requiredSize;
-       
-       char name[40];
-       NToName(name,n);
-       int fSize;
-       int i;
-       
-       h =  open(name, O_RDWR | O_CREAT, S_IREAD | S_IWRITE);
-       if(h >= 0){
-               fSize = lseek(h,0,SEEK_END);
-               requiredSize = BLOCKS_PER_HANDLE * BLOCK_SIZE;
-               if(fSize < requiredSize){
-                  for(i = 0; i < BLOCKS_PER_HANDLE; i++)
-                       if(write(h,dummyBuffer,BLOCK_SIZE) != BLOCK_SIZE)
-                               return -1;
-                       
-               }
-       }
-       
-       return h;
-
-}
-
-static int  CheckInit(void)
-{
-       static int initialised = 0;
-       int i;
-
-       int blk;
-
-       
-       if(initialised) 
-       {
-               return YAFFS_OK;
-       }
-
-       initialised = 1;
-       
-
-       srand(random_seed);
-       remaining_ops = (rand() % 1000) * 5;
-       memset(dummyBuffer,0xff,sizeof(dummyBuffer));
-
-       
-       
-       filedisk.nBlocks = SIZE_IN_MB * BLOCKS_PER_MB;
-
-       for(i = 0; i <  MAX_HANDLES; i++)
-               filedisk.handle[i] = -1;
-       
-       for(i = 0,blk = 0; blk < filedisk.nBlocks; blk+=BLOCKS_PER_HANDLE,i++)
-               filedisk.handle[i] = GetBlockFileHandle(i);
-       
-       
-       return 1;
-}
-
-
-int yflash2_GetNumberOfBlocks(void)
-{
-       CheckInit();
-       
-       return filedisk.nBlocks;
-}
-
-int yflash2_WriteChunkWithTagsToNAND(struct yaffs_dev *dev,int nand_chunk,const u8 *data, const struct yaffs_ext_tags *tags)
-{
-       int written;
-       int pos;
-       int h;
-       int i;
-       int nRead;
-       int error;
-       
-       yaffs_trace(YAFFS_TRACE_MTD, "write chunk %d data %p tags %p",nand_chunk, data, tags);
-
-       CheckInit();
-       
-       
-       if(dev->param.inband_tags){
-               
-               struct yaffs_packed_tags2_tags_only * pt2tp;
-               pt2tp = (struct yaffs_packed_tags2_tags_only *)&data[dev->data_bytes_per_chunk];
-               yaffs_pack_tags2_tags_only(pt2tp,tags);
-               
-               pos = (nand_chunk % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE;
-               h = filedisk.handle[(nand_chunk / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
-                                                       
-               lseek(h,pos,SEEK_SET);
-               written = write(h,data,dev->param.total_bytes_per_chunk);
-
-               
-               if(yaffs_test_partial_write){
-                       close(h);
-                       exit(1);
-               }
-               
-               if(written != dev->param.total_bytes_per_chunk) return YAFFS_FAIL;
-
-
-       }
-       
-       else {
-               /* First do a write of a partial page */
-               int n_partials;
-               int bpos;
-
-               if(data)
-               {
-                       pos = (nand_chunk % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE;
-                       h = filedisk.handle[(nand_chunk / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
-               
-                       
-                       memcpy(localBuffer,data, dev->data_bytes_per_chunk);
-                       
-                       n_partials = rand()%20;
-                       
-                       for(i = 0; i < n_partials; i++){
-                               bpos = rand() % dev->data_bytes_per_chunk;
-                               
-                               localBuffer[bpos] |= (1 << (rand() & 7));
-                       }
-                 
-                       if(REPORT_ERROR && memcmp(localBuffer,data,dev->data_bytes_per_chunk))
-                               printf("nand simulator: data does not match\n");
-                       
-                       lseek(h,pos,SEEK_SET);
-                       written = write(h,localBuffer,dev->data_bytes_per_chunk);
-               
-                       if(yaffs_test_partial_write){
-                               close(h);
-                               exit(1);
-                       }
-
-
-                       if(written != dev->data_bytes_per_chunk) return YAFFS_FAIL;
-               }
-               // yflash2_MaybePowerFail(nand_chunk,1);
-       
-               if(tags)
-               {
-                       pos = (nand_chunk % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE + PAGE_DATA_SIZE ;
-                       h = filedisk.handle[(nand_chunk / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
-               
-                       lseek(h,pos,SEEK_SET);
-
-                       if( 0 && dev->param.is_yaffs2)
-                       {
-                       
-                               written = write(h,tags,sizeof(struct yaffs_ext_tags));
-                               if(written != sizeof(struct yaffs_ext_tags)) return YAFFS_FAIL;
-                       }
-                       else
-                       {
-                               struct yaffs_packed_tags2 pt;
-                               yaffs_pack_tags2(&pt,tags, !dev->param.no_tags_ecc);
-                               u8 * ptab = (u8 *)&pt;
-
-                               nRead = read(h,localBuffer,sizeof(pt));
-                               for(i = error = 0; REPORT_ERROR && i < sizeof(pt) && !error; i++){
-                                       if(localBuffer[i] != 0xFF){
-                                               printf("nand simulation: chunk %d oob byte %d was %0x2\n",
-                                                       nand_chunk,i,localBuffer[i]);
-                                                       error = 1;
-                                       }
-                               }
-               
-                               for(i = 0; i < sizeof(pt); i++)
-                               localBuffer[i] &= ptab[i];
-                               
-                               n_partials = rand()% sizeof(pt);
-                       
-                               for(i = 0; i < n_partials; i++){
-                                       bpos = rand() % sizeof(pt);
-                               
-                                       localBuffer[bpos] |= (1 << (rand() & 7));
-                               }                       
-                        
-                               if(REPORT_ERROR && memcmp(localBuffer,&pt,sizeof(pt)))
-                                       printf("nand sim: tags corruption\n");
-                               
-                               lseek(h,pos,SEEK_SET);
-                       
-                               written = write(h,localBuffer,sizeof(pt));
-                               if(written != sizeof(pt)) return YAFFS_FAIL;
-                       }
-               }
-               
-               //yflash2_MaybePowerFail(nand_chunk,2);
-               
-               /* Next do the whole write */
-               if(data)
-               {
-                       pos = (nand_chunk % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE;
-                       h = filedisk.handle[(nand_chunk / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
-               
-                       
-                       memset(localBuffer,0xFF, PAGE_SIZE);            
-                       for(i = 0; i < dev->data_bytes_per_chunk; i++){
-                               localBuffer[i] &= data[i];
-                       }
-                 
-                       if(REPORT_ERROR && memcmp(localBuffer,data,dev->data_bytes_per_chunk))
-                               printf("nand simulator: data does not match\n");
-                       
-                       lseek(h,pos,SEEK_SET);
-                       written = write(h,localBuffer,dev->data_bytes_per_chunk);
-               
-                       if(yaffs_test_partial_write){
-                               close(h);
-                               exit(1);
-                       }
-
-
-                       if(written != dev->data_bytes_per_chunk) return YAFFS_FAIL;
-               }
-       
-               if(tags)
-               {
-                       pos = (nand_chunk % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE + PAGE_DATA_SIZE ;
-                       h = filedisk.handle[(nand_chunk / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
-               
-                       lseek(h,pos,SEEK_SET);
-
-                       if( 0 && dev->param.is_yaffs2)
-                       {
-                       
-                               written = write(h,tags,sizeof(struct yaffs_ext_tags));
-                               if(written != sizeof(struct yaffs_ext_tags)) return YAFFS_FAIL;
-                       }
-                       else
-                       {
-                               struct yaffs_packed_tags2 pt;
-                               yaffs_pack_tags2(&pt,tags,!dev->param.no_tags_ecc);
-                               u8 * ptab = (u8 *)&pt;
-
-                               nRead = read(h,localBuffer,sizeof(pt));
-                               for(i = error = 0; REPORT_ERROR && i < sizeof(pt) && !error; i++){
-                                       if(localBuffer[i] != 0xFF){
-                                               printf("nand simulation: chunk %d oob byte %d was %0x2\n",
-                                                       nand_chunk,i,localBuffer[i]);
-                                                       error = 1;
-                                       }
-                               }
-               
-                               for(i = 0; i < sizeof(pt); i++)
-                               localBuffer[i] &= ptab[i];
-                        
-                               if(REPORT_ERROR && memcmp(localBuffer,&pt,sizeof(pt)))
-                                       printf("nand sim: tags corruption\n");
-                               
-                               lseek(h,pos,SEEK_SET);
-                       
-                               written = write(h,localBuffer,sizeof(pt));
-                               if(written != sizeof(pt)) return YAFFS_FAIL;
-                       }
-               }
-               
-               yflash2_MaybePowerFail(nand_chunk,3);
-       
-       }
-       return YAFFS_OK;        
-
-}
-
-int yaffs_check_all_ff(const u8 *ptr, int n)
-{
-       while(n)
-       {
-               n--;
-               if(*ptr!=0xFF) return 0;
-               ptr++;
-       }
-       return 1;
-}
-
-
-static int fail300 = 1;
-static int fail320 = 1;
-
-static int failRead10 = 2;
-
-int yflash2_ReadChunkWithTagsFromNAND(struct yaffs_dev *dev,int nand_chunk, u8 *data, struct yaffs_ext_tags *tags)
-{
-       int nread;
-       int pos;
-       int h;
-       int localData = 0;
-       int retval = YAFFS_OK;
-       int nRead;
-       
-       yaffs_trace(YAFFS_TRACE_MTD,"read chunk %d data %p tags %p",nand_chunk, data, tags);
-       
-       CheckInit();
-       
-       
-       
-       
-       if(dev->param.inband_tags){
-               /* Got to suck the tags out of the data area */
-               if(!data) {
-                       localData=1;
-                       data = yaffs_get_temp_buffer(dev);
-               }
-
-               
-               struct yaffs_packed_tags2_tags_only * pt2tp;
-               pt2tp = (struct yaffs_packed_tags2_tags_only *)&data[dev->data_bytes_per_chunk];
-
-               
-               pos = (nand_chunk % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE;
-               h = filedisk.handle[(nand_chunk / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
-               
-               lseek(h,pos,SEEK_SET);
-
-               nRead = read(h, data,dev->param.total_bytes_per_chunk);
-
-               yaffs_unpack_tags2_tags_only(tags,pt2tp);
-               
-               if(nread != dev->param.total_bytes_per_chunk)
-                       retval = YAFFS_FAIL;
-                       
-               if(localData)
-                       yaffs_release_temp_buffer(dev, data);
-
-
-
-       }
-       
-       else {
-       
-               if(data)
-               {
-
-                       pos = (nand_chunk % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE;
-                       h = filedisk.handle[(nand_chunk / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];              
-                       lseek(h,pos,SEEK_SET);
-                       nread = read(h,data,dev->data_bytes_per_chunk);
-               
-               
-                       if(nread != dev->data_bytes_per_chunk) 
-                               retval = YAFFS_FAIL;
-               }
-       
-               if(tags)
-               {
-                       pos = (nand_chunk % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE + PAGE_DATA_SIZE;
-                       h = filedisk.handle[(nand_chunk / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];              
-                       lseek(h,pos,SEEK_SET);
-
-                       if(0 && dev->param.is_yaffs2)
-                       {
-                               nread= read(h,tags,sizeof(struct yaffs_ext_tags));
-                               if(nread != sizeof(struct yaffs_ext_tags))
-                                        retval =  YAFFS_FAIL;
-                               if(yaffs_check_all_ff((u8 *)tags, sizeof(struct yaffs_ext_tags)))
-                                       memset(tags, 0, sizeof(struct yaffs_ext_tags));
-                               else
-                                       tags->chunk_used = 1;
-                       }
-                       else
-                       {
-                               struct yaffs_packed_tags2 pt;
-                               nread= read(h,&pt,sizeof(pt));
-                               yaffs_unpack_tags2(tags,&pt, !dev->param.no_tags_ecc);
-#ifdef SIMULATE_FAILURES
-                               if((nand_chunk >> 6) == 100) {
-                                       if(fail300 && tags->ecc_result == YAFFS_ECC_RESULT_NO_ERROR){
-                                               tags->ecc_result = YAFFS_ECC_RESULT_FIXED;
-                                               fail300 = 0;
-                                       }
-                               }
-                               
-                               if((nand_chunk >> 6) == 110) {
-                                       if(fail320 && tags->ecc_result == YAFFS_ECC_RESULT_NO_ERROR){
-                                               tags->ecc_result = YAFFS_ECC_RESULT_FIXED;
-                                               fail320 = 0;
-                                       }
-                               }
-#endif
-                               if(failRead10>0 && nand_chunk == 10){
-                                       failRead10--;
-                                       nread = 0;
-                               }
-                       
-                               if(nread != sizeof(pt))
-                                       retval = YAFFS_FAIL;
-                       }
-               }
-       }
-       
-
-
-       return retval;  
-
-}
-
-
-int yflash2_MarkNANDBlockBad(struct yaffs_dev *dev, int block_no)
-{
-       int written;
-       int h;
-       
-       struct yaffs_packed_tags2 pt;
-
-       CheckInit();
-       
-       memset(&pt,0,sizeof(pt));
-       h = filedisk.handle[(block_no / ( BLOCKS_PER_HANDLE))];
-       lseek(h,((block_no % BLOCKS_PER_HANDLE) * dev->param.chunks_per_block) * PAGE_SIZE + PAGE_DATA_SIZE,SEEK_SET);
-       written = write(h,&pt,sizeof(pt));
-               
-       if(written != sizeof(pt)) return YAFFS_FAIL;
-       
-       
-       return YAFFS_OK;
-       
-}
-
-int yflash2_EraseBlockInNAND(struct yaffs_dev *dev, int blockNumber)
-{
-
-       int i;
-       int h;
-               
-       CheckInit();
-       
-       //printf("erase block %d\n",blockNumber);
-       
-       if(blockNumber == 320)
-               fail320 = 1;
-       
-       if(blockNumber < 0 || blockNumber >= filedisk.nBlocks)
-       {
-               yaffs_trace(YAFFS_TRACE_ALWAYS,"Attempt to erase non-existant block %d",blockNumber);
-               return YAFFS_FAIL;
-       }
-       else
-       {
-       
-               u8 pg[PAGE_SIZE];
-               int syz = PAGE_SIZE;
-               int pos;
-               
-               memset(pg,0xff,syz);
-               
-
-               h = filedisk.handle[(blockNumber / ( BLOCKS_PER_HANDLE))];
-               lseek(h,((blockNumber % BLOCKS_PER_HANDLE) * dev->param.chunks_per_block) * PAGE_SIZE,SEEK_SET);                
-               for(i = 0; i < dev->param.chunks_per_block; i++)
-               {
-                       write(h,pg,PAGE_SIZE);
-               }
-               pos = lseek(h, 0,SEEK_CUR);
-               
-               return YAFFS_OK;
-       }
-       
-}
-
-int yflash2_InitialiseNAND(struct yaffs_dev *dev)
-{
-       CheckInit();
-       
-       return YAFFS_OK;
-}
-
-
-
-
-int yflash2_QueryNANDBlock(struct yaffs_dev *dev, int block_no, enum yaffs_block_state *state, u32 *seq_number)
-{
-       struct yaffs_ext_tags tags;
-       int chunkNo;
-
-       *seq_number = 0;
-       
-       chunkNo = block_no * dev->param.chunks_per_block;
-       
-       yflash2_ReadChunkWithTagsFromNAND(dev,chunkNo,NULL,&tags);
-       if(tags.block_bad)
-       {
-               *state = YAFFS_BLOCK_STATE_DEAD;
-       }
-       else if(!tags.chunk_used)
-       {
-               *state = YAFFS_BLOCK_STATE_EMPTY;
-       }
-       else if(tags.chunk_used)
-       {
-               *state = YAFFS_BLOCK_STATE_NEEDS_SCAN;
-               *seq_number = tags.seq_number;
-       }
-       return YAFFS_OK;
-}
-
diff --git a/direct/basic-test/yaffs_fileem2k.h b/direct/basic-test/yaffs_fileem2k.h
deleted file mode 100644 (file)
index e2e8dc3..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * YAFFS: Yet another Flash File System . A NAND-flash specific file system. 
- *
- * Copyright (C) 2002-2011 Aleph One Ltd.
- *   for Toby Churchill Ltd and Brightstar Engineering
- *
- * 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 Lesser General Public License version 2.1 as
- * published by the Free Software Foundation.
- *
- * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
- */
-
-#ifndef __FILEEM2K_H__
-#define __FILEEM2K_H__
-
-#if 1
-
-#define SIZE_IN_MB 32
-/* #define SIZE_IN_MB 128 */
-
-#define PAGE_DATA_SIZE (2048)
-#define PAGE_SPARE_SIZE  (64)
-#define PAGE_SIZE  (PAGE_DATA_SIZE + PAGE_SPARE_SIZE)
-#define PAGES_PER_BLOCK (64)
-#define BLOCK_DATA_SIZE (PAGE_DATA_SIZE * PAGES_PER_BLOCK)
-#define BLOCK_SIZE (PAGES_PER_BLOCK * (PAGE_SIZE))
-#define BLOCKS_PER_MB ((1024*1024)/BLOCK_DATA_SIZE)
-#define SIZE_IN_BLOCKS (BLOCKS_PER_MB * SIZE_IN_MB)
-
-#else
-
-#define SIZE_IN_MB 128
-#define PAGE_DATA_SIZE (512)
-#define SPARE_SIZE  (16)
-#define PAGE_SIZE  (PAGE_DATA_SIZE + SPARE_SIZE)
-#define PAGES_PER_BLOCK (32)
-#define BLOCK_DATA_SIZE (PAGE_SIZE * PAGES_PER_BLOCK)
-#define BLOCK_SIZE (PAGES_PER_BLOCK * (PAGE_SIZE))
-#define BLOCKS_PER_MB ((1024*1024)/BLOCK_DATA_SIZE)
-#define SIZE_IN_BLOCKS (BLOCKS_PER_MB * SIZE_IN_MB)
-
-#endif
-
-
-int yflash2_GetNumberOfBlocks(void);
-
-#endif
-
diff --git a/direct/basic-test/yaffscfg2k.c b/direct/basic-test/yaffscfg2k.c
deleted file mode 100644 (file)
index bbaacb9..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
- *
- * Copyright (C) 2002-2011 Aleph One Ltd.
- *   for Toby Churchill Ltd and Brightstar Engineering
- *
- * 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.
- */
-
-/*
- * yaffscfg2k.c  The configuration for the "direct" use of yaffs.
- *
- * This file is intended to be modified to your requirements.
- * There is no need to redistribute this file.
- */
-
-#include "yaffscfg.h"
-#include "yaffs_guts.h"
-#include "yaffsfs.h"
-#include "yaffs_fileem2k.h"
-#include "yaffs_nandemul2k.h"
-#include "yaffs_norif1.h"
-#include "yaffs_trace.h"
-#include "yaffs_osglue.h"
-
-
-#include <errno.h>
-
-unsigned yaffs_trace_mask =
-
-       YAFFS_TRACE_SCAN |
-       YAFFS_TRACE_GC |
-       YAFFS_TRACE_ERASE |
-       YAFFS_TRACE_ERROR |
-       YAFFS_TRACE_TRACING |
-       YAFFS_TRACE_ALLOCATE |
-       YAFFS_TRACE_BAD_BLOCKS |
-       YAFFS_TRACE_VERIFY |
-
-       0;
-
-
-
-// Configuration
-
-#include "yaffs_ramdisk.h"
-#include "yaffs_flashif.h"
-#include "yaffs_flashif2.h"
-#include "yaffs_nandemul2k.h"
-
-struct yaffs_dev ram1Dev;
-struct yaffs_dev flashDev;
-struct yaffs_dev m18_1Dev;
-
-int yaffs_start_up(void)
-{
-       static int start_up_called = 0;
-
-       if(start_up_called)
-               return;
-       start_up_called = 1;
-
-       // Stuff to configure YAFFS
-       // Stuff to initialise anything special (eg lock semaphore).
-       yaffsfs_OSInitialisation();
-
-       // Set up devices
-       // /ram1   ram, yaffs1
-       memset(&ram1Dev,0,sizeof(ram1Dev));
-       ram1Dev.param.name = "ram1";
-       ram1Dev.param.total_bytes_per_chunk = 512;
-       ram1Dev.param.chunks_per_block = 32;
-       ram1Dev.param.n_reserved_blocks = 2; // Set this smaller for RAM
-       ram1Dev.param.start_block = 0; // Can use block 0
-       ram1Dev.param.end_block = 127; // Last block in 2MB.
-       //ram1Dev.param.use_nand_ecc = 1;
-       ram1Dev.param.n_caches = 0;     // Disable caching on this device.
-       ram1Dev.driver_context = (void *) 0;    // Used to identify the device in fstat.
-       ram1Dev.param.write_chunk_tags_fn = yramdisk_wr_chunk;
-       ram1Dev.param.read_chunk_tags_fn = yramdisk_rd_chunk;
-       ram1Dev.param.erase_fn = yramdisk_erase;
-       ram1Dev.param.initialise_flash_fn = yramdisk_initialise;
-
-       yaffs_add_device(&ram1Dev);
-
-       // /M18-1 yaffs1 on M18 nor sim
-       memset(&m18_1Dev,0,sizeof(m18_1Dev));
-       m18_1Dev.param.name = "M18-1";
-       m18_1Dev.param.total_bytes_per_chunk = 1024;
-       m18_1Dev.param.chunks_per_block =248;
-       m18_1Dev.param.n_reserved_blocks = 2;
-       m18_1Dev.param.start_block = 0; // Can use block 0
-       m18_1Dev.param.end_block = 31; // Last block
-       m18_1Dev.param.use_nand_ecc = 0; // use YAFFS's ECC
-       m18_1Dev.param.n_caches = 10; // Use caches
-       m18_1Dev.param.disable_soft_del = 1;
-       m18_1Dev.driver_context = (void *) 1;   // Used to identify the device in fstat.
-       m18_1Dev.param.write_chunk_fn = ynorif1_WriteChunkToNAND;
-       m18_1Dev.param.read_chunk_fn = ynorif1_ReadChunkFromNAND;
-       m18_1Dev.param.erase_fn = ynorif1_EraseBlockInNAND;
-       m18_1Dev.param.initialise_flash_fn = ynorif1_InitialiseNAND;
-       m18_1Dev.param.deinitialise_flash_fn = ynorif1_Deinitialise_flash_fn;
-
-//     m18_1Dev.param.disable_soft_del = 1;
-
-       yaffs_add_device(&m18_1Dev);
-
-       // /yaffs2  yaffs2 file emulation
-       // 2kpage/64chunk per block
-       //
-       memset(&flashDev,0,sizeof(flashDev));
-       flashDev.param.name = "yaffs2";
-       flashDev.param.total_bytes_per_chunk = 2048;
-       flashDev.param.chunks_per_block = 64;
-       flashDev.param.n_reserved_blocks = 5;
-       flashDev.param.inband_tags = 0;
-       flashDev.param.start_block = 0;
-       flashDev.param.end_block = yflash2_GetNumberOfBlocks()-1;
-       flashDev.param.is_yaffs2 = 1;
-       flashDev.param.use_nand_ecc=1;
-       flashDev.param.wide_tnodes_disabled=0;
-       flashDev.param.refresh_period = 1000;
-       flashDev.param.n_caches = 10; // Use caches
-       flashDev.driver_context = (void *) 2;   // Used to identify the device in fstat.
-       flashDev.param.write_chunk_tags_fn = yflash2_WriteChunkWithTagsToNAND;
-       flashDev.param.read_chunk_tags_fn = yflash2_ReadChunkWithTagsFromNAND;
-       flashDev.param.erase_fn = yflash2_EraseBlockInNAND;
-       flashDev.param.initialise_flash_fn = yflash2_InitialiseNAND;
-       flashDev.param.bad_block_fn = yflash2_MarkNANDBlockBad;
-       flashDev.param.query_block_fn = yflash2_QueryNANDBlock;
-       flashDev.param.enable_xattr = 1;
-
-       yaffs_add_device(&flashDev);
-
-// todo        yaffs_initialise(yaffsfs_config);
-
-       return 0;
-}
-
-
-
diff --git a/direct/basic-test/ynorsim.c b/direct/basic-test/ynorsim.c
deleted file mode 100644 (file)
index 36bfa62..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
- *
- * Copyright (C) 2002-2011 Aleph One Ltd.
- *   for Toby Churchill Ltd and Brightstar Engineering
- *
- * 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.
- */
-
-#include "ynorsim.h"
-
-
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <time.h>
-
-#define YNORSIM_FNAME "emfile-nor"
-
-/* Set YNORSIM_BIT_CHANGES to a a value from 1..30 to 
- *simulate bit flipping as the programming happens. 
- * A low value results in faster simulation with less chance of encountering a partially programmed
- * word. 
- */
-   
-//#define YNORSIM_BIT_CHANGES 15
-#define YNORSIM_BIT_CHANGES 2
-
-#if 0
-/* Simulate 32MB of flash in 256k byte blocks.
- * This stuff is x32.
- */
-
-#define YNORSIM_BLOCK_SIZE_U32  (256*1024/4)
-#define YNORSIM_DEV_SIZE_U32   (32*1024 * 1024/4)
-#else
-/* Simulate 8MB of flash in 256k byte blocks.
- * This stuff is x32.
- */
-
-#define YNORSIM_BLOCK_SIZE_U32  (256*1024/4)
-#define YNORSIM_DEV_SIZE_U32   (8*1024 * 1024/4)
-#endif
-
-static u32 word[YNORSIM_DEV_SIZE_U32];
-
-extern int random_seed;
-extern int simulate_power_failure;
-
-static void NorError(void)
-{
-  printf("Nor error\n");
-  while(1){}
-}
-
-static void ynorsim_save_image(void)
-{
-  int h = open(YNORSIM_FNAME, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
-  write(h,word,sizeof(word));
-  close(h);
-}
-
-static void ynorsim_restore_image(void)
-{
-  int h = open(YNORSIM_FNAME, O_RDONLY, S_IREAD | S_IWRITE);
-  memset(word,0xFF,sizeof(word));
-  read(h,word,sizeof(word));
-  close(h);
-}
-
-
-static void ynorsim_power_fail(void)
-{
-  ynorsim_save_image();
-  exit(1);
-}
-
-static int initialised = 0;
-static int remaining_ops;
-static int nops_so_far;
-
-int ops_multiplier = 500;
-
-static void ynorsim_maybe_power_fail(void)
-{
-
-   nops_so_far++;
-   
-   
-   remaining_ops--;
-   if(simulate_power_failure &&
-      remaining_ops < 1){
-       printf("Simulated power failure after %d operations\n",nops_so_far);
-       ynorsim_power_fail();
-  }
-}
-
-static void ynorsim_ready(void)
-{
-  if(initialised) 
-    return;
-  srand(random_seed);
-  remaining_ops = 1000000000;
-  remaining_ops = (rand() % 10000) * ops_multiplier * YNORSIM_BIT_CHANGES;
-  ynorsim_restore_image();
-}
-
-void ynorsim_rd32(u32 *addr,u32 *buf, int nwords)
-{ 
-   while(nwords > 0){
-     *buf = *addr;
-     buf++;
-     addr++;
-     nwords--;
-   }
-}
-
-void ynorsim_wr_one_word32(u32 *addr,u32 val)
-{
-  u32 tmp;
-  u32 m;
-  int i;
-
-  tmp = *addr;
-  if(val & ~tmp){
-    // Fail due to trying to change a zero into a 1
-    printf("attempt to set a zero to one (%x)->(%x)\n",tmp,val);
-    NorError();
-  }
-  
-  for(i = 0; i < YNORSIM_BIT_CHANGES; i++){
-    m = 1 << (rand() & 31);
-    if(!(m & val)){
-      tmp &= ~m;
-      *addr = tmp;
-      ynorsim_maybe_power_fail();
-    }
-       
-  }
-  
-  *addr = tmp & val;
-  ynorsim_maybe_power_fail();
-}
-
-void ynorsim_wr32(u32 *addr, u32 *buf, int nwords)
-{
-  while(nwords >0){
-    ynorsim_wr_one_word32(addr,*buf);
-    addr++;
-    buf++;
-    nwords--;
-  }
-}
-
-void ynorsim_erase(u32 *addr)
-{
-  /* Todo... bit flipping */
-  memset(addr,0xFF,YNORSIM_BLOCK_SIZE_U32 * 4);
-}
-
-void ynorsim_initialise(void)
-{
-  ynorsim_ready();
-}
-
-void ynorsim_shutdown(void)
-{
-  ynorsim_save_image();
-  initialised=0;
-}
-
-u32 *ynorsim_get_base(void)
-{
-  return word;
-}
index 0e339f190ebd1c14003f33cea354da507e60f1bf..2b5a043c138ab14abc61c756eed3336bbd9d8ceb 100755 (executable)
@@ -3,6 +3,7 @@
 YAFFS_COMMON_SOURCES="\
           yaffs_ecc.c yaffs_ecc.h yaffs_guts.c yaffs_guts.h \
           yaffs_tagscompat.c yaffs_tagscompat.h \
+          yaffs_tagsmarshall.c yaffs_tagsmarshall.h \
           yaffs_packedtags1.c yaffs_packedtags1.h \
           yaffs_packedtags2.c yaffs_packedtags2.h \
           yaffs_nand.c yaffs_nand.h yaffs_getblockinfo.h \
@@ -19,6 +20,7 @@ YAFFS_COMMON_SOURCES="\
 
 
 if [ "$1" = "copy" ] ; then
+set -e -x
        for i in $YAFFS_COMMON_SOURCES ; do
                sed ../$i \
                -e "s/strcat/yaffs_strcat/g" \
diff --git a/direct/python/Makefile b/direct/python/Makefile
deleted file mode 100644 (file)
index 2c70f5a..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-# Makefile for YAFFS direct stress tests
-#
-#
-# YAFFS: Yet another Flash File System. A NAND-flash specific file system.
-#
-# Copyright (C) 2003-2010 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.
-#
-# NB Warning this Makefile does not include header dependencies.
-#
-# $Id: Makefile,v 1.6 2010-02-17 00:51:15 charles Exp $
-
-#EXTRA_COMPILE_FLAGS = -DYAFFS_IGNORE_TAGS_ECC
-
-CFLAGS =      -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_YAFFS2  -DCONFIG_YAFFS_DEFINES_TYPES
-CFLAGS +=     -DCONFIG_YAFFS_PROVIDE_DEFS -DCONFIG_YAFFSFS_PROVIDE_VALUES -DNO_Y_INLINE
-CFLAGS +=    -Wall -g $(EXTRA_COMPILE_FLAGS) -Wstrict-aliasing 
-#CFLAGS +=    -fno-strict-aliasing
-CFLAGS +=    -O0 -fPIC
-#CFLAGS +=    -DVALGRIND_TEST
-
-#CFLAGS+=   -Wshadow -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Wmissing-declarations
-#CFLAGS+=   -Wmissing-prototypes -Wredundant-decls -Wnested-externs -Winline
-
-
-COMMONTESTOBJS = yaffscfg2k.o yaffs_osglue.o yaffs_hweight.o\
-                yramsim.o yaffs_fileem2k.o\
-                yaffs_nandif.o yaffs_attribs.o \
-                yaffsfs.o  yaffs_ecc.o yaffs_guts.o \
-                yaffs_packedtags1.o yaffs_ramdisk.o yaffs_ramem2k.o \
-                yaffs_tagscompat.o yaffs_packedtags2.o yaffs_nand.o \
-                yaffs_checkptrw.o  yaffs_qsort.o\
-                yaffs_nameval.o \
-                yaffs_summary.o \
-                yaffs_allocator.o \
-                yaffs_norif1.o  ynorsim.o \
-                yaffs_bitmap.o \
-                yaffs_verify.o \
-                yaffs_yaffs1.o yaffs_yaffs2.o \
-                yaffs_error.o
-
-
-YAFFSLIBOBJS  = $(COMMONTESTOBJS) yaffs_python_helper.o
-
-
-
-          
-
-YAFFSDIRECTSYMLINKS =   \
-          yaffsfs.c yaffsfs.h yaffscfg.h yaffs_osglue.h  ydirectenv.h \
-          yaffs_flashif.h yaffs_flashif2.h yaffs_list.h \
-          yaffs_nandif.c yaffs_nandif.h yaffs_qsort.c yaffs_nandemul2k.h \
-          yportenv.h yaffs_attribs.c \
-          yaffs_hweight.c yaffs_hweight.h \
-          yaffs_error.c \
-          yaffs_ecc.c yaffs_ecc.h yaffs_guts.c yaffs_guts.h yaffs_tagscompat.c yaffs_tagscompat.h \
-          yaffs_packedtags1.c yaffs_packedtags1.h yaffs_packedtags2.c yaffs_packedtags2.h  \
-          yaffs_nand.c yaffs_nand.h yaffs_getblockinfo.h  \
-          yaffs_checkptrw.h yaffs_checkptrw.c \
-          yaffs_summary.c yaffs_summary.h \
-          yaffs_nameval.c yaffs_nameval.h yaffs_attribs.h \
-          yaffs_trace.h \
-          yaffs_allocator.c yaffs_allocator.h \
-          yaffs_yaffs1.c yaffs_yaffs1.h \
-          yaffs_yaffs2.c yaffs_yaffs2.h \
-          yaffs_bitmap.c yaffs_bitmap.h \
-          yaffs_verify.c yaffs_verify.h
-
-DIRECTEXTRASYMLINKS =   yaffscfg2k.c yaffs_fileem2k.c yaffs_fileem2k.h\
-                        yaffs_fileem.c yaffs_norif1.c yaffs_norif1.h \
-                        yaffs_ramdisk.c yaffs_ramdisk.h yaffs_ramem2k.c \
-                        yaffsnewcfg.c yramsim.c yramsim.h \
-                        ynorsim.h ynorsim.c yaffs_osglue.c
-                                                                        
-COPIED_SOURCES = $(YAFFSDIRECTSYMLINKS) $(DIRECTEXTRASYMLINKS)
-
-all:  libyaffsfs.so
-
-
-$(YAFFSLIBOBJS): %.o: %.c
-       gcc -c $(CFLAGS)   -o $@ $<
-
-
-$(YAFFSDIRECTSYMLINKS):
-       ln -s ../$@ $@
-
-$(DIRECTEXTRASYMLINKS):
-       ln -s ../basic-test/$@ $@
-
-
-libyaffsfs.so: $(COPIED_SOURCES) $(YAFFSLIBOBJS)
-       gcc -shared $(YAFFSLIBOBJS) -o $@
-
-
-clean:
-       rm -f  $(YAFFSLIBOBJS)  core $(COPIED_SOURCES)
-       rm -f libyaffsfs.so
-       rm -f *.pyc
similarity index 71%
rename from direct/tests/Makefile
rename to direct/test-framework/FrameworkRules.mk
index 4f6e3c3148d2ee8d078f260c8b29dfea3b38731a..52cd4da4ca04c506f31d950c0db9a81a125d212b 100644 (file)
@@ -1,4 +1,4 @@
-# Makefile for YAFFS direct stress tests
+# Makefile rules for building in test framwork
 #
 #
 # YAFFS: Yet another Flash File System. A NAND-flash specific file system.
 #
 # NB Warning this Makefile does not include header dependencies.
 #
-# $Id: Makefile,v 1.7 2010-02-25 22:34:47 charles Exp $
 
 #EXTRA_COMPILE_FLAGS = -DYAFFS_IGNORE_TAGS_ECC
 
 CFLAGS =      -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_YAFFS2  -DCONFIG_YAFFS_DEFINES_TYPES
 CFLAGS +=     -DCONFIG_YAFFS_PROVIDE_DEFS -DCONFIG_YAFFSFS_PROVIDE_VALUES
-CFLAGS +=    -Wall -g $(EXTRA_COMPILE_FLAGS) -Wstrict-aliasing 
+CFLAGS +=    -Wall -g $(EXTRA_COMPILE_FLAGS) -Wstrict-aliasing
 #CFLAGS +=    -fno-strict-aliasing
 CFLAGS +=    -O0
 CFLAGS +=    -Wextra -Wpointer-arith
@@ -33,10 +32,11 @@ CFLAGS +=    -Wextra -Wpointer-arith
 COMMONTESTOBJS = yaffscfg2k.o yaffs_osglue.o yaffs_hweight.o\
                 yaffs_ecc.o yaffs_fileem.o yaffs_fileem2k.o yaffsfs.o yaffs_guts.o \
                 yaffs_packedtags1.o yaffs_ramdisk.o yaffs_ramem2k.o \
-                yaffs_tagscompat.o yaffs_packedtags2.o yaffs_nand.o \
+                yaffs_tagscompat.o yaffs_tagsmarshall.o \
+                yaffs_packedtags2.o yaffs_nand.o \
                 yaffs_checkptrw.o  yaffs_qsort.o\
                 yaffs_nameval.o yaffs_attribs.o \
-                yaffs_norif1.o  ynorsim.o nor_stress.o yaffs_fsx.o \
+                yaffs_m18_drv.o  yaffs_nor_drv.o ynorsim.o \
                 yaffs_allocator.o \
                 yaffs_bitmap.o \
                 yaffs_yaffs1.o \
@@ -44,12 +44,9 @@ COMMONTESTOBJS = yaffscfg2k.o yaffs_osglue.o yaffs_hweight.o\
                 yaffs_verify.o \
                 yaffs_summary.o
 
-#               yaffs_checkptrwtest.o\
 
-YAFFSTESTOBJS  = $(COMMONTESTOBJS) yaffs_test.o
 
-
-ALLOBJS = $(sort $(YAFFSTESTOBJS))
+ALLOBJS = $(sort $(ALL_UNSORTED_OBJS))
 
 YAFFSDIRECTSYMLINKS =  \
           yaffsfs.c yaffs_flashif.h yaffs_flashif2.h\
@@ -61,6 +58,7 @@ YAFFSDIRECTSYMLINKS =  \
           yaffs_hweight.c yaffs_hweight.h \
           yaffs_ecc.c yaffs_ecc.h yaffs_guts.c yaffs_guts.h \
           yaffs_tagscompat.c yaffs_tagscompat.h \
+          yaffs_tagsmarshall.c yaffs_tagsmarshall.h \
           yaffs_packedtags1.c yaffs_packedtags1.h \
           yaffs_packedtags2.c yaffs_packedtags2.h  \
           yaffs_nand.c yaffs_nand.h yaffs_getblockinfo.h \
@@ -75,31 +73,24 @@ YAFFSDIRECTSYMLINKS =  \
           yaffs_summary.c yaffs_summary.h
 
 
-DIRECTEXTRASYMLINKS =  yaffscfg2k.c yaffs_fileem2k.c yaffs_fileem2k.h\
-                       yaffs_fileem.c yaffs_norif1.c yaffs_norif1.h \
-                       yaffs_ramdisk.c yaffs_ramdisk.h yaffs_ramem2k.c \
-                       ynorsim.h ynorsim.c yaffs_osglue.c
-
-COPIED_SOURCES = $(YAFFSDIRECTSYMLINKS) $(DIRECTEXTRASYMLINKS)
+FRAMEWORKEXTRASYMLINKS = \
+               yaffscfg2k.c yaffs_fileem2k.c yaffs_fileem2k.h\
+               yaffs_fileem.c yaffs_m18_drv.c yaffs_m18_drv.h \
+               yaffs_nor_drv.c yaffs_nor_drv.h \
+               yaffs_ramdisk.c yaffs_ramdisk.h yaffs_ramem2k.c \
+               ynorsim.h ynorsim.c yaffs_osglue.c
 
-all: yaffs_test fuzzer
-
-$(ALLOBJS): %.o: %.c
-       gcc -c $(CFLAGS) -o $@ $<
+FRAMEWORK_SOURCES = $(YAFFSDIRECTSYMLINKS) $(FRAMEWORKEXTRASYMLINKS)
 
+clean:
+       rm -f $(TARGETS) $(ALLOBJS) core $(FRAMEWORK_SOURCES)
 
 $(YAFFSDIRECTSYMLINKS):
-       ln -s ../$@ $@
+       ln -s $(YDI_DIR)/$@ $@
 
-$(DIRECTEXTRASYMLINKS):
-       ln -s ../basic-test/$@ $@
 
+$(FRAMEWORKEXTRASYMLINKS):
+       ln -s $(YDI_FRAMEWORK_DIR)/$@ $@
 
-yaffs_test: $(COPIED_SOURCES) $(YAFFSTESTOBJS)
-       gcc $(CFLLAG) -o $@ $(YAFFSTESTOBJS)
-
-fuzzer: fuzzer.c
-       gcc $(CFLAGS) -o $@ $<
-
-clean:
-       rm -f yaffs_test fuzzer fuzzer.o $(ALLOBJS) core $(COPIED_SOURCES)
+$(ALLOBJS): %.o: %.c
+       gcc -c $(CFLAGS)   -o $@ $<
diff --git a/direct/test-framework/basic-tests/Makefile b/direct/test-framework/basic-tests/Makefile
new file mode 100644 (file)
index 0000000..c1f3391
--- /dev/null
@@ -0,0 +1,36 @@
+# Makefile for YAFFS direct test
+#
+#
+# YAFFS: Yet another Flash File System. A NAND-flash specific file system.
+#
+# Copyright (C) 2003-2010 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.
+#
+# NB Warning this Makefile does not include header dependencies.
+#
+
+
+
+
+YDI_DIR = ../../
+YDI_FRAMEWORK_DIR = ../
+
+TARGETS = directtest2k
+
+all: $(TARGETS)
+
+DIRECTTESTOBJS = $(COMMONTESTOBJS) dtest.o
+
+ALL_UNSORTED_OBJS += $(DIRECTTESTOBJS)
+
+include ../FrameworkRules.mk
+
+directtest2k: $(FRAMEWORK_SOURCES) $(DIRECTTESTOBJS)
+       gcc -o $@ $(DIRECTTESTOBJS)
+
diff --git a/direct/test-framework/python/Makefile b/direct/test-framework/python/Makefile
new file mode 100644 (file)
index 0000000..9deee5e
--- /dev/null
@@ -0,0 +1,72 @@
+# Makefile for YAFFS direct stress tests
+#
+#
+# YAFFS: Yet another Flash File System. A NAND-flash specific file system.
+#
+# Copyright (C) 2003-2010 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.
+#
+# NB Warning this Makefile does not include header dependencies.
+#
+
+
+
+
+          
+
+
+$(YAFFSLIBOBJS): %.o: %.c
+       gcc -c $(CFLAGS)   -o $@ $<
+
+
+$(YAFFSDIRECTSYMLINKS):
+       ln -s ../$@ $@
+
+$(DIRECTEXTRASYMLINKS):
+       ln -s ../basic-test/$@ $@
+
+
+# Makefile for stress tests and fuzzer
+#
+#
+# YAFFS: Yet another Flash File System. A NAND-flash specific file system.
+#
+# Copyright (C) 2003-2010 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.
+#
+# NB Warning this Makefile does not include header dependencies.
+#
+
+YDI_DIR = ../../
+YDI_FRAMEWORK_DIR = ../
+
+TARGETS = libyaffsfs.so
+
+
+all: $(TARGETS)
+
+
+YAFFSLIBOBJS  = $(COMMONTESTOBJS) yaffs_python_helper.o
+
+ALL_UNSORTED_OBJS += $(YAFFSLIBOBJS)
+
+include ../FrameworkRules.mk
+
+CFLAGS +=    -O0 -fPIC
+
+
+libyaffsfs.so: $(FRAMEWORK_SOURCES) $(YAFFSLIBOBJS)
+       gcc -shared $(YAFFSLIBOBJS) -o $@
+
diff --git a/direct/test-framework/tests/Makefile b/direct/test-framework/tests/Makefile
new file mode 100644 (file)
index 0000000..cbfe151
--- /dev/null
@@ -0,0 +1,37 @@
+# Makefile for stress tests and fuzzer
+#
+#
+# YAFFS: Yet another Flash File System. A NAND-flash specific file system.
+#
+# Copyright (C) 2003-2010 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.
+#
+# NB Warning this Makefile does not include header dependencies.
+#
+
+YDI_DIR = ../../
+YDI_FRAMEWORK_DIR = ../
+
+TARGETS = yaffs_test fuzzer
+
+all: $(TARGETS)
+
+YAFFS_TEST_OBJS = $(COMMONTESTOBJS) yaffs_test.o nor_stress.o yaffs_fsx.o
+FUZZER_OBJS = fuzzer.o
+
+ALL_UNSORTED_OBJS += $(YAFFS_TEST_OBJS) $(FUZZER_OBJS)
+
+include ../FrameworkRules.mk
+
+
+yaffs_test: $(FRAMEWORK_SOURCES) $(YAFFS_TEST_OBJS)
+       gcc $(CFLLAG) -o $@ $(YAFFS_TEST_OBJS)
+
+fuzzer: $(FUZZER_OBJS)
+       gcc $(CFLAGS) -o $@ $<
diff --git a/direct/test-framework/tests/init_fw_update_test_m18.sh b/direct/test-framework/tests/init_fw_update_test_m18.sh
new file mode 100755 (executable)
index 0000000..0460897
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/bash
+# Run this to initialise the file system for the test runs.
+set -x
+rm seed-m18-*
+rm emfile-m18*
+./yaffs_test  -u -i M18-1
similarity index 79%
rename from direct/tests/init_fw_update_test_nor.sh
rename to direct/test-framework/tests/init_fw_update_test_nor.sh
index 8a0cb1af7a0e9c5e9f1e9fe29a0e9edd10e7d642..963f081d90395d9a6b75bfe0ea430a45603542ce 100755 (executable)
@@ -2,4 +2,4 @@
 # Run this to initialise the file system for the test runs.
 rm seed-nor-*
 rm emfile-nor*
-./yaffs_test  -u -i M18-1
+./yaffs_test  -u -i nor
similarity index 76%
rename from direct/tests/launch_tests.sh
rename to direct/test-framework/tests/launch_tests.sh
index 779fa48c5301406c162355e8460be59888d21003..b2041d3f1b62767aaa98d075b9b00503afe4bd8c 100755 (executable)
@@ -20,8 +20,13 @@ fi
 
 
 xterm  -e "$LAUNCHDIR/manage_nor_test.sh  0 $iterations"&
-xterm  -e "$LAUNCHDIR/manage_nand_test.sh  0 $iterations"&
 xterm  -e "$LAUNCHDIR/manage_nor_test.sh  1 $iterations"&
-xterm  -e "$LAUNCHDIR/manage_nand_test.sh  1 $iterations"&
 xterm  -e "$LAUNCHDIR/manage_nor_test.sh  2 $iterations"&
+
+xterm  -e "$LAUNCHDIR/manage_m18_test.sh  0 $iterations"&
+xterm  -e "$LAUNCHDIR/manage_m18_test.sh  1 $iterations"&
+xterm  -e "$LAUNCHDIR/manage_m18_test.sh  2 $iterations"&
+
+xterm  -e "$LAUNCHDIR/manage_nand_test.sh  0 $iterations"&
+xterm  -e "$LAUNCHDIR/manage_nand_test.sh  1 $iterations"&
 xterm  -e "$LAUNCHDIR/manage_nand_test.sh  2 $iterations"&
diff --git a/direct/test-framework/tests/manage_m18_test.sh b/direct/test-framework/tests/manage_m18_test.sh
new file mode 100755 (executable)
index 0000000..17a41a3
--- /dev/null
@@ -0,0 +1,28 @@
+#! /bin/sh
+
+set -x
+
+dir_id=-none
+[ -z $1 ] || dir_id=$1
+
+
+iterations=100000
+
+[ -z $2 ]  || iterations=$2
+
+STARTDIR=`pwd`
+RUNDIR=`pwd`/tmp/m18-$dir_id
+mkdir $RUNDIR
+cd $RUNDIR
+cp $STARTDIR/*sh .
+ln -s $STARTDIR/yaffs_test yaffs_test
+
+./init_fw_update_test_m18.sh
+./run_fw_update_test_m18.sh $iterations
+
+echo "!!!!!!!!!!!"
+echo "Tests done"
+while true
+do
+sleep 10
+done
similarity index 97%
rename from direct/tests/nor_stress.c
rename to direct/test-framework/tests/nor_stress.c
index 3905771a14d44d66b9ade78c5b81523e96b621cd..adf1b29d362e1638927e286b329c7a99d3dd892a 100644 (file)
@@ -51,7 +51,7 @@ static unsigned cycleEnds;
 static int interleave_fsx;
 
 static int no_verification;
+
 char fullPathName[100];
 char fullPowerUpName[100];
 char fullStartName[100];
@@ -96,7 +96,7 @@ static void FatalError(int line_no)
 
   if(ext_fatal)
        ext_fatal();
-       
+
   while(1){
    sleep(1);
   }
@@ -113,11 +113,11 @@ static void UpdateCounter(const char *name, unsigned *val,  int initialise)
   unsigned x[2];
   int nread = 0;
   int nwritten = 0;
-  
+
   x[0] = x[1] = 0;
-  
+
   if(initialise){
-    x[0] = 0; 
+    x[0] = 0;
     x[1] = 1;
   } else {
     inh = yaffs_open(name,O_RDONLY, S_IREAD | S_IWRITE);
@@ -132,18 +132,18 @@ static void UpdateCounter(const char *name, unsigned *val,  int initialise)
       printf("Error reading counter %s handle %d, x[0] %u x[1] %u last error %d\n",
               name, inh, x[0], x[1],yaffsfs_GetLastError());
       FatalError(__LINE__);
-              
+
     }
     x[0]++;
     x[1]++;
   }
-  
+
   FSX();
   outh = yaffs_open(fullTempCounterName, O_RDWR | O_TRUNC | O_CREAT, S_IREAD | S_IWRITE);
-  
+
   if(outh >= 0){
    struct yaffs_stat tmpstat, oldstat, tmpfstat;
-   FSX(); 
+   FSX();
     yaffs_fstat(outh,&tmpfstat);
     printf("\n\n\n*** Writing file %s inode %d\n",fullTempCounterName,tmpfstat.st_ino);
     nwritten = yaffs_write(outh,x,sizeof(x));
@@ -160,15 +160,15 @@ static void UpdateCounter(const char *name, unsigned *val,  int initialise)
     yaffs_rename(fullTempCounterName,name);
     FSX();
   }
-  
+
   if(nwritten != sizeof(x)){
       printf("Error writing counter %s handle %d, x[0] %u x[1] %u\n",
               name, inh, x[0], x[1]);
       FatalError(__LINE__);
   }
-  
+
   *val = x[0];
-  
+
   printf("##\n"
          "## Set counter %s to %u\n"
          "##\n", name,x[0]);
@@ -183,9 +183,9 @@ static void dump_directory_tree_worker(const char *dname,int recursive)
        char str[1000];
        int error_line = 0;
        int nentries;
-                       
+
        d = yaffs_opendir(dname);
-       
+
        if(!d)
        {
                printf("opendir failed\n");
@@ -199,9 +199,9 @@ static void dump_directory_tree_worker(const char *dname,int recursive)
                        strcat(str,"/");
                        strcat(str,de->d_name);
                        nentries++;
-                       
+
                        yaffs_lstat(str,&s);
-                       
+
                        printf("%s inode %ld %d obj %x length %d mode %X ",str, de->d_ino, s.st_ino,de->d_dont_use,(int)s.st_size,s.st_mode);\
                        if(de->d_ino != s.st_ino){
                                printf(" \n\n!!!! HEY inode mismatch\n\n");
@@ -216,21 +216,21 @@ static void dump_directory_tree_worker(const char *dname,int recursive)
                                                          if(yaffs_readlink(str,str,100) < 0)
                                                                printf("no alias");
                                                          else
-                                                               printf("\"%s\"",str);    
+                                                               printf("\"%s\"",str);
                                                          break;
                                default: printf("unknown"); break;
                        }
-                       
+
                        printf("\n");
 
                        if((s.st_mode & S_IFMT) == S_IFDIR && recursive)
                                dump_directory_tree_worker(str,1);
-                               
+
                         if(s.st_ino > 10000)
                                error_line = __LINE__;
-                                                       
+
                }
-               
+
                if(strstr(dname,"lost+found") && nentries >0){
                        printf("\n\n!!! HEY lost+found not empty, had %d entries\n\n\n",nentries);
                        error_line = __LINE__;
@@ -238,7 +238,7 @@ static void dump_directory_tree_worker(const char *dname,int recursive)
 
                if(error_line && !no_verification)
                        FatalError(error_line);
-               
+
                yaffs_closedir(d);
        }
 
@@ -265,13 +265,13 @@ static int y_wr_file(const char *fname, unsigned sz32)
        int i;
        struct yaffs_stat st;
        unsigned checksum = 0;
-       
+
 
        FSX();
        h = yaffs_open(fname,O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
        yaffs_fstat(h,&st);
        printf("\n\n\n**** Open writing file %s inode %d\n",fname, st.st_ino);
-       
+
        FSX();
 
        if(h < 0){
@@ -291,7 +291,7 @@ static int y_wr_file(const char *fname, unsigned sz32)
                  xx[i] = sz32 + i;
                  checksum ^= xx[i];
                 }
-                
+
                 FSX();
                if((r = yaffs_write(h,xx,sizeof(xx))) != sizeof(xx)){
                        goto WRITE_ERROR;
@@ -304,7 +304,7 @@ static int y_wr_file(const char *fname, unsigned sz32)
        if((r = yaffs_write(h,xx,sizeof(unsigned))) != sizeof(unsigned)){
                goto WRITE_ERROR;
        }
-       
+
        FSX();
        yaffs_close(h);
        printf("File closed\n");
@@ -314,7 +314,7 @@ WRITE_ERROR:
        printf("ywrite error at position %d\n",(int)yaffs_lseek(h,0,SEEK_END));
        yaffs_close(h);
        return -1;
-       
+
 }
 
 static int y_verify_file(const char *fName)
@@ -332,7 +332,7 @@ static int y_verify_file(const char *fName)
                return 0;
 
         printf("Verifying file %s\n",fName);
-               
+
        h = yaffs_open(fName, O_RDONLY,S_IREAD | S_IWRITE);
 
        if(h < 0){
@@ -350,7 +350,7 @@ static int y_verify_file(const char *fName)
                yaffs_close(h);
                return -1;
        }
-       
+
        recordedSize = sz32 * sizeof(xx) + 8;
 
        printf("verify %s: file size is %d, recorded size is %d\n", fName, totalSize, recordedSize);
@@ -380,7 +380,7 @@ static int y_verify_file(const char *fName)
                yaffs_close(h);
                return -1;
        }
-       
+
        checksum ^= xx[0];
 
        if(checksum != 0){
@@ -399,12 +399,12 @@ static void DoUpdateMainFile(void)
         int result;
         int sz32;
         sz32 = (myrand() % 1000)   + 20;
-        
+
        result = y_wr_file(fullTempMainName,sz32);
        FSX();
        if(!no_verification && result)
            FatalError(__LINE__);
-       printf("Raname file %s to %s\n",fullTempMainName,fullMainName);
+       printf("Rename file %s to %s\n",fullTempMainName,fullMainName);
        yaffs_rename(fullTempMainName,fullMainName);
        FSX();
 }
@@ -424,7 +424,7 @@ static void DoVerifyMainFile(void)
 void NorStressTestInitialise(const char *prefix)
 {
   MakeFullNames(prefix);
-  
+
   UpdateCounter(fullPowerUpName,&powerUps,1);
   UpdateCounter(fullStartName,&cycleStarts,1);
   UpdateCounter(fullEndName,&cycleEnds,1);
@@ -439,16 +439,16 @@ void NorStressTestRun(const char *prefix, int n_cycles, int do_fsx, int skip_ver
 
   interleave_fsx = do_fsx;
   no_verification = skip_verification;
+
   MakeFullNames(prefix);
   dump_directory_tree(fullPathName);
   FSX_INIT(prefix);
-    
+
   dump_directory_tree(fullPathName);
-  
+
   UpdateCounter(fullPowerUpName,&powerUps,0);
   dump_directory_tree(fullPathName);
-  
+
   while(n_cycles < 0 || n_cycles > 0){
     if(n_cycles > 0)
       n_cycles--;
@@ -457,7 +457,7 @@ void NorStressTestRun(const char *prefix, int n_cycles, int do_fsx, int skip_ver
     DoVerifyMainFile();
     DoUpdateMainFile();
     dump_directory_tree(fullPathName);
-  
+
     UpdateCounter(fullEndName,&cycleEnds,0);
     dump_directory_tree(fullPathName);
   }
diff --git a/direct/test-framework/tests/run_fw_update_test_m18.sh b/direct/test-framework/tests/run_fw_update_test_m18.sh
new file mode 100755 (executable)
index 0000000..f05a263
--- /dev/null
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+
+set -x
+
+iterations=100000
+
+[ -z $1 ]  || iterations=$1
+
+
+rm iteration-max-*
+touch iteration-max-$iterations
+
+echo " Running $iterations iterations"
+sleep 2
+
+for ((i=0; i < $iterations; i++))  
+do
+
+   seed=$RANDOM   
+   j=$(( $i % 10 ))
+
+   rm seed-m18-*$j
+   echo $seed>seed-m18-for-run-$i
+
+
+   rm emfile-m18-*$j
+   cp emfile-m18 emfile-m18-$i
+
+   rm log-m18-*$j
+
+   echo "#########"
+   echo "#########"
+   echo "#########"
+   echo "######### Run $i of $iterations with seed $seed"
+   echo "#########"
+   echo "#########"
+   echo "#########"
+   ./yaffs_test -u -f -p -s$seed -t0 M18-1
+   #>log-m18-$i
+done
+
similarity index 92%
rename from direct/tests/run_fw_update_test_nor.sh
rename to direct/test-framework/tests/run_fw_update_test_nor.sh
index 9265336111f592b3fac6b92aa40e496e1b7d7e06..82eebb7f195e24f265cf46d8efc936c8c3a7baff 100755 (executable)
@@ -33,7 +33,7 @@ do
    echo "#########"
    echo "#########"
    echo "#########"
-   ./yaffs_test -u -f -p -s$seed -t0 M18-1 
+   ./yaffs_test -u -f -p -s$seed -t0 nor
    #>log-nor-$i
 done
 
similarity index 97%
rename from direct/basic-test/yaffs_fileem.c
rename to direct/test-framework/yaffs_fileem.c
index 267e1341bc0d3d09805a94adb94b6e5a89d65372..96a64c61a32c1084abf9c361ececaf32351ebb9a 100644 (file)
@@ -16,9 +16,6 @@
  * This is only intended as test code to test persistence etc.
  */
 
-const char *yaffs_flashif_c_version = "$Id: yaffs_fileem.c,v 1.7 2010-02-18 01:18:04 charles Exp $";
-
-
 #include "yportenv.h"
 #include "yaffs_trace.h"
 
diff --git a/direct/test-framework/yaffs_fileem2k.c b/direct/test-framework/yaffs_fileem2k.c
new file mode 100644 (file)
index 0000000..b9a00f1
--- /dev/null
@@ -0,0 +1,400 @@
+/*
+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
+ *
+ * Copyright (C) 2002-2011 Aleph One Ltd.
+ *   for Toby Churchill Ltd and Brightstar Engineering
+ *
+ * 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 provides a YAFFS nand emulation on a file for emulating 2kB pages.
+ * This is only intended as test code to test persistence etc.
+ */
+
+#include "yportenv.h"
+#include "yaffs_trace.h"
+
+#include "yaffs_flashif2.h"
+#include "yaffs_guts.h"
+#include "yaffs_fileem2k.h"
+#include "yaffs_packedtags2.h"
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#if 1
+
+#define SIZE_IN_MB 32
+/* #define SIZE_IN_MB 128 */
+
+#define PAGE_DATA_SIZE (2048)
+#define PAGE_SPARE_SIZE  (64)
+#define PAGE_SIZE  (PAGE_DATA_SIZE + PAGE_SPARE_SIZE)
+#define PAGES_PER_BLOCK (64)
+#define BLOCK_DATA_SIZE (PAGE_DATA_SIZE * PAGES_PER_BLOCK)
+#define BLOCK_SIZE (PAGES_PER_BLOCK * (PAGE_SIZE))
+#define BLOCKS_PER_MB ((1024*1024)/BLOCK_DATA_SIZE)
+#define SIZE_IN_BLOCKS (BLOCKS_PER_MB * SIZE_IN_MB)
+
+#else
+
+#define SIZE_IN_MB 128
+#define PAGE_DATA_SIZE (512)
+#define SPARE_SIZE  (16)
+#define PAGE_SIZE  (PAGE_DATA_SIZE + SPARE_SIZE)
+#define PAGES_PER_BLOCK (32)
+#define BLOCK_DATA_SIZE (PAGE_SIZE * PAGES_PER_BLOCK)
+#define BLOCK_SIZE (PAGES_PER_BLOCK * (PAGE_SIZE))
+#define BLOCKS_PER_MB ((1024*1024)/BLOCK_DATA_SIZE)
+#define SIZE_IN_BLOCKS (BLOCKS_PER_MB * SIZE_IN_MB)
+
+#endif
+
+#define REPORT_ERROR 0
+
+typedef struct
+{
+       u8 data[PAGE_SIZE]; // Data + spare
+} yflash_Page;
+
+typedef struct
+{
+       yflash_Page page[PAGES_PER_BLOCK]; // The pages in the block
+
+} yflash_Block;
+
+
+
+#define MAX_HANDLES 20
+#define BLOCKS_PER_HANDLE (32*8)
+
+typedef struct
+{
+       int handle[MAX_HANDLES];
+       int nBlocks;
+} yflash_Device;
+
+static yflash_Device filedisk;
+
+int yaffs_test_partial_write = 0;
+
+extern int random_seed;
+extern int simulate_power_failure;
+static int remaining_ops;
+static int nops_so_far;
+
+int ops_multiplier;
+
+
+static void yflash2_MaybePowerFail(unsigned int nand_chunk, int failPoint)
+{
+
+   nops_so_far++;
+
+
+   remaining_ops--;
+   if(simulate_power_failure &&
+      remaining_ops < 1){
+       printf("Simulated power failure after %d operations\n",nops_so_far);
+       printf("  power failed on nand_chunk %d, at fail point %d\n",
+                               nand_chunk, failPoint);
+       exit(0);
+  }
+}
+
+
+
+
+
+static u8 localBuffer[PAGE_SIZE];
+
+static char *NToName(char *buf,int n)
+{
+       sprintf(buf,"emfile-2k-%d",n);
+       return buf;
+}
+
+static char dummyBuffer[BLOCK_SIZE];
+
+static int GetBlockFileHandle(int n)
+{
+       int h;
+       int requiredSize;
+
+       char name[40];
+       NToName(name,n);
+       int fSize;
+       int i;
+
+       h =  open(name, O_RDWR | O_CREAT, S_IREAD | S_IWRITE);
+       if(h >= 0){
+               fSize = lseek(h,0,SEEK_END);
+               requiredSize = BLOCKS_PER_HANDLE * BLOCK_SIZE;
+               if(fSize < requiredSize){
+                  for(i = 0; i < BLOCKS_PER_HANDLE; i++)
+                       if(write(h,dummyBuffer,BLOCK_SIZE) != BLOCK_SIZE)
+                               return -1;
+
+               }
+       }
+
+       return h;
+
+}
+
+static int  CheckInit(void)
+{
+       static int initialised = 0;
+       int i;
+
+       int blk;
+
+
+       if(initialised)
+       {
+               return YAFFS_OK;
+       }
+
+       initialised = 1;
+
+
+       srand(random_seed);
+       remaining_ops = (rand() % 1000) * 5;
+       memset(dummyBuffer,0xff,sizeof(dummyBuffer));
+
+
+
+       filedisk.nBlocks = SIZE_IN_MB * BLOCKS_PER_MB;
+
+       for(i = 0; i <  MAX_HANDLES; i++)
+               filedisk.handle[i] = -1;
+
+       for(i = 0,blk = 0; blk < filedisk.nBlocks; blk+=BLOCKS_PER_HANDLE,i++)
+               filedisk.handle[i] = GetBlockFileHandle(i);
+
+
+       return 1;
+}
+
+
+int yflash2_GetNumberOfBlocks(void)
+{
+       CheckInit();
+
+       return filedisk.nBlocks;
+}
+
+
+int yaffs_check_all_ff(const u8 *ptr, int n)
+{
+       while(n)
+       {
+               n--;
+               if(*ptr!=0xFF) return 0;
+               ptr++;
+       }
+       return 1;
+}
+
+
+static int yflash2_WriteChunk(struct yaffs_dev *dev, int nand_chunk,
+                                  const u8 *data, int data_len,
+                                  const u8 *oob, int oob_len)
+{
+       int retval = YAFFS_OK;
+       int pos;
+       int h;
+       int nwritten;
+
+       (void) dev;
+
+       if (data && data_len) {
+               pos = (nand_chunk % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE;
+               h = filedisk.handle[(nand_chunk / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
+               lseek(h,pos,SEEK_SET);
+               nwritten = write(h,data,data_len);
+               if(nwritten != data_len)
+                       retval = YAFFS_FAIL;
+       }
+
+       if (oob && oob_len) {
+               pos = (nand_chunk % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE + PAGE_DATA_SIZE;
+               h = filedisk.handle[(nand_chunk / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
+               lseek(h,pos,SEEK_SET);
+               nwritten = write(h,oob,oob_len);
+               if(nwritten != oob_len)
+                       retval = YAFFS_FAIL;
+       }
+
+       yflash2_MaybePowerFail(nand_chunk,3);
+
+       return retval;
+}
+
+static int yflash2_ReadChunk(struct yaffs_dev *dev, int nand_chunk,
+                                  u8 *data, int data_len,
+                                  u8 *oob, int oob_len,
+                                  enum yaffs_ecc_result *ecc_result)
+{
+       int retval = YAFFS_OK;
+       int pos;
+       int h;
+       int nread;
+
+       (void) dev;
+
+       if (data && data_len) {
+               pos = (nand_chunk % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE;
+               h = filedisk.handle[(nand_chunk / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
+               lseek(h,pos,SEEK_SET);
+               nread = read(h,data,data_len);
+               if(nread != data_len)
+                       retval = YAFFS_FAIL;
+       }
+
+       if (oob && oob_len) {
+               pos = (nand_chunk % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE + PAGE_DATA_SIZE;
+               h = filedisk.handle[(nand_chunk / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
+               lseek(h,pos,SEEK_SET);
+               nread = read(h,oob,oob_len);
+               if(nread != oob_len)
+                       retval = YAFFS_FAIL;
+       }
+
+       if (ecc_result)
+               *ecc_result = YAFFS_ECC_RESULT_NO_ERROR;
+
+       return retval;
+}
+
+static int yflash2_EraseBlock(struct yaffs_dev *dev, int block_no)
+{
+       int i;
+       int h;
+
+       CheckInit();
+
+       if(block_no < 0 || block_no >= filedisk.nBlocks)
+       {
+               yaffs_trace(YAFFS_TRACE_ALWAYS,"Attempt to erase non-existant block %d",block_no);
+               return YAFFS_FAIL;
+       }
+       else
+       {
+
+               u8 pg[PAGE_SIZE];
+               int syz = PAGE_SIZE;
+               int pos;
+
+               memset(pg,0xff,syz);
+
+
+               h = filedisk.handle[(block_no / ( BLOCKS_PER_HANDLE))];
+               lseek(h,((block_no % BLOCKS_PER_HANDLE) * dev->param.chunks_per_block) * PAGE_SIZE,SEEK_SET);
+               for(i = 0; i < dev->param.chunks_per_block; i++)
+               {
+                       write(h,pg,PAGE_SIZE);
+               }
+               pos = lseek(h, 0,SEEK_CUR);
+
+               return YAFFS_OK;
+       }
+}
+
+static int yflash2_MarkBad(struct yaffs_dev *dev, int block_no)
+{
+       int written;
+       int h;
+
+       struct yaffs_packed_tags2 pt;
+
+       CheckInit();
+
+       memset(&pt,0,sizeof(pt));
+       h = filedisk.handle[(block_no / ( BLOCKS_PER_HANDLE))];
+       lseek(h,((block_no % BLOCKS_PER_HANDLE) * dev->param.chunks_per_block) * PAGE_SIZE + PAGE_DATA_SIZE,SEEK_SET);
+       written = write(h,&pt,sizeof(pt));
+
+       if(written != sizeof(pt))
+               return YAFFS_FAIL;
+
+       return YAFFS_OK;
+
+}
+
+static int yflash2_CheckBad(struct yaffs_dev *dev, int block_no)
+{
+       (void) dev;
+       (void) block_no;
+
+       return YAFFS_OK;
+}
+
+static int yflash2_Initialise(struct yaffs_dev *dev)
+{
+       (void) dev;
+
+       CheckInit();
+
+       return YAFFS_OK;
+}
+
+struct yaffs_dev *yflash2_install_drv(const char *name)
+{
+       struct yaffs_dev *dev = NULL;
+       struct yaffs_param *param;
+       struct yaffs_driver *drv;
+
+       dev = malloc(sizeof(*dev));
+
+       if(!dev)
+               return NULL;
+
+       memset(dev, 0, sizeof(*dev));
+
+       dev->param.name = strdup(name);
+
+       if(!dev->param.name) {
+               free(dev);
+               return NULL;
+       }
+
+       drv = &dev->drv;
+
+       drv->drv_write_chunk_fn = yflash2_WriteChunk;
+       drv->drv_read_chunk_fn = yflash2_ReadChunk;
+       drv->drv_erase_fn = yflash2_EraseBlock;
+       drv->drv_mark_bad_fn = yflash2_MarkBad;
+       drv->drv_check_bad_fn = yflash2_CheckBad;
+       drv->drv_initialise_fn = yflash2_Initialise;
+
+       param = &dev->param;
+
+       param->total_bytes_per_chunk = 2048;
+       param->chunks_per_block = 64;
+       param->start_block = 0;
+       param->end_block = yflash2_GetNumberOfBlocks()-1;
+       param->is_yaffs2 = 1;
+       param->use_nand_ecc=1;
+
+       param->n_reserved_blocks = 5;
+       param->wide_tnodes_disabled=0;
+       param->refresh_period = 1000;
+       param->n_caches = 10; // Use caches
+
+       param->enable_xattr = 1;
+
+       /* dev->driver_context is not used by this simulator */
+
+       yaffs_add_device(dev);
+
+       return dev;
+}
diff --git a/direct/test-framework/yaffs_fileem2k.h b/direct/test-framework/yaffs_fileem2k.h
new file mode 100644 (file)
index 0000000..b7234c0
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
+ *
+ * Copyright (C) 2002-2011 Aleph One Ltd.
+ *   for Toby Churchill Ltd and Brightstar Engineering
+ *
+ * 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 Lesser General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ *
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
+ */
+
+#ifndef __FILEEM2K_H__
+#define __FILEEM2K_H__
+
+
+struct yaffs_dev;
+
+struct yaffs_dev *yflash2_install_drv(const char *name);
+
+
+#endif
+
similarity index 53%
rename from direct/basic-test/yaffs_norif1.c
rename to direct/test-framework/yaffs_m18_drv.c
index 98008b505bd8a53ec34b33bc9fbb79b79188e5ed..9a8ee49e903044d97e80ed4121e3ecdb38686cbf 100644 (file)
 
 /* First set up for M18 with 1k chunks and 16-byte spares.
  *
- * NB We're using the oddball M18 modes of operation here 
+ * NB We're using the oddball M18 modes of operation here
  * The chip is 64MB based at 0x0000, but YAFFS only going to use the top half
  * ie. YAFFS will be from 32MB to 64MB.
  *
- * The M18 has two ways of writing data. Every Programming Region (1kbytes) 
+ * The M18 has two ways of writing data. Every Programming Region (1kbytes)
  * can be programmed in two modes:
  * * Object Mode 1024 bytes of write once data.
- * * Control Mode: 512bytes of bit-writeable data. 
+ * * Control Mode: 512bytes of bit-writeable data.
  *    This is arranged as 32 * (16 bytes of bit-writable followed by 16 bytes of "dont touch")
- * 
+ *
  * The block size is 256kB, making 128 blocks in the 32MB YAFFS area.
  * Each block comprises:
  *   Offset   0k: 248 x 1k data pages
  *   Offset 248k: 248 x 32-byte spare areas implemented as 16 bytes of spare followed by 16 bytes untouched)
  *   Offset 248k + (248 * 32): Format marker
- *   
+ *
  */
 
-const char *yaffs_norif1_c_version = "$Id: yaffs_norif1.c,v 1.6 2010-02-18 01:18:04 charles Exp $";
-
-#include "yaffs_norif1.h"
+#include "yaffs_m18_drv.h"
 
 #include "yportenv.h"
 #include "yaffs_trace.h"
@@ -52,7 +50,8 @@ const char *yaffs_norif1_c_version = "$Id: yaffs_norif1.c,v 1.6 2010-02-18 01:18
 #define CHUNKS_PER_BLOCK       248
 #define SPARE_AREA_OFFSET      (CHUNKS_PER_BLOCK * PROG_REGION_SIZE)
 
-#define FORMAT_OFFSET          (SPARE_AREA_OFFSET + CHUNKS_PER_BLOCK * (SPARE_BYTES_PER_CHUNK + M18_SKIP))
+#define FORMAT_OFFSET          (SPARE_AREA_OFFSET + CHUNKS_PER_BLOCK * \
+                               (SPARE_BYTES_PER_CHUNK + M18_SKIP))
 
 #define FORMAT_VALUE           0x1234
 
@@ -68,76 +67,82 @@ const char *yaffs_norif1_c_version = "$Id: yaffs_norif1.c,v 1.6 2010-02-18 01:18
 
 /* Compile this for a simulation */
 #include "ynorsim.h"
-#define ynorif1_FlashInit() ynorsim_initialise()
-#define ynorif1_FlashDeinit() ynorsim_shutdown()
-#define ynorif1_FlashWrite32(addr,buf,nwords) ynorsim_wr32(addr,buf,nwords) 
-#define ynorif1_FlashRead32(addr,buf,nwords) ynorsim_rd32(addr,buf,nwords) 
-#define ynorif1_FlashEraseBlock(addr) ynorsim_erase(addr)
-#define DEVICE_BASE     ynorsim_get_base()
+
+static struct nor_sim *nor_sim;
+
+#define m18_drv_FlashInit() do {nor_sim = ynorsim_initialise("emfile-m18", BLOCKS_IN_DEVICE, BLOCK_SIZE_IN_BYTES); } while(0)
+#define m18_drv_FlashDeinit() ynorsim_shutdown(nor_sim)
+#define m18_drv_FlashWrite32(addr,buf,nwords) ynorsim_wr32(nor_sim,addr,buf,nwords)
+#define m18_drv_FlashRead32(addr,buf,nwords) ynorsim_rd32(nor_sim,addr,buf,nwords)
+#define m18_drv_FlashEraseBlock(addr) ynorsim_erase(nor_sim,addr)
+#define DEVICE_BASE     ynorsim_get_base(nor_sim)
+
 #else
 
-/* Compile this for running on blob, hacked for yaffs access */
+/* Compile this to hook up to read hardware */
 #include "../blob/yflashrw.h"
-#define ynorif1_FlashInit()  do{} while(0)
-#define ynorif1_FlashDeinit() do {} while(0)
-#define ynorif1_FlashWrite32(addr,buf,nwords) Y_FlashWrite(addr,buf,nwords) 
-#define ynorif1_FlashRead32(addr,buf,nwords)  Y_FlashRead(addr,buf,nwords) 
-#define ynorif1_FlashEraseBlock(addr)         Y_FlashErase(addr,BLOCK_SIZE_IN_BYTES)
+#define m18_drv_FlashInit()  do{} while(0)
+#define m18_drv_FlashDeinit() do {} while(0)
+#define m18_drv_FlashWrite32(addr,buf,nwords) Y_FlashWrite(addr,buf,nwords)
+#define m18_drv_FlashRead32(addr,buf,nwords)  Y_FlashRead(addr,buf,nwords)
+#define m18_drv_FlashEraseBlock(addr)         Y_FlashErase(addr,BLOCK_SIZE_IN_BYTES)
 #define DEVICE_BASE     (32 * 1024 * 1024)
 #endif
 
-u32 *Block2Addr(struct yaffs_dev *dev, int blockNumber)
+
+static u32 *Block2Addr(struct yaffs_dev *dev, int blockNumber)
 {
-       u32 addr;
+       u8 *addr;
        dev=dev;
-       
-       addr = (u32) DEVICE_BASE;
+
+       addr = (u8*) DEVICE_BASE;
        addr += blockNumber * BLOCK_SIZE_IN_BYTES;
-       
+
        return (u32 *) addr;
 }
 
-u32 *Block2FormatAddr(struct yaffs_dev *dev,int blockNumber)
+static u32 *Block2FormatAddr(struct yaffs_dev *dev,int blockNumber)
 {
-       u32 addr;
+       u8 *addr;
 
-       addr = (u32) Block2Addr(dev,blockNumber);
+       addr = (u8*) Block2Addr(dev,blockNumber);
        addr += FORMAT_OFFSET;
-       
+
        return (u32 *)addr;
 }
-u32 *Chunk2DataAddr(struct yaffs_dev *dev,int chunk_id)
+
+static u32 *Chunk2DataAddr(struct yaffs_dev *dev,int chunk_id)
 {
        unsigned block;
        unsigned chunkInBlock;
-       u32  addr;
-       
+       u8 *addr;
+
        block = chunk_id/dev->param.chunks_per_block;
        chunkInBlock = chunk_id % dev->param.chunks_per_block;
-       
-       addr = (u32) Block2Addr(dev,block);
+
+       addr = (u8*) Block2Addr(dev,block);
        addr += chunkInBlock * DATA_BYTES_PER_CHUNK;
-       
+
        return (u32 *)addr;
 }
 
-u32 *Chunk2SpareAddr(struct yaffs_dev *dev,int chunk_id)
+static u32 *Chunk2SpareAddr(struct yaffs_dev *dev,int chunk_id)
 {
        unsigned block;
        unsigned chunkInBlock;
-       u32 addr;
-       
+       u8 *addr;
+
        block = chunk_id/dev->param.chunks_per_block;
        chunkInBlock = chunk_id % dev->param.chunks_per_block;
-       
-       addr = (u32) Block2Addr(dev,block);
+
+       addr = (u8*) Block2Addr(dev,block);
        addr += SPARE_AREA_OFFSET;
        addr += chunkInBlock * (SPARE_BYTES_PER_CHUNK + M18_SKIP);
        return (u32 *)addr;
 }
 
 
-void ynorif1_AndBytes(u8*target, const u8   *src, int nbytes)
+static void m18_drv_AndBytes(u8*target, const u8   *src, int nbytes)
 {
         while(nbytes > 0){
                 *target &= *src;
@@ -147,78 +152,87 @@ void ynorif1_AndBytes(u8*target, const u8   *src, int nbytes)
         }
 }
 
-int ynorif1_WriteChunkToNAND(struct yaffs_dev *dev,int nand_chunk,const u8 *data, const struct yaffs_spare *spare)
+static int m18_drv_WriteChunkToNAND(struct yaffs_dev *dev,int nand_chunk,
+                                   const u8 *data, int data_len,
+                                   const u8 *oob, int oob_len)
 {
         u32 *dataAddr = Chunk2DataAddr(dev,nand_chunk);
         u32 *spareAddr = Chunk2SpareAddr(dev,nand_chunk);
-        
+
+       struct yaffs_spare *spare = (struct yaffs_spare *)oob;
         struct yaffs_spare tmpSpare;
-        
+
+       (void) oob_len;
+
         /* We should only be getting called for one of 3 reasons:
          * Writing a chunk: data and spare will not be NULL
          * Writing a deletion marker: data will be NULL, spare not NULL
          * Writing a bad block marker: data will be NULL, spare not NULL
          */
-         
+
         if(sizeof(struct yaffs_spare) != 16)
                 BUG();
-        
-        if(data && spare)
+
+        if(data && oob)
         {
                 if(spare->page_status != 0xff)
                         BUG();
                 /* Write a pre-marker */
                 memset(&tmpSpare,0xff,sizeof(tmpSpare));
                 tmpSpare.page_status = YNOR_PREMARKER;
-                ynorif1_FlashWrite32(spareAddr,(u32 *)&tmpSpare,sizeof(struct yaffs_spare)/4);
+                m18_drv_FlashWrite32(spareAddr,(u32 *)&tmpSpare,sizeof(struct yaffs_spare)/4);
+
+                /* Write the data */
+                m18_drv_FlashWrite32(dataAddr,(u32 *)data, data_len/ 4);
+
 
-                /* Write the data */            
-                ynorif1_FlashWrite32(dataAddr,(u32 *)data,dev->param.total_bytes_per_chunk / 4);
-                
-                
                 memcpy(&tmpSpare,spare,sizeof(struct yaffs_spare));
-                
+
                 /* Write the real tags, but override the premarker*/
                 tmpSpare.page_status = YNOR_PREMARKER;
-                ynorif1_FlashWrite32(spareAddr,(u32 *)&tmpSpare,sizeof(struct yaffs_spare)/4);
-                
+                m18_drv_FlashWrite32(spareAddr,(u32 *)&tmpSpare,sizeof(struct yaffs_spare)/4);
+
                 /* Write a post-marker */
                 tmpSpare.page_status = YNOR_POSTMARKER;
-                ynorif1_FlashWrite32(spareAddr,(u32 *)&tmpSpare,sizeof(tmpSpare)/4);  
+                m18_drv_FlashWrite32(spareAddr,(u32 *)&tmpSpare,sizeof(tmpSpare)/4);
 
         } else if(spare){
                 /* This has to be a read-modify-write operation to handle NOR-ness */
 
-                ynorif1_FlashRead32(spareAddr,(u32 *)&tmpSpare,16/ 4);
-                
-                ynorif1_AndBytes((u8 *)&tmpSpare,(u8 *)spare,sizeof(struct yaffs_spare));
-                
-                ynorif1_FlashWrite32(spareAddr,(u32 *)&tmpSpare,16/ 4);
+                m18_drv_FlashRead32(spareAddr,(u32 *)&tmpSpare,16/ 4);
+
+                m18_drv_AndBytes((u8 *)&tmpSpare,(u8 *)spare,sizeof(struct yaffs_spare));
+
+                m18_drv_FlashWrite32(spareAddr,(u32 *)&tmpSpare,16/ 4);
         }
         else {
                 BUG();
         }
-        
 
-       return YAFFS_OK;        
+
+       return YAFFS_OK;
 
 }
 
-int ynorif1_ReadChunkFromNAND(struct yaffs_dev *dev,int nand_chunk, u8 *data, struct yaffs_spare *spare)
+static int m18_drv_ReadChunkFromNAND(struct yaffs_dev *dev,int nand_chunk,
+                                       u8 *data, int data_len,
+                                       u8 *oob, int oob_len,
+                                       enum yaffs_ecc_result *ecc_result)
 {
+       struct yaffs_spare *spare = (struct yaffs_spare *)oob;
 
        u32 *dataAddr = Chunk2DataAddr(dev,nand_chunk);
        u32 *spareAddr = Chunk2SpareAddr(dev,nand_chunk);
-       
+
        if(data)
        {
-               ynorif1_FlashRead32(dataAddr,(u32 *)data,dev->param.total_bytes_per_chunk / 4);
+               m18_drv_FlashRead32(dataAddr,(u32 *)data,dev->param.total_bytes_per_chunk / 4);
        }
-       
-        if(spare)
+
+        if(oob)
         {
-                ynorif1_FlashRead32(spareAddr,(u32 *)spare,16/ 4);
-                
+                m18_drv_FlashRead32(spareAddr,(u32 *)spare, oob_len/ 4);
+
                 /* If the page status is YNOR_POSTMARKER then it was written properly
                  * so change that to 0xFF so that the rest of yaffs is happy.
                  */
@@ -228,46 +242,49 @@ int ynorif1_ReadChunkFromNAND(struct yaffs_dev *dev,int nand_chunk, u8 *data, st
                        (spare->page_status | YNOR_PREMARKER) != 0xff)
                        spare->page_status = YNOR_PREMARKER;
         }
-        
 
-       return YAFFS_OK;        
+       if(ecc_result)
+               *ecc_result = YAFFS_ECC_RESULT_NO_ERROR;
+
+       return YAFFS_OK;
 
 }
 
-static int ynorif1_FormatBlock(struct yaffs_dev *dev, int blockNumber)
+
+static int m18_drv_FormatBlock(struct yaffs_dev *dev, int blockNumber)
 {
        u32 *blockAddr = Block2Addr(dev,blockNumber);
        u32 *formatAddr = Block2FormatAddr(dev,blockNumber);
        u32 formatValue = FORMAT_VALUE;
-       
-       ynorif1_FlashEraseBlock(blockAddr);
-       ynorif1_FlashWrite32(formatAddr,&formatValue,1);
-       
+
+       m18_drv_FlashEraseBlock(blockAddr);
+       m18_drv_FlashWrite32(formatAddr,&formatValue,1);
+
        return YAFFS_OK;
 }
 
-static int ynorif1_UnformatBlock(struct yaffs_dev *dev, int blockNumber)
+static int m18_drv_UnformatBlock(struct yaffs_dev *dev, int blockNumber)
 {
        u32 *formatAddr = Block2FormatAddr(dev,blockNumber);
        u32 formatValue = 0;
-       
-       ynorif1_FlashWrite32(formatAddr,&formatValue,1);
-       
+
+       m18_drv_FlashWrite32(formatAddr,&formatValue,1);
+
        return YAFFS_OK;
 }
 
-static int ynorif1_IsBlockFormatted(struct yaffs_dev *dev, int blockNumber)
+static int m18_drv_IsBlockFormatted(struct yaffs_dev *dev, int blockNumber)
 {
        u32 *formatAddr = Block2FormatAddr(dev,blockNumber);
        u32 formatValue;
-       
-       
-       ynorif1_FlashRead32(formatAddr,&formatValue,1);
-       
+
+
+       m18_drv_FlashRead32(formatAddr,&formatValue,1);
+
        return (formatValue == FORMAT_VALUE);
 }
 
-int ynorif1_EraseBlockInNAND(struct yaffs_dev *dev, int blockNumber)
+static int m18_drv_EraseBlockInNAND(struct yaffs_dev *dev, int blockNumber)
 {
 
        if(blockNumber < 0 || blockNumber >= BLOCKS_IN_DEVICE)
@@ -279,33 +296,78 @@ int ynorif1_EraseBlockInNAND(struct yaffs_dev *dev, int blockNumber)
        }
        else
        {
-               ynorif1_UnformatBlock(dev,blockNumber);
-               ynorif1_FormatBlock(dev,blockNumber);
+               m18_drv_UnformatBlock(dev,blockNumber);
+               m18_drv_FormatBlock(dev,blockNumber);
                return YAFFS_OK;
        }
-       
+
 }
 
-int ynorif1_InitialiseNAND(struct yaffs_dev *dev)
+static int m18_drv_InitialiseNAND(struct yaffs_dev *dev)
 {
        int i;
-       
-       ynorif1_FlashInit();
+
+       m18_drv_FlashInit();
        /* Go through the blocks formatting them if they are not formatted */
        for(i = dev->param.start_block; i <= dev->param.end_block; i++){
-               if(!ynorif1_IsBlockFormatted(dev,i)){
-                       ynorif1_FormatBlock(dev,i);
+               if(!m18_drv_IsBlockFormatted(dev,i)){
+                       m18_drv_FormatBlock(dev,i);
                }
        }
        return YAFFS_OK;
 }
 
-int ynorif1_Deinitialise_flash_fn(struct yaffs_dev *dev)
+static int m18_drv_Deinitialise_flash_fn(struct yaffs_dev *dev)
 {
-       dev=dev;        
-       ynorif1_FlashDeinit();
+       dev=dev;
+
+       m18_drv_FlashDeinit();
 
        return YAFFS_OK;
 }
 
 
+struct yaffs_dev *yaffs_m18_install_drv(const char *name)
+{
+
+       struct yaffs_dev *dev = malloc(sizeof(struct yaffs_dev));
+       char *name_copy = strdup(name);
+       struct yaffs_param *param;
+       struct yaffs_driver *drv;
+
+
+       if(!dev || !name_copy) {
+               free(name_copy);
+               free(dev);
+               return NULL;
+       }
+
+       param = &dev->param;
+       drv = &dev->drv;
+
+       memset(dev, 0, sizeof(*dev));
+
+       param->name = name_copy;
+
+       param->total_bytes_per_chunk = 1024;
+       param->chunks_per_block =248;
+       param->n_reserved_blocks = 2;
+       param->start_block = 0; // Can use block 0
+       param->end_block = 31; // Last block
+       param->use_nand_ecc = 0; // use YAFFS's ECC
+
+       drv->drv_write_chunk_fn = m18_drv_WriteChunkToNAND;
+       drv->drv_read_chunk_fn = m18_drv_ReadChunkFromNAND;
+       drv->drv_erase_fn = m18_drv_EraseBlockInNAND;
+       drv->drv_initialise_fn = m18_drv_InitialiseNAND;
+       drv->drv_deinitialise_fn = m18_drv_Deinitialise_flash_fn;
+
+       param->n_caches = 10;
+       param->disable_soft_del = 1;
+
+       dev->driver_context = (void *) 1;       // Used to identify the device in fstat.
+
+       yaffs_add_device(dev);
+
+       return NULL;
+}
diff --git a/direct/test-framework/yaffs_m18_drv.h b/direct/test-framework/yaffs_m18_drv.h
new file mode 100644 (file)
index 0000000..7befb1a
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
+ *
+ * Copyright (C) 2002-2011 Aleph One Ltd.
+ *   for Toby Churchill Ltd and Brightstar Engineering
+ *
+ * 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 Lesser General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ *
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
+ */
+
+
+#ifndef __YAFFS_M18_DRV_H__
+#define __YAFFS_M18_DRV_H__
+
+struct yaffs_dev;
+struct yaffs_dev *yaffs_m18_install_drv(const char *name);
+
+#endif
+
+
diff --git a/direct/test-framework/yaffs_nor_drv.c b/direct/test-framework/yaffs_nor_drv.c
new file mode 100644 (file)
index 0000000..a510979
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
+ *
+ * Copyright (C) 2002-2011 Aleph One Ltd.
+ *   for Toby Churchill Ltd and Brightstar Engineering
+ *
+ * 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 is an interface module for handling NOR in yaffs1 mode.
+ */
+
+/* This code is intended to be used with "regular" NOR that is bit-modifyable.
+ *
+ * Each "chunk" is a contguous area of 512 + 16 bytes.
+ * This makes 248 such chunks with some space left over where a format markerr
+ * is stored.
+ */
+
+#include "yaffs_nor_drv.h"
+
+#include "yportenv.h"
+#include "yaffs_trace.h"
+
+#include "yaffs_flashif.h"
+#include "yaffs_guts.h"
+
+/* Tunable data */
+#define DATA_BYTES_PER_CHUNK   512
+#define SPARE_BYTES_PER_CHUNK  16
+#define BLOCK_SIZE_IN_BYTES    (128*1024)
+#define BYTES_IN_DEVICE                (4*1024*1024)
+
+#define BYTES_PER_CHUNK                (DATA_BYTES_PER_CHUNK + SPARE_BYTES_PER_CHUNK)
+#define SPARE_AREA_OFFSET      DATA_BYTES_PER_CHUNK
+#define CHUNKS_PER_BLOCK (BLOCK_SIZE_IN_BYTES/BYTES_PER_CHUNK)
+
+#define BLOCKS_IN_DEVICE       (BYTES_IN_DEVICE/BLOCK_SIZE_IN_BYTES)
+
+#define YNOR_PREMARKER          (0xF6)
+#define YNOR_POSTMARKER         (0xF0)
+
+#define FORMAT_OFFSET          (CHUNKS_PER_BLOCK * BYTES_PER_CHUNK)
+#define FORMAT_VALUE           0x1234
+
+#if 1
+
+/* Compile this for a simulation */
+#include "ynorsim.h"
+
+static struct nor_sim *nor_sim;
+
+#define nor_drv_FlashInit() do {nor_sim = ynorsim_initialise("emfile-nor", BLOCKS_IN_DEVICE, BLOCK_SIZE_IN_BYTES); } while(0)
+#define nor_drv_FlashDeinit() ynorsim_shutdown(nor_sim)
+#define nor_drv_FlashWrite32(addr,buf,nwords) ynorsim_wr32(nor_sim,addr,buf,nwords)
+#define nor_drv_FlashRead32(addr,buf,nwords) ynorsim_rd32(nor_sim,addr,buf,nwords)
+#define nor_drv_FlashEraseBlock(addr) ynorsim_erase(nor_sim,addr)
+#define DEVICE_BASE     ynorsim_get_base(nor_sim)
+
+#else
+
+/* Compile this to hook up to read hardware */
+#include "../blob/yflashrw.h"
+#define nor_drv_FlashInit()  do{} while(0)
+#define nor_drv_FlashDeinit() do {} while(0)
+#define nor_drv_FlashWrite32(addr,buf,nwords) Y_FlashWrite(addr,buf,nwords)
+#define nor_drv_FlashRead32(addr,buf,nwords)  Y_FlashRead(addr,buf,nwords)
+#define nor_drv_FlashEraseBlock(addr)         Y_FlashErase(addr,BLOCK_SIZE_IN_BYTES)
+#define DEVICE_BASE     (32 * 1024 * 1024)
+#endif
+
+
+static u32 *Block2Addr(struct yaffs_dev *dev, int blockNumber)
+{
+       u8 *addr;
+
+       dev=dev;
+
+       addr = (u8*)DEVICE_BASE;
+       addr += blockNumber * BLOCK_SIZE_IN_BYTES;
+
+       return (u32 *) addr;
+}
+
+static u32 *Block2FormatAddr(struct yaffs_dev *dev, int blockNumber)
+{
+       u8 *addr;
+
+       addr = (u8*) Block2Addr(dev,blockNumber);
+       addr += FORMAT_OFFSET;
+
+       return (u32 *)addr;
+}
+
+static u32 *Chunk2DataAddr(struct yaffs_dev *dev, int chunk_id)
+{
+       unsigned block;
+       unsigned chunkInBlock;
+       u8 *addr;
+
+       block = chunk_id/dev->param.chunks_per_block;
+       chunkInBlock = chunk_id % dev->param.chunks_per_block;
+
+       addr = (u8*) Block2Addr(dev,block);
+       addr += chunkInBlock * BYTES_PER_CHUNK;
+
+       return (u32 *)addr;
+}
+
+static u32 *Chunk2SpareAddr(struct yaffs_dev *dev, int chunk_id)
+{
+       u8 *addr;
+
+       addr = (u8*) Chunk2DataAddr(dev, chunk_id);
+       addr += SPARE_AREA_OFFSET;
+       return (u32 *)addr;
+}
+
+
+static void nor_drv_AndBytes(u8*target, const u8 *src, int nbytes)
+{
+       while(nbytes > 0){
+               *target &= *src;
+               target++;
+               src++;
+               nbytes--;
+       }
+}
+
+static int nor_drv_WriteChunkToNAND(struct yaffs_dev *dev,int nand_chunk,
+                                   const u8 *data, int data_len,
+                                   const u8 *oob, int oob_len)
+{
+       u32 *dataAddr = Chunk2DataAddr(dev,nand_chunk);
+       u32 *spareAddr = Chunk2SpareAddr(dev,nand_chunk);
+
+       struct yaffs_spare *spare = (struct yaffs_spare *)oob;
+       struct yaffs_spare tmpSpare;
+
+       (void) oob_len;
+
+       /* We should only be getting called for one of 3 reasons:
+         * Writing a chunk: data and spare will not be NULL
+         * Writing a deletion marker: data will be NULL, spare not NULL
+         * Writing a bad block marker: data will be NULL, spare not NULL
+         */
+
+       if(sizeof(struct yaffs_spare) != SPARE_BYTES_PER_CHUNK)
+               BUG();
+
+       if(data && oob) {
+               if(spare->page_status != 0xff)
+                       BUG();
+               /* Write a pre-marker */
+               memset(&tmpSpare,0xff,sizeof(tmpSpare));
+               tmpSpare.page_status = YNOR_PREMARKER;
+               nor_drv_FlashWrite32(spareAddr,(u32 *)&tmpSpare,sizeof(struct yaffs_spare)/sizeof(u32));
+
+               /* Write the data */
+               nor_drv_FlashWrite32(dataAddr,(u32 *)data, data_len/ sizeof(u32));
+
+               memcpy(&tmpSpare,spare,sizeof(struct yaffs_spare));
+
+               /* Write the real tags, but override the premarker*/
+               tmpSpare.page_status = YNOR_PREMARKER;
+               nor_drv_FlashWrite32(spareAddr,(u32 *)&tmpSpare,sizeof(struct yaffs_spare)/sizeof(u32));
+
+               /* Write a post-marker */
+               tmpSpare.page_status = YNOR_POSTMARKER;
+               nor_drv_FlashWrite32(spareAddr,(u32 *)&tmpSpare,sizeof(tmpSpare)/sizeof(u32));
+
+       } else if(spare){
+               /* This has to be a read-modify-write operation to handle NOR-ness */
+
+               nor_drv_FlashRead32(spareAddr,(u32 *)&tmpSpare,sizeof(struct yaffs_spare)/sizeof(u32));
+
+               nor_drv_AndBytes((u8 *)&tmpSpare,(u8 *)spare,sizeof(struct yaffs_spare));
+
+               nor_drv_FlashWrite32(spareAddr,(u32 *)&tmpSpare,sizeof(struct yaffs_spare)/sizeof(u32));
+       } else {
+               BUG();
+       }
+
+       return YAFFS_OK;
+}
+
+static int nor_drv_ReadChunkFromNAND(struct yaffs_dev *dev,int nand_chunk,
+                                       u8 *data, int data_len,
+                                       u8 *oob, int oob_len,
+                                       enum yaffs_ecc_result *ecc_result)
+{
+       struct yaffs_spare *spare = (struct yaffs_spare *)oob;
+
+       u32 *dataAddr = Chunk2DataAddr(dev,nand_chunk);
+       u32 *spareAddr = Chunk2SpareAddr(dev,nand_chunk);
+
+       if (data) {
+               nor_drv_FlashRead32(dataAddr,(u32 *)data,dev->param.total_bytes_per_chunk / sizeof(u32));
+       }
+
+       if (oob) {
+               nor_drv_FlashRead32(spareAddr,(u32 *)spare, oob_len/ sizeof(u32));
+
+               /* If the page status is YNOR_POSTMARKER then it was written properly
+                 * so change that to 0xFF so that the rest of yaffs is happy.
+                 */
+               if(spare->page_status == YNOR_POSTMARKER)
+                       spare->page_status = 0xff;
+               else if(spare->page_status != 0xff &&
+                       (spare->page_status | YNOR_PREMARKER) != 0xff)
+                       spare->page_status = YNOR_PREMARKER;
+       }
+
+       if(ecc_result)
+               *ecc_result = YAFFS_ECC_RESULT_NO_ERROR;
+
+       return YAFFS_OK;
+
+}
+
+
+static int nor_drv_FormatBlock(struct yaffs_dev *dev, int blockNumber)
+{
+       u32 *blockAddr = Block2Addr(dev,blockNumber);
+       u32 *formatAddr = Block2FormatAddr(dev,blockNumber);
+       u32 formatValue = FORMAT_VALUE;
+
+       nor_drv_FlashEraseBlock(blockAddr);
+       nor_drv_FlashWrite32(formatAddr,&formatValue,1);
+
+       return YAFFS_OK;
+}
+
+static int nor_drv_UnformatBlock(struct yaffs_dev *dev, int blockNumber)
+{
+       u32 *formatAddr = Block2FormatAddr(dev,blockNumber);
+       u32 formatValue = 0;
+
+       nor_drv_FlashWrite32(formatAddr,&formatValue,1);
+
+       return YAFFS_OK;
+}
+
+static int nor_drv_IsBlockFormatted(struct yaffs_dev *dev, int blockNumber)
+{
+       u32 *formatAddr = Block2FormatAddr(dev,blockNumber);
+       u32 formatValue;
+
+
+       nor_drv_FlashRead32(formatAddr,&formatValue,1);
+
+       return (formatValue == FORMAT_VALUE);
+}
+
+static int nor_drv_EraseBlockInNAND(struct yaffs_dev *dev, int blockNumber)
+{
+
+       if(blockNumber < 0 || blockNumber >= BLOCKS_IN_DEVICE)
+       {
+               yaffs_trace(YAFFS_TRACE_ALWAYS,
+                       "Attempt to erase non-existant block %d\n",
+                       blockNumber);
+               return YAFFS_FAIL;
+       }
+       else
+       {
+               nor_drv_UnformatBlock(dev,blockNumber);
+               nor_drv_FormatBlock(dev,blockNumber);
+               return YAFFS_OK;
+       }
+
+}
+
+static int nor_drv_InitialiseNAND(struct yaffs_dev *dev)
+{
+       int i;
+
+       nor_drv_FlashInit();
+       /* Go through the blocks formatting them if they are not formatted */
+       for(i = dev->param.start_block; i <= dev->param.end_block; i++){
+               if(!nor_drv_IsBlockFormatted(dev,i)){
+                       nor_drv_FormatBlock(dev,i);
+               }
+       }
+       return YAFFS_OK;
+}
+
+static int nor_drv_Deinitialise_flash_fn(struct yaffs_dev *dev)
+{
+       dev=dev;
+
+       nor_drv_FlashDeinit();
+
+       return YAFFS_OK;
+}
+
+
+struct yaffs_dev *yaffs_nor_install_drv(const char *name)
+{
+
+       struct yaffs_dev *dev = malloc(sizeof(struct yaffs_dev));
+       char *name_copy = strdup(name);
+       struct yaffs_param *param;
+       struct yaffs_driver *drv;
+
+
+       if(!dev || !name_copy) {
+               free(name_copy);
+               free(dev);
+               return NULL;
+       }
+
+       param = &dev->param;
+       drv = &dev->drv;
+
+       memset(dev, 0, sizeof(*dev));
+
+       param->name = name_copy;
+
+       param->total_bytes_per_chunk = DATA_BYTES_PER_CHUNK;
+       param->chunks_per_block = CHUNKS_PER_BLOCK;
+       param->n_reserved_blocks = 2;
+       param->start_block = 0; // Can use block 0
+       param->end_block = BLOCKS_IN_DEVICE - 1; // Last block
+       param->use_nand_ecc = 0; // use YAFFS's ECC
+
+       drv->drv_write_chunk_fn = nor_drv_WriteChunkToNAND;
+       drv->drv_read_chunk_fn = nor_drv_ReadChunkFromNAND;
+       drv->drv_erase_fn = nor_drv_EraseBlockInNAND;
+       drv->drv_initialise_fn = nor_drv_InitialiseNAND;
+       drv->drv_deinitialise_fn = nor_drv_Deinitialise_flash_fn;
+
+       param->n_caches = 10;
+       param->disable_soft_del = 1;
+
+       dev->driver_context = (void *) nor_sim;
+
+       yaffs_add_device(dev);
+
+       return NULL;
+}
diff --git a/direct/test-framework/yaffs_nor_drv.h b/direct/test-framework/yaffs_nor_drv.h
new file mode 100644 (file)
index 0000000..f856223
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
+ *
+ * Copyright (C) 2002-2011 Aleph One Ltd.
+ *   for Toby Churchill Ltd and Brightstar Engineering
+ *
+ * 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 Lesser General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ *
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
+ */
+
+
+#ifndef __YAFFS_NOR_DRV_H__
+#define __YAFFS_NOR_DRV_H__
+
+struct yaffs_dev;
+struct yaffs_dev *yaffs_nor_install_drv(const char *name);
+
+#endif
+
+
similarity index 94%
rename from direct/basic-test/yaffs_osglue.c
rename to direct/test-framework/yaffs_osglue.c
index 4a149e277588dd9bc4387bcfe02c57eb3a495186..40e405209fa1641e6472de0710c928aedfc7326f 100644 (file)
@@ -15,9 +15,6 @@
 #include "yaffscfg.h"
 #include "yaffs_guts.h"
 #include "yaffsfs.h"
-#include "yaffs_fileem2k.h"
-#include "yaffs_nandemul2k.h"
-#include "yaffs_norif1.h"
 #include "yaffs_trace.h"
 #include <assert.h>
 
@@ -37,6 +34,13 @@ int yaffsfs_GetLastError(void)
        return yaffsfs_lastError;
 }
 
+int yaffsfs_CheckMemRegion(const void *addr, size_t size, int writeable)
+{
+       if(!addr)
+               return -1;
+       return 0;
+}
+
 
 #ifdef CONFIG_YAFFS_USE_PTHREADS
 #include <pthread.h>
similarity index 97%
rename from direct/basic-test/yaffs_ramdisk.c
rename to direct/test-framework/yaffs_ramdisk.c
index bea5cfb8beaceb81f2bd35d7256390adc89dcab0..3d71e5170e0190aaf7e9c8c378bebe4623b67774 100644 (file)
@@ -18,9 +18,6 @@
  * Use this with dev->use_nand_ecc enabled, then ECC overheads are not required.
  */
 
-const char *yaffs_ramdisk_c_version = "$Id: yaffs_ramdisk.c,v 1.6 2010-01-11 04:06:47 charles Exp $";
-
-
 #include "yportenv.h"
 #include "yaffs_trace.h"
 
similarity index 98%
rename from direct/basic-test/yaffs_ramem2k.c
rename to direct/test-framework/yaffs_ramem2k.c
index 5bd0affbc742c026414da433f409859f7d7fcf2e..715ae77c97fd95b90088ddd73850fd9187430e92 100644 (file)
@@ -16,8 +16,6 @@
  */
 
 
-const char *yaffs_ramem2k_c_version = "$Id: yaffs_ramem2k.c,v 1.8 2010-02-18 01:18:04 charles Exp $";
-
 #ifndef __KERNEL__
 #define CONFIG_YAFFS_RAM_ENABLED
 #else
diff --git a/direct/test-framework/yaffscfg2k.c b/direct/test-framework/yaffscfg2k.c
new file mode 100644 (file)
index 0000000..9e24866
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
+ *
+ * Copyright (C) 2002-2011 Aleph One Ltd.
+ *   for Toby Churchill Ltd and Brightstar Engineering
+ *
+ * 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.
+ */
+
+/*
+ * yaffscfg2k.c  The configuration for the "direct" use of yaffs.
+ *
+ * This file is intended to be modified to your requirements.
+ * There is no need to redistribute this file.
+ */
+
+#include "yaffscfg.h"
+#include "yaffs_guts.h"
+#include "yaffsfs.h"
+#include "yaffs_fileem2k.h"
+#include "yaffs_nandemul2k.h"
+#include "yaffs_trace.h"
+#include "yaffs_osglue.h"
+
+
+#include <errno.h>
+
+unsigned yaffs_trace_mask =
+
+       YAFFS_TRACE_SCAN |
+       YAFFS_TRACE_GC |
+       YAFFS_TRACE_ERASE |
+       YAFFS_TRACE_ERROR |
+       YAFFS_TRACE_TRACING |
+       YAFFS_TRACE_ALLOCATE |
+       YAFFS_TRACE_BAD_BLOCKS |
+       YAFFS_TRACE_VERIFY |
+
+       0;
+
+
+
+// Configuration
+
+#include "yaffs_flashif2.h"
+#include "yaffs_m18_drv.h"
+#include "yaffs_nor_drv.h"
+
+int yaffs_start_up(void)
+{
+       static int start_up_called = 0;
+
+       if(start_up_called)
+               return 0;
+       start_up_called = 1;
+
+       // Stuff to configure YAFFS
+       // Stuff to initialise anything special (eg lock semaphore).
+       yaffsfs_OSInitialisation();
+
+
+       yaffs_m18_install_drv("M18-1");
+       yaffs_nor_install_drv("nor");
+
+       // /yaffs2  yaffs2 file emulation
+       yflash2_install_drv("yaffs2");
+
+       return 0;
+}
+
+
+
diff --git a/direct/test-framework/ynorsim.c b/direct/test-framework/ynorsim.c
new file mode 100644 (file)
index 0000000..38a4632
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
+ *
+ * Copyright (C) 2002-2011 Aleph One Ltd.
+ *   for Toby Churchill Ltd and Brightstar Engineering
+ *
+ * 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.
+ */
+
+#include "ynorsim.h"
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <time.h>
+
+#define YNORSIM_FNAME "emfile-nor"
+
+/* Set YNORSIM_BIT_CHANGES to a a value from 1..30 to
+ *simulate bit flipping as the programming happens.
+ * A low value results in faster simulation with less chance of encountering a partially programmed
+ * word.
+ */
+
+//#define YNORSIM_BIT_CHANGES 15
+#define YNORSIM_BIT_CHANGES 2
+
+#if 0
+/* Simulate 32MB of flash in 256k byte blocks.
+ * This stuff is x32.
+ */
+
+#define YNORSIM_BLOCK_SIZE_U32  (256*1024/4)
+#define YNORSIM_DEV_SIZE_U32   (32*1024 * 1024/4)
+#else
+/* Simulate 8MB of flash in 256k byte blocks.
+ * This stuff is x32.
+ */
+
+#define YNORSIM_BLOCK_SIZE_U32  (256*1024/4)
+#define YNORSIM_DEV_SIZE_U32   (8*1024 * 1024/4)
+#endif
+
+struct nor_sim {
+       int n_blocks;
+       int block_size_bytes;
+       int file_size;
+       u32 *word;
+       int initialised;
+       char *fname;
+       int remaining_ops;
+       int nops_so_far;
+};
+
+int ops_multiplier = 500;
+extern int random_seed;
+extern int simulate_power_failure;
+
+static void NorError(struct nor_sim *sim)
+{
+       printf("Nor error on device %s\n", sim->fname);
+       while (1) {
+       }
+}
+
+static void ynorsim_save_image(struct nor_sim *sim)
+{
+       int h;
+
+       h = open(sim->fname, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
+       write(h, sim->word, sim->file_size);
+       close(h);
+}
+
+static void ynorsim_restore_image(struct nor_sim *sim)
+{
+       int h;
+
+       h = open(sim->fname, O_RDONLY, S_IREAD | S_IWRITE);
+       memset(sim->word, 0xFF, sim->file_size);
+       read(h, sim->word, sim->file_size);
+       close(h);
+}
+
+static void ynorsim_power_fail(struct nor_sim *sim)
+{
+       ynorsim_save_image(sim);
+       exit(1);
+}
+
+static void ynorsim_maybe_power_fail(struct nor_sim *sim)
+{
+       sim->nops_so_far++;
+       sim->remaining_ops--;
+       if (simulate_power_failure && sim->remaining_ops < 1) {
+               printf("Simulated power failure after %d operations\n",
+                      sim->nops_so_far);
+               ynorsim_power_fail(sim);
+       }
+}
+
+static void ynorsim_ready(struct nor_sim *sim)
+{
+       if (sim->initialised)
+               return;
+       srand(random_seed);
+       sim->remaining_ops = 1000000000;
+       sim->remaining_ops =
+           (rand() % 10000) * ops_multiplier * YNORSIM_BIT_CHANGES;
+       ynorsim_restore_image(sim);
+       sim->initialised = 1;
+}
+
+/* Public functions. */
+
+void ynorsim_rd32(struct nor_sim *sim, u32 * addr, u32 * buf, int nwords)
+{
+       sim = sim;
+       while (nwords > 0) {
+               *buf = *addr;
+               buf++;
+               addr++;
+               nwords--;
+       }
+}
+
+void ynorsim_wr_one_word32(struct nor_sim *sim, u32 * addr, u32 val)
+{
+       u32 tmp;
+       u32 m;
+       int i;
+
+       tmp = *addr;
+       if (val & ~tmp) {
+               /* Fail due to trying to change a zero into a 1 */
+               printf("attempt to set a zero to one (%x)->(%x)\n", tmp, val);
+               NorError(sim);
+       }
+
+       for (i = 0; i < YNORSIM_BIT_CHANGES; i++) {
+               m = 1 << (rand() & 31);
+               if (!(m & val)) {
+                       tmp &= ~m;
+                       *addr = tmp;
+                       ynorsim_maybe_power_fail(sim);
+               }
+
+       }
+
+       *addr = tmp & val;
+       ynorsim_maybe_power_fail(sim);
+}
+
+void ynorsim_wr32(struct nor_sim *sim, u32 * addr, u32 * buf, int nwords)
+{
+       while (nwords > 0) {
+               ynorsim_wr_one_word32(sim, addr, *buf);
+               addr++;
+               buf++;
+               nwords--;
+       }
+}
+
+void ynorsim_erase(struct nor_sim *sim, u32 * addr)
+{
+       /* Todo... bit flipping */
+       memset(addr, 0xFF, sim->block_size_bytes);
+}
+
+struct nor_sim *ynorsim_initialise(char *name, int n_blocks,
+                                  int block_size_bytes)
+{
+       struct nor_sim *sim;
+
+       sim = malloc(sizeof(*sim));
+       if (!sim)
+               return NULL;
+
+       memset(sim, 0, sizeof(*sim));
+       sim->n_blocks = n_blocks;
+       sim->block_size_bytes = block_size_bytes;
+       sim->file_size = n_blocks * block_size_bytes;
+       sim->word = malloc(sim->file_size);
+       sim->fname = strdup(name);
+
+       if(!sim->word)
+               return NULL;
+
+       ynorsim_ready(sim);
+       return sim;
+}
+
+void ynorsim_shutdown(struct nor_sim *sim)
+{
+       ynorsim_save_image(sim);
+       sim->initialised = 0;
+}
+
+u32 *ynorsim_get_base(struct nor_sim *sim)
+{
+       return sim->word;
+}
similarity index 53%
rename from direct/basic-test/yaffs_norif1.h
rename to direct/test-framework/ynorsim.h
index 72952b4d8f0a529a50ef58f6217aa71a40284b1a..a51617ec32a9dbd091dfe9a68cd30a9e3e6b36e5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * YAFFS: Yet another Flash File System . A NAND-flash specific file system. 
+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
  * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
  */
 
-
-#ifndef __YAFFS_NOR_IF1_H__
-#define __YAFFS_NOR_IF1_H__
+#ifndef __Y_NORSIM_H__
+#define __Y_NORSIM_H__
 
 #include "yaffs_guts.h"
 
-int ynorif1_WriteChunkToNAND(struct yaffs_dev *dev,int nand_chunk,const u8 *data, const struct yaffs_spare *spare);
-int ynorif1_ReadChunkFromNAND(struct yaffs_dev *dev,int nand_chunk, u8 *data, struct yaffs_spare *spare);
-int ynorif1_EraseBlockInNAND(struct yaffs_dev *dev, int blockNumber);
-int ynorif1_InitialiseNAND(struct yaffs_dev *dev);
-int ynorif1_Deinitialise_flash_fn(struct yaffs_dev *dev);
-
-#endif
+struct nor_sim;
 
+void ynorsim_rd32(struct nor_sim *sim, u32 *addr, u32 *data, int nwords);
+void ynorsim_wr32(struct nor_sim *sim, u32 *addr, u32 *data, int nwords);
+void ynorsim_erase(struct nor_sim *sim, u32 *addr);
+void ynorsim_shutdown(struct nor_sim *sim);
+struct nor_sim *ynorsim_initialise(char *name, int n_blocks, int block_size_bytes);
+u32 * ynorsim_get_base(struct nor_sim *sim);
 
+#endif
index ed0d336dcbac30a19d8b4786c521f38a0256b011..99675634fe4bf5d9efee96e6f666de833dad0a7e 100644 (file)
@@ -329,7 +329,7 @@ test_template test_list[]={
 
        {test_yaffs_write,test_yaffs_write_clean,"test_yaffs_write"},
        {test_yaffs_write_EBADF,test_yaffs_write_EBADF_clean,"test_yaffs_write_EBADF"},
-       {test_yaffs_write_big_file,test_yaffs_write_big_file_clean,"test_yaffs_write_big_file"},
+//     {test_yaffs_write_big_file,test_yaffs_write_big_file_clean,"test_yaffs_write_big_file"},
        {test_yaffs_write_EROFS,test_yaffs_write_EROFS_clean,"test_yaffs_write_EROFS"},
 
        {test_yaffs_read,test_yaffs_read_clean,"test_yaffs_read"},
index d43a9d444c8f7077e8eb7652ca89e72d92a0c173..23cf0007dbd6bcf2954f97e5d34a9b0a22efbfd6 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <config.h>
 #include <command.h>
+#include "../fs/yaffs2/yaffs_uboot_glue.h"
 
 #ifdef YAFFS2_DEBUG
 #define PRINTF(fmt, args...) printf(fmt, ##args)
 #define PRINTF(fmt, args...) do { } while (0)
 #endif
 
-extern void cmd_yaffs_dev_ls(void);
-extern void cmd_yaffs_tracemask(unsigned set, unsigned mask);
-extern void cmd_yaffs_devconfig(char *mp, int flash_dev,
-                               int start_block, int end_block);
-extern void cmd_yaffs_mount(char *mp);
-extern void cmd_yaffs_umount(char *mp);
-extern void cmd_yaffs_read_file(char *fn);
-extern void cmd_yaffs_write_file(char *fn, char bval, int sizeOfFile);
-extern void cmd_yaffs_ls(const char *mountpt, int longlist);
-extern void cmd_yaffs_mwrite_file(char *fn, char *addr, int size);
-extern void cmd_yaffs_mread_file(char *fn, char *addr);
-extern void cmd_yaffs_mkdir(const char *dir);
-extern void cmd_yaffs_rmdir(const char *dir);
-extern void cmd_yaffs_rm(const char *path);
-extern void cmd_yaffs_mv(const char *oldPath, const char *newPath);
-
-extern int yaffs_dump_dev(const char *path);
 
 /* ytrace - show/set yaffs trace mask */
 int do_ytrace(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
        if (argc > 1)
-               cmd_yaffs_tracemask(1, simple_strtol(argv[1], NULL, 16));
+               return cmd_yaffs_tracemask(1, simple_strtol(argv[1], NULL, 16));
        else
-               cmd_yaffs_tracemask(0, 0);
-
-       return 0;
+               return cmd_yaffs_tracemask(0, 0);
 }
 
 /* ydevls - lists yaffs mount points. */
 int do_ydevls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
-       cmd_yaffs_dev_ls();
-
-       return 0;
+       return cmd_yaffs_dev_ls();
 }
 
 /* ydevconfig mount_pt mtd_dev_num start_block end_block */
@@ -80,9 +60,7 @@ int do_ydevconfig(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        start_block = simple_strtol(argv[3], NULL, 16);
        end_block = simple_strtol(argv[4], NULL, 16);
 
-       cmd_yaffs_devconfig(mtpoint, mtd_dev, start_block, end_block);
-
-       return 0;
+       return cmd_yaffs_devconfig(mtpoint, mtd_dev, start_block, end_block);
 }
 
 int do_ymount(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
@@ -97,9 +75,7 @@ int do_ymount(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        mtpoint = argv[1];
        printf("Mounting yaffs2 mount point %s\n", mtpoint);
 
-       cmd_yaffs_mount(mtpoint);
-
-       return 0;
+       return cmd_yaffs_mount(mtpoint);
 }
 
 int do_yumount(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
@@ -113,9 +89,7 @@ int do_yumount(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 
        mtpoint = argv[1];
        printf("Unmounting yaffs2 mount point %s\n", mtpoint);
-       cmd_yaffs_umount(mtpoint);
-
-       return 0;
+       return cmd_yaffs_umount(mtpoint);
 }
 
 int do_yls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
@@ -129,9 +103,30 @@ int do_yls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 
        dirname = argv[argc - 1];
 
-       cmd_yaffs_ls(dirname, (argc > 2) ? 1 : 0);
+       return cmd_yaffs_ls(dirname, (argc > 2) ? 1 : 0);
+}
 
-       return 0;
+static int ycheck_option_valid(const char *str)
+{
+       return strcmp(str,"DIR") == 0 || strcmp(str,"REG") == 0;
+}
+
+int do_ycheck(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+       const char *dirname;
+       const char *str = "ANY";
+
+       if (argc < 2 || argc > 3 ||
+       (argc == 3 && ! ycheck_option_valid(argv[2]))) {
+               printf("Bad arguments: ycheck name [DIR|REG]");
+               return -1;
+       }
+
+       dirname = argv[1];
+       if(argc>2)
+               str = argv[2];
+
+       return cmd_yaffs_check(dirname, str);
 }
 
 int do_yrd(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
@@ -147,10 +142,7 @@ int do_yrd(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 
        printf("Reading file %s ", filename);
 
-       cmd_yaffs_read_file(filename);
-
-       printf("done\n");
-       return 0;
+       return cmd_yaffs_read_file(filename);
 }
 
 int do_ywr(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
@@ -171,10 +163,7 @@ int do_ywr(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        printf("Writing value (%lx) %lx times to %s... ", value, numValues,
               filename);
 
-       cmd_yaffs_write_file(filename, value, numValues);
-
-       printf("done\n");
-       return 0;
+       return cmd_yaffs_write_file(filename, value, numValues);
 }
 
 int do_yrdm(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
@@ -190,9 +179,7 @@ int do_yrdm(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        filename = argv[1];
        addr = simple_strtoul(argv[2], NULL, 16);
 
-       cmd_yaffs_mread_file(filename, (char *)addr);
-
-       return 0;
+       return cmd_yaffs_mread_file(filename, (char *)addr);
 }
 
 int do_ywrm(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
@@ -210,9 +197,7 @@ int do_ywrm(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        addr = simple_strtoul(argv[2], NULL, 16);
        size = simple_strtoul(argv[3], NULL, 16);
 
-       cmd_yaffs_mwrite_file(filename, (char *)addr, size);
-
-       return 0;
+       return cmd_yaffs_mwrite_file(filename, (char *)addr, size);
 }
 
 int do_ymkdir(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
@@ -225,9 +210,7 @@ int do_ymkdir(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        }
 
        dirname = argv[1];
-       cmd_yaffs_mkdir(dirname);
-
-       return 0;
+       return cmd_yaffs_mkdir(dirname);
 }
 
 int do_yrmdir(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
@@ -240,9 +223,7 @@ int do_yrmdir(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        }
 
        dirname = argv[1];
-       cmd_yaffs_rmdir(dirname);
-
-       return 0;
+       return cmd_yaffs_rmdir(dirname);
 }
 
 int do_yrm(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
@@ -256,9 +237,7 @@ int do_yrm(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 
        name = argv[1];
 
-       cmd_yaffs_rm(name);
-
-       return 0;
+       return cmd_yaffs_rm(name);
 }
 
 int do_ymv(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
@@ -274,9 +253,7 @@ int do_ymv(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        oldPath = argv[1];
        newPath = argv[2];
 
-       cmd_yaffs_mv(newPath, oldPath);
-
-       return 0;
+       return cmd_yaffs_mv(newPath, oldPath);
 }
 
 U_BOOT_CMD(ytrace, 2, 0, do_ytrace,
@@ -298,6 +275,9 @@ U_BOOT_CMD(yumount, 2, 0, do_yumount,
 
 U_BOOT_CMD(yls, 3, 0, do_yls, "yaffs ls", "yls [-l] dirname");
 
+U_BOOT_CMD(ycheck, 3, 0, do_ycheck,
+          "ycheck name [DIR|REG]", "checks if the named object exists");
+
 U_BOOT_CMD(yrd, 2, 0, do_yrd,
           "read file from yaffs", "yrd path   read file from yaffs");
 
index db49052b385ea0d9c46de954fc3d648869f3f526..b7ec90915dc1a9dbfdc4eed0b442129503c3b0ff 100644 (file)
@@ -66,7 +66,7 @@ int nandmtd_WriteChunkToNAND(struct yaffs_dev *dev, int chunkInNAND,
        struct mtd_oob_ops ops;
        size_t dummy;
        int retval = 0;
-       loff_t addr = ((loff_t) chunkInNAND) * dev->data_bytes_per_chunk;
+       loff_t addr = ((loff_t) chunkInNAND) * dev->param.total_bytes_per_chunk;
        u8 spareAsBytes[8]; /* OOB */
 
        if (data && !spare)
@@ -102,7 +102,7 @@ int nandmtd_ReadChunkFromNAND(struct yaffs_dev *dev, int chunkInNAND, u8 *data,
        size_t dummy;
        int retval = 0;
 
-       loff_t addr = ((loff_t) chunkInNAND) * dev->data_bytes_per_chunk;
+       loff_t addr = ((loff_t) chunkInNAND) * dev->param.total_bytes_per_chunk;
        u8 spareAsBytes[8]; /* OOB */
 
        if (data && !spare)
@@ -135,7 +135,7 @@ int nandmtd_EraseBlockInNAND(struct yaffs_dev *dev, int blockNumber)
 {
        struct mtd_info *mtd = (struct mtd_info *)(dev->driver_context);
        __u32 addr =
-           ((loff_t) blockNumber) * dev->data_bytes_per_chunk
+           ((loff_t) blockNumber) * dev->param.total_bytes_per_chunk
                * dev->param.chunks_per_block;
        struct erase_info ei;
        int retval = 0;
index e113e4039e1f78a66d7258142df8854f6519eb06..f7ac21c635cabe32dc44f0212df40c2e10fa9a0f 100644 (file)
@@ -28,6 +28,8 @@
 #include "yaffs_packedtags2.h"
 #include "yaffs_mtdif.h"
 #include "yaffs_mtdif2.h"
+#include "yaffs_uboot_glue.h"
+
 #if 0
 #include <errno.h>
 #else
@@ -142,12 +144,13 @@ static const char *yaffs_error_str(void)
 
 extern nand_info_t nand_info[];
 
-void cmd_yaffs_tracemask(unsigned set, unsigned mask)
+int cmd_yaffs_tracemask(unsigned set, unsigned mask)
 {
        if (set)
                yaffs_trace_mask = mask;
 
        printf("yaffs trace mask: %08x\n", yaffs_trace_mask);
+       return 0;
 }
 
 static int yaffs_regions_overlap(int a, int b, int x, int y)
@@ -158,7 +161,7 @@ static int yaffs_regions_overlap(int a, int b, int x, int y)
                (x <= b && b <= y);
 }
 
-void cmd_yaffs_devconfig(char *_mp, int flash_dev,
+int cmd_yaffs_devconfig(char *_mp, int flash_dev,
                        int start_block, int end_block)
 {
        struct mtd_info *mtd = NULL;
@@ -240,14 +243,15 @@ void cmd_yaffs_devconfig(char *_mp, int flash_dev,
        printf("Configures yaffs mount %s: dev %d start block %d, end block %d %s\n",
                mp, flash_dev, start_block, end_block,
                dev->param.inband_tags ? "using inband tags" : "");
-       return;
+       return 0;
 
 err:
        free(dev);
        free(mp);
+       return -1;
 }
 
-void cmd_yaffs_dev_ls(void)
+int cmd_yaffs_dev_ls(void)
 {
        struct yaffs_dev *dev;
        int flash_dev;
@@ -258,7 +262,7 @@ void cmd_yaffs_dev_ls(void)
        while (1) {
                dev = yaffs_next_dev();
                if (!dev)
-                       return;
+                       break;
                flash_dev =
                        ((unsigned) dev->driver_context - (unsigned) nand_info)/
                                sizeof(nand_info[0]);
@@ -274,12 +278,15 @@ void cmd_yaffs_dev_ls(void)
                        printf("free 0x%x\n", free_space);
 
        }
+
+       return 0;
 }
 
-void make_a_file(char *yaffsName, char bval, int sizeOfFile)
+int make_a_file(char *yaffsName, char bval, int sizeOfFile)
 {
        int outh;
        int i;
+       int written;
        unsigned char buffer[100];
 
        outh = yaffs_open(yaffsName,
@@ -287,26 +294,28 @@ void make_a_file(char *yaffsName, char bval, int sizeOfFile)
                                S_IREAD | S_IWRITE);
        if (outh < 0) {
                printf("Error opening file: %d. %s\n", outh, yaffs_error_str());
-               return;
+               return -1;
        }
 
        memset(buffer, bval, 100);
 
-       do {
-               i = sizeOfFile;
+       written = 0;
+       while (written < sizeOfFile) {
+               i = sizeOfFile - written;
                if (i > 100)
                        i = 100;
-               sizeOfFile -= i;
-
-               yaffs_write(outh, buffer, i);
-
-       } while (sizeOfFile > 0);
 
+               if (yaffs_write(outh, buffer, i) != i)
+                       break;
+               written += i;
+       }
 
        yaffs_close(outh);
+
+       return (written == sizeOfFile) ? 0 : -1;
 }
 
-void read_a_file(char *fn)
+int read_a_file(char *fn)
 {
        int h;
        int i = 0;
@@ -315,7 +324,7 @@ void read_a_file(char *fn)
        h = yaffs_open(fn, O_RDWR, 0);
        if (h < 0) {
                printf("File not found\n");
-               return;
+               return -1;
        }
 
        while (yaffs_read(h, &b, 1) > 0) {
@@ -328,40 +337,49 @@ void read_a_file(char *fn)
        }
        printf("\n");
        yaffs_close(h);
+
+       return 0;
 }
 
-void cmd_yaffs_mount(char *mp)
+int cmd_yaffs_mount(char *mp)
 {
        int retval = yaffs_mount(mp);
        if (retval < 0)
                printf("Error mounting %s, return value: %d, %s\n", mp,
                        yaffsfs_GetError(), yaffs_error_str());
+       return retval;
 }
 
 
-void cmd_yaffs_umount(char *mp)
+int cmd_yaffs_umount(char *mp)
 {
-       if (yaffs_unmount(mp) == -1)
+       int retval = yaffs_unmount(mp);
+
+       if (retval < 0)
                printf("Error umounting %s, return value: %d, %s\n", mp,
                        yaffsfs_GetError(), yaffs_error_str());
+       return retval;
 }
 
-void cmd_yaffs_write_file(char *yaffsName, char bval, int sizeOfFile)
+int cmd_yaffs_write_file(char *yaffsName, char bval, int sizeOfFile)
 {
-       make_a_file(yaffsName, bval, sizeOfFile);
+       return make_a_file(yaffsName, bval, sizeOfFile);
 }
 
 
-void cmd_yaffs_read_file(char *fn)
+int cmd_yaffs_read_file(char *fn)
 {
-       read_a_file(fn);
+       return read_a_file(fn);
 }
 
 
-void cmd_yaffs_mread_file(char *fn, char *addr)
+int cmd_yaffs_mread_file(char *fn, char *addr)
 {
        int h;
+       int retval = 0;
        struct yaffs_stat s;
+       int read_size;
+       char buf[16];
 
        yaffs_stat(fn, &s);
 
@@ -369,31 +387,47 @@ void cmd_yaffs_mread_file(char *fn, char *addr)
        h = yaffs_open(fn, O_RDWR, 0);
        if (h < 0) {
                printf("File not found\n");
-               return;
+               retval = -1;
+               read_size = 0;
+       } else {
+               read_size = (int) s.st_size;
+               yaffs_read(h, addr, read_size);
+               printf("\t[DONE]\n");
+
+               yaffs_close(h);
        }
+       sprintf(buf,"%x", read_size);
+       setenv("filesize", buf);
 
-       yaffs_read(h, addr, (int)s.st_size);
-       printf("\t[DONE]\n");
-
-       yaffs_close(h);
+       return retval;
 }
 
 
-void cmd_yaffs_mwrite_file(char *fn, char *addr, int size)
+int cmd_yaffs_mwrite_file(char *fn, char *addr, int size)
 {
        int outh;
+       int wrote;
 
        outh = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
-       if (outh < 0)
+       if (outh < 0) {
                printf("Error opening file: %d, %s\n", outh, yaffs_error_str());
+               return -1;
+       }
 
-       yaffs_write(outh, addr, size);
-
+       wrote = yaffs_write(outh, addr, size);
        yaffs_close(outh);
+
+       if(wrote != size) {
+               printf("only wrote %d (0x%x) bytes\n", wrote, wrote);
+               return -1;
+       }
+       return 0;
+
+
 }
 
 
-void cmd_yaffs_ls(const char *mountpt, int longlist)
+int cmd_yaffs_ls(const char *mountpt, int longlist)
 {
        int i;
        yaffs_DIR *d;
@@ -405,7 +439,7 @@ void cmd_yaffs_ls(const char *mountpt, int longlist)
 
        if (!d) {
                printf("opendir failed, %s\n", yaffs_error_str());
-               return;
+               return -1;
        }
 
        for (i = 0; (de = yaffs_readdir(d)) != NULL; i++) {
@@ -424,41 +458,87 @@ void cmd_yaffs_ls(const char *mountpt, int longlist)
        }
 
        yaffs_closedir(d);
+
+       return 0;
 }
 
+int cmd_yaffs_check(const char *fname, const char *type)
+{
+       int retval = 0;
+       int ret;
+       struct yaffs_stat stat;
+
+       ret = yaffs_stat(fname, &stat);
+       if (ret < 0) {
+               printf("%s not found\n", fname);
+               return -1;
+       }
+
+       printf("%s is a %s\n", fname, yaffs_file_type_str(&stat));
+
+       if (strcmp(type, "REG") == 0 &&
+           (stat.st_mode & S_IFMT) != S_IFREG)
+               retval = -1;
 
-void cmd_yaffs_mkdir(const char *dir)
+       if (strcmp(type, "DIR") == 0 &&
+           (stat.st_mode & S_IFMT) != S_IFDIR)
+               retval = -1;
+
+       if (retval == 0)
+               printf("check ok\n");
+       else
+               printf("check failed\n");
+
+       return retval;
+}
+
+
+int cmd_yaffs_mkdir(const char *dir)
 {
        int retval = yaffs_mkdir(dir, 0);
 
-       if (retval < 0)
+       if (retval < 0) {
                printf("yaffs_mkdir returning error: %d, %s\n",
                        retval, yaffs_error_str());
+               return -1;
+       }
+       return 0;
 }
 
-void cmd_yaffs_rmdir(const char *dir)
+int cmd_yaffs_rmdir(const char *dir)
 {
        int retval = yaffs_rmdir(dir);
 
-       if (retval < 0)
+       if (retval < 0) {
                printf("yaffs_rmdir returning error: %d, %s\n",
                        retval, yaffs_error_str());
+               return -1;
+       }
+       return 0;
 }
 
-void cmd_yaffs_rm(const char *path)
+int cmd_yaffs_rm(const char *path)
 {
        int retval = yaffs_unlink(path);
 
-       if (retval < 0)
+       if (retval < 0) {
                printf("yaffs_unlink returning error: %d, %s\n",
                        retval, yaffs_error_str());
+               return -1;
+       }
+
+       return 0;
 }
 
-void cmd_yaffs_mv(const char *oldPath, const char *newPath)
+int cmd_yaffs_mv(const char *oldPath, const char *newPath)
 {
        int retval = yaffs_rename(newPath, oldPath);
 
-       if (retval < 0)
+       if (retval < 0) {
                printf("yaffs_unlink returning error: %d, %s\n",
                        retval, yaffs_error_str());
+               return -1;
+       }
+
+       return 0;
 }
diff --git a/direct/u-boot/fs/yaffs2/yaffs_uboot_glue.h b/direct/u-boot/fs/yaffs2/yaffs_uboot_glue.h
new file mode 100644 (file)
index 0000000..d3ae162
--- /dev/null
@@ -0,0 +1,24 @@
+
+#ifndef __YAFFS_UBOOT_GLUE_H__
+#define __YAFFS_UBOOT_GLUE_H__
+
+
+int cmd_yaffs_dev_ls(void);
+int cmd_yaffs_tracemask(unsigned set, unsigned mask);
+int cmd_yaffs_devconfig(char *mp, int flash_dev,
+                               int start_block, int end_block);
+int cmd_yaffs_mount(char *mp);
+int cmd_yaffs_umount(char *mp);
+int cmd_yaffs_read_file(char *fn);
+int cmd_yaffs_write_file(char *fn, char bval, int sizeOfFile);
+int cmd_yaffs_ls(const char *mountpt, int longlist);
+int cmd_yaffs_check(const char *fn, const char *type);
+int cmd_yaffs_mwrite_file(char *fn, char *addr, int size);
+int cmd_yaffs_mread_file(char *fn, char *addr);
+int cmd_yaffs_mkdir(const char *dir);
+int cmd_yaffs_rmdir(const char *dir);
+int cmd_yaffs_rm(const char *path);
+int cmd_yaffs_mv(const char *oldPath, const char *newPath);
+
+int yaffs_dump_dev(const char *path);
+#endif
index bb008f9a8ced71c5113a3901aa9494b5d17dcd9c..7fe0bf4fc294f4e5f6c0baae3fe4faeecc9fda03 100644 (file)
@@ -35,6 +35,8 @@ void yaffsfs_SetError(int err);
 void *yaffsfs_malloc(size_t size);
 void yaffsfs_free(void *ptr);
 
+int yaffsfs_CheckMemRegion(const void *addr, size_t size, int writeable);
+
 void yaffsfs_OSInitialisation(void);
 
 
index 705106e7a13e603333fbeaf15c02ca5f9d26a1fa..a26998439ccefd2f0d4fe6b2119c15e65dee3cf1 100644 (file)
@@ -122,6 +122,8 @@ static void yaffsfs_InitHandles(void)
        if (yaffsfs_handlesInitialised)
                return;
 
+       yaffsfs_handlesInitialised = 1;
+
        memset(yaffsfs_inode, 0, sizeof(yaffsfs_inode));
        memset(yaffsfs_fd, 0, sizeof(yaffsfs_fd));
        memset(yaffsfs_handle, 0, sizeof(yaffsfs_handle));
@@ -501,6 +503,9 @@ static struct yaffs_dev *yaffsfs_FindDevice(const YCHAR *path,
                thisMatchLength = 0;
                matching = 1;
 
+               if(!p)
+                       continue;
+
                while (matching && *p && *leftOver) {
                        /* Skip over any /s */
                        while (yaffsfs_IsPathDivider(*p))
@@ -793,7 +798,7 @@ int yaffs_open_sharing(const YCHAR *path, int oflag, int mode, int sharing)
        int notDir = 0;
        int loop = 0;
 
-       if (!path) {
+       if (yaffsfs_CheckMemRegion(path, 0, 0)< 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -1077,7 +1082,7 @@ static int yaffsfs_do_read(int handle, void *vbuf, unsigned int nbyte,
        Y_LOFF_T maxRead;
        u8 *buf = (u8 *) vbuf;
 
-       if (!vbuf) {
+       if (yaffsfs_CheckMemRegion(vbuf, nbyte, 1) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -1199,7 +1204,7 @@ static int yaffsfs_do_write(int handle, const void *vbuf, unsigned int nbyte,
        int nToWrite = 0;
        const u8 *buf = (const u8 *)vbuf;
 
-       if (!vbuf) {
+       if (yaffsfs_CheckMemRegion(vbuf, nbyte, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -1310,7 +1315,7 @@ int yaffs_truncate(const YCHAR *path, Y_LOFF_T new_size)
        int notDir = 0;
        int loop = 0;
 
-       if (!path) {
+       if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -1425,7 +1430,7 @@ static int yaffsfs_DoUnlink(const YCHAR *path, int isDirectory)
        int notDir = 0;
        int loop = 0;
 
-       if (!path) {
+       if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -1494,7 +1499,8 @@ int yaffs_rename(const YCHAR *oldPath, const YCHAR *newPath)
 
        YCHAR *alt_newpath = NULL;
 
-       if (!oldPath || !newPath) {
+       if (yaffsfs_CheckMemRegion(oldPath, 0, 0) < 0 ||
+           yaffsfs_CheckMemRegion(newPath, 0, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -1633,7 +1639,8 @@ static int yaffsfs_DoStatOrLStat(const YCHAR *path,
        int notDir = 0;
        int loop = 0;
 
-       if (!path || !buf) {
+       if (yaffsfs_CheckMemRegion(path, 0, 0) < 0 ||
+           yaffsfs_CheckMemRegion(buf, sizeof(*buf), 1) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -1681,7 +1688,7 @@ int yaffs_fstat(int fd, struct yaffs_stat *buf)
 
        int retVal = -1;
 
-       if (!buf) {
+       if (yaffsfs_CheckMemRegion(buf, sizeof(*buf), 1) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -1802,7 +1809,9 @@ static int yaffs_do_setxattr(const YCHAR *path, const char *name,
 
        int retVal = -1;
 
-       if (!path || !name || !data) {
+       if (yaffsfs_CheckMemRegion(path, 0, 0) < 0 ||
+           yaffsfs_CheckMemRegion(name, 0, 0) < 0 ||
+           yaffsfs_CheckMemRegion(data, size, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -1858,7 +1867,8 @@ int yaffs_fsetxattr(int fd, const char *name,
 
        int retVal = -1;
 
-       if (!name || !data) {
+       if (yaffsfs_CheckMemRegion(name, 0, 0) < 0 ||
+           yaffsfs_CheckMemRegion(data, size, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -1890,7 +1900,9 @@ static int yaffs_do_getxattr(const YCHAR *path, const char *name,
        int notDir = 0;
        int loop = 0;
 
-       if (!path || !name || !data) {
+       if (yaffsfs_CheckMemRegion(path, 0, 0) < 0 ||
+           yaffsfs_CheckMemRegion(name, 0, 0) < 0 ||
+           yaffsfs_CheckMemRegion(data, size, 1) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -1942,7 +1954,8 @@ int yaffs_fgetxattr(int fd, const char *name, void *data, int size)
 
        int retVal = -1;
 
-       if (!name || !data) {
+       if (yaffsfs_CheckMemRegion(name, 0, 0) < 0 ||
+           yaffsfs_CheckMemRegion(data, size, 1) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -1974,7 +1987,8 @@ static int yaffs_do_listxattr(const YCHAR *path, char *data,
        int notDir = 0;
        int loop = 0;
 
-       if (!path || !data) {
+       if (yaffsfs_CheckMemRegion(path, 0, 0) < 0 ||
+           yaffsfs_CheckMemRegion(data, size, 1) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -2027,7 +2041,7 @@ int yaffs_flistxattr(int fd, char *data, int size)
 
        int retVal = -1;
 
-       if (!data) {
+       if (yaffsfs_CheckMemRegion(data, size, 1) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -2059,7 +2073,8 @@ static int yaffs_do_removexattr(const YCHAR *path, const char *name,
        int loop = 0;
        int retVal = -1;
 
-       if (!path || !name) {
+       if (yaffsfs_CheckMemRegion(path, 0, 0) < 0 ||
+           yaffsfs_CheckMemRegion(name, 0, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -2112,7 +2127,7 @@ int yaffs_fremovexattr(int fd, const char *name)
 
        int retVal = -1;
 
-       if (!name) {
+       if (yaffsfs_CheckMemRegion(name, 0, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -2236,7 +2251,7 @@ int yaffs_access(const YCHAR *path, int amode)
        int loop = 0;
        int retval = -1;
 
-       if (!path) {
+       if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -2294,7 +2309,7 @@ int yaffs_chmod(const YCHAR *path, mode_t mode)
        int notDir = 0;
        int loop = 0;
 
-       if (!path) {
+       if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -2366,7 +2381,7 @@ int yaffs_mkdir(const YCHAR *path, mode_t mode)
        int notDir = 0;
        int loop = 0;
 
-       if (!path) {
+       if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -2420,7 +2435,7 @@ int yaffs_rmdir(const YCHAR *path)
        int result;
        YCHAR *alt_path;
 
-       if (!path) {
+       if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -2457,7 +2472,7 @@ int yaffs_mount_common(const YCHAR *path, int read_only, int skip_checkpt)
        int result = YAFFS_FAIL;
        struct yaffs_dev *dev = NULL;
 
-       if (!path) {
+       if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -2516,7 +2531,7 @@ int yaffs_sync(const YCHAR *path)
        struct yaffs_dev *dev = NULL;
        YCHAR *dummy;
 
-       if (!path) {
+       if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -2565,7 +2580,7 @@ int yaffs_remount(const YCHAR *path, int force, int read_only)
        int retVal = -1;
        struct yaffs_dev *dev = NULL;
 
-       if (!path) {
+       if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -2605,7 +2620,7 @@ int yaffs_unmount2(const YCHAR *path, int force)
        int retVal = -1;
        struct yaffs_dev *dev = NULL;
 
-       if (!path) {
+       if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -2715,7 +2730,7 @@ Y_LOFF_T yaffs_freespace(const YCHAR *path)
        struct yaffs_dev *dev = NULL;
        YCHAR *dummy;
 
-       if (!path) {
+       if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -2744,7 +2759,7 @@ Y_LOFF_T yaffs_totalspace(const YCHAR *path)
        struct yaffs_dev *dev = NULL;
        YCHAR *dummy;
 
-       if (!path) {
+       if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -2775,7 +2790,7 @@ int yaffs_inodecount(const YCHAR *path)
        struct yaffs_dev *dev = NULL;
        YCHAR *dummy;
 
-       if (!path) {
+       if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -2927,7 +2942,7 @@ yaffs_DIR *yaffs_opendir(const YCHAR *dirname)
        int notDir = 0;
        int loop = 0;
 
-       if (!dirname) {
+       if (yaffsfs_CheckMemRegion(dirname, 0, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return NULL;
        }
@@ -3021,6 +3036,9 @@ void yaffs_rewinddir(yaffs_DIR *dirp)
 
        dsc = (struct yaffsfs_DirSearchContxt *) dirp;
 
+       if (yaffsfs_CheckMemRegion(dirp, sizeof(*dsc), 0) < 0)
+               return;
+
        yaffsfs_Lock();
 
        yaffsfs_SetDirRewound(dsc);
@@ -3034,7 +3052,7 @@ int yaffs_closedir(yaffs_DIR *dirp)
 
        dsc = (struct yaffsfs_DirSearchContxt *) dirp;
 
-       if (!dsc) {
+       if (yaffsfs_CheckMemRegion(dirp, sizeof(*dsc), 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -3058,7 +3076,8 @@ int yaffs_symlink(const YCHAR *oldpath, const YCHAR *newpath)
        int notDir = 0;
        int loop = 0;
 
-       if (!oldpath || !newpath) {
+       if (yaffsfs_CheckMemRegion(oldpath, 0, 0) < 0 ||
+           yaffsfs_CheckMemRegion(newpath, 0, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -3105,7 +3124,8 @@ int yaffs_readlink(const YCHAR *path, YCHAR *buf, int bufsiz)
        int notDir = 0;
        int loop = 0;
 
-       if (!path || !buf) {
+       if (yaffsfs_CheckMemRegion(path, 0, 0) < 0 ||
+           yaffsfs_CheckMemRegion(buf, bufsiz, 1) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -3146,7 +3166,8 @@ int yaffs_link(const YCHAR *oldpath, const YCHAR *linkpath)
        int lnkLoop = 0;
        YCHAR *newname;
 
-       if (!oldpath || !linkpath) {
+       if (yaffsfs_CheckMemRegion(oldpath, 0, 0) < 0 ||
+           yaffsfs_CheckMemRegion(linkpath, 0, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
@@ -3218,7 +3239,7 @@ int yaffs_n_handles(const YCHAR *path)
 {
        struct yaffs_obj *obj;
 
-       if (!path) {
+       if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) {
                yaffsfs_SetError(-EFAULT);
                return -1;
        }
index ed54d53505eb37821617d6ae3c12eee7c21536af..3da6925fd42163b92c6b26cf4e1a66b397e4accb 100755 (executable)
@@ -54,14 +54,12 @@ fi
 
 if [ $MULTIORSINGLE = m ]; then
    VFS_CODE="yaffs_vfs_multi.c"
-   MTD1_CODE="yaffs_mtdif1_multi.c"
-   MTD2_CODE="yaffs_mtdif2_multi.c"
+   MTD_CODE="yaffs_mtdif_multi.c"
    YPORTENV="yportenv_multi.h"
    KCONFIG_SRC="Kconfig_multi"
 elif [ $MULTIORSINGLE = s ]; then
    VFS_CODE="yaffs_vfs_single.c"
-   MTD1_CODE="yaffs_mtdif1_single.c"
-   MTD2_CODE="yaffs_mtdif2_single.c"
+   MTD_CODE="yaffs_mtdif_single.c"
    YPORTENV="yportenv_single.h"
    KCONFIG_SRC="Kconfig_single"
 
@@ -149,11 +147,10 @@ else
    $CPY  $PWD/Makefile.kernel $LINUXDIR/fs/yaffs2/Makefile
    $CPY $PWD/$KCONFIG_SRC $LINUXDIR/fs/yaffs2/Kconfig
    $CPY $PWD/*.c $PWD/*.h  $LINUXDIR/fs/yaffs2
-   rm $LINUXDIR/fs/yaffs2/yaffs_vfs*.c $LINUXDIR/fs/yaffs2/yaffs_mtdif[12]*.c
+   rm $LINUXDIR/fs/yaffs2/yaffs_vfs*.c $LINUXDIR/fs/yaffs2/yaffs_mtdif*.c
    rm $LINUXDIR/fs/yaffs2/yportenv*.h
    rm $LINUXDIR/fs/yaffs2/moduleconfig.h
    $CPY $PWD/$VFS_CODE $LINUXDIR/fs/yaffs2/yaffs_vfs.c
-   $CPY $PWD/$MTD1_CODE $LINUXDIR/fs/yaffs2/yaffs_mtdif1.c
-   $CPY $PWD/$MTD2_CODE $LINUXDIR/fs/yaffs2/yaffs_mtdif2.c
+   $CPY $PWD/$MTD_CODE $LINUXDIR/fs/yaffs2/yaffs_mtdif.c
    $CPY $PWD/$YPORTENV $LINUXDIR/fs/yaffs2/yportenv.h
 fi
index 8478eb88185fc4e1b271f161f31062e1f84bffb4..e739fb4a104b6261969a5ef869caeb7b87bdbbe3 100644 (file)
@@ -74,7 +74,7 @@ static int yaffs_checkpt_erase(struct yaffs_dev *dev)
 {
        int i;
 
-       if (!dev->param.erase_fn)
+       if (!dev->drv.drv_erase_fn)
                return 0;
        yaffs_trace(YAFFS_TRACE_CHECKPOINT,
                "checking blocks %d to %d",
@@ -91,14 +91,14 @@ static int yaffs_checkpt_erase(struct yaffs_dev *dev)
 
                        dev->n_erasures++;
 
-                       result = dev->param.erase_fn(dev, offset_i);
+                       result = dev->drv.drv_erase_fn(dev, offset_i);
                        if(result) {
                                bi->block_state = YAFFS_BLOCK_STATE_EMPTY;
                                dev->n_erased_blocks++;
                                dev->n_free_chunks +=
                                    dev->param.chunks_per_block;
                        } else {
-                               dev->param.bad_block_fn(dev, offset_i);
+                               dev->drv.drv_mark_bad_fn(dev, offset_i);
                                bi->block_state = YAFFS_BLOCK_STATE_DEAD;
                        }
                }
@@ -159,7 +159,7 @@ static void yaffs2_checkpt_find_block(struct yaffs_dev *dev)
                        enum yaffs_block_state state;
                        u32 seq;
 
-                       dev->param.read_chunk_tags_fn(dev,
+                       dev->tagger.read_chunk_tags_fn(dev,
                                        apply_chunk_offset(dev, chunk),
                                        NULL, &tags);
                        yaffs_trace(YAFFS_TRACE_CHECKPOINT,
@@ -171,7 +171,7 @@ static void yaffs2_checkpt_find_block(struct yaffs_dev *dev)
                        if (tags.seq_number != YAFFS_SEQUENCE_CHECKPOINT_DATA)
                                continue;
 
-                       dev->param.query_block_fn(dev,
+                       dev->tagger.query_block_fn(dev,
                                                apply_block_offset(dev, i),
                                                &state, &seq);
                        if (state == YAFFS_BLOCK_STATE_DEAD)
@@ -200,9 +200,10 @@ int yaffs2_checkpt_open(struct yaffs_dev *dev, int writing)
        dev->checkpt_open_write = writing;
 
        /* Got the functions we need? */
-       if (!dev->param.write_chunk_tags_fn ||
-           !dev->param.read_chunk_tags_fn ||
-           !dev->param.erase_fn || !dev->param.bad_block_fn)
+       if (!dev->tagger.write_chunk_tags_fn ||
+           !dev->tagger.read_chunk_tags_fn ||
+           !dev->drv.drv_erase_fn ||
+           !dev->drv.drv_mark_bad_fn)
                return 0;
 
        if (writing && !yaffs2_checkpt_space_ok(dev))
@@ -298,7 +299,7 @@ static int yaffs2_checkpt_flush_buffer(struct yaffs_dev *dev)
 
        dev->n_page_writes++;
 
-       dev->param.write_chunk_tags_fn(dev, offset_chunk,
+       dev->tagger.write_chunk_tags_fn(dev, offset_chunk,
                                       dev->checkpt_buffer, &tags);
        dev->checkpt_page_seq++;
        dev->checkpt_cur_chunk++;
@@ -382,7 +383,7 @@ int yaffs2_checkpt_rd(struct yaffs_dev *dev, void *data, int n_bytes)
                        dev->n_page_reads++;
 
                        /* read in the next chunk */
-                       dev->param.read_chunk_tags_fn(dev,
+                       dev->tagger.read_chunk_tags_fn(dev,
                                                offset_chunk,
                                                dev->checkpt_buffer,
                                                &tags);
index 9c296e24bcd181440cdb254f3dc3b3602f3730a9..9f6b40964b5e85d154294fef73af38b544634cd8 100644 (file)
@@ -17,6 +17,7 @@
 #include "yaffs_guts.h"
 #include "yaffs_getblockinfo.h"
 #include "yaffs_tagscompat.h"
+#include "yaffs_tagsmarshall.h"
 #include "yaffs_nand.h"
 #include "yaffs_yaffs1.h"
 #include "yaffs_yaffs2.h"
@@ -609,10 +610,10 @@ static void yaffs_retire_block(struct yaffs_dev *dev, int flash_block)
                        memset(buffer, 0xff, dev->data_bytes_per_chunk);
                        memset(&tags, 0, sizeof(tags));
                        tags.seq_number = YAFFS_SEQUENCE_BAD_BLOCK;
-                       if (dev->param.write_chunk_tags_fn(dev, chunk_id -
-                                                          dev->chunk_offset,
-                                                          buffer,
-                                                          &tags) != YAFFS_OK)
+                       if (dev->tagger.write_chunk_tags_fn(dev, chunk_id -
+                                                       dev->chunk_offset,
+                                                       buffer,
+                                                       &tags) != YAFFS_OK)
                                yaffs_trace(YAFFS_TRACE_ALWAYS,
                                        "yaffs: Failed to write bad block marker to block %d",
                                        flash_block);
@@ -2804,7 +2805,8 @@ static int yaffs_check_gc(struct yaffs_dev *dev, int background)
        int erased_chunks;
        int checkpt_block_adjust;
 
-       if (dev->param.gc_control && (dev->param.gc_control(dev) & 1) == 0)
+       if (dev->param.gc_control_fn &&
+               (dev->param.gc_control_fn(dev) & 1) == 0)
                return YAFFS_OK;
 
        if (dev->gc_disable)
@@ -3566,9 +3568,11 @@ int yaffs_do_file_wr(struct yaffs_obj *in, const u8 *buffer, loff_t offset,
                }
 
                if (n_copy != dev->data_bytes_per_chunk ||
+                   !dev->param.cache_bypass_aligned ||
                    dev->param.inband_tags) {
                        /* An incomplete start or end chunk (or maybe both
                         * start and end chunk), or we're using inband tags,
+                        * or we're forcing writes through the cache,
                         * so we want to use the cache buffers.
                         */
                        if (dev->param.n_caches > 0) {
@@ -4536,30 +4540,33 @@ YCHAR *yaffs_get_symlink_alias(struct yaffs_obj *obj)
 
 /*--------------------------- Initialisation code -------------------------- */
 
-static int yaffs_check_dev_fns(const struct yaffs_dev *dev)
+static int yaffs_check_dev_fns(struct yaffs_dev *dev)
 {
+       struct yaffs_driver *drv = &dev->drv;
+       struct yaffs_tags_handler *tagger = &dev->tagger;
+
        /* Common functions, gotta have */
-       if (!dev->param.erase_fn || !dev->param.initialise_flash_fn)
+       if (!drv->drv_read_chunk_fn ||
+           !drv->drv_write_chunk_fn ||
+           !drv->drv_erase_fn)
                return 0;
 
-       /* Can use the "with tags" style interface for yaffs1 or yaffs2 */
-       if (dev->param.write_chunk_tags_fn &&
-           dev->param.read_chunk_tags_fn &&
-           !dev->param.write_chunk_fn &&
-           !dev->param.read_chunk_fn &&
-           dev->param.bad_block_fn && dev->param.query_block_fn)
-               return 1;
+       if (dev->param.is_yaffs2 &&
+            (!drv->drv_mark_bad_fn  || !drv->drv_check_bad_fn))
+               return 0;
 
-       /* Can use the "spare" style interface for yaffs1 */
-       if (!dev->param.is_yaffs2 &&
-           !dev->param.write_chunk_tags_fn &&
-           !dev->param.read_chunk_tags_fn &&
-           dev->param.write_chunk_fn &&
-           dev->param.read_chunk_fn &&
-           !dev->param.bad_block_fn && !dev->param.query_block_fn)
-               return 1;
+       /* Install the default tags marshalling functions if needed. */
+       yaffs_tags_compat_install(dev);
+       yaffs_tags_marshall_install(dev);
 
-       return 0;               /* bad */
+       /* Check we now have the marshalling functions required. */
+       if (!tagger->write_chunk_tags_fn ||
+           !tagger->read_chunk_tags_fn ||
+           !tagger->query_block_fn ||
+           !tagger->mark_bad_fn)
+               return 0;
+
+       return 1;
 }
 
 static int yaffs_create_initial_dir(struct yaffs_dev *dev)
@@ -4929,8 +4936,7 @@ void yaffs_deinitialise(struct yaffs_dev *dev)
 
                dev->is_mounted = 0;
 
-               if (dev->param.deinitialise_flash_fn)
-                       dev->param.deinitialise_flash_fn(dev);
+               yaffs_deinit_nand(dev);
        }
 }
 
index 941782d8c3af29894203490263dd5f1c718c60dc..64929ed37c29b6e4debf22e83b1a38a288d33fa5 100644 (file)
@@ -520,7 +520,7 @@ struct yaffs_param {
        /*
         * Entry parameters set up way early. Yaffs sets up the rest.
         * The structure should be zeroed out before use so that unused
-        * and defualt values are zero.
+        * and default values are zero.
         */
 
        int inband_tags;        /* Use unband tags */
@@ -536,6 +536,10 @@ struct yaffs_param {
        int n_caches;           /* If <= 0, then short op caching is disabled,
                                 * else the number of short op caches.
                                 */
+       int cache_bypass_aligned; /* If non-zero then bypass the cache for
+                                  * aligned writes.
+                                  */
+
        int use_nand_ecc;       /* Flag to decide whether or not to use
                                 * NAND driver ECC on data (yaffs1) */
        int tags_9bytes;        /* Use 9 byte tags */
@@ -554,29 +558,10 @@ struct yaffs_param {
 
        int enable_xattr;       /* Enable xattribs */
 
-       /* NAND access functions (Must be set before calling YAFFS) */
-
-       int (*write_chunk_fn) (struct yaffs_dev *dev,
-                              int nand_chunk, const u8 *data,
-                              const struct yaffs_spare *spare);
-       int (*read_chunk_fn) (struct yaffs_dev *dev,
-                             int nand_chunk, u8 *data,
-                             struct yaffs_spare *spare);
-       int (*erase_fn) (struct yaffs_dev *dev, int flash_block);
-       int (*initialise_flash_fn) (struct yaffs_dev *dev);
-       int (*deinitialise_flash_fn) (struct yaffs_dev *dev);
-
-       /* yaffs2 mode functions */
-       int (*write_chunk_tags_fn) (struct yaffs_dev *dev,
-                                   int nand_chunk, const u8 *data,
-                                   const struct yaffs_ext_tags *tags);
-       int (*read_chunk_tags_fn) (struct yaffs_dev *dev,
-                                  int nand_chunk, u8 *data,
-                                  struct yaffs_ext_tags *tags);
-       int (*bad_block_fn) (struct yaffs_dev *dev, int block_no);
-       int (*query_block_fn) (struct yaffs_dev *dev, int block_no,
-                              enum yaffs_block_state *state,
-                              u32 *seq_number);
+       int max_objects;        /*
+                                * Set to limit the number of objects created.
+                                * 0 = no limit.
+                               */
 
        /* The remove_obj_fn function must be supplied by OS flavours that
         * need it.
@@ -589,7 +574,7 @@ struct yaffs_param {
        void (*sb_dirty_fn) (struct yaffs_dev *dev);
 
        /*  Callback to control garbage collection. */
-       unsigned (*gc_control) (struct yaffs_dev *dev);
+       unsigned (*gc_control_fn) (struct yaffs_dev *dev);
 
        /* Debug control flags. Don't use unless you know what you're doing */
        int use_header_file_size;       /* Flag to determine if we should use
@@ -608,14 +593,41 @@ struct yaffs_param {
 
        int disable_summary;
 
-       int max_objects;        /*
-                                * Set to limit the number of objects created.
-                                * 0 = no limit.
-                               */
+};
+
+struct yaffs_driver {
+       int (*drv_write_chunk_fn) (struct yaffs_dev *dev, int nand_chunk,
+                                  const u8 *data, int data_len,
+                                  const u8 *oob, int oob_len);
+       int (*drv_read_chunk_fn) (struct yaffs_dev *dev, int nand_chunk,
+                                  u8 *data, int data_len,
+                                  u8 *oob, int oob_len,
+                                  enum yaffs_ecc_result *ecc_result);
+       int (*drv_erase_fn) (struct yaffs_dev *dev, int block_no);
+       int (*drv_mark_bad_fn) (struct yaffs_dev *dev, int block_no);
+       int (*drv_check_bad_fn) (struct yaffs_dev *dev, int block_no);
+       int (*drv_initialise_fn) (struct yaffs_dev *dev);
+       int (*drv_deinitialise_fn) (struct yaffs_dev *dev);
+};
+
+struct yaffs_tags_handler {
+       int (*write_chunk_tags_fn) (struct yaffs_dev *dev,
+                                   int nand_chunk, const u8 *data,
+                                   const struct yaffs_ext_tags *tags);
+       int (*read_chunk_tags_fn) (struct yaffs_dev *dev,
+                                  int nand_chunk, u8 *data,
+                                  struct yaffs_ext_tags *tags);
+
+       int (*query_block_fn) (struct yaffs_dev *dev, int block_no,
+                              enum yaffs_block_state *state,
+                              u32 *seq_number);
+       int (*mark_bad_fn) (struct yaffs_dev *dev, int block_no);
 };
 
 struct yaffs_dev {
        struct yaffs_param param;
+       struct yaffs_driver drv;
+       struct yaffs_tags_handler tagger;
 
        /* Context storage. Holds extra OS specific data for this device */
 
@@ -762,6 +774,7 @@ struct yaffs_dev {
        u32 n_page_writes;
        u32 n_page_reads;
        u32 n_erasures;
+       u32 n_bad_markings;
        u32 n_erase_failures;
        u32 n_gc_copies;
        u32 all_gcs;
index 8c522c84852a391e281df3b2815792de933f8721..c541e31b3061073590ae541a46b1819ff7a6b7b5 100644 (file)
@@ -29,8 +29,6 @@ struct yaffs_linux_context {
                                 * at compile time so we have to allocate it.
                                 */
        struct list_head search_contexts;
-       void (*put_super_fn) (struct super_block *sb);
-
        struct task_struct *readdir_process;
        unsigned mount_id;
 };
diff --git a/yaffs_mtdif.c b/yaffs_mtdif.c
deleted file mode 100644 (file)
index edc1525..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
- *
- * Copyright (C) 2002-2011 Aleph One Ltd.
- *   for Toby Churchill Ltd and Brightstar Engineering
- *
- * 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.
- */
-
-#include "yportenv.h"
-
-#include "yaffs_mtdif.h"
-
-#include "linux/mtd/mtd.h"
-#include "linux/types.h"
-#include "linux/time.h"
-#include "linux/mtd/nand.h"
-
-#include "yaffs_linux.h"
-
-int nandmtd_erase_block(struct yaffs_dev *dev, int block_no)
-{
-       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-       u32 addr =
-           ((loff_t) block_no) * dev->param.total_bytes_per_chunk *
-           dev->param.chunks_per_block;
-       struct erase_info ei;
-       int retval = 0;
-
-       ei.mtd = mtd;
-       ei.addr = addr;
-       ei.len = dev->param.total_bytes_per_chunk * dev->param.chunks_per_block;
-       ei.time = 1000;
-       ei.retries = 2;
-       ei.callback = NULL;
-       ei.priv = (u_long) dev;
-
-       retval = mtd->erase(mtd, &ei);
-
-       if (retval == 0)
-               return YAFFS_OK;
-
-       return YAFFS_FAIL;
-}
-
-int nandmtd_initialise(struct yaffs_dev *dev)
-{
-       return YAFFS_OK;
-}
index 3ef5581fdbcfabd2f4fd41b9d521870527152285..e5172eb1336727737a2bdb87c655143b66b8fbac 100644 (file)
@@ -18,6 +18,6 @@
 
 #include "yaffs_guts.h"
 
-int nandmtd_erase_block(struct yaffs_dev *dev, int block_no);
-int nandmtd_initialise(struct yaffs_dev *dev);
+void yaffs_mtd_drv_install(struct yaffs_dev *dev);
+
 #endif
diff --git a/yaffs_mtdif1.h b/yaffs_mtdif1.h
deleted file mode 100644 (file)
index 6a5df50..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * YAFFS: Yet another Flash File System. A NAND-flash specific file system.
- *
- * Copyright (C) 2002-2011 Aleph One Ltd.
- *   for Toby Churchill Ltd and Brightstar Engineering
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1 as
- * published by the Free Software Foundation.
- *
- * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
- */
-
-#ifndef __YAFFS_MTDIF1_H__
-#define __YAFFS_MTDIF1_H__
-
-int nandmtd1_write_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
-                             const u8 *data,
-                             const struct yaffs_ext_tags *tags);
-
-int nandmtd1_read_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
-                            u8 *data, struct yaffs_ext_tags *tags);
-
-int nandmtd1_mark_block_bad(struct yaffs_dev *dev, int block_no);
-
-int nandmtd1_query_block(struct yaffs_dev *dev, int block_no,
-                        enum yaffs_block_state *state, u32 *seq_number);
-
-#endif
diff --git a/yaffs_mtdif1_multi.c b/yaffs_mtdif1_multi.c
deleted file mode 100644 (file)
index 14d5c6f..0000000
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * YAFFS: Yet another FFS. A NAND-flash specific file system.
- *
- * Copyright (C) 2002-2011 Aleph One Ltd.
- *   for Toby Churchill Ltd and Brightstar Engineering
- *
- * 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 module provides the interface between yaffs_nand.c and the
- * MTD API.  This version is used when the MTD interface supports the
- * 'mtd_oob_ops' style calls to read_oob and write_oob, circa 2.6.17,
- * and we have small-page NAND device.
- *
- * These functions are invoked via function pointers in yaffs_nand.c.
- * This replaces functionality provided by functions in yaffs_mtdif.c
- * and the yaffs_tags compatability functions in yaffs_tagscompat.c that are
- * called in yaffs_mtdif.c when the function pointers are NULL.
- * We assume the MTD layer is performing ECC (use_nand_ecc is true).
- */
-
-#include "yportenv.h"
-#include "yaffs_trace.h"
-#include "yaffs_guts.h"
-#include "yaffs_packedtags1.h"
-#include "yaffs_tagscompat.h"  /* for yaffs_calc_tags_ecc */
-#include "yaffs_linux.h"
-
-#include "linux/kernel.h"
-#include "linux/version.h"
-#include "linux/types.h"
-#include "linux/mtd/mtd.h"
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
-#define MTD_OPS_AUTO_OOB MTD_OOB_AUTO
-#endif
-
-
-/* Don't compile this module if we don't have MTD's mtd_oob_ops interface */
-#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
-
-
-#if 0
-/* Use the following nand_ecclayout with MTD when using
- * 9 byte tags and the older on-NAND tags layout.
- * If you have existing Yaffs images and the byte order differs from this,
- * adjust 'oobfree' to match your existing Yaffs data.
- *
- * This nand_ecclayout scatters/gathers to/from the old-yaffs layout with the
- * page_status byte (at NAND spare offset 4) scattered/gathered from/to
- * the 9th byte.
- *
- * Old-style on-NAND format: T0,T1,T2,T3,P,B,T4,T5,E0,E1,E2,T6,T7,E3,E4,E5
- * We have/need packed_tags1 plus page_status: T0,T1,T2,T3,T4,T5,T6,T7,P
- * where Tn are the tag bytes, En are MTD's ECC bytes, P is the page_status
- * byte and B is the small-page bad-block indicator byte.
- */
-static struct nand_ecclayout nand_oob_16 = {
-       .eccbytes = 6,
-       .eccpos = {8, 9, 10, 13, 14, 15},
-       .oobavail = 9,
-       .oobfree = {{0, 4}, {6, 2}, {11, 2}, {4, 1} }
-};
-#endif
-
-/* Write a chunk (page) of data to NAND.
- *
- * Caller always provides ExtendedTags data which are converted to a more
- * compact (packed) form for storage in NAND.  A mini-ECC runs over the
- * contents of the tags meta-data; used to valid the tags when read.
- *
- *  - Pack ExtendedTags to packed_tags1 form
- *  - Compute mini-ECC for packed_tags1
- *  - Write data and packed tags to NAND.
- *
- * Note: Due to the use of the packed_tags1 meta-data which does not include
- * a full sequence number (as found in the larger packed_tags2 form) it is
- * necessary for Yaffs to re-write a chunk/page (just once) to mark it as
- * discarded and dirty.  This is not ideal: newer NAND parts are supposed
- * to be written just once.  When Yaffs performs this operation, this
- * function is called with a NULL data pointer -- calling MTD write_oob
- * without data is valid usage (2.6.17).
- *
- * Any underlying MTD error results in YAFFS_FAIL.
- * Returns YAFFS_OK or YAFFS_FAIL.
- */
-int nandmtd1_write_chunk_tags(struct yaffs_dev *dev,
-                             int nand_chunk, const u8 *data,
-                             const struct yaffs_ext_tags *etags)
-{
-       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-       int chunk_bytes = dev->data_bytes_per_chunk;
-       loff_t addr = ((loff_t) nand_chunk) * chunk_bytes;
-       struct mtd_oob_ops ops;
-       struct yaffs_packed_tags1 pt1;
-       int retval;
-
-       /* we assume that packed_tags1 and struct yaffs_tags are compatible */
-       compile_time_assertion(sizeof(struct yaffs_packed_tags1) == 12);
-       compile_time_assertion(sizeof(struct yaffs_tags) == 8);
-
-       yaffs_pack_tags1(&pt1, etags);
-       yaffs_calc_tags_ecc((struct yaffs_tags *)&pt1);
-
-       /* When deleting a chunk, the upper layer provides only skeletal
-        * etags, one with is_deleted set.  However, we need to update the
-        * tags, not erase them completely.  So we use the NAND write property
-        * that only zeroed-bits stick and set tag bytes to all-ones and
-        * zero just the (not) deleted bit.
-        */
-       if(dev->param.tags_9bytes) {
-               ((u8 *) &pt1)[8] = 0xff;
-               if (etags->is_deleted) {
-                       memset(&pt1, 0xff, 8);
-                       /* zero page_status byte to indicate deleted */
-                       ((u8 *) &pt1)[8] = 0;
-                }
-        } else {
-               if (etags->is_deleted) {
-                       memset(&pt1, 0xff, 8);
-                       /* clear delete status bit to indicate deleted */
-                       pt1.deleted = 0;
-                }
-       }
-
-       memset(&ops, 0, sizeof(ops));
-       ops.mode = MTD_OPS_AUTO_OOB;
-       ops.len = (data) ? chunk_bytes : 0;
-       ops.ooblen = dev->param.tags_9bytes ? 9 : 8;
-       ops.datbuf = (u8 *) data;
-       ops.oobbuf = (u8 *) &pt1;
-
-       retval = mtd->write_oob(mtd, addr, &ops);
-       if (retval) {
-               yaffs_trace(YAFFS_TRACE_MTD,
-                       "write_oob failed, chunk %d, mtd error %d",
-                       nand_chunk, retval);
-       }
-       return retval ? YAFFS_FAIL : YAFFS_OK;
-}
-
-/* Return with empty ExtendedTags but add ecc_result.
- */
-static int rettags(struct yaffs_ext_tags *etags, int ecc_result, int retval)
-{
-       if (etags) {
-               memset(etags, 0, sizeof(*etags));
-               etags->ecc_result = ecc_result;
-       }
-       return retval;
-}
-
-/* Read a chunk (page) from NAND.
- *
- * Caller expects ExtendedTags data to be usable even on error; that is,
- * all members except ecc_result and block_bad are zeroed.
- *
- *  - Check ECC results for data (if applicable)
- *  - Check for blank/erased block (return empty ExtendedTags if blank)
- *  - Check the packed_tags1 mini-ECC (correct if necessary/possible)
- *  - Convert packed_tags1 to ExtendedTags
- *  - Update ecc_result and block_bad members to refect state.
- *
- * Returns YAFFS_OK or YAFFS_FAIL.
- */
-int nandmtd1_read_chunk_tags(struct yaffs_dev *dev,
-                            int nand_chunk, u8 *data,
-                            struct yaffs_ext_tags *etags)
-{
-       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-       int chunk_bytes = dev->data_bytes_per_chunk;
-       loff_t addr = ((loff_t) nand_chunk) * chunk_bytes;
-       int eccres = YAFFS_ECC_RESULT_NO_ERROR;
-       struct mtd_oob_ops ops;
-       struct yaffs_packed_tags1 pt1;
-       int retval;
-       int deleted;
-
-       memset(&ops, 0, sizeof(ops));
-       ops.mode = MTD_OPS_AUTO_OOB;
-       ops.len = (data) ? chunk_bytes : 0;
-       ops.ooblen = dev->param.tags_9bytes ? 9 : 8;
-       ops.datbuf = data;
-       ops.oobbuf = (u8 *) &pt1;
-
-#if (MTD_VERSION_CODE < MTD_VERSION(2, 6, 20))
-       /* In MTD 2.6.18 to 2.6.19 nand_base.c:nand_do_read_oob() has a bug;
-        * help it out with ops.len = ops.ooblen when ops.datbuf == NULL.
-        */
-       ops.len = (ops.datbuf) ? ops.len : ops.ooblen;
-#endif
-       /* Read page and oob using MTD.
-        * Check status and determine ECC result.
-        */
-       retval = mtd->read_oob(mtd, addr, &ops);
-       if (retval)
-               yaffs_trace(YAFFS_TRACE_MTD,
-                       "read_oob failed, chunk %d, mtd error %d",
-                       nand_chunk, retval);
-
-       switch (retval) {
-       case 0:
-               /* no error */
-               break;
-
-       case -EUCLEAN:
-               /* MTD's ECC fixed the data */
-               eccres = YAFFS_ECC_RESULT_FIXED;
-               dev->n_ecc_fixed++;
-               break;
-
-       case -EBADMSG:
-               /* MTD's ECC could not fix the data */
-               dev->n_ecc_unfixed++;
-               /* fall into... */
-       default:
-               rettags(etags, YAFFS_ECC_RESULT_UNFIXED, 0);
-               etags->block_bad = (mtd->block_isbad) (mtd, addr);
-               return YAFFS_FAIL;
-       }
-
-       /* Check for a blank/erased chunk.
-        */
-       if (yaffs_check_ff((u8 *) &pt1, 8)) {
-               /* when blank, upper layers want ecc_result to be <= NO_ERROR */
-               return rettags(etags, YAFFS_ECC_RESULT_NO_ERROR, YAFFS_OK);
-       }
-
-       if(dev->param.tags_9bytes) {
-               deleted = (hweight8(((u8 *) &pt1)[8]) < 7);
-        } else {
-               /* Read deleted status (bit) then return it to it's non-deleted
-                * state before performing tags mini-ECC check. pt1.deleted is
-                * inverted.
-                */
-               deleted = !pt1.deleted;
-               pt1.deleted = 1;
-        }
-
-       /* Check the packed tags mini-ECC and correct if necessary/possible.
-        */
-       retval = yaffs_check_tags_ecc((struct yaffs_tags *)&pt1);
-       switch (retval) {
-       case 0:
-               /* no tags error, use MTD result */
-               break;
-       case 1:
-               /* recovered tags-ECC error */
-               dev->n_tags_ecc_fixed++;
-               if (eccres == YAFFS_ECC_RESULT_NO_ERROR)
-                       eccres = YAFFS_ECC_RESULT_FIXED;
-               break;
-       default:
-               /* unrecovered tags-ECC error */
-               dev->n_tags_ecc_unfixed++;
-               return rettags(etags, YAFFS_ECC_RESULT_UNFIXED, YAFFS_FAIL);
-       }
-
-       /* Unpack the tags to extended form and set ECC result.
-        * [set should_be_ff just to keep yaffs_unpack_tags1 happy]
-        */
-       pt1.should_be_ff = 0xffffffff;
-       yaffs_unpack_tags1(etags, &pt1);
-       etags->ecc_result = eccres;
-
-       /* Set deleted state */
-       etags->is_deleted = deleted;
-       return YAFFS_OK;
-}
-
-/* Mark a block bad.
- *
- * This is a persistant state.
- * Use of this function should be rare.
- *
- * Returns YAFFS_OK or YAFFS_FAIL.
- */
-int nandmtd1_mark_block_bad(struct yaffs_dev *dev, int block_no)
-{
-       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-       int blocksize = dev->param.chunks_per_block * dev->data_bytes_per_chunk;
-       int retval;
-
-       yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, "marking block %d bad", block_no);
-
-       retval = mtd->block_markbad(mtd, (loff_t) blocksize * block_no);
-       return (retval) ? YAFFS_FAIL : YAFFS_OK;
-}
-
-/* Check any MTD prerequists.
- *
- * Returns YAFFS_OK or YAFFS_FAIL.
- */
-static int nandmtd1_test_prerequists(struct yaffs_dev *dev, struct mtd_info *mtd)
-{
-       /* 2.6.18 has mtd->ecclayout->oobavail */
-       /* 2.6.21 has mtd->ecclayout->oobavail and mtd->oobavail */
-       int oobavail = mtd->ecclayout->oobavail;
-
-       if (oobavail < (dev->param.tags_9bytes ? 9 : 8)) {
-               yaffs_trace(YAFFS_TRACE_ERROR,
-                       "mtd device has only %d bytes for tags, need %d",
-                       oobavail, dev->param.tags_9bytes ? 9 : 8);
-               return YAFFS_FAIL;
-       }
-       return YAFFS_OK;
-}
-
-/* Query for the current state of a specific block.
- *
- * Examine the tags of the first chunk of the block and return the state:
- *  - YAFFS_BLOCK_STATE_DEAD, the block is marked bad
- *  - YAFFS_BLOCK_STATE_NEEDS_SCAN, the block is in use
- *  - YAFFS_BLOCK_STATE_EMPTY, the block is clean
- *
- * Always returns YAFFS_OK.
- */
-int nandmtd1_query_block(struct yaffs_dev *dev, int block_no,
-                        enum yaffs_block_state *state_ptr, u32 * seq_ptr)
-{
-       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-       int chunk_num = block_no * dev->param.chunks_per_block;
-       loff_t addr = (loff_t) chunk_num * dev->data_bytes_per_chunk;
-       struct yaffs_ext_tags etags;
-       int state = YAFFS_BLOCK_STATE_DEAD;
-       int seqnum = 0;
-       int retval;
-
-       /* We don't yet have a good place to test for MTD config prerequists.
-        * Do it here as we are called during the initial scan.
-        */
-       if (nandmtd1_test_prerequists(dev, mtd) != YAFFS_OK)
-               return YAFFS_FAIL;
-
-       retval = nandmtd1_read_chunk_tags(dev, chunk_num, NULL, &etags);
-       etags.block_bad = (mtd->block_isbad) (mtd, addr);
-       if (etags.block_bad) {
-               yaffs_trace(YAFFS_TRACE_BAD_BLOCKS,
-                       "block %d is marked bad",
-                       block_no);
-               state = YAFFS_BLOCK_STATE_DEAD;
-       } else if (etags.ecc_result != YAFFS_ECC_RESULT_NO_ERROR) {
-               /* bad tags, need to look more closely */
-               state = YAFFS_BLOCK_STATE_NEEDS_SCAN;
-       } else if (etags.chunk_used) {
-               state = YAFFS_BLOCK_STATE_NEEDS_SCAN;
-               seqnum = etags.seq_number;
-       } else {
-               state = YAFFS_BLOCK_STATE_EMPTY;
-       }
-
-       *state_ptr = state;
-       *seq_ptr = seqnum;
-
-       /* query always succeeds */
-       return YAFFS_OK;
-}
-
-#endif /*MTD_VERSION */
diff --git a/yaffs_mtdif1_single.c b/yaffs_mtdif1_single.c
deleted file mode 100644 (file)
index dbc9122..0000000
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * YAFFS: Yet another FFS. A NAND-flash specific file system.
- *
- * Copyright (C) 2002-2011 Aleph One Ltd.
- *   for Toby Churchill Ltd and Brightstar Engineering
- *
- * 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 module provides the interface between yaffs_nand.c and the
- * MTD API.  This version is used when the MTD interface supports the
- * 'mtd_oob_ops' style calls to read_oob and write_oob, circa 2.6.17,
- * and we have small-page NAND device.
- *
- * These functions are invoked via function pointers in yaffs_nand.c.
- * This replaces functionality provided by functions in yaffs_mtdif.c
- * and the yaffs_tags compatability functions in yaffs_tagscompat.c that are
- * called in yaffs_mtdif.c when the function pointers are NULL.
- * We assume the MTD layer is performing ECC (use_nand_ecc is true).
- */
-
-#include "yportenv.h"
-#include "yaffs_trace.h"
-#include "yaffs_guts.h"
-#include "yaffs_packedtags1.h"
-#include "yaffs_tagscompat.h"  /* for yaffs_calc_tags_ecc */
-#include "yaffs_linux.h"
-#include "linux/kernel.h"
-#include "linux/version.h"
-#include "linux/types.h"
-#include "linux/mtd/mtd.h"
-
-/* Write a chunk (page) of data to NAND.
- *
- * Caller always provides ExtendedTags data which are converted to a more
- * compact (packed) form for storage in NAND.  A mini-ECC runs over the
- * contents of the tags meta-data; used to valid the tags when read.
- *
- *  - Pack ExtendedTags to packed_tags1 form
- *  - Compute mini-ECC for packed_tags1
- *  - Write data and packed tags to NAND.
- *
- * Note: Due to the use of the packed_tags1 meta-data which does not include
- * a full sequence number (as found in the larger packed_tags2 form) it is
- * necessary for Yaffs to re-write a chunk/page (just once) to mark it as
- * discarded and dirty.  This is not ideal: newer NAND parts are supposed
- * to be written just once.  When Yaffs performs this operation, this
- * function is called with a NULL data pointer -- calling MTD write_oob
- * without data is valid usage (2.6.17).
- *
- * Any underlying MTD error results in YAFFS_FAIL.
- * Returns YAFFS_OK or YAFFS_FAIL.
- */
-int nandmtd1_write_chunk_tags(struct yaffs_dev *dev,
-                             int nand_chunk, const u8 *data,
-                             const struct yaffs_ext_tags *etags)
-{
-       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-       int chunk_bytes = dev->data_bytes_per_chunk;
-       loff_t addr = ((loff_t) nand_chunk) * chunk_bytes;
-       struct mtd_oob_ops ops;
-       struct yaffs_packed_tags1 pt1;
-       int retval;
-
-       /* we assume that packed_tags1 and struct yaffs_tags are compatible */
-       compile_time_assertion(sizeof(struct yaffs_packed_tags1) == 12);
-       compile_time_assertion(sizeof(struct yaffs_tags) == 8);
-
-       yaffs_pack_tags1(&pt1, etags);
-       yaffs_calc_tags_ecc((struct yaffs_tags *)&pt1);
-
-       /* When deleting a chunk, the upper layer provides only skeletal
-        * etags, one with is_deleted set.  However, we need to update the
-        * tags, not erase them completely.  So we use the NAND write property
-        * that only zeroed-bits stick and set tag bytes to all-ones and
-        * zero just the (not) deleted bit.
-        */
-
-       if (dev->param.tags_9bytes) {
-               ((u8 *) &pt1)[8] = 0xff;
-               if (etags->is_deleted) {
-                       memset(&pt1, 0xff, 8);
-                       /* zero page_status byte to indicate deleted */
-                       ((u8 *) &pt1)[8] = 0;
-               }
-       } else {
-               if (etags->is_deleted) {
-                       memset(&pt1, 0xff, 8);
-                       /* clear delete status bit to indicate deleted */
-                       pt1.deleted = 0;
-               }
-       }
-
-       memset(&ops, 0, sizeof(ops));
-       ops.mode = MTD_OPS_AUTO_OOB;
-       ops.len = (data) ? chunk_bytes : 0;
-       ops.ooblen = dev->param.tags_9bytes ? 9 : 8;
-       ops.datbuf = (u8 *) data;
-       ops.oobbuf = (u8 *) &pt1;
-
-       retval = mtd->write_oob(mtd, addr, &ops);
-       if (retval) {
-               yaffs_trace(YAFFS_TRACE_MTD,
-                       "write_oob failed, chunk %d, mtd error %d",
-                       nand_chunk, retval);
-       }
-       return retval ? YAFFS_FAIL : YAFFS_OK;
-}
-
-/* Return with empty ExtendedTags but add ecc_result.
- */
-static int rettags(struct yaffs_ext_tags *etags, int ecc_result, int retval)
-{
-       if (etags) {
-               memset(etags, 0, sizeof(*etags));
-               etags->ecc_result = ecc_result;
-       }
-       return retval;
-}
-
-/* Read a chunk (page) from NAND.
- *
- * Caller expects ExtendedTags data to be usable even on error; that is,
- * all members except ecc_result and block_bad are zeroed.
- *
- *  - Check ECC results for data (if applicable)
- *  - Check for blank/erased block (return empty ExtendedTags if blank)
- *  - Check the packed_tags1 mini-ECC (correct if necessary/possible)
- *  - Convert packed_tags1 to ExtendedTags
- *  - Update ecc_result and block_bad members to refect state.
- *
- * Returns YAFFS_OK or YAFFS_FAIL.
- */
-int nandmtd1_read_chunk_tags(struct yaffs_dev *dev,
-                            int nand_chunk, u8 *data,
-                            struct yaffs_ext_tags *etags)
-{
-       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-       int chunk_bytes = dev->data_bytes_per_chunk;
-       loff_t addr = ((loff_t) nand_chunk) * chunk_bytes;
-       int eccres = YAFFS_ECC_RESULT_NO_ERROR;
-       struct mtd_oob_ops ops;
-       struct yaffs_packed_tags1 pt1;
-       int retval;
-       int deleted;
-
-       memset(&ops, 0, sizeof(ops));
-       ops.mode = MTD_OPS_AUTO_OOB;
-       ops.len = (data) ? chunk_bytes : 0;
-       ops.ooblen =  dev->param.tags_9bytes ? 9 : 8;
-       ops.datbuf = data;
-       ops.oobbuf = (u8 *) &pt1;
-
-       /* Read page and oob using MTD.
-        * Check status and determine ECC result.
-        */
-       retval = mtd->read_oob(mtd, addr, &ops);
-       if (retval) {
-               yaffs_trace(YAFFS_TRACE_MTD,
-                       "read_oob failed, chunk %d, mtd error %d",
-                       nand_chunk, retval);
-       }
-
-       switch (retval) {
-       case 0:
-               /* no error */
-               break;
-
-       case -EUCLEAN:
-               /* MTD's ECC fixed the data */
-               eccres = YAFFS_ECC_RESULT_FIXED;
-               dev->n_ecc_fixed++;
-               break;
-
-       case -EBADMSG:
-               /* MTD's ECC could not fix the data */
-               dev->n_ecc_unfixed++;
-               /* fall into... */
-       default:
-               rettags(etags, YAFFS_ECC_RESULT_UNFIXED, 0);
-               etags->block_bad = (mtd->block_isbad) (mtd, addr);
-               return YAFFS_FAIL;
-       }
-
-       /* Check for a blank/erased chunk.
-        */
-       if (yaffs_check_ff((u8 *) &pt1, 8)) {
-               /* when blank, upper layers want ecc_result to be <= NO_ERROR */
-               return rettags(etags, YAFFS_ECC_RESULT_NO_ERROR, YAFFS_OK);
-       }
-#ifndef CONFIG_YAFFS_9BYTE_TAGS
-       /* Read deleted status (bit) then return it to it's non-deleted
-        * state before performing tags mini-ECC check. pt1.deleted is
-        * inverted.
-        */
-       deleted = !pt1.deleted;
-       pt1.deleted = 1;
-#else
-       deleted = (hweight8(((u8 *) &pt1)[8]) < 7);
-#endif
-
-       /* Check the packed tags mini-ECC and correct if necessary/possible.
-        */
-       retval = yaffs_check_tags_ecc((struct yaffs_tags *)&pt1);
-       switch (retval) {
-       case 0:
-               /* no tags error, use MTD result */
-               break;
-       case 1:
-               /* recovered tags-ECC error */
-               dev->n_tags_ecc_fixed++;
-               if (eccres == YAFFS_ECC_RESULT_NO_ERROR)
-                       eccres = YAFFS_ECC_RESULT_FIXED;
-               break;
-       default:
-               /* unrecovered tags-ECC error */
-               dev->n_tags_ecc_unfixed++;
-               return rettags(etags, YAFFS_ECC_RESULT_UNFIXED, YAFFS_FAIL);
-       }
-
-       /* Unpack the tags to extended form and set ECC result.
-        * [set should_be_ff just to keep yaffs_unpack_tags1 happy]
-        */
-       pt1.should_be_ff = 0xffffffff;
-       yaffs_unpack_tags1(etags, &pt1);
-       etags->ecc_result = eccres;
-
-       /* Set deleted state */
-       etags->is_deleted = deleted;
-       return YAFFS_OK;
-}
-
-/* Mark a block bad.
- *
- * This is a persistant state.
- * Use of this function should be rare.
- *
- * Returns YAFFS_OK or YAFFS_FAIL.
- */
-int nandmtd1_mark_block_bad(struct yaffs_dev *dev, int block_no)
-{
-       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-       int blocksize = dev->param.chunks_per_block * dev->data_bytes_per_chunk;
-       int retval;
-
-       yaffs_trace(YAFFS_TRACE_BAD_BLOCKS,
-               "marking block %d bad", block_no);
-
-       retval = mtd->block_markbad(mtd, (loff_t) blocksize * block_no);
-       return (retval) ? YAFFS_FAIL : YAFFS_OK;
-}
-
-/* Check any MTD prerequists.
- *
- * Returns YAFFS_OK or YAFFS_FAIL.
- */
-static int nandmtd1_test_prerequists(struct yaffs_dev *dev,
-                                       struct mtd_info *mtd)
-{
-       /* 2.6.18 has mtd->ecclayout->oobavail */
-       /* 2.6.21 has mtd->ecclayout->oobavail and mtd->oobavail */
-       int oobavail = mtd->ecclayout->oobavail;
-
-       if (oobavail < (dev->param.tags_9bytes ? 9 : 8)) {
-               yaffs_trace(YAFFS_TRACE_ERROR,
-                       "mtd device has only %d bytes for tags, need %d",
-                       oobavail, (dev->param.tags_9bytes ? 9 : 8));
-               return YAFFS_FAIL;
-       }
-       return YAFFS_OK;
-}
-
-/* Query for the current state of a specific block.
- *
- * Examine the tags of the first chunk of the block and return the state:
- *  - YAFFS_BLOCK_STATE_DEAD, the block is marked bad
- *  - YAFFS_BLOCK_STATE_NEEDS_SCAN, the block is in use
- *  - YAFFS_BLOCK_STATE_EMPTY, the block is clean
- *
- * Always returns YAFFS_OK.
- */
-int nandmtd1_query_block(struct yaffs_dev *dev, int block_no,
-                        enum yaffs_block_state *state_ptr, u32 * seq_ptr)
-{
-       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-       int chunk_num = block_no * dev->param.chunks_per_block;
-       loff_t addr = (loff_t) chunk_num * dev->data_bytes_per_chunk;
-       struct yaffs_ext_tags etags;
-       int state = YAFFS_BLOCK_STATE_DEAD;
-       int seqnum = 0;
-       int retval;
-
-       /* We don't yet have a good place to test for MTD config prerequists.
-        * Do it here as we are called during the initial scan.
-        */
-       if (nandmtd1_test_prerequists(dev, mtd) != YAFFS_OK)
-               return YAFFS_FAIL;
-
-       retval = nandmtd1_read_chunk_tags(dev, chunk_num, NULL, &etags);
-       etags.block_bad = (mtd->block_isbad) (mtd, addr);
-       if (etags.block_bad) {
-               yaffs_trace(YAFFS_TRACE_BAD_BLOCKS,
-                       "block %d is marked bad", block_no);
-               state = YAFFS_BLOCK_STATE_DEAD;
-       } else if (etags.ecc_result != YAFFS_ECC_RESULT_NO_ERROR) {
-               /* bad tags, need to look more closely */
-               state = YAFFS_BLOCK_STATE_NEEDS_SCAN;
-       } else if (etags.chunk_used) {
-               state = YAFFS_BLOCK_STATE_NEEDS_SCAN;
-               seqnum = etags.seq_number;
-       } else {
-               state = YAFFS_BLOCK_STATE_EMPTY;
-       }
-
-       *state_ptr = state;
-       *seq_ptr = seqnum;
-
-       /* query always succeeds */
-       return YAFFS_OK;
-}
diff --git a/yaffs_mtdif2.h b/yaffs_mtdif2.h
deleted file mode 100644 (file)
index d4d1858..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
- *
- * Copyright (C) 2002-2011 Aleph One Ltd.
- *   for Toby Churchill Ltd and Brightstar Engineering
- *
- * 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 Lesser General Public License version 2.1 as
- * published by the Free Software Foundation.
- *
- * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
- */
-
-#ifndef __YAFFS_MTDIF2_H__
-#define __YAFFS_MTDIF2_H__
-
-#include "yaffs_guts.h"
-int nandmtd2_write_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
-                             const u8 *data,
-                             const struct yaffs_ext_tags *tags);
-int nandmtd2_read_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
-                            u8 *data, struct yaffs_ext_tags *tags);
-int nandmtd2_mark_block_bad(struct yaffs_dev *dev, int block_no);
-int nandmtd2_query_block(struct yaffs_dev *dev, int block_no,
-                        enum yaffs_block_state *state, u32 *seq_number);
-
-#endif
diff --git a/yaffs_mtdif2_multi.c b/yaffs_mtdif2_multi.c
deleted file mode 100644 (file)
index 18ac992..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
- *
- * Copyright (C) 2002-2011 Aleph One Ltd.
- *   for Toby Churchill Ltd and Brightstar Engineering
- *
- * 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.
- */
-
-/* mtd interface for YAFFS2 */
-
-#include "yportenv.h"
-#include "yaffs_trace.h"
-
-#include "yaffs_mtdif2.h"
-
-#include "linux/mtd/mtd.h"
-#include "linux/types.h"
-#include "linux/time.h"
-
-#include "yaffs_packedtags2.h"
-
-#include "yaffs_linux.h"
-
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
-#define MTD_OPS_AUTO_OOB MTD_OOB_AUTO
-#endif
-
-
-
-/* NB For use with inband tags....
- * We assume that the data buffer is of size total_bytes_per_chunk so
- * that we can also use it to load the tags.
- */
-int nandmtd2_write_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
-                             const u8 *data,
-                             const struct yaffs_ext_tags *tags)
-{
-       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
-       struct mtd_oob_ops ops;
-#else
-       size_t dummy;
-#endif
-       int retval = 0;
-
-       loff_t addr;
-
-       struct yaffs_packed_tags2 pt;
-
-       int packed_tags_size =
-           dev->param.no_tags_ecc ? sizeof(pt.t) : sizeof(pt);
-       void *packed_tags_ptr =
-           dev->param.no_tags_ecc ? (void *)&pt.t : (void *)&pt;
-
-       yaffs_trace(YAFFS_TRACE_MTD,
-               "nandmtd2_write_chunk_tags chunk %d data %p tags %p",
-               nand_chunk, data, tags);
-
-       addr = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk;
-
-       /* For yaffs2 writing there must be both data and tags.
-        * If we're using inband tags, then the tags are stuffed into
-        * the end of the data buffer.
-        */
-       if (!data || !tags)
-               BUG();
-       else if (dev->param.inband_tags) {
-               struct yaffs_packed_tags2_tags_only *pt2tp;
-               pt2tp =
-                   (struct yaffs_packed_tags2_tags_only *)(data +
-                                                       dev->
-                                                       data_bytes_per_chunk);
-               yaffs_pack_tags2_tags_only(pt2tp, tags);
-       } else {
-               yaffs_pack_tags2(&pt, tags, !dev->param.no_tags_ecc);
-       }
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-       ops.mode = MTD_OPS_AUTO_OOB;
-       ops.ooblen = (dev->param.inband_tags) ? 0 : packed_tags_size;
-       ops.len = dev->param.total_bytes_per_chunk;
-       ops.ooboffs = 0;
-       ops.datbuf = (u8 *) data;
-       ops.oobbuf = (dev->param.inband_tags) ? NULL : packed_tags_ptr;
-       retval = mtd->write_oob(mtd, addr, &ops);
-
-#else
-       if (!dev->param.inband_tags) {
-               retval =
-                   mtd->write_ecc(mtd, addr, dev->data_bytes_per_chunk,
-                                  &dummy, data, (u8 *) packed_tags_ptr, NULL);
-       } else {
-               retval =
-                   mtd->write(mtd, addr, dev->param.total_bytes_per_chunk,
-                              &dummy, data);
-       }
-#endif
-
-       if (retval == 0)
-               return YAFFS_OK;
-       else
-               return YAFFS_FAIL;
-}
-
-int nandmtd2_read_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
-                            u8 *data, struct yaffs_ext_tags *tags)
-{
-       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
-       struct mtd_oob_ops ops;
-#endif
-       size_t dummy;
-       int retval = 0;
-       int local_data = 0;
-
-       loff_t addr = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk;
-
-       struct yaffs_packed_tags2 pt;
-
-       int packed_tags_size =
-           dev->param.no_tags_ecc ? sizeof(pt.t) : sizeof(pt);
-       void *packed_tags_ptr =
-           dev->param.no_tags_ecc ? (void *)&pt.t : (void *)&pt;
-
-       yaffs_trace(YAFFS_TRACE_MTD,
-               "nandmtd2_read_chunk_tags chunk %d data %p tags %p",
-               nand_chunk, data, tags);
-
-       if (dev->param.inband_tags) {
-
-               if (!data) {
-                       local_data = 1;
-                       data = yaffs_get_temp_buffer(dev);
-               }
-
-       }
-
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-       if (dev->param.inband_tags || (data && !tags))
-               retval = mtd->read(mtd, addr, dev->param.total_bytes_per_chunk,
-                                  &dummy, data);
-       else if (tags) {
-               ops.mode = MTD_OPS_AUTO_OOB;
-               ops.ooblen = packed_tags_size;
-               ops.len = data ? dev->data_bytes_per_chunk : packed_tags_size;
-               ops.ooboffs = 0;
-               ops.datbuf = data;
-               ops.oobbuf = yaffs_dev_to_lc(dev)->spare_buffer;
-               retval = mtd->read_oob(mtd, addr, &ops);
-       }
-#else
-       if (!dev->param.inband_tags && data && tags) {
-
-               retval = mtd->read_ecc(mtd, addr, dev->data_bytes_per_chunk,
-                                      &dummy, data, dev->spare_buffer, NULL);
-       } else {
-               if (data)
-                       retval =
-                           mtd->read(mtd, addr, dev->data_bytes_per_chunk,
-                                     &dummy, data);
-               if (!dev->param.inband_tags && tags)
-                       retval =
-                           mtd->read_oob(mtd, addr, mtd->oobsize, &dummy,
-                                         dev->spare_buffer);
-       }
-#endif
-
-       if (dev->param.inband_tags) {
-               if (tags) {
-                       struct yaffs_packed_tags2_tags_only *pt2tp;
-                       pt2tp =
-                               (struct yaffs_packed_tags2_tags_only *)
-                               &data[dev->data_bytes_per_chunk];
-                       yaffs_unpack_tags2_tags_only(tags, pt2tp);
-               }
-       } else {
-               if (tags) {
-                       memcpy(packed_tags_ptr,
-                              yaffs_dev_to_lc(dev)->spare_buffer,
-                              packed_tags_size);
-                       yaffs_unpack_tags2(tags, &pt, !dev->param.no_tags_ecc);
-               }
-       }
-
-       if (local_data)
-               yaffs_release_temp_buffer(dev, data);
-
-       if (tags && retval == -EBADMSG
-           && tags->ecc_result == YAFFS_ECC_RESULT_NO_ERROR) {
-               tags->ecc_result = YAFFS_ECC_RESULT_UNFIXED;
-               dev->n_ecc_unfixed++;
-       }
-       if (tags && retval == -EUCLEAN
-           && tags->ecc_result == YAFFS_ECC_RESULT_NO_ERROR) {
-               tags->ecc_result = YAFFS_ECC_RESULT_FIXED;
-               dev->n_ecc_fixed++;
-       }
-       if (retval == 0)
-               return YAFFS_OK;
-       else
-               return YAFFS_FAIL;
-}
-
-int nandmtd2_mark_block_bad(struct yaffs_dev *dev, int block_no)
-{
-       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-       int retval;
-       yaffs_trace(YAFFS_TRACE_MTD,
-               "nandmtd2_mark_block_bad %d",
-               block_no);
-
-       retval =
-           mtd->block_markbad(mtd,
-                              block_no * dev->param.chunks_per_block *
-                              dev->param.total_bytes_per_chunk);
-
-       if (retval == 0)
-               return YAFFS_OK;
-       else
-               return YAFFS_FAIL;
-
-}
-
-int nandmtd2_query_block(struct yaffs_dev *dev, int block_no,
-                        enum yaffs_block_state *state, u32 *seq_number)
-{
-       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-       int retval;
-
-       yaffs_trace(YAFFS_TRACE_MTD, "nandmtd2_query_block %d", block_no);
-       retval =
-           mtd->block_isbad(mtd,
-                            block_no * dev->param.chunks_per_block *
-                            dev->param.total_bytes_per_chunk);
-
-       if (retval) {
-               yaffs_trace(YAFFS_TRACE_MTD, "block is bad");
-
-               *state = YAFFS_BLOCK_STATE_DEAD;
-               *seq_number = 0;
-       } else {
-               struct yaffs_ext_tags t;
-               nandmtd2_read_chunk_tags(dev, block_no *
-                                        dev->param.chunks_per_block, NULL, &t);
-
-               if (t.chunk_used) {
-                       *seq_number = t.seq_number;
-                       *state = YAFFS_BLOCK_STATE_NEEDS_SCAN;
-               } else {
-                       *seq_number = 0;
-                       *state = YAFFS_BLOCK_STATE_EMPTY;
-               }
-       }
-       yaffs_trace(YAFFS_TRACE_MTD,
-               "block is bad seq %d state %d",
-               *seq_number, *state);
-
-       if (retval == 0)
-               return YAFFS_OK;
-       else
-               return YAFFS_FAIL;
-}
-
diff --git a/yaffs_mtdif2_single.c b/yaffs_mtdif2_single.c
deleted file mode 100644 (file)
index f92c49f..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
- *
- * Copyright (C) 2002-2011 Aleph One Ltd.
- *   for Toby Churchill Ltd and Brightstar Engineering
- *
- * 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.
- */
-
-/* mtd interface for YAFFS2 */
-
-#include "yportenv.h"
-#include "yaffs_trace.h"
-#include "yaffs_mtdif2.h"
-#include "yaffs_packedtags2.h"
-#include "yaffs_linux.h"
-#include "linux/mtd/mtd.h"
-#include "linux/types.h"
-#include "linux/time.h"
-#include "mtd/mtd-abi.h"
-
-
-/* NB For use with inband tags....
- * We assume that the data buffer is of size total_bytes_per_chunk so that
- * we can also use it to load the tags.
- */
-int nandmtd2_write_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
-                             const u8 *data,
-                             const struct yaffs_ext_tags *tags)
-{
-       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-       struct mtd_oob_ops ops;
-       int retval = 0;
-       loff_t addr;
-       struct yaffs_packed_tags2 pt;
-       int packed_tags_size =
-           dev->param.no_tags_ecc ? sizeof(pt.t) : sizeof(pt);
-       void *packed_tags_ptr =
-           dev->param.no_tags_ecc ? (void *)&pt.t : (void *)&pt;
-
-       yaffs_trace(YAFFS_TRACE_MTD,
-               "nandmtd2_write_chunk_tags chunk %d data %p tags %p",
-               nand_chunk, data, tags);
-
-       addr = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk;
-
-       /* For yaffs2 writing there must be both data and tags.
-        * If we're using inband tags, then the tags are stuffed into
-        * the end of the data buffer.
-        */
-       if (!data || !tags)
-               BUG();
-       else if (dev->param.inband_tags) {
-               struct yaffs_packed_tags2_tags_only *pt2tp;
-
-               pt2tp =
-                   (struct yaffs_packed_tags2_tags_only *)
-                       (data + dev->data_bytes_per_chunk);
-               yaffs_pack_tags2_tags_only(pt2tp, tags);
-       } else {
-               yaffs_pack_tags2(&pt, tags, !dev->param.no_tags_ecc);
-       }
-
-       ops.mode = MTD_OPS_AUTO_OOB;
-       ops.ooblen = (dev->param.inband_tags) ? 0 : packed_tags_size;
-       ops.len = dev->param.total_bytes_per_chunk;
-       ops.ooboffs = 0;
-       ops.datbuf = (u8 *) data;
-       ops.oobbuf = (dev->param.inband_tags) ? NULL : packed_tags_ptr;
-       retval = mtd->write_oob(mtd, addr, &ops);
-
-       if (retval == 0)
-               return YAFFS_OK;
-
-       return YAFFS_FAIL;
-}
-
-int nandmtd2_read_chunk_tags(struct yaffs_dev *dev, int nand_chunk,
-                            u8 *data, struct yaffs_ext_tags *tags)
-{
-       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-       struct mtd_oob_ops ops;
-       size_t dummy;
-       int retval = 0;
-       int local_data = 0;
-       loff_t addr = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk;
-       struct yaffs_packed_tags2 pt;
-       int packed_tags_size =
-           dev->param.no_tags_ecc ? sizeof(pt.t) : sizeof(pt);
-       void *packed_tags_ptr =
-           dev->param.no_tags_ecc ? (void *)&pt.t : (void *)&pt;
-
-       yaffs_trace(YAFFS_TRACE_MTD,
-               "nandmtd2_read_chunk_tags chunk %d data %p tags %p",
-               nand_chunk, data, tags);
-
-       if (dev->param.inband_tags && !data) {
-               local_data = 1;
-               data = yaffs_get_temp_buffer(dev);
-       }
-
-       if (dev->param.inband_tags || (data && !tags)) {
-               retval = mtd->read(mtd, addr, dev->param.total_bytes_per_chunk,
-                                  &dummy, data);
-       } else if (tags) {
-               ops.mode = MTD_OPS_AUTO_OOB;
-               ops.ooblen = packed_tags_size;
-               ops.len = data ? dev->data_bytes_per_chunk : packed_tags_size;
-               ops.ooboffs = 0;
-               ops.datbuf = data;
-               ops.oobbuf = yaffs_dev_to_lc(dev)->spare_buffer;
-               retval = mtd->read_oob(mtd, addr, &ops);
-       }
-
-       if (dev->param.inband_tags && tags) {
-               struct yaffs_packed_tags2_tags_only *pt2tp;
-
-               pt2tp =
-                       (struct yaffs_packed_tags2_tags_only *)
-                               &data[dev->data_bytes_per_chunk];
-               yaffs_unpack_tags2_tags_only(tags, pt2tp);
-       } else if (tags) {
-               memcpy(packed_tags_ptr,
-                      yaffs_dev_to_lc(dev)->spare_buffer,
-                      packed_tags_size);
-               yaffs_unpack_tags2(tags, &pt, !dev->param.no_tags_ecc);
-       }
-
-       if (local_data)
-               yaffs_release_temp_buffer(dev, data);
-
-       if (tags && retval == -EBADMSG &&
-           tags->ecc_result == YAFFS_ECC_RESULT_NO_ERROR) {
-               tags->ecc_result = YAFFS_ECC_RESULT_UNFIXED;
-               dev->n_ecc_unfixed++;
-       }
-       if (tags && retval == -EUCLEAN &&
-           tags->ecc_result == YAFFS_ECC_RESULT_NO_ERROR) {
-               tags->ecc_result = YAFFS_ECC_RESULT_FIXED;
-               dev->n_ecc_fixed++;
-       }
-
-       if (retval == 0)
-               return YAFFS_OK;
-
-       return YAFFS_FAIL;
-}
-
-int nandmtd2_mark_block_bad(struct yaffs_dev *dev, int block_no)
-{
-       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-       int retval;
-
-       yaffs_trace(YAFFS_TRACE_MTD,
-               "nandmtd2_mark_block_bad %d", block_no);
-
-       retval =
-           mtd->block_markbad(mtd,
-                              block_no * dev->param.chunks_per_block *
-                              dev->param.total_bytes_per_chunk);
-
-       if (retval == 0)
-               return YAFFS_OK;
-
-       return YAFFS_FAIL;
-}
-
-int nandmtd2_query_block(struct yaffs_dev *dev, int block_no,
-                        enum yaffs_block_state *state, u32 * seq_number)
-{
-       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-       int retval;
-
-       yaffs_trace(YAFFS_TRACE_MTD, "nandmtd2_query_block %d", block_no);
-       retval =
-           mtd->block_isbad(mtd,
-                            block_no * dev->param.chunks_per_block *
-                            dev->param.total_bytes_per_chunk);
-
-       if (retval) {
-               yaffs_trace(YAFFS_TRACE_MTD, "block is bad");
-
-               *state = YAFFS_BLOCK_STATE_DEAD;
-               *seq_number = 0;
-       } else {
-               struct yaffs_ext_tags t;
-
-               nandmtd2_read_chunk_tags(dev, block_no *
-                                        dev->param.chunks_per_block, NULL, &t);
-
-               if (t.chunk_used) {
-                       *seq_number = t.seq_number;
-                       *state = YAFFS_BLOCK_STATE_NEEDS_SCAN;
-               } else {
-                       *seq_number = 0;
-                       *state = YAFFS_BLOCK_STATE_EMPTY;
-               }
-       }
-       yaffs_trace(YAFFS_TRACE_MTD,
-               "block is bad seq %d state %d", *seq_number, *state);
-
-       if (retval == 0)
-               return YAFFS_OK;
-
-       return YAFFS_FAIL;
-}
diff --git a/yaffs_mtdif_multi.c b/yaffs_mtdif_multi.c
new file mode 100644 (file)
index 0000000..e61699d
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
+ *
+ * Copyright (C) 2002-2011 Aleph One Ltd.
+ *   for Toby Churchill Ltd and Brightstar Engineering
+ *
+ * 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.
+ */
+
+#include "yportenv.h"
+
+#include "yaffs_mtdif.h"
+
+#include "linux/mtd/mtd.h"
+#include "linux/types.h"
+#include "linux/time.h"
+#include "linux/mtd/nand.h"
+#include "linux/kernel.h"
+#include "linux/version.h"
+#include "linux/types.h"
+
+#include "yaffs_trace.h"
+#include "yaffs_guts.h"
+#include "yaffs_linux.h"
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
+#define MTD_OPS_AUTO_OOB MTD_OOB_AUTO
+#endif
+
+
+int nandmtd_erase_block(struct yaffs_dev *dev, int block_no)
+{
+       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
+       u32 addr =
+           ((loff_t) block_no) * dev->param.total_bytes_per_chunk *
+           dev->param.chunks_per_block;
+       struct erase_info ei;
+       int retval = 0;
+
+       ei.mtd = mtd;
+       ei.addr = addr;
+       ei.len = dev->param.total_bytes_per_chunk * dev->param.chunks_per_block;
+       ei.time = 1000;
+       ei.retries = 2;
+       ei.callback = NULL;
+       ei.priv = (u_long) dev;
+
+       retval = mtd->erase(mtd, &ei);
+
+       if (retval == 0)
+               return YAFFS_OK;
+
+       return YAFFS_FAIL;
+}
+
+
+static         int yaffs_mtd_write(struct yaffs_dev *dev, int nand_chunk,
+                                  const u8 *data, int data_len,
+                                  const u8 *oob, int oob_len)
+{
+       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
+       loff_t addr;
+       struct mtd_oob_ops ops;
+       int retval;
+
+       addr = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk;
+       memset(&ops, 0, sizeof(ops));
+       ops.mode = MTD_OPS_AUTO_OOB;
+       ops.len = (data) ? data_len : 0;
+       ops.ooblen = oob_len;
+       ops.datbuf = (u8 *)data;
+       ops.oobbuf = (u8 *)oob;
+
+       retval = mtd->write_oob(mtd, addr, &ops);
+       if (retval) {
+               yaffs_trace(YAFFS_TRACE_MTD,
+                       "write_oob failed, chunk %d, mtd error %d",
+                       nand_chunk, retval);
+       }
+       return retval ? YAFFS_FAIL : YAFFS_OK;
+}
+
+static int yaffs_mtd_read(struct yaffs_dev *dev, int nand_chunk,
+                                  u8 *data, int data_len,
+                                  u8 *oob, int oob_len,
+                                  enum yaffs_ecc_result *ecc_result)
+{
+       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
+       loff_t addr;
+       struct mtd_oob_ops ops;
+       int retval;
+
+       addr = ((loff_t) nand_chunk) * dev->data_bytes_per_chunk;
+       memset(&ops, 0, sizeof(ops));
+       ops.mode = MTD_OPS_AUTO_OOB;
+       ops.len = (data) ? data_len : 0;
+       ops.ooblen = oob_len;
+       ops.datbuf = data;
+       ops.oobbuf = oob;
+
+#if (MTD_VERSION_CODE < MTD_VERSION(2, 6, 20))
+       /* In MTD 2.6.18 to 2.6.19 nand_base.c:nand_do_read_oob() has a bug;
+        * help it out with ops.len = ops.ooblen when ops.datbuf == NULL.
+        */
+       ops.len = (ops.datbuf) ? ops.len : ops.ooblen;
+#endif
+       /* Read page and oob using MTD.
+        * Check status and determine ECC result.
+        */
+       retval = mtd->read_oob(mtd, addr, &ops);
+       if (retval)
+               yaffs_trace(YAFFS_TRACE_MTD,
+                       "read_oob failed, chunk %d, mtd error %d",
+                       nand_chunk, retval);
+
+       switch (retval) {
+       case 0:
+               /* no error */
+               if(ecc_result)
+                       *ecc_result = YAFFS_ECC_RESULT_NO_ERROR;
+               break;
+
+       case -EUCLEAN:
+               /* MTD's ECC fixed the data */
+               if(ecc_result)
+                       *ecc_result = YAFFS_ECC_RESULT_FIXED;
+               dev->n_ecc_fixed++;
+               break;
+
+       case -EBADMSG:
+       default:
+               /* MTD's ECC could not fix the data */
+               dev->n_ecc_unfixed++;
+               if(ecc_result)
+                       *ecc_result = YAFFS_ECC_RESULT_UNFIXED;
+               return YAFFS_FAIL;
+       }
+
+       return YAFFS_OK;
+}
+
+static         int yaffs_mtd_erase(struct yaffs_dev *dev, int block_no)
+{
+       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
+
+       loff_t addr;
+       struct erase_info ei;
+       int retval = 0;
+       u32 block_size;
+
+       block_size = dev->param.total_bytes_per_chunk *
+                    dev->param.chunks_per_block;
+       addr = ((loff_t) block_no) * block_size;
+
+       ei.mtd = mtd;
+       ei.addr = addr;
+       ei.len = block_size;
+       ei.time = 1000;
+       ei.retries = 2;
+       ei.callback = NULL;
+       ei.priv = (u_long) dev;
+
+       retval = mtd->erase(mtd, &ei);
+
+       if (retval == 0)
+               return YAFFS_OK;
+
+       return YAFFS_FAIL;
+}
+
+static int yaffs_mtd_mark_bad(struct yaffs_dev *dev, int block_no)
+{
+       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
+       int blocksize = dev->param.chunks_per_block * dev->data_bytes_per_chunk;
+       int retval;
+
+       yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, "marking block %d bad", block_no);
+
+       retval = mtd->block_markbad(mtd, (loff_t) blocksize * block_no);
+       return (retval) ? YAFFS_FAIL : YAFFS_OK;
+}
+
+static int yaffs_mtd_check_bad(struct yaffs_dev *dev, int block_no)
+{
+       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
+       int blocksize = dev->param.chunks_per_block * dev->data_bytes_per_chunk;
+       int retval;
+
+       yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, "checking block %d bad", block_no);
+
+       retval = mtd->block_isbad(mtd, (loff_t) blocksize * block_no);
+       return (retval) ? YAFFS_FAIL : YAFFS_OK;
+}
+
+static int yaffs_mtd_initialise(struct yaffs_dev *dev)
+{
+       return YAFFS_OK;
+}
+
+static int yaffs_mtd_deinitialise(struct yaffs_dev *dev)
+{
+       return YAFFS_OK;
+}
+
+
+
+void yaffs_mtd_drv_install(struct yaffs_dev *dev)
+{
+       struct yaffs_driver *drv = &dev->drv;
+
+       drv->drv_write_chunk_fn = yaffs_mtd_write;
+       drv->drv_read_chunk_fn = yaffs_mtd_read;
+       drv->drv_erase_fn = yaffs_mtd_erase;
+       drv->drv_mark_bad_fn = yaffs_mtd_mark_bad;
+       drv->drv_check_bad_fn = yaffs_mtd_check_bad;
+       drv->drv_initialise_fn = yaffs_mtd_initialise;
+       drv->drv_deinitialise_fn = yaffs_mtd_deinitialise;
+}
diff --git a/yaffs_mtdif_single.c b/yaffs_mtdif_single.c
new file mode 100644 (file)
index 0000000..e61699d
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
+ *
+ * Copyright (C) 2002-2011 Aleph One Ltd.
+ *   for Toby Churchill Ltd and Brightstar Engineering
+ *
+ * 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.
+ */
+
+#include "yportenv.h"
+
+#include "yaffs_mtdif.h"
+
+#include "linux/mtd/mtd.h"
+#include "linux/types.h"
+#include "linux/time.h"
+#include "linux/mtd/nand.h"
+#include "linux/kernel.h"
+#include "linux/version.h"
+#include "linux/types.h"
+
+#include "yaffs_trace.h"
+#include "yaffs_guts.h"
+#include "yaffs_linux.h"
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
+#define MTD_OPS_AUTO_OOB MTD_OOB_AUTO
+#endif
+
+
+int nandmtd_erase_block(struct yaffs_dev *dev, int block_no)
+{
+       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
+       u32 addr =
+           ((loff_t) block_no) * dev->param.total_bytes_per_chunk *
+           dev->param.chunks_per_block;
+       struct erase_info ei;
+       int retval = 0;
+
+       ei.mtd = mtd;
+       ei.addr = addr;
+       ei.len = dev->param.total_bytes_per_chunk * dev->param.chunks_per_block;
+       ei.time = 1000;
+       ei.retries = 2;
+       ei.callback = NULL;
+       ei.priv = (u_long) dev;
+
+       retval = mtd->erase(mtd, &ei);
+
+       if (retval == 0)
+               return YAFFS_OK;
+
+       return YAFFS_FAIL;
+}
+
+
+static         int yaffs_mtd_write(struct yaffs_dev *dev, int nand_chunk,
+                                  const u8 *data, int data_len,
+                                  const u8 *oob, int oob_len)
+{
+       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
+       loff_t addr;
+       struct mtd_oob_ops ops;
+       int retval;
+
+       addr = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk;
+       memset(&ops, 0, sizeof(ops));
+       ops.mode = MTD_OPS_AUTO_OOB;
+       ops.len = (data) ? data_len : 0;
+       ops.ooblen = oob_len;
+       ops.datbuf = (u8 *)data;
+       ops.oobbuf = (u8 *)oob;
+
+       retval = mtd->write_oob(mtd, addr, &ops);
+       if (retval) {
+               yaffs_trace(YAFFS_TRACE_MTD,
+                       "write_oob failed, chunk %d, mtd error %d",
+                       nand_chunk, retval);
+       }
+       return retval ? YAFFS_FAIL : YAFFS_OK;
+}
+
+static int yaffs_mtd_read(struct yaffs_dev *dev, int nand_chunk,
+                                  u8 *data, int data_len,
+                                  u8 *oob, int oob_len,
+                                  enum yaffs_ecc_result *ecc_result)
+{
+       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
+       loff_t addr;
+       struct mtd_oob_ops ops;
+       int retval;
+
+       addr = ((loff_t) nand_chunk) * dev->data_bytes_per_chunk;
+       memset(&ops, 0, sizeof(ops));
+       ops.mode = MTD_OPS_AUTO_OOB;
+       ops.len = (data) ? data_len : 0;
+       ops.ooblen = oob_len;
+       ops.datbuf = data;
+       ops.oobbuf = oob;
+
+#if (MTD_VERSION_CODE < MTD_VERSION(2, 6, 20))
+       /* In MTD 2.6.18 to 2.6.19 nand_base.c:nand_do_read_oob() has a bug;
+        * help it out with ops.len = ops.ooblen when ops.datbuf == NULL.
+        */
+       ops.len = (ops.datbuf) ? ops.len : ops.ooblen;
+#endif
+       /* Read page and oob using MTD.
+        * Check status and determine ECC result.
+        */
+       retval = mtd->read_oob(mtd, addr, &ops);
+       if (retval)
+               yaffs_trace(YAFFS_TRACE_MTD,
+                       "read_oob failed, chunk %d, mtd error %d",
+                       nand_chunk, retval);
+
+       switch (retval) {
+       case 0:
+               /* no error */
+               if(ecc_result)
+                       *ecc_result = YAFFS_ECC_RESULT_NO_ERROR;
+               break;
+
+       case -EUCLEAN:
+               /* MTD's ECC fixed the data */
+               if(ecc_result)
+                       *ecc_result = YAFFS_ECC_RESULT_FIXED;
+               dev->n_ecc_fixed++;
+               break;
+
+       case -EBADMSG:
+       default:
+               /* MTD's ECC could not fix the data */
+               dev->n_ecc_unfixed++;
+               if(ecc_result)
+                       *ecc_result = YAFFS_ECC_RESULT_UNFIXED;
+               return YAFFS_FAIL;
+       }
+
+       return YAFFS_OK;
+}
+
+static         int yaffs_mtd_erase(struct yaffs_dev *dev, int block_no)
+{
+       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
+
+       loff_t addr;
+       struct erase_info ei;
+       int retval = 0;
+       u32 block_size;
+
+       block_size = dev->param.total_bytes_per_chunk *
+                    dev->param.chunks_per_block;
+       addr = ((loff_t) block_no) * block_size;
+
+       ei.mtd = mtd;
+       ei.addr = addr;
+       ei.len = block_size;
+       ei.time = 1000;
+       ei.retries = 2;
+       ei.callback = NULL;
+       ei.priv = (u_long) dev;
+
+       retval = mtd->erase(mtd, &ei);
+
+       if (retval == 0)
+               return YAFFS_OK;
+
+       return YAFFS_FAIL;
+}
+
+static int yaffs_mtd_mark_bad(struct yaffs_dev *dev, int block_no)
+{
+       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
+       int blocksize = dev->param.chunks_per_block * dev->data_bytes_per_chunk;
+       int retval;
+
+       yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, "marking block %d bad", block_no);
+
+       retval = mtd->block_markbad(mtd, (loff_t) blocksize * block_no);
+       return (retval) ? YAFFS_FAIL : YAFFS_OK;
+}
+
+static int yaffs_mtd_check_bad(struct yaffs_dev *dev, int block_no)
+{
+       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
+       int blocksize = dev->param.chunks_per_block * dev->data_bytes_per_chunk;
+       int retval;
+
+       yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, "checking block %d bad", block_no);
+
+       retval = mtd->block_isbad(mtd, (loff_t) blocksize * block_no);
+       return (retval) ? YAFFS_FAIL : YAFFS_OK;
+}
+
+static int yaffs_mtd_initialise(struct yaffs_dev *dev)
+{
+       return YAFFS_OK;
+}
+
+static int yaffs_mtd_deinitialise(struct yaffs_dev *dev)
+{
+       return YAFFS_OK;
+}
+
+
+
+void yaffs_mtd_drv_install(struct yaffs_dev *dev)
+{
+       struct yaffs_driver *drv = &dev->drv;
+
+       drv->drv_write_chunk_fn = yaffs_mtd_write;
+       drv->drv_read_chunk_fn = yaffs_mtd_read;
+       drv->drv_erase_fn = yaffs_mtd_erase;
+       drv->drv_mark_bad_fn = yaffs_mtd_mark_bad;
+       drv->drv_check_bad_fn = yaffs_mtd_check_bad;
+       drv->drv_initialise_fn = yaffs_mtd_initialise;
+       drv->drv_deinitialise_fn = yaffs_mtd_deinitialise;
+}
index 165d01004d6efde447d4b88a42f38c74dafa5fed..9afd5ec8e1c6cdf2233fc81264a69cf79cae4d28 100644 (file)
 #include "yaffs_getblockinfo.h"
 #include "yaffs_summary.h"
 
+static int apply_chunk_offset(struct yaffs_dev *dev, int chunk)
+{
+       return chunk - dev->chunk_offset;
+}
+
 int yaffs_rd_chunk_tags_nand(struct yaffs_dev *dev, int nand_chunk,
                             u8 *buffer, struct yaffs_ext_tags *tags)
 {
        int result;
        struct yaffs_ext_tags local_tags;
-       int flash_chunk = nand_chunk - dev->chunk_offset;
+       int flash_chunk = apply_chunk_offset(dev, nand_chunk);
 
        dev->n_page_reads++;
 
@@ -30,13 +35,7 @@ int yaffs_rd_chunk_tags_nand(struct yaffs_dev *dev, int nand_chunk,
        if (!tags)
                tags = &local_tags;
 
-       if (dev->param.read_chunk_tags_fn)
-               result =
-                   dev->param.read_chunk_tags_fn(dev, flash_chunk, buffer,
-                                                 tags);
-       else
-               result = yaffs_tags_compat_rd(dev,
-                                             flash_chunk, buffer, tags);
+       result = dev->tagger.read_chunk_tags_fn(dev, flash_chunk, buffer, tags);
        if (tags && tags->ecc_result > YAFFS_ECC_RESULT_NO_ERROR) {
 
                struct yaffs_block_info *bi;
@@ -53,27 +52,24 @@ int yaffs_wr_chunk_tags_nand(struct yaffs_dev *dev,
                                const u8 *buffer, struct yaffs_ext_tags *tags)
 {
        int result;
-       int flash_chunk = nand_chunk - dev->chunk_offset;
+       int flash_chunk = apply_chunk_offset(dev, nand_chunk);
 
        dev->n_page_writes++;
 
-       if (tags) {
-               tags->seq_number = dev->seq_number;
-               tags->chunk_used = 1;
-               yaffs_trace(YAFFS_TRACE_WRITE,
-                       "Writing chunk %d tags %d %d",
-                       nand_chunk, tags->obj_id, tags->chunk_id);
-       } else {
+       if (!tags) {
                yaffs_trace(YAFFS_TRACE_ERROR, "Writing with no tags");
                BUG();
                return YAFFS_FAIL;
        }
 
-       if (dev->param.write_chunk_tags_fn)
-               result = dev->param.write_chunk_tags_fn(dev, flash_chunk,
+       tags->seq_number = dev->seq_number;
+       tags->chunk_used = 1;
+       yaffs_trace(YAFFS_TRACE_WRITE,
+               "Writing chunk %d tags %d %d",
+               nand_chunk, tags->obj_id, tags->chunk_id);
+
+       result = dev->tagger.write_chunk_tags_fn(dev, flash_chunk,
                                                        buffer, tags);
-       else
-               result = yaffs_tags_compat_wr(dev, flash_chunk, buffer, tags);
 
        yaffs_summary_add(dev, tags, nand_chunk);
 
@@ -83,38 +79,40 @@ int yaffs_wr_chunk_tags_nand(struct yaffs_dev *dev,
 int yaffs_mark_bad(struct yaffs_dev *dev, int block_no)
 {
        block_no -= dev->block_offset;
-       if (dev->param.bad_block_fn)
-               return dev->param.bad_block_fn(dev, block_no);
-
-       return yaffs_tags_compat_mark_bad(dev, block_no);
+       dev->n_bad_markings++;
+       return dev->tagger.mark_bad_fn(dev, block_no);
 }
 
+
 int yaffs_query_init_block_state(struct yaffs_dev *dev,
                                 int block_no,
                                 enum yaffs_block_state *state,
                                 u32 *seq_number)
 {
        block_no -= dev->block_offset;
-       if (dev->param.query_block_fn)
-               return dev->param.query_block_fn(dev, block_no, state,
-                                                seq_number);
-
-       return yaffs_tags_compat_query_block(dev, block_no, state, seq_number);
+       return dev->tagger.query_block_fn(dev, block_no, state, seq_number);
 }
 
-int yaffs_erase_block(struct yaffs_dev *dev, int flash_block)
+int yaffs_erase_block(struct yaffs_dev *dev, int block_no)
 {
        int result;
 
-       flash_block -= dev->block_offset;
+       block_no -= dev->block_offset;
        dev->n_erasures++;
-       result = dev->param.erase_fn(dev, flash_block);
+       result = dev->drv.drv_erase_fn(dev, block_no);
        return result;
 }
 
 int yaffs_init_nand(struct yaffs_dev *dev)
 {
-       if (dev->param.initialise_flash_fn)
-               return dev->param.initialise_flash_fn(dev);
+       if (dev->drv.drv_initialise_fn)
+               return dev->drv.drv_initialise_fn(dev);
+       return YAFFS_OK;
+}
+
+int yaffs_deinit_nand(struct yaffs_dev *dev)
+{
+       if (dev->drv.drv_deinitialise_fn)
+               return dev->drv.drv_deinitialise_fn(dev);
        return YAFFS_OK;
 }
index 71346627fc0b7db66a90b833231ce4d186f5b4d6..804e97ad66d0ca50385b730af435ea1d944d90eb 100644 (file)
@@ -34,5 +34,6 @@ int yaffs_query_init_block_state(struct yaffs_dev *dev,
 int yaffs_erase_block(struct yaffs_dev *dev, int flash_block);
 
 int yaffs_init_nand(struct yaffs_dev *dev);
+int yaffs_deinit_nand(struct yaffs_dev *dev);
 
 #endif
index 32ba11fa9d5ce8e2ed0aab3fc8988fef0b2908f5..092430beccb7780311d1f148870a83a443fa0164 100644 (file)
@@ -22,11 +22,6 @@ static void yaffs_handle_rd_data_error(struct yaffs_dev *dev, int nand_chunk);
 
 /********** Tags ECC calculations  *********/
 
-static void yaffs_calc_ecc(const u8 *data, struct yaffs_spare *spare)
-{
-       yaffs_ecc_calc(data, spare->ecc1);
-       yaffs_ecc_calc(&data[256], spare->ecc2);
-}
 
 void yaffs_calc_tags_ecc(struct yaffs_tags *tags)
 {
@@ -127,14 +122,11 @@ static int yaffs_wr_nand(struct yaffs_dev *dev,
                         int nand_chunk, const u8 *data,
                         struct yaffs_spare *spare)
 {
-       if (nand_chunk < dev->param.start_block * dev->param.chunks_per_block) {
-               yaffs_trace(YAFFS_TRACE_ERROR,
-                       "**>> yaffs chunk %d is not valid",
-                       nand_chunk);
-               return YAFFS_FAIL;
-       }
+       int data_size = dev->data_bytes_per_chunk;
 
-       return dev->param.write_chunk_fn(dev, nand_chunk, data, spare);
+       return dev->drv.drv_write_chunk_fn(dev, nand_chunk,
+                               data, data_size,
+                               (u8 *) spare, sizeof(*spare));
 }
 
 static int yaffs_rd_chunk_nand(struct yaffs_dev *dev,
@@ -146,112 +138,77 @@ static int yaffs_rd_chunk_nand(struct yaffs_dev *dev,
 {
        int ret_val;
        struct yaffs_spare local_spare;
+       int data_size;
+       int spare_size;
+       int ecc_result1, ecc_result2;
+       u8 calc_ecc[3];
 
        if (!spare) {
                /* If we don't have a real spare, then we use a local one. */
                /* Need this for the calculation of the ecc */
                spare = &local_spare;
        }
+       data_size = dev->data_bytes_per_chunk;
+       spare_size = sizeof(struct yaffs_spare);
 
-       if (!dev->param.use_nand_ecc) {
-               ret_val =
-                   dev->param.read_chunk_fn(dev, nand_chunk, data, spare);
-               if (data && correct_errors) {
-                       /* Do ECC correction */
-                       /* Todo handle any errors */
-                       int ecc_result1, ecc_result2;
-                       u8 calc_ecc[3];
-
-                       yaffs_ecc_calc(data, calc_ecc);
-                       ecc_result1 =
-                           yaffs_ecc_correct(data, spare->ecc1, calc_ecc);
-                       yaffs_ecc_calc(&data[256], calc_ecc);
-                       ecc_result2 =
-                           yaffs_ecc_correct(&data[256], spare->ecc2,
-                                             calc_ecc);
-
-                       if (ecc_result1 > 0) {
-                               yaffs_trace(YAFFS_TRACE_ERROR,
-                                       "**>>yaffs ecc error fix performed on chunk %d:0",
-                                       nand_chunk);
-                               dev->n_ecc_fixed++;
-                       } else if (ecc_result1 < 0) {
-                               yaffs_trace(YAFFS_TRACE_ERROR,
-                                       "**>>yaffs ecc error unfixed on chunk %d:0",
-                                       nand_chunk);
-                               dev->n_ecc_unfixed++;
-                       }
-
-                       if (ecc_result2 > 0) {
-                               yaffs_trace(YAFFS_TRACE_ERROR,
-                                       "**>>yaffs ecc error fix performed on chunk %d:1",
-                                       nand_chunk);
-                               dev->n_ecc_fixed++;
-                       } else if (ecc_result2 < 0) {
-                               yaffs_trace(YAFFS_TRACE_ERROR,
-                                       "**>>yaffs ecc error unfixed on chunk %d:1",
-                                       nand_chunk);
-                               dev->n_ecc_unfixed++;
-                       }
-
-                       if (ecc_result1 || ecc_result2) {
-                               /* We had a data problem on this page */
-                               yaffs_handle_rd_data_error(dev, nand_chunk);
-                       }
-
-                       if (ecc_result1 < 0 || ecc_result2 < 0)
-                               *ecc_result = YAFFS_ECC_RESULT_UNFIXED;
-                       else if (ecc_result1 > 0 || ecc_result2 > 0)
-                               *ecc_result = YAFFS_ECC_RESULT_FIXED;
-                       else
-                               *ecc_result = YAFFS_ECC_RESULT_NO_ERROR;
-               }
-       } else {
-               /* Must allocate enough memory for spare+2*sizeof(int) */
-               /* for ecc results from device. */
-               struct yaffs_nand_spare nspare;
-
-               memset(&nspare, 0, sizeof(nspare));
-
-               ret_val = dev->param.read_chunk_fn(dev, nand_chunk, data,
-                                                  (struct yaffs_spare *)
-                                                  &nspare);
-               memcpy(spare, &nspare, sizeof(struct yaffs_spare));
-               if (data && correct_errors) {
-                       if (nspare.eccres1 > 0) {
-                               yaffs_trace(YAFFS_TRACE_ERROR,
-                                       "**>>mtd ecc error fix performed on chunk %d:0",
-                                       nand_chunk);
-                       } else if (nspare.eccres1 < 0) {
-                               yaffs_trace(YAFFS_TRACE_ERROR,
-                                       "**>>mtd ecc error unfixed on chunk %d:0",
-                                       nand_chunk);
-                       }
-
-                       if (nspare.eccres2 > 0) {
-                               yaffs_trace(YAFFS_TRACE_ERROR,
-                                       "**>>mtd ecc error fix performed on chunk %d:1",
-                                       nand_chunk);
-                       } else if (nspare.eccres2 < 0) {
-                               yaffs_trace(YAFFS_TRACE_ERROR,
-                                       "**>>mtd ecc error unfixed on chunk %d:1",
-                                       nand_chunk);
-                       }
-
-                       if (nspare.eccres1 || nspare.eccres2) {
-                               /* We had a data problem on this page */
-                               yaffs_handle_rd_data_error(dev, nand_chunk);
-                       }
-
-                       if (nspare.eccres1 < 0 || nspare.eccres2 < 0)
-                               *ecc_result = YAFFS_ECC_RESULT_UNFIXED;
-                       else if (nspare.eccres1 > 0 || nspare.eccres2 > 0)
-                               *ecc_result = YAFFS_ECC_RESULT_FIXED;
-                       else
-                               *ecc_result = YAFFS_ECC_RESULT_NO_ERROR;
+       if (dev->param.use_nand_ecc)
+               return dev->drv.drv_read_chunk_fn(dev, nand_chunk,
+                                               data, data_size,
+                                               (u8 *) spare, spare_size,
+                                               ecc_result);
 
-               }
+
+       /* Handle the ECC at this level. */
+
+       ret_val = dev->drv.drv_read_chunk_fn(dev, nand_chunk,
+                                                data, data_size,
+                                                (u8 *)spare, spare_size,
+                                               NULL);
+       if (!data || !correct_errors)
+               return ret_val;
+
+       /* Do ECC correction if needed. */
+       yaffs_ecc_calc(data, calc_ecc);
+       ecc_result1 = yaffs_ecc_correct(data, spare->ecc1, calc_ecc);
+       yaffs_ecc_calc(&data[256], calc_ecc);
+       ecc_result2 = yaffs_ecc_correct(&data[256], spare->ecc2, calc_ecc);
+
+       if (ecc_result1 > 0) {
+               yaffs_trace(YAFFS_TRACE_ERROR,
+                       "**>>yaffs ecc error fix performed on chunk %d:0",
+                       nand_chunk);
+               dev->n_ecc_fixed++;
+       } else if (ecc_result1 < 0) {
+               yaffs_trace(YAFFS_TRACE_ERROR,
+                       "**>>yaffs ecc error unfixed on chunk %d:0",
+                       nand_chunk);
+               dev->n_ecc_unfixed++;
        }
+
+       if (ecc_result2 > 0) {
+               yaffs_trace(YAFFS_TRACE_ERROR,
+                       "**>>yaffs ecc error fix performed on chunk %d:1",
+                       nand_chunk);
+               dev->n_ecc_fixed++;
+       } else if (ecc_result2 < 0) {
+               yaffs_trace(YAFFS_TRACE_ERROR,
+                       "**>>yaffs ecc error unfixed on chunk %d:1",
+                       nand_chunk);
+               dev->n_ecc_unfixed++;
+       }
+
+       if (ecc_result1 || ecc_result2) {
+               /* We had a data problem on this page */
+               yaffs_handle_rd_data_error(dev, nand_chunk);
+       }
+
+       if (ecc_result1 < 0 || ecc_result2 < 0)
+               *ecc_result = YAFFS_ECC_RESULT_UNFIXED;
+       else if (ecc_result1 > 0 || ecc_result2 > 0)
+               *ecc_result = YAFFS_ECC_RESULT_FIXED;
+       else
+               *ecc_result = YAFFS_ECC_RESULT_NO_ERROR;
+
        return ret_val;
 }
 
@@ -277,7 +234,7 @@ static void yaffs_handle_rd_data_error(struct yaffs_dev *dev, int nand_chunk)
         */
 }
 
-int yaffs_tags_compat_wr(struct yaffs_dev *dev,
+static int yaffs_tags_compat_wr(struct yaffs_dev *dev,
                         int nand_chunk,
                         const u8 *data, const struct yaffs_ext_tags *ext_tags)
 {
@@ -301,15 +258,17 @@ int yaffs_tags_compat_wr(struct yaffs_dev *dev,
 
                tags.serial_number = ext_tags->serial_number;
 
-               if (!dev->param.use_nand_ecc && data)
-                       yaffs_calc_ecc(data, &spare);
+               if (!dev->param.use_nand_ecc && data) {
+                       yaffs_ecc_calc(data, spare.ecc1);
+                       yaffs_ecc_calc(&data[256], spare.ecc2);
+               }
 
                yaffs_load_tags_to_spare(&spare, &tags);
        }
        return yaffs_wr_nand(dev, nand_chunk, data, &spare);
 }
 
-int yaffs_tags_compat_rd(struct yaffs_dev *dev,
+static int yaffs_tags_compat_rd(struct yaffs_dev *dev,
                         int nand_chunk,
                         u8 *data, struct yaffs_ext_tags *ext_tags)
 {
@@ -358,7 +317,7 @@ int yaffs_tags_compat_rd(struct yaffs_dev *dev,
        return YAFFS_OK;
 }
 
-int yaffs_tags_compat_mark_bad(struct yaffs_dev *dev, int flash_block)
+static int yaffs_tags_compat_mark_bad(struct yaffs_dev *dev, int flash_block)
 {
        struct yaffs_spare spare;
 
@@ -374,7 +333,7 @@ int yaffs_tags_compat_mark_bad(struct yaffs_dev *dev, int flash_block)
        return YAFFS_OK;
 }
 
-int yaffs_tags_compat_query_block(struct yaffs_dev *dev,
+static int yaffs_tags_compat_query_block(struct yaffs_dev *dev,
                                  int block_no,
                                  enum yaffs_block_state *state,
                                  u32 *seq_number)
@@ -391,10 +350,11 @@ int yaffs_tags_compat_query_block(struct yaffs_dev *dev,
 
        *seq_number = 0;
 
-       yaffs_rd_chunk_nand(dev, block_no * dev->param.chunks_per_block, NULL,
-                           &spare0, &dummy, 1);
+       /* Look for bad block markers in the first two chunks */
+       yaffs_rd_chunk_nand(dev, block_no * dev->param.chunks_per_block,
+                           NULL, &spare0, &dummy, 0);
        yaffs_rd_chunk_nand(dev, block_no * dev->param.chunks_per_block + 1,
-                           NULL, &spare1, &dummy, 1);
+                           NULL, &spare1, &dummy, 0);
 
        if (hweight8(spare0.block_status & spare1.block_status) < 7)
                *state = YAFFS_BLOCK_STATE_DEAD;
@@ -405,3 +365,17 @@ int yaffs_tags_compat_query_block(struct yaffs_dev *dev,
 
        return YAFFS_OK;
 }
+
+void yaffs_tags_compat_install(struct yaffs_dev *dev)
+{
+       if(dev->param.is_yaffs2)
+               return;
+       if(!dev->tagger.write_chunk_tags_fn)
+               dev->tagger.write_chunk_tags_fn = yaffs_tags_compat_wr;
+       if(!dev->tagger.read_chunk_tags_fn)
+               dev->tagger.read_chunk_tags_fn = yaffs_tags_compat_rd;
+       if(!dev->tagger.query_block_fn)
+               dev->tagger.query_block_fn = yaffs_tags_compat_query_block;
+       if(!dev->tagger.mark_bad_fn)
+               dev->tagger.mark_bad_fn = yaffs_tags_compat_mark_bad;
+}
index b3c665577252bbbc059295aa5ee10e45f16fbeb8..92d298a6f582b8d8475840fb13e8034d9d6b1381 100644 (file)
 #ifndef __YAFFS_TAGSCOMPAT_H__
 #define __YAFFS_TAGSCOMPAT_H__
 
+
 #include "yaffs_guts.h"
+
+#if 0
+
+
 int yaffs_tags_compat_wr(struct yaffs_dev *dev,
                         int nand_chunk,
                         const u8 *data, const struct yaffs_ext_tags *tags);
@@ -29,8 +34,11 @@ int yaffs_tags_compat_query_block(struct yaffs_dev *dev,
                                  enum yaffs_block_state *state,
                                  u32 *seq_number);
 
+#endif
+
+
+void yaffs_tags_compat_install(struct yaffs_dev *dev);
 void yaffs_calc_tags_ecc(struct yaffs_tags *tags);
 int yaffs_check_tags_ecc(struct yaffs_tags *tags);
-int yaffs_count_bits(u8 byte);
 
 #endif
diff --git a/yaffs_tagsmarshall.c b/yaffs_tagsmarshall.c
new file mode 100644 (file)
index 0000000..44a83b1
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
+ *
+ * Copyright (C) 2002-2011 Aleph One Ltd.
+ *   for Toby Churchill Ltd and Brightstar Engineering
+ *
+ * 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.
+ */
+
+#include "yaffs_guts.h"
+#include "yaffs_trace.h"
+#include "yaffs_packedtags2.h"
+
+static int yaffs_tags_marshall_write(struct yaffs_dev *dev,
+                                   int nand_chunk, const u8 *data,
+                                   const struct yaffs_ext_tags *tags)
+{
+       struct yaffs_packed_tags2 pt;
+       int retval;
+
+       int packed_tags_size =
+           dev->param.no_tags_ecc ? sizeof(pt.t) : sizeof(pt);
+       void *packed_tags_ptr =
+           dev->param.no_tags_ecc ? (void *)&pt.t : (void *)&pt;
+
+       yaffs_trace(YAFFS_TRACE_MTD,
+               "yaffs_tags_marshall_write chunk %d data %p tags %p",
+               nand_chunk, data, tags);
+
+       /* For yaffs2 writing there must be both data and tags.
+        * If we're using inband tags, then the tags are stuffed into
+        * the end of the data buffer.
+        */
+       if (!data || !tags)
+               BUG();
+       else if (dev->param.inband_tags) {
+               struct yaffs_packed_tags2_tags_only *pt2tp;
+               pt2tp =
+                   (struct yaffs_packed_tags2_tags_only *)(data +
+                                                       dev->
+                                                       data_bytes_per_chunk);
+               yaffs_pack_tags2_tags_only(pt2tp, tags);
+       } else {
+               yaffs_pack_tags2(&pt, tags, !dev->param.no_tags_ecc);
+       }
+
+       retval = dev->drv.drv_write_chunk_fn(dev, nand_chunk,
+                       data, dev->param.total_bytes_per_chunk,
+                       (dev->param.inband_tags) ? NULL : packed_tags_ptr,
+                       (dev->param.inband_tags) ? 0 : packed_tags_size);
+
+       return retval;
+}
+
+static int yaffs_tags_marshall_read(struct yaffs_dev *dev,
+                                  int nand_chunk, u8 *data,
+                                  struct yaffs_ext_tags *tags)
+{
+       int retval = 0;
+       int local_data = 0;
+       u8 spare_buffer[100];
+       enum yaffs_ecc_result ecc_result;
+
+       struct yaffs_packed_tags2 pt;
+
+       int packed_tags_size =
+           dev->param.no_tags_ecc ? sizeof(pt.t) : sizeof(pt);
+       void *packed_tags_ptr =
+           dev->param.no_tags_ecc ? (void *)&pt.t : (void *)&pt;
+
+       yaffs_trace(YAFFS_TRACE_MTD,
+               "yaffs_tags_marshall_read chunk %d data %p tags %p",
+               nand_chunk, data, tags);
+
+       if (dev->param.inband_tags) {
+               if (!data) {
+                       local_data = 1;
+                       data = yaffs_get_temp_buffer(dev);
+               }
+       }
+
+       if (dev->param.inband_tags || (data && !tags))
+               retval = dev->drv.drv_read_chunk_fn(dev, nand_chunk,
+                                       data, dev->param.total_bytes_per_chunk,
+                                       NULL, 0,
+                                       &ecc_result);
+       else if (tags)
+               retval = dev->drv.drv_read_chunk_fn(dev, nand_chunk,
+                                       data, dev->param.total_bytes_per_chunk,
+                                       spare_buffer, packed_tags_size,
+                                       &ecc_result);
+       else
+               BUG();
+
+
+       if (dev->param.inband_tags) {
+               if (tags) {
+                       struct yaffs_packed_tags2_tags_only *pt2tp;
+                       pt2tp =
+                               (struct yaffs_packed_tags2_tags_only *)
+                               &data[dev->data_bytes_per_chunk];
+                       yaffs_unpack_tags2_tags_only(tags, pt2tp);
+               }
+       } else if (tags) {
+               memcpy(packed_tags_ptr, spare_buffer, packed_tags_size);
+               yaffs_unpack_tags2(tags, &pt, !dev->param.no_tags_ecc);
+       }
+
+       if (local_data)
+               yaffs_release_temp_buffer(dev, data);
+
+       if (tags && ecc_result == YAFFS_ECC_RESULT_UNFIXED) {
+               tags->ecc_result = YAFFS_ECC_RESULT_UNFIXED;
+               dev->n_ecc_unfixed++;
+       }
+
+       if (tags && ecc_result == -YAFFS_ECC_RESULT_FIXED) {
+               if (tags->ecc_result <= YAFFS_ECC_RESULT_NO_ERROR)
+                       tags->ecc_result = YAFFS_ECC_RESULT_FIXED;
+               dev->n_ecc_fixed++;
+       }
+
+       if (ecc_result < YAFFS_ECC_RESULT_UNFIXED)
+               return YAFFS_OK;
+       else
+               return YAFFS_FAIL;
+}
+
+static int yaffs_tags_marshall_query_block(struct yaffs_dev *dev, int block_no,
+                              enum yaffs_block_state *state,
+                              u32 *seq_number)
+{
+       int retval;
+
+       yaffs_trace(YAFFS_TRACE_MTD, "yaffs_tags_marshall_query_block %d",
+                       block_no);
+
+       retval = dev->drv.drv_check_bad_fn(dev, block_no);
+
+       if (retval== YAFFS_FAIL) {
+               yaffs_trace(YAFFS_TRACE_MTD, "block is bad");
+
+               *state = YAFFS_BLOCK_STATE_DEAD;
+               *seq_number = 0;
+       } else {
+               struct yaffs_ext_tags t;
+
+               yaffs_tags_marshall_read(dev,
+                                   block_no * dev->param.chunks_per_block,
+                                   NULL, &t);
+
+               if (t.chunk_used) {
+                       *seq_number = t.seq_number;
+                       *state = YAFFS_BLOCK_STATE_NEEDS_SCAN;
+               } else {
+                       *seq_number = 0;
+                       *state = YAFFS_BLOCK_STATE_EMPTY;
+               }
+       }
+
+       yaffs_trace(YAFFS_TRACE_MTD,
+               "block query returns  seq %d state %d",
+               *seq_number, *state);
+
+       if (retval == 0)
+               return YAFFS_OK;
+       else
+               return YAFFS_FAIL;
+}
+
+static int yaffs_tags_marshall_mark_bad(struct yaffs_dev *dev, int block_no)
+{
+       return dev->drv.drv_mark_bad_fn(dev, block_no);
+
+}
+
+
+void yaffs_tags_marshall_install(struct yaffs_dev *dev)
+{
+       if (!dev->param.is_yaffs2)
+               return;
+
+       if (!dev->tagger.write_chunk_tags_fn)
+               dev->tagger.write_chunk_tags_fn = yaffs_tags_marshall_write;
+
+       if (!dev->tagger.read_chunk_tags_fn)
+               dev->tagger.read_chunk_tags_fn = yaffs_tags_marshall_read;
+
+       if (!dev->tagger.query_block_fn)
+               dev->tagger.query_block_fn = yaffs_tags_marshall_query_block;
+
+       if (!dev->tagger.mark_bad_fn)
+               dev->tagger.mark_bad_fn = yaffs_tags_marshall_mark_bad;
+
+}
similarity index 64%
rename from direct/basic-test/ynorsim.h
rename to yaffs_tagsmarshall.h
index 6b1193fc5460ec1ed0e9d227c51a4d35da49a589..bf3e68a1a5be8a7e2321f08a7d3828851949f6b7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * YAFFS: Yet another Flash File System . A NAND-flash specific file system. 
+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
  *
  * Copyright (C) 2002-2011 Aleph One Ltd.
  *   for Toby Churchill Ltd and Brightstar Engineering
  * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
  */
 
-#ifndef __Y_NORSIM_H__
-#define __Y_NORSIM_H__
+#ifndef __YAFFS_TAGSMARSHALL_H__
+#define __YAFFS_TAGSMARSHALL_H__
 
 #include "yaffs_guts.h"
-
-void ynorsim_rd32(u32 *addr, u32 *data, int nwords);
-void ynorsim_wr32(u32 *addr, u32 *data, int nwords);
-void ynorsim_erase(u32 *addr);
-void ynorsim_shutdown(void);
-void ynorsim_initialise(void);
-u32 * ynorsim_get_base(void);
+void yaffs_tags_marshall_install(struct yaffs_dev *dev);
 
 #endif
index ce41d6c81d8150a0ad59a70fec185c2645d167c7..3cf6dde1717c394487c3780189da83801fddcb52 100644 (file)
@@ -176,8 +176,6 @@ static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size)
 #include "yaffs_linux.h"
 
 #include "yaffs_mtdif.h"
-#include "yaffs_mtdif1.h"
-#include "yaffs_mtdif2.h"
 
 unsigned int yaffs_trace_mask = YAFFS_TRACE_BAD_BLOCKS | YAFFS_TRACE_ALWAYS;
 unsigned int yaffs_wr_attempts = YAFFS_WR_ATTEMPTS;
@@ -2475,8 +2473,10 @@ struct mutex yaffs_context_lock;
 static void yaffs_put_super(struct super_block *sb)
 {
        struct yaffs_dev *dev = yaffs_super_to_dev(sb);
+       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
 
-       yaffs_trace(YAFFS_TRACE_OS, "yaffs_put_super");
+       yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_ALWAYS,
+                       "yaffs_put_super");
 
        yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_BACKGROUND,
                "Shutting down yaffs background thread");
@@ -2488,9 +2488,6 @@ static void yaffs_put_super(struct super_block *sb)
 
        yaffs_flush_super(sb, 1);
 
-       if (yaffs_dev_to_lc(dev)->put_super_fn)
-               yaffs_dev_to_lc(dev)->put_super_fn(sb);
-
        yaffs_deinitialise(dev);
 
        yaffs_gross_unlock(dev);
@@ -2505,18 +2502,18 @@ static void yaffs_put_super(struct super_block *sb)
        }
 
        kfree(dev);
-}
-
-static void yaffs_mtd_put_super(struct super_block *sb)
-{
-       struct mtd_info *mtd = yaffs_dev_to_mtd(yaffs_super_to_dev(sb));
 
-       if (mtd->sync)
+       if (mtd && mtd->sync)
                mtd->sync(mtd);
 
-       put_mtd_device(mtd);
+       if(mtd)
+               put_mtd_device(mtd);
+
+       yaffs_trace(YAFFS_TRACE_OS | YAFFS_TRACE_ALWAYS,
+                       "yaffs_put_super done");
 }
 
+
 static void yaffs_touch_super(struct yaffs_dev *dev)
 {
        struct super_block *sb = yaffs_dev_to_lc(dev)->super;
@@ -2831,14 +2828,7 @@ static struct super_block *yaffs_internal_read_super(int yaffs_version,
 
        /* Set up the memory size parameters.... */
 
-       n_blocks =
-           YCALCBLOCKS(mtd->size,
-                       (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK));
 
-       param->start_block = 0;
-       param->end_block = n_blocks - 1;
-       param->chunks_per_block = YAFFS_CHUNKS_PER_BLOCK;
-       param->total_bytes_per_chunk = YAFFS_BYTES_PER_CHUNK;
        param->n_reserved_blocks = 5;
        param->n_caches = (options.no_cache) ? 0 : 10;
        param->inband_tags = options.inband_tags;
@@ -2861,12 +2851,6 @@ static struct super_block *yaffs_internal_read_super(int yaffs_version,
 
        /* ... and the functions. */
        if (yaffs_version == 2) {
-               param->write_chunk_tags_fn = nandmtd2_write_chunk_tags;
-               param->read_chunk_tags_fn = nandmtd2_read_chunk_tags;
-               param->bad_block_fn = nandmtd2_mark_block_bad;
-               param->query_block_fn = nandmtd2_query_block;
-               yaffs_dev_to_lc(dev)->spare_buffer =
-                               kmalloc(mtd->oobsize, GFP_NOFS);
                param->is_yaffs2 = 1;
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
                param->total_bytes_per_chunk = mtd->writesize;
@@ -2880,26 +2864,21 @@ static struct super_block *yaffs_internal_read_super(int yaffs_version,
                param->start_block = 0;
                param->end_block = n_blocks - 1;
        } else {
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-               /* use the MTD interface in yaffs_mtdif1.c */
-               param->write_chunk_tags_fn = nandmtd1_write_chunk_tags;
-               param->read_chunk_tags_fn = nandmtd1_read_chunk_tags;
-               param->bad_block_fn = nandmtd1_mark_block_bad;
-               param->query_block_fn = nandmtd1_query_block;
-#else
-               param->write_chunk_fn = nandmtd_write_chunk;
-               param->read_chunk_fn = nandmtd_read_chunk;
-#endif
                param->is_yaffs2 = 0;
+               n_blocks = YCALCBLOCKS(mtd->size,
+                            YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
+
+               param->chunks_per_block = YAFFS_CHUNKS_PER_BLOCK;
+               param->total_bytes_per_chunk = YAFFS_BYTES_PER_CHUNK;
        }
-       /* ... and common functions */
-       param->erase_fn = nandmtd_erase_block;
-       param->initialise_flash_fn = nandmtd_initialise;
 
-       yaffs_dev_to_lc(dev)->put_super_fn = yaffs_mtd_put_super;
+       param->start_block = 0;
+       param->end_block = n_blocks - 1;
+
+       yaffs_mtd_drv_install(dev);
 
        param->sb_dirty_fn = yaffs_touch_super;
-       param->gc_control = yaffs_gc_control_callback;
+       param->gc_control_fn = yaffs_gc_control_callback;
 
        yaffs_dev_to_lc(dev)->super = sb;
 
index 8d41f69a2b1f830028c060e08624a4e6dfcaa4ef..145517b69b165d4274037493075046c85c78ac58 100644 (file)
@@ -1912,6 +1912,7 @@ static void yaffs_fill_inode_from_obj(struct inode *inode,
 static void yaffs_put_super(struct super_block *sb)
 {
        struct yaffs_dev *dev = yaffs_super_to_dev(sb);
+       struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
 
        yaffs_trace(YAFFS_TRACE_OS, "yaffs_put_super");
 
@@ -1941,16 +1942,14 @@ static void yaffs_put_super(struct super_block *sb)
        }
 
        kfree(dev);
-}
 
-static void yaffs_mtd_put_super(struct super_block *sb)
-{
-       struct mtd_info *mtd = yaffs_dev_to_mtd(yaffs_super_to_dev(sb));
 
-       if (mtd->sync)
+
+       if (mtd && mtd->sync)
                mtd->sync(mtd);
 
-       put_mtd_device(mtd);
+       if (mtd)
+               put_mtd_device(mtd);
 }
 
 static const struct super_operations yaffs_super_ops = {
@@ -2213,7 +2212,7 @@ static struct super_block *yaffs_internal_read_super(int yaffs_version,
        yaffs_dev_to_lc(dev)->put_super_fn = yaffs_mtd_put_super;
 
        param->sb_dirty_fn = yaffs_touch_super;
-       param->gc_control = yaffs_gc_control_callback;
+       param->gc_control_fn = yaffs_gc_control_callback;
 
        yaffs_dev_to_lc(dev)->super = sb;