summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--devextras.h99
-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.c112
-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.c277
-rw-r--r--direct/basic-test/yramsim.h11
-rw-r--r--direct/python/Makefile25
-rw-r--r--direct/tests/Makefile25
-rw-r--r--direct/yaffs_nandif.c501
-rw-r--r--direct/yaffs_nandif.h51
-rw-r--r--direct/yaffsfs.c63
-rw-r--r--direct/yaffsfs.h162
-rw-r--r--direct/ydirectenv.h4
-rw-r--r--yaffs_fs.c88
-rw-r--r--yaffs_guts.c143
-rw-r--r--yaffs_guts.h13
-rw-r--r--yaffs_linux.h4
-rw-r--r--yaffs_list.h127
-rw-r--r--yaffs_mtdif.c2
-rw-r--r--yaffs_mtdif1.c8
-rw-r--r--yaffs_mtdif2.c12
-rw-r--r--yaffs_yaffs1.c2
-rw-r--r--yaffs_yaffs2.c2
-rw-r--r--yportenv.h166
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)
diff --git a/yaffs_fs.c b/yaffs_fs.c
index f0c2771..15096a9 100644
--- a/yaffs_fs.c
+++ b/yaffs_fs.c
@@ -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,
diff --git a/yportenv.h b/yportenv.h
index 687f5e6..cb79d9b 100644
--- a/yportenv.h
+++ b/yportenv.h
@@ -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