Add files to hook up yaffs direct to u-boot
authorCharles Manning <cdhmanning@gmail.com>
Tue, 3 Apr 2012 01:06:16 +0000 (13:06 +1200)
committerCharles Manning <cdhmanning@gmail.com>
Tue, 3 Apr 2012 01:06:16 +0000 (13:06 +1200)
Signed-off-by: Charles Manning <cdhmanning@gmail.com>
16 files changed:
direct/u-boot/common/cmd_yaffs2.c [new file with mode: 0644]
direct/u-boot/fs/yaffs2/Makefile [new file with mode: 0644]
direct/u-boot/fs/yaffs2/assert.h [new file with mode: 0644]
direct/u-boot/fs/yaffs2/copy-code.sh [new file with mode: 0755]
direct/u-boot/fs/yaffs2/stdio.h [new file with mode: 0644]
direct/u-boot/fs/yaffs2/stdlib.h [new file with mode: 0644]
direct/u-boot/fs/yaffs2/string.h [new file with mode: 0644]
direct/u-boot/fs/yaffs2/yaffs_mtdif.c [new file with mode: 0644]
direct/u-boot/fs/yaffs2/yaffs_mtdif.h [new file with mode: 0644]
direct/u-boot/fs/yaffs2/yaffs_mtdif2.c [new file with mode: 0644]
direct/u-boot/fs/yaffs2/yaffs_mtdif2.h [new file with mode: 0644]
direct/u-boot/fs/yaffs2/yaffscfg.c [new file with mode: 0644]
direct/yaffsfs.c
direct/yaffsfs.h
direct/yportenv.h
yaffs_guts.c

diff --git a/direct/u-boot/common/cmd_yaffs2.c b/direct/u-boot/common/cmd_yaffs2.c
new file mode 100644 (file)
index 0000000..fd9b4fa
--- /dev/null
@@ -0,0 +1,325 @@
+/* Yaffs commands.
+ * Modified by Charles Manning by adding ydevconfig command.
+ *
+ */
+
+#include <common.h>
+
+#include <config.h>
+#include <command.h>
+
+#ifdef  YAFFS2_DEBUG
+#define PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...) do { } while(0)
+#endif
+
+extern void cmd_yaffs_devconfig(char *mp, int flash_dev, int start_block, int end_block);
+extern void cmd_yaffs_mount(char *mp);
+extern void cmd_yaffs_umount(char *mp);
+extern void cmd_yaffs_read_file(char *fn);
+extern void cmd_yaffs_write_file(char *fn,char bval,int sizeOfFile);
+extern void cmd_yaffs_ls(const char *mountpt, int longlist);
+extern void cmd_yaffs_mwrite_file(char *fn, char *addr, int size);
+extern void cmd_yaffs_mread_file(char *fn, char *addr);
+extern void cmd_yaffs_mkdir(const char *dir);
+extern void cmd_yaffs_rmdir(const char *dir);
+extern void cmd_yaffs_rm(const char *path);
+extern void cmd_yaffs_mv(const char *oldPath, const char *newPath);
+
+extern int yaffs_dump_dev(const char *path);
+
+
+/* ydevconfig mount_pt mtd_dev_num start_block end_block */
+int do_ydevconfig (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+    char *mtpoint;
+    int mtd_dev;
+    int start_block;
+    int end_block;
+
+    if(argc != 5) {
+       printf("Bad arguments: ydevconfig mount_pt mtd_dev start_block end_block\n");
+       return -1;
+    }
+    
+    mtpoint = argv[1];
+    mtd_dev = simple_strtol(argv[2], NULL, 16);
+    start_block = simple_strtol(argv[3], NULL, 16);
+    end_block = simple_strtol(argv[4], NULL, 16);
+    
+    printf("Configure yaffs2 mount point %s on nand device %d from block %x to block %x\n",
+       mtpoint, mtd_dev, start_block, end_block);
+    
+    cmd_yaffs_devconfig(mtpoint, mtd_dev, start_block, end_block);
+
+    return(0);
+}
+
+int do_ymount (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+    char *mtpoint;
+    
+    if(argc != 2) {
+       printf("Bad arguments: ymount mount_pt\n");
+       return -1;
+    }
+    
+    mtpoint = argv[1];
+    printf("Mounting yaffs2 mount point %s\n",mtpoint);
+    
+    cmd_yaffs_mount(mtpoint);
+
+    return(0);
+}
+
+int do_yumount (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+    char *mtpoint;
+    
+    if(argc != 2) {
+       printf("Bad arguments: yumount mount_pt\n");
+       return -1;
+    }
+    
+    mtpoint = argv[1];
+    printf("Unmounting yaffs2 mount point %s\n",mtpoint);
+    cmd_yaffs_umount(mtpoint);
+
+    return(0);
+}
+
+int do_yls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+    char *dirname;
+    
+    if(argc < 2 || argc > 3 ||
+       (argc == 3 && strcmp(argv[1],"-l"))) {
+       printf("Bad arguments: yls [-l] dir\n");
+       return -1;
+    }
+    
+    dirname = argv[argc-1];
+
+    cmd_yaffs_ls(dirname, (argc>2)?1:0);
+
+    return(0);
+}
+
+int do_yrd (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+    char *filename;
+    
+    if(argc != 2) {
+       printf("Bad arguments: yrd file_name\n");
+       return -1;
+    }
+    
+    filename = argv[1];
+    
+    printf ("Reading file %s ", filename);
+
+    cmd_yaffs_read_file(filename);
+
+    printf ("done\n");
+    return(0);
+}
+
+int do_ywr (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+    char *filename;
+    ulong value;
+    ulong numValues;
+
+    if(argc != 4) {
+       printf("Bad arguments: ywr file_name value n_values\n");
+       return -1;
+    }
+    
+    filename = argv[1];
+    value = simple_strtoul(argv[2], NULL, 16);
+    numValues = simple_strtoul(argv[3], NULL, 16);
+
+    printf ("Writing value (%lx) %lx times to %s... ", value, numValues, filename);
+
+    cmd_yaffs_write_file(filename,value,numValues);
+
+    printf ("done\n");
+    return(0);
+}
+
+int do_yrdm (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+    char *filename;
+    ulong addr;
+
+    if(argc != 3) {
+       printf("Bad arguments: yrdm file_name addr\n");
+       return -1;
+    }
+
+    filename = argv[1];
+    addr = simple_strtoul(argv[2], NULL, 16);
+
+    cmd_yaffs_mread_file(filename, (char *)addr);
+
+    return(0);
+}
+
+int do_ywrm (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+    char *filename;
+    ulong addr;
+    ulong size;
+
+    if(argc != 4) {
+       printf("Bad arguments: ywrm file_name addr size\n");
+       return -1;
+    }
+    
+    filename = argv[1];
+    addr = simple_strtoul(argv[2], NULL, 16);
+    size = simple_strtoul(argv[3], NULL, 16);
+
+    cmd_yaffs_mwrite_file(filename, (char *)addr, size);
+
+    return(0);
+}
+
+int do_ymkdir (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+    char *dirname;
+
+    if(argc != 2) {
+       printf("Bad arguments: ymkdir dir_name\n");
+       return -1;
+    }
+
+    dirname = argv[1];
+    cmd_yaffs_mkdir(dirname);
+
+    return(0);
+}
+
+int do_yrmdir (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+    char *dirname;
+
+    if(argc != 2) {
+       printf("Bad arguments: yrmdir dir_name\n");
+       return -1;
+    }
+
+    dirname = argv[1];
+    cmd_yaffs_rmdir(dirname);
+
+    return(0);
+}
+
+int do_yrm (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+    char *name;
+
+    if(argc != 2) {
+       printf("Bad arguments: yrm name\n");
+       return -1;
+    }
+
+    name = argv[1];
+
+    cmd_yaffs_rm(name);
+
+    return(0);
+}
+
+int do_ymv (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+    char *oldPath;
+    char *newPath;
+
+    if(argc != 3) {
+       printf("Bad arguments: ymv old_path new_path\n");
+       return -1;
+    }
+
+    oldPath = argv[1];
+    newPath = argv[2];
+
+    cmd_yaffs_mv(newPath, oldPath);
+
+    return(0);
+}
+
+U_BOOT_CMD(
+    ydevconfig, 5,  0,  do_ydevconfig,
+    "configure yaffs mount point",
+    "ydevconfig mtpoint mtd_id start_block end_block   configures a yaffs2 mount point"
+);
+
+U_BOOT_CMD(
+    ymount, 2,  0,  do_ymount,
+    "mount yaffs",
+    "ymount mtpoint  mounts a yaffs2 mount point"
+);
+
+
+U_BOOT_CMD(
+    yumount, 2,  0,  do_yumount,
+    "unmount yaffs",
+    "yunmount mtpoint  unmounts a yaffs2 mount point"
+);
+
+U_BOOT_CMD(
+    yls,    3,  0,  do_yls,
+    "yaffs ls",
+    "yls [-l] dirname"
+);
+
+U_BOOT_CMD(
+    yrd,    2,  0,  do_yrd,
+    "read file from yaffs",
+    "yrd path   read file from yaffs"
+);
+
+U_BOOT_CMD(
+    ywr,    4,  0,  do_ywr,
+    "write file to yaffs",
+    "ywr filename value num_vlues   write values to yaffs file"
+);
+
+U_BOOT_CMD(
+    yrdm,   3,  0,  do_yrdm,
+    "read file to memory from yaffs",
+    "yrdm filename offset    reads yaffs file into memory"
+);
+
+U_BOOT_CMD(
+    ywrm,   4,  0,  do_ywrm,
+    "write file from memory to yaffs",
+    "ywrm filename offset size  writes memory to yaffs file"
+);
+
+U_BOOT_CMD(
+    ymkdir, 2,  0,  do_ymkdir,
+    "YAFFS mkdir",
+    "ymkdir dir    create a yaffs directory"
+);
+
+U_BOOT_CMD(
+    yrmdir, 2,  0,  do_yrmdir,
+    "YAFFS rmdir",
+    "yrmdir dirname   removes a yaffs directory"
+);
+
+U_BOOT_CMD(
+    yrm,    2,  0,  do_yrm,
+    "YAFFS rm",
+    "yrm path   removes a yaffs file"
+);
+
+U_BOOT_CMD(
+    ymv,    4,  0,  do_ymv,
+    "YAFFS mv",
+    "ymv old_path new_path   moves/rename files within a yaffs mount point"
+);
+
diff --git a/direct/u-boot/fs/yaffs2/Makefile b/direct/u-boot/fs/yaffs2/Makefile
new file mode 100644 (file)
index 0000000..0237f3c
--- /dev/null
@@ -0,0 +1,61 @@
+# 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.o
+
+COBJS-$(CONFIG_YAFFS2) := \
+       yaffs_allocator.o yaffs_attribs.o yaffs_bitmap.o yaffscfg.o\
+       yaffs_checkptrw.o yaffs_ecc.o yaffs_error.o \
+       yaffsfs.o yaffs_guts.o yaffs_hweight.o yaffs_nameval.o yaffs_nand.o\
+       yaffs_packedtags1.o yaffs_packedtags2.o yaffs_qsort.o \
+       yaffs_summary.o yaffs_tagscompat.o yaffs_verify.o yaffs_yaffs1.o \
+       yaffs_yaffs2.o yaffs_mtdif.o yaffs_mtdif2.o
+
+SRCS    := $(COBJS-y:.o=.c)
+OBJS    := $(addprefix $(obj),$(COBJS-y))
+
+YCFLAGS =  -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM 
+YCFLAGS += -DCONFIG_YAFFS_YAFFS2 -DNO_Y_INLINE -DLINUX_VERSION_CODE=0x20622
+YCFLAGS += -DCONFIG_YAFFS_PROVIDE_DEFS -DCONFIG_YAFFSFS_PROVIDE_VALUES
+
+CFLAGS += $(YCFLAGS)
+CPPFLAGS +=  $(YCFLAGS)
+
+all:  $(LIB)
+
+$(LIB): $(obj).depend $(OBJS)
+       $(call cmd_link_o_target, $(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/direct/u-boot/fs/yaffs2/assert.h b/direct/u-boot/fs/yaffs2/assert.h
new file mode 100644 (file)
index 0000000..9f379d7
--- /dev/null
@@ -0,0 +1 @@
+/* Dummy header for u-boot */
diff --git a/direct/u-boot/fs/yaffs2/copy-code.sh b/direct/u-boot/fs/yaffs2/copy-code.sh
new file mode 100755 (executable)
index 0000000..34520f6
--- /dev/null
@@ -0,0 +1,13 @@
+#! /bin/sh
+if [ "$1" = "copy" ] ; then
+       cp ../../../*.[ch] .
+elif [ "$1" = "clean" ] ; then
+       for i in `ls ../../../*.[ch]` ; do
+               f=`echo $i | sed -e "sx../xxg"`
+               rm $f
+       done
+else
+       echo "please specify copy or clean"
+       exit 1
+fi
+
diff --git a/direct/u-boot/fs/yaffs2/stdio.h b/direct/u-boot/fs/yaffs2/stdio.h
new file mode 100644 (file)
index 0000000..9f379d7
--- /dev/null
@@ -0,0 +1 @@
+/* Dummy header for u-boot */
diff --git a/direct/u-boot/fs/yaffs2/stdlib.h b/direct/u-boot/fs/yaffs2/stdlib.h
new file mode 100644 (file)
index 0000000..9f379d7
--- /dev/null
@@ -0,0 +1 @@
+/* Dummy header for u-boot */
diff --git a/direct/u-boot/fs/yaffs2/string.h b/direct/u-boot/fs/yaffs2/string.h
new file mode 100644 (file)
index 0000000..136716a
--- /dev/null
@@ -0,0 +1,6 @@
+#include <linux/stddef.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <common.h>
+
+
diff --git a/direct/u-boot/fs/yaffs2/yaffs_mtdif.c b/direct/u-boot/fs/yaffs2/yaffs_mtdif.c
new file mode 100644 (file)
index 0000000..6f3a028
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * 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>
+
+const char *yaffs_mtdif_c_version =
+    "$Id: yaffs_mtdif.c,v 1.19 2007/02/14 01:09:06 wookey Exp $";
+
+#include "yportenv.h"
+
+
+#include "yaffs_mtdif.h"
+
+#include "linux/mtd/mtd.h"
+#include "linux/types.h"
+#include "linux/time.h"
+#include "linux/mtd/nand.h"
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18))
+static struct nand_oobinfo yaffs_oobinfo = {
+       .useecc = 1,
+       .eccbytes = 6,
+       .eccpos = {8, 9, 10, 13, 14, 15}
+};
+
+static struct nand_oobinfo yaffs_noeccinfo = {
+       .useecc = 0,
+};
+#endif
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
+static inline void translate_spare2oob(const struct yaffs_spare *spare, u8 *oob)
+{
+       oob[0] = spare->tb0;
+       oob[1] = spare->tb1;
+       oob[2] = spare->tb2;
+       oob[3] = spare->tb3;
+       oob[4] = spare->tb4;
+       oob[5] = spare->tb5 & 0x3f;
+       oob[5] |= spare->block_status == 'Y' ? 0: 0x80;
+       oob[5] |= spare->page_status == 0 ? 0: 0x40;
+       oob[6] = spare->tb6;
+       oob[7] = spare->tb7;
+}
+
+static inline void translate_oob2spare(struct yaffs_spare *spare, u8 *oob)
+{
+       struct yaffs_nand_spare *nspare = (struct yaffs_nand_spare *)spare;
+       spare->tb0 = oob[0];
+       spare->tb1 = oob[1];
+       spare->tb2 = oob[2];
+       spare->tb3 = oob[3];
+       spare->tb4 = oob[4];
+       spare->tb5 = oob[5] == 0xff ? 0xff : oob[5] & 0x3f;
+       spare->block_status = oob[5] & 0x80 ? 0xff : 'Y';
+       spare->page_status = oob[5] & 0x40 ? 0xff : 0;
+       spare->ecc1[0] = spare->ecc1[1] = spare->ecc1[2] = 0xff;
+       spare->tb6 = oob[6];
+       spare->tb7 = oob[7];
+       spare->ecc2[0] = spare->ecc2[1] = spare->ecc2[2] = 0xff;
+
+       nspare->eccres1 = nspare->eccres2 = 0; /* FIXME */
+}
+#endif
+
+int nandmtd_WriteChunkToNAND(struct yaffs_dev * dev, int chunkInNAND,
+                            const u8 * data, const struct yaffs_spare * spare)
+{
+       struct mtd_info *mtd = (struct mtd_info *)(dev->driver_context);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
+       struct mtd_oob_ops ops;
+#endif
+       size_t dummy;
+       int retval = 0;
+
+       loff_t addr = ((loff_t) chunkInNAND) * dev->data_bytes_per_chunk;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
+       u8 spareAsBytes[8]; /* OOB */
+
+       if (data && !spare)
+               retval = mtd->write(mtd, addr, dev->data_bytes_per_chunk,
+                               &dummy, data);
+       else if (spare) {
+               if (dev->param.use_nand_ecc) {
+                       translate_spare2oob(spare, spareAsBytes);
+                       ops.mode = MTD_OOB_AUTO;
+                       ops.ooblen = 8; /* temp hack */
+               } else {
+                       ops.mode = MTD_OOB_RAW;
+                       ops.ooblen = YAFFS_BYTES_PER_SPARE;
+               }
+               ops.len = data ? dev->data_bytes_per_chunk : ops.ooblen;
+               ops.datbuf = (u8 *)data;
+               ops.ooboffs = 0;
+               ops.oobbuf = spareAsBytes;
+               retval = mtd->write_oob(mtd, addr, &ops);
+       }
+#else
+       u8 *spareAsBytes = (u8 *) spare;
+
+       if (data && spare) {
+               if (dev->param.use_nand_ecc)
+                       retval =
+                           mtd->write_ecc(mtd, addr, dev->data_bytes_per_chunk,
+                                          &dummy, data, spareAsBytes,
+                                          &yaffs_oobinfo);
+               else
+                       retval =
+                           mtd->write_ecc(mtd, addr, dev->data_bytes_per_chunk,
+                                          &dummy, data, spareAsBytes,
+                                          &yaffs_noeccinfo);
+       } else {
+               if (data)
+                       retval =
+                           mtd->write(mtd, addr, dev->data_bytes_per_chunk, &dummy,
+                                      data);
+               if (spare)
+                       retval =
+                           mtd->write_oob(mtd, addr, YAFFS_BYTES_PER_SPARE,
+                                          &dummy, spareAsBytes);
+       }
+#endif
+
+       if (retval == 0)
+               return YAFFS_OK;
+       else
+               return YAFFS_FAIL;
+}
+
+int nandmtd_ReadChunkFromNAND(struct yaffs_dev * dev, int chunkInNAND, u8 * data,
+                             struct yaffs_spare * spare)
+{
+       struct mtd_info *mtd = (struct mtd_info *)(dev->driver_context);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
+       struct mtd_oob_ops ops;
+#endif
+       size_t dummy;
+       int retval = 0;
+
+       loff_t addr = ((loff_t) chunkInNAND) * dev->data_bytes_per_chunk;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
+       u8 spareAsBytes[8]; /* OOB */
+
+       if (data && !spare)
+               retval = mtd->read(mtd, addr, dev->data_bytes_per_chunk,
+                               &dummy, data);
+       else if (spare) {
+               if (dev->param.use_nand_ecc) {
+                       ops.mode = MTD_OOB_AUTO;
+                       ops.ooblen = 8; /* temp hack */
+               } else {
+                       ops.mode = MTD_OOB_RAW;
+                       ops.ooblen = YAFFS_BYTES_PER_SPARE;
+               }
+               ops.len = data ? dev->data_bytes_per_chunk : ops.ooblen;
+               ops.datbuf = data;
+               ops.ooboffs = 0;
+               ops.oobbuf = spareAsBytes;
+               retval = mtd->read_oob(mtd, addr, &ops);
+               if (dev->param.use_nand_ecc)
+                       translate_oob2spare(spare, spareAsBytes);
+       }
+#else
+       u8 *spareAsBytes = (u8 *) spare;
+
+       if (data && spare) {
+               if (dev->param.use_nand_ecc) {
+                       /* Careful, this call adds 2 ints */
+                       /* to the end of the spare data.  Calling function */
+                       /* should allocate enough memory for spare, */
+                       /* i.e. [YAFFS_BYTES_PER_SPARE+2*sizeof(int)]. */
+                       retval =
+                           mtd->read_ecc(mtd, addr, dev->data_bytes_per_chunk,
+                                         &dummy, data, spareAsBytes,
+                                         &yaffs_oobinfo);
+               } else {
+                       retval =
+                           mtd->read_ecc(mtd, addr, dev->data_bytes_per_chunk,
+                                         &dummy, data, spareAsBytes,
+                                         &yaffs_noeccinfo);
+               }
+       } else {
+               if (data)
+                       retval =
+                           mtd->read(mtd, addr, dev->data_bytes_per_chunk, &dummy,
+                                     data);
+               if (spare)
+                       retval =
+                           mtd->read_oob(mtd, addr, YAFFS_BYTES_PER_SPARE,
+                                         &dummy, spareAsBytes);
+       }
+#endif
+
+       if (retval == 0)
+               return YAFFS_OK;
+       else
+               return YAFFS_FAIL;
+}
+
+int nandmtd_EraseBlockInNAND(struct yaffs_dev * dev, int blockNumber)
+{
+       struct mtd_info *mtd = (struct mtd_info *)(dev->driver_context);
+       __u32 addr =
+           ((loff_t) blockNumber) * dev->data_bytes_per_chunk
+               * dev->param.chunks_per_block;
+       struct erase_info ei;
+       int retval = 0;
+
+       ei.mtd = mtd;
+       ei.addr = addr;
+       ei.len = dev->data_bytes_per_chunk * dev->param.chunks_per_block;
+       ei.time = 1000;
+       ei.retries = 2;
+       ei.callback = NULL;
+       ei.priv = (u_long) dev;
+
+       /* Todo finish off the ei if required */
+
+/* XXX U-BOOT XXX */
+#if 0
+       sema_init(&dev->sem, 0);
+#endif
+
+       retval = mtd->erase(mtd, &ei);
+
+       if (retval == 0)
+               return YAFFS_OK;
+       else
+               return YAFFS_FAIL;
+}
+
+int nandmtd_InitialiseNAND(struct yaffs_dev * dev)
+{
+       return YAFFS_OK;
+}
diff --git a/direct/u-boot/fs/yaffs2/yaffs_mtdif.h b/direct/u-boot/fs/yaffs2/yaffs_mtdif.h
new file mode 100644 (file)
index 0000000..91e8dc9
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * 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_MTDIF_H__
+#define __YAFFS_MTDIF_H__
+
+#include "yaffs_guts.h"
+
+int nandmtd_WriteChunkToNAND(struct yaffs_dev * dev, int chunkInNAND,
+                            const u8 * data, const struct yaffs_spare * spare);
+int nandmtd_ReadChunkFromNAND(struct yaffs_dev * dev, int chunkInNAND, u8 * data,
+                             struct yaffs_spare * spare);
+int nandmtd_EraseBlockInNAND(struct yaffs_dev * dev, int blockNumber);
+int nandmtd_InitialiseNAND(struct yaffs_dev * dev);
+#endif
diff --git a/direct/u-boot/fs/yaffs2/yaffs_mtdif2.c b/direct/u-boot/fs/yaffs2/yaffs_mtdif2.c
new file mode 100644 (file)
index 0000000..2f29491
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ * 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.
+ */
+
+/* mtd interface for YAFFS2 */
+
+/* XXX U-BOOT XXX */
+#include <common.h>
+#include "asm/errno.h"
+
+#include "yportenv.h"
+#include "yaffs_trace.h"
+
+#include "yaffs_mtdif2.h"
+
+#include "linux/mtd/mtd.h"
+#include "linux/types.h"
+#include "linux/time.h"
+
+#include "yaffs_trace.h"
+
+#include "yaffs_packedtags2.h"
+#include "string.h"
+
+
+int nandmtd2_WriteChunkWithTagsToNAND(struct yaffs_dev* dev, int chunkInNAND,
+                                     const u8 * data,
+                                     const struct yaffs_ext_tags * tags)
+{
+       struct mtd_info *mtd = (struct mtd_info *)(dev->driver_context);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
+       struct mtd_oob_ops ops;
+#else
+       size_t dummy;
+#endif
+       int retval = 0;
+
+       loff_t addr = ((loff_t) chunkInNAND) * dev->data_bytes_per_chunk;
+
+       struct yaffs_packed_tags2 pt;
+
+       yaffs_trace(YAFFS_TRACE_MTD,
+               "nandmtd2_WriteChunkWithTagsToNAND chunk %d data %p tags %p",
+               chunkInNAND, data, tags);
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
+       if (tags)
+               yaffs_pack_tags2(&pt, tags, !dev->param.no_tags_ecc);
+       else
+               BUG(); /* both tags and data should always be present */
+
+       if (data) {
+               ops.mode = MTD_OOB_AUTO;
+               ops.ooblen = sizeof(pt);
+               ops.len = dev->data_bytes_per_chunk;
+               ops.ooboffs = 0;
+               ops.datbuf = (u8 *)data;
+               ops.oobbuf = (void *)&pt;
+               retval = mtd->write_oob(mtd, addr, &ops);
+       } else
+               BUG(); /* both tags and data should always be present */
+#else
+       if (tags) {
+               yaffs_pack_tags2(&pt, tags);
+       }
+
+       if (data && tags) {
+               if (dev->param.use_nand_ecc)
+                       retval =
+                           mtd->write_ecc(mtd, addr, dev->data_bytes_per_chunk,
+                                          &dummy, data, (u8 *) & pt, NULL);
+               else
+                       retval =
+                           mtd->write_ecc(mtd, addr, dev->data_bytes_per_chunk,
+                                          &dummy, data, (u8 *) & pt, NULL);
+       } else {
+               if (data)
+                       retval =
+                           mtd->write(mtd, addr, dev->data_bytes_per_chunk, &dummy,
+                                      data);
+               if (tags)
+                       retval =
+                           mtd->write_oob(mtd, addr, mtd->oobsize, &dummy,
+                                          (u8 *) & pt);
+
+       }
+#endif
+
+       if (retval == 0)
+               return YAFFS_OK;
+       else
+               return YAFFS_FAIL;
+}
+
+int nandmtd2_ReadChunkWithTagsFromNAND(struct yaffs_dev * dev, int chunkInNAND,
+                                      u8 * data, struct yaffs_ext_tags * tags)
+{
+       static u8 *spare_buffer = NULL;
+
+       struct mtd_info *mtd = (struct mtd_info *)(dev->driver_context);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
+       struct mtd_oob_ops ops;
+#endif
+       size_t dummy;
+       int retval = 0;
+
+       loff_t addr = ((loff_t) chunkInNAND) * dev->data_bytes_per_chunk;
+
+       struct yaffs_packed_tags2 pt;
+       
+       if(!spare_buffer)
+               spare_buffer = kmalloc(mtd->oobsize, GFP_NOFS);
+
+       yaffs_trace(YAFFS_TRACE_MTD,
+               "nandmtd2_ReadChunkWithTagsFromNAND chunk %d data %p tags %p",
+               chunkInNAND, data, tags);
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
+       if (data && !tags)
+               retval = mtd->read(mtd, addr, dev->data_bytes_per_chunk,
+                               &dummy, data);
+       else if (tags) {
+               ops.mode = MTD_OOB_AUTO;
+               ops.ooblen = sizeof(pt);
+               ops.len = data ? dev->data_bytes_per_chunk : sizeof(pt);
+               ops.ooboffs = 0;
+               ops.datbuf = data;
+               ops.oobbuf = spare_buffer;
+               retval = mtd->read_oob(mtd, addr, &ops);
+       }
+#else
+       if (data && tags) {
+               if (dev->useNANDECC) {
+                       retval =
+                           mtd->read_ecc(mtd, addr, dev->data_bytes_per_chunk,
+                                         &dummy, data, dev->spare_buffer,
+                                         NULL);
+               } else {
+                       retval =
+                           mtd->read_ecc(mtd, addr, dev->data_bytes_per_chunk,
+                                         &dummy, data, dev->spare_buffer,
+                                         NULL);
+               }
+       } else {
+               if (data)
+                       retval =
+                           mtd->read(mtd, addr, dev->data_bytes_per_chunk, &dummy,
+                                     data);
+               if (tags)
+                       retval =
+                           mtd->read_oob(mtd, addr, mtd->oobsize, &dummy,
+                                         dev->spare_buffer);
+       }
+#endif
+
+       memcpy(&pt, spare_buffer, sizeof(pt));
+
+       if (tags)
+               yaffs_unpack_tags2(tags, &pt, !dev->param.no_tags_ecc);
+
+       if(tags && retval == -EBADMSG && tags->ecc_result == YAFFS_ECC_RESULT_NO_ERROR)
+               tags->ecc_result = YAFFS_ECC_RESULT_UNFIXED;
+
+       if (retval == 0)
+               return YAFFS_OK;
+       else
+               return YAFFS_FAIL;
+}
+
+int nandmtd2_MarkNANDBlockBad(struct yaffs_dev *dev, int blockNo)
+{
+       struct mtd_info *mtd = (struct mtd_info *)(dev->driver_context);
+       int retval;
+
+       yaffs_trace(YAFFS_TRACE_MTD,
+               "nandmtd2_MarkNANDBlockBad %d", blockNo);
+
+       retval =
+           mtd->block_markbad(mtd,
+                              blockNo * dev->param.chunks_per_block *
+                              dev->data_bytes_per_chunk);
+
+       if (retval == 0)
+               return YAFFS_OK;
+       else
+               return YAFFS_FAIL;
+
+}
+
+int nandmtd2_QueryNANDBlock(struct yaffs_dev *dev, int blockNo,
+                           enum yaffs_block_state * state, int *sequenceNumber)
+{
+       struct mtd_info *mtd = (struct mtd_info *)(dev->driver_context);
+       int retval;
+
+       yaffs_trace(YAFFS_TRACE_MTD, "nandmtd2_QueryNANDBlock %d", blockNo);
+       retval =
+           mtd->block_isbad(mtd,
+                            blockNo * dev->param.chunks_per_block *
+                            dev->data_bytes_per_chunk);
+
+       if (retval) {
+               yaffs_trace(YAFFS_TRACE_MTD, "block is bad");
+
+               *state = YAFFS_BLOCK_STATE_DEAD;
+               *sequenceNumber = 0;
+       } else {
+               struct yaffs_ext_tags t;
+               nandmtd2_ReadChunkWithTagsFromNAND(dev,
+                                                  blockNo *
+                                                  dev->param.chunks_per_block, NULL,
+                                                  &t);
+
+               if (t.chunk_used) {
+                       *sequenceNumber = t.seq_number;
+                       *state = YAFFS_BLOCK_STATE_NEEDS_SCAN;
+               } else {
+                       *sequenceNumber = 0;
+                       *state = YAFFS_BLOCK_STATE_EMPTY;
+               }
+       }
+       yaffs_trace(YAFFS_TRACE_MTD, "block is bad seq %d state %d", *sequenceNumber, *state);
+
+       if (retval == 0)
+               return YAFFS_OK;
+       else
+               return YAFFS_FAIL;
+}
diff --git a/direct/u-boot/fs/yaffs2/yaffs_mtdif2.h b/direct/u-boot/fs/yaffs2/yaffs_mtdif2.h
new file mode 100644 (file)
index 0000000..3b842be
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * 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_MTDIF2_H__
+#define __YAFFS_MTDIF2_H__
+
+#include "yaffs_guts.h"
+
+int nandmtd2_WriteChunkWithTagsToNAND(struct yaffs_dev * dev, int chunkInNAND,
+                                     const u8 * data,
+                                     const struct yaffs_ext_tags * tags);
+int nandmtd2_ReadChunkWithTagsFromNAND(struct yaffs_dev * dev, int chunkInNAND,
+                                      __u8 * data, struct yaffs_ext_tags * tags);
+int nandmtd2_MarkNANDBlockBad(struct yaffs_dev *dev, int blockNo);
+int nandmtd2_QueryNANDBlock(struct yaffs_dev *dev, int blockNo,
+                           enum yaffs_block_state * state, int *sequenceNumber);
+
+#endif
diff --git a/direct/u-boot/fs/yaffs2/yaffscfg.c b/direct/u-boot/fs/yaffs2/yaffscfg.c
new file mode 100644 (file)
index 0000000..49bd596
--- /dev/null
@@ -0,0 +1,324 @@
+/*
+ * 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 is set up for u-boot.
+ *
+ * This version now uses the ydevconfig mechanism to set up partitions.
+ */
+
+#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_trace_mask = 0x0; /* Disable logging */
+static int yaffs_errno = 0;
+
+
+
+void *yaffsfs_malloc(size_t x)
+{
+       return malloc(x);
+}
+
+void yaffsfs_free(void *x)
+{
+       free(x);
+}
+
+void yaffsfs_SetError(int err)
+{
+       //Do whatever to set error
+       yaffs_errno = err;
+}
+
+int yaffsfs_GetLastError(void)
+{
+       return yaffs_errno;
+}
+
+
+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.
+}
+
+extern nand_info_t nand_info[];
+
+
+void cmd_yaffs_devconfig(char *_mp, int flash_dev, int start_block, int end_block)
+{
+       struct mtd_info *mtd = NULL;
+       struct yaffs_dev *dev;
+       char *mp;
+       
+       dev = calloc(1, sizeof(*dev));
+       mp = strdup(_mp);
+       
+       mtd = &nand_info[flash_dev];
+       if(!dev || !mp) {
+               /* Alloc error */
+               return;
+       }
+
+       if(end_block < start_block)
+               end_block = mtd->size / mtd->erasesize;
+
+       memset(dev, 0, sizeof(*dev));
+       dev->param.name = mp;
+       dev->driver_context = mtd;
+       dev->param.start_block = start_block;
+       dev->param.end_block = end_block;
+       dev->param.chunks_per_block = mtd->erasesize / mtd->writesize;
+       dev->param.total_bytes_per_chunk = mtd->writesize;
+       dev->param.is_yaffs2 = 1;
+       dev->param.use_nand_ecc = 1;
+       dev->param.n_reserved_blocks = 5;
+       dev->param.inband_tags = 0;
+       dev->param.n_caches = 10;
+       dev->param.write_chunk_tags_fn = nandmtd2_WriteChunkWithTagsToNAND;
+       dev->param.read_chunk_tags_fn = nandmtd2_ReadChunkWithTagsFromNAND;
+       dev->param.erase_fn = nandmtd_EraseBlockInNAND;
+       dev->param.initialise_flash_fn = nandmtd_InitialiseNAND;
+       dev->param.bad_block_fn = nandmtd2_MarkNANDBlockBad;
+       dev->param.query_block_fn = nandmtd2_QueryNANDBlock;
+       
+       yaffs_add_device(dev);
+}
+       
+
+
+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)
+{
+       int retval = yaffs_mount(mp);
+       if( retval < 0)
+               printf("Error mounting %s, return value: %d\n", mp, yaffsfs_GetError());
+}
+
+
+void cmd_yaffs_umount(char *mp)
+{
+       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)
+{
+       make_a_file(yaffsName,bval,sizeOfFile);
+}
+
+
+void cmd_yaffs_read_file(char *fn)
+{
+       read_a_file(fn);
+}
+
+
+void cmd_yaffs_mread_file(char *fn, char *addr)
+{
+       int h;
+       struct yaffs_stat s;
+
+       yaffs_stat(fn,&s);
+
+       printf ("Copy %s to 0x%p... ", 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;
+
+       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];
+
+       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%7ld\n",de->d_name, stat.st_size);
+                       }
+                       else
+                       {
+                               printf("%s\n",de->d_name);
+                       }
+               }
+       }
+}
+
+
+void cmd_yaffs_mkdir(const char *dir)
+{
+       int retval = yaffs_mkdir(dir, 0);
+
+       if ( retval < 0)
+               printf("yaffs_mkdir returning error: %d\n", retval);
+}
+
+void cmd_yaffs_rmdir(const char *dir)
+{
+       int retval = yaffs_rmdir(dir);
+
+       if ( retval < 0)
+               printf("yaffs_rmdir returning error: %d\n", retval);
+}
+
+void cmd_yaffs_rm(const char *path)
+{
+       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)
+{
+       int retval = yaffs_rename(newPath, oldPath);
+
+       if ( retval < 0)
+               printf("yaffs_unlink returning error: %d\n", retval);
+}
index 9ef19bf..fffc11e 100644 (file)
@@ -17,7 +17,7 @@
 #include "yportenv.h"
 #include "yaffs_trace.h"
 
-#include <string.h> /* for memset */
+#include "string.h"
 
 #define YAFFSFS_MAX_SYMLINK_DEREFERENCES 5
 
index 0bcf23e..657f364 100644 (file)
@@ -200,27 +200,3 @@ int yaffs_set_error(int error);
 unsigned  yaffs_set_trace(unsigned tm);
 unsigned  yaffs_get_trace(void);
 #endif
-
-
-/*
- * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
- *
- * Copyright (C) 2002-2011 Aleph One Ltd.
- *   for Toby Churchill Ltd and Brightstar Engineering
- *
- * Created by Timothy Manning <timothy@yaffs.net>
- *
- * 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 __error_handler_h__
-#define __error_handler_h__
-#include <stdio.h>
-
-#include "yaffsfs.h"
-#include "yportenv.h"
-#endif
index 0d0d0fa..a797c8a 100644 (file)
 
 
 /* Definition of types */
+#ifdef CONFIG_YAFFS_DEFINES_TYPES
 typedef unsigned char u8;
 typedef unsigned short u16;
 typedef unsigned u32;
+#endif
 
 
 #ifdef CONFIG_YAFFS_PROVIDE_DEFS
index 6ad45fc..8acb59b 100644 (file)
@@ -280,7 +280,8 @@ static void yaffs_handle_chunk_wr_error(struct yaffs_dev *dev, int nand_chunk,
 
 static inline int yaffs_hash_fn(int n)
 {
-       n = abs(n);
+       if(n < 0)
+               n = -n;
        return n % YAFFS_NOBJECT_BUCKETS;
 }