]> git.sur5r.net Git - u-boot/commitdiff
moving files from yaffs2/direct/ to yaffs2/ and deleting all symlinks
authorWilliam Juul <william.juul@datarespons.no>
Mon, 19 Nov 2007 13:46:00 +0000 (14:46 +0100)
committerScott Wood <scottwood@freescale.com>
Tue, 12 Aug 2008 16:31:21 +0000 (11:31 -0500)
Signed-off-by: William Juul <william.juul@tandberg.com>
46 files changed:
Makefile
fs/Makefile
fs/yaffs2/Makefile [new file with mode: 0644]
fs/yaffs2/direct/Makefile [deleted file]
fs/yaffs2/direct/devextras.h [deleted symlink]
fs/yaffs2/direct/yaffs_checkptrw.c [deleted symlink]
fs/yaffs2/direct/yaffs_checkptrw.h [deleted symlink]
fs/yaffs2/direct/yaffs_ecc.c [deleted symlink]
fs/yaffs2/direct/yaffs_ecc.h [deleted symlink]
fs/yaffs2/direct/yaffs_flashif.h [deleted file]
fs/yaffs2/direct/yaffs_guts.c [deleted symlink]
fs/yaffs2/direct/yaffs_guts.h [deleted symlink]
fs/yaffs2/direct/yaffs_malloc.h [deleted file]
fs/yaffs2/direct/yaffs_mtdif.c [deleted symlink]
fs/yaffs2/direct/yaffs_mtdif.h [deleted symlink]
fs/yaffs2/direct/yaffs_mtdif2.c [deleted symlink]
fs/yaffs2/direct/yaffs_mtdif2.h [deleted symlink]
fs/yaffs2/direct/yaffs_nand.c [deleted symlink]
fs/yaffs2/direct/yaffs_nand.h [deleted symlink]
fs/yaffs2/direct/yaffs_nandemul2k.h [deleted symlink]
fs/yaffs2/direct/yaffs_packedtags1.c [deleted symlink]
fs/yaffs2/direct/yaffs_packedtags1.h [deleted symlink]
fs/yaffs2/direct/yaffs_packedtags2.c [deleted symlink]
fs/yaffs2/direct/yaffs_packedtags2.h [deleted symlink]
fs/yaffs2/direct/yaffs_qsort.c [deleted symlink]
fs/yaffs2/direct/yaffs_qsort.h [deleted symlink]
fs/yaffs2/direct/yaffs_ramdisk.h [deleted file]
fs/yaffs2/direct/yaffs_tagscompat.c [deleted symlink]
fs/yaffs2/direct/yaffs_tagscompat.h [deleted symlink]
fs/yaffs2/direct/yaffs_tagsvalidity.c [deleted symlink]
fs/yaffs2/direct/yaffs_tagsvalidity.h [deleted symlink]
fs/yaffs2/direct/yaffscfg.c [deleted file]
fs/yaffs2/direct/yaffscfg.h [deleted file]
fs/yaffs2/direct/yaffsfs.c [deleted file]
fs/yaffs2/direct/yaffsfs.h [deleted file]
fs/yaffs2/direct/yaffsinterface.h [deleted symlink]
fs/yaffs2/direct/ydirectenv.h [deleted file]
fs/yaffs2/direct/yportenv.h [deleted symlink]
fs/yaffs2/yaffs_flashif.h [new file with mode: 0644]
fs/yaffs2/yaffs_malloc.h [new file with mode: 0644]
fs/yaffs2/yaffs_ramdisk.h [new file with mode: 0644]
fs/yaffs2/yaffscfg.c [new file with mode: 0644]
fs/yaffs2/yaffscfg.h [new file with mode: 0644]
fs/yaffs2/yaffsfs.c [new file with mode: 0644]
fs/yaffs2/yaffsfs.h [new file with mode: 0644]
fs/yaffs2/ydirectenv.h [new file with mode: 0644]

index b2048847c6e3b53ed77a604cbda41de1370a1a2e..f25750fd7eff720fbcd0612734c5bb6e8cf833a1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -210,7 +210,7 @@ LIBS += cpu/ixp/npe/libnpe.a
 endif
 LIBS += lib_$(ARCH)/lib$(ARCH).a
 LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a \
-       fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a fs/yaffs2/direct/libyaffs2.a
+       fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a fs/yaffs2/libyaffs2.a
 LIBS += net/libnet.a
 LIBS += disk/libdisk.a
 LIBS += drivers/bios_emulator/libatibiosemu.a
@@ -378,7 +378,7 @@ TAG_SUBDIRS += fs/cramfs
 TAG_SUBDIRS += fs/fat
 TAG_SUBDIRS += fs/fdos
 TAG_SUBDIRS += fs/jffs2
-TAG_SUBDIRS += fs/yaffs2/direct
+TAG_SUBDIRS += fs/yaffs2
 TAG_SUBDIRS += net
 TAG_SUBDIRS += disk
 TAG_SUBDIRS += common
index 48cf1d2c3a8a1a733f26d4afbd4ad0ecad8685ec..95ac0e93fe2ca40e955b4fc844f3f3f9267d0744 100644 (file)
@@ -22,7 +22,7 @@
 #
 #
 
-SUBDIRS        := jffs2 cramfs fdos fat reiserfs ext2 yaffs2/direct
+SUBDIRS        := jffs2 cramfs fdos fat reiserfs ext2 yaffs2
 
 $(obj).depend all:
        @for dir in $(SUBDIRS) ; do \
diff --git a/fs/yaffs2/Makefile b/fs/yaffs2/Makefile
new file mode 100644 (file)
index 0000000..ab8b27f
--- /dev/null
@@ -0,0 +1,56 @@
+# Makefile for YAFFS direct test
+#
+#
+# YAFFS: Yet another Flash File System. A NAND-flash specific file system.
+#
+# Copyright (C) 2003 Aleph One Ltd.
+#
+#
+# Created by Charles Manning <charles@aleph1.co.uk>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# NB Warning this Makefile does not include header dependencies.
+#
+# $Id: Makefile,v 1.15 2007/07/18 19:40:38 charles Exp $
+
+#EXTRA_COMPILE_FLAGS = -DYAFFS_IGNORE_TAGS_ECC
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)libyaffs2.a
+
+COBJS-$(CONFIG_YAFFS2) := \
+       yaffscfg.o yaffs_ecc.o yaffsfs.o yaffs_guts.o yaffs_packedtags1.o \
+       yaffs_tagscompat.o yaffs_packedtags2.o yaffs_tagsvalidity.o \
+       yaffs_nand.o yaffs_checkptrw.o yaffs_qsort.o yaffs_mtdif.o \
+       yaffs_mtdif2.o
+
+SRCS    := $(COBJS-y:.o=.c)
+OBJS    := $(addprefix $(obj),$(COBJS-y))
+
+# -DCONFIG_YAFFS_NO_YAFFS1
+CFLAGS +=    -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_YAFFS2 -DNO_Y_INLINE -DLINUX_VERSION_CODE=0x20622 
+
+all:  $(LIB)
+
+$(LIB): $(obj).depend $(OBJS)
+       $(AR) $(ARFLAGS) $@ $(OBJS)
+
+.PHONY: clean distclean
+clean:
+       rm -f $(OBJS)
+
+distclean:  clean
+       rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
+
diff --git a/fs/yaffs2/direct/Makefile b/fs/yaffs2/direct/Makefile
deleted file mode 100644 (file)
index 0ee18e5..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-# Makefile for YAFFS direct test
-#
-#
-# YAFFS: Yet another Flash File System. A NAND-flash specific file system.
-#
-# Copyright (C) 2003 Aleph One Ltd.
-#
-#
-# Created by Charles Manning <charles@aleph1.co.uk>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 2 as
-# published by the Free Software Foundation.
-#
-# NB Warning this Makefile does not include header dependencies.
-#
-# $Id: Makefile,v 1.15 2007/07/18 19:40:38 charles Exp $
-
-#EXTRA_COMPILE_FLAGS = -DYAFFS_IGNORE_TAGS_ECC
-include $(TOPDIR)/config.mk
-
-LIB = $(obj)libyaffs2.a
-
-COBJS-$(CONFIG_YAFFS2) := \
-       yaffscfg.o yaffs_ecc.o yaffsfs.o yaffs_guts.o yaffs_packedtags1.o \
-       yaffs_tagscompat.o yaffs_packedtags2.o yaffs_tagsvalidity.o \
-       yaffs_nand.o yaffs_checkptrw.o yaffs_qsort.o yaffs_mtdif.o \
-       yaffs_mtdif2.o
-
-SRCS    := $(COBJS-y:.o=.c)
-OBJS    := $(addprefix $(obj),$(COBJS-y))
-
-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 \
-          yaffs_packedtags1.c yaffs_packedtags1.h yaffs_packedtags2.c yaffs_packedtags2.h  yaffs_nandemul2k.h \
-          yaffs_nand.c yaffs_nand.h yaffs_mtdif.c yaffs_mtdif.h \
-          yaffs_tagsvalidity.c yaffs_tagsvalidity.h yaffs_checkptrw.h yaffs_checkptrw.c \
-          yaffs_qsort.c yaffs_qsort.h yaffs_mtdif2.c yaffs_mtdif2.h
-
-# -DCONFIG_YAFFS_NO_YAFFS1
-CFLAGS +=    -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_YAFFS2 -DNO_Y_INLINE -DLINUX_VERSION_CODE=0x20616 
-
-all:  $(LIB)
-
-$(LIB): $(obj).depend $(OBJS)
-       $(AR) $(ARFLAGS) $@ $(OBJS)
-
-.PHONY: clean distclean
-clean:
-       rm -f $(OBJS)
-
-distclean:  clean
-       rm -f $(LIB) core *.bak .depend
-
-#########################################################################
-
-# defines $(obj).depend target
-include $(SRCTREE)/rules.mk
-
-sinclude $(obj).depend
-
-#########################################################################
-
diff --git a/fs/yaffs2/direct/devextras.h b/fs/yaffs2/direct/devextras.h
deleted file mode 120000 (symlink)
index 6c1a6bf..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../devextras.h
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_checkptrw.c b/fs/yaffs2/direct/yaffs_checkptrw.c
deleted file mode 120000 (symlink)
index a5d3a15..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_checkptrw.c
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_checkptrw.h b/fs/yaffs2/direct/yaffs_checkptrw.h
deleted file mode 120000 (symlink)
index 9b09986..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_checkptrw.h
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_ecc.c b/fs/yaffs2/direct/yaffs_ecc.c
deleted file mode 120000 (symlink)
index d20dc82..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_ecc.c
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_ecc.h b/fs/yaffs2/direct/yaffs_ecc.h
deleted file mode 120000 (symlink)
index cb50bb2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_ecc.h
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_flashif.h b/fs/yaffs2/direct/yaffs_flashif.h
deleted file mode 100644 (file)
index f7f4e42..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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 Lesser General Public License version 2.1 as
- * published by the Free Software Foundation.
- *
- * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
- */
-
-#ifndef __YAFFS_FLASH_H__
-#define __YAFFS_FLASH_H__
-
-
-#include "yaffs_guts.h"
-int yflash_EraseBlockInNAND(yaffs_Device *dev, int blockNumber);
-int yflash_WriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_Spare *spare);
-int yflash_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_ExtendedTags *tags);
-int yflash_ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare);
-int yflash_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_ExtendedTags *tags);
-int yflash_EraseBlockInNAND(yaffs_Device *dev, int blockNumber);
-int yflash_InitialiseNAND(yaffs_Device *dev);
-int yflash_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo);
-int yflash_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, yaffs_BlockState *state, int *sequenceNumber);
-
-#endif
diff --git a/fs/yaffs2/direct/yaffs_guts.c b/fs/yaffs2/direct/yaffs_guts.c
deleted file mode 120000 (symlink)
index 7a118f8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_guts.c
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_guts.h b/fs/yaffs2/direct/yaffs_guts.h
deleted file mode 120000 (symlink)
index c10089f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_guts.h
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_malloc.h b/fs/yaffs2/direct/yaffs_malloc.h
deleted file mode 100644 (file)
index 122fb4c..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef __YAFFS_MALLOC_H__
-/*
- * 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 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.
- */
-/* XXX U-BOOT XXX */
-#if 0
-#include <stdlib.h>
-#endif 
-
-void *yaffs_malloc(size_t size); 
-void yaffs_free(void *ptr);
-#endif
-
diff --git a/fs/yaffs2/direct/yaffs_mtdif.c b/fs/yaffs2/direct/yaffs_mtdif.c
deleted file mode 120000 (symlink)
index be0612d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_mtdif.c
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_mtdif.h b/fs/yaffs2/direct/yaffs_mtdif.h
deleted file mode 120000 (symlink)
index bcfc59b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_mtdif.h
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_mtdif2.c b/fs/yaffs2/direct/yaffs_mtdif2.c
deleted file mode 120000 (symlink)
index a5b1bb9..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_mtdif2.c
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_mtdif2.h b/fs/yaffs2/direct/yaffs_mtdif2.h
deleted file mode 120000 (symlink)
index aa1feda..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_mtdif2.h
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_nand.c b/fs/yaffs2/direct/yaffs_nand.c
deleted file mode 120000 (symlink)
index 6dd30c2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_nand.c
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_nand.h b/fs/yaffs2/direct/yaffs_nand.h
deleted file mode 120000 (symlink)
index 8a539ee..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_nand.h
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_nandemul2k.h b/fs/yaffs2/direct/yaffs_nandemul2k.h
deleted file mode 120000 (symlink)
index 1c2d0c2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_nandemul2k.h
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_packedtags1.c b/fs/yaffs2/direct/yaffs_packedtags1.c
deleted file mode 120000 (symlink)
index f7c5639..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_packedtags1.c
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_packedtags1.h b/fs/yaffs2/direct/yaffs_packedtags1.h
deleted file mode 120000 (symlink)
index b74537b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_packedtags1.h
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_packedtags2.c b/fs/yaffs2/direct/yaffs_packedtags2.c
deleted file mode 120000 (symlink)
index 243d4b6..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_packedtags2.c
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_packedtags2.h b/fs/yaffs2/direct/yaffs_packedtags2.h
deleted file mode 120000 (symlink)
index bd1b3a3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_packedtags2.h
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_qsort.c b/fs/yaffs2/direct/yaffs_qsort.c
deleted file mode 120000 (symlink)
index 928ada7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_qsort.c
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_qsort.h b/fs/yaffs2/direct/yaffs_qsort.h
deleted file mode 120000 (symlink)
index 1b04c21..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_qsort.h
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_ramdisk.h b/fs/yaffs2/direct/yaffs_ramdisk.h
deleted file mode 100644 (file)
index 045ab42..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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 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.
- */
-
-/*
- * yaffs_ramdisk.h: yaffs ram disk component
- */
-
-#ifndef __YAFFS_RAMDISK_H__
-#define __YAFFS_RAMDISK_H__
-
-
-#include "yaffs_guts.h"
-int yramdisk_EraseBlockInNAND(yaffs_Device *dev, int blockNumber);
-int yramdisk_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_ExtendedTags *tags);
-int yramdisk_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_ExtendedTags *tags);
-int yramdisk_EraseBlockInNAND(yaffs_Device *dev, int blockNumber);
-int yramdisk_InitialiseNAND(yaffs_Device *dev);
-int yramdisk_MarkNANDBlockBad(yaffs_Device *dev,int blockNumber);
-int yramdisk_QueryNANDBlock(yaffs_Device *dev, int blockNo, yaffs_BlockState *state, int *sequenceNumber);
-#endif
diff --git a/fs/yaffs2/direct/yaffs_tagscompat.c b/fs/yaffs2/direct/yaffs_tagscompat.c
deleted file mode 120000 (symlink)
index 4819106..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_tagscompat.c
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_tagscompat.h b/fs/yaffs2/direct/yaffs_tagscompat.h
deleted file mode 120000 (symlink)
index bff900c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_tagscompat.h
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_tagsvalidity.c b/fs/yaffs2/direct/yaffs_tagsvalidity.c
deleted file mode 120000 (symlink)
index 4e8b83f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_tagsvalidity.c
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffs_tagsvalidity.h b/fs/yaffs2/direct/yaffs_tagsvalidity.h
deleted file mode 120000 (symlink)
index b7bb014..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffs_tagsvalidity.h
\ No newline at end of file
diff --git a/fs/yaffs2/direct/yaffscfg.c b/fs/yaffs2/direct/yaffscfg.c
deleted file mode 100644 (file)
index a4a0924..0000000
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * 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.
- */
-
-/*
- * yaffscfg.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.
- */
-
-/* XXX U-BOOT XXX */
-#include <common.h>
-
-#include <config.h>
-#include "nand.h"
-#include "yaffscfg.h"
-#include "yaffsfs.h"
-#include "yaffs_packedtags2.h"
-#include "yaffs_mtdif.h"
-#include "yaffs_mtdif2.h"
-#if 0
-#include <errno.h>
-#else
-#include "malloc.h"
-#endif
-
-unsigned yaffs_traceMask = 0xFFFFFFFF;
-static int yaffs_errno = 0;
-
-void yaffsfs_SetError(int err)
-{
-       //Do whatever to set error
-       yaffs_errno = err;
-}
-
-int yaffsfs_GetError(void)
-{
-       return yaffs_errno;
-}
-
-void yaffsfs_Lock(void)
-{
-}
-
-void yaffsfs_Unlock(void)
-{
-}
-
-__u32 yaffsfs_CurrentTime(void)
-{
-       return 0;
-}
-
-void *yaffs_malloc(size_t size)
-{
-       return malloc(size);
-}
-
-void yaffs_free(void *ptr)
-{
-       free(ptr);
-}
-
-void yaffsfs_LocalInitialisation(void)
-{
-       // Define locking semaphore.
-}
-
-// Configuration for:
-// /ram  2MB ramdisk
-// /boot 2MB boot disk (flash)
-// /flash 14MB flash disk (flash)
-// NB Though /boot and /flash occupy the same physical device they
-// are still disticnt "yaffs_Devices. You may think of these as "partitions"
-// using non-overlapping areas in the same device.
-// 
-
-#include "yaffs_ramdisk.h"
-#include "yaffs_flashif.h"
-
-static int isMounted = 0;
-#define MOUNT_POINT "/flash"
-extern nand_info_t nand_info[];
-
-/* XXX U-BOOT XXX */
-#if 0
-static yaffs_Device ramDev;
-static yaffs_Device bootDev;
-static yaffs_Device flashDev;
-#endif
-
-static yaffsfs_DeviceConfiguration yaffsfs_config[] = {
-/* XXX U-BOOT XXX */
-#if 0
-       { "/ram", &ramDev},
-       { "/boot", &bootDev},
-       { "/flash", &flashDev},
-#else
-       { MOUNT_POINT, 0},
-#endif
-       {(void *)0,(void *)0}
-};
-
-
-int yaffs_StartUp(void)
-{
-       struct mtd_info *mtd = &nand_info[0];
-       int yaffsVersion = 2;
-       int nBlocks;
-
-       yaffs_Device *flashDev = calloc(1, sizeof(yaffs_Device));
-       yaffsfs_config[0].dev = flashDev;
-
-       // Stuff to configure YAFFS
-       // Stuff to initialise anything special (eg lock semaphore).
-       yaffsfs_LocalInitialisation();
-       
-       // Set up devices
-
-/* XXX U-BOOT XXX */
-#if 0
-       // /ram
-       ramDev.nBytesPerChunk = 512;
-       ramDev.nChunksPerBlock = 32;
-       ramDev.nReservedBlocks = 2; // Set this smaller for RAM
-       ramDev.startBlock = 1; // Can't use block 0
-       ramDev.endBlock = 127; // Last block in 2MB.    
-       ramDev.useNANDECC = 1;
-       ramDev.nShortOpCaches = 0;      // Disable caching on this device.
-       ramDev.genericDevice = (void *) 0;      // Used to identify the device in fstat.
-       ramDev.writeChunkWithTagsToNAND = yramdisk_WriteChunkWithTagsToNAND;
-       ramDev.readChunkWithTagsFromNAND = yramdisk_ReadChunkWithTagsFromNAND;
-       ramDev.eraseBlockInNAND = yramdisk_EraseBlockInNAND;
-       ramDev.initialiseNAND = yramdisk_InitialiseNAND;
-
-       // /boot
-       bootDev.nBytesPerChunk = 612;
-       bootDev.nChunksPerBlock = 32;
-       bootDev.nReservedBlocks = 5;
-       bootDev.startBlock = 1; // Can't use block 0
-       bootDev.endBlock = 127; // Last block in 2MB.   
-       bootDev.useNANDECC = 0; // use YAFFS's ECC
-       bootDev.nShortOpCaches = 10; // Use caches
-       bootDev.genericDevice = (void *) 1;     // Used to identify the device in fstat.
-       bootDev.writeChunkToNAND = yflash_WriteChunkToNAND;
-       bootDev.readChunkFromNAND = yflash_ReadChunkFromNAND;
-       bootDev.eraseBlockInNAND = yflash_EraseBlockInNAND;
-       bootDev.initialiseNAND = yflash_InitialiseNAND;
-#endif
-
-               // /flash
-       flashDev->nReservedBlocks = 5;
-//  flashDev->nShortOpCaches = (options.no_cache) ? 0 : 10;
-       flashDev->nShortOpCaches = 10; // Use caches
-       flashDev->useNANDECC = 0; // do not use YAFFS's ECC
-
-       if (yaffsVersion == 2)
-       {
-               flashDev->writeChunkWithTagsToNAND = nandmtd2_WriteChunkWithTagsToNAND;
-               flashDev->readChunkWithTagsFromNAND = nandmtd2_ReadChunkWithTagsFromNAND;
-               flashDev->markNANDBlockBad = nandmtd2_MarkNANDBlockBad;
-               flashDev->queryNANDBlock = nandmtd2_QueryNANDBlock;
-               flashDev->spareBuffer = YMALLOC(mtd->oobsize);
-               flashDev->isYaffs2 = 1;
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-               flashDev->nDataBytesPerChunk = mtd->writesize;
-               flashDev->nChunksPerBlock = mtd->erasesize / mtd->writesize;
-#else
-               flashDev->nDataBytesPerChunk = mtd->oobblock;
-               flashDev->nChunksPerBlock = mtd->erasesize / mtd->oobblock;
-#endif
-               nBlocks = mtd->size / mtd->erasesize;
-
-               flashDev->nCheckpointReservedBlocks = 10;
-               flashDev->startBlock = 0;
-               flashDev->endBlock = nBlocks - 1;
-       }
-       else
-       {
-               flashDev->writeChunkToNAND = nandmtd_WriteChunkToNAND;
-               flashDev->readChunkFromNAND = nandmtd_ReadChunkFromNAND;
-               flashDev->isYaffs2 = 0;
-               nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
-               flashDev->startBlock = 320;
-               flashDev->endBlock = nBlocks - 1;
-               flashDev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
-               flashDev->nDataBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
-       }
-       
-       /* ... and common functions */
-       flashDev->eraseBlockInNAND = nandmtd_EraseBlockInNAND;
-       flashDev->initialiseNAND = nandmtd_InitialiseNAND;
-
-       yaffs_initialise(yaffsfs_config);
-       
-       return 0;
-}
-
-
-void make_a_file(char *yaffsName,char bval,int sizeOfFile)
-{
-       int outh;
-       int i;
-       unsigned char buffer[100];
-
-       outh = yaffs_open(yaffsName, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
-       if (outh < 0)
-       {
-               printf("Error opening file: %d\n", outh);
-               return;
-       }
-       
-       memset(buffer,bval,100);
-       
-       do{
-               i = sizeOfFile;
-               if(i > 100) i = 100;
-               sizeOfFile -= i;
-               
-               yaffs_write(outh,buffer,i);
-               
-       } while (sizeOfFile > 0);
-       
-               
-       yaffs_close(outh);
-}
-
-void read_a_file(char *fn)
-{
-       int h;
-       int i = 0;
-       unsigned char b;
-
-       h = yaffs_open(fn, O_RDWR,0);
-       if(h<0)
-       {
-               printf("File not found\n");
-               return;
-       }
-
-       while(yaffs_read(h,&b,1)> 0)
-       {
-               printf("%02x ",b);
-               i++;
-               if(i > 32) 
-               {
-                  printf("\n");
-                  i = 0;;
-                }
-       }
-       printf("\n");
-       yaffs_close(h);
-}
-
-void cmd_yaffs_mount(char *mp)
-{
-       yaffs_StartUp();
-       int retval = yaffs_mount(mp);
-       if( retval != -1)
-               isMounted = 1;
-       else
-               printf("Error mounting %s, return value: %d\n", mp, yaffsfs_GetError());
-}
-
-static void checkMount(void)
-{
-       if( !isMounted )
-       {
-               cmd_yaffs_mount(MOUNT_POINT);
-       }
-}
-
-void cmd_yaffs_umount(char *mp)
-{
-       checkMount();
-       if( yaffs_unmount(mp) == -1)
-               printf("Error umounting %s, return value: %d\n", mp, yaffsfs_GetError());
-}
-
-void cmd_yaffs_write_file(char *yaffsName,char bval,int sizeOfFile)
-{
-       checkMount();
-       make_a_file(yaffsName,bval,sizeOfFile);
-}
-
-
-void cmd_yaffs_read_file(char *fn)
-{
-       checkMount();
-       read_a_file(fn);
-}
-
-
-void cmd_yaffs_mread_file(char *fn, char *addr)
-{
-       int h;
-       struct yaffs_stat s;
-       
-       checkMount();
-
-       yaffs_stat(fn,&s);
-
-       printf ("Copy %s to 0x%08x... ", fn, addr);
-       h = yaffs_open(fn, O_RDWR,0);
-       if(h<0)
-       {
-               printf("File not found\n");
-               return;
-       }
-                               
-       yaffs_read(h,addr,(int)s.st_size);
-       printf("\t[DONE]\n");
-
-       yaffs_close(h);
-}
-
-
-void cmd_yaffs_mwrite_file(char *fn, char *addr, int size)
-{
-       int outh;
-
-       checkMount();
-       outh = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
-       if (outh < 0)
-       {
-               printf("Error opening file: %d\n", outh);
-       }
-       
-       yaffs_write(outh,addr,size);
-       
-       yaffs_close(outh);
-}
-
-
-void cmd_yaffs_ls(const char *mountpt, int longlist)
-{
-       int i;
-       yaffs_DIR *d;
-       yaffs_dirent *de;
-       struct yaffs_stat stat;
-       char tempstr[255];
-
-       checkMount();
-       d = yaffs_opendir(mountpt);
-
-       if(!d)
-       {
-               printf("opendir failed\n");
-       }
-       else
-       {
-               for(i = 0; (de = yaffs_readdir(d)) != NULL; i++)
-               {
-                       if (longlist)
-                       {
-                               sprintf(tempstr, "%s/%s", mountpt, de->d_name);
-                               yaffs_stat(tempstr, &stat);
-                               printf("%-25s\t%7d\n",de->d_name, stat.st_size);
-                       }
-                       else
-                       {
-                               printf("%s\n",de->d_name);
-                       }
-               }
-       }
-}
-
-
-void cmd_yaffs_mkdir(const char *dir)
-{
-       checkMount();
-
-       int retval = yaffs_mkdir(dir, 0);
-       
-       if ( retval < 0)
-               printf("yaffs_mkdir returning error: %d\n", retval);
-}
-
-void cmd_yaffs_rmdir(const char *dir)
-{
-       checkMount();
-
-       int retval = yaffs_rmdir(dir);
-       
-       if ( retval < 0)
-               printf("yaffs_rmdir returning error: %d\n", retval);
-}
-
-void cmd_yaffs_rm(const char *path)
-{
-       checkMount();
-
-       int retval = yaffs_unlink(path);
-       
-       if ( retval < 0)
-               printf("yaffs_unlink returning error: %d\n", retval);
-}
-
-void cmd_yaffs_mv(const char *oldPath, const char *newPath)
-{
-       checkMount();
-
-       int retval = yaffs_rename(newPath, oldPath);
-       
-       if ( retval < 0)
-               printf("yaffs_unlink returning error: %d\n", retval);
-}
diff --git a/fs/yaffs2/direct/yaffscfg.h b/fs/yaffs2/direct/yaffscfg.h
deleted file mode 100644 (file)
index 6ae1696..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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 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.
- */
-
-/*
- * Header file for using yaffs in an application via
- * a direct interface.
- */
-
-
-#ifndef __YAFFSCFG_H__
-#define __YAFFSCFG_H__
-
-
-#include "devextras.h"
-
-#define YAFFSFS_N_HANDLES 200
-
-
-typedef struct {
-       const char *prefix;
-       struct yaffs_DeviceStruct *dev;
-} yaffsfs_DeviceConfiguration;
-
-
-void yaffsfs_Lock(void);
-void yaffsfs_Unlock(void);
-
-__u32 yaffsfs_CurrentTime(void);
-
-void yaffsfs_SetError(int err);
-int yaffsfs_GetError(void);
-
-#endif
-
diff --git a/fs/yaffs2/direct/yaffsfs.c b/fs/yaffs2/direct/yaffsfs.c
deleted file mode 100644 (file)
index f62c952..0000000
+++ /dev/null
@@ -1,1510 +0,0 @@
-/*
- * 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.
- */
-/* XXX U-BOOT XXX */
-#include <common.h>
-#include <malloc.h>
-
-#include "yaffsfs.h"
-#include "yaffs_guts.h"
-#include "yaffscfg.h"
-#include "yportenv.h"
-
-/* XXX U-BOOT XXX */
-#if 0
-#include <string.h> // for memset
-#endif
-
-#define YAFFSFS_MAX_SYMLINK_DEREFERENCES 5
-
-#ifndef NULL
-#define NULL ((void *)0)
-#endif
-
-
-const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.18 2007/07/18 19:40:38 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 char *path, int symDepth);
-static void yaffsfs_RemoveObjectCallback(yaffs_Object *obj);
-
-
-// Handle management.
-// 
-
-
-unsigned int yaffs_wr_attempts;
-
-typedef struct
-{
-       __u8  inUse:1;          // this handle is in use
-       __u8  readOnly:1;       // this handle is read only
-       __u8  append:1;         // append only
-       __u8  exclusive:1;      // exclusive
-       __u32 position;         // current position in file
-       yaffs_Object *obj;      // the object
-}yaffsfs_Handle;
-
-
-static yaffsfs_Handle yaffsfs_handle[YAFFSFS_N_HANDLES];
-
-// yaffsfs_InitHandle
-/// Inilitalise handles on start-up.
-//
-static int yaffsfs_InitHandles(void)
-{
-       int i;
-       for(i = 0; i < YAFFSFS_N_HANDLES; i++)
-       {
-               yaffsfs_handle[i].inUse = 0;
-               yaffsfs_handle[i].obj = NULL;
-       }
-       return 0;
-}
-
-yaffsfs_Handle *yaffsfs_GetHandlePointer(int h)
-{
-       if(h < 0 || h >= YAFFSFS_N_HANDLES)
-       {
-               return NULL;
-       }
-       
-       return &yaffsfs_handle[h];
-}
-
-yaffs_Object *yaffsfs_GetHandleObject(int handle)
-{
-       yaffsfs_Handle *h = yaffsfs_GetHandlePointer(handle);
-
-       if(h && h->inUse)
-       {
-               return h->obj;
-       }
-       
-       return NULL;
-}
-
-
-//yaffsfs_GetHandle
-// Grab a handle (when opening a file)
-//
-
-static int yaffsfs_GetHandle(void)
-{
-       int i;
-       yaffsfs_Handle *h;
-       
-       for(i = 0; i < YAFFSFS_N_HANDLES; i++)
-       {
-               h = yaffsfs_GetHandlePointer(i);
-               if(!h)
-               {
-                       // todo bug: should never happen
-               }
-               if(!h->inUse)
-               {
-                       memset(h,0,sizeof(yaffsfs_Handle));
-                       h->inUse=1;
-                       return i;
-               }
-       }
-       return -1;
-}
-
-// yaffs_PutHandle
-// Let go of a handle (when closing a file)
-//
-static int yaffsfs_PutHandle(int handle)
-{
-       yaffsfs_Handle *h = yaffsfs_GetHandlePointer(handle);
-       
-       if(h)
-       {
-               h->inUse = 0;
-               h->obj = NULL;
-       }
-       return 0;
-}
-
-
-
-// Stuff to search for a directory from a path
-
-
-int yaffsfs_Match(char a, char b)
-{
-       // case sensitive
-       return (a == b);
-}
-
-// yaffsfs_FindDevice
-// yaffsfs_FindRoot
-// Scan the configuration list to find the root.
-// Curveballs: Should match paths that end in '/' too
-// Curveball2 Might have "/x/ and "/x/y". Need to return the longest match
-static yaffs_Device *yaffsfs_FindDevice(const char *path, char **restOfPath)
-{
-       yaffsfs_DeviceConfiguration *cfg = yaffsfs_configurationList;
-       const char *leftOver;
-       const char *p;
-       yaffs_Device *retval = NULL;
-       int thisMatchLength;
-       int longestMatch = -1;
-       
-       // Check all configs, choose the one that:
-       // 1) Actually matches a prefix (ie /a amd /abc will not match
-       // 2) Matches the longest.
-       while(cfg && cfg->prefix && cfg->dev)
-       {
-               leftOver = path;
-               p = cfg->prefix;
-               thisMatchLength = 0;
-               
-               while(*p &&  //unmatched part of prefix 
-                     strcmp(p,"/") && // the rest of the prefix is not / (to catch / at end)
-                     *leftOver && 
-                     yaffsfs_Match(*p,*leftOver))
-               {
-                       p++;
-                       leftOver++;
-                       thisMatchLength++;
-               }
-               if((!*p || strcmp(p,"/") == 0) &&      // end of prefix
-                  (!*leftOver || *leftOver == '/') && // no more in this path name part
-                  (thisMatchLength > longestMatch))
-               {
-                       // Matched prefix
-                       *restOfPath = (char *)leftOver;
-                       retval = cfg->dev;
-                       longestMatch = thisMatchLength;
-               }
-               cfg++;
-       }
-       return retval;
-}
-
-static yaffs_Object *yaffsfs_FindRoot(const char *path, char **restOfPath)
-{
-
-       yaffs_Device *dev;
-       
-       dev= yaffsfs_FindDevice(path,restOfPath);
-       if(dev && dev->isMounted)
-       {
-               return dev->rootDir;
-       }
-       return NULL;
-}
-
-static yaffs_Object *yaffsfs_FollowLink(yaffs_Object *obj,int symDepth)
-{
-
-       while(obj && obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
-       {
-               char *alias = obj->variant.symLinkVariant.alias;
-                                               
-               if(*alias == '/')
-               {
-                       // Starts with a /, need to scan from root up
-                       obj = yaffsfs_FindObject(NULL,alias,symDepth++);
-               }
-               else
-               {
-                       // Relative to here, so use the parent of the symlink as a start
-                       obj = yaffsfs_FindObject(obj->parent,alias,symDepth++);
-               }
-       }
-       return obj;
-}
-
-
-// yaffsfs_FindDirectory
-// Parse a path to determine the directory and the name within the directory.
-//
-// eg. "/data/xx/ff" --> puts name="ff" and returns the directory "/data/xx"
-static yaffs_Object *yaffsfs_DoFindDirectory(yaffs_Object *startDir,const char *path,char **name,int symDepth)
-{
-       yaffs_Object *dir;
-       char *restOfPath;
-       char str[YAFFS_MAX_NAME_LENGTH+1];
-       int i;
-       
-       if(symDepth > YAFFSFS_MAX_SYMLINK_DEREFERENCES)
-       {
-               return NULL;
-       }
-       
-       if(startDir)
-       {
-               dir = startDir;
-               restOfPath = (char *)path;
-       }
-       else
-       {
-               dir = yaffsfs_FindRoot(path,&restOfPath);
-       }
-       
-       while(dir)
-       {       
-               // parse off /.
-               // curve ball: also throw away surplus '/' 
-               // eg. "/ram/x////ff" gets treated the same as "/ram/x/ff"
-               while(*restOfPath == '/')
-               {
-                       restOfPath++; // get rid of '/'
-               }
-               
-               *name = restOfPath;
-               i = 0;
-               
-               while(*restOfPath && *restOfPath != '/')
-               {
-                       if (i < YAFFS_MAX_NAME_LENGTH)
-                       {
-                               str[i] = *restOfPath;
-                               str[i+1] = '\0';
-                               i++;
-                       }
-                       restOfPath++;
-               }
-               
-               if(!*restOfPath)
-               {
-                       // got to the end of the string
-                       return dir;
-               }
-               else
-               {
-                       if(strcmp(str,".") == 0)
-                       {
-                               // Do nothing
-                       }
-                       else if(strcmp(str,"..") == 0)
-                       {
-                               dir = dir->parent;
-                       }
-                       else
-                       {
-                               dir = yaffs_FindObjectByName(dir,str);
-                               
-                               while(dir && dir->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
-                               {
-                               
-                                       dir = yaffsfs_FollowLink(dir,symDepth);
-               
-                               }
-                               
-                               if(dir && dir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY)
-                               {
-                                       dir = NULL;
-                               }
-                       }
-               }
-       }
-       // directory did not exist.
-       return NULL;
-}
-
-static yaffs_Object *yaffsfs_FindDirectory(yaffs_Object *relativeDirectory,const char *path,char **name,int symDepth)
-{
-       return yaffsfs_DoFindDirectory(relativeDirectory,path,name,symDepth);
-}
-
-// yaffsfs_FindObject turns a path for an existing object into the object
-// 
-static yaffs_Object *yaffsfs_FindObject(yaffs_Object *relativeDirectory, const char *path,int symDepth)
-{
-       yaffs_Object *dir;
-       char *name;
-       
-       dir = yaffsfs_FindDirectory(relativeDirectory,path,&name,symDepth);
-       
-       if(dir && *name)
-       {
-               return yaffs_FindObjectByName(dir,name);
-       }
-       
-       return dir;
-}
-
-
-
-int yaffs_open(const char *path, int oflag, int mode)
-{
-       yaffs_Object *obj = NULL;
-       yaffs_Object *dir = NULL;
-       char *name;
-       int handle = -1;
-       yaffsfs_Handle *h = NULL;
-       int alreadyOpen = 0;
-       int alreadyExclusive = 0;
-       int openDenied = 0;
-       int symDepth = 0;
-       int errorReported = 0;
-       
-       int i;
-       
-       
-       // todo sanity check oflag (eg. can't have O_TRUNC without WRONLY or RDWR
-       
-       
-       yaffsfs_Lock();
-       
-       handle = yaffsfs_GetHandle();
-       
-       if(handle >= 0)
-       {
-
-               h = yaffsfs_GetHandlePointer(handle);
-       
-       
-               // try to find the exisiting object
-               obj = yaffsfs_FindObject(NULL,path,0);
-               
-               if(obj && obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
-               {
-               
-                       obj = yaffsfs_FollowLink(obj,symDepth++);
-               }
-
-               if(obj)
-               {
-                       // Check if the object is already in use
-                       alreadyOpen = alreadyExclusive = 0;
-                       
-                       for(i = 0; i <= YAFFSFS_N_HANDLES; i++)
-                       {
-                               
-                               if(i != handle &&
-                                  yaffsfs_handle[i].inUse &&
-                                   obj == yaffsfs_handle[i].obj)
-                                {
-                                       alreadyOpen = 1;
-                                       if(yaffsfs_handle[i].exclusive)
-                                       {
-                                               alreadyExclusive = 1;
-                                       }
-                                }
-                       }
-
-                       if(((oflag & O_EXCL) && alreadyOpen) || alreadyExclusive)
-                       {
-                               openDenied = 1;
-                       }
-                       
-                       // Open should fail if O_CREAT and O_EXCL are specified
-                       if((oflag & O_EXCL) && (oflag & O_CREAT))
-                       {
-                               openDenied = 1;
-                               yaffsfs_SetError(-EEXIST);
-                               errorReported = 1;
-                       }
-                       
-                       // Check file permissions
-                       if( (oflag & (O_RDWR | O_WRONLY)) == 0 &&     // ie O_RDONLY
-                          !(obj->yst_mode & S_IREAD))
-                       {
-                               openDenied = 1;
-                       }
-
-                       if( (oflag & O_RDWR) && 
-                          !(obj->yst_mode & S_IREAD))
-                       {
-                               openDenied = 1;
-                       }
-
-                       if( (oflag & (O_RDWR | O_WRONLY)) && 
-                          !(obj->yst_mode & S_IWRITE))
-                       {
-                               openDenied = 1;
-                       }
-                       
-               }
-               
-               else if((oflag & O_CREAT))
-               {
-                       // Let's see if we can create this file
-                       dir = yaffsfs_FindDirectory(NULL,path,&name,0);
-                       if(dir)
-                       {
-                               obj = yaffs_MknodFile(dir,name,mode,0,0);       
-                       }
-                       else
-                       {
-                               yaffsfs_SetError(-ENOTDIR);
-                       }
-               }
-               
-               if(obj && !openDenied)
-               {
-                       h->obj = obj;
-                       h->inUse = 1;
-               h->readOnly = (oflag & (O_WRONLY | O_RDWR)) ? 0 : 1;
-                       h->append =  (oflag & O_APPEND) ? 1 : 0;
-                       h->exclusive = (oflag & O_EXCL) ? 1 : 0;
-                       h->position = 0;
-                       
-                       obj->inUse++;
-                       if((oflag & O_TRUNC) && !h->readOnly)
-                       {
-                               //todo truncate
-                               yaffs_ResizeFile(obj,0);
-                       }
-                       
-               }
-               else
-               {
-                       yaffsfs_PutHandle(handle);
-                       if(!errorReported)
-                       {
-                               yaffsfs_SetError(-EACCESS);
-                               errorReported = 1;
-                       }
-                       handle = -1;
-               }
-               
-       }
-       
-       yaffsfs_Unlock();
-       
-       return handle;          
-}
-
-int yaffs_close(int fd)
-{
-       yaffsfs_Handle *h = NULL;
-       int retVal = 0;
-       
-       yaffsfs_Lock();
-
-       h = yaffsfs_GetHandlePointer(fd);
-       
-       if(h && h->inUse)
-       {
-               // clean up
-               yaffs_FlushFile(h->obj,1);
-               h->obj->inUse--;
-               if(h->obj->inUse <= 0 && h->obj->unlinked)
-               {
-                       yaffs_DeleteFile(h->obj);
-               }
-               yaffsfs_PutHandle(fd);
-               retVal = 0;
-       }
-       else
-       {
-               // bad handle
-               yaffsfs_SetError(-EBADF);               
-               retVal = -1;
-       }
-       
-       yaffsfs_Unlock();
-       
-       return retVal;
-}
-
-int yaffs_read(int fd, void *buf, unsigned int nbyte)
-{
-       yaffsfs_Handle *h = NULL;
-       yaffs_Object *obj = NULL;
-       int pos = 0;
-       int nRead = -1;
-       int maxRead;
-       
-       yaffsfs_Lock();
-       h = yaffsfs_GetHandlePointer(fd);
-       obj = yaffsfs_GetHandleObject(fd);
-       
-       if(!h || !obj)
-       {
-               // bad handle
-               yaffsfs_SetError(-EBADF);               
-       }
-       else if( h && obj)
-       {
-               pos=  h->position;
-               if(yaffs_GetObjectFileLength(obj) > pos)
-               {
-                       maxRead = yaffs_GetObjectFileLength(obj) - pos;
-               }
-               else
-               {
-                       maxRead = 0;
-               }
-
-               if(nbyte > maxRead)
-               {
-                       nbyte = maxRead;
-               }
-
-               
-               if(nbyte > 0)
-               {
-                       nRead = yaffs_ReadDataFromFile(obj,buf,pos,nbyte);
-                       if(nRead >= 0)
-                       {
-                               h->position = pos + nRead;
-                       }
-                       else
-                       {
-                               //todo error
-                       }
-               }
-               else
-               {
-                       nRead = 0;
-               }
-               
-       }
-       
-       yaffsfs_Unlock();
-       
-       
-       return (nRead >= 0) ? nRead : -1;
-               
-}
-
-int yaffs_write(int fd, const void *buf, unsigned int nbyte)
-{
-       yaffsfs_Handle *h = NULL;
-       yaffs_Object *obj = NULL;
-       int pos = 0;
-       int nWritten = -1;
-       int writeThrough = 0;
-       
-       yaffsfs_Lock();
-       h = yaffsfs_GetHandlePointer(fd);
-       obj = yaffsfs_GetHandleObject(fd);
-       
-       if(!h || !obj)
-       {
-               // bad handle
-               yaffsfs_SetError(-EBADF);               
-       }
-       else if( h && obj && h->readOnly)
-       {
-               // todo error
-       }
-       else if( h && obj)
-       {
-               if(h->append)
-               {
-                       pos =  yaffs_GetObjectFileLength(obj);
-               }
-               else
-               {
-                       pos = h->position;
-               }
-               
-               nWritten = yaffs_WriteDataToFile(obj,buf,pos,nbyte,writeThrough);
-               
-               if(nWritten >= 0)
-               {
-                       h->position = pos + nWritten;
-               }
-               else
-               {
-                       //todo error
-               }
-               
-       }
-       
-       yaffsfs_Unlock();
-       
-       
-       return (nWritten >= 0) ? nWritten : -1;
-
-}
-
-int yaffs_truncate(int fd, off_t newSize)
-{
-       yaffsfs_Handle *h = NULL;
-       yaffs_Object *obj = NULL;
-       int result = 0;
-       
-       yaffsfs_Lock();
-       h = yaffsfs_GetHandlePointer(fd);
-       obj = yaffsfs_GetHandleObject(fd);
-       
-       if(!h || !obj)
-       {
-               // bad handle
-               yaffsfs_SetError(-EBADF);               
-       }
-       else
-       {
-               // resize the file
-               result = yaffs_ResizeFile(obj,newSize);
-       }       
-       yaffsfs_Unlock();
-       
-       
-       return (result) ? 0 : -1;
-
-}
-
-off_t yaffs_lseek(int fd, off_t offset, int whence) 
-{
-       yaffsfs_Handle *h = NULL;
-       yaffs_Object *obj = NULL;
-       int pos = -1;
-       int fSize = -1;
-       
-       yaffsfs_Lock();
-       h = yaffsfs_GetHandlePointer(fd);
-       obj = yaffsfs_GetHandleObject(fd);
-       
-       if(!h || !obj)
-       {
-               // bad handle
-               yaffsfs_SetError(-EBADF);               
-       }
-       else if(whence == SEEK_SET)
-       {
-               if(offset >= 0)
-               {
-                       pos = offset;
-               }
-       }
-       else if(whence == SEEK_CUR)
-       {
-               if( (h->position + offset) >= 0)
-               {
-                       pos = (h->position + offset);
-               }
-       }
-       else if(whence == SEEK_END)
-       {
-               fSize = yaffs_GetObjectFileLength(obj);
-               if(fSize >= 0 && (fSize + offset) >= 0)
-               {
-                       pos = fSize + offset;
-               }
-       }
-       
-       if(pos >= 0)
-       {
-               h->position = pos;
-       }
-       else
-       {
-               // todo error
-       }
-
-       
-       yaffsfs_Unlock();
-       
-       return pos;
-}
-
-
-int yaffsfs_DoUnlink(const char *path,int isDirectory) 
-{
-       yaffs_Object *dir = NULL;
-       yaffs_Object *obj = NULL;
-       char *name;
-       int result = YAFFS_FAIL;
-       
-       yaffsfs_Lock();
-
-       obj = yaffsfs_FindObject(NULL,path,0);
-       dir = yaffsfs_FindDirectory(NULL,path,&name,0);
-       if(!dir)
-       {
-               yaffsfs_SetError(-ENOTDIR);
-       }
-       else if(!obj)
-       {
-               yaffsfs_SetError(-ENOENT);
-       }
-       else if(!isDirectory && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)
-       {
-               yaffsfs_SetError(-EISDIR);
-       }
-       else if(isDirectory && obj->variantType != YAFFS_OBJECT_TYPE_DIRECTORY)
-       {
-               yaffsfs_SetError(-ENOTDIR);
-       }
-       else
-       {
-               result = yaffs_Unlink(dir,name);
-               
-               if(result == YAFFS_FAIL && isDirectory)
-               {
-                       yaffsfs_SetError(-ENOTEMPTY);
-               }
-       }
-       
-       yaffsfs_Unlock();
-       
-       // todo error
-       
-       return (result == YAFFS_FAIL) ? -1 : 0;
-}
-int yaffs_rmdir(const char *path) 
-{
-       return yaffsfs_DoUnlink(path,1);
-}
-
-int yaffs_unlink(const char *path) 
-{
-       return yaffsfs_DoUnlink(path,0);
-}
-
-int yaffs_rename(const char *oldPath, const char *newPath)
-{
-       yaffs_Object *olddir = NULL;
-       yaffs_Object *newdir = NULL;
-       yaffs_Object *obj = NULL;
-       char *oldname;
-       char *newname;
-       int result= YAFFS_FAIL;
-       int renameAllowed = 1;
-       
-       yaffsfs_Lock();
-       
-       olddir = yaffsfs_FindDirectory(NULL,oldPath,&oldname,0);
-       newdir = yaffsfs_FindDirectory(NULL,newPath,&newname,0);
-       obj = yaffsfs_FindObject(NULL,oldPath,0);
-       
-       if(!olddir || !newdir || !obj)
-       {
-               // bad file
-               yaffsfs_SetError(-EBADF);       
-               renameAllowed = 0;      
-       }
-       else if(olddir->myDev != newdir->myDev)
-       {
-               // oops must be on same device
-               // todo error
-               yaffsfs_SetError(-EXDEV);
-               renameAllowed = 0;      
-       }
-       else if(obj && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)
-       {
-               // It is a directory, check that it is not being renamed to 
-               // being its own decendent.
-               // Do this by tracing from the new directory back to the root, checking for obj
-               
-               yaffs_Object *xx = newdir;
-               
-               while( renameAllowed && xx)
-               {
-                       if(xx == obj)
-                       {
-                               renameAllowed = 0;
-                       }
-                       xx = xx->parent;
-               }
-               if(!renameAllowed) yaffsfs_SetError(-EACCESS);
-       }
-       
-       if(renameAllowed)
-       {
-               result = yaffs_RenameObject(olddir,oldname,newdir,newname);
-       }
-       
-       yaffsfs_Unlock();
-       
-       return (result == YAFFS_FAIL) ? -1 : 0; 
-}
-
-
-static int yaffsfs_DoStat(yaffs_Object *obj,struct yaffs_stat *buf)
-{
-       int retVal = -1;
-
-       if(obj)
-       {
-               obj = yaffs_GetEquivalentObject(obj);
-       }
-
-       if(obj && buf)
-       {
-       buf->st_dev = (int)obj->myDev->genericDevice;
-       buf->st_ino = obj->objectId;
-       buf->st_mode = obj->yst_mode & ~S_IFMT; // clear out file type bits
-       
-               if(obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) 
-               {
-                       buf->st_mode |= S_IFDIR;
-               }
-               else if(obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK) 
-               {
-                       buf->st_mode |= S_IFLNK;
-               }
-               else if(obj->variantType == YAFFS_OBJECT_TYPE_FILE)
-               {
-                       buf->st_mode |= S_IFREG;
-               }
-               
-       buf->st_nlink = yaffs_GetObjectLinkCount(obj);
-       buf->st_uid = 0;    
-       buf->st_gid = 0;;     
-       buf->st_rdev = obj->yst_rdev;
-       buf->st_size = yaffs_GetObjectFileLength(obj);
-               buf->st_blksize = obj->myDev->nDataBytesPerChunk;
-       buf->st_blocks = (buf->st_size + buf->st_blksize -1)/buf->st_blksize;
-       buf->yst_atime = obj->yst_atime; 
-       buf->yst_ctime = obj->yst_ctime; 
-       buf->yst_mtime = obj->yst_mtime; 
-               retVal = 0;
-       }
-       return retVal;
-}
-
-static int yaffsfs_DoStatOrLStat(const char *path, struct yaffs_stat *buf,int doLStat)
-{
-       yaffs_Object *obj;
-       
-       int retVal = -1;
-       
-       yaffsfs_Lock();
-       obj = yaffsfs_FindObject(NULL,path,0);
-       
-       if(!doLStat && obj)
-       {
-               obj = yaffsfs_FollowLink(obj,0);
-       }
-       
-       if(obj)
-       {
-               retVal = yaffsfs_DoStat(obj,buf);
-       }
-       else
-       {
-               // todo error not found
-               yaffsfs_SetError(-ENOENT);
-       }
-       
-       yaffsfs_Unlock();
-       
-       return retVal;
-       
-}
-
-int yaffs_stat(const char *path, struct yaffs_stat *buf)
-{
-       return yaffsfs_DoStatOrLStat(path,buf,0);
-}
-
-int yaffs_lstat(const char *path, struct yaffs_stat *buf)
-{
-       return yaffsfs_DoStatOrLStat(path,buf,1);
-}
-
-int yaffs_fstat(int fd, struct yaffs_stat *buf)
-{
-       yaffs_Object *obj;
-       
-       int retVal = -1;
-       
-       yaffsfs_Lock();
-       obj = yaffsfs_GetHandleObject(fd);
-       
-       if(obj)
-       {
-               retVal = yaffsfs_DoStat(obj,buf);
-       }
-       else
-       {
-               // bad handle
-               yaffsfs_SetError(-EBADF);               
-       }
-       
-       yaffsfs_Unlock();
-       
-       return retVal;
-}
-
-static int yaffsfs_DoChMod(yaffs_Object *obj,mode_t mode)
-{
-       int result = YAFFS_FAIL;
-
-       if(obj)
-       {
-               obj = yaffs_GetEquivalentObject(obj);
-       }
-       
-       if(obj)
-       {
-               obj->yst_mode = mode;
-               obj->dirty = 1;
-               result = yaffs_FlushFile(obj,0);
-       }
-       
-       return result == YAFFS_OK ? 0 : -1;
-}
-
-
-int yaffs_chmod(const char *path, mode_t mode)
-{
-       yaffs_Object *obj;
-       
-       int retVal = -1;
-       
-       yaffsfs_Lock();
-       obj = yaffsfs_FindObject(NULL,path,0);
-       
-       if(obj)
-       {
-               retVal = yaffsfs_DoChMod(obj,mode);
-       }
-       else
-       {
-               // todo error not found
-               yaffsfs_SetError(-ENOENT);
-       }
-       
-       yaffsfs_Unlock();
-       
-       return retVal;
-       
-}
-
-
-int yaffs_fchmod(int fd, mode_t mode)
-{
-       yaffs_Object *obj;
-       
-       int retVal = -1;
-       
-       yaffsfs_Lock();
-       obj = yaffsfs_GetHandleObject(fd);
-       
-       if(obj)
-       {
-               retVal = yaffsfs_DoChMod(obj,mode);
-       }
-       else
-       {
-               // bad handle
-               yaffsfs_SetError(-EBADF);               
-       }
-       
-       yaffsfs_Unlock();
-       
-       return retVal;
-}
-
-
-int yaffs_mkdir(const char *path, mode_t mode)
-{
-       yaffs_Object *parent = NULL;
-       yaffs_Object *dir = NULL;
-       char *name;
-       int retVal= -1;
-       
-       yaffsfs_Lock();
-       parent = yaffsfs_FindDirectory(NULL,path,&name,0);
-       if(parent)
-               dir = yaffs_MknodDirectory(parent,name,mode,0,0);
-       if(dir)
-       {
-               retVal = 0;
-       }
-       else
-       {
-               yaffsfs_SetError(-ENOSPC); // just assume no space for now
-               retVal = -1;
-       }
-       
-       yaffsfs_Unlock();
-       
-       return retVal;
-}
-
-int yaffs_mount(const char *path)
-{
-       int retVal=-1;
-       int result=YAFFS_FAIL;
-       yaffs_Device *dev=NULL;
-       char *dummy;
-       
-       T(YAFFS_TRACE_ALWAYS,("yaffs: Mounting %s\n",path));
-       
-       yaffsfs_Lock();
-       dev = yaffsfs_FindDevice(path,&dummy);
-       if(dev)
-       {
-               if(!dev->isMounted)
-               {
-                       result = yaffs_GutsInitialise(dev);
-                       if(result == YAFFS_FAIL)
-                       {
-                               // todo error - mount failed
-                               yaffsfs_SetError(-ENOMEM);
-                       }
-                       retVal = result ? 0 : -1;
-                       
-               }
-               else
-               {
-                       //todo error - already mounted.
-                       yaffsfs_SetError(-EBUSY);
-               }
-       }
-       else
-       {
-               // todo error - no device
-               yaffsfs_SetError(-ENODEV);
-       }
-       yaffsfs_Unlock();
-       return retVal;
-       
-}
-
-int yaffs_unmount(const char *path)
-{
-       int retVal=-1;
-       yaffs_Device *dev=NULL;
-       char *dummy;
-       
-       yaffsfs_Lock();
-       dev = yaffsfs_FindDevice(path,&dummy);
-       if(dev)
-       {
-               if(dev->isMounted)
-               {
-                       int i;
-                       int inUse;
-                       
-                       yaffs_FlushEntireDeviceCache(dev);
-                       yaffs_CheckpointSave(dev);
-                       
-                       for(i = inUse = 0; i < YAFFSFS_N_HANDLES && !inUse; i++)
-                       {
-                               if(yaffsfs_handle[i].inUse && yaffsfs_handle[i].obj->myDev == dev)
-                               {
-                                       inUse = 1; // the device is in use, can't unmount
-                               }
-                       }
-                       
-                       if(!inUse)
-                       {
-                               yaffs_Deinitialise(dev);
-                                       
-                               retVal = 0;
-                       }
-                       else
-                       {
-                               // todo error can't unmount as files are open
-                               yaffsfs_SetError(-EBUSY);
-                       }
-                       
-               }
-               else
-               {
-                       //todo error - not mounted.
-                       yaffsfs_SetError(-EINVAL);
-                       
-               }
-       }
-       else
-       {
-               // todo error - no device
-               yaffsfs_SetError(-ENODEV);
-       }       
-       yaffsfs_Unlock();
-       return retVal;
-       
-}
-
-loff_t yaffs_freespace(const char *path)
-{
-       loff_t retVal=-1;
-       yaffs_Device *dev=NULL;
-       char *dummy;
-       
-       yaffsfs_Lock();
-       dev = yaffsfs_FindDevice(path,&dummy);
-       if(dev  && dev->isMounted)
-       {
-               retVal = yaffs_GetNumberOfFreeChunks(dev);
-               retVal *= dev->nDataBytesPerChunk;
-               
-       }
-       else
-       {
-               yaffsfs_SetError(-EINVAL);
-       }
-       
-       yaffsfs_Unlock();
-       return retVal;  
-}
-
-
-
-void yaffs_initialise(yaffsfs_DeviceConfiguration *cfgList)
-{
-       
-       yaffsfs_DeviceConfiguration *cfg;
-       
-       yaffsfs_configurationList = cfgList;
-       
-       yaffsfs_InitHandles();
-       
-       cfg = yaffsfs_configurationList;
-       
-       while(cfg && cfg->prefix && cfg->dev)
-       {
-               cfg->dev->isMounted = 0;
-               cfg->dev->removeObjectCallback = yaffsfs_RemoveObjectCallback;
-               cfg++;
-       }
-}
-
-
-//
-// Directory search stuff.
-
-//
-// Directory search context
-//
-// NB this is an opaque structure.
-
-
-typedef struct
-{
-       __u32 magic;
-       yaffs_dirent de;                /* directory entry being used by this dsc */
-       char name[NAME_MAX+1];          /* name of directory being searched */
-       yaffs_Object *dirObj;           /* ptr to directory being searched */
-       yaffs_Object *nextReturn;       /* obj to be returned by next readddir */
-       int offset;
-       struct list_head others;        
-} yaffsfs_DirectorySearchContext;
-
-
-
-static struct list_head search_contexts;
-
-
-static void yaffsfs_SetDirRewound(yaffsfs_DirectorySearchContext *dsc)
-{
-       if(dsc &&
-          dsc->dirObj &&
-          dsc->dirObj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY){
-          
-          dsc->offset = 0;
-          
-          if( list_empty(&dsc->dirObj->variant.directoryVariant.children)){
-               dsc->nextReturn = NULL;
-          } else {
-               dsc->nextReturn = list_entry(dsc->dirObj->variant.directoryVariant.children.next,
-                                               yaffs_Object,siblings);
-          }
-       } else {
-               /* Hey someone isn't playing nice! */
-       }
-}
-
-static void yaffsfs_DirAdvance(yaffsfs_DirectorySearchContext *dsc)
-{
-       if(dsc &&
-          dsc->dirObj &&
-          dsc->dirObj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY){
-          
-          if( dsc->nextReturn == NULL ||
-              list_empty(&dsc->dirObj->variant.directoryVariant.children)){
-               dsc->nextReturn = NULL;
-          } else {
-                  struct list_head *next = dsc->nextReturn->siblings.next;
-   
-                  if( next == &dsc->dirObj->variant.directoryVariant.children)
-                       dsc->nextReturn = NULL; /* end of list */
-                  else 
-                       dsc->nextReturn = list_entry(next,yaffs_Object,siblings);
-          }
-       } else {
-               /* Hey someone isn't playing nice! */
-       }
-}
-
-static void yaffsfs_RemoveObjectCallback(yaffs_Object *obj)
-{
-
-       struct list_head *i;
-       yaffsfs_DirectorySearchContext *dsc;
-       
-       /* if search contexts not initilised then skip */
-       if(!search_contexts.next)
-               return;
-               
-       /* Iteratethrough the directory search contexts.
-        * If any are the one being removed, then advance the dsc to
-        * the next one to prevent a hanging ptr.
-        */
-        list_for_each(i, &search_contexts) {
-               if (i) {
-                       dsc = list_entry(i, yaffsfs_DirectorySearchContext,others);
-                       if(dsc->nextReturn == obj)
-                               yaffsfs_DirAdvance(dsc);
-               }
-       }
-                               
-}
-
-yaffs_DIR *yaffs_opendir(const char *dirname)
-{
-       yaffs_DIR *dir = NULL;
-       yaffs_Object *obj = NULL;
-       yaffsfs_DirectorySearchContext *dsc = NULL;
-       
-       yaffsfs_Lock();
-       
-       obj = yaffsfs_FindObject(NULL,dirname,0);
-       
-       if(obj && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)
-       {
-               
-               dsc = YMALLOC(sizeof(yaffsfs_DirectorySearchContext));
-               dir = (yaffs_DIR *)dsc;
-               if(dsc)
-               {
-                       memset(dsc,0,sizeof(yaffsfs_DirectorySearchContext));
-                       dsc->magic = YAFFS_MAGIC;
-                       dsc->dirObj = obj;
-                       strncpy(dsc->name,dirname,NAME_MAX);
-                       INIT_LIST_HEAD(&dsc->others);
-                       
-                       if(!search_contexts.next)
-                               INIT_LIST_HEAD(&search_contexts);
-                               
-                       list_add(&dsc->others,&search_contexts);        
-                       yaffsfs_SetDirRewound(dsc);             }
-       
-       }
-       
-       yaffsfs_Unlock();
-       
-       return dir;
-}
-
-struct yaffs_dirent *yaffs_readdir(yaffs_DIR *dirp)
-{
-       yaffsfs_DirectorySearchContext *dsc = (yaffsfs_DirectorySearchContext *)dirp;
-       struct yaffs_dirent *retVal = NULL;
-               
-       yaffsfs_Lock();
-       
-       if(dsc && dsc->magic == YAFFS_MAGIC){
-               yaffsfs_SetError(0);
-               if(dsc->nextReturn){
-                       dsc->de.d_ino = yaffs_GetEquivalentObject(dsc->nextReturn)->objectId;
-                       dsc->de.d_dont_use = (unsigned)dsc->nextReturn;
-                       dsc->de.d_off = dsc->offset++;
-                       yaffs_GetObjectName(dsc->nextReturn,dsc->de.d_name,NAME_MAX);
-                       if(strlen(dsc->de.d_name) == 0)
-                       {
-                               // this should not happen!
-                               strcpy(dsc->de.d_name,"zz");
-                       }
-                       dsc->de.d_reclen = sizeof(struct yaffs_dirent);
-                       retVal = &dsc->de;
-                       yaffsfs_DirAdvance(dsc);
-               } else
-                       retVal = NULL;
-       }
-       else
-       {
-               yaffsfs_SetError(-EBADF);
-       }
-       
-       yaffsfs_Unlock();
-       
-       return retVal;
-       
-}
-
-
-void yaffs_rewinddir(yaffs_DIR *dirp)
-{
-       yaffsfs_DirectorySearchContext *dsc = (yaffsfs_DirectorySearchContext *)dirp;
-       
-       yaffsfs_Lock();
-       
-       yaffsfs_SetDirRewound(dsc);
-
-       yaffsfs_Unlock();
-}
-
-
-int yaffs_closedir(yaffs_DIR *dirp)
-{
-       yaffsfs_DirectorySearchContext *dsc = (yaffsfs_DirectorySearchContext *)dirp;
-               
-       yaffsfs_Lock();
-       dsc->magic = 0;
-       list_del(&dsc->others); /* unhook from list */
-       YFREE(dsc);
-       yaffsfs_Unlock();
-       return 0;
-}
-
-// end of directory stuff
-
-
-int yaffs_symlink(const char *oldpath, const char *newpath)
-{
-       yaffs_Object *parent = NULL;
-       yaffs_Object *obj;
-       char *name;
-       int retVal= -1;
-       int mode = 0; // ignore for now
-       
-       yaffsfs_Lock();
-       parent = yaffsfs_FindDirectory(NULL,newpath,&name,0);
-       obj = yaffs_MknodSymLink(parent,name,mode,0,0,oldpath);
-       if(obj)
-       {
-               retVal = 0;
-       }
-       else
-       {
-               yaffsfs_SetError(-ENOSPC); // just assume no space for now
-               retVal = -1;
-       }
-       
-       yaffsfs_Unlock();
-       
-       return retVal;
-       
-}
-
-int yaffs_readlink(const char *path, char *buf, int bufsiz)
-{
-       yaffs_Object *obj = NULL;
-       int retVal;
-
-               
-       yaffsfs_Lock();
-       
-       obj = yaffsfs_FindObject(NULL,path,0);
-       
-       if(!obj)
-       {
-               yaffsfs_SetError(-ENOENT);
-               retVal = -1;
-       }
-       else if(obj->variantType != YAFFS_OBJECT_TYPE_SYMLINK)
-       {
-               yaffsfs_SetError(-EINVAL);
-               retVal = -1;
-       }
-       else
-       {
-               char *alias = obj->variant.symLinkVariant.alias;
-               memset(buf,0,bufsiz);
-               strncpy(buf,alias,bufsiz - 1);
-               retVal = 0;
-       }
-       yaffsfs_Unlock();
-       return retVal;
-}
-
-int yaffs_link(const char *oldpath, const char *newpath)
-{
-       // Creates a link called newpath to existing oldpath
-       yaffs_Object *obj = NULL;
-       yaffs_Object *target = NULL;
-       int retVal = 0;
-
-               
-       yaffsfs_Lock();
-       
-       obj = yaffsfs_FindObject(NULL,oldpath,0);
-       target = yaffsfs_FindObject(NULL,newpath,0);
-       
-       if(!obj)
-       {
-               yaffsfs_SetError(-ENOENT);
-               retVal = -1;
-       }
-       else if(target)
-       {
-               yaffsfs_SetError(-EEXIST);
-               retVal = -1;
-       }
-       else    
-       {
-               yaffs_Object *newdir = NULL;
-               yaffs_Object *link = NULL;
-               
-               char *newname;
-               
-               newdir = yaffsfs_FindDirectory(NULL,newpath,&newname,0);
-               
-               if(!newdir)
-               {
-                       yaffsfs_SetError(-ENOTDIR);
-                       retVal = -1;
-               }
-               else if(newdir->myDev != obj->myDev)
-               {
-                       yaffsfs_SetError(-EXDEV);
-                       retVal = -1;
-               }
-               if(newdir && strlen(newname) > 0)
-               {
-                       link = yaffs_Link(newdir,newname,obj);
-                       if(link)
-                               retVal = 0;
-                       else
-                       {
-                               yaffsfs_SetError(-ENOSPC);
-                               retVal = -1;
-                       }
-
-               }
-       }
-       yaffsfs_Unlock();
-       
-       return retVal;
-}
-
-int yaffs_mknod(const char *pathname, mode_t mode, dev_t dev);
-
-int yaffs_DumpDevStruct(const char *path)
-{
-       char *rest;
-       
-       yaffs_Object *obj = yaffsfs_FindRoot(path,&rest);
-       
-       if(obj)
-       {
-               yaffs_Device *dev = obj->myDev;
-               
-               printf("\n"
-                          "nPageWrites.......... %d\n"
-                          "nPageReads........... %d\n"
-                          "nBlockErasures....... %d\n"
-                          "nGCCopies............ %d\n"
-                          "garbageCollections... %d\n"
-                          "passiveGarbageColl'ns %d\n"
-                          "\n",
-                               dev->nPageWrites,
-                               dev->nPageReads,
-                               dev->nBlockErasures,
-                               dev->nGCCopies,
-                               dev->garbageCollections,
-                               dev->passiveGarbageCollections
-               );
-               
-       }
-       return 0;
-}
diff --git a/fs/yaffs2/direct/yaffsfs.h b/fs/yaffs2/direct/yaffsfs.h
deleted file mode 100644 (file)
index 9afe60a..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * 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 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.
- */
-
-/*
- * Header file for using yaffs in an application via
- * a direct interface.
- */
-
-
-#ifndef __YAFFSFS_H__
-#define __YAFFSFS_H__
-
-#include "yaffscfg.h"
-#include "yportenv.h"
-
-
-//typedef long off_t;
-//typedef long dev_t;
-//typedef unsigned long mode_t;
-
-
-#ifndef NAME_MAX
-#define NAME_MAX       256
-#endif
-
-#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 EACCESS
-#define EACCESS        13
-#endif
-
-#ifndef EXDEV  
-#define EXDEV  18
-#endif
-
-#ifndef ENOENT
-#define ENOENT 2
-#endif
-
-#ifndef ENOSPC
-#define ENOSPC 28
-#endif
-
-#ifndef ENOTEMPTY
-#define ENOTEMPTY 39
-#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
-
-
-
-
-struct yaffs_dirent{
-    long d_ino;                 /* inode number */
-    off_t d_off;                /* offset to this dirent */
-    unsigned short d_reclen;    /* length of this d_name */
-    char d_name [NAME_MAX+1];   /* file name (null-terminated) */
-    unsigned d_dont_use;       /* debug pointer, not for public consumption */
-};
-
-typedef struct yaffs_dirent yaffs_dirent;
-
-
-typedef struct __opaque yaffs_DIR;
-
-
-
-struct yaffs_stat{
-    int                      st_dev;      /* device */
-    int           st_ino;      /* inode */
-    mode_t        st_mode;     /* protection */
-    int           st_nlink;    /* number of hard links */
-    int           st_uid;      /* user ID of owner */
-    int           st_gid;      /* group ID of owner */
-    unsigned      st_rdev;     /* device type (if inode device) */
-    off_t         st_size;     /* total size, in bytes */
-    unsigned long st_blksize;  /* blocksize for filesystem I/O */
-    unsigned long st_blocks;   /* number of blocks allocated */
-    unsigned long yst_atime;    /* time of last access */
-    unsigned long yst_mtime;    /* time of last modification */
-    unsigned long yst_ctime;    /* time of last change */
-};
-
-int yaffs_open(const char *path, int oflag, int mode) ;
-int yaffs_read(int fd, void *buf, unsigned int nbyte) ;
-int yaffs_write(int fd, const void *buf, unsigned int nbyte) ;
-int yaffs_close(int fd) ;
-off_t yaffs_lseek(int fd, off_t offset, int whence) ;
-int yaffs_truncate(int fd, off_t newSize);
-
-int yaffs_unlink(const char *path) ;
-int yaffs_rename(const char *oldPath, const char *newPath) ;
-
-int yaffs_stat(const char *path, struct yaffs_stat *buf) ;
-int yaffs_lstat(const char *path, struct yaffs_stat *buf) ;
-int yaffs_fstat(int fd, struct yaffs_stat *buf) ;
-
-int yaffs_chmod(const char *path, mode_t mode); 
-int yaffs_fchmod(int fd, mode_t mode); 
-
-int yaffs_mkdir(const char *path, mode_t mode) ;
-int yaffs_rmdir(const char *path) ;
-
-yaffs_DIR *yaffs_opendir(const char *dirname) ;
-struct yaffs_dirent *yaffs_readdir(yaffs_DIR *dirp) ;
-void yaffs_rewinddir(yaffs_DIR *dirp) ;
-int yaffs_closedir(yaffs_DIR *dirp) ;
-
-int yaffs_mount(const char *path) ;
-int yaffs_unmount(const char *path) ;
-
-int yaffs_symlink(const char *oldpath, const char *newpath); 
-int yaffs_readlink(const char *path, char *buf, int bufsiz); 
-
-int yaffs_link(const char *oldpath, const char *newpath); 
-int yaffs_mknod(const char *pathname, mode_t mode, dev_t dev);
-
-loff_t yaffs_freespace(const char *path);
-
-void yaffs_initialise(yaffsfs_DeviceConfiguration *configList);
-
-int yaffs_StartUp(void);
-
-#endif
-
-
diff --git a/fs/yaffs2/direct/yaffsinterface.h b/fs/yaffs2/direct/yaffsinterface.h
deleted file mode 120000 (symlink)
index 0a6c87a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yaffsinterface.h
\ No newline at end of file
diff --git a/fs/yaffs2/direct/ydirectenv.h b/fs/yaffs2/direct/ydirectenv.h
deleted file mode 100644 (file)
index adcc0b5..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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 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.
- */
-
-/*
- * ydirectenv.h: Environment wrappers for YAFFS direct.
- */
-
-#ifndef __YDIRECTENV_H__
-#define __YDIRECTENV_H__
-
-// Direct interface
-
-#include "devextras.h"
-
-/* XXX U-BOOT XXX */
-#if 0
-#include "stdlib.h"
-#include "stdio.h"
-#include "string.h"
-#include "assert.h"
-#endif
-#include "yaffs_malloc.h"
-
-/* XXX U-BOOT XXX */
-#if 0
-#define YBUG() assert(1)
-#endif
-
-#define YCHAR char
-#define YUCHAR unsigned char
-#define _Y(x) x
-#define yaffs_strcpy(a,b)    strcpy(a,b)
-#define yaffs_strncpy(a,b,c) strncpy(a,b,c)
-#define yaffs_strncmp(a,b,c) strncmp(a,b,c)
-#define yaffs_strlen(s)             strlen(s)
-#define yaffs_sprintf       sprintf
-#define yaffs_toupper(a)     toupper(a)
-
-#ifdef NO_Y_INLINE
-#define Y_INLINE
-#else
-#define Y_INLINE inline
-#endif
-
-#define YMALLOC(x) yaffs_malloc(x)
-#define YFREE(x)   free(x)
-#define YMALLOC_ALT(x) yaffs_malloc(x)
-#define YFREE_ALT(x)   free(x)
-
-#define YMALLOC_DMA(x) yaffs_malloc(x)
-
-#define YYIELD()  do {} while(0)
-
-
-
-//#define YINFO(s) YPRINTF(( __FILE__ " %d %s\n",__LINE__,s))
-//#define YALERT(s) YINFO(s)
-
-
-#define TENDSTR "\n"
-#define TSTR(x) x
-#define TOUT(p) printf p
-
-
-#define YAFFS_LOSTNFOUND_NAME          "lost+found"
-#define YAFFS_LOSTNFOUND_PREFIX                "obj"
-//#define YPRINTF(x) printf x
-
-#include "yaffscfg.h"
-
-#define Y_CURRENT_TIME yaffsfs_CurrentTime()
-#define Y_TIME_CONVERT(x) x
-
-#define YAFFS_ROOT_MODE                                0666
-#define YAFFS_LOSTNFOUND_MODE          0666
-
-#define yaffs_SumCompare(x,y) ((x) == (y))
-#define yaffs_strcmp(a,b) strcmp(a,b)
-
-#endif
-
-
diff --git a/fs/yaffs2/direct/yportenv.h b/fs/yaffs2/direct/yportenv.h
deleted file mode 120000 (symlink)
index 205c44b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../yportenv.h
\ No newline at end of file
diff --git a/fs/yaffs2/yaffs_flashif.h b/fs/yaffs2/yaffs_flashif.h
new file mode 100644 (file)
index 0000000..f7f4e42
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * 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 Lesser General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ *
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
+ */
+
+#ifndef __YAFFS_FLASH_H__
+#define __YAFFS_FLASH_H__
+
+
+#include "yaffs_guts.h"
+int yflash_EraseBlockInNAND(yaffs_Device *dev, int blockNumber);
+int yflash_WriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_Spare *spare);
+int yflash_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_ExtendedTags *tags);
+int yflash_ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare);
+int yflash_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_ExtendedTags *tags);
+int yflash_EraseBlockInNAND(yaffs_Device *dev, int blockNumber);
+int yflash_InitialiseNAND(yaffs_Device *dev);
+int yflash_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo);
+int yflash_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, yaffs_BlockState *state, int *sequenceNumber);
+
+#endif
diff --git a/fs/yaffs2/yaffs_malloc.h b/fs/yaffs2/yaffs_malloc.h
new file mode 100644 (file)
index 0000000..122fb4c
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef __YAFFS_MALLOC_H__
+/*
+ * 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 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.
+ */
+/* XXX U-BOOT XXX */
+#if 0
+#include <stdlib.h>
+#endif 
+
+void *yaffs_malloc(size_t size); 
+void yaffs_free(void *ptr);
+#endif
+
diff --git a/fs/yaffs2/yaffs_ramdisk.h b/fs/yaffs2/yaffs_ramdisk.h
new file mode 100644 (file)
index 0000000..045ab42
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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 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.
+ */
+
+/*
+ * yaffs_ramdisk.h: yaffs ram disk component
+ */
+
+#ifndef __YAFFS_RAMDISK_H__
+#define __YAFFS_RAMDISK_H__
+
+
+#include "yaffs_guts.h"
+int yramdisk_EraseBlockInNAND(yaffs_Device *dev, int blockNumber);
+int yramdisk_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_ExtendedTags *tags);
+int yramdisk_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_ExtendedTags *tags);
+int yramdisk_EraseBlockInNAND(yaffs_Device *dev, int blockNumber);
+int yramdisk_InitialiseNAND(yaffs_Device *dev);
+int yramdisk_MarkNANDBlockBad(yaffs_Device *dev,int blockNumber);
+int yramdisk_QueryNANDBlock(yaffs_Device *dev, int blockNo, yaffs_BlockState *state, int *sequenceNumber);
+#endif
diff --git a/fs/yaffs2/yaffscfg.c b/fs/yaffs2/yaffscfg.c
new file mode 100644 (file)
index 0000000..a4a0924
--- /dev/null
@@ -0,0 +1,417 @@
+/*
+ * 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.
+ */
+
+/*
+ * yaffscfg.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.
+ */
+
+/* XXX U-BOOT XXX */
+#include <common.h>
+
+#include <config.h>
+#include "nand.h"
+#include "yaffscfg.h"
+#include "yaffsfs.h"
+#include "yaffs_packedtags2.h"
+#include "yaffs_mtdif.h"
+#include "yaffs_mtdif2.h"
+#if 0
+#include <errno.h>
+#else
+#include "malloc.h"
+#endif
+
+unsigned yaffs_traceMask = 0xFFFFFFFF;
+static int yaffs_errno = 0;
+
+void yaffsfs_SetError(int err)
+{
+       //Do whatever to set error
+       yaffs_errno = err;
+}
+
+int yaffsfs_GetError(void)
+{
+       return yaffs_errno;
+}
+
+void yaffsfs_Lock(void)
+{
+}
+
+void yaffsfs_Unlock(void)
+{
+}
+
+__u32 yaffsfs_CurrentTime(void)
+{
+       return 0;
+}
+
+void *yaffs_malloc(size_t size)
+{
+       return malloc(size);
+}
+
+void yaffs_free(void *ptr)
+{
+       free(ptr);
+}
+
+void yaffsfs_LocalInitialisation(void)
+{
+       // Define locking semaphore.
+}
+
+// Configuration for:
+// /ram  2MB ramdisk
+// /boot 2MB boot disk (flash)
+// /flash 14MB flash disk (flash)
+// NB Though /boot and /flash occupy the same physical device they
+// are still disticnt "yaffs_Devices. You may think of these as "partitions"
+// using non-overlapping areas in the same device.
+// 
+
+#include "yaffs_ramdisk.h"
+#include "yaffs_flashif.h"
+
+static int isMounted = 0;
+#define MOUNT_POINT "/flash"
+extern nand_info_t nand_info[];
+
+/* XXX U-BOOT XXX */
+#if 0
+static yaffs_Device ramDev;
+static yaffs_Device bootDev;
+static yaffs_Device flashDev;
+#endif
+
+static yaffsfs_DeviceConfiguration yaffsfs_config[] = {
+/* XXX U-BOOT XXX */
+#if 0
+       { "/ram", &ramDev},
+       { "/boot", &bootDev},
+       { "/flash", &flashDev},
+#else
+       { MOUNT_POINT, 0},
+#endif
+       {(void *)0,(void *)0}
+};
+
+
+int yaffs_StartUp(void)
+{
+       struct mtd_info *mtd = &nand_info[0];
+       int yaffsVersion = 2;
+       int nBlocks;
+
+       yaffs_Device *flashDev = calloc(1, sizeof(yaffs_Device));
+       yaffsfs_config[0].dev = flashDev;
+
+       // Stuff to configure YAFFS
+       // Stuff to initialise anything special (eg lock semaphore).
+       yaffsfs_LocalInitialisation();
+       
+       // Set up devices
+
+/* XXX U-BOOT XXX */
+#if 0
+       // /ram
+       ramDev.nBytesPerChunk = 512;
+       ramDev.nChunksPerBlock = 32;
+       ramDev.nReservedBlocks = 2; // Set this smaller for RAM
+       ramDev.startBlock = 1; // Can't use block 0
+       ramDev.endBlock = 127; // Last block in 2MB.    
+       ramDev.useNANDECC = 1;
+       ramDev.nShortOpCaches = 0;      // Disable caching on this device.
+       ramDev.genericDevice = (void *) 0;      // Used to identify the device in fstat.
+       ramDev.writeChunkWithTagsToNAND = yramdisk_WriteChunkWithTagsToNAND;
+       ramDev.readChunkWithTagsFromNAND = yramdisk_ReadChunkWithTagsFromNAND;
+       ramDev.eraseBlockInNAND = yramdisk_EraseBlockInNAND;
+       ramDev.initialiseNAND = yramdisk_InitialiseNAND;
+
+       // /boot
+       bootDev.nBytesPerChunk = 612;
+       bootDev.nChunksPerBlock = 32;
+       bootDev.nReservedBlocks = 5;
+       bootDev.startBlock = 1; // Can't use block 0
+       bootDev.endBlock = 127; // Last block in 2MB.   
+       bootDev.useNANDECC = 0; // use YAFFS's ECC
+       bootDev.nShortOpCaches = 10; // Use caches
+       bootDev.genericDevice = (void *) 1;     // Used to identify the device in fstat.
+       bootDev.writeChunkToNAND = yflash_WriteChunkToNAND;
+       bootDev.readChunkFromNAND = yflash_ReadChunkFromNAND;
+       bootDev.eraseBlockInNAND = yflash_EraseBlockInNAND;
+       bootDev.initialiseNAND = yflash_InitialiseNAND;
+#endif
+
+               // /flash
+       flashDev->nReservedBlocks = 5;
+//  flashDev->nShortOpCaches = (options.no_cache) ? 0 : 10;
+       flashDev->nShortOpCaches = 10; // Use caches
+       flashDev->useNANDECC = 0; // do not use YAFFS's ECC
+
+       if (yaffsVersion == 2)
+       {
+               flashDev->writeChunkWithTagsToNAND = nandmtd2_WriteChunkWithTagsToNAND;
+               flashDev->readChunkWithTagsFromNAND = nandmtd2_ReadChunkWithTagsFromNAND;
+               flashDev->markNANDBlockBad = nandmtd2_MarkNANDBlockBad;
+               flashDev->queryNANDBlock = nandmtd2_QueryNANDBlock;
+               flashDev->spareBuffer = YMALLOC(mtd->oobsize);
+               flashDev->isYaffs2 = 1;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
+               flashDev->nDataBytesPerChunk = mtd->writesize;
+               flashDev->nChunksPerBlock = mtd->erasesize / mtd->writesize;
+#else
+               flashDev->nDataBytesPerChunk = mtd->oobblock;
+               flashDev->nChunksPerBlock = mtd->erasesize / mtd->oobblock;
+#endif
+               nBlocks = mtd->size / mtd->erasesize;
+
+               flashDev->nCheckpointReservedBlocks = 10;
+               flashDev->startBlock = 0;
+               flashDev->endBlock = nBlocks - 1;
+       }
+       else
+       {
+               flashDev->writeChunkToNAND = nandmtd_WriteChunkToNAND;
+               flashDev->readChunkFromNAND = nandmtd_ReadChunkFromNAND;
+               flashDev->isYaffs2 = 0;
+               nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
+               flashDev->startBlock = 320;
+               flashDev->endBlock = nBlocks - 1;
+               flashDev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
+               flashDev->nDataBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
+       }
+       
+       /* ... and common functions */
+       flashDev->eraseBlockInNAND = nandmtd_EraseBlockInNAND;
+       flashDev->initialiseNAND = nandmtd_InitialiseNAND;
+
+       yaffs_initialise(yaffsfs_config);
+       
+       return 0;
+}
+
+
+void make_a_file(char *yaffsName,char bval,int sizeOfFile)
+{
+       int outh;
+       int i;
+       unsigned char buffer[100];
+
+       outh = yaffs_open(yaffsName, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
+       if (outh < 0)
+       {
+               printf("Error opening file: %d\n", outh);
+               return;
+       }
+       
+       memset(buffer,bval,100);
+       
+       do{
+               i = sizeOfFile;
+               if(i > 100) i = 100;
+               sizeOfFile -= i;
+               
+               yaffs_write(outh,buffer,i);
+               
+       } while (sizeOfFile > 0);
+       
+               
+       yaffs_close(outh);
+}
+
+void read_a_file(char *fn)
+{
+       int h;
+       int i = 0;
+       unsigned char b;
+
+       h = yaffs_open(fn, O_RDWR,0);
+       if(h<0)
+       {
+               printf("File not found\n");
+               return;
+       }
+
+       while(yaffs_read(h,&b,1)> 0)
+       {
+               printf("%02x ",b);
+               i++;
+               if(i > 32) 
+               {
+                  printf("\n");
+                  i = 0;;
+                }
+       }
+       printf("\n");
+       yaffs_close(h);
+}
+
+void cmd_yaffs_mount(char *mp)
+{
+       yaffs_StartUp();
+       int retval = yaffs_mount(mp);
+       if( retval != -1)
+               isMounted = 1;
+       else
+               printf("Error mounting %s, return value: %d\n", mp, yaffsfs_GetError());
+}
+
+static void checkMount(void)
+{
+       if( !isMounted )
+       {
+               cmd_yaffs_mount(MOUNT_POINT);
+       }
+}
+
+void cmd_yaffs_umount(char *mp)
+{
+       checkMount();
+       if( yaffs_unmount(mp) == -1)
+               printf("Error umounting %s, return value: %d\n", mp, yaffsfs_GetError());
+}
+
+void cmd_yaffs_write_file(char *yaffsName,char bval,int sizeOfFile)
+{
+       checkMount();
+       make_a_file(yaffsName,bval,sizeOfFile);
+}
+
+
+void cmd_yaffs_read_file(char *fn)
+{
+       checkMount();
+       read_a_file(fn);
+}
+
+
+void cmd_yaffs_mread_file(char *fn, char *addr)
+{
+       int h;
+       struct yaffs_stat s;
+       
+       checkMount();
+
+       yaffs_stat(fn,&s);
+
+       printf ("Copy %s to 0x%08x... ", fn, addr);
+       h = yaffs_open(fn, O_RDWR,0);
+       if(h<0)
+       {
+               printf("File not found\n");
+               return;
+       }
+                               
+       yaffs_read(h,addr,(int)s.st_size);
+       printf("\t[DONE]\n");
+
+       yaffs_close(h);
+}
+
+
+void cmd_yaffs_mwrite_file(char *fn, char *addr, int size)
+{
+       int outh;
+
+       checkMount();
+       outh = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
+       if (outh < 0)
+       {
+               printf("Error opening file: %d\n", outh);
+       }
+       
+       yaffs_write(outh,addr,size);
+       
+       yaffs_close(outh);
+}
+
+
+void cmd_yaffs_ls(const char *mountpt, int longlist)
+{
+       int i;
+       yaffs_DIR *d;
+       yaffs_dirent *de;
+       struct yaffs_stat stat;
+       char tempstr[255];
+
+       checkMount();
+       d = yaffs_opendir(mountpt);
+
+       if(!d)
+       {
+               printf("opendir failed\n");
+       }
+       else
+       {
+               for(i = 0; (de = yaffs_readdir(d)) != NULL; i++)
+               {
+                       if (longlist)
+                       {
+                               sprintf(tempstr, "%s/%s", mountpt, de->d_name);
+                               yaffs_stat(tempstr, &stat);
+                               printf("%-25s\t%7d\n",de->d_name, stat.st_size);
+                       }
+                       else
+                       {
+                               printf("%s\n",de->d_name);
+                       }
+               }
+       }
+}
+
+
+void cmd_yaffs_mkdir(const char *dir)
+{
+       checkMount();
+
+       int retval = yaffs_mkdir(dir, 0);
+       
+       if ( retval < 0)
+               printf("yaffs_mkdir returning error: %d\n", retval);
+}
+
+void cmd_yaffs_rmdir(const char *dir)
+{
+       checkMount();
+
+       int retval = yaffs_rmdir(dir);
+       
+       if ( retval < 0)
+               printf("yaffs_rmdir returning error: %d\n", retval);
+}
+
+void cmd_yaffs_rm(const char *path)
+{
+       checkMount();
+
+       int retval = yaffs_unlink(path);
+       
+       if ( retval < 0)
+               printf("yaffs_unlink returning error: %d\n", retval);
+}
+
+void cmd_yaffs_mv(const char *oldPath, const char *newPath)
+{
+       checkMount();
+
+       int retval = yaffs_rename(newPath, oldPath);
+       
+       if ( retval < 0)
+               printf("yaffs_unlink returning error: %d\n", retval);
+}
diff --git a/fs/yaffs2/yaffscfg.h b/fs/yaffs2/yaffscfg.h
new file mode 100644 (file)
index 0000000..6ae1696
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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 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.
+ */
+
+/*
+ * Header file for using yaffs in an application via
+ * a direct interface.
+ */
+
+
+#ifndef __YAFFSCFG_H__
+#define __YAFFSCFG_H__
+
+
+#include "devextras.h"
+
+#define YAFFSFS_N_HANDLES 200
+
+
+typedef struct {
+       const char *prefix;
+       struct yaffs_DeviceStruct *dev;
+} yaffsfs_DeviceConfiguration;
+
+
+void yaffsfs_Lock(void);
+void yaffsfs_Unlock(void);
+
+__u32 yaffsfs_CurrentTime(void);
+
+void yaffsfs_SetError(int err);
+int yaffsfs_GetError(void);
+
+#endif
+
diff --git a/fs/yaffs2/yaffsfs.c b/fs/yaffs2/yaffsfs.c
new file mode 100644 (file)
index 0000000..f62c952
--- /dev/null
@@ -0,0 +1,1510 @@
+/*
+ * 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.
+ */
+/* XXX U-BOOT XXX */
+#include <common.h>
+#include <malloc.h>
+
+#include "yaffsfs.h"
+#include "yaffs_guts.h"
+#include "yaffscfg.h"
+#include "yportenv.h"
+
+/* XXX U-BOOT XXX */
+#if 0
+#include <string.h> // for memset
+#endif
+
+#define YAFFSFS_MAX_SYMLINK_DEREFERENCES 5
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+
+const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.18 2007/07/18 19:40:38 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 char *path, int symDepth);
+static void yaffsfs_RemoveObjectCallback(yaffs_Object *obj);
+
+
+// Handle management.
+// 
+
+
+unsigned int yaffs_wr_attempts;
+
+typedef struct
+{
+       __u8  inUse:1;          // this handle is in use
+       __u8  readOnly:1;       // this handle is read only
+       __u8  append:1;         // append only
+       __u8  exclusive:1;      // exclusive
+       __u32 position;         // current position in file
+       yaffs_Object *obj;      // the object
+}yaffsfs_Handle;
+
+
+static yaffsfs_Handle yaffsfs_handle[YAFFSFS_N_HANDLES];
+
+// yaffsfs_InitHandle
+/// Inilitalise handles on start-up.
+//
+static int yaffsfs_InitHandles(void)
+{
+       int i;
+       for(i = 0; i < YAFFSFS_N_HANDLES; i++)
+       {
+               yaffsfs_handle[i].inUse = 0;
+               yaffsfs_handle[i].obj = NULL;
+       }
+       return 0;
+}
+
+yaffsfs_Handle *yaffsfs_GetHandlePointer(int h)
+{
+       if(h < 0 || h >= YAFFSFS_N_HANDLES)
+       {
+               return NULL;
+       }
+       
+       return &yaffsfs_handle[h];
+}
+
+yaffs_Object *yaffsfs_GetHandleObject(int handle)
+{
+       yaffsfs_Handle *h = yaffsfs_GetHandlePointer(handle);
+
+       if(h && h->inUse)
+       {
+               return h->obj;
+       }
+       
+       return NULL;
+}
+
+
+//yaffsfs_GetHandle
+// Grab a handle (when opening a file)
+//
+
+static int yaffsfs_GetHandle(void)
+{
+       int i;
+       yaffsfs_Handle *h;
+       
+       for(i = 0; i < YAFFSFS_N_HANDLES; i++)
+       {
+               h = yaffsfs_GetHandlePointer(i);
+               if(!h)
+               {
+                       // todo bug: should never happen
+               }
+               if(!h->inUse)
+               {
+                       memset(h,0,sizeof(yaffsfs_Handle));
+                       h->inUse=1;
+                       return i;
+               }
+       }
+       return -1;
+}
+
+// yaffs_PutHandle
+// Let go of a handle (when closing a file)
+//
+static int yaffsfs_PutHandle(int handle)
+{
+       yaffsfs_Handle *h = yaffsfs_GetHandlePointer(handle);
+       
+       if(h)
+       {
+               h->inUse = 0;
+               h->obj = NULL;
+       }
+       return 0;
+}
+
+
+
+// Stuff to search for a directory from a path
+
+
+int yaffsfs_Match(char a, char b)
+{
+       // case sensitive
+       return (a == b);
+}
+
+// yaffsfs_FindDevice
+// yaffsfs_FindRoot
+// Scan the configuration list to find the root.
+// Curveballs: Should match paths that end in '/' too
+// Curveball2 Might have "/x/ and "/x/y". Need to return the longest match
+static yaffs_Device *yaffsfs_FindDevice(const char *path, char **restOfPath)
+{
+       yaffsfs_DeviceConfiguration *cfg = yaffsfs_configurationList;
+       const char *leftOver;
+       const char *p;
+       yaffs_Device *retval = NULL;
+       int thisMatchLength;
+       int longestMatch = -1;
+       
+       // Check all configs, choose the one that:
+       // 1) Actually matches a prefix (ie /a amd /abc will not match
+       // 2) Matches the longest.
+       while(cfg && cfg->prefix && cfg->dev)
+       {
+               leftOver = path;
+               p = cfg->prefix;
+               thisMatchLength = 0;
+               
+               while(*p &&  //unmatched part of prefix 
+                     strcmp(p,"/") && // the rest of the prefix is not / (to catch / at end)
+                     *leftOver && 
+                     yaffsfs_Match(*p,*leftOver))
+               {
+                       p++;
+                       leftOver++;
+                       thisMatchLength++;
+               }
+               if((!*p || strcmp(p,"/") == 0) &&      // end of prefix
+                  (!*leftOver || *leftOver == '/') && // no more in this path name part
+                  (thisMatchLength > longestMatch))
+               {
+                       // Matched prefix
+                       *restOfPath = (char *)leftOver;
+                       retval = cfg->dev;
+                       longestMatch = thisMatchLength;
+               }
+               cfg++;
+       }
+       return retval;
+}
+
+static yaffs_Object *yaffsfs_FindRoot(const char *path, char **restOfPath)
+{
+
+       yaffs_Device *dev;
+       
+       dev= yaffsfs_FindDevice(path,restOfPath);
+       if(dev && dev->isMounted)
+       {
+               return dev->rootDir;
+       }
+       return NULL;
+}
+
+static yaffs_Object *yaffsfs_FollowLink(yaffs_Object *obj,int symDepth)
+{
+
+       while(obj && obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
+       {
+               char *alias = obj->variant.symLinkVariant.alias;
+                                               
+               if(*alias == '/')
+               {
+                       // Starts with a /, need to scan from root up
+                       obj = yaffsfs_FindObject(NULL,alias,symDepth++);
+               }
+               else
+               {
+                       // Relative to here, so use the parent of the symlink as a start
+                       obj = yaffsfs_FindObject(obj->parent,alias,symDepth++);
+               }
+       }
+       return obj;
+}
+
+
+// yaffsfs_FindDirectory
+// Parse a path to determine the directory and the name within the directory.
+//
+// eg. "/data/xx/ff" --> puts name="ff" and returns the directory "/data/xx"
+static yaffs_Object *yaffsfs_DoFindDirectory(yaffs_Object *startDir,const char *path,char **name,int symDepth)
+{
+       yaffs_Object *dir;
+       char *restOfPath;
+       char str[YAFFS_MAX_NAME_LENGTH+1];
+       int i;
+       
+       if(symDepth > YAFFSFS_MAX_SYMLINK_DEREFERENCES)
+       {
+               return NULL;
+       }
+       
+       if(startDir)
+       {
+               dir = startDir;
+               restOfPath = (char *)path;
+       }
+       else
+       {
+               dir = yaffsfs_FindRoot(path,&restOfPath);
+       }
+       
+       while(dir)
+       {       
+               // parse off /.
+               // curve ball: also throw away surplus '/' 
+               // eg. "/ram/x////ff" gets treated the same as "/ram/x/ff"
+               while(*restOfPath == '/')
+               {
+                       restOfPath++; // get rid of '/'
+               }
+               
+               *name = restOfPath;
+               i = 0;
+               
+               while(*restOfPath && *restOfPath != '/')
+               {
+                       if (i < YAFFS_MAX_NAME_LENGTH)
+                       {
+                               str[i] = *restOfPath;
+                               str[i+1] = '\0';
+                               i++;
+                       }
+                       restOfPath++;
+               }
+               
+               if(!*restOfPath)
+               {
+                       // got to the end of the string
+                       return dir;
+               }
+               else
+               {
+                       if(strcmp(str,".") == 0)
+                       {
+                               // Do nothing
+                       }
+                       else if(strcmp(str,"..") == 0)
+                       {
+                               dir = dir->parent;
+                       }
+                       else
+                       {
+                               dir = yaffs_FindObjectByName(dir,str);
+                               
+                               while(dir && dir->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
+                               {
+                               
+                                       dir = yaffsfs_FollowLink(dir,symDepth);
+               
+                               }
+                               
+                               if(dir && dir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY)
+                               {
+                                       dir = NULL;
+                               }
+                       }
+               }
+       }
+       // directory did not exist.
+       return NULL;
+}
+
+static yaffs_Object *yaffsfs_FindDirectory(yaffs_Object *relativeDirectory,const char *path,char **name,int symDepth)
+{
+       return yaffsfs_DoFindDirectory(relativeDirectory,path,name,symDepth);
+}
+
+// yaffsfs_FindObject turns a path for an existing object into the object
+// 
+static yaffs_Object *yaffsfs_FindObject(yaffs_Object *relativeDirectory, const char *path,int symDepth)
+{
+       yaffs_Object *dir;
+       char *name;
+       
+       dir = yaffsfs_FindDirectory(relativeDirectory,path,&name,symDepth);
+       
+       if(dir && *name)
+       {
+               return yaffs_FindObjectByName(dir,name);
+       }
+       
+       return dir;
+}
+
+
+
+int yaffs_open(const char *path, int oflag, int mode)
+{
+       yaffs_Object *obj = NULL;
+       yaffs_Object *dir = NULL;
+       char *name;
+       int handle = -1;
+       yaffsfs_Handle *h = NULL;
+       int alreadyOpen = 0;
+       int alreadyExclusive = 0;
+       int openDenied = 0;
+       int symDepth = 0;
+       int errorReported = 0;
+       
+       int i;
+       
+       
+       // todo sanity check oflag (eg. can't have O_TRUNC without WRONLY or RDWR
+       
+       
+       yaffsfs_Lock();
+       
+       handle = yaffsfs_GetHandle();
+       
+       if(handle >= 0)
+       {
+
+               h = yaffsfs_GetHandlePointer(handle);
+       
+       
+               // try to find the exisiting object
+               obj = yaffsfs_FindObject(NULL,path,0);
+               
+               if(obj && obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
+               {
+               
+                       obj = yaffsfs_FollowLink(obj,symDepth++);
+               }
+
+               if(obj)
+               {
+                       // Check if the object is already in use
+                       alreadyOpen = alreadyExclusive = 0;
+                       
+                       for(i = 0; i <= YAFFSFS_N_HANDLES; i++)
+                       {
+                               
+                               if(i != handle &&
+                                  yaffsfs_handle[i].inUse &&
+                                   obj == yaffsfs_handle[i].obj)
+                                {
+                                       alreadyOpen = 1;
+                                       if(yaffsfs_handle[i].exclusive)
+                                       {
+                                               alreadyExclusive = 1;
+                                       }
+                                }
+                       }
+
+                       if(((oflag & O_EXCL) && alreadyOpen) || alreadyExclusive)
+                       {
+                               openDenied = 1;
+                       }
+                       
+                       // Open should fail if O_CREAT and O_EXCL are specified
+                       if((oflag & O_EXCL) && (oflag & O_CREAT))
+                       {
+                               openDenied = 1;
+                               yaffsfs_SetError(-EEXIST);
+                               errorReported = 1;
+                       }
+                       
+                       // Check file permissions
+                       if( (oflag & (O_RDWR | O_WRONLY)) == 0 &&     // ie O_RDONLY
+                          !(obj->yst_mode & S_IREAD))
+                       {
+                               openDenied = 1;
+                       }
+
+                       if( (oflag & O_RDWR) && 
+                          !(obj->yst_mode & S_IREAD))
+                       {
+                               openDenied = 1;
+                       }
+
+                       if( (oflag & (O_RDWR | O_WRONLY)) && 
+                          !(obj->yst_mode & S_IWRITE))
+                       {
+                               openDenied = 1;
+                       }
+                       
+               }
+               
+               else if((oflag & O_CREAT))
+               {
+                       // Let's see if we can create this file
+                       dir = yaffsfs_FindDirectory(NULL,path,&name,0);
+                       if(dir)
+                       {
+                               obj = yaffs_MknodFile(dir,name,mode,0,0);       
+                       }
+                       else
+                       {
+                               yaffsfs_SetError(-ENOTDIR);
+                       }
+               }
+               
+               if(obj && !openDenied)
+               {
+                       h->obj = obj;
+                       h->inUse = 1;
+               h->readOnly = (oflag & (O_WRONLY | O_RDWR)) ? 0 : 1;
+                       h->append =  (oflag & O_APPEND) ? 1 : 0;
+                       h->exclusive = (oflag & O_EXCL) ? 1 : 0;
+                       h->position = 0;
+                       
+                       obj->inUse++;
+                       if((oflag & O_TRUNC) && !h->readOnly)
+                       {
+                               //todo truncate
+                               yaffs_ResizeFile(obj,0);
+                       }
+                       
+               }
+               else
+               {
+                       yaffsfs_PutHandle(handle);
+                       if(!errorReported)
+                       {
+                               yaffsfs_SetError(-EACCESS);
+                               errorReported = 1;
+                       }
+                       handle = -1;
+               }
+               
+       }
+       
+       yaffsfs_Unlock();
+       
+       return handle;          
+}
+
+int yaffs_close(int fd)
+{
+       yaffsfs_Handle *h = NULL;
+       int retVal = 0;
+       
+       yaffsfs_Lock();
+
+       h = yaffsfs_GetHandlePointer(fd);
+       
+       if(h && h->inUse)
+       {
+               // clean up
+               yaffs_FlushFile(h->obj,1);
+               h->obj->inUse--;
+               if(h->obj->inUse <= 0 && h->obj->unlinked)
+               {
+                       yaffs_DeleteFile(h->obj);
+               }
+               yaffsfs_PutHandle(fd);
+               retVal = 0;
+       }
+       else
+       {
+               // bad handle
+               yaffsfs_SetError(-EBADF);               
+               retVal = -1;
+       }
+       
+       yaffsfs_Unlock();
+       
+       return retVal;
+}
+
+int yaffs_read(int fd, void *buf, unsigned int nbyte)
+{
+       yaffsfs_Handle *h = NULL;
+       yaffs_Object *obj = NULL;
+       int pos = 0;
+       int nRead = -1;
+       int maxRead;
+       
+       yaffsfs_Lock();
+       h = yaffsfs_GetHandlePointer(fd);
+       obj = yaffsfs_GetHandleObject(fd);
+       
+       if(!h || !obj)
+       {
+               // bad handle
+               yaffsfs_SetError(-EBADF);               
+       }
+       else if( h && obj)
+       {
+               pos=  h->position;
+               if(yaffs_GetObjectFileLength(obj) > pos)
+               {
+                       maxRead = yaffs_GetObjectFileLength(obj) - pos;
+               }
+               else
+               {
+                       maxRead = 0;
+               }
+
+               if(nbyte > maxRead)
+               {
+                       nbyte = maxRead;
+               }
+
+               
+               if(nbyte > 0)
+               {
+                       nRead = yaffs_ReadDataFromFile(obj,buf,pos,nbyte);
+                       if(nRead >= 0)
+                       {
+                               h->position = pos + nRead;
+                       }
+                       else
+                       {
+                               //todo error
+                       }
+               }
+               else
+               {
+                       nRead = 0;
+               }
+               
+       }
+       
+       yaffsfs_Unlock();
+       
+       
+       return (nRead >= 0) ? nRead : -1;
+               
+}
+
+int yaffs_write(int fd, const void *buf, unsigned int nbyte)
+{
+       yaffsfs_Handle *h = NULL;
+       yaffs_Object *obj = NULL;
+       int pos = 0;
+       int nWritten = -1;
+       int writeThrough = 0;
+       
+       yaffsfs_Lock();
+       h = yaffsfs_GetHandlePointer(fd);
+       obj = yaffsfs_GetHandleObject(fd);
+       
+       if(!h || !obj)
+       {
+               // bad handle
+               yaffsfs_SetError(-EBADF);               
+       }
+       else if( h && obj && h->readOnly)
+       {
+               // todo error
+       }
+       else if( h && obj)
+       {
+               if(h->append)
+               {
+                       pos =  yaffs_GetObjectFileLength(obj);
+               }
+               else
+               {
+                       pos = h->position;
+               }
+               
+               nWritten = yaffs_WriteDataToFile(obj,buf,pos,nbyte,writeThrough);
+               
+               if(nWritten >= 0)
+               {
+                       h->position = pos + nWritten;
+               }
+               else
+               {
+                       //todo error
+               }
+               
+       }
+       
+       yaffsfs_Unlock();
+       
+       
+       return (nWritten >= 0) ? nWritten : -1;
+
+}
+
+int yaffs_truncate(int fd, off_t newSize)
+{
+       yaffsfs_Handle *h = NULL;
+       yaffs_Object *obj = NULL;
+       int result = 0;
+       
+       yaffsfs_Lock();
+       h = yaffsfs_GetHandlePointer(fd);
+       obj = yaffsfs_GetHandleObject(fd);
+       
+       if(!h || !obj)
+       {
+               // bad handle
+               yaffsfs_SetError(-EBADF);               
+       }
+       else
+       {
+               // resize the file
+               result = yaffs_ResizeFile(obj,newSize);
+       }       
+       yaffsfs_Unlock();
+       
+       
+       return (result) ? 0 : -1;
+
+}
+
+off_t yaffs_lseek(int fd, off_t offset, int whence) 
+{
+       yaffsfs_Handle *h = NULL;
+       yaffs_Object *obj = NULL;
+       int pos = -1;
+       int fSize = -1;
+       
+       yaffsfs_Lock();
+       h = yaffsfs_GetHandlePointer(fd);
+       obj = yaffsfs_GetHandleObject(fd);
+       
+       if(!h || !obj)
+       {
+               // bad handle
+               yaffsfs_SetError(-EBADF);               
+       }
+       else if(whence == SEEK_SET)
+       {
+               if(offset >= 0)
+               {
+                       pos = offset;
+               }
+       }
+       else if(whence == SEEK_CUR)
+       {
+               if( (h->position + offset) >= 0)
+               {
+                       pos = (h->position + offset);
+               }
+       }
+       else if(whence == SEEK_END)
+       {
+               fSize = yaffs_GetObjectFileLength(obj);
+               if(fSize >= 0 && (fSize + offset) >= 0)
+               {
+                       pos = fSize + offset;
+               }
+       }
+       
+       if(pos >= 0)
+       {
+               h->position = pos;
+       }
+       else
+       {
+               // todo error
+       }
+
+       
+       yaffsfs_Unlock();
+       
+       return pos;
+}
+
+
+int yaffsfs_DoUnlink(const char *path,int isDirectory) 
+{
+       yaffs_Object *dir = NULL;
+       yaffs_Object *obj = NULL;
+       char *name;
+       int result = YAFFS_FAIL;
+       
+       yaffsfs_Lock();
+
+       obj = yaffsfs_FindObject(NULL,path,0);
+       dir = yaffsfs_FindDirectory(NULL,path,&name,0);
+       if(!dir)
+       {
+               yaffsfs_SetError(-ENOTDIR);
+       }
+       else if(!obj)
+       {
+               yaffsfs_SetError(-ENOENT);
+       }
+       else if(!isDirectory && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)
+       {
+               yaffsfs_SetError(-EISDIR);
+       }
+       else if(isDirectory && obj->variantType != YAFFS_OBJECT_TYPE_DIRECTORY)
+       {
+               yaffsfs_SetError(-ENOTDIR);
+       }
+       else
+       {
+               result = yaffs_Unlink(dir,name);
+               
+               if(result == YAFFS_FAIL && isDirectory)
+               {
+                       yaffsfs_SetError(-ENOTEMPTY);
+               }
+       }
+       
+       yaffsfs_Unlock();
+       
+       // todo error
+       
+       return (result == YAFFS_FAIL) ? -1 : 0;
+}
+int yaffs_rmdir(const char *path) 
+{
+       return yaffsfs_DoUnlink(path,1);
+}
+
+int yaffs_unlink(const char *path) 
+{
+       return yaffsfs_DoUnlink(path,0);
+}
+
+int yaffs_rename(const char *oldPath, const char *newPath)
+{
+       yaffs_Object *olddir = NULL;
+       yaffs_Object *newdir = NULL;
+       yaffs_Object *obj = NULL;
+       char *oldname;
+       char *newname;
+       int result= YAFFS_FAIL;
+       int renameAllowed = 1;
+       
+       yaffsfs_Lock();
+       
+       olddir = yaffsfs_FindDirectory(NULL,oldPath,&oldname,0);
+       newdir = yaffsfs_FindDirectory(NULL,newPath,&newname,0);
+       obj = yaffsfs_FindObject(NULL,oldPath,0);
+       
+       if(!olddir || !newdir || !obj)
+       {
+               // bad file
+               yaffsfs_SetError(-EBADF);       
+               renameAllowed = 0;      
+       }
+       else if(olddir->myDev != newdir->myDev)
+       {
+               // oops must be on same device
+               // todo error
+               yaffsfs_SetError(-EXDEV);
+               renameAllowed = 0;      
+       }
+       else if(obj && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)
+       {
+               // It is a directory, check that it is not being renamed to 
+               // being its own decendent.
+               // Do this by tracing from the new directory back to the root, checking for obj
+               
+               yaffs_Object *xx = newdir;
+               
+               while( renameAllowed && xx)
+               {
+                       if(xx == obj)
+                       {
+                               renameAllowed = 0;
+                       }
+                       xx = xx->parent;
+               }
+               if(!renameAllowed) yaffsfs_SetError(-EACCESS);
+       }
+       
+       if(renameAllowed)
+       {
+               result = yaffs_RenameObject(olddir,oldname,newdir,newname);
+       }
+       
+       yaffsfs_Unlock();
+       
+       return (result == YAFFS_FAIL) ? -1 : 0; 
+}
+
+
+static int yaffsfs_DoStat(yaffs_Object *obj,struct yaffs_stat *buf)
+{
+       int retVal = -1;
+
+       if(obj)
+       {
+               obj = yaffs_GetEquivalentObject(obj);
+       }
+
+       if(obj && buf)
+       {
+       buf->st_dev = (int)obj->myDev->genericDevice;
+       buf->st_ino = obj->objectId;
+       buf->st_mode = obj->yst_mode & ~S_IFMT; // clear out file type bits
+       
+               if(obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) 
+               {
+                       buf->st_mode |= S_IFDIR;
+               }
+               else if(obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK) 
+               {
+                       buf->st_mode |= S_IFLNK;
+               }
+               else if(obj->variantType == YAFFS_OBJECT_TYPE_FILE)
+               {
+                       buf->st_mode |= S_IFREG;
+               }
+               
+       buf->st_nlink = yaffs_GetObjectLinkCount(obj);
+       buf->st_uid = 0;    
+       buf->st_gid = 0;;     
+       buf->st_rdev = obj->yst_rdev;
+       buf->st_size = yaffs_GetObjectFileLength(obj);
+               buf->st_blksize = obj->myDev->nDataBytesPerChunk;
+       buf->st_blocks = (buf->st_size + buf->st_blksize -1)/buf->st_blksize;
+       buf->yst_atime = obj->yst_atime; 
+       buf->yst_ctime = obj->yst_ctime; 
+       buf->yst_mtime = obj->yst_mtime; 
+               retVal = 0;
+       }
+       return retVal;
+}
+
+static int yaffsfs_DoStatOrLStat(const char *path, struct yaffs_stat *buf,int doLStat)
+{
+       yaffs_Object *obj;
+       
+       int retVal = -1;
+       
+       yaffsfs_Lock();
+       obj = yaffsfs_FindObject(NULL,path,0);
+       
+       if(!doLStat && obj)
+       {
+               obj = yaffsfs_FollowLink(obj,0);
+       }
+       
+       if(obj)
+       {
+               retVal = yaffsfs_DoStat(obj,buf);
+       }
+       else
+       {
+               // todo error not found
+               yaffsfs_SetError(-ENOENT);
+       }
+       
+       yaffsfs_Unlock();
+       
+       return retVal;
+       
+}
+
+int yaffs_stat(const char *path, struct yaffs_stat *buf)
+{
+       return yaffsfs_DoStatOrLStat(path,buf,0);
+}
+
+int yaffs_lstat(const char *path, struct yaffs_stat *buf)
+{
+       return yaffsfs_DoStatOrLStat(path,buf,1);
+}
+
+int yaffs_fstat(int fd, struct yaffs_stat *buf)
+{
+       yaffs_Object *obj;
+       
+       int retVal = -1;
+       
+       yaffsfs_Lock();
+       obj = yaffsfs_GetHandleObject(fd);
+       
+       if(obj)
+       {
+               retVal = yaffsfs_DoStat(obj,buf);
+       }
+       else
+       {
+               // bad handle
+               yaffsfs_SetError(-EBADF);               
+       }
+       
+       yaffsfs_Unlock();
+       
+       return retVal;
+}
+
+static int yaffsfs_DoChMod(yaffs_Object *obj,mode_t mode)
+{
+       int result = YAFFS_FAIL;
+
+       if(obj)
+       {
+               obj = yaffs_GetEquivalentObject(obj);
+       }
+       
+       if(obj)
+       {
+               obj->yst_mode = mode;
+               obj->dirty = 1;
+               result = yaffs_FlushFile(obj,0);
+       }
+       
+       return result == YAFFS_OK ? 0 : -1;
+}
+
+
+int yaffs_chmod(const char *path, mode_t mode)
+{
+       yaffs_Object *obj;
+       
+       int retVal = -1;
+       
+       yaffsfs_Lock();
+       obj = yaffsfs_FindObject(NULL,path,0);
+       
+       if(obj)
+       {
+               retVal = yaffsfs_DoChMod(obj,mode);
+       }
+       else
+       {
+               // todo error not found
+               yaffsfs_SetError(-ENOENT);
+       }
+       
+       yaffsfs_Unlock();
+       
+       return retVal;
+       
+}
+
+
+int yaffs_fchmod(int fd, mode_t mode)
+{
+       yaffs_Object *obj;
+       
+       int retVal = -1;
+       
+       yaffsfs_Lock();
+       obj = yaffsfs_GetHandleObject(fd);
+       
+       if(obj)
+       {
+               retVal = yaffsfs_DoChMod(obj,mode);
+       }
+       else
+       {
+               // bad handle
+               yaffsfs_SetError(-EBADF);               
+       }
+       
+       yaffsfs_Unlock();
+       
+       return retVal;
+}
+
+
+int yaffs_mkdir(const char *path, mode_t mode)
+{
+       yaffs_Object *parent = NULL;
+       yaffs_Object *dir = NULL;
+       char *name;
+       int retVal= -1;
+       
+       yaffsfs_Lock();
+       parent = yaffsfs_FindDirectory(NULL,path,&name,0);
+       if(parent)
+               dir = yaffs_MknodDirectory(parent,name,mode,0,0);
+       if(dir)
+       {
+               retVal = 0;
+       }
+       else
+       {
+               yaffsfs_SetError(-ENOSPC); // just assume no space for now
+               retVal = -1;
+       }
+       
+       yaffsfs_Unlock();
+       
+       return retVal;
+}
+
+int yaffs_mount(const char *path)
+{
+       int retVal=-1;
+       int result=YAFFS_FAIL;
+       yaffs_Device *dev=NULL;
+       char *dummy;
+       
+       T(YAFFS_TRACE_ALWAYS,("yaffs: Mounting %s\n",path));
+       
+       yaffsfs_Lock();
+       dev = yaffsfs_FindDevice(path,&dummy);
+       if(dev)
+       {
+               if(!dev->isMounted)
+               {
+                       result = yaffs_GutsInitialise(dev);
+                       if(result == YAFFS_FAIL)
+                       {
+                               // todo error - mount failed
+                               yaffsfs_SetError(-ENOMEM);
+                       }
+                       retVal = result ? 0 : -1;
+                       
+               }
+               else
+               {
+                       //todo error - already mounted.
+                       yaffsfs_SetError(-EBUSY);
+               }
+       }
+       else
+       {
+               // todo error - no device
+               yaffsfs_SetError(-ENODEV);
+       }
+       yaffsfs_Unlock();
+       return retVal;
+       
+}
+
+int yaffs_unmount(const char *path)
+{
+       int retVal=-1;
+       yaffs_Device *dev=NULL;
+       char *dummy;
+       
+       yaffsfs_Lock();
+       dev = yaffsfs_FindDevice(path,&dummy);
+       if(dev)
+       {
+               if(dev->isMounted)
+               {
+                       int i;
+                       int inUse;
+                       
+                       yaffs_FlushEntireDeviceCache(dev);
+                       yaffs_CheckpointSave(dev);
+                       
+                       for(i = inUse = 0; i < YAFFSFS_N_HANDLES && !inUse; i++)
+                       {
+                               if(yaffsfs_handle[i].inUse && yaffsfs_handle[i].obj->myDev == dev)
+                               {
+                                       inUse = 1; // the device is in use, can't unmount
+                               }
+                       }
+                       
+                       if(!inUse)
+                       {
+                               yaffs_Deinitialise(dev);
+                                       
+                               retVal = 0;
+                       }
+                       else
+                       {
+                               // todo error can't unmount as files are open
+                               yaffsfs_SetError(-EBUSY);
+                       }
+                       
+               }
+               else
+               {
+                       //todo error - not mounted.
+                       yaffsfs_SetError(-EINVAL);
+                       
+               }
+       }
+       else
+       {
+               // todo error - no device
+               yaffsfs_SetError(-ENODEV);
+       }       
+       yaffsfs_Unlock();
+       return retVal;
+       
+}
+
+loff_t yaffs_freespace(const char *path)
+{
+       loff_t retVal=-1;
+       yaffs_Device *dev=NULL;
+       char *dummy;
+       
+       yaffsfs_Lock();
+       dev = yaffsfs_FindDevice(path,&dummy);
+       if(dev  && dev->isMounted)
+       {
+               retVal = yaffs_GetNumberOfFreeChunks(dev);
+               retVal *= dev->nDataBytesPerChunk;
+               
+       }
+       else
+       {
+               yaffsfs_SetError(-EINVAL);
+       }
+       
+       yaffsfs_Unlock();
+       return retVal;  
+}
+
+
+
+void yaffs_initialise(yaffsfs_DeviceConfiguration *cfgList)
+{
+       
+       yaffsfs_DeviceConfiguration *cfg;
+       
+       yaffsfs_configurationList = cfgList;
+       
+       yaffsfs_InitHandles();
+       
+       cfg = yaffsfs_configurationList;
+       
+       while(cfg && cfg->prefix && cfg->dev)
+       {
+               cfg->dev->isMounted = 0;
+               cfg->dev->removeObjectCallback = yaffsfs_RemoveObjectCallback;
+               cfg++;
+       }
+}
+
+
+//
+// Directory search stuff.
+
+//
+// Directory search context
+//
+// NB this is an opaque structure.
+
+
+typedef struct
+{
+       __u32 magic;
+       yaffs_dirent de;                /* directory entry being used by this dsc */
+       char name[NAME_MAX+1];          /* name of directory being searched */
+       yaffs_Object *dirObj;           /* ptr to directory being searched */
+       yaffs_Object *nextReturn;       /* obj to be returned by next readddir */
+       int offset;
+       struct list_head others;        
+} yaffsfs_DirectorySearchContext;
+
+
+
+static struct list_head search_contexts;
+
+
+static void yaffsfs_SetDirRewound(yaffsfs_DirectorySearchContext *dsc)
+{
+       if(dsc &&
+          dsc->dirObj &&
+          dsc->dirObj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY){
+          
+          dsc->offset = 0;
+          
+          if( list_empty(&dsc->dirObj->variant.directoryVariant.children)){
+               dsc->nextReturn = NULL;
+          } else {
+               dsc->nextReturn = list_entry(dsc->dirObj->variant.directoryVariant.children.next,
+                                               yaffs_Object,siblings);
+          }
+       } else {
+               /* Hey someone isn't playing nice! */
+       }
+}
+
+static void yaffsfs_DirAdvance(yaffsfs_DirectorySearchContext *dsc)
+{
+       if(dsc &&
+          dsc->dirObj &&
+          dsc->dirObj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY){
+          
+          if( dsc->nextReturn == NULL ||
+              list_empty(&dsc->dirObj->variant.directoryVariant.children)){
+               dsc->nextReturn = NULL;
+          } else {
+                  struct list_head *next = dsc->nextReturn->siblings.next;
+   
+                  if( next == &dsc->dirObj->variant.directoryVariant.children)
+                       dsc->nextReturn = NULL; /* end of list */
+                  else 
+                       dsc->nextReturn = list_entry(next,yaffs_Object,siblings);
+          }
+       } else {
+               /* Hey someone isn't playing nice! */
+       }
+}
+
+static void yaffsfs_RemoveObjectCallback(yaffs_Object *obj)
+{
+
+       struct list_head *i;
+       yaffsfs_DirectorySearchContext *dsc;
+       
+       /* if search contexts not initilised then skip */
+       if(!search_contexts.next)
+               return;
+               
+       /* Iteratethrough the directory search contexts.
+        * If any are the one being removed, then advance the dsc to
+        * the next one to prevent a hanging ptr.
+        */
+        list_for_each(i, &search_contexts) {
+               if (i) {
+                       dsc = list_entry(i, yaffsfs_DirectorySearchContext,others);
+                       if(dsc->nextReturn == obj)
+                               yaffsfs_DirAdvance(dsc);
+               }
+       }
+                               
+}
+
+yaffs_DIR *yaffs_opendir(const char *dirname)
+{
+       yaffs_DIR *dir = NULL;
+       yaffs_Object *obj = NULL;
+       yaffsfs_DirectorySearchContext *dsc = NULL;
+       
+       yaffsfs_Lock();
+       
+       obj = yaffsfs_FindObject(NULL,dirname,0);
+       
+       if(obj && obj->variantType == YAFFS_OBJECT_TYPE_DIRECTORY)
+       {
+               
+               dsc = YMALLOC(sizeof(yaffsfs_DirectorySearchContext));
+               dir = (yaffs_DIR *)dsc;
+               if(dsc)
+               {
+                       memset(dsc,0,sizeof(yaffsfs_DirectorySearchContext));
+                       dsc->magic = YAFFS_MAGIC;
+                       dsc->dirObj = obj;
+                       strncpy(dsc->name,dirname,NAME_MAX);
+                       INIT_LIST_HEAD(&dsc->others);
+                       
+                       if(!search_contexts.next)
+                               INIT_LIST_HEAD(&search_contexts);
+                               
+                       list_add(&dsc->others,&search_contexts);        
+                       yaffsfs_SetDirRewound(dsc);             }
+       
+       }
+       
+       yaffsfs_Unlock();
+       
+       return dir;
+}
+
+struct yaffs_dirent *yaffs_readdir(yaffs_DIR *dirp)
+{
+       yaffsfs_DirectorySearchContext *dsc = (yaffsfs_DirectorySearchContext *)dirp;
+       struct yaffs_dirent *retVal = NULL;
+               
+       yaffsfs_Lock();
+       
+       if(dsc && dsc->magic == YAFFS_MAGIC){
+               yaffsfs_SetError(0);
+               if(dsc->nextReturn){
+                       dsc->de.d_ino = yaffs_GetEquivalentObject(dsc->nextReturn)->objectId;
+                       dsc->de.d_dont_use = (unsigned)dsc->nextReturn;
+                       dsc->de.d_off = dsc->offset++;
+                       yaffs_GetObjectName(dsc->nextReturn,dsc->de.d_name,NAME_MAX);
+                       if(strlen(dsc->de.d_name) == 0)
+                       {
+                               // this should not happen!
+                               strcpy(dsc->de.d_name,"zz");
+                       }
+                       dsc->de.d_reclen = sizeof(struct yaffs_dirent);
+                       retVal = &dsc->de;
+                       yaffsfs_DirAdvance(dsc);
+               } else
+                       retVal = NULL;
+       }
+       else
+       {
+               yaffsfs_SetError(-EBADF);
+       }
+       
+       yaffsfs_Unlock();
+       
+       return retVal;
+       
+}
+
+
+void yaffs_rewinddir(yaffs_DIR *dirp)
+{
+       yaffsfs_DirectorySearchContext *dsc = (yaffsfs_DirectorySearchContext *)dirp;
+       
+       yaffsfs_Lock();
+       
+       yaffsfs_SetDirRewound(dsc);
+
+       yaffsfs_Unlock();
+}
+
+
+int yaffs_closedir(yaffs_DIR *dirp)
+{
+       yaffsfs_DirectorySearchContext *dsc = (yaffsfs_DirectorySearchContext *)dirp;
+               
+       yaffsfs_Lock();
+       dsc->magic = 0;
+       list_del(&dsc->others); /* unhook from list */
+       YFREE(dsc);
+       yaffsfs_Unlock();
+       return 0;
+}
+
+// end of directory stuff
+
+
+int yaffs_symlink(const char *oldpath, const char *newpath)
+{
+       yaffs_Object *parent = NULL;
+       yaffs_Object *obj;
+       char *name;
+       int retVal= -1;
+       int mode = 0; // ignore for now
+       
+       yaffsfs_Lock();
+       parent = yaffsfs_FindDirectory(NULL,newpath,&name,0);
+       obj = yaffs_MknodSymLink(parent,name,mode,0,0,oldpath);
+       if(obj)
+       {
+               retVal = 0;
+       }
+       else
+       {
+               yaffsfs_SetError(-ENOSPC); // just assume no space for now
+               retVal = -1;
+       }
+       
+       yaffsfs_Unlock();
+       
+       return retVal;
+       
+}
+
+int yaffs_readlink(const char *path, char *buf, int bufsiz)
+{
+       yaffs_Object *obj = NULL;
+       int retVal;
+
+               
+       yaffsfs_Lock();
+       
+       obj = yaffsfs_FindObject(NULL,path,0);
+       
+       if(!obj)
+       {
+               yaffsfs_SetError(-ENOENT);
+               retVal = -1;
+       }
+       else if(obj->variantType != YAFFS_OBJECT_TYPE_SYMLINK)
+       {
+               yaffsfs_SetError(-EINVAL);
+               retVal = -1;
+       }
+       else
+       {
+               char *alias = obj->variant.symLinkVariant.alias;
+               memset(buf,0,bufsiz);
+               strncpy(buf,alias,bufsiz - 1);
+               retVal = 0;
+       }
+       yaffsfs_Unlock();
+       return retVal;
+}
+
+int yaffs_link(const char *oldpath, const char *newpath)
+{
+       // Creates a link called newpath to existing oldpath
+       yaffs_Object *obj = NULL;
+       yaffs_Object *target = NULL;
+       int retVal = 0;
+
+               
+       yaffsfs_Lock();
+       
+       obj = yaffsfs_FindObject(NULL,oldpath,0);
+       target = yaffsfs_FindObject(NULL,newpath,0);
+       
+       if(!obj)
+       {
+               yaffsfs_SetError(-ENOENT);
+               retVal = -1;
+       }
+       else if(target)
+       {
+               yaffsfs_SetError(-EEXIST);
+               retVal = -1;
+       }
+       else    
+       {
+               yaffs_Object *newdir = NULL;
+               yaffs_Object *link = NULL;
+               
+               char *newname;
+               
+               newdir = yaffsfs_FindDirectory(NULL,newpath,&newname,0);
+               
+               if(!newdir)
+               {
+                       yaffsfs_SetError(-ENOTDIR);
+                       retVal = -1;
+               }
+               else if(newdir->myDev != obj->myDev)
+               {
+                       yaffsfs_SetError(-EXDEV);
+                       retVal = -1;
+               }
+               if(newdir && strlen(newname) > 0)
+               {
+                       link = yaffs_Link(newdir,newname,obj);
+                       if(link)
+                               retVal = 0;
+                       else
+                       {
+                               yaffsfs_SetError(-ENOSPC);
+                               retVal = -1;
+                       }
+
+               }
+       }
+       yaffsfs_Unlock();
+       
+       return retVal;
+}
+
+int yaffs_mknod(const char *pathname, mode_t mode, dev_t dev);
+
+int yaffs_DumpDevStruct(const char *path)
+{
+       char *rest;
+       
+       yaffs_Object *obj = yaffsfs_FindRoot(path,&rest);
+       
+       if(obj)
+       {
+               yaffs_Device *dev = obj->myDev;
+               
+               printf("\n"
+                          "nPageWrites.......... %d\n"
+                          "nPageReads........... %d\n"
+                          "nBlockErasures....... %d\n"
+                          "nGCCopies............ %d\n"
+                          "garbageCollections... %d\n"
+                          "passiveGarbageColl'ns %d\n"
+                          "\n",
+                               dev->nPageWrites,
+                               dev->nPageReads,
+                               dev->nBlockErasures,
+                               dev->nGCCopies,
+                               dev->garbageCollections,
+                               dev->passiveGarbageCollections
+               );
+               
+       }
+       return 0;
+}
diff --git a/fs/yaffs2/yaffsfs.h b/fs/yaffs2/yaffsfs.h
new file mode 100644 (file)
index 0000000..9afe60a
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * 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 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.
+ */
+
+/*
+ * Header file for using yaffs in an application via
+ * a direct interface.
+ */
+
+
+#ifndef __YAFFSFS_H__
+#define __YAFFSFS_H__
+
+#include "yaffscfg.h"
+#include "yportenv.h"
+
+
+//typedef long off_t;
+//typedef long dev_t;
+//typedef unsigned long mode_t;
+
+
+#ifndef NAME_MAX
+#define NAME_MAX       256
+#endif
+
+#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 EACCESS
+#define EACCESS        13
+#endif
+
+#ifndef EXDEV  
+#define EXDEV  18
+#endif
+
+#ifndef ENOENT
+#define ENOENT 2
+#endif
+
+#ifndef ENOSPC
+#define ENOSPC 28
+#endif
+
+#ifndef ENOTEMPTY
+#define ENOTEMPTY 39
+#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
+
+
+
+
+struct yaffs_dirent{
+    long d_ino;                 /* inode number */
+    off_t d_off;                /* offset to this dirent */
+    unsigned short d_reclen;    /* length of this d_name */
+    char d_name [NAME_MAX+1];   /* file name (null-terminated) */
+    unsigned d_dont_use;       /* debug pointer, not for public consumption */
+};
+
+typedef struct yaffs_dirent yaffs_dirent;
+
+
+typedef struct __opaque yaffs_DIR;
+
+
+
+struct yaffs_stat{
+    int                      st_dev;      /* device */
+    int           st_ino;      /* inode */
+    mode_t        st_mode;     /* protection */
+    int           st_nlink;    /* number of hard links */
+    int           st_uid;      /* user ID of owner */
+    int           st_gid;      /* group ID of owner */
+    unsigned      st_rdev;     /* device type (if inode device) */
+    off_t         st_size;     /* total size, in bytes */
+    unsigned long st_blksize;  /* blocksize for filesystem I/O */
+    unsigned long st_blocks;   /* number of blocks allocated */
+    unsigned long yst_atime;    /* time of last access */
+    unsigned long yst_mtime;    /* time of last modification */
+    unsigned long yst_ctime;    /* time of last change */
+};
+
+int yaffs_open(const char *path, int oflag, int mode) ;
+int yaffs_read(int fd, void *buf, unsigned int nbyte) ;
+int yaffs_write(int fd, const void *buf, unsigned int nbyte) ;
+int yaffs_close(int fd) ;
+off_t yaffs_lseek(int fd, off_t offset, int whence) ;
+int yaffs_truncate(int fd, off_t newSize);
+
+int yaffs_unlink(const char *path) ;
+int yaffs_rename(const char *oldPath, const char *newPath) ;
+
+int yaffs_stat(const char *path, struct yaffs_stat *buf) ;
+int yaffs_lstat(const char *path, struct yaffs_stat *buf) ;
+int yaffs_fstat(int fd, struct yaffs_stat *buf) ;
+
+int yaffs_chmod(const char *path, mode_t mode); 
+int yaffs_fchmod(int fd, mode_t mode); 
+
+int yaffs_mkdir(const char *path, mode_t mode) ;
+int yaffs_rmdir(const char *path) ;
+
+yaffs_DIR *yaffs_opendir(const char *dirname) ;
+struct yaffs_dirent *yaffs_readdir(yaffs_DIR *dirp) ;
+void yaffs_rewinddir(yaffs_DIR *dirp) ;
+int yaffs_closedir(yaffs_DIR *dirp) ;
+
+int yaffs_mount(const char *path) ;
+int yaffs_unmount(const char *path) ;
+
+int yaffs_symlink(const char *oldpath, const char *newpath); 
+int yaffs_readlink(const char *path, char *buf, int bufsiz); 
+
+int yaffs_link(const char *oldpath, const char *newpath); 
+int yaffs_mknod(const char *pathname, mode_t mode, dev_t dev);
+
+loff_t yaffs_freespace(const char *path);
+
+void yaffs_initialise(yaffsfs_DeviceConfiguration *configList);
+
+int yaffs_StartUp(void);
+
+#endif
+
+
diff --git a/fs/yaffs2/ydirectenv.h b/fs/yaffs2/ydirectenv.h
new file mode 100644 (file)
index 0000000..adcc0b5
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * 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 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.
+ */
+
+/*
+ * ydirectenv.h: Environment wrappers for YAFFS direct.
+ */
+
+#ifndef __YDIRECTENV_H__
+#define __YDIRECTENV_H__
+
+// Direct interface
+
+#include "devextras.h"
+
+/* XXX U-BOOT XXX */
+#if 0
+#include "stdlib.h"
+#include "stdio.h"
+#include "string.h"
+#include "assert.h"
+#endif
+#include "yaffs_malloc.h"
+
+/* XXX U-BOOT XXX */
+#if 0
+#define YBUG() assert(1)
+#endif
+
+#define YCHAR char
+#define YUCHAR unsigned char
+#define _Y(x) x
+#define yaffs_strcpy(a,b)    strcpy(a,b)
+#define yaffs_strncpy(a,b,c) strncpy(a,b,c)
+#define yaffs_strncmp(a,b,c) strncmp(a,b,c)
+#define yaffs_strlen(s)             strlen(s)
+#define yaffs_sprintf       sprintf
+#define yaffs_toupper(a)     toupper(a)
+
+#ifdef NO_Y_INLINE
+#define Y_INLINE
+#else
+#define Y_INLINE inline
+#endif
+
+#define YMALLOC(x) yaffs_malloc(x)
+#define YFREE(x)   free(x)
+#define YMALLOC_ALT(x) yaffs_malloc(x)
+#define YFREE_ALT(x)   free(x)
+
+#define YMALLOC_DMA(x) yaffs_malloc(x)
+
+#define YYIELD()  do {} while(0)
+
+
+
+//#define YINFO(s) YPRINTF(( __FILE__ " %d %s\n",__LINE__,s))
+//#define YALERT(s) YINFO(s)
+
+
+#define TENDSTR "\n"
+#define TSTR(x) x
+#define TOUT(p) printf p
+
+
+#define YAFFS_LOSTNFOUND_NAME          "lost+found"
+#define YAFFS_LOSTNFOUND_PREFIX                "obj"
+//#define YPRINTF(x) printf x
+
+#include "yaffscfg.h"
+
+#define Y_CURRENT_TIME yaffsfs_CurrentTime()
+#define Y_TIME_CONVERT(x) x
+
+#define YAFFS_ROOT_MODE                                0666
+#define YAFFS_LOSTNFOUND_MODE          0666
+
+#define yaffs_SumCompare(x,y) ((x) == (y))
+#define yaffs_strcmp(a,b) strcmp(a,b)
+
+#endif
+
+