diff options
-rw-r--r-- | devextras.h | 99 | ||||
-rw-r--r-- | direct/basic-test/Makefile (renamed from direct/Makefile) | 68 | ||||
-rw-r--r-- | direct/basic-test/dtest.c (renamed from direct/dtest.c) | 0 | ||||
-rw-r--r-- | direct/basic-test/yaffs_fileem.c (renamed from direct/yaffs_fileem.c) | 0 | ||||
-rw-r--r-- | direct/basic-test/yaffs_fileem2k.c (renamed from direct/yaffs_fileem2k.c) | 0 | ||||
-rw-r--r-- | direct/basic-test/yaffs_fileem2k.h (renamed from direct/yaffs_fileem2k.h) | 0 | ||||
-rw-r--r-- | direct/basic-test/yaffs_norif1.c (renamed from direct/yaffs_norif1.c) | 5 | ||||
-rw-r--r-- | direct/basic-test/yaffs_norif1.h (renamed from direct/yaffs_norif1.h) | 0 | ||||
-rw-r--r-- | direct/basic-test/yaffs_ramdisk.c (renamed from direct/yaffs_ramdisk.c) | 0 | ||||
-rw-r--r-- | direct/basic-test/yaffs_ramdisk.h (renamed from direct/yaffs_ramdisk.h) | 0 | ||||
-rw-r--r-- | direct/basic-test/yaffs_ramem2k.c (renamed from direct/yaffs_ramem2k.c) | 0 | ||||
-rw-r--r-- | direct/basic-test/yaffscfg.c (renamed from direct/yaffscfg.c) | 7 | ||||
-rw-r--r-- | direct/basic-test/yaffscfg.h (renamed from direct/yaffscfg.h) | 1 | ||||
-rw-r--r-- | direct/basic-test/yaffscfg2k.c (renamed from direct/yaffscfg2k.c) | 35 | ||||
-rw-r--r-- | direct/basic-test/yaffsnewcfg.c | 112 | ||||
-rw-r--r-- | direct/basic-test/ynorsim.c (renamed from direct/ynorsim.c) | 0 | ||||
-rw-r--r-- | direct/basic-test/ynorsim.h (renamed from direct/ynorsim.h) | 0 | ||||
-rw-r--r-- | direct/basic-test/yramsim.c | 277 | ||||
-rw-r--r-- | direct/basic-test/yramsim.h | 11 | ||||
-rw-r--r-- | direct/python/Makefile | 25 | ||||
-rw-r--r-- | direct/tests/Makefile | 25 | ||||
-rw-r--r-- | direct/yaffs_nandif.c | 501 | ||||
-rw-r--r-- | direct/yaffs_nandif.h | 51 | ||||
-rw-r--r-- | direct/yaffsfs.c | 63 | ||||
-rw-r--r-- | direct/yaffsfs.h | 162 | ||||
-rw-r--r-- | direct/ydirectenv.h | 4 | ||||
-rw-r--r-- | yaffs_fs.c | 88 | ||||
-rw-r--r-- | yaffs_guts.c | 143 | ||||
-rw-r--r-- | yaffs_guts.h | 13 | ||||
-rw-r--r-- | yaffs_linux.h | 4 | ||||
-rw-r--r-- | yaffs_list.h | 127 | ||||
-rw-r--r-- | yaffs_mtdif.c | 2 | ||||
-rw-r--r-- | yaffs_mtdif1.c | 8 | ||||
-rw-r--r-- | yaffs_mtdif2.c | 12 | ||||
-rw-r--r-- | yaffs_yaffs1.c | 2 | ||||
-rw-r--r-- | yaffs_yaffs2.c | 2 | ||||
-rw-r--r-- | yportenv.h | 166 |
37 files changed, 1319 insertions, 694 deletions
diff --git a/devextras.h b/devextras.h index 215caa5..ce30c82 100644 --- a/devextras.h +++ b/devextras.h @@ -24,6 +24,8 @@ #define __EXTRAS_H__ +#include "yportenv.h" + #if !(defined __KERNEL__) /* Definition of types */ @@ -33,103 +35,6 @@ typedef unsigned __u32; #endif -/* - * This is a simple doubly linked list implementation that matches the - * way the Linux kernel doubly linked list implementation works. - */ - -struct ylist_head { - struct ylist_head *next; /* next in chain */ - struct ylist_head *prev; /* previous in chain */ -}; - - -/* Initialise a static list */ -#define YLIST_HEAD(name) \ -struct ylist_head name = { &(name), &(name)} - - - -/* Initialise a list head to an empty list */ -#define YINIT_LIST_HEAD(p) \ -do { \ - (p)->next = (p);\ - (p)->prev = (p); \ -} while (0) - - -/* Add an element to a list */ -static __inline__ void ylist_add(struct ylist_head *newEntry, - struct ylist_head *list) -{ - struct ylist_head *listNext = list->next; - - list->next = newEntry; - newEntry->prev = list; - newEntry->next = listNext; - listNext->prev = newEntry; - -} - -static __inline__ void ylist_add_tail(struct ylist_head *newEntry, - struct ylist_head *list) -{ - struct ylist_head *listPrev = list->prev; - - list->prev = newEntry; - newEntry->next = list; - newEntry->prev = listPrev; - listPrev->next = newEntry; - -} - - -/* Take an element out of its current list, with or without - * reinitialising the links.of the entry*/ -static __inline__ void ylist_del(struct ylist_head *entry) -{ - struct ylist_head *listNext = entry->next; - struct ylist_head *listPrev = entry->prev; - - listNext->prev = listPrev; - listPrev->next = listNext; - -} - -static __inline__ void ylist_del_init(struct ylist_head *entry) -{ - ylist_del(entry); - entry->next = entry->prev = entry; -} - - -/* Test if the list is empty */ -static __inline__ int ylist_empty(struct ylist_head *entry) -{ - return (entry->next == entry); -} - - -/* ylist_entry takes a pointer to a list entry and offsets it to that - * we can find a pointer to the object it is embedded in. - */ - - -#define ylist_entry(entry, type, member) \ - ((type *)((char *)(entry)-(unsigned long)(&((type *)NULL)->member))) - - -/* ylist_for_each and list_for_each_safe iterate over lists. - * ylist_for_each_safe uses temporary storage to make the list delete safe - */ - -#define ylist_for_each(itervar, list) \ - for (itervar = (list)->next; itervar != (list); itervar = itervar->next) - -#define ylist_for_each_safe(itervar, saveVar, list) \ - for (itervar = (list)->next, saveVar = (list)->next->next; \ - itervar != (list); itervar = saveVar, saveVar = saveVar->next) - #if !(defined __KERNEL__) diff --git a/direct/Makefile b/direct/basic-test/Makefile index 931fed1..d8ddd32 100644 --- a/direct/Makefile +++ b/direct/basic-test/Makefile @@ -28,49 +28,83 @@ CFLAGS += -O0 #CFLAGS+= -Wshadow -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Wmissing-declarations #CFLAGS+= -Wmissing-prototypes -Wredundant-decls -Wnested-externs -Winline - COMMONTESTOBJS = yaffscfg2k.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_tagsvalidity.o yaffs_nand.o \ yaffs_checkptrw.o yaffs_qsort.o\ yaffs_nameval.o \ - yaffs_norif1.o ynorsim.o \ - yaffs_allocator.o yaffs_yaffs1.o \ + yaffs_norif1.o ynorsim.o nor_stress.o yaffs_fsx.o \ + yaffs_allocator.o \ + yaffs_bitmap.o \ + yaffs_yaffs1.o \ yaffs_yaffs2.o \ - yaffs_bitmap.o yaffs_verify.o + yaffs_verify.o # yaffs_checkptrwtest.o\ -DIRECTTESTOBJS = $(COMMONTESTOBJS) dtest.o +YAFFSTESTOBJS = $(COMMONTESTOBJS) yaffs_test.o -BOOTTESTOBJS = bootldtst.o yboot.o yaffs_fileem.o nand_ecc.o - -#ALLOBJS = dtest.o nand_ecc.o yaffscfg.o yaffs_fileem.o yaffsfs.o yaffs_ramdisk.o bootldtst.o yboot.o yaffs_ramem2k.o -ALLOBJS = $(sort $(DIRECTTESTOBJS) $(YAFFSTESTOBJS)) +ALLOBJS = $(sort $(YAFFSTESTOBJS)) -SYMLINKS = devextras.h yaffs_ecc.c yaffs_ecc.h yaffs_guts.c yaffs_guts.h yaffsinterface.h yportenv.h yaffs_tagscompat.c yaffs_tagscompat.h \ +YAFFSSYMLINKS = devextras.h yaffs_ecc.c yaffs_ecc.h yaffs_guts.c yaffs_guts.h yaffsinterface.h yportenv.h yaffs_tagscompat.c yaffs_tagscompat.h \ yaffs_packedtags1.c yaffs_packedtags1.h yaffs_packedtags2.c yaffs_packedtags2.h yaffs_nandemul2k.h \ - yaffs_nand.c yaffs_nand.h yaffs_getblockinfo.h \ + yaffs_nand.c yaffs_nand.h yaffs_getblockinfo.h yaffs_list.h \ yaffs_tagsvalidity.c yaffs_tagsvalidity.h yaffs_checkptrw.h yaffs_checkptrw.c \ - yaffs_nameval.h yaffs_nameval.c \ + yaffs_nameval.c yaffs_nameval.h \ yaffs_qsort.c yaffs_qsort.h yaffs_trace.h \ yaffs_allocator.c yaffs_allocator.h \ - yaffs_bitmap.c yaffs_bitmap.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 -#all: directtest2k boottest +YAFFSDIRECTSYMLINKS = yaffsfs.c yaffs_flashif.h yaffs_flashif2.h\ + yaffsfs.h yaffs_malloc.h ydirectenv.h \ + yaffs_flashif.c \ + yaffs_nandif.c yaffs_nandif.h + -all: directtest2k + +SYMLINKS = $(YAFFSSYMLINKS) $(YAFFSDIRECTSYMLINKS) + + + + +COMMONTESTOBJS = yaffsnewcfg.o yramsim.o \ + yaffsfs.o yaffs_guts.o yaffs_ecc.o yaffs_nandif.o \ + yaffs_packedtags1.o yaffs_ramdisk.o yaffs_ramem2k.o \ + yaffs_tagscompat.o yaffs_packedtags2.o yaffs_tagsvalidity.o yaffs_nand.o \ + yaffs_checkptrw.o yaffs_qsort.o\ + yaffs_nameval.o \ + yaffs_norif1.o ynorsim.o \ + yaffs_allocator.o yaffs_yaffs1.o \ + yaffs_yaffs2.o \ + yaffs_bitmap.o yaffs_verify.o + +# yaffs_checkptrwtest.o\ + +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 $@ $< -$(SYMLINKS): + +$(YAFFSSYMLINKS): + ln -s ../../$@ $@ + +$(YAFFSDIRECTSYMLINKS): ln -s ../$@ $@ + directtest2k: $(SYMLINKS) $(DIRECTTESTOBJS) gcc -o $@ $(DIRECTTESTOBJS) @@ -83,4 +117,4 @@ boottest: $(SYMLINKS) $(BOOTTESTOBJS) clean: - rm -f $(ALLOBJS) core core $(SYMLINKS) + rm -f $(TARGETS) $(ALLOBJS) core core $(SYMLINKS) diff --git a/direct/dtest.c b/direct/basic-test/dtest.c index 34112c8..34112c8 100644 --- a/direct/dtest.c +++ b/direct/basic-test/dtest.c diff --git a/direct/yaffs_fileem.c b/direct/basic-test/yaffs_fileem.c index 90c8f9e..90c8f9e 100644 --- a/direct/yaffs_fileem.c +++ b/direct/basic-test/yaffs_fileem.c diff --git a/direct/yaffs_fileem2k.c b/direct/basic-test/yaffs_fileem2k.c index 84b7eb8..84b7eb8 100644 --- a/direct/yaffs_fileem2k.c +++ b/direct/basic-test/yaffs_fileem2k.c diff --git a/direct/yaffs_fileem2k.h b/direct/basic-test/yaffs_fileem2k.h index 2b6f6e9..2b6f6e9 100644 --- a/direct/yaffs_fileem2k.h +++ b/direct/basic-test/yaffs_fileem2k.h diff --git a/direct/yaffs_norif1.c b/direct/basic-test/yaffs_norif1.c index ab582b0..ff86747 100644 --- a/direct/yaffs_norif1.c +++ b/direct/basic-test/yaffs_norif1.c @@ -91,6 +91,7 @@ const char *yaffs_norif1_c_version = "$Id: yaffs_norif1.c,v 1.6 2010-02-18 01:18 __u32 *Block2Addr(yaffs_Device *dev, int blockNumber) { __u32 addr; + dev=dev; addr = (__u32) DEVICE_BASE; addr += blockNumber * BLOCK_SIZE_IN_BYTES; @@ -101,7 +102,7 @@ __u32 *Block2Addr(yaffs_Device *dev, int blockNumber) __u32 *Block2FormatAddr(yaffs_Device *dev,int blockNumber) { __u32 addr; - + addr = (__u32) Block2Addr(dev,blockNumber); addr += FORMAT_OFFSET; @@ -301,7 +302,7 @@ int ynorif1_InitialiseNAND(yaffs_Device *dev) int ynorif1_DeinitialiseNAND(yaffs_Device *dev) { - + dev=dev; ynorif1_FlashDeinit(); return YAFFS_OK; diff --git a/direct/yaffs_norif1.h b/direct/basic-test/yaffs_norif1.h index 2ab11d2..2ab11d2 100644 --- a/direct/yaffs_norif1.h +++ b/direct/basic-test/yaffs_norif1.h diff --git a/direct/yaffs_ramdisk.c b/direct/basic-test/yaffs_ramdisk.c index d44c3da..d44c3da 100644 --- a/direct/yaffs_ramdisk.c +++ b/direct/basic-test/yaffs_ramdisk.c diff --git a/direct/yaffs_ramdisk.h b/direct/basic-test/yaffs_ramdisk.h index 57af69a..57af69a 100644 --- a/direct/yaffs_ramdisk.h +++ b/direct/basic-test/yaffs_ramdisk.h diff --git a/direct/yaffs_ramem2k.c b/direct/basic-test/yaffs_ramem2k.c index b3a8724..b3a8724 100644 --- a/direct/yaffs_ramem2k.c +++ b/direct/basic-test/yaffs_ramem2k.c diff --git a/direct/yaffscfg.c b/direct/basic-test/yaffscfg.c index 0d83c65..a235bb2 100644 --- a/direct/yaffscfg.c +++ b/direct/basic-test/yaffscfg.c @@ -22,6 +22,9 @@ #include "yaffsfs.h" #include <errno.h> + +#include "yramsim.h" + unsigned yaffs_traceMask = 0xFFFFFFFF; @@ -90,6 +93,9 @@ int yaffs_StartUp(void) // Stuff to initialise anything special (eg lock semaphore). yaffsfs_LocalInitialisation(); +#if 1 + yramsim_CreateSim("yaffs2"); +#else // Set up devices // /ram @@ -135,6 +141,7 @@ int yaffs_StartUp(void) flashDev.initialiseNAND = yflash_InitialiseNAND; yaffs_initialise(yaffsfs_config); +#endif return 0; } diff --git a/direct/yaffscfg.h b/direct/basic-test/yaffscfg.h index 29417c2..a14797f 100644 --- a/direct/yaffscfg.h +++ b/direct/basic-test/yaffscfg.h @@ -24,6 +24,7 @@ #include "yportenv.h" +#include "devextras.h" #define YAFFSFS_N_HANDLES 100 diff --git a/direct/yaffscfg2k.c b/direct/basic-test/yaffscfg2k.c index bfea4f3..b4a4590 100644 --- a/direct/yaffscfg2k.c +++ b/direct/basic-test/yaffscfg2k.c @@ -19,12 +19,14 @@ */ #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 <errno.h> unsigned yaffs_traceMask = @@ -104,20 +106,9 @@ void yaffsfs_LocalInitialisation(void) #include "yaffs_flashif2.h" #include "yaffs_nandemul2k.h" -static yaffs_Device ram1Dev; -static yaffs_Device flashDev; -static yaffs_Device ram2kDev; -static yaffs_Device m18_1Dev; - -static yaffsfs_DeviceConfiguration yaffsfs_config[] = { - - { "/ram1", &ram1Dev}, - { "/M18-1", &m18_1Dev}, - { "/yaffs2", &flashDev}, - { "/ram2k", &ram2kDev}, - { NULL, NULL } /* Null entry to terminate list */ -}; - +struct yaffs_DeviceStruct ram1Dev; +struct yaffs_DeviceStruct flashDev; +struct yaffs_DeviceStruct m18_1Dev; int yaffs_StartUp(void) { @@ -128,6 +119,7 @@ int yaffs_StartUp(void) // Set up devices // /ram1 ram, yaffs1 memset(&ram1Dev,0,sizeof(ram1Dev)); + ram1Dev.param.name = "ram1"; ram1Dev.param.totalBytesPerChunk = 512; ram1Dev.param.nChunksPerBlock = 32; ram1Dev.param.nReservedBlocks = 2; // Set this smaller for RAM @@ -135,14 +127,17 @@ int yaffs_StartUp(void) ram1Dev.param.endBlock = 127; // Last block in 2MB. //ram1Dev.param.useNANDECC = 1; ram1Dev.param.nShortOpCaches = 0; // Disable caching on this device. - ram1Dev.context = (void *) 0; // Used to identify the device in fstat. + ram1Dev.driverContext = (void *) 0; // Used to identify the device in fstat. ram1Dev.param.writeChunkWithTagsToNAND = yramdisk_WriteChunkWithTagsToNAND; ram1Dev.param.readChunkWithTagsFromNAND = yramdisk_ReadChunkWithTagsFromNAND; ram1Dev.param.eraseBlockInNAND = yramdisk_EraseBlockInNAND; ram1Dev.param.initialiseNAND = yramdisk_InitialiseNAND; + + yaffs_AddDevice(&ram1Dev); // /M18-1 yaffs1 on M18 nor sim memset(&m18_1Dev,0,sizeof(m18_1Dev)); + m18_1Dev.param.name = "M18-1"; m18_1Dev.param.totalBytesPerChunk = 1024; m18_1Dev.param.nChunksPerBlock =248; m18_1Dev.param.nReservedBlocks = 2; @@ -150,19 +145,20 @@ int yaffs_StartUp(void) m18_1Dev.param.endBlock = 31; // Last block m18_1Dev.param.useNANDECC = 0; // use YAFFS's ECC m18_1Dev.param.nShortOpCaches = 10; // Use caches - m18_1Dev.context = (void *) 1; // Used to identify the device in fstat. + m18_1Dev.driverContext = (void *) 1; // Used to identify the device in fstat. m18_1Dev.param.writeChunkToNAND = ynorif1_WriteChunkToNAND; m18_1Dev.param.readChunkFromNAND = ynorif1_ReadChunkFromNAND; m18_1Dev.param.eraseBlockInNAND = ynorif1_EraseBlockInNAND; m18_1Dev.param.initialiseNAND = ynorif1_InitialiseNAND; m18_1Dev.param.deinitialiseNAND = ynorif1_DeinitialiseNAND; + yaffs_AddDevice(&m18_1Dev); // /yaffs2 yaffs2 file emulation // 2kpage/64chunk per block // memset(&flashDev,0,sizeof(flashDev)); - + flashDev.param.name = "yaffs2"; flashDev.param.totalBytesPerChunk = 2048; flashDev.param.nChunksPerBlock = 64; flashDev.param.nReservedBlocks = 5; @@ -174,7 +170,7 @@ int yaffs_StartUp(void) flashDev.param.wideTnodesDisabled=0; flashDev.param.refreshPeriod = 1000; flashDev.param.nShortOpCaches = 10; // Use caches - flashDev.context = (void *) 2; // Used to identify the device in fstat. + flashDev.driverContext = (void *) 2; // Used to identify the device in fstat. flashDev.param.writeChunkWithTagsToNAND = yflash2_WriteChunkWithTagsToNAND; flashDev.param.readChunkWithTagsFromNAND = yflash2_ReadChunkWithTagsFromNAND; flashDev.param.eraseBlockInNAND = yflash2_EraseBlockInNAND; @@ -183,8 +179,9 @@ int yaffs_StartUp(void) flashDev.param.queryNANDBlock = yflash2_QueryNANDBlock; flashDev.param.enableXattr = 1; + yaffs_AddDevice(&flashDev); - yaffs_initialise(yaffsfs_config); +// todo yaffs_initialise(yaffsfs_config); return 0; } diff --git a/direct/basic-test/yaffsnewcfg.c b/direct/basic-test/yaffsnewcfg.c new file mode 100644 index 0000000..6f1a9e4 --- /dev/null +++ b/direct/basic-test/yaffsnewcfg.c @@ -0,0 +1,112 @@ +/* + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. + * + * Copyright (C) 2002-2010 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 "yaffsfs.h" +#include "yaffs_trace.h" +#include "yramsim.h" + +unsigned yaffs_traceMask = + + 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; + + +static int yaffsfs_lastError; + +void yaffsfs_SetError(int err) +{ + //Do whatever to set error + yaffsfs_lastError = err; +} + + +int yaffsfs_GetLastError(void) +{ + return yaffsfs_lastError; +} + +void yaffsfs_Lock(void) +{ +} + +void yaffsfs_Unlock(void) +{ +} + +__u32 yaffsfs_CurrentTime(void) +{ + return 0; +} + + +static int yaffs_kill_alloc = 0; +static size_t total_malloced = 0; +static size_t malloc_limit = 0 & 6000000; + +void *yaffs_malloc(size_t size) +{ + void * this; + if(yaffs_kill_alloc) + return NULL; + if(malloc_limit && malloc_limit <(total_malloced + size) ) + return NULL; + + this = malloc(size); + if(this) + total_malloced += size; + return this; +} + +void yaffs_free(void *ptr) +{ + free(ptr); +} + +void yaffsfs_LocalInitialisation(void) +{ + // Define locking semaphore. +} + +// Configuration + + +int yaffs_StartUp(void) +{ + // Stuff to configure YAFFS + // Stuff to initialise anything special (eg lock semaphore). + yaffsfs_LocalInitialisation(); + + yramsim_CreateSim("yaffs2",200); + yramsim_CreateSim("yaffs2-2",50); + + return 0; +} + + + diff --git a/direct/ynorsim.c b/direct/basic-test/ynorsim.c index 0c691a6..0c691a6 100644 --- a/direct/ynorsim.c +++ b/direct/basic-test/ynorsim.c diff --git a/direct/ynorsim.h b/direct/basic-test/ynorsim.h index 2c70ad9..2c70ad9 100644 --- a/direct/ynorsim.h +++ b/direct/basic-test/ynorsim.h diff --git a/direct/basic-test/yramsim.c b/direct/basic-test/yramsim.c new file mode 100644 index 0000000..a791791 --- /dev/null +++ b/direct/basic-test/yramsim.c @@ -0,0 +1,277 @@ +// NAND Simulator for testing YAFFS
+
+#include <string.h>
+
+#include "yramsim.h"
+
+#include "yaffs_nandif.h"
+
+
+#ifdef __WINCE__
+#include <windows.h>
+#else
+#define DebugBreak() do { } while(0)
+#endif
+
+
+#define DATA_SIZE 2048
+#define SPARE_SIZE 64
+#define PAGE_SIZE (DATA_SIZE + SPARE_SIZE)
+#define PAGES_PER_BLOCK 64
+
+
+typedef struct {
+ unsigned char page[PAGES_PER_BLOCK][PAGE_SIZE];
+ unsigned blockOk;
+} Block;
+
+typedef struct {
+ Block **blockList;
+ int nBlocks;
+} SymData;
+
+
+static SymData *DevToSym(yaffs_Device *dev)
+{
+ ynandif_Geometry *geom = (ynandif_Geometry *)(dev->driverContext);
+ SymData * sym = (SymData*)(geom->privateData);
+ return sym;
+}
+
+
+static void CheckInitialised(void)
+{
+
+}
+
+static int yramsim_EraseBlockInternal(SymData *sym, unsigned blockId,int force)
+{
+ if(blockId < 0 || blockId >= sym->nBlocks){
+ DebugBreak();
+ return 0;
+ }
+
+ if(!sym->blockList[blockId]){
+ DebugBreak();
+ return 0;
+ }
+
+ if(!force && !sym->blockList[blockId]->blockOk){
+ DebugBreak();
+ return 0;
+ }
+
+ memset(sym->blockList[blockId],0xff,sizeof(Block));
+ sym->blockList[blockId]->blockOk = 1;
+
+ return 1;
+}
+
+
+
+
+static int yramsim_Initialise(yaffs_Device *dev)
+{
+ SymData *sym = DevToSym(dev);
+ Block **blockList = sym->blockList;
+ return blockList != NULL;
+}
+
+
+static int yramsim_Deinitialise(yaffs_Device *dev)
+{
+ return 1;
+}
+
+static int yramsim_ReadChunk (yaffs_Device *dev, unsigned pageId,
+ unsigned char *data, unsigned dataLength,
+ unsigned char *spare, unsigned spareLength,
+ int *eccStatus)
+{
+ SymData *sym = DevToSym(dev);
+ Block **blockList = sym->blockList;
+
+ unsigned blockId = pageId / PAGES_PER_BLOCK;
+ unsigned pageOffset = pageId % PAGES_PER_BLOCK;
+ unsigned char * d;
+ unsigned char *s;
+ if(blockId >= sym->nBlocks ||
+ pageOffset >= PAGES_PER_BLOCK ||
+ dataLength >DATA_SIZE ||
+ spareLength > SPARE_SIZE ||
+ !eccStatus ||
+ !blockList[blockId]->blockOk){
+ DebugBreak();
+ return 0;
+ }
+
+ d = blockList[blockId]->page[pageOffset];
+ s = d + DATA_SIZE;
+
+ if(data)
+ memcpy(data,d,dataLength);
+
+ if(spare)
+ memcpy(spare,s,spareLength);
+
+ *eccStatus = 0; // 0 = no error, -1 = unfixable error, 1 = fixable
+
+ return 1;
+
+}
+
+static int yramsim_WriteChunk (yaffs_Device *dev,unsigned pageId,
+ const unsigned char *data, unsigned dataLength,
+ const unsigned char *spare, unsigned spareLength)
+{
+ SymData *sym = DevToSym(dev);
+ Block **blockList = sym->blockList;
+
+ unsigned blockId = pageId / PAGES_PER_BLOCK;
+ unsigned pageOffset = pageId % PAGES_PER_BLOCK;
+ unsigned char * d;
+ unsigned char *s;
+ if(blockId >= sym->nBlocks ||
+ pageOffset >= PAGES_PER_BLOCK ||
+ dataLength >DATA_SIZE ||
+ spareLength > SPARE_SIZE ||
+ !blockList[blockId]->blockOk){
+ DebugBreak();
+ return 0;
+ }
+
+ d = blockList[blockId]->page[pageOffset];
+ s = d + DATA_SIZE;
+
+ if(data)
+ memcpy(d,data,dataLength);
+
+ if(spare)
+ memcpy(s,spare,spareLength);
+
+ return 1;
+
+}
+
+
+static int yramsim_EraseBlock(yaffs_Device *dev,unsigned blockId)
+{
+ SymData *sym = DevToSym(dev);
+
+ CheckInitialised();
+ return yramsim_EraseBlockInternal(sym,blockId,0);
+}
+
+static int yramsim_CheckBlockOk(yaffs_Device *dev,unsigned blockId)
+{
+ SymData *sym = DevToSym(dev);
+ Block **blockList = sym->blockList;
+ if(blockId >= sym->nBlocks){
+ DebugBreak();
+ return 0;
+ }
+
+ return blockList[blockId]->blockOk ? 1 : 0;
+}
+
+static int yramsim_MarkBlockBad(yaffs_Device *dev,unsigned blockId)
+{
+ SymData *sym = DevToSym(dev);
+ Block **blockList = sym->blockList;
+ if(blockId >= sym->nBlocks){
+ DebugBreak();
+ return 0;
+ }
+
+ blockList[blockId]->blockOk = 0;
+
+ return 1;
+}
+
+
+static SymData *yramsim_AllocSymData(int nBlocks)
+{
+ int ok = 1;
+
+ Block **blockList;
+ SymData *sym;
+ Block *b;
+ int i;
+
+ sym = malloc(sizeof (SymData));
+ if(!sym)
+ return NULL;
+
+ blockList = malloc(nBlocks * sizeof(Block *));
+
+ sym->blockList = blockList;
+ sym->nBlocks = nBlocks;
+ if(!blockList){
+ free(sym);
+ return NULL;
+ }
+
+ for(i = 0; i < nBlocks; i++)
+ blockList[i] = NULL;
+
+ for(i = 0; i < nBlocks && ok; i++){
+ b= malloc(sizeof(Block));
+ if(b){
+ blockList[i] = b;
+ yramsim_EraseBlockInternal(sym,i,1);
+ }
+ else
+ ok = 0;
+ }
+
+ if(!ok){
+ for(i = 0; i < nBlocks; i++)
+ if(blockList[i]){
+ free(blockList[i]);
+ blockList[i] = NULL;
+ }
+ free(blockList);
+ blockList = NULL;
+ free(sym);
+ sym = NULL;
+ }
+
+ return sym;
+}
+
+
+struct yaffs_DeviceStruct *yramsim_CreateSim(const YCHAR *name,int nBlocks)
+{
+ void *sym = (void *)yramsim_AllocSymData(nBlocks);
+ ynandif_Geometry *g;
+
+ g = YMALLOC(sizeof(ynandif_Geometry));
+
+ if(!sym || !g){
+ if(sym)
+ YFREE(sym);
+ if(g)
+ YFREE(g);
+ return NULL;
+ }
+
+ memset(g,0,sizeof(ynandif_Geometry));
+ g->startBlock = 0;
+ g->endBlock = nBlocks - 1;
+ g->dataSize = DATA_SIZE;
+ g->spareSize= SPARE_SIZE;
+ g->pagesPerBlock = PAGES_PER_BLOCK;
+ g->hasECC = 1;
+ g->inbandTags = 0;
+ g->useYaffs2 = 1;
+ g->initialise = yramsim_Initialise;
+ g->deinitialise = yramsim_Deinitialise;
+ g->readChunk = yramsim_ReadChunk,
+ g->writeChunk = yramsim_WriteChunk,
+ g->eraseBlock = yramsim_EraseBlock,
+ g->checkBlockOk = yramsim_CheckBlockOk,
+ g->markBlockBad = yramsim_MarkBlockBad,
+ g->privateData = sym;
+
+ return yaffs_AddDeviceFromGeometry(name,g);
+} diff --git a/direct/basic-test/yramsim.h b/direct/basic-test/yramsim.h new file mode 100644 index 0000000..694ceaf --- /dev/null +++ b/direct/basic-test/yramsim.h @@ -0,0 +1,11 @@ +// NAND Simulator for testing YAFFS
+#ifndef __YAFF_RAM_SIM_H__
+#define __YAFF_RAM_SIM_H__
+
+
+#include "yaffs_guts.h"
+
+struct yaffs_DeviceStruct *yramsim_CreateSim(const YCHAR *name, int nBlocks);
+
+
+#endif
diff --git a/direct/python/Makefile b/direct/python/Makefile index 3c952ee..2f4e5cd 100644 --- a/direct/python/Makefile +++ b/direct/python/Makefile @@ -29,7 +29,9 @@ CFLAGS += -O0 #CFLAGS+= -Wmissing-prototypes -Wredundant-decls -Wnested-externs -Winline -COMMONTESTOBJS = yaffscfg2k.o yaffs_ecc.o yaffs_fileem.o yaffs_fileem2k.o yaffsfs.o yaffs_guts.o \ +COMMONTESTOBJS = yaffsnewcfg.o yramsim.o \ + yaffs_nandif.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_tagsvalidity.o yaffs_nand.o \ yaffs_checkptrw.o yaffs_qsort.o\ @@ -47,7 +49,7 @@ YAFFSLIBOBJS = $(COMMONTESTOBJS) yaffs_python_helper.o YAFFSSYMLINKS = devextras.h yaffs_ecc.c yaffs_ecc.h yaffs_guts.c yaffs_guts.h yaffsinterface.h yportenv.h yaffs_tagscompat.c yaffs_tagscompat.h \ yaffs_packedtags1.c yaffs_packedtags1.h yaffs_packedtags2.c yaffs_packedtags2.h yaffs_nandemul2k.h \ - yaffs_nand.c yaffs_nand.h yaffs_getblockinfo.h \ + yaffs_nand.c yaffs_nand.h yaffs_getblockinfo.h yaffs_list.h \ yaffs_tagsvalidity.c yaffs_tagsvalidity.h yaffs_checkptrw.h yaffs_checkptrw.c \ yaffs_nameval.c yaffs_nameval.h \ yaffs_qsort.c yaffs_qsort.h yaffs_trace.h \ @@ -58,14 +60,17 @@ YAFFSSYMLINKS = devextras.h yaffs_ecc.c yaffs_ecc.h yaffs_guts.c yaffs_guts.h ya yaffs_verify.c yaffs_verify.h -YAFFSDIRECTSYMLINKS = yaffscfg2k.c yaffs_fileem2k.c yaffsfs.c yaffs_flashif.h yaffs_flashif2.h\ - yaffs_fileem2k.h yaffsfs.h yaffs_malloc.h yaffs_ramdisk.h ydirectenv.h \ - yaffscfg.h yaffs_fileem.c yaffs_flashif.c yaffs_ramdisk.c yaffs_ramem2k.c\ - yaffs_norif1.c yaffs_norif1.h ynorsim.c ynorsim.h \ +YAFFSDIRECTSYMLINKS = yaffsfs.c yaffsfs.h yaffs_malloc.h ydirectenv.h \ + yaffs_flashif.c yaffs_flashif.h\ yaffs_nandif.c yaffs_nandif.h - -SYMLINKS = $(YAFFSSYMLINKS) $(YAFFSDIRECTSYMLINKS) +DIRECTEXTRASYMLINKS = yaffscfg2k.c yaffscfg.h 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 + +SYMLINKS = $(YAFFSSYMLINKS) $(YAFFSDIRECTSYMLINKS) $(DIRECTEXTRASYMLINKS) all: libyaffsfs.so @@ -80,6 +85,8 @@ $(YAFFSSYMLINKS): $(YAFFSDIRECTSYMLINKS): ln -s ../$@ $@ +$(DIRECTEXTRASYMLINKS): + ln -s ../basic-test/$@ $@ libyaffsfs.so: $(SYMLINKS) $(YAFFSLIBOBJS) @@ -89,6 +96,6 @@ libyaffsfs.so: $(SYMLINKS) $(YAFFSLIBOBJS) clean: - rm -f $(YAFFSLIBOBJS) core $(YAFFSSYMLINKS) $(YAFFSDIRECTSYMLINKS) + rm -f $(YAFFSLIBOBJS) core $(SYMLINKS) rm -f libyaffsfs.so rm -f *.pyc diff --git a/direct/tests/Makefile b/direct/tests/Makefile index 4b92592..e750571 100644 --- a/direct/tests/Makefile +++ b/direct/tests/Makefile @@ -19,7 +19,7 @@ #EXTRA_COMPILE_FLAGS = -DYAFFS_IGNORE_TAGS_ECC CFLAGS = -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_YAFFS2 -CFLAGS += -DCONFIG_YAFFS_PROVIDE_DEFS -DCONFIG_YAFFSFS_PROVIDE_VALUES -DNO_Y_INLINE +CFLAGS += -DCONFIG_YAFFS_PROVIDE_DEFS -DCONFIG_YAFFSFS_PROVIDE_VALUES CFLAGS += -Wall -g $(EXTRA_COMPILE_FLAGS) -Wstrict-aliasing #CFLAGS += -fno-strict-aliasing CFLAGS += -O0 @@ -47,13 +47,11 @@ COMMONTESTOBJS = yaffscfg2k.o yaffs_ecc.o yaffs_fileem.o yaffs_fileem2k.o yaffsf YAFFSTESTOBJS = $(COMMONTESTOBJS) yaffs_test.o -#ALLOBJS = dtest.o nand_ecc.o yaffscfg.o yaffs_fileem.o yaffsfs.o yaffs_ramdisk.o bootldtst.o yboot.o yaffs_ramem2k.o - ALLOBJS = $(sort $(YAFFSTESTOBJS)) YAFFSSYMLINKS = devextras.h yaffs_ecc.c yaffs_ecc.h yaffs_guts.c yaffs_guts.h yaffsinterface.h yportenv.h yaffs_tagscompat.c yaffs_tagscompat.h \ yaffs_packedtags1.c yaffs_packedtags1.h yaffs_packedtags2.c yaffs_packedtags2.h yaffs_nandemul2k.h \ - yaffs_nand.c yaffs_nand.h yaffs_getblockinfo.h \ + yaffs_nand.c yaffs_nand.h yaffs_getblockinfo.h yaffs_list.h \ yaffs_tagsvalidity.c yaffs_tagsvalidity.h yaffs_checkptrw.h yaffs_checkptrw.c \ yaffs_nameval.c yaffs_nameval.h \ yaffs_qsort.c yaffs_qsort.h yaffs_trace.h \ @@ -63,14 +61,18 @@ YAFFSSYMLINKS = devextras.h yaffs_ecc.c yaffs_ecc.h yaffs_guts.c yaffs_guts.h ya yaffs_bitmap.c yaffs_bitmap.h \ yaffs_verify.c yaffs_verify.h -YAFFSDIRECTSYMLINKS = yaffscfg2k.c yaffs_fileem2k.c yaffsfs.c yaffs_flashif.h yaffs_flashif2.h\ - yaffs_fileem2k.h yaffsfs.h yaffs_malloc.h yaffs_ramdisk.h ydirectenv.h \ - yaffscfg.h yaffs_fileem.c yaffs_flashif.c yaffs_ramdisk.c yaffs_ramem2k.c\ - yaffs_norif1.c yaffs_norif1.h ynorsim.c ynorsim.h \ +YAFFSDIRECTSYMLINKS = yaffsfs.c yaffs_flashif.h yaffs_flashif2.h\ + yaffsfs.h yaffs_malloc.h ydirectenv.h \ + yaffs_flashif.c \ yaffs_nandif.c yaffs_nandif.h -SYMLINKS = $(YAFFSSYMLINKS) $(YAFFSDIRECTSYMLINKS) +DIRECTEXTRASYMLINKS = yaffscfg2k.c yaffscfg.h 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 + +SYMLINKS = $(YAFFSSYMLINKS) $(YAFFSDIRECTSYMLINKS) $(DIRECTEXTRASYMLINKS) #all: directtest2k boottest all: yaffs_test fuzzer @@ -85,6 +87,9 @@ $(YAFFSSYMLINKS): $(YAFFSDIRECTSYMLINKS): ln -s ../$@ $@ +$(DIRECTEXTRASYMLINKS): + ln -s ../basic-test/$@ $@ + yaffs_test: $(SYMLINKS) $(YAFFSTESTOBJS) gcc $(CFLLAG) -o $@ $(YAFFSTESTOBJS) @@ -97,4 +102,4 @@ fuzzer: fuzzer.c clean: - rm -f yaffs_test fuzzer fuzzer.o $(ALLOBJS) core $(YAFFSSYMLINKS) $(YAFFSDIRECTSYMLINKS) + rm -f yaffs_test fuzzer fuzzer.o $(ALLOBJS) core $(SYMLINKS) diff --git a/direct/yaffs_nandif.c b/direct/yaffs_nandif.c index 1d33685..6f36eb7 100644 --- a/direct/yaffs_nandif.c +++ b/direct/yaffs_nandif.c @@ -1,244 +1,257 @@ -/*
- * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
- *
- * Copyright (C) 2002-2010 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_guts.h"
-#include "devextras.h"
-
-
-#include "yaffs_nandif.h"
-#include "yaffs_packedtags2.h"
-
-
-#if 0
-
-
-static unsigned char *DevBufferIn(yaffs_Device *dev)
-{
- yfsd_WinCEDevice *cedev = (yfsd_WinCEDevice *)(dev->genericDevice);
- return cedev->bufferIn;
-}
-static unsigned char *DevBufferOut(yaffs_Device *dev)
-{
- yfsd_WinCEDevice *cedev = (yfsd_WinCEDevice *)(dev->genericDevice);
- return cedev->bufferOut;
-}
-
-static unsigned DevBufferSize(yaffs_Device *dev)
-{
- yfsd_WinCEDevice *cedev = (yfsd_WinCEDevice *)(dev->genericDevice);
- return cedev->bufferSize;
-}
-
-#endif
-
-/* NB For use with inband tags....
- * We assume that the data buffer is of size totalBytersPerChunk so that we can also
- * use it to load the tags.
- */
-int ynandif_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND,
- const __u8 * data,
- const yaffs_ExtendedTags * tags)
-{
-
- int retval = 0;
- yaffs_PackedTags2 pt;
- void *spare;
- unsigned spareSize = 0;
-
- unsigned char *bufferIn = DevBufferIn(dev);
- unsigned char *bufferOut = DevBufferOut(dev);
- unsigned bufferSize = DevBufferSize(dev);
-
- T(YAFFS_TRACE_MTD,
- (TSTR
- ("nandmtd2_WriteChunkWithTagsToNAND chunk %d data %p tags %p"
- TENDSTR), chunkInNAND, 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(dev->inbandTags){
- yaffs_PackedTags2TagsPart *pt2tp;
- pt2tp = (yaffs_PackedTags2TagsPart *)(data + dev->nDataBytesPerChunk);
- yaffs_PackTags2TagsPart(pt2tp,tags);
- spare = NULL;
- spareSize = 0;
- }
- else{
- yaffs_PackTags2(&pt, tags);
- spare = &pt;
- spareSize = sizeof(yaffs_PackedTags2);
- }
-
- yramsim_WritePage(chunkInNAND,
- data, dev->totalBytesPerChunk, spare, spareSize);
-
- return YAFFS_OK;
-}
-
-int ynandif_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
- __u8 * data, yaffs_ExtendedTags * tags)
-{
- yaffs_PackedTags2 pt;
- int localData = 0;
- void *spare = NULL;
- unsigned spareSize;
- int eccStatus; //0 = ok, 1 = fixed, -1 = unfixed
-
- unsigned char *bufferIn = DevBufferIn(dev);
- unsigned char *bufferOut = DevBufferOut(dev);
- unsigned bufferSize = DevBufferSize(dev);
-
- T(YAFFS_TRACE_MTD,
- (TSTR
- ("nandmtd2_ReadChunkWithTagsFromNAND chunk %d data %p tags %p"
- TENDSTR), chunkInNAND, data, tags));
-
- if(!tags){
- spare = NULL;
- spareSize = 0;
- }else if(dev->inbandTags){
-
- if(!data) {
- localData = 1;
- data = yaffs_GetTempBuffer(dev,__LINE__);
- }
- spare = NULL;
- spareSize = 0;
- }
- else {
- spare = &pt;
- spareSize = sizeof(yaffs_PackedTags2);
- }
-
- yramsim_ReadPage(chunkInNAND,
- data,data ? dev->totalBytesPerChunk : 0,
- spare,spareSize,
- &eccStatus);
-
-
-
- if(dev->inbandTags){
- if(tags){
- yaffs_PackedTags2TagsPart * pt2tp;
- pt2tp = (yaffs_PackedTags2TagsPart *)&data[dev->nDataBytesPerChunk];
- yaffs_UnpackTags2TagsPart(tags,pt2tp);
- }
- }
- else {
- if (tags){
- yaffs_UnpackTags2(tags, &pt);
- }
- }
-
- if(tags && tags->chunkUsed){
- if(eccStatus == 0)
- tags->eccResult = YAFFS_ECC_RESULT_NO_ERROR;
- else if(eccStatus < 0)
- tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
- else
- tags->eccResult = YAFFS_ECC_RESULT_FIXED;
- }
-
- if(localData)
- yaffs_ReleaseTempBuffer(dev,data,__LINE__);
-
- return YAFFS_OK;
-}
-
-int ynandif_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockId)
-{
-
- yramsim_MarkBlockBad(blockId);
-
- return YAFFS_OK;
-}
-
-int ynandif_EraseBlockInNAND(struct yaffs_DeviceStruct *dev, int blockId)
-{
-
- yramsim_EraseBlock(blockId);
-
- return YAFFS_OK;
-}
-
-
-static int ynandif_IsBlockOk(struct yaffs_DeviceStruct *dev, int blockId)
-{
- return yramsim_CheckBlockOk(blockId);
-}
-
-int ynandif_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockId, yaffs_BlockState *state, __u32 *sequenceNumber)
-{
- unsigned chunkNo;
- yaffs_ExtendedTags tags;
-
- *sequenceNumber = 0;
-
- chunkNo = blockId * dev->nChunksPerBlock;
-
- if(!ynandif_IsBlockOk(dev,blockId)){
- *state = YAFFS_BLOCK_STATE_DEAD;
- }
- else
- {
- ynandif_ReadChunkWithTagsFromNAND(dev,chunkNo,NULL,&tags);
-
- if(!tags.chunkUsed)
- {
- *state = YAFFS_BLOCK_STATE_EMPTY;
- }
- else
- {
- *state = YAFFS_BLOCK_STATE_NEEDS_SCANNING;
- *sequenceNumber = tags.sequenceNumber;
- }
- }
-
- return YAFFS_OK;
-}
-
-
-int ynandif_GetGeometry(yaffs_Device *dev, ynandif_Geometry *geometry)
-{
-
- yramsim_Geometry g;
-
- yramsim_GetGeometry(&g);
- geometry->startBlock = g.startBlock;
- geometry->endBlock = g.endBlock;
- geometry->dataSize = g.dataSize;
- geometry->spareSize = g.spareSize;
- geometry->pagesPerBlock = g.pagesPerBlock;
- geometry->hasECC = g.hasECC;
- geometry->inbandTags = g.inbandTags;
- geometry->useYaffs2 = g.useYaffs2;
-
- return YAFFS_OK;
-
-}
-
-int ynandif_InitialiseNAND(yaffs_Device *dev)
-{
-
- yramsim_Initialise();
-
- return YAFFS_OK;
-}
+/* + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. + * + * Copyright (C) 2002-2007 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_guts.h" +#include "devextras.h" + + +#include "yaffs_nandif.h" +#include "yaffs_packedtags2.h" + +#include "yramsim.h" + +#include "yaffs_trace.h" + + + +/* NB For use with inband tags.... + * We assume that the data buffer is of size totalBytersPerChunk so that we can also + * use it to load the tags. + */ +int ynandif_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND, + const __u8 * data, + const yaffs_ExtendedTags * tags) +{ + + int retval = 0; + yaffs_PackedTags2 pt; + void *spare; + unsigned spareSize = 0; + ynandif_Geometry *geometry = (ynandif_Geometry *)(dev->driverContext); + + T(YAFFS_TRACE_MTD, + (TSTR + ("nandmtd2_WriteChunkWithTagsToNAND chunk %d data %p tags %p" + TENDSTR), chunkInNAND, 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(dev->param.inbandTags){ + yaffs_PackedTags2TagsPart *pt2tp; + pt2tp = (yaffs_PackedTags2TagsPart *)(data + dev->nDataBytesPerChunk); + yaffs_PackTags2TagsPart(pt2tp,tags); + spare = NULL; + spareSize = 0; + } + else{ + yaffs_PackTags2(&pt, tags,!dev->param.noTagsECC); + spare = &pt; + spareSize = sizeof(yaffs_PackedTags2); + } + + retval = geometry->writeChunk(dev,chunkInNAND, + data, dev->param.totalBytesPerChunk, spare, spareSize); + + return retval; +} + +int ynandif_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND, + __u8 * data, yaffs_ExtendedTags * tags) +{ + yaffs_PackedTags2 pt; + int localData = 0; + void *spare = NULL; + unsigned spareSize; + int retval = 0; + int eccStatus; //0 = ok, 1 = fixed, -1 = unfixed + ynandif_Geometry *geometry = (ynandif_Geometry *)(dev->driverContext); + + T(YAFFS_TRACE_MTD, + (TSTR + ("nandmtd2_ReadChunkWithTagsFromNAND chunk %d data %p tags %p" + TENDSTR), chunkInNAND, data, tags)); + + if(!tags){ + spare = NULL; + spareSize = 0; + }else if(dev->param.inbandTags){ + + if(!data) { + localData = 1; + data = yaffs_GetTempBuffer(dev,__LINE__); + } + spare = NULL; + spareSize = 0; + } + else { + spare = &pt; + spareSize = sizeof(yaffs_PackedTags2); + } + + retval = geometry->readChunk(dev,chunkInNAND, + data, + data ? dev->param.totalBytesPerChunk : 0, + spare,spareSize, + &eccStatus); + + if(dev->param.inbandTags){ + if(tags){ + yaffs_PackedTags2TagsPart * pt2tp; + pt2tp = (yaffs_PackedTags2TagsPart *)&data[dev->nDataBytesPerChunk]; + yaffs_UnpackTags2TagsPart(tags,pt2tp); + } + } + else { + if (tags){ + yaffs_UnpackTags2(tags, &pt,!dev->param.noTagsECC); + } + } + + if(tags && tags->chunkUsed){ + if(eccStatus < 0 || + tags->eccResult == YAFFS_ECC_RESULT_UNFIXED) + tags->eccResult = YAFFS_ECC_RESULT_UNFIXED; + else if(eccStatus > 0 || + tags->eccResult == YAFFS_ECC_RESULT_FIXED) + tags->eccResult = YAFFS_ECC_RESULT_FIXED; + else + tags->eccResult = YAFFS_ECC_RESULT_NO_ERROR; + } + + if(localData) + yaffs_ReleaseTempBuffer(dev,data,__LINE__); + + return retval; +} + +int ynandif_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockId) +{ + ynandif_Geometry *geometry = (ynandif_Geometry *)(dev->driverContext); + + return geometry->markBlockBad(dev,blockId); +} + +int ynandif_EraseBlockInNAND(struct yaffs_DeviceStruct *dev, int blockId) +{ + ynandif_Geometry *geometry = (ynandif_Geometry *)(dev->driverContext); + + return geometry->eraseBlock(dev,blockId); + +} + + +static int ynandif_IsBlockOk(struct yaffs_DeviceStruct *dev, int blockId) +{ + ynandif_Geometry *geometry = (ynandif_Geometry *)(dev->driverContext); + + return geometry->checkBlockOk(dev,blockId); +} + +int ynandif_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockId, yaffs_BlockState *state, __u32 *sequenceNumber) +{ + unsigned chunkNo; + yaffs_ExtendedTags tags; + ynandif_Geometry *geometry = (ynandif_Geometry *)(dev->driverContext); + + *sequenceNumber = 0; + + chunkNo = blockId * dev->param.nChunksPerBlock; + + if(!ynandif_IsBlockOk(dev,blockId)){ + *state = YAFFS_BLOCK_STATE_DEAD; + } + else + { + ynandif_ReadChunkWithTagsFromNAND(dev,chunkNo,NULL,&tags); + + if(!tags.chunkUsed) + { + *state = YAFFS_BLOCK_STATE_EMPTY; + } + else + { + *state = YAFFS_BLOCK_STATE_NEEDS_SCANNING; + *sequenceNumber = tags.sequenceNumber; + } + } + + return YAFFS_OK; +} + + +int ynandif_InitialiseNAND(yaffs_Device *dev) +{ + ynandif_Geometry *geometry = (ynandif_Geometry *)(dev->driverContext); + + geometry->initialise(dev); + + return YAFFS_OK; +} + +int ynandif_DeinitialiseNAND(yaffs_Device *dev) +{ + ynandif_Geometry *geometry = (ynandif_Geometry *)(dev->driverContext); + + geometry->deinitialise(dev); + + return YAFFS_OK; +} + + +struct yaffs_DeviceStruct * + yaffs_AddDeviceFromGeometry(const YCHAR *name, + const ynandif_Geometry *geometry) +{ + YCHAR *clonedName = YMALLOC(sizeof(YCHAR) * (yaffs_strnlen(name,YAFFS_MAX_NAME_LENGTH)+1)); + struct yaffs_DeviceStruct *dev = YMALLOC(sizeof(struct yaffs_DeviceStruct)); + + if(dev && clonedName){ + memset(dev,0,sizeof(struct yaffs_DeviceStruct)); + yaffs_strcpy(clonedName,name); + + dev->param.name = clonedName; + dev->param.writeChunkWithTagsToNAND = ynandif_WriteChunkWithTagsToNAND; + dev->param.readChunkWithTagsFromNAND = ynandif_ReadChunkWithTagsFromNAND; + dev->param.eraseBlockInNAND = ynandif_EraseBlockInNAND; + dev->param.initialiseNAND = ynandif_InitialiseNAND; + dev->param.queryNANDBlock = ynandif_QueryNANDBlock; + dev->param.markNANDBlockBad = ynandif_MarkNANDBlockBad; + dev->param.nShortOpCaches = 20; + dev->param.startBlock = geometry->startBlock; + dev->param.endBlock = geometry->endBlock; + dev->param.totalBytesPerChunk = geometry->dataSize; + dev->param.spareBytesPerChunk = geometry->spareSize; + dev->param.inbandTags = geometry->inbandTags; + dev->param.nChunksPerBlock = geometry->pagesPerBlock; + dev->param.useNANDECC = geometry->hasECC; + dev->param.isYaffs2 = geometry->useYaffs2; + dev->param.nReservedBlocks = 5; + dev->driverContext = (void *)geometry; + + yaffs_AddDevice(dev); + + return dev; + } + + if(dev) + YFREE(dev); + if(clonedName) + YFREE(clonedName); + + return NULL; +} diff --git a/direct/yaffs_nandif.h b/direct/yaffs_nandif.h index f7a67dd..cf4562c 100644 --- a/direct/yaffs_nandif.h +++ b/direct/yaffs_nandif.h @@ -1,7 +1,7 @@ /* * YAFFS: Yet another Flash File System . A NAND-flash specific file system. * - * Copyright (C) 2002-2010 Aleph One Ltd. + * Copyright (C) 2002-2007 Aleph One Ltd. * for Toby Churchill Ltd and Brightstar Engineering * * Created by Charles Manning <charles@aleph1.co.uk> @@ -19,17 +19,47 @@ #include "yaffs_guts.h" + typedef struct { - unsigned startBlock; - unsigned endBlock; - unsigned dataSize; // Number of data bytes per page - unsigned spareSize; // Number of spare bytes per chunk - unsigned pagesPerBlock; - unsigned hasECC; - unsigned inbandTags; // Use inband tags on this device - unsigned useYaffs2; + unsigned startBlock; + unsigned endBlock; + unsigned dataSize; + unsigned spareSize; + unsigned pagesPerBlock; + unsigned hasECC; + unsigned inbandTags; + unsigned useYaffs2; + + int (*initialise)(yaffs_Device *dev); + int (*deinitialise)(yaffs_Device *dev); + + int (*readChunk) (yaffs_Device *dev, + unsigned pageId, + unsigned char *data, unsigned dataLength, + unsigned char *spare, unsigned spareLength, + int *eccStatus); +// ECC status is set to 0 for OK, 1 for fixed, -1 for unfixed. + + int (*writeChunk)(yaffs_Device *dev, + unsigned pageId, + const unsigned char *data, unsigned dataLength, + const unsigned char *spare, unsigned spareLength); + + int (*eraseBlock)(yaffs_Device *dev, unsigned blockId); + + int (*checkBlockOk)(yaffs_Device *dev, unsigned blockId); + int (*markBlockBad)(yaffs_Device *dev, unsigned blockId); + + void *privateData; + } ynandif_Geometry; +struct yaffs_DeviceStruct * + yaffs_AddDeviceFromGeometry(const YCHAR *name, + const ynandif_Geometry *geometry); + +#if 0 + int ynandif_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_ExtendedTags *tags); int ynandif_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_ExtendedTags *tags); int ynandif_EraseBlockInNAND(yaffs_Device *dev, int blockNumber); @@ -38,3 +68,6 @@ int ynandif_MarkNANDBlockBad(yaffs_Device *dev,int blockNumber); int ynandif_QueryNANDBlock(yaffs_Device *dev, int blockNo, yaffs_BlockState *state, __u32 *sequenceNumber); int ynandif_GetGeometry(yaffs_Device *dev, ynandif_Geometry *geometry); #endif + + +#endif diff --git a/direct/yaffsfs.c b/direct/yaffsfs.c index 041287c..9fc4417 100644 --- a/direct/yaffsfs.c +++ b/direct/yaffsfs.c @@ -30,13 +30,6 @@ #define YAFFSFS_RW_SHIFT (13) #define YAFFSFS_RW_SIZE (1<<YAFFSFS_RW_SHIFT) - -const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.35 2010-02-25 22:38:03 charles Exp $"; - -/* configurationList is the list of devices that are supported */ -static yaffsfs_DeviceConfiguration *yaffsfs_configurationList; - - /* Some forward references */ static yaffs_Object *yaffsfs_FindObject(yaffs_Object *relativeDirectory, const YCHAR *path, int symDepth); static void yaffsfs_RemoveObjectCallback(yaffs_Object *obj); @@ -264,6 +257,10 @@ int yaffsfs_IsPathDivider(YCHAR ch) return 0; } + + +YLIST_HEAD(yaffsfs_deviceList); + /* * yaffsfs_FindDevice * yaffsfs_FindRoot @@ -273,10 +270,11 @@ int yaffsfs_IsPathDivider(YCHAR ch) */ static yaffs_Device *yaffsfs_FindDevice(const YCHAR *path, YCHAR **restOfPath) { - yaffsfs_DeviceConfiguration *cfg = yaffsfs_configurationList; + struct ylist_head *cfg; const YCHAR *leftOver; const YCHAR *p; yaffs_Device *retval = NULL; + yaffs_Device *dev = NULL; int thisMatchLength; int longestMatch = -1; int matching; @@ -286,9 +284,10 @@ static yaffs_Device *yaffsfs_FindDevice(const YCHAR *path, YCHAR **restOfPath) * 1) Actually matches a prefix (ie /a amd /abc will not match * 2) Matches the longest. */ - while(cfg && cfg->prefix && cfg->dev){ + ylist_for_each(cfg, &yaffsfs_deviceList){ + dev = ylist_entry(cfg, yaffs_Device, devList); leftOver = path; - p = cfg->prefix; + p = dev->param.name; thisMatchLength = 0; matching = 1; @@ -319,16 +318,23 @@ static yaffs_Device *yaffsfs_FindDevice(const YCHAR *path, YCHAR **restOfPath) /* Skip over any /s in leftOver */ while(yaffsfs_IsPathDivider(*leftOver)) leftOver++; - - if( matching && (thisMatchLength > longestMatch)){ - /* Matched prefix */ + // Skip over any /s in p + while(yaffsfs_IsPathDivider(*p)) + p++; + + // p should now be at the end of the string (ie. fully matched) + if(*p) + matching = 0; + + if( matching && (thisMatchLength > longestMatch)) + { + // Matched prefix *restOfPath = (YCHAR *)leftOver; - retval = cfg->dev; + retval = dev; longestMatch = thisMatchLength; } - cfg++; } return retval; } @@ -1091,7 +1097,7 @@ static int yaffsfs_DoStat(yaffs_Object *obj,struct yaffs_stat *buf) obj = yaffs_GetEquivalentObject(obj); if(obj && buf){ - buf->st_dev = (int)obj->myDev->context; + buf->st_dev = (int)obj->myDev->osContext; buf->st_ino = obj->objectId; buf->st_mode = obj->yst_mode & ~S_IFMT; /* clear out file type bits */ @@ -1859,26 +1865,23 @@ int yaffs_inodecount(const YCHAR *path) } - -void yaffs_initialise(yaffsfs_DeviceConfiguration *cfgList) +void yaffs_AddDevice(yaffs_Device *dev) { + dev->isMounted = 0; + dev->param.removeObjectCallback = yaffsfs_RemoveObjectCallback; - yaffsfs_DeviceConfiguration *cfg; + if(!dev->devList.next) + YINIT_LIST_HEAD(&dev->devList); - yaffsfs_configurationList = cfgList; - - yaffsfs_InitHandles(); - - cfg = yaffsfs_configurationList; + ylist_add(&dev->devList,&yaffsfs_deviceList); +} - while(cfg && cfg->prefix && cfg->dev){ - cfg->dev->isMounted = 0; - cfg->dev->param.removeObjectCallback = yaffsfs_RemoveObjectCallback; - cfg++; - } +void yaffs_RemoveDevice(yaffs_Device *dev) +{ + ylist_del_init(&dev->devList); +} -} /* Directory search stuff. */ diff --git a/direct/yaffsfs.h b/direct/yaffsfs.h index fc9bb9e..7961dff 100644 --- a/direct/yaffsfs.h +++ b/direct/yaffsfs.h @@ -36,165 +36,6 @@ #endif -#ifdef CONFIG_YAFFSFS_PROVIDE_VALUES - -#ifndef O_RDONLY -#define O_RDONLY 00 -#endif - -#ifndef O_WRONLY -#define O_WRONLY 01 -#endif - -#ifndef O_RDWR -#define O_RDWR 02 -#endif - -#ifndef O_CREAT -#define O_CREAT 0100 -#endif - -#ifndef O_EXCL -#define O_EXCL 0200 -#endif - -#ifndef O_TRUNC -#define O_TRUNC 01000 -#endif - -#ifndef O_APPEND -#define O_APPEND 02000 -#endif - -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif - -#ifndef SEEK_CUR -#define SEEK_CUR 1 -#endif - -#ifndef SEEK_END -#define SEEK_END 2 -#endif - -#ifndef EBUSY -#define EBUSY 16 -#endif - -#ifndef ENODEV -#define ENODEV 19 -#endif - -#ifndef EINVAL -#define EINVAL 22 -#endif - -#ifndef EBADF -#define EBADF 9 -#endif - -#ifndef EACCES -#define EACCES 13 -#endif - -#ifndef EXDEV -#define EXDEV 18 -#endif - -#ifndef ENOENT -#define ENOENT 2 -#endif - -#ifndef ENOSPC -#define ENOSPC 28 -#endif - -#ifndef ERANGE -#define ERANGE 34 -#endif - -#ifndef ENODATA -#define ENODATA 61 -#endif - -#ifndef ENOTEMPTY -#define ENOTEMPTY 39 -#endif - -#ifndef ENAMETOOLONG -#define ENAMETOOLONG 36 -#endif - -#ifndef ENOMEM -#define ENOMEM 12 -#endif - -#ifndef EEXIST -#define EEXIST 17 -#endif - -#ifndef ENOTDIR -#define ENOTDIR 20 -#endif - -#ifndef EISDIR -#define EISDIR 21 -#endif - - -// Mode flags - -#ifndef S_IFMT -#define S_IFMT 0170000 -#endif - -#ifndef S_IFLNK -#define S_IFLNK 0120000 -#endif - -#ifndef S_IFDIR -#define S_IFDIR 0040000 -#endif - -#ifndef S_IFREG -#define S_IFREG 0100000 -#endif - -#ifndef S_IREAD -#define S_IREAD 0000400 -#endif - -#ifndef S_IWRITE -#define S_IWRITE 0000200 -#endif - -#ifndef S_IEXEC -#define S_IEXEC 0000100 -#endif - -#ifndef XATTR_CREATE -#define XATTR_CREATE 1 -#endif - -#ifndef XATTR_REPLACE -#define XATTR_REPLACE 2 -#endif - -#ifndef R_OK -#define R_OK 4 -#define W_OK 2 -#define X_OK 1 -#define F_OK 0 -#endif - -#else -#include <errno.h> -#include <sys/stat.h> -#include <fcntl.h> -#endif - - struct yaffs_dirent{ long d_ino; /* inode number */ off_t d_off; /* offset to this dirent */ @@ -318,7 +159,8 @@ loff_t yaffs_totalspace(const YCHAR *path); int yaffs_inodecount(const YCHAR *path); - +struct yaffs_DeviceStruct; +void yaffs_AddDevice(struct yaffs_DeviceStruct *dev); int yaffs_StartUp(void); diff --git a/direct/ydirectenv.h b/direct/ydirectenv.h index d3e2711..677ab8a 100644 --- a/direct/ydirectenv.h +++ b/direct/ydirectenv.h @@ -22,8 +22,6 @@ // Direct interface -#include "devextras.h" - #include "stdlib.h" #include "stdio.h" #include "string.h" @@ -50,7 +48,7 @@ #ifdef NO_Y_INLINE #define Y_INLINE #else -#define Y_INLINE inline +#define Y_INLINE __inline__ #endif #define YMALLOC(x) yaffs_malloc(x) @@ -438,14 +438,14 @@ static unsigned yaffs_gc_control_callback(yaffs_Device *dev) static void yaffs_GrossLock(yaffs_Device *dev) { T(YAFFS_TRACE_LOCK, (TSTR("yaffs locking %p\n"), current)); - down(&(yaffs_DeviceToContext(dev)->grossLock)); + down(&(yaffs_DeviceToLC(dev)->grossLock)); T(YAFFS_TRACE_LOCK, (TSTR("yaffs locked %p\n"), current)); } static void yaffs_GrossUnlock(yaffs_Device *dev) { T(YAFFS_TRACE_LOCK, (TSTR("yaffs unlocking %p\n"), current)); - up(&(yaffs_DeviceToContext(dev)->grossLock)); + up(&(yaffs_DeviceToLC(dev)->grossLock)); } #ifdef YAFFS_COMPILE_EXPORTFS @@ -560,7 +560,7 @@ static struct yaffs_SearchContext * yaffs_NewSearch(yaffs_Object *dir) dir->variant.directoryVariant.children.next, yaffs_Object,siblings); YINIT_LIST_HEAD(&sc->others); - ylist_add(&sc->others,&(yaffs_DeviceToContext(dev)->searchContexts)); + ylist_add(&sc->others,&(yaffs_DeviceToLC(dev)->searchContexts)); } return sc; } @@ -609,7 +609,7 @@ static void yaffs_RemoveObjectCallback(yaffs_Object *obj) struct ylist_head *i; struct yaffs_SearchContext *sc; - struct ylist_head *search_contexts = &(yaffs_DeviceToContext(obj->myDev)->searchContexts); + struct ylist_head *search_contexts = &(yaffs_DeviceToLC(obj->myDev)->searchContexts); /* Iterate through the directory search contexts. @@ -701,7 +701,7 @@ static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry) yaffs_Device *dev = yaffs_InodeToObject(dir)->myDev; - if(current != yaffs_DeviceToContext(dev)->readdirProcess) + if(current != yaffs_DeviceToLC(dev)->readdirProcess) yaffs_GrossLock(dev); T(YAFFS_TRACE_OS, @@ -714,7 +714,7 @@ static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry) obj = yaffs_GetEquivalentObject(obj); /* in case it was a hardlink */ /* Can't hold gross lock when calling yaffs_get_inode() */ - if(current != yaffs_DeviceToContext(dev)->readdirProcess) + if(current != yaffs_DeviceToLC(dev)->readdirProcess) yaffs_GrossUnlock(dev); if (obj) { @@ -1435,7 +1435,7 @@ static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir) yaffs_GrossLock(dev); - yaffs_DeviceToContext(dev)->readdirProcess = current; + yaffs_DeviceToLC(dev)->readdirProcess = current; offset = f->f_pos; @@ -1520,7 +1520,7 @@ static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir) out: yaffs_EndSearch(sc); - yaffs_DeviceToContext(dev)->readdirProcess = NULL; + yaffs_DeviceToLC(dev)->readdirProcess = NULL; yaffs_GrossUnlock(dev); return retVal; @@ -2100,7 +2100,7 @@ static void yaffs_FlushSuperBlock(struct super_block *sb, int do_checkpoint) static unsigned yaffs_bg_gc_urgency(yaffs_Device *dev) { unsigned erasedChunks = dev->nErasedBlocks * dev->param.nChunksPerBlock; - struct yaffs_LinuxContext *context = yaffs_DeviceToContext(dev); + struct yaffs_LinuxContext *context = yaffs_DeviceToLC(dev); unsigned scatteredFree = 0; /* Free chunks not in an erased block */ if(erasedChunks < dev->nFreeChunks) @@ -2172,7 +2172,7 @@ void yaffs_background_waker(unsigned long data) static int yaffs_BackgroundThread(void *data) { yaffs_Device *dev = (yaffs_Device *)data; - struct yaffs_LinuxContext *context = yaffs_DeviceToContext(dev); + struct yaffs_LinuxContext *context = yaffs_DeviceToLC(dev); unsigned long now = jiffies; unsigned long next_dir_update = now; unsigned long next_gc = now; @@ -2251,7 +2251,7 @@ static int yaffs_BackgroundThread(void *data) static int yaffs_BackgroundStart(yaffs_Device *dev) { int retval = 0; - struct yaffs_LinuxContext *context = yaffs_DeviceToContext(dev); + struct yaffs_LinuxContext *context = yaffs_DeviceToLC(dev); context->bgRunning = 1; @@ -2268,7 +2268,7 @@ static int yaffs_BackgroundStart(yaffs_Device *dev) static void yaffs_BackgroundStop(yaffs_Device *dev) { - struct yaffs_LinuxContext *ctxt = yaffs_DeviceToContext(dev); + struct yaffs_LinuxContext *ctxt = yaffs_DeviceToLC(dev); ctxt->bgRunning = 0; @@ -2380,14 +2380,14 @@ static void yaffs_read_inode(struct inode *inode) T(YAFFS_TRACE_OS, (TSTR("yaffs_read_inode for %d\n"), (int)inode->i_ino)); - if(current != yaffs_DeviceToContext(dev)->readdirProcess) + if(current != yaffs_DeviceToLC(dev)->readdirProcess) yaffs_GrossLock(dev); obj = yaffs_FindObjectByNumber(dev, inode->i_ino); yaffs_FillInodeFromObject(inode, obj); - if(current != yaffs_DeviceToContext(dev)->readdirProcess) + if(current != yaffs_DeviceToLC(dev)->readdirProcess) yaffs_GrossUnlock(dev); } @@ -2396,34 +2396,6 @@ static void yaffs_read_inode(struct inode *inode) static YLIST_HEAD(yaffs_context_list); struct semaphore yaffs_context_lock; -#if 0 /* not used */ -static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data) -{ - yaffs_Device *dev = yaffs_SuperToDevice(sb); - - if (*flags & MS_RDONLY) { - struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice; - - T(YAFFS_TRACE_OS, - (TSTR("yaffs_remount_fs: %s: RO\n"), dev->name)); - - yaffs_GrossLock(dev); - - yaffs_FlushSuperBlock(sb,1); - - if (mtd->sync) - mtd->sync(mtd); - - yaffs_GrossUnlock(dev); - } else { - T(YAFFS_TRACE_OS, - (TSTR("yaffs_remount_fs: %s: RW\n"), dev->name)); - } - - return 0; -} -#endif - static void yaffs_put_super(struct super_block *sb) { yaffs_Device *dev = yaffs_SuperToDevice(sb); @@ -2440,8 +2412,8 @@ static void yaffs_put_super(struct super_block *sb) yaffs_FlushSuperBlock(sb,1); - if (yaffs_DeviceToContext(dev)->putSuperFunc) - yaffs_DeviceToContext(dev)->putSuperFunc(sb); + if (yaffs_DeviceToLC(dev)->putSuperFunc) + yaffs_DeviceToLC(dev)->putSuperFunc(sb); yaffs_Deinitialise(dev); @@ -2449,12 +2421,12 @@ static void yaffs_put_super(struct super_block *sb) yaffs_GrossUnlock(dev); down(&yaffs_context_lock); - ylist_del_init(&(yaffs_DeviceToContext(dev)->contextList)); + ylist_del_init(&(yaffs_DeviceToLC(dev)->contextList)); up(&yaffs_context_lock); - if (yaffs_DeviceToContext(dev)->spareBuffer) { - YFREE(yaffs_DeviceToContext(dev)->spareBuffer); - yaffs_DeviceToContext(dev)->spareBuffer = NULL; + if (yaffs_DeviceToLC(dev)->spareBuffer) { + YFREE(yaffs_DeviceToLC(dev)->spareBuffer); + yaffs_DeviceToLC(dev)->spareBuffer = NULL; } kfree(dev); @@ -2463,7 +2435,7 @@ static void yaffs_put_super(struct super_block *sb) static void yaffs_MTDPutSuper(struct super_block *sb) { - struct mtd_info *mtd = yaffs_DeviceToContext(yaffs_SuperToDevice(sb))->mtd; + struct mtd_info *mtd = yaffs_DeviceToMtd(yaffs_SuperToDevice(sb)); if (mtd->sync) mtd->sync(mtd); @@ -2474,7 +2446,7 @@ static void yaffs_MTDPutSuper(struct super_block *sb) static void yaffs_MarkSuperBlockDirty(yaffs_Device *dev) { - struct super_block *sb = yaffs_DeviceToContext(dev)->superBlock; + struct super_block *sb = yaffs_DeviceToLC(dev)->superBlock; T(YAFFS_TRACE_OS, (TSTR("yaffs_MarkSuperBlockDirty() sb = %p\n"), sb)); if (sb) @@ -2759,7 +2731,7 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion, param = &(dev->param); memset(context,0,sizeof(struct yaffs_LinuxContext)); - dev->context = context; + dev->osContext = context; YINIT_LIST_HEAD(&(context->contextList)); context->dev = dev; context->superBlock = sb; @@ -2772,7 +2744,7 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion, sb->u.generic_sbp = dev; #endif - yaffs_DeviceToContext(dev)->mtd = mtd; + dev->driverContext = mtd; param->name = mtd->name; /* Set up the memory size parameters.... */ @@ -2829,7 +2801,7 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion, nandmtd2_ReadChunkWithTagsFromNAND; param->markNANDBlockBad = nandmtd2_MarkNANDBlockBad; param->queryNANDBlock = nandmtd2_QueryNANDBlock; - yaffs_DeviceToContext(dev)->spareBuffer = YMALLOC(mtd->oobsize); + yaffs_DeviceToLC(dev)->spareBuffer = YMALLOC(mtd->oobsize); param->isYaffs2 = 1; #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) param->totalBytesPerChunk = mtd->writesize; @@ -2861,12 +2833,12 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion, param->eraseBlockInNAND = nandmtd_EraseBlockInNAND; param->initialiseNAND = nandmtd_InitialiseNAND; - yaffs_DeviceToContext(dev)->putSuperFunc = yaffs_MTDPutSuper; + yaffs_DeviceToLC(dev)->putSuperFunc = yaffs_MTDPutSuper; param->markSuperBlockDirty = yaffs_MarkSuperBlockDirty; param->gcControl = yaffs_gc_control_callback; - yaffs_DeviceToContext(dev)->superBlock= sb; + yaffs_DeviceToLC(dev)->superBlock= sb; #ifndef CONFIG_YAFFS_DOES_ECC @@ -2893,14 +2865,14 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion, } context->mount_id = mount_id; - ylist_add_tail(&(yaffs_DeviceToContext(dev)->contextList), &yaffs_context_list); + ylist_add_tail(&(yaffs_DeviceToLC(dev)->contextList), &yaffs_context_list); up(&yaffs_context_lock); /* Directory search handling...*/ - YINIT_LIST_HEAD(&(yaffs_DeviceToContext(dev)->searchContexts)); + YINIT_LIST_HEAD(&(yaffs_DeviceToLC(dev)->searchContexts)); param->removeObjectCallback = yaffs_RemoveObjectCallback; - init_MUTEX(&(yaffs_DeviceToContext(dev)->grossLock)); + init_MUTEX(&(yaffs_DeviceToLC(dev)->grossLock)); yaffs_GrossLock(dev); diff --git a/yaffs_guts.c b/yaffs_guts.c index a8b850a..d65c0ca 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -99,6 +99,11 @@ static int yaffs_VerifyChunkWritten(yaffs_Device *dev, const __u8 *data, yaffs_ExtendedTags *tags); + +static void yaffs_LoadNameFromObjectHeader(yaffs_Device *dev,YCHAR *name, const YCHAR *ohName, int bufferSize); +static void yaffs_LoadObjectHeaderFromName(yaffs_Device *dev,YCHAR *ohName, const YCHAR *name); + + /* Function to calculate chunk and offset */ static void yaffs_AddrToChunk(yaffs_Device *dev, loff_t addr, int *chunkOut, @@ -622,6 +627,18 @@ void yaffs_SetObjectName(yaffs_Object *obj, const YCHAR *name) obj->sum = yaffs_CalcNameSum(name); } +void yaffs_SetObjectNameFromOH(yaffs_Object *obj, const yaffs_ObjectHeader *oh) +{ +#ifdef CONFIG_YAFFS_AUTO_UNICODE + YCHAR tmpName[YAFFS_MAX_NAME_LENGTH+1]; + memset(tmpName,0,sizeof(tmpName)); + yaffs_LoadNameFromObjectHeader(obj->myDev,tmpName,oh->name,YAFFS_MAX_NAME_LENGTH+1); + yaffs_SetObjectName(obj,tmpName); +#else + yaffs_SetObjectName(obj,oh->name); +#endif +} + /*-------------------- TNODES ------------------- * List of spare tnodes @@ -3036,7 +3053,7 @@ int yaffs_UpdateObjectHeader(yaffs_Object *in, const YCHAR *name, int force, if (name && *name) { memset(oh->name, 0, sizeof(oh->name)); - yaffs_strncpy(oh->name, name, YAFFS_MAX_NAME_LENGTH); + yaffs_LoadObjectHeaderFromName(dev,oh->name,name); } else if (prevChunkId > 0) memcpy(oh->name, oldName, sizeof(oh->name)); else @@ -4386,6 +4403,7 @@ static void yaffs_UpdateParent(yaffs_Object *obj) yaffs_Device *dev; if(!obj) return; +#ifndef CONFIG_YAFFS_WINCE dev = obj->myDev; obj->dirty = 1; @@ -4400,6 +4418,7 @@ static void yaffs_UpdateParent(yaffs_Object *obj) } else yaffs_UpdateObjectHeader(obj, NULL, 0, 0, 0, NULL); +#endif } void yaffs_UpdateDirtyDirectories(yaffs_Device *dev) @@ -4600,36 +4619,124 @@ yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object *obj) return obj; } -int yaffs_GetObjectName(yaffs_Object *obj, YCHAR *name, int buffSize) -{ - memset(name, 0, buffSize * sizeof(YCHAR)); - - yaffs_CheckObjectDetailsLoaded(obj); +/* + * A note or two on object names. + * * If the object name is missing, we then make one up in the form objnnn + * + * * ASCII names are stored in the object header's name field from byte zero + * * Unicode names are historically stored starting from byte zero. + * + * Then there are automatic Unicode names... + * The purpose of these is to save names in a way that can be read as + * ASCII or Unicode names as appropriate, thus allowing a Unicode and ASCII + * system to share files. + * + * These automatic unicode are stored slightly differently... + * - If the name can fit in the ASCII character space then they are saved as + * ascii names as per above. + * - If the name needs Unicode then the name is saved in Unicode + * starting at oh->name[1]. - if (obj->objectId == YAFFS_OBJECTID_LOSTNFOUND) { - yaffs_strncpy(name, YAFFS_LOSTNFOUND_NAME, buffSize - 1); - } else if (obj->hdrChunk <= 0) { + */ +static void yaffs_FixNullName(yaffs_Object * obj,YCHAR * name, int buffSize) +{ + /* Create an object name if we could not find one. */ + if(yaffs_strnlen(name,YAFFS_MAX_NAME_LENGTH) == 0){ YCHAR locName[20]; YCHAR numString[20]; YCHAR *x = &numString[19]; unsigned v = obj->objectId; numString[19] = 0; - while (v > 0) { + while(v>0){ x--; *x = '0' + (v % 10); v /= 10; } /* make up a name */ yaffs_strcpy(locName, YAFFS_LOSTNFOUND_PREFIX); - yaffs_strcat(locName, x); + yaffs_strcat(locName,x); yaffs_strncpy(name, locName, buffSize - 1); + } +} + +static void yaffs_LoadNameFromObjectHeader(yaffs_Device *dev,YCHAR *name, const YCHAR *ohName, int bufferSize) +{ +#ifdef CONFIG_YAFFS_AUTO_UNICODE + if(dev->param.autoUnicode){ + if(*ohName){ + /* It is an ASCII name, so do an ASCII to unicode conversion */ + const char *asciiOhName = (const char *)ohName; + int n = bufferSize - 1; + while(n > 0 && *asciiOhName){ + *name = *asciiOhName; + name++; + asciiOhName++; + n--; + } + } else + yaffs_strncpy(name,ohName+1, bufferSize -1); + } else +#endif + yaffs_strncpy(name, ohName, bufferSize - 1); +} + + +static void yaffs_LoadObjectHeaderFromName(yaffs_Device *dev, YCHAR *ohName, const YCHAR *name) +{ +#ifdef CONFIG_YAFFS_AUTO_UNICODE + + int isAscii; + YCHAR *w; + + if(dev->param.autoUnicode){ + isAscii = 1; + w = name; + + /* Figure out if the name will fit in ascii character set */ + while(isAscii && *w){ + if((*w) & 0xff00) + isAscii = 0; + w++; + } + + if(isAscii){ + /* It is an ASCII name, so do a unicode to ascii conversion */ + char *asciiOhName = (char *)ohName; + int n = YAFFS_MAX_NAME_LENGTH - 1; + while(n > 0 && *name){ + *asciiOhName= *name; + name++; + asciiOhName++; + n--; + } + } else{ + /* It is a unicode name, so save starting at the second YCHAR */ + *ohName = 0; + yaffs_strncpy(ohName+1,name, YAFFS_MAX_NAME_LENGTH -2); + } } + else +#endif + yaffs_strncpy(ohName,name, YAFFS_MAX_NAME_LENGTH - 1); + +} + +int yaffs_GetObjectName(yaffs_Object * obj, YCHAR * name, int buffSize) +{ + memset(name, 0, buffSize * sizeof(YCHAR)); + + yaffs_CheckObjectDetailsLoaded(obj); + + if (obj->objectId == YAFFS_OBJECTID_LOSTNFOUND) { + yaffs_strncpy(name, YAFFS_LOSTNFOUND_NAME, buffSize - 1); + } #ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM - else if (obj->shortName[0]) - yaffs_strncpy(name, obj->shortName,YAFFS_SHORT_NAME_LENGTH+1); + else if (obj->shortName[0]) { + yaffs_strcpy(name, obj->shortName); + } #endif - else { + else if(obj->hdrChunk > 0) { int result; __u8 *buffer = yaffs_GetTempBuffer(obj->myDev, __LINE__); @@ -4642,15 +4749,17 @@ int yaffs_GetObjectName(yaffs_Object *obj, YCHAR *name, int buffSize) obj->hdrChunk, buffer, NULL); } - yaffs_strncpy(name, oh->name, buffSize - 1); - name[buffSize-1]=0; + yaffs_LoadNameFromObjectHeader(obj->myDev,name,oh->name,buffSize); yaffs_ReleaseTempBuffer(obj->myDev, buffer, __LINE__); } - return yaffs_strnlen(name,buffSize-1); + yaffs_FixNullName(obj,name,buffSize); + + return yaffs_strnlen(name,YAFFS_MAX_NAME_LENGTH); } + int yaffs_GetObjectFileLength(yaffs_Object *obj) { /* Dereference any hard linking */ diff --git a/yaffs_guts.h b/yaffs_guts.h index c6e49c4..b7e2f4b 100644 --- a/yaffs_guts.h +++ b/yaffs_guts.h @@ -16,8 +16,9 @@ #ifndef __YAFFS_GUTS_H__ #define __YAFFS_GUTS_H__ -#include "devextras.h" #include "yportenv.h" +#include "devextras.h" +#include "yaffs_list.h" #define YAFFS_OK 1 #define YAFFS_FAIL 0 @@ -598,6 +599,10 @@ struct yaffs_DeviceParamStruct { int disableSoftDelete; /* yaffs 1 only: Set to disable the use of softdeletion. */ int deferDirectoryUpdate; /* Set to defer directory updates */ + +#ifdef CONFIG_YAFFS_AUTO_UNICODE + int autoUnicode; +#endif }; @@ -608,7 +613,10 @@ struct yaffs_DeviceStruct { /* Context storage. Holds extra OS specific data for this device */ - void *context; + void *osContext; + void *driverContext; + + struct ylist_head devList; /* Runtime parameters. Set up by YAFFS. */ int nDataBytesPerChunk; @@ -928,6 +936,7 @@ yaffs_Object *yaffs_FindOrCreateObjectByNumber(yaffs_Device *dev, int yaffs_PutChunkIntoFile(yaffs_Object *in, int chunkInInode, int chunkInNAND, int inScan); void yaffs_SetObjectName(yaffs_Object *obj, const YCHAR *name); +void yaffs_SetObjectNameFromOH(yaffs_Object *obj, const yaffs_ObjectHeader *oh); void yaffs_AddObjectToDirectory(yaffs_Object *directory, yaffs_Object *obj); YCHAR *yaffs_CloneString(const YCHAR *str); diff --git a/yaffs_linux.h b/yaffs_linux.h index 6832681..ce059fd 100644 --- a/yaffs_linux.h +++ b/yaffs_linux.h @@ -29,7 +29,6 @@ struct yaffs_LinuxContext { __u8 *spareBuffer; /* For mtdif2 use. Don't know the size of the buffer * at compile time so we have to allocate it. */ - struct mtd_info *mtd; struct ylist_head searchContexts; void (*putSuperFunc)(struct super_block *sb); @@ -37,7 +36,8 @@ struct yaffs_LinuxContext { unsigned mount_id; }; -#define yaffs_DeviceToContext(dev) ((struct yaffs_LinuxContext *)((dev)->context)) +#define yaffs_DeviceToLC(dev) ((struct yaffs_LinuxContext *)((dev)->osContext)) +#define yaffs_DeviceToMtd(dev) ((struct mtd_info *)((dev)->driverContext)) #endif diff --git a/yaffs_list.h b/yaffs_list.h new file mode 100644 index 0000000..09d80b8 --- /dev/null +++ b/yaffs_list.h @@ -0,0 +1,127 @@ +/* + * YAFFS: Yet another Flash File System . A NAND-flash specific file system. + * + * Copyright (C) 2002-2010 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. + */ + +/* + * This file is just holds extra declarations of macros that would normally + * be providesd in the Linux kernel. These macros have been written from + * scratch but are functionally equivalent to the Linux ones. + * + */ + +#ifndef __YAFFS_LIST_H__ +#define __YAFFS_LIST_H__ + + +#include "yportenv.h" + +/* + * This is a simple doubly linked list implementation that matches the + * way the Linux kernel doubly linked list implementation works. + */ + +struct ylist_head { + struct ylist_head *next; /* next in chain */ + struct ylist_head *prev; /* previous in chain */ +}; + + +/* Initialise a static list */ +#define YLIST_HEAD(name) \ +struct ylist_head name = { &(name), &(name)} + + + +/* Initialise a list head to an empty list */ +#define YINIT_LIST_HEAD(p) \ +do { \ + (p)->next = (p);\ + (p)->prev = (p); \ +} while (0) + + +/* Add an element to a list */ +static Y_INLINE void ylist_add(struct ylist_head *newEntry, + struct ylist_head *list) +{ + struct ylist_head *listNext = list->next; + + list->next = newEntry; + newEntry->prev = list; + newEntry->next = listNext; + listNext->prev = newEntry; + +} + +static Y_INLINE void ylist_add_tail(struct ylist_head *newEntry, + struct ylist_head *list) +{ + struct ylist_head *listPrev = list->prev; + + list->prev = newEntry; + newEntry->next = list; + newEntry->prev = listPrev; + listPrev->next = newEntry; + +} + + +/* Take an element out of its current list, with or without + * reinitialising the links.of the entry*/ +static Y_INLINE void ylist_del(struct ylist_head *entry) +{ + struct ylist_head *listNext = entry->next; + struct ylist_head *listPrev = entry->prev; + + listNext->prev = listPrev; + listPrev->next = listNext; + +} + +static Y_INLINE void ylist_del_init(struct ylist_head *entry) +{ + ylist_del(entry); + entry->next = entry->prev = entry; +} + + +/* Test if the list is empty */ +static Y_INLINE int ylist_empty(struct ylist_head *entry) +{ + return (entry->next == entry); +} + + +/* ylist_entry takes a pointer to a list entry and offsets it to that + * we can find a pointer to the object it is embedded in. + */ + + +#define ylist_entry(entry, type, member) \ + ((type *)((char *)(entry)-(unsigned long)(&((type *)NULL)->member))) + + +/* ylist_for_each and list_for_each_safe iterate over lists. + * ylist_for_each_safe uses temporary storage to make the list delete safe + */ + +#define ylist_for_each(itervar, list) \ + for (itervar = (list)->next; itervar != (list); itervar = itervar->next) + +#define ylist_for_each_safe(itervar, saveVar, list) \ + for (itervar = (list)->next, saveVar = (list)->next->next; \ + itervar != (list); itervar = saveVar, saveVar = saveVar->next) + + +#endif diff --git a/yaffs_mtdif.c b/yaffs_mtdif.c index 5de3193..e073a5e 100644 --- a/yaffs_mtdif.c +++ b/yaffs_mtdif.c @@ -25,7 +25,7 @@ int nandmtd_EraseBlockInNAND(yaffs_Device *dev, int blockNumber) { - struct mtd_info *mtd = yaffs_DeviceToContext(dev)->mtd; + struct mtd_info *mtd = yaffs_DeviceToMtd(dev); __u32 addr = ((loff_t) blockNumber) * dev->param.totalBytesPerChunk * dev->param.nChunksPerBlock; diff --git a/yaffs_mtdif1.c b/yaffs_mtdif1.c index aaa02db..b14a254 100644 --- a/yaffs_mtdif1.c +++ b/yaffs_mtdif1.c @@ -91,7 +91,7 @@ static struct nand_ecclayout nand_oob_16 = { int nandmtd1_WriteChunkWithTagsToNAND(yaffs_Device *dev, int chunkInNAND, const __u8 *data, const yaffs_ExtendedTags *etags) { - struct mtd_info *mtd = yaffs_DeviceToContext(dev)->mtd; + struct mtd_info *mtd = yaffs_DeviceToMtd(dev); int chunkBytes = dev->nDataBytesPerChunk; loff_t addr = ((loff_t)chunkInNAND) * chunkBytes; struct mtd_oob_ops ops; @@ -169,7 +169,7 @@ static int rettags(yaffs_ExtendedTags *etags, int eccResult, int retval) int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND, __u8 *data, yaffs_ExtendedTags *etags) { - struct mtd_info *mtd = yaffs_DeviceToContext(dev)->mtd; + struct mtd_info *mtd = yaffs_DeviceToMtd(dev); int chunkBytes = dev->nDataBytesPerChunk; loff_t addr = ((loff_t)chunkInNAND) * chunkBytes; int eccres = YAFFS_ECC_RESULT_NO_ERROR; @@ -280,7 +280,7 @@ int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev, */ int nandmtd1_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo) { - struct mtd_info *mtd = yaffs_DeviceToContext(dev)->mtd; + struct mtd_info *mtd = yaffs_DeviceToMtd(dev); int blocksize = dev->param.nChunksPerBlock * dev->nDataBytesPerChunk; int retval; @@ -321,7 +321,7 @@ static int nandmtd1_TestPrerequists(struct mtd_info *mtd) int nandmtd1_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, yaffs_BlockState *pState, __u32 *pSequenceNumber) { - struct mtd_info *mtd = yaffs_DeviceToContext(dev)->mtd; + struct mtd_info *mtd = yaffs_DeviceToMtd(dev); int chunkNo = blockNo * dev->param.nChunksPerBlock; loff_t addr = (loff_t)chunkNo * dev->nDataBytesPerChunk; yaffs_ExtendedTags etags; diff --git a/yaffs_mtdif2.c b/yaffs_mtdif2.c index c1d4478..2b0a601 100644 --- a/yaffs_mtdif2.c +++ b/yaffs_mtdif2.c @@ -34,7 +34,7 @@ int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device *dev, int chunkInNAND, const __u8 *data, const yaffs_ExtendedTags *tags) { - struct mtd_info *mtd = yaffs_DeviceToContext(dev)->mtd; + struct mtd_info *mtd = yaffs_DeviceToMtd(dev); #if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17)) struct mtd_oob_ops ops; #else @@ -100,7 +100,7 @@ int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device *dev, int chunkInNAND, int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND, __u8 *data, yaffs_ExtendedTags *tags) { - struct mtd_info *mtd = yaffs_DeviceToContext(dev)->mtd; + struct mtd_info *mtd = yaffs_DeviceToMtd(dev); #if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17)) struct mtd_oob_ops ops; #endif @@ -141,7 +141,7 @@ int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND, ops.len = data ? dev->nDataBytesPerChunk : packed_tags_size; ops.ooboffs = 0; ops.datbuf = data; - ops.oobbuf = yaffs_DeviceToContext(dev)->spareBuffer; + ops.oobbuf = yaffs_DeviceToLC(dev)->spareBuffer; retval = mtd->read_oob(mtd, addr, &ops); } #else @@ -171,7 +171,7 @@ int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND, } } else { if (tags) { - memcpy(packed_tags_ptr, yaffs_DeviceToContext(dev)->spareBuffer, packed_tags_size); + memcpy(packed_tags_ptr, yaffs_DeviceToLC(dev)->spareBuffer, packed_tags_size); yaffs_UnpackTags2(tags, &pt, !dev->param.noTagsECC); } } @@ -195,7 +195,7 @@ int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND, int nandmtd2_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo) { - struct mtd_info *mtd = yaffs_DeviceToContext(dev)->mtd; + struct mtd_info *mtd = yaffs_DeviceToMtd(dev); int retval; T(YAFFS_TRACE_MTD, (TSTR("nandmtd2_MarkNANDBlockBad %d" TENDSTR), blockNo)); @@ -215,7 +215,7 @@ int nandmtd2_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo) int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, yaffs_BlockState *state, __u32 *sequenceNumber) { - struct mtd_info *mtd = yaffs_DeviceToContext(dev)->mtd; + struct mtd_info *mtd = yaffs_DeviceToMtd(dev); int retval; T(YAFFS_TRACE_MTD, diff --git a/yaffs_yaffs1.c b/yaffs_yaffs1.c index bcfd594..1b8fcf1 100644 --- a/yaffs_yaffs1.c +++ b/yaffs_yaffs1.c @@ -305,7 +305,7 @@ int yaffs1_Scan(yaffs_Device *dev) in->hdrChunk = chunk; in->serial = tags.serialNumber; - yaffs_SetObjectName(in, oh->name); + yaffs_SetObjectNameFromOH(in, oh); in->dirty = 0; /* directory stuff... diff --git a/yaffs_yaffs2.c b/yaffs_yaffs2.c index 90646fd..ab175b9 100644 --- a/yaffs_yaffs2.c +++ b/yaffs_yaffs2.c @@ -1373,7 +1373,7 @@ int yaffs2_ScanBackwards(yaffs_Device *dev) - yaffs_SetObjectName(in, oh->name); + yaffs_SetObjectNameFromOH(in, oh); parent = yaffs_FindOrCreateObjectByNumber (dev, oh->parentObjectId, @@ -60,7 +60,7 @@ #define yaffs_sprintf sprintf #define yaffs_toupper(a) toupper(a) -#define Y_INLINE inline +#define Y_INLINE __inline__ #define YAFFS_LOSTNFOUND_NAME "lost+found" #define YAFFS_LOSTNFOUND_PREFIX "obj" @@ -112,7 +112,6 @@ #include "stdio.h" #include "string.h" -#include "devextras.h" #define YMALLOC(x) malloc(x) #define YFREE(x) free(x) @@ -154,6 +153,168 @@ #endif +#if defined(CONFIG_YAFFS_DIRECT) || defined(CONFIG_YAFFS_WINCE) + +#ifdef CONFIG_YAFFSFS_PROVIDE_VALUES + +#ifndef O_RDONLY +#define O_RDONLY 00 +#endif + +#ifndef O_WRONLY +#define O_WRONLY 01 +#endif + +#ifndef O_RDWR +#define O_RDWR 02 +#endif + +#ifndef O_CREAT +#define O_CREAT 0100 +#endif + +#ifndef O_EXCL +#define O_EXCL 0200 +#endif + +#ifndef O_TRUNC +#define O_TRUNC 01000 +#endif + +#ifndef O_APPEND +#define O_APPEND 02000 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef EBUSY +#define EBUSY 16 +#endif + +#ifndef ENODEV +#define ENODEV 19 +#endif + +#ifndef EINVAL +#define EINVAL 22 +#endif + +#ifndef EBADF +#define EBADF 9 +#endif + +#ifndef EACCES +#define EACCES 13 +#endif + +#ifndef EXDEV +#define EXDEV 18 +#endif + +#ifndef ENOENT +#define ENOENT 2 +#endif + +#ifndef ENOSPC +#define ENOSPC 28 +#endif + +#ifndef ERANGE +#define ERANGE 34 +#endif + +#ifndef ENODATA +#define ENODATA 61 +#endif + +#ifndef ENOTEMPTY +#define ENOTEMPTY 39 +#endif + +#ifndef ENAMETOOLONG +#define ENAMETOOLONG 36 +#endif + +#ifndef ENOMEM +#define ENOMEM 12 +#endif + +#ifndef EEXIST +#define EEXIST 17 +#endif + +#ifndef ENOTDIR +#define ENOTDIR 20 +#endif + +#ifndef EISDIR +#define EISDIR 21 +#endif + + +// Mode flags + +#ifndef S_IFMT +#define S_IFMT 0170000 +#endif + +#ifndef S_IFLNK +#define S_IFLNK 0120000 +#endif + +#ifndef S_IFDIR +#define S_IFDIR 0040000 +#endif + +#ifndef S_IFREG +#define S_IFREG 0100000 +#endif + +#ifndef S_IREAD +#define S_IREAD 0000400 +#endif + +#ifndef S_IWRITE +#define S_IWRITE 0000200 +#endif + +#ifndef S_IEXEC +#define S_IEXEC 0000100 +#endif + +#ifndef XATTR_CREATE +#define XATTR_CREATE 1 +#endif + +#ifndef XATTR_REPLACE +#define XATTR_REPLACE 2 +#endif + +#ifndef R_OK +#define R_OK 4 +#define W_OK 2 +#define X_OK 1 +#define F_OK 0 +#endif + +#else +#include <errno.h> +#include <sys/stat.h> +#include <fcntl.h> +#endif + +#endif + #ifndef Y_DUMP_STACK #define Y_DUMP_STACK() do { } while (0) #endif @@ -167,4 +328,5 @@ } while (0) #endif + #endif |