summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-04-28 19:26:46 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-04-28 19:26:46 +0000
commitf5deadfbb2ea797607ce7646c2bca1fdfe74c3c2 (patch)
tree7b25391c6c8172936f0c27efae5b40503b7d03c4
parentb501edd4c0f7b4fffc6d187ee5e0bd862d381a79 (diff)
downloadnuttx-f5deadfbb2ea797607ce7646c2bca1fdfe74c3c2.tar.gz
nuttx-f5deadfbb2ea797607ce7646c2bca1fdfe74c3c2.tar.bz2
nuttx-f5deadfbb2ea797607ce7646c2bca1fdfe74c3c2.zip
Add first NXFFS files
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3536 42af7a65-404d-4744-a932-0658087f49c3
-rw-r--r--nuttx/fs/Makefile8
-rw-r--r--nuttx/fs/fat/Make.defs14
-rw-r--r--nuttx/fs/nxffs/Make.defs44
-rw-r--r--nuttx/fs/nxffs/nxffs.h690
-rw-r--r--nuttx/fs/nxffs/nxffs_block.c166
-rw-r--r--nuttx/fs/nxffs/nxffs_blockstats.c153
-rw-r--r--nuttx/fs/nxffs/nxffs_cache.c243
-rw-r--r--nuttx/fs/nxffs/nxffs_initialize.c272
-rw-r--r--nuttx/fs/nxffs/nxffs_inode.c380
-rw-r--r--nuttx/fs/nxffs/nxffs_reformat.c281
-rw-r--r--nuttx/fs/nxffs/nxffs_util.c112
-rw-r--r--nuttx/fs/romfs/Make.defs12
12 files changed, 2364 insertions, 11 deletions
diff --git a/nuttx/fs/Makefile b/nuttx/fs/Makefile
index 3423250ba..3f9356391 100644
--- a/nuttx/fs/Makefile
+++ b/nuttx/fs/Makefile
@@ -63,6 +63,7 @@ CSRCS += fs_mount.c fs_umount.c fs_fsync.c fs_unlink.c fs_rename.c \
fs_mkdir.c fs_rmdir.c
include fat/Make.defs
include romfs/Make.defs
+include nxffs/Make.defs
endif
endif
@@ -73,8 +74,8 @@ OBJS = $(AOBJS) $(COBJS)
BIN = libfs$(LIBEXT)
-SUBDIRS = fat romfs
-VPATH = fat:romfs
+SUBDIRS = fat romfs nxffs
+VPATH = fat:romfs:nxffs
all: $(BIN)
@@ -90,7 +91,8 @@ $(BIN): $(OBJS)
done ; )
.depend: Makefile $(SRCS)
- @$(MKDEP) --dep-path . --dep-path fat --dep-path romfs $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
+ @$(MKDEP) --dep-path . $(FATDEPPATH) $(ROMFSDEPPATH) $(NXFFSDEPPATH) \
+ $(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
@touch $@
depend: .depend
diff --git a/nuttx/fs/fat/Make.defs b/nuttx/fs/fat/Make.defs
index 2f1a01003..111217efc 100644
--- a/nuttx/fs/fat/Make.defs
+++ b/nuttx/fs/fat/Make.defs
@@ -1,7 +1,7 @@
############################################################################
# Make.defs
#
-# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Copyright (C) 2008, 2011 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <spudmonkey@racsa.co.cr>
#
# Redistribution and use in source and binary forms, with or without
@@ -36,11 +36,15 @@
ifeq ($(CONFIG_FS_FAT),y)
# Files required for FAT file system support
-ASRCS +=
-CSRCS += fs_fat32.c fs_fat32attrib.c fs_fat32util.c
+ASRCS +=
+CSRCS += fs_fat32.c fs_fat32attrib.c fs_fat32util.c
# Files required for mkfatfs utility function
-ASRCS +=
-CSRCS += fs_mkfatfs.c fs_configfat.c fs_writefat.c
+ASRCS +=
+CSRCS += fs_mkfatfs.c fs_configfat.c fs_writefat.c
+
+# Argument for dependency checking
+
+FATDEPPATH = --dep-path fat
endif
diff --git a/nuttx/fs/nxffs/Make.defs b/nuttx/fs/nxffs/Make.defs
new file mode 100644
index 000000000..23e9d3ec2
--- /dev/null
+++ b/nuttx/fs/nxffs/Make.defs
@@ -0,0 +1,44 @@
+############################################################################
+# fs/nxffs/Make.defs
+#
+# Copyright (C) 2011 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name Nuttx nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+ifeq ($(CONFIG_FS_NXFFS),y)
+ASRCS +=
+CSRCS += nxffs_block.c nxffs_blockstats.c nxffs_cache.c \
+ nxffs_initialize.c nxffs_inode.c nxffs_reformat.c nxffs_util.c
+
+# Argument for dependency checking
+
+NXFFSDEPPATH = --dep-path nxffs
+endif
diff --git a/nuttx/fs/nxffs/nxffs.h b/nuttx/fs/nxffs/nxffs.h
new file mode 100644
index 000000000..13f93644e
--- /dev/null
+++ b/nuttx/fs/nxffs/nxffs.h
@@ -0,0 +1,690 @@
+/****************************************************************************
+ * fs/nxffs/nxffs.h
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * References: Linux/Documentation/filesystems/romfs.txt
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __FS_NXFFS_NXFFS_H
+#define __FS_NXFFS_NXFFS_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <semaphore.h>
+
+#include <nuttx/mtd.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+/* Configuration ************************************************************/
+#ifndef CONFIG_NXFFS_ERASEDSTATE
+# define CONFIG_NXFFS_ERASEDSTATE 0xff
+#endif
+
+#if CONFIG_NXFFS_ERASEDSTATE != 0xff && CONFIG_NXFFS_ERASEDSTATE != 0x00
+# error "CONFIG_NXFFS_ERASEDSTATE must be either 0x00 or 0xff"
+#endif
+
+/* NXFFS Definitions ********************************************************/
+/* General NXFFS organization. The following example assumes 4 logical
+ * blocks per FLASH erase block. The actual relationship is determined by
+ * the FLASH geometry reported by the MTD driver.
+ *
+ * ERASE LOGICAL Inodes begin with a inode header. inode may
+ * BLOCK BLOCK CONTENTS be marked as "deleted," pending clean-up.
+ * n 4*n --+--------------+
+ * |BBBBBBBBBBBBBB| Logic block header
+ * |IIIIIIIIIIIIII| Inodes begin with a inode header
+ * |DDDDDDDDDDDDD| Data block containing inode data block
+ * | (Inode Data) |
+ * 4*n+1 --+--------------+
+ * |BBBBBBBBBBBBBB| Logic block header
+ * |DDDDDDDDDDDDDD| Inodes may consist of multiple data blocks
+ * | (Inode Data) |
+ * |IIIIIIIIIIIIII| Next inode header
+ * | | Possibly a few unused bytes at the end of a block
+ * 4*n+2 --+--------------+
+ * |BBBBBBBBBBBBBB| Logic block header
+ * |DDDDDDDDDDDDDD|
+ * | (Inode Data) |
+ * 4*n+3 --+--------------+
+ * |BBBBBBBBBBBBBB| Logic block header
+ * |IIIIIIIIIIIIII| Next inode header
+ * |DDDDDDDDDDDDDD|
+ * | (Inode Data) |
+ * n+1 4*(n+1) --+--------------+
+ * |BBBBBBBBBBBBBB| Logic block header
+ * | | All FLASH is unused after the end of the final
+ * | | inode.
+ * --+--------------+
+ *
+ * General operation:
+ * Inodes are written starting at the beginning of FLASH. As inodes are
+ * deleted, they are marked as deleted but not removed. As new inodes are
+ * written, allocations proceed to toward the end of the FLASH -- thus,
+ * supporting wear leveling by using all FLASH blocks equally.
+ *
+ * When the FLASH becomes full (no more space at the end of the FLASH), a
+ * clean-up operation must be performed: All inodes marked deleted are
+ * finally removed and the remaining inodes are packed at the beginning of
+ * the FLASH. Allocations then continue at the freed FLASH memory at the
+ * end of the FLASH.
+ *
+ * BLOCK HEADER:
+ * The block header is used to determine if the block has every been
+ * formatted and also indicates bad blocks which should never be used.
+ *
+ * INODE HEADER:
+ * Each inode begins with an inode header that contains, among other things,
+ * the name of the inode, the offset to the first data block, and the
+ * length of the inode data.
+ *
+ * At present, the only kind of inode support is a file. So for now, the
+ * term file and inode are interchangeable.
+ *
+ * INODE DATA HEADER:
+ * Inode data is enclosed in a data header. For a given inode, there
+ * is at most one inode data block per logical block. If the inode data
+ * spans more than one logical block, then the inode data may be enclosed
+ * in multiple data blocks, one per logical block.
+ *
+ * NXFFS Limitations:
+ * 1. Since the files are contiguous in FLASH and since allocations always
+ * proceed toward the end of the FLASH, there can only be one file opened
+ * for writing at a time. Multiple files may be opened for reading.
+ * 2. Files may not be increased in size after they have been closed. The
+ * O_APPEND open flag is not supported.
+ * 3. Files are always written sequential. Seeking within a file opened for
+ * writing will not work.
+ * 4. There are no directories, however, '/' may be used within a file name
+ * string providing some illusion of directories.
+ * 5. Files may be opened for reading or for writing, but not both: The O_RDWR
+ * open flag is not supported.
+ * 6. The clean-up process occurs only during a write when the free FLASH
+ * memory at the end of the FLASH is exhausted. Thus, occasionally, file
+ * writing may take a long time.
+ *
+ */
+
+/* Values for logical block state. Basically, there are only two, perhaps
+ * three, states:
+ *
+ * BLOCK_STATE_GOOD - The block is not known to be bad.
+ * BLOCK_STATE_BAD - An error was found on the block and it is marked bad.
+ * Other values - The block is bad and has an invalid state.
+ */
+
+#define BLOCK_STATE_GOOD CONFIG_NXFFS_ERASEDSTATE
+#define BLOCK_STATE_BAD 0xaa
+
+/* Values for NXFFS inode state. Similar there are 2 (maybe 3) inode states:
+ *
+ * INODE_STATE_FILE - The inode is a valid usuable, file
+ * INODE_STATE_DELETED - The inode has been deleted.
+ */
+
+#define INODE_STATE_FILE CONFIG_NXFFS_ERASEDSTATE
+#define INODE_STATE_DELETED 0x55
+
+/* Number of bytes in an the NXFFS magic sequences */
+
+#define NXFFS_MAGICSIZE 4
+
+/* Internal definitions *****************************************************/
+/* Values for volume flags */
+
+#define VOL_FLAGS_WRITER (1 << 0) /* Only one writer of the volune */
+
+#define VOL_FLAGS_SET(p,f) ((p)->flags &= ~(f))
+#define VOL_FLAGS_CLEAR(p,f) ((p)->flags |= (f))
+#define VOL_FLAGS_TEST(p,f) (((p)->flags & (f)) == 0)
+
+/* If we encounter this number of erased bytes, we assume that all of the
+ * flash beyond this point is erased.
+ */
+
+#define NXFFS_NERASED 128
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* This structure defines each packed block on the FLASH media */
+
+struct nxffs_block_s
+{
+ uint8_t magic[4]; /* 0-3: Magic number for valid block */
+ uint8_t state; /* 4: Block state: See BLOCK_STATE_* */
+};
+#define SIZEOF_NXFFS_BLOCK_HDR 5
+
+/* This structure defines each packed NXFFS inode header on the FLASH media */
+
+struct nxffs_inode_s
+{
+ uint8_t magic[4]; /* 0-3: Magic number for valid inode */
+ uint8_t state; /* 4: Inode state: See INODE_STATE_* */
+ uint8_t noffset; /* 5: Offset to the file name from the header */
+ uint8_t doffset; /* 5: Offset to data from file header */
+ uint8_t utc[4]; /* 7-9: Creation time */
+ uint8_t crc[4]; /* 10-13: CRC32 */
+ uint8_t datlen[4]; /* 14-17: Length of data in bytes */
+ /* 18-: Variable length file name follows */
+};
+#define SIZEOF_NXFFS_INODE_HDR 18
+
+/* This structure defines each packed NXFFS data header on the FLASH media */
+
+struct nxffs_data_s
+{
+ uint8_t magic[4]; /* 0-3: Magic number for valid data */
+ uint8_t crc[4]; /* 4-7: CRC32 */
+ uint8_t datlen[4]; /* 8-11: Length of data in bytes */
+ /* 12-: Variable length data follows */
+};
+#define SIZEOF_NXFFS_DATA_HDR 12
+
+/* This is an in-memory representation of the NXFFS inode as extracted from
+ * FLASH and with additional state information.
+ */
+
+struct nxffs_entry_s
+{
+ off_t hoffset; /* Offset to the inode on the media */
+ off_t doffset; /* Offset to the data on the media */
+ FAR char *name; /* inode name */
+ uint32_t utc; /* Time stamp */
+ uint32_t datlen; /* Length of inode data */
+};
+
+/* This structure represents the overall state of on NXFFS instance. */
+
+struct nxffs_volume_s
+{
+ FAR struct mtd_dev_s *mtd; /* Supports FLASH access */
+ sem_t exclsem; /* Used to assure thread-safe access */
+ struct mtd_geometry_s geo; /* Device geometry */
+ uint8_t wrbusy: 1; /* 1: Volume open for writing */
+ uint8_t blkper; /* R/W blocks per erase block */
+ uint8_t ncached; /* Number of blocks in cache */
+ uint16_t iooffset; /* Next offset in read/write access (in ioblock) */
+ off_t inoffset; /* Offset to the first valid inode header */
+ off_t froffset; /* Offset to the first free byte */
+ off_t ioblock; /* Current block number being accessed */
+ off_t cblock; /* Starting block number in cache */
+ FAR uint8_t *cache; /* Allocated erase block */
+};
+
+/* This structure describes the state of one open file. This structure
+ * is protected by the volume semaphore.
+ */
+
+struct nxffs_ofile_s
+{
+ struct nxffs_ofile_s *flink; /* Supports a singly linked list */
+ int16_t crefs; /* Reference count */
+ mode_t mode; /* Open mode */
+ struct nxffs_entry_s entry; /* Describes the NXFFS inode entry */
+};
+
+/* A file opened for writing require some additional information */
+
+struct nxffs_wrfile_s
+{
+ /* The following fields provide the common open file information. */
+
+ struct nxffs_ofile_s ofile;
+
+ /* The following fields are required to support the current write
+ * operation. Note that the size of the current block can be determined
+ * from (wroffset - dathdr - SIZEOF_NXFFS_DATA_HDR). Basic write
+ * operation:
+ *
+ * 1. Inode header location determined (but not yet written).
+ * 2. Block header location determined (but not yet written).
+ * 3. Check FLASH memory to make sure that it is erased.
+ * 4. As data is written, wrlen is updated and the data is written to FLASH.
+ * 5. If the end of the FLASH block is encountered, the data block CRC is
+ * calculated and the block header is also written to flash.
+ * 6. When the file is closed, the final, partial data block is written to
+ * FLASH in the same way. The final file size is determined, the header
+ * CRC is calculated, and the inode header is written to FLASH, completing
+ * the write operation.
+ */
+
+ uint16_t wrlen; /* Number of bytes written in data block */
+ off_t dathdr; /* FLASH offset to the current data header */
+};
+
+/* This structure describes the state of the blocks on the NXFFS volume */
+
+struct nxffs_blkstats_s
+{
+ off_t nblocks; /* Total number of FLASH blocks */
+ off_t ngood; /* Number of good FLASH blocks found */
+ off_t nbad; /* Number of well-formatted FLASH blocks marked as bad */
+ off_t nunformat; /* Number of unformatted FLASH blocks */
+ off_t ncorrupt; /* Number of blocks with correupted format info */
+};
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/* A singly-linked list of open files */
+
+extern struct nxffs_ofile_s *g_ofiles;
+
+/* The magic number that appears that the beginning of each NXFFS (logical)
+ * block
+ */
+
+extern const uint8_t g_blockmagic[NXFFS_MAGICSIZE];
+
+/* The magic number that appears that the beginning of each NXFFS inode */
+
+extern const uint8_t g_inodemagic[NXFFS_MAGICSIZE];
+
+/* The magic number that appears that the beginning of each NXFFS inode
+ * data block.
+ */
+
+extern const uint8_t g_datamagic[NXFFS_MAGICSIZE];
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxffs_limits
+ *
+ * Description:
+ * Recalculate file system limits: (1) the FLASH offset to the first,
+ * valid inode, and (2) the FLASH offset to the first, unused byte after
+ * the last inode (invalid or not).
+ *
+ * The first, lower limit must be recalculated: (1) initially, (2)
+ * whenever the first inode is deleted, or (3) whenever inode is moved
+ * as part of the clean-up operation.
+ *
+ * The second, upper limit must be (1) incremented whenever new file
+ * data is written, or (2) recalculated as part of the clean-up operation.
+ *
+ * Input Parameters:
+ * volume - Identifies the NXFFS volume
+ *
+ * Returned Value:
+ * Zero on success. Otherwise, a negated error is returned indicating the
+ * nature of the failure.
+ *
+ * Defined in nxffs_initialize.c
+ *
+ ****************************************************************************/
+
+extern int nxffs_limits(FAR struct nxffs_volume_s *volume);
+
+/****************************************************************************
+ * Name: nxffs_rdle16
+ *
+ * Description:
+ * Get a (possibly unaligned) 16-bit little endian value.
+ *
+ * Input Parameters:
+ * val - A pointer to the first byte of the little endian value.
+ *
+ * Returned Values:
+ * A uint16_t representing the whole 16-bit integer value
+ *
+ * Defined in nxffs_util.c
+ *
+ ****************************************************************************/
+
+extern uint16_t nxffs_rdle16(const uint8_t *val);
+
+/****************************************************************************
+ * Name: nxffs_rdle32
+ *
+ * Description:
+ * Get a (possibly unaligned) 32-bit little endian value.
+ *
+ * Input Parameters:
+ * val - A pointer to the first byte of the little endian value.
+ *
+ * Returned Values:
+ * A uint32_t representing the whole 32-bit integer value
+ *
+ * Defined in nxffs_util.c
+ *
+ ****************************************************************************/
+
+extern uint32_t nxffs_rdle32(const uint8_t *val);
+
+/****************************************************************************
+ * Name: nxffs_rdcache
+ *
+ * Description:
+ * Read one or more logical blocks into the volume cache memory.
+ *
+ * Input Parameters:
+ * volume - Describes the current volume
+ * block - The first logical block to read
+ * nblocks - The number of logical blocks to be read.
+ *
+ * Returned Value:
+ * Negated errnos are returned only in the case of MTD reported failures.
+ * Nothing in the volume data itself will generate errors.
+ *
+ * Defined in nxffs_cache.c
+ *
+ ****************************************************************************/
+
+extern int nxffs_rdcache(FAR struct nxffs_volume_s *volume, off_t block,
+ uint8_t nblocks);
+
+/****************************************************************************
+ * Name: nxffs_ioseek
+ *
+ * Description:
+ * Seek to a position in FLASH memory. This simply sets up the offsets
+ * and pointer values. This is a necessary step prior to using
+ * nxffs_getc().
+ *
+ * Input Parameters:
+ * volume - Describes the NXFFS volume
+ * offset - The physical offset in bytes from the beginning of the FLASH
+ * in bytes.
+ *
+ * Defined in nxffs_cache.c
+ *
+ ****************************************************************************/
+
+extern void nxffs_ioseek(FAR struct nxffs_volume_s *volume, off_t offset);
+
+/****************************************************************************
+ * Name: nxffs_getc
+ *
+ * Description:
+ * Get the next byte from FLASH. This function allows the data in the
+ * formatted FLASH blocks to be read as a continuous byte stream, skipping
+ * over bad blocks and block headers as necessary.
+ *
+ * Input Parameters:
+ * volume - Describes the NXFFS volume. The paramters ioblock and iooffset
+ * in the volume structure determine the behavior of nxffs_getc().
+ *
+ * Returned Value:
+ * Zero is returned on success. Otherwise, a negated errno indicating the
+ * nature of the failure.
+ *
+ * Defined in nxffs_cache.c
+ *
+ ****************************************************************************/
+
+extern int nxffs_getc(FAR struct nxffs_volume_s *volume);
+
+/****************************************************************************
+ * Name: nxffs_rddata
+ *
+ * Description:
+ * Read a sequence of data bytes from the FLASH memory. This function
+ * allows the data in the formatted FLASH blocks to be read as a continuous\
+ * byte stream, skipping over bad blocks and block headers as necessary.
+ *
+ * Input Parameters:
+ * volume - Describes the NXFFS volume. The paramters ioblock and iooffset
+ * in the volume structure determine the behavior of nxffs_getc().
+ *
+ * Returned Value:
+ * The number of bytes read is returned on success. Otherwise, a negated
+ * errno indicating the nature of the failure.
+ *
+ * Defined in nxffs_cache.c
+ *
+ ****************************************************************************/
+
+extern ssize_t nxffs_rddata(FAR struct nxffs_volume_s *volume,
+ FAR uint8_t *buffer, size_t buflen);
+
+/****************************************************************************
+ * Name: nxffs_freeentry
+ *
+ * Description:
+ * The inode values returned by nxffs_nextentry() include allocated memory
+ * (specifically, the file name string). This function should be called
+ * to dispose of that memory when the inode entry is no longer needed.
+ *
+ * Note that the nxffs_entry_s containing structure is not freed. The
+ * caller may call kfree upon return of this function if necessary to
+ * free the entry container.
+ *
+ * Input parameters:
+ * entry - The entry to be freed.
+ *
+ * Returned Value:
+ * None
+ *
+ * Defined in nxffs_inode.c
+ *
+ ****************************************************************************/
+
+extern void nxffs_freeentry(FAR struct nxffs_entry_s *entry);
+
+/****************************************************************************
+ * Name: nxffs_nextentry
+ *
+ * Description:
+ * Search for the next valid inode starting at the provided FLASH offset.
+ *
+ * Input Parameters:
+ * volume - Describes the NXFFS volume.
+ * offset - The FLASH memory offset to begin searching.
+ * entry - A pointer to memory provided by the caller in which to return
+ * the inode description.
+ *
+ * Returned Value:
+ * Zero is returned on success. Otherwise, a negated errno is returned
+ * that indicates the nature of the failure.
+ *
+ * Defined in nxffs_inode.c
+ *
+ ****************************************************************************/
+
+extern int nxffs_nextentry(FAR struct nxffs_volume_s *volume, off_t offset,
+ FAR struct nxffs_entry_s *entry);
+
+/****************************************************************************
+ * Name: nxffs_findinode
+ *
+ * Description:
+ * Search for an inode with the provided name starting with the first
+ * valid inode and proceeding to the end FLASH or until the matching
+ * inode is found.
+ *
+ * Input Parameters:
+ * volume - Describes the NXFFS volume
+ * name - The name of the inode to find
+ * entry - The location to return information about the inode.
+ *
+ * Returned Value:
+ * Zero is returned on success. Otherwise, a negated errno is returned
+ * that indicates the nature of the failure.
+ *
+ * Defined in nxffs_inode.c
+ *
+ ****************************************************************************/
+
+extern int nxffs_findinode(FAR struct nxffs_volume_s *volume,
+ FAR const char *name,
+ struct nxffs_entry_s *entry);
+
+/****************************************************************************
+ * Name: nxffs_verifyblock
+ *
+ * Description:
+ * Assure the the provided (logical) block number is in the block cache
+ * and that it has a valid block header (i.e., proper magic and
+ * marked good)
+ *
+ * Input Parameters:
+ * volume - Describes the NXFFS volume
+ * block - The (logical) block number to load and verify.
+ *
+ * Returned Values:
+ * Zero is returned on success. Otherwise, a negated errno value is
+ * returned indicating the nature of the failure.
+ *
+ * Defined in nxffs_block.c
+ *
+ ****************************************************************************/
+
+extern int nxffs_verifyblock(FAR struct nxffs_volume_s *volume, off_t block);
+
+/****************************************************************************
+ * Name: nxffs_validblock
+ *
+ * Description:
+ * Find the next valid (logical) block in the volume.
+ *
+ * Input Parameters:
+ * volume - Describes the NXFFS volume
+ * block - On entry, this provides the starting block number. If the
+ * function is succesfful, then this memory location will hold the
+ * block number of the next valid block on return.
+ *
+ * Returned Value:
+ * Zero on success otherwise a negated errno value indicating the nature
+ * of the failure.
+ *
+ * Defined in nxffs_block.c
+ *
+ ****************************************************************************/
+
+extern int nxffs_validblock(struct nxffs_volume_s *volume, off_t *block);
+
+/****************************************************************************
+ * Name: nxffs_blockstats
+ *
+ * Description:
+ * Analyze the NXFFS volume. This operation must be performed when the
+ * volume is first mounted in order to detect if the volume has been
+ * formatted and contains a usable NXFFS file system.
+ *
+ * Input Parameters:
+ * volume - Describes the current NXFFS volume.
+ * stats - On return, will hold nformation describing the state of the
+ * volume.
+ *
+ * Returned Value:
+ * Negated errnos are returned only in the case of MTD reported failures.
+ * Nothing in the volume data itself will generate errors.
+ *
+ * Defined in nxffs_blockstats.c
+ *
+ ****************************************************************************/
+
+extern int nxffs_blockstats(FAR struct nxffs_volume_s *volume,
+ FAR struct nxffs_blkstats_s *stats);
+
+/****************************************************************************
+ * Name: nxffs_reformat
+ *
+ * Description:
+ * Erase and reformat the entire volume. Verify each block and mark
+ * improperly erased blocks as bad.
+ *
+ * Input Parameters:
+ * volume - Describes the NXFFS volume to be reformatted.
+ *
+ * Returned Value:
+ * Zero on success or a negated errno on a failure. Failures will be
+ * returned n the case of MTD reported failures o.
+ * Nothing in the volume data itself will generate errors.
+ *
+ * Defined in nxffs_reformat.c
+ *
+ ****************************************************************************/
+
+extern int nxffs_reformat(FAR struct nxffs_volume_s *volume);
+
+/****************************************************************************
+ * Standard mountpoint operation methods
+ *
+ * Description:
+ * See include/nuttx/fs.h
+ *
+ * - nxffs_open() and nxffs_close() are defined in nxffs_open.c
+ * - nxffs_ioctl() is defined in nxffs_ioctl.c
+ * - nxffs_opendir(), nxffs_readdir(), and nxffs_rewindir() are defined in
+ * nxffs_dir.c
+ * - nxffs_stat() and nxffs_statfs() are defined in nxffs_stat.c
+ * - nxffs_unlink() is defined nxffs_unlink.c
+ *
+ ****************************************************************************/
+
+struct file; /* Forward references */
+struct inode;
+struct fs_dirent_s;
+struct statfs;
+struct stat;
+
+extern int nxffs_open(FAR struct file *filep, FAR const char *relpath,
+ int oflags, mode_t mode);
+extern int nxffs_close(FAR struct file *filep);
+extern ssize_t nxffs_read(FAR struct file *filep, FAR char *buffer,
+ size_t buflen);
+extern ssize_t nxffs_write(FAR struct file *filep, FAR const char *buffer,
+ size_t buflen);
+extern int nxffs_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
+extern int nxffs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
+ FAR struct fs_dirent_s *dir);
+extern int nxffs_readdir(FAR struct inode *mountpt, FAR struct fs_dirent_s *dir);
+extern int nxffs_rewinddir(FAR struct inode *mountpt, FAR struct fs_dirent_s *dir);
+extern int nxffs_bind(FAR struct inode *blkdriver, FAR const void *data,
+ FAR void **handle);
+extern int nxffs_unbind(FAR void *handle, FAR struct inode **blkdriver);
+extern int nxffs_statfs(FAR struct inode *mountpt, FAR struct statfs *buf);
+extern int nxffs_stat(FAR struct inode *mountpt, FAR const char *relpath,
+ FAR struct stat *buf);
+extern int nxffs_unlink(FAR struct inode *mountpt, FAR const char *relpath);
+
+#endif /* __FS_NXFFS_NXFFS_H */
+
+
diff --git a/nuttx/fs/nxffs/nxffs_block.c b/nuttx/fs/nxffs/nxffs_block.c
new file mode 100644
index 000000000..fd49df8f2
--- /dev/null
+++ b/nuttx/fs/nxffs/nxffs_block.c
@@ -0,0 +1,166 @@
+/****************************************************************************
+ * fs/nxffs/nxffs_block.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * References: Linux/Documentation/filesystems/romfs.txt
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/mtd.h>
+
+#include "nxffs.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxffs_verifyblock
+ *
+ * Description:
+ * Assure the the provided (logical) block number is in the block cache
+ * and that it has a valid block header (i.e., proper magic and
+ * marked good)
+ *
+ * Input Parameters:
+ * volume - Describes the NXFFS volume
+ * block - The (logical) block number to load and verify.
+ *
+ * Returned Values:
+ * Zero is returned on success. Otherwise, a negated errno value is
+ * returned indicating the nature of the failure. -ENOENT is returned
+ * if the block is a bad block.
+ *
+ ****************************************************************************/
+
+int nxffs_verifyblock(FAR struct nxffs_volume_s *volume, off_t block)
+{
+ FAR struct nxffs_block_s *blkhdr;
+ int ret;
+
+ /* Make sure the the block is in the cache */
+
+ ret = nxffs_rdcache(volume, block, 1);
+ if (ret < 0)
+ {
+ fdbg("Failed to read data into cache: %d\n", ret);
+ return ret;
+ }
+
+ /* Check if the block has a magic number (meaning that it is not
+ * erased) and that it is valid (meaning that it is not marked
+ * for cleanup)
+ */
+
+ blkhdr = (FAR struct nxffs_block_s *)volume->cache;
+ if (memcmp(blkhdr->magic, g_blockmagic, 4) == 0 &&
+ blkhdr->state == BLOCK_STATE_GOOD)
+ {
+ /* The block is valid */
+
+ return OK;
+ }
+
+ return -ENOENT;
+}
+
+/****************************************************************************
+ * Name: nxffs_validblock
+ *
+ * Description:
+ * Find the next valid (logical) block in the volume.
+ *
+ * Input Parameters:
+ * volume - Describes the NXFFS volume
+ * block - On entry, this provides the starting block number. If the
+ * function is succesfful, then this memory location will hold the
+ * block number of the next valid block on return.
+ *
+ * Returned Value:
+ * Zero on success otherwise a negated errno value indicating the nature
+ * of the failure.
+ *
+ ****************************************************************************/
+
+int nxffs_validblock(struct nxffs_volume_s *volume, off_t *block)
+{
+ off_t i;
+ int ret;
+
+ DEBUGASSERT(volume && block);
+
+ /* Loop for each possible block or until a valid block is found */
+
+ for (i = *block; i < volume->geo.neraseblocks * volume->blkper; i++)
+ {
+ /* Loop until we find a valid block */
+
+ ret = nxffs_verifyblock(volume, i);
+ if (ret == OK)
+ {
+ /* We found it, return the block number */
+
+ *block = i;
+ return OK;
+ }
+ }
+
+ fdbg("No valid block found\n");
+ return -ENOENT;
+}
diff --git a/nuttx/fs/nxffs/nxffs_blockstats.c b/nuttx/fs/nxffs/nxffs_blockstats.c
new file mode 100644
index 000000000..8ad6f0978
--- /dev/null
+++ b/nuttx/fs/nxffs/nxffs_blockstats.c
@@ -0,0 +1,153 @@
+/****************************************************************************
+ * fs/nxffs/nxffs_blockstats.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * References: Linux/Documentation/filesystems/romfs.txt
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <string.h>
+#include <debug.h>
+
+#include <nuttx/mtd.h>
+
+#include "nxffs.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxffs_blockstats
+ *
+ * Description:
+ * Analyze the NXFFS volume. This operation must be performed when the
+ * volume is first mounted in order to detect if the volume has been
+ * formatted and contains a usable NXFFS file system.
+ *
+ * Input Parameters:
+ * volume - Describes the current NXFFS volume.
+ * stats - On return, will hold nformation describing the state of the
+ * volume.
+ *
+ * Returned Value:
+ * Negated errnos are returned only in the case of MTD reported failures.
+ * Nothing in the volume data itself will generate errors.
+ *
+ ****************************************************************************/
+
+int nxffs_blockstats(FAR struct nxffs_volume_s *volume,
+ FAR struct nxffs_blkstats_s *stats)
+{
+ FAR uint8_t *bptr; /* Pointer to next block data */
+ off_t eblock; /* Erase block number */
+ int lblock; /* Logical block index */
+ int ret;
+
+ /* Process each erase block */
+
+ memset(stats, 0, sizeof(struct nxffs_blkstats_s));
+
+ for (eblock = 0; eblock < volume->geo.neraseblocks; eblock++)
+ {
+ /* Read the full erase block */
+
+ volume->ioblock = eblock * volume->blkper;
+ volume->iooffset = 0;
+ ret = nxffs_rdcache(volume, volume->ioblock, volume->blkper);
+ if (ret < 0)
+ {
+ fdbg("Failed to read erase block %d: %d\n", eblock, -ret);
+ return ret;
+ }
+
+ /* Process each logical block */
+
+ for (bptr = volume->cache, lblock = 0;
+ lblock < volume->blkper;
+ bptr += SIZEOF_NXFFS_BLOCK_HDR, lblock++)
+ {
+ FAR struct nxffs_block_s *blkhdr = (FAR struct nxffs_block_s*)bptr;
+
+ /* Collect statistics */
+
+ stats->nblocks++;
+ if (memcmp(blkhdr->magic, g_blockmagic, NXFFS_MAGICSIZE) != 0)
+ {
+ stats->nunformat++;
+ }
+ else if (blkhdr->state == BLOCK_STATE_BAD)
+ {
+ stats->nbad++;
+ }
+ else if (blkhdr->state == BLOCK_STATE_GOOD)
+ {
+ stats-> ngood++;
+ }
+ else
+ {
+ stats->ncorrupt++;
+ }
+ }
+ }
+
+ fdbg("Number blocks: %d\n", stats->nblocks);
+ fdbg(" Good blocks: %d\n", stats->ngood);
+ fdbg(" Bad blocks: %d\n", stats->nbad);
+ fdbg(" Unformatted blocks: %d\n", stats->nunformat);
+ fdbg(" Corrupt blocks: %d\n", stats->ncorrupt);
+ return OK;
+}
+
+
diff --git a/nuttx/fs/nxffs/nxffs_cache.c b/nuttx/fs/nxffs/nxffs_cache.c
new file mode 100644
index 000000000..0e7cff256
--- /dev/null
+++ b/nuttx/fs/nxffs/nxffs_cache.c
@@ -0,0 +1,243 @@
+/****************************************************************************
+ * fs/nxffs/nxffs_cache.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * References: Linux/Documentation/filesystems/romfs.txt
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/mtd.h>
+
+#include "nxffs.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxffs_rdcache
+ *
+ * Description:
+ * Read one or more logical blocks into the volume block cache memory.
+ *
+ * Input Parameters:
+ * volume - Describes the current volume
+ * block - The first logical block to read
+ * nblocks - The number of logical blocks to be read.
+ *
+ * Returned Value:
+ * Negated errnos are returned only in the case of MTD reported failures.
+ * Nothing in the volume data itself will generate errors.
+ *
+ ****************************************************************************/
+
+int nxffs_rdcache(FAR struct nxffs_volume_s *volume, off_t block,
+ uint8_t nblocks)
+{
+ size_t nxfrd;
+
+ DEBUGASSERT(nblocks <= volume->blkper);
+
+ /* Check if the requested data is already in the cache */
+
+ if (block != volume->cblock || nblocks <= volume->ncached)
+ {
+ /* Read the specified blocks into cache */
+
+ nxfrd = MTD_BREAD(volume->mtd, block, nblocks, volume->cache);
+ if (nxfrd != nblocks)
+ {
+ fdbg("Read block %d-%d failed: %d\n",
+ block, block + nblocks -1, nxfrd);
+ return -EIO;
+ }
+
+ /* Remember what is in the cache */
+
+ volume->cblock = block;
+ volume->ncached = nblocks;
+ }
+ return OK;
+}
+
+/****************************************************************************
+ * Name: nxffs_ioseek
+ *
+ * Description:
+ * Seek to a position in FLASH memory. This simply sets up the offsets
+ * and pointer values. This is a necessary step prior to using
+ * nxffs_getc().
+ *
+ * Input Parameters:
+ * volume - Describes the NXFFS volume
+ * offset - The physical offset in bytes from the beginning of the FLASH
+ * in bytes.
+ *
+ ****************************************************************************/
+
+void nxffs_ioseek(FAR struct nxffs_volume_s *volume, off_t offset)
+{
+ /* Convert the offset into a block number and a byte offset into the
+ * block.
+ */
+
+ volume->ioblock = offset / volume->geo.blocksize;
+ volume->iooffset = offset - volume->geo.blocksize * volume->ioblock;
+}
+
+/****************************************************************************
+ * Name: nxffs_getc
+ *
+ * Description:
+ * Get the next byte from FLASH. This function allows the data in the
+ * formatted FLASH blocks to be read as a continuous byte stream, skipping
+ * over bad blocks and block headers as necessary.
+ *
+ * Input Parameters:
+ * volume - Describes the NXFFS volume. The paramters ioblock and iooffset
+ * in the volume structure determine the behavior of nxffs_getc().
+ *
+ * Returned Value:
+ * Zero is returned on success. Otherwise, a negated errno indicating the
+ * nature of the failure.
+ *
+ ****************************************************************************/
+
+int nxffs_getc(FAR struct nxffs_volume_s *volume)
+{
+ int ret;
+
+ /* Loop to skip over bad blocks */
+
+ do
+ {
+ /* Check if we have read past the current block */
+
+ if (volume->iooffset >= volume->geo.blocksize)
+ {
+ volume->ioblock++;
+ volume->iooffset = SIZEOF_NXFFS_BLOCK_HDR;
+ }
+
+ /* Make sure that the block is in the cache. The special error
+ * -ENOENT indicates the block was read successfully but was not
+ * marked as a good block. In this case we need to skip to the
+ * next block. All other errors are fatal.
+ */
+
+ ret = nxffs_verifyblock(volume, volume->ioblock);
+ if (ret < 0 && ret != -ENOENT)
+ {
+ fdbg("Failed to read valid data into cache: %d\n", ret);
+ return ret;
+ }
+ }
+ while (ret == -ENOENT);
+
+ /* Return the the character at this offset. Note that on return,
+ * iooffset could point to the byte outside of the current block.
+ */
+
+ ret = (int)volume->cache[volume->iooffset];
+ volume->iooffset++;
+ return ret;
+}
+
+/****************************************************************************
+ * Name: nxffs_rddata
+ *
+ * Description:
+ * Read a sequence of data bytes from the FLASH memory. This function
+ * allows the data in the formatted FLASH blocks to be read as a continuous\
+ * byte stream, skipping over bad blocks and block headers as necessary.
+ *
+ * Input Parameters:
+ * volume - Describes the NXFFS volume. The paramters ioblock and iooffset
+ * in the volume structure determine the behavior of nxffs_getc().
+ *
+ * Returned Value:
+ * The number of bytes read is returned on success. Otherwise, a negated
+ * errno indicating the nature of the failure.
+ *
+ ****************************************************************************/
+
+ssize_t nxffs_rddata(FAR struct nxffs_volume_s *volume,
+ FAR uint8_t *buffer, size_t buflen)
+{
+ size_t nbytes;
+ int ch;
+
+ for (nbytes = buflen; nbytes > 0; nbytes--)
+ {
+ /* Read the next character (which could be in the next block) */
+
+ ch = nxffs_getc(volume);
+ if (ch < 0)
+ {
+ fdbg("Failed to read byte: %d\n", -ch);
+ return ch;
+ }
+
+ /* Add the next character to the user buffer */
+
+ *buffer++ = (uint8_t)ch;
+ }
+
+ return buflen;
+}
+
diff --git a/nuttx/fs/nxffs/nxffs_initialize.c b/nuttx/fs/nxffs/nxffs_initialize.c
new file mode 100644
index 000000000..f473d55c5
--- /dev/null
+++ b/nuttx/fs/nxffs/nxffs_initialize.c
@@ -0,0 +1,272 @@
+/****************************************************************************
+ * fs/nxffs/nxffs_initialize.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * References: Linux/Documentation/filesystems/romfs.txt
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <errno.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/mtd.h>
+#include <nuttx/fs.h>
+#include <nuttx/ioctl.h>
+
+#include "nxffs.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Variables
+ ****************************************************************************/
+
+/* See fs_mount.c -- this structure is explicitly externed there.
+ * We use the old-fashioned kind of initializers so that this will compile
+ * with any compiler.
+ */
+
+const struct mountpt_operations nxffs_operations =
+{
+ nxffs_open, /* open */
+ nxffs_close, /* close */
+ nxffs_read, /* read */
+ nxffs_write, /* write */
+ NULL, /* seek -- Use f_pos in struct file */
+ nxffs_ioctl, /* ioctl */
+ NULL, /* sync -- No buffered data */
+
+ nxffs_opendir, /* opendir */
+ NULL, /* closedir */
+ nxffs_readdir, /* readdir */
+ nxffs_rewinddir, /* rewinddir */
+
+ nxffs_bind, /* bind */
+ nxffs_unbind, /* unbind */
+ nxffs_statfs, /* statfs */
+
+ nxffs_unlink, /* unlink */
+ NULL, /* mkdir -- no directories */
+ NULL, /* rmdir -- no directories */
+ NULL, /* rename -- cannot rename in place if name is longer */
+ nxffs_stat /* stat */
+};
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/* A singly-linked list of open files */
+
+struct nxffs_ofile_s *g_ofiles;
+
+/* The magic number that appears that the beginning of each NXFFS (logical)
+ * block
+ */
+
+const uint8_t g_blockmagic[NXFFS_MAGICSIZE] = { 'B', 'l', 'c', 'k' };
+
+/* The magic number that appears that the beginning of each NXFFS inode */
+
+const uint8_t g_inodemagic[NXFFS_MAGICSIZE] = { 'I', 'n', 'o', 'd' };
+
+/* The magic number that appears that the beginning of each NXFFS inode
+ * data block.
+ */
+
+const uint8_t g_datamagic[NXFFS_MAGICSIZE] = { 'D', 'a', 't', 'a' };
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxffs_initialize
+ *
+ * Description:
+ * Initialize to provide NXFFS on an MTD interface
+ *
+ * Input Parameters:
+ * mtd - The MTD device that supports the FLASH interface.
+ * start - The first block of the file system begins at this block number
+ * in the FLASH
+ * nblocks - This number of blocks is set aside for the file system.
+ *
+ ****************************************************************************/
+
+int nxffs_initialize(FAR struct mtd_dev_s *mtd, off_t start, off_t nblocks)
+{
+ FAR struct nxffs_volume_s *volume;
+ struct nxffs_blkstats_s stats;
+ off_t threshold;
+ int ret;
+
+ /* Allocate a NXFFS volume structure */
+
+ volume = (FAR struct nxffs_volume_s *)kzalloc(sizeof(struct nxffs_volume_s));
+ if (!volume)
+ {
+ ret = -ENOMEM;
+ goto errout;
+ }
+
+ /* Initialize the NXFFS volume structure */
+
+ volume->mtd = mtd;
+
+ /* Get the volume geometry. (casting to uintptr_t first eliminates
+ * complaints on some architectures where the sizeof long is different
+ * from the size of a pointer).
+ */
+
+ ret = MTD_IOCTL(mtd, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&volume->geo));
+ if (ret < 0)
+ {
+ fdbg("MTD ioctl(MTDIOC_GEOMETRY) failed: %d\n", -ret);
+ goto errout_with_volume;
+ }
+
+ /* Allocate one, in-memory erase block buffer */
+
+ volume->cache = (FAR uint8_t *)kmalloc(volume->geo.erasesize);
+ if (!volume->cache)
+ {
+ fdbg("Failed to allocate an erase block buffer\n");
+ ret = -ENOMEM;
+ goto errout_with_volume;
+ }
+
+ /* Get the number of R/W blocks per erase block */
+
+ volume->blkper = volume->geo.erasesize / volume->geo.blocksize;
+ DEBUGASSERT((off_t)volume->blkper * volume->geo.blocksize == volume->geo.erasesize);
+
+ /* Check if there is a valid NXFFS file system on the flash */
+
+ ret = nxffs_blockstats(volume, &stats);
+ if (ret < 0)
+ {
+ fdbg("Failed to collect block statistics: %d\n", -ret);
+ goto errout_with_iobuffer;
+ }
+
+ /* If the proportion of good blocks is low or the proportion of unformatted
+ * blocks is high, then reformat the FLASH.
+ */
+
+ threshold = stats.nblocks / 5;
+ if (stats.ngood < threshold || stats.nunformat > threshold)
+ {
+ /* Reformat the volume */
+
+ ret = nxffs_reformat(volume);
+ if (ret < 0)
+ {
+ fdbg("Failed to reformat the volume: %d\n", -ret);
+ goto errout_with_iobuffer;
+ }
+
+ /* Get statistics on the re-formatted volume */
+
+#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_FS)
+ ret = nxffs_blockstats(volume, &stats);
+ if (ret < 0)
+ {
+ fdbg("Failed to collect block statistics: %d\n", -ret);
+ goto errout_with_iobuffer;
+ }
+#endif
+ }
+
+ /* Return success */
+
+ return OK;
+
+errout_with_iobuffer:
+ kfree(volume->cache);
+errout_with_volume:
+ kfree(volume);
+errout:
+ return ret;
+}
+
+/****************************************************************************
+ * Name: nxffs_limits
+ *
+ * Description:
+ * Recalculate file system limits: (1) the FLASH offset to the first,
+ * valid inode, and (2) the FLASH offset to the first, unused byte after
+ * the last inode (invalid or not).
+ *
+ * The first, lower limit must be recalculated: (1) initially, (2)
+ * whenever the first inode is deleted, or (3) whenever inode is moved
+ * as part of the clean-up operation.
+ *
+ * The second, upper limit must be (1) incremented whenever new file
+ * data is written, or (2) recalculated as part of the clean-up operation.
+ *
+ * Input Parameters:
+ * volume - Identifies the NXFFS volume
+ *
+ * Returned Value:
+ * Zero on success. Otherwise, a negated error is returned indicating the
+ * nature of the failure.
+ *
+ ****************************************************************************/
+
+int nxffs_limits(FAR struct nxffs_volume_s *volume)
+{
+#warning "Missing Logic"
+}
+
diff --git a/nuttx/fs/nxffs/nxffs_inode.c b/nuttx/fs/nxffs/nxffs_inode.c
new file mode 100644
index 000000000..a0b2fc0ef
--- /dev/null
+++ b/nuttx/fs/nxffs/nxffs_inode.c
@@ -0,0 +1,380 @@
+/****************************************************************************
+ * fs/nxffs/nxffs_inode.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * References: Linux/Documentation/filesystems/romfs.txt
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/mtd.h>
+
+#include "nxffs.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxffs_rdentry
+ *
+ * Description:
+ * Read the inode entry at this offset. Called only from nxffs_nextentry().
+ *
+ * Input Parameters:
+ * volume - Describes the current volume.
+ * offset - The byte offset from the beginning of FLASH where the inode
+ * header is expected.
+ * entry - A memory location to return the expanded inode header
+ * information.
+ *
+ * Returned Value:
+ * Zero on success. Otherwise, a negater errno value is returned
+ * indicating the nature of the failure.
+ *
+ ****************************************************************************/
+
+static int nxffs_rdentry(FAR struct nxffs_volume_s *volume, off_t offset,
+ FAR struct nxffs_entry_s *entry)
+{
+ struct nxffs_inode_s inode;
+ uint32_t ecrc;
+ uint32_t crc;
+ int namelen;
+ int ret;
+
+ DEBUGASSERT(volume && entry);
+ memset(entry, 0, sizeof(struct nxffs_entry_s));
+
+ /* Read the header at the FLASH offset */
+
+ nxffs_ioseek(volume, offset);
+ ret = nxffs_rddata(volume, (FAR uint8_t *)&inode, SIZEOF_NXFFS_INODE_HDR);
+ if (ret < 0)
+ {
+ fdbg("Failed to read inode, offset %d: %d\n", offset, -ret);
+ return -EIO;
+ }
+
+ /* Check if the file is marked as deleted. */
+
+ if (inode.state != INODE_STATE_FILE)
+ {
+ return -ENOENT;
+ }
+
+ /* Copy the packed header into the user-friendly buffer */
+
+ entry->hoffset = offset;
+ entry->doffset = offset + inode.doffset;
+ entry->utc = nxffs_rdle32(inode.utc);
+ entry->datlen = nxffs_rdle32(inode.datlen);
+
+ /* Modify the packed header and perform the (partial) CRC calculation */
+
+ ecrc = nxffs_rdle32(inode.crc);
+ inode.state = CONFIG_NXFFS_ERASEDSTATE;
+ memset(inode.crc, 0, 4);
+ crc = crc32((FAR const uint8_t *)&inode, SIZEOF_NXFFS_INODE_HDR);
+
+ /* Allocate memory to hold the variable-length file name */
+
+ namelen = (int)inode.doffset - (int)inode.noffset;
+ if (namelen < 0)
+ {
+ fdbg("Bad offsets, name: %d data: %d\n", inode.noffset, inode.doffset);
+ return -EIO;
+ }
+
+ entry->name = (FAR char *)kmalloc(namelen+1);
+ if (!entry->name)
+ {
+ fdbg("Failed to allocate name, namelen: %d\n", namelen);
+ return -ENOMEM;
+ }
+
+ /* Read the file name from the expected offset in FLASH */
+
+ nxffs_ioseek(volume, offset + inode.noffset);
+ ret = nxffs_rddata(volume, (FAR uint8_t*)entry->name, namelen);
+ if (ret < 0)
+ {
+ fdbg("Failed to read inode, offset %d: %d\n", offset, -ret);
+ return -EIO;
+ }
+ entry->name[namelen] = '\0';
+
+ /* Finish the CRC calculation and verify the entry */
+
+ crc = crc32part(entry->name, namelen, crc);
+ if (crc != ecrc)
+ {
+ fdbg("CRC entry: %08x CRC calculated: %08x\n", ecrc, crc);
+ nxffs_freeentry(entry);
+ return -EIO;
+ }
+ return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxffs_freeentry
+ *
+ * Description:
+ * The inode values returned by nxffs_nextentry() include allocated memory
+ * (specifically, the file name string). This function should be called
+ * to dispose of that memory when the inode entry is no longer needed.
+ *
+ * Note that the nxffs_entry_s containing structure is not freed. The
+ * caller may call kfree upon return of this function if necessary to
+ * free the entry container.
+ *
+ * Input parameters:
+ * entry - The entry to be freed.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void nxffs_freeentry(FAR struct nxffs_entry_s *entry)
+{
+ if (entry->name)
+ {
+ kfree(entry->name);
+ entry->name = NULL;
+ }
+}
+
+/****************************************************************************
+ * Name: nxffs_nextentry
+ *
+ * Description:
+ * Search for the next valid inode starting at the provided FLASH offset.
+ *
+ * Input Parameters:
+ * volume - Describes the NXFFS volume.
+ * offset - The FLASH memory offset to begin searching.
+ * entry - A pointer to memory provided by the caller in which to return
+ * the inode description.
+ *
+ * Returned Value:
+ * Zero is returned on success. Otherwise, a negated errno is returned
+ * that indicates the nature of the failure.
+ *
+ ****************************************************************************/
+
+int nxffs_nextentry(FAR struct nxffs_volume_s *volume, off_t offset,
+ FAR struct nxffs_entry_s *entry)
+{
+ int nmagic;
+ int ch;
+ int nerased;
+ int ret;
+
+ /* Seek to the first FLASH offset provided by the caller. */
+
+ nxffs_ioseek(volume, offset);
+
+ /* Then begin searching */
+
+ nerased = 0;
+ nmagic = 0;
+ for (;;)
+ {
+ /* Read the next character */
+
+ ch = nxffs_getc(volume);
+ if (ch < 0)
+ {
+ fvdbg("nxffs_getc failed: %d\n", -ch);
+ return ch;
+ }
+
+ /* Check for another erased byte */
+
+ else if (ch == CONFIG_NXFFS_ERASEDSTATE)
+ {
+ /* If we have encountered NXFFS_NERASED number of consecutive
+ * erased bytes, then presume we have reached the end of valid
+ * data.
+ */
+
+ if (++nerased >= NXFFS_NERASED)
+ {
+ fvdbg("No entry found\n");
+ return -ENOENT;
+ }
+ }
+ else
+ {
+ nerased = 0;
+
+ /* Check for the magic sequence indicating the start of an NXFFS
+ * inode. There is the possibility of this magic sequnce occurring
+ * in FLASH data. However, the header CRC should distinguish
+ * between real NXFFS inode headers and such false alarms.
+ */
+
+ if (ch != g_inodemagic[nmagic])
+ {
+ nmagic = 0;
+ }
+ else if (nmagic < NXFFS_MAGICSIZE - 1)
+ {
+ nmagic++;
+ }
+
+ /* We have found the magic sequence in the FLASH data that may
+ * indicate the beginning of an NXFFS inode.
+ */
+
+ else
+ {
+ ret = nxffs_rdentry(volume, offset, entry);
+ if (ret == OK)
+ {
+ fdbg("Found a valid fileheader\n");
+ return OK;
+ }
+
+ /* False alarm.. keep looking */
+
+ nmagic = 0;
+ }
+ }
+ }
+
+ /* We won't get here, but to keep some compilers happy: */
+
+ return -ENOENT;
+}
+
+/****************************************************************************
+ * Name: nxffs_findinode
+ *
+ * Description:
+ * Search for an inode with the provided name starting with the first
+ * valid inode and proceeding to the end FLASH or until the matching
+ * inode is found.
+ *
+ * Input Parameters:
+ * volume - Describes the NXFFS volume
+ * name - The name of the inode to find
+ * entry - The location to return information about the inode.
+ *
+ * Returned Value:
+ * Zero is returned on success. Otherwise, a negated errno is returned
+ * that indicates the nature of the failure.
+ *
+ ****************************************************************************/
+
+int nxffs_findinode(FAR struct nxffs_volume_s *volume, FAR const char *name,
+ struct nxffs_entry_s *entry)
+{
+ off_t offset;
+ int ret;
+
+ /* Start with the first valid inode that was discovered when the volume
+ * was created (or modified after the last cleanup).
+ */
+
+ offset = volume->inoffset;
+
+ /* Loop, checking each NXFFS inode until either: (1) we find the NXFFS inode
+ * with the matching name, or (2) we reach the end of data written on the
+ * media.
+ */
+
+ for (;;)
+ {
+ /* Get the next, valid NXFFS inode entry */
+
+ ret = nxffs_nextentry(volume, offset, entry);
+ if (ret < 0)
+ {
+ fdbg("No inode found: %d\n", -ret);
+ return ret;
+ }
+
+ /* Is this the NXFFS inode we are looking for? */
+
+ else if (strcmp(name, entry->name) == 0)
+ {
+ /* Yes, return success with the entry data in 'enty' */
+
+ return OK;
+ }
+
+ /* Discard this entry and try the next one. Here we set the
+ * next offset using the raw data length as the offset
+ * increment. This is, of course, not accurate because it
+ * does not account for the data headers that inclose the
+ * data. But it is guaranteed to be less than or equal to
+ * the correct offset and, hence, better then seraching
+ * byte-for-byte.
+ */
+
+ offset = entry->doffset + entry->datlen;
+ nxffs_freeentry(entry);
+ }
+
+ /* We won't get here, but for some compilers: */
+
+ return -ENOENT;
+}
diff --git a/nuttx/fs/nxffs/nxffs_reformat.c b/nuttx/fs/nxffs/nxffs_reformat.c
new file mode 100644
index 000000000..8f34a9373
--- /dev/null
+++ b/nuttx/fs/nxffs/nxffs_reformat.c
@@ -0,0 +1,281 @@
+/****************************************************************************
+ * fs/nxffs/nxffs_reformat.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * References: Linux/Documentation/filesystems/romfs.txt
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/mtd.h>
+
+#include "nxffs.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxffs_format
+ *
+ * Description:
+ * Erase and reformat the entire volume.
+ *
+ * Input Parameters:
+ * volume - Describes the NXFFS volume to be reformatted.
+ *
+ * Returned Value:
+ * Zero on success or a negated errno on a failure. Failures will be
+ * returned n the case of MTD reported failures o.
+ * Nothing in the volume data itself will generate errors.
+ *
+ ****************************************************************************/
+
+static int nxffs_format(FAR struct nxffs_volume_s *volume)
+{
+ FAR uint8_t *blkptr; /* Pointer to next block data */
+ off_t eblock; /* Erase block number */
+ off_t lblock; /* Logical block number */
+ ssize_t nxfrd; /* Number of blocks transferred */
+ int i;
+ int ret;
+
+ /* Create an image of one properly formatted erase sector */
+
+ memset(volume->cache, CONFIG_NXFFS_ERASEDSTATE, volume->geo.erasesize);
+ for (blkptr = volume->cache, i = 0;
+ i < volume->blkper;
+ blkptr += SIZEOF_NXFFS_BLOCK_HDR, i++)
+ {
+ FAR struct nxffs_block_s *blkhdr = (FAR struct nxffs_block_s*)blkptr;
+ memcpy(blkhdr->magic, g_blockmagic, NXFFS_MAGICSIZE);
+ blkhdr->state = BLOCK_STATE_GOOD;
+ }
+
+ /* Erase and format each erase block */
+
+ for (eblock = 0; eblock < volume->geo.neraseblocks; eblock++)
+ {
+ /* Erase the block */
+
+ ret = MTD_ERASE(volume->mtd, eblock, 1);
+ if (ret < 0)
+ {
+ fdbg("Erase block %d failed: %d\n", eblock, ret);
+ return ret;
+ }
+
+ /* Write the formatted image to the erase block */
+
+ lblock = eblock * volume->blkper;
+ nxfrd = MTD_BWRITE(volume->mtd, lblock, volume->blkper, volume->cache);
+ if (nxfrd != volume->blkper)
+ {
+ fdbg("Write erase block %d failed: %d\n", alignedblock, nxfrd);
+ return -EIO;
+ }
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: nxffs_badblocks
+ *
+ * Description:
+ * Verify each block and mark improperly erased blocks as bad.
+ *
+ * Input Parameters:
+ * volume - Describes the NXFFS volume to be reformatted.
+ *
+ * Returned Value:
+ * Zero on success or a negated errno on a failure. Failures will be
+ * returned n the case of MTD reported failures o.
+ * Nothing in the volume data itself will generate errors.
+ *
+ ****************************************************************************/
+
+static int nxffs_badblocks(FAR struct nxffs_volume_s *volume)
+{
+ FAR uint8_t *blkptr; /* Pointer to next block data */
+ FAR uint8_t *datptr; /* Pointer to next data byte */
+ off_t eblock; /* Erase block number */
+ off_t lblock; /* Logical block number */
+ ssize_t nxfrd; /* Number of blocks transferred */
+ uint16_t blkndx; /* Logical block data index */
+ bool bad; /* TRUE: block is bad */
+ bool modified; /* TRUE: The erase block has been modified */
+ int i;
+
+ /* Read and verify each erase block */
+
+ for (eblock = 0; eblock < volume->geo.neraseblocks; eblock++)
+ {
+ /* Read the entire erase block */
+
+ lblock = eblock * volume->blkper;
+ nxfrd = MTD_BREAD(volume->mtd, lblock, volume->blkper, volume->cache);
+ if (nxfrd != volume->blkper)
+ {
+ fdbg("Read erase block %d failed: %d\n", lblock, nxfrd);
+ return -EIO;
+ }
+
+ /* Process each logical block */
+
+ modified = false;
+ for (blkptr = volume->cache, i = 0;
+ i < volume->blkper;
+ blkptr += SIZEOF_NXFFS_BLOCK_HDR, i++)
+ {
+ FAR struct nxffs_block_s *blkhdr = (FAR struct nxffs_block_s*)blkptr;
+
+ /* Check block header */
+
+ bad = false;
+ if (memcmp(blkhdr->magic, g_blockmagic, NXFFS_MAGICSIZE) != 0 ||
+ blkhdr->state == BLOCK_STATE_GOOD)
+ {
+ bad = true;;
+ }
+
+ /* Check that block data is erased */
+
+ else
+ {
+ /* Check every byte in the block payload */
+
+ for (blkndx = SIZEOF_NXFFS_BLOCK_HDR, datptr = &blkptr[blkndx];
+ blkndx < volume->geo.blocksize;
+ blkndx++)
+ {
+ /* If the data byte is not in the erased state, then the block is bad */
+
+ uint8_t byte = *datptr++;
+ if (byte != CONFIG_NXFFS_ERASEDSTATE)
+ {
+ bad = true;
+ break;
+ }
+ }
+ }
+
+ /* If the block is bad, attempt to re-write the block header indicating
+ * a bad block (of course, if the block has failed, this may not be
+ * possible, depending upon failure modes.
+ */
+
+ if (bad)
+ {
+ memcpy(blkhdr->magic, g_blockmagic, NXFFS_MAGICSIZE);
+ blkhdr->state = BLOCK_STATE_BAD;
+ modified = true;
+ }
+ }
+
+ /* If the erase block was modified, then re-write it */
+
+ nxfrd = MTD_BWRITE(volume->mtd, lblock, volume->blkper, volume->cache);
+ if (nxfrd != volume->blkper)
+ {
+ fdbg("Write erase block %d failed: %d\n", alignedblock, nxfrd);
+ return -EIO;
+ }
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxffs_reformat
+ *
+ * Description:
+ * Erase and reformat the entire volume. Verify each block and mark
+ * improperly erased blocks as bad.
+ *
+ * Input Parameters:
+ * volume - Describes the NXFFS volume to be reformatted.
+ *
+ * Returned Value:
+ * Zero on success or a negated errno on a failure. Failures will be
+ * returned n the case of MTD reported failures o.
+ * Nothing in the volume data itself will generate errors.
+ *
+ ****************************************************************************/
+
+int nxffs_reformat(FAR struct nxffs_volume_s *volume)
+{
+ int ret;
+
+ /* Erase and reformat the entire volume */
+
+ ret = nxffs_format(volume);
+ if (ret < 0)
+ {
+ fdbg("Failed to reformat the volume: %d\n", -ret);
+ return ret;
+ }
+
+ /* Check for bad blocks */
+
+ ret = nxffs_badblocks(volume);
+ if (ret < 0)
+ {
+ fdbg("Bad block check failed: %d\n", -ret);
+ }
+ return ret;
+}
diff --git a/nuttx/fs/nxffs/nxffs_util.c b/nuttx/fs/nxffs/nxffs_util.c
new file mode 100644
index 000000000..9eea32243
--- /dev/null
+++ b/nuttx/fs/nxffs/nxffs_util.c
@@ -0,0 +1,112 @@
+/****************************************************************************
+ * fs/nxffs/nxffs_util.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * References: Linux/Documentation/filesystems/romfs.txt
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/mtd.h>
+
+#include "nxffs.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Variables
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nxffs_rdle16
+ *
+ * Description:
+ * Get a (possibly unaligned) 16-bit little endian value.
+ *
+ * Input Parameters:
+ * val - A pointer to the first byte of the little endian value.
+ *
+ * Returned Values:
+ * A uint16_t representing the whole 16-bit integer value
+ *
+ ****************************************************************************/
+
+uint16_t nxffs_rdle16(const uint8_t *val)
+{
+ return (uint16_t)val[1] << 8 | (uint16_t)val[0];
+}
+
+/****************************************************************************
+ * Name: nxffs_rdle32
+ *
+ * Description:
+ * Get a (possibly unaligned) 32-bit little endian value.
+ *
+ * Input Parameters:
+ * val - A pointer to the first byte of the little endian value.
+ *
+ * Returned Values:
+ * A uint32_t representing the whole 32-bit integer value
+ *
+ ****************************************************************************/
+
+uint32_t nxffs_rdle32(const uint8_t *val)
+{
+ /* Little endian means LS halfword first in byte stream */
+
+ return (uint32_t)nxffs_rdle16(&val[2]) << 16 | (uint32_t)nxffs_rdle16(val);
+}
+
diff --git a/nuttx/fs/romfs/Make.defs b/nuttx/fs/romfs/Make.defs
index 172eb27b9..56b4c9862 100644
--- a/nuttx/fs/romfs/Make.defs
+++ b/nuttx/fs/romfs/Make.defs
@@ -1,7 +1,7 @@
############################################################################
# fs/romfs/Make.defs
#
-# Copyright (C) 2008 Gregory Nutt. All rights reserved.
+# Copyright (C) 2008, 2011 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <spudmonkey@racsa.co.cr>
#
# Redistribution and use in source and binary forms, with or without
@@ -34,6 +34,12 @@
############################################################################
ifeq ($(CONFIG_FS_ROMFS),y)
-ASRCS +=
-CSRCS += fs_romfs.c fs_romfsutil.c
+# Files required for ROMFS file system support
+
+ASRCS +=
+CSRCS += fs_romfs.c fs_romfsutil.c
+
+# Argument for dependency checking
+
+ROMFSDEPPATH = --dep-path romfs
endif