Merge branch 'driver-refactoring' into new-driver-refactoring
authorCharles Manning <cdhmanning@gmail.com>
Tue, 2 Oct 2012 02:41:32 +0000 (15:41 +1300)
committerCharles Manning <cdhmanning@gmail.com>
Tue, 2 Oct 2012 02:41:32 +0000 (15:41 +1300)
75 files changed:
Makefile
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/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_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 100% similarity]
direct/test-framework/tests/launch_tests.sh [moved from direct/tests/launch_tests.sh with 100% similarity]
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 100% 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_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 100% 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 56% similarity]
direct/test-framework/yaffs_m18_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 [moved from direct/basic-test/ynorsim.c with 100% similarity]
direct/test-framework/ynorsim.h [moved from direct/basic-test/ynorsim.h with 100% 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/yaffs_osglue.h
direct/yaffsfs.c
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_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/yaffs_norif1.h with 52% 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
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;
-}
-
-
-
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..da47e491de10b6243836307bdfe174769e1d9cf5 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  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,23 @@ 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_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 $@ $<
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 56%
rename from direct/basic-test/yaffs_norif1.c
rename to direct/test-framework/yaffs_m18_drv.c
index 98008b505bd8a53ec34b33bc9fbb79b79188e5ed..0325968279ac0521e9d67c51a8c706e2eb8adf89 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,68 +67,69 @@ 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 m18_drv_FlashInit() ynorsim_initialise()
+#define m18_drv_FlashDeinit() ynorsim_shutdown()
+#define m18_drv_FlashWrite32(addr,buf,nwords) ynorsim_wr32(addr,buf,nwords)
+#define m18_drv_FlashRead32(addr,buf,nwords) ynorsim_rd32(addr,buf,nwords)
+#define m18_drv_FlashEraseBlock(addr) ynorsim_erase(addr)
 #define DEVICE_BASE     ynorsim_get_base()
 #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;
        dev=dev;
-       
+
        addr = (u32) 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;
 
        addr = (u32) 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;
-       
+
        block = chunk_id/dev->param.chunks_per_block;
        chunkInBlock = chunk_id % dev->param.chunks_per_block;
-       
+
        addr = (u32) 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;
-       
+
        block = chunk_id/dev->param.chunks_per_block;
        chunkInBlock = chunk_id % dev->param.chunks_per_block;
-       
+
        addr = (u32) Block2Addr(dev,block);
        addr += SPARE_AREA_OFFSET;
        addr += chunkInBlock * (SPARE_BYTES_PER_CHUNK + M18_SKIP);
@@ -137,7 +137,7 @@ u32 *Chunk2SpareAddr(struct yaffs_dev *dev,int chunk_id)
 }
 
 
-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 +147,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 +237,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 +291,77 @@ 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
+
+
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..b9a09a7
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * 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"
+
+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");
+
+       // /yaffs2  yaffs2 file emulation
+       yflash2_install_drv("yaffs2");
+
+       return 0;
+}
+
+
+
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 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..7ee486a8d0d95cb2afa2dcd2eb69dd368db441de 100644 (file)
@@ -501,6 +501,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 +796,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 +1080,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 +1202,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 +1313,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 +1428,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 +1497,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 +1637,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 +1686,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 +1807,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 +1865,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 +1898,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 +1952,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 +1985,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 +2039,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 +2071,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 +2125,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 +2249,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 +2307,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 +2379,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 +2433,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 +2470,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 +2529,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 +2578,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 +2618,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 +2728,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 +2757,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 +2788,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 +2940,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 +3034,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 +3050,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 +3074,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 +3122,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 +3164,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 +3237,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 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 0e334bdd5e723ad6a028d10e1c5b1b1cda9092e8..26ad54d401028020c356edc2d1c6b70a72aeadc5 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;
+}
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 52%
rename from direct/basic-test/yaffs_norif1.h
rename to yaffs_tagsmarshall.h
index 72952b4d8f0a529a50ef58f6217aa71a40284b1a..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 __YAFFS_NOR_IF1_H__
-#define __YAFFS_NOR_IF1_H__
+#ifndef __YAFFS_TAGSMARSHALL_H__
+#define __YAFFS_TAGSMARSHALL_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);
+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;