From: Charles Manning Date: Tue, 3 Apr 2012 01:06:16 +0000 (+1200) Subject: Add files to hook up yaffs direct to u-boot X-Git-Tag: pre-driver-refactoring~21 X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=commitdiff_plain;h=80f85303d264f804ea288e1995280345804ec01c Add files to hook up yaffs direct to u-boot Signed-off-by: Charles Manning --- diff --git a/direct/u-boot/common/cmd_yaffs2.c b/direct/u-boot/common/cmd_yaffs2.c new file mode 100644 index 0000000..fd9b4fa --- /dev/null +++ b/direct/u-boot/common/cmd_yaffs2.c @@ -0,0 +1,325 @@ +/* Yaffs commands. + * Modified by Charles Manning by adding ydevconfig command. + * + */ + +#include + +#include +#include + +#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 index 0000000..0237f3c --- /dev/null +++ b/direct/u-boot/fs/yaffs2/Makefile @@ -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 +# +# 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 index 0000000..9f379d7 --- /dev/null +++ b/direct/u-boot/fs/yaffs2/assert.h @@ -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 index 0000000..34520f6 --- /dev/null +++ b/direct/u-boot/fs/yaffs2/copy-code.sh @@ -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 index 0000000..9f379d7 --- /dev/null +++ b/direct/u-boot/fs/yaffs2/stdio.h @@ -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 index 0000000..9f379d7 --- /dev/null +++ b/direct/u-boot/fs/yaffs2/stdlib.h @@ -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 index 0000000..136716a --- /dev/null +++ b/direct/u-boot/fs/yaffs2/string.h @@ -0,0 +1,6 @@ +#include +#include +#include +#include + + diff --git a/direct/u-boot/fs/yaffs2/yaffs_mtdif.c b/direct/u-boot/fs/yaffs2/yaffs_mtdif.c new file mode 100644 index 0000000..6f3a028 --- /dev/null +++ b/direct/u-boot/fs/yaffs2/yaffs_mtdif.c @@ -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 + * + * 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 + +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 index 0000000..91e8dc9 --- /dev/null +++ b/direct/u-boot/fs/yaffs2/yaffs_mtdif.h @@ -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 + * + * 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 index 0000000..2f29491 --- /dev/null +++ b/direct/u-boot/fs/yaffs2/yaffs_mtdif2.c @@ -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 + * + * 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 +#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 index 0000000..3b842be --- /dev/null +++ b/direct/u-boot/fs/yaffs2/yaffs_mtdif2.h @@ -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 + * + * 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 index 0000000..49bd596 --- /dev/null +++ b/direct/u-boot/fs/yaffs2/yaffscfg.c @@ -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 + * + * 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 + +#include +#include "nand.h" +#include "yaffscfg.h" +#include "yaffsfs.h" +#include "yaffs_packedtags2.h" +#include "yaffs_mtdif.h" +#include "yaffs_mtdif2.h" +#if 0 +#include +#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); +} diff --git a/direct/yaffsfs.c b/direct/yaffsfs.c index 9ef19bf..fffc11e 100644 --- a/direct/yaffsfs.c +++ b/direct/yaffsfs.c @@ -17,7 +17,7 @@ #include "yportenv.h" #include "yaffs_trace.h" -#include /* for memset */ +#include "string.h" #define YAFFSFS_MAX_SYMLINK_DEREFERENCES 5 diff --git a/direct/yaffsfs.h b/direct/yaffsfs.h index 0bcf23e..657f364 100644 --- a/direct/yaffsfs.h +++ b/direct/yaffsfs.h @@ -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 - * - * 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 - -#include "yaffsfs.h" -#include "yportenv.h" -#endif diff --git a/direct/yportenv.h b/direct/yportenv.h index 0d0d0fa..a797c8a 100644 --- a/direct/yportenv.h +++ b/direct/yportenv.h @@ -19,9 +19,11 @@ /* 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 diff --git a/yaffs_guts.c b/yaffs_guts.c index 6ad45fc..8acb59b 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -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; }