Commit d13a371b authored by 张青山(steven.zhang)'s avatar 张青山(steven.zhang)

Merge branch 'neuros' of...

Merge branch 'neuros' of ssh://git@git.neuros.com.cn/git/git-pub/osd20/linux-davinci-2.6 into neuros
parents 5a958b35 762a79f1
...@@ -466,7 +466,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 ...@@ -466,7 +466,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
# CONFIG_MTD_DOC2001 is not set # CONFIG_MTD_DOC2001 is not set
# CONFIG_MTD_DOC2001PLUS is not set # CONFIG_MTD_DOC2001PLUS is not set
CONFIG_MTD_NAND=y CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_VERIFY_WRITE is not set CONFIG_MTD_NAND_VERIFY_WRITE=y
# CONFIG_MTD_NAND_ECC_SMC is not set # CONFIG_MTD_NAND_ECC_SMC is not set
# CONFIG_MTD_NAND_MUSEUM_IDS is not set # CONFIG_MTD_NAND_MUSEUM_IDS is not set
CONFIG_MTD_NAND_IDS=y CONFIG_MTD_NAND_IDS=y
...@@ -474,6 +474,7 @@ CONFIG_MTD_NAND_IDS=y ...@@ -474,6 +474,7 @@ CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_NANDSIM is not set
# CONFIG_MTD_NAND_PLATFORM is not set # CONFIG_MTD_NAND_PLATFORM is not set
CONFIG_MTD_NAND_DAVINCI=y CONFIG_MTD_NAND_DAVINCI=y
CONFIG_NAND_FLASH_HW_ECC=y
# CONFIG_MTD_ONENAND is not set # CONFIG_MTD_ONENAND is not set
# #
...@@ -1202,6 +1203,16 @@ CONFIG_RAMFS=y ...@@ -1202,6 +1203,16 @@ CONFIG_RAMFS=y
# CONFIG_BEFS_FS is not set # CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set # CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set # CONFIG_EFS_FS is not set
CONFIG_YAFFS_FS=y
CONFIG_YAFFS_YAFFS1=y
# CONFIG_YAFFS_9BYTE_TAGS is not set
# CONFIG_YAFFS_DOES_ECC is not set
CONFIG_YAFFS_YAFFS2=y
CONFIG_YAFFS_AUTO_YAFFS2=y
# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y CONFIG_JFFS2_FS_WRITEBUFFER=y
......
...@@ -100,20 +100,20 @@ static struct platform_device ntosd_644xa_norflash_device = { ...@@ -100,20 +100,20 @@ static struct platform_device ntosd_644xa_norflash_device = {
}; };
#if defined(CONFIG_MTD_NAND_DAVINCI) || defined(CONFIG_MTD_NAND_DAVINCI_MODULE) #if defined(CONFIG_MTD_NAND_DAVINCI) || defined(CONFIG_MTD_NAND_DAVINCI_MODULE)
#define UBOOT_START 0x18000 #define UBOOT_START 0xc0000
struct mtd_partition ntosd_644xa_nandflash_partition[] = { struct mtd_partition ntosd_644xa_nandflash_partition[] = {
/* uboot parameter */ /* uboot parameter */
{ {
.name = "u-boot-parameter", .name = "u-boot-parameter",
.offset = 0, .offset = 0,
.size = 1 * SZ_16K, .size = 1 * SZ_128K,
.mask_flags = 0, .mask_flags = 0,
}, },
/* ubl */ /* ubl */
{ {
.name = "ubl", .name = "ubl",
.offset = 1 * SZ_16K, .offset = 1 * SZ_128K,
.size = 5 * SZ_16K, .size = 5 * SZ_128K,
.mask_flags = 0, .mask_flags = 0,
}, },
/* 1 MB space from bootloader start for bootloader */ /* 1 MB space from bootloader start for bootloader */
......
...@@ -53,7 +53,13 @@ ...@@ -53,7 +53,13 @@
#include <asm/mach/flash.h> #include <asm/mach/flash.h>
#ifdef CONFIG_NAND_FLASH_HW_ECC #ifdef CONFIG_NAND_FLASH_HW_ECC
#ifdef CONFIG_MACH_NTOSD_644XA
#define DAVINCI_NAND_ECC_MODE NAND_ECC_HW16_2048
#else
#define DAVINCI_NAND_ECC_MODE NAND_ECC_HW3_512 #define DAVINCI_NAND_ECC_MODE NAND_ECC_HW3_512
#endif
#else #else
#define DAVINCI_NAND_ECC_MODE NAND_ECC_SOFT #define DAVINCI_NAND_ECC_MODE NAND_ECC_SOFT
#endif #endif
...@@ -90,6 +96,24 @@ static struct nand_bbt_descr davinci_memorybased_large = { ...@@ -90,6 +96,24 @@ static struct nand_bbt_descr davinci_memorybased_large = {
.pattern = scan_ff_pattern .pattern = scan_ff_pattern
}; };
#ifdef CONFIG_MACH_NTOSD_644XA
static struct nand_ecclayout davinci_nand_oob_16 = {
.eccbytes = 4,
.eccpos = {0, 1, 2, 3},
.oobfree = { {.offset = 8, .length = 8} }
};
static struct nand_ecclayout davinci_nand_oob_64 = {
.eccbytes = 16,
.eccpos = {8, 9, 10, 11, 24, 25, 26, 27, 40, 41, 42, 43, 56, 57, 58, 59},
.oobfree = { {.offset = 2, .length = 6},
{.offset = 12, .length = 12},
{.offset = 28, .length = 12},
{.offset = 44, .length = 12},
{.offset = 60, .length = 4} }
};
#endif
inline unsigned int davinci_nand_readl(int offset) inline unsigned int davinci_nand_readl(int offset)
{ {
return davinci_readl(DAVINCI_ASYNC_EMIF_CNTRL_BASE + offset); return davinci_readl(DAVINCI_ASYNC_EMIF_CNTRL_BASE + offset);
...@@ -153,6 +177,58 @@ static u32 nand_davinci_readecc(struct mtd_info *mtd) ...@@ -153,6 +177,58 @@ static u32 nand_davinci_readecc(struct mtd_info *mtd)
return davinci_nand_readl(NANDF1ECC_OFFSET); return davinci_nand_readl(NANDF1ECC_OFFSET);
} }
#ifdef CONFIG_MACH_NTOSD_644XA
/*
* Read DaVinci ECC registers and rework into MTD format
*/
static int nand_davinci_calculate_ecc(struct mtd_info *mtd,
const u_char *dat, u_char *ecc_code)
{
unsigned int ecc_val = nand_davinci_readecc(mtd);
unsigned int tmp;
/* invert so that erased block ecc is correct */
tmp = ecc_val;
if(tmp == 0) tmp = ~tmp;
ecc_code[0] = (u_char)(tmp >> 24);
ecc_code[1] = (u_char)(tmp >> 16);
ecc_code[2] = (u_char)(tmp >> 8);
ecc_code[3] = (u_char)(tmp);
return 0;
}
static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat,
u_char *read_ecc, u_char *calc_ecc)
{
struct nand_chip *chip = mtd->priv;
u_int32_t eccNand = (read_ecc[0] << 24) | (read_ecc[1] << 16) |
(read_ecc[2] << 8) | (read_ecc[3]);
u_int32_t eccCalc = (calc_ecc[0] << 24) | (calc_ecc[1] << 16) |
(calc_ecc[2] << 8) | (calc_ecc[3]);
u_int32_t diff;
diff = eccCalc ^ eccNand;
if (diff) {
if ((((diff>>16)^diff) & 0xffff) == 0xffff) {
/* Correctable error */
if ((diff>>(16+4)) < chip->ecc.size) {
dat[diff>>(16+4)] ^= (1 << ((diff>>16)&7));
return 1;
} else {
return -1;
}
} else if (!(diff & (diff-1))) {
/* Single bit ECC error in the ECC itself,
nothing to fix */
return 1;
} else {
/* Uncorrectable error */
return -1;
}
}
return 0;
}
#else /* not NTOSD_644XA */
/* /*
* Read DaVinci ECC registers and rework into MTD format * Read DaVinci ECC registers and rework into MTD format
*/ */
...@@ -202,6 +278,7 @@ static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, ...@@ -202,6 +278,7 @@ static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat,
} }
return 0; return 0;
} }
#endif /* CONFIG_MACH_NTOSD_644XA */
#endif #endif
/* /*
...@@ -369,10 +446,12 @@ static void nand_davinci_set_eccsize(struct nand_chip *chip) ...@@ -369,10 +446,12 @@ static void nand_davinci_set_eccsize(struct nand_chip *chip)
#ifdef CONFIG_NAND_FLASH_HW_ECC #ifdef CONFIG_NAND_FLASH_HW_ECC
switch (chip->ecc.mode) { switch (chip->ecc.mode) {
case NAND_ECC_HW12_2048: case NAND_ECC_HW12_2048:
case NAND_ECC_HW16_2048:
chip->ecc.size = 2048; chip->ecc.size = 2048;
break; break;
case NAND_ECC_HW3_512: case NAND_ECC_HW3_512:
case NAND_ECC_HW4_512:
case NAND_ECC_HW6_512: case NAND_ECC_HW6_512:
case NAND_ECC_HW8_512: case NAND_ECC_HW8_512:
chip->ecc.size = 512; chip->ecc.size = 512;
...@@ -392,12 +471,16 @@ static void nand_davinci_set_eccbytes(struct nand_chip *chip) ...@@ -392,12 +471,16 @@ static void nand_davinci_set_eccbytes(struct nand_chip *chip)
#ifdef CONFIG_NAND_FLASH_HW_ECC #ifdef CONFIG_NAND_FLASH_HW_ECC
switch (chip->ecc.mode) { switch (chip->ecc.mode) {
case NAND_ECC_HW16_2048:
chip->ecc.bytes += 4;
case NAND_ECC_HW12_2048: case NAND_ECC_HW12_2048:
chip->ecc.bytes += 4; chip->ecc.bytes += 4;
case NAND_ECC_HW8_512: case NAND_ECC_HW8_512:
chip->ecc.bytes += 2; chip->ecc.bytes += 2;
case NAND_ECC_HW6_512: case NAND_ECC_HW6_512:
chip->ecc.bytes += 3; chip->ecc.bytes += 2;
case NAND_ECC_HW4_512:
chip->ecc.bytes += 1;
case NAND_ECC_HW3_512: case NAND_ECC_HW3_512:
case NAND_ECC_HW3_256: case NAND_ECC_HW3_256:
default: default:
...@@ -544,6 +627,12 @@ int __devinit nand_davinci_probe(struct platform_device *pdev) ...@@ -544,6 +627,12 @@ int __devinit nand_davinci_probe(struct platform_device *pdev)
chip->dev_ready = nand_davinci_dev_ready; chip->dev_ready = nand_davinci_dev_ready;
#ifdef CONFIG_NAND_FLASH_HW_ECC #ifdef CONFIG_NAND_FLASH_HW_ECC
#ifdef CONFIG_MACH_NTOSD_644XA
if(chip->ecc.size > 512)
chip->ecc.layout = &davinci_nand_oob_64;
else
chip->ecc.layout = &davinci_nand_oob_16;
#endif
chip->ecc.calculate = nand_davinci_calculate_ecc; chip->ecc.calculate = nand_davinci_calculate_ecc;
chip->ecc.correct = nand_davinci_correct_data; chip->ecc.correct = nand_davinci_correct_data;
chip->ecc.hwctl = nand_davinci_enable_hwecc; chip->ecc.hwctl = nand_davinci_enable_hwecc;
......
...@@ -52,6 +52,11 @@ ...@@ -52,6 +52,11 @@
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#endif #endif
#ifdef CONFIG_MACH_NTOSD_644XA
#define DM6446_NAND_ECC_SIZE 512
#define DM6446_NAND_ECC_BYTES 4
#endif
/* Define default oob placement schemes for large and small page devices */ /* Define default oob placement schemes for large and small page devices */
static struct nand_ecclayout nand_oob_8 = { static struct nand_ecclayout nand_oob_8 = {
.eccbytes = 3, .eccbytes = 3,
...@@ -808,9 +813,16 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, ...@@ -808,9 +813,16 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
uint8_t *buf) uint8_t *buf)
{ {
#ifdef CONFIG_MACH_NTOSD_644XA
/* every 512 bytes generate 4 bytes ecc */
int i, eccsize = DM6446_NAND_ECC_SIZE;
int eccbytes = DM6446_NAND_ECC_BYTES;
int eccsteps = chip->ecc.size / eccsize;
#else
int i, eccsize = chip->ecc.size; int i, eccsize = chip->ecc.size;
int eccbytes = chip->ecc.bytes; int eccbytes = chip->ecc.bytes;
int eccsteps = chip->ecc.steps; int eccsteps = chip->ecc.steps;
#endif
uint8_t *p = buf; uint8_t *p = buf;
uint8_t *ecc_calc = chip->buffers->ecccalc; uint8_t *ecc_calc = chip->buffers->ecccalc;
uint8_t *ecc_code = chip->buffers->ecccode; uint8_t *ecc_code = chip->buffers->ecccode;
...@@ -1441,9 +1453,16 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, ...@@ -1441,9 +1453,16 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf) const uint8_t *buf)
{ {
#ifdef CONFIG_MACH_NTOSD_644XA
/* every 512 bytes generate 4 bytes ecc */
int i, eccsize = DM6446_NAND_ECC_SIZE;
int eccbytes = DM6446_NAND_ECC_BYTES;
int eccsteps = chip->ecc.size / eccsize;
#else
int i, eccsize = chip->ecc.size; int i, eccsize = chip->ecc.size;
int eccbytes = chip->ecc.bytes; int eccbytes = chip->ecc.bytes;
int eccsteps = chip->ecc.steps; int eccsteps = chip->ecc.steps;
#endif
uint8_t *ecc_calc = chip->buffers->ecccalc; uint8_t *ecc_calc = chip->buffers->ecccalc;
const uint8_t *p = buf; const uint8_t *p = buf;
uint32_t *eccpos = chip->ecc.layout->eccpos; uint32_t *eccpos = chip->ecc.layout->eccpos;
...@@ -2457,9 +2476,11 @@ int nand_scan_tail(struct mtd_info *mtd) ...@@ -2457,9 +2476,11 @@ int nand_scan_tail(struct mtd_info *mtd)
switch (chip->ecc.mode) { switch (chip->ecc.mode) {
#ifdef CONFIG_NAND_FLASH_HW_ECC #ifdef CONFIG_NAND_FLASH_HW_ECC
case NAND_ECC_HW16_2048:
case NAND_ECC_HW12_2048: case NAND_ECC_HW12_2048:
case NAND_ECC_HW8_512: case NAND_ECC_HW8_512:
case NAND_ECC_HW6_512: case NAND_ECC_HW6_512:
case NAND_ECC_HW4_512:
case NAND_ECC_HW3_512: case NAND_ECC_HW3_512:
case NAND_ECC_HW3_256: case NAND_ECC_HW3_256:
#endif #endif
......
...@@ -1182,6 +1182,10 @@ config EFS_FS ...@@ -1182,6 +1182,10 @@ config EFS_FS
To compile the EFS file system support as a module, choose M here: the To compile the EFS file system support as a module, choose M here: the
module will be called efs. module will be called efs.
# Patched by YAFFS
source "fs/yaffs2/Kconfig"
config JFFS2_FS config JFFS2_FS
tristate "Journalling Flash File System v2 (JFFS2) support" tristate "Journalling Flash File System v2 (JFFS2) support"
select CRC32 select CRC32
......
...@@ -118,3 +118,6 @@ obj-$(CONFIG_HPPFS) += hppfs/ ...@@ -118,3 +118,6 @@ obj-$(CONFIG_HPPFS) += hppfs/
obj-$(CONFIG_DEBUG_FS) += debugfs/ obj-$(CONFIG_DEBUG_FS) += debugfs/
obj-$(CONFIG_OCFS2_FS) += ocfs2/ obj-$(CONFIG_OCFS2_FS) += ocfs2/
obj-$(CONFIG_GFS2_FS) += gfs2/ obj-$(CONFIG_GFS2_FS) += gfs2/
# Patched by YAFFS
obj-$(CONFIG_YAFFS_FS) += yaffs2/
#
# YAFFS file system configurations
#
config YAFFS_FS
tristate "YAFFS2 file system support"
default y
depends on MTD
select YAFFS_YAFFS1
select YAFFS_YAFFS2
help
YAFFS2, or Yet Another Flash Filing System, is a filing system
optimised for NAND Flash chips.
To compile the YAFFS2 file system support as a module, choose M
here: the module will be called yaffs2.
If unsure, say N.
Further information on YAFFS2 is available at
<http://www.aleph1.co.uk/yaffs/>.
config YAFFS_YAFFS1
bool "512 byte / page devices"
depends on YAFFS_FS
default y
help
Enable YAFFS1 support -- yaffs for 512 byte / page devices
Not needed for 2K-page devices.
If unsure, say Y.
config YAFFS_9BYTE_TAGS
bool "Use older-style on-NAND data format with pageStatus byte"
depends on YAFFS_YAFFS1
default n
help
Older-style on-NAND data format has a "pageStatus" byte to record
chunk/page state. This byte is zero when the page is discarded.
Choose this option if you have existing on-NAND data using this
format that you need to continue to support. New data written
also uses the older-style format. Note: Use of this option
generally requires that MTD's oob layout be adjusted to use the
older-style format. See notes on tags formats and MTD versions
in yaffs_mtdif1.c.
If unsure, say N.
config YAFFS_DOES_ECC
bool "Lets Yaffs do its own ECC"
depends on YAFFS_FS && YAFFS_YAFFS1 && !YAFFS_9BYTE_TAGS
default n
help
This enables Yaffs to use its own ECC functions instead of using
the ones from the generic MTD-NAND driver.
If unsure, say N.
config YAFFS_ECC_WRONG_ORDER
bool "Use the same ecc byte order as Steven Hill's nand_ecc.c"
depends on YAFFS_FS && YAFFS_DOES_ECC && !YAFFS_9BYTE_TAGS
default n
help
This makes yaffs_ecc.c use the same ecc byte order as Steven
Hill's nand_ecc.c. If not set, then you get the same ecc byte
order as SmartMedia.
If unsure, say N.
config YAFFS_YAFFS2
bool "2048 byte (or larger) / page devices"
depends on YAFFS_FS
default y
help
Enable YAFFS2 support -- yaffs for >= 2K bytes per page devices
If unsure, say Y.
config YAFFS_AUTO_YAFFS2
bool "Autoselect yaffs2 format"
depends on YAFFS_YAFFS2
default y
help
Without this, you need to explicitely use yaffs2 as the file
system type. With this, you can say "yaffs" and yaffs or yaffs2
will be used depending on the device page size (yaffs on
512-byte page devices, yaffs2 on 2K page devices).
If unsure, say Y.
config YAFFS_DISABLE_LAZY_LOAD
bool "Disable lazy loading"
depends on YAFFS_YAFFS2
default n
help
"Lazy loading" defers loading file details until they are
required. This saves mount time, but makes the first look-up
a bit longer.
Lazy loading will only happen if enabled by this option being 'n'
and if the appropriate tags are available, else yaffs2 will
automatically fall back to immediate loading and do the right
thing.
Lazy laoding will be required by checkpointing.
Setting this to 'y' will disable lazy loading.
If unsure, say N.
config YAFFS_DISABLE_WIDE_TNODES
bool "Turn off wide tnodes"
depends on YAFFS_FS
default n
help
Wide tnodes are only used for NAND arrays >=32MB for 512-byte
page devices and >=128MB for 2k page devices. They use slightly
more RAM but are faster since they eliminate chunk group
searching.
Setting this to 'y' will force tnode width to 16 bits and save
memory but make large arrays slower.
If unsure, say N.
config YAFFS_ALWAYS_CHECK_CHUNK_ERASED
bool "Force chunk erase check"
depends on YAFFS_FS
default n
help
Normally YAFFS only checks chunks before writing until an erased
chunk is found. This helps to detect any partially written
chunks that might have happened due to power loss.
Enabling this forces on the test that chunks are erased in flash
before writing to them. This takes more time but is potentially
a bit more secure.
Suggest setting Y during development and ironing out driver
issues etc. Suggest setting to N if you want faster writing.
If unsure, say Y.
config YAFFS_SHORT_NAMES_IN_RAM
bool "Cache short names in RAM"
depends on YAFFS_FS
default y
help
If this config is set, then short names are stored with the
yaffs_Object. This costs an extra 16 bytes of RAM per object,
but makes look-ups faster.
If unsure, say Y.
#
# Makefile for the linux YAFFS filesystem routines.
#
obj-$(CONFIG_YAFFS_FS) += yaffs.o
yaffs-y := yaffs_ecc.o yaffs_fs.o yaffs_guts.o yaffs_checkptrw.o
yaffs-y += yaffs_packedtags1.o yaffs_packedtags2.o yaffs_nand.o yaffs_qsort.o
yaffs-y += yaffs_tagscompat.o yaffs_tagsvalidity.o
yaffs-y += yaffs_mtdif.o yaffs_mtdif1.o yaffs_mtdif2.o
/*
* 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.
*/
/*
* This file is just holds extra declarations of macros that would normally
* be providesd in the Linux kernel. These macros have been written from
* scratch but are functionally equivalent to the Linux ones.
*
*/
#ifndef __EXTRAS_H__
#define __EXTRAS_H__
#if !(defined __KERNEL__)
/* Definition of types */
typedef unsigned char __u8;
typedef unsigned short __u16;
typedef unsigned __u32;
#endif
/*
* This is a simple doubly linked list implementation that matches the
* way the Linux kernel doubly linked list implementation works.
*/
struct ylist_head {
struct ylist_head *next; /* next in chain */
struct ylist_head *prev; /* previous in chain */
};
/* Initialise a list head to an empty list */
#define YINIT_LIST_HEAD(p) \
do { \
(p)->next = (p);\
(p)->prev = (p); \
} while(0)
/* Add an element to a list */
static __inline__ void ylist_add(struct ylist_head *newEntry,
struct ylist_head *list)
{
struct ylist_head *listNext = list->next;
list->next = newEntry;
newEntry->prev = list;
newEntry->next = listNext;
listNext->prev = newEntry;
}
/* Take an element out of its current list, with or without
* reinitialising the links.of the entry*/
static __inline__ void ylist_del(struct ylist_head *entry)
{
struct ylist_head *listNext = entry->next;
struct ylist_head *listPrev = entry->prev;
listNext->prev = listPrev;
listPrev->next = listNext;
}
static __inline__ void ylist_del_init(struct ylist_head *entry)
{
ylist_del(entry);
entry->next = entry->prev = entry;
}
/* Test if the list is empty */
static __inline__ int ylist_empty(struct ylist_head *entry)
{
return (entry->next == entry);
}
/* ylist_entry takes a pointer to a list entry and offsets it to that
* we can find a pointer to the object it is embedded in.
*/
#define ylist_entry(entry, type, member) \
((type *)((char *)(entry)-(unsigned long)(&((type *)NULL)->member)))
/* ylist_for_each and list_for_each_safe iterate over lists.
* ylist_for_each_safe uses temporary storage to make the list delete safe
*/
#define ylist_for_each(itervar, list) \
for (itervar = (list)->next; itervar != (list); itervar = itervar->next )
#define ylist_for_each_safe(itervar,saveVar, list) \
for (itervar = (list)->next, saveVar = (list)->next->next; itervar != (list); \
itervar = saveVar, saveVar = saveVar->next)
#if !(defined __KERNEL__)
#ifndef WIN32
#include <sys/stat.h>
#endif
#ifdef CONFIG_YAFFS_PROVIDE_DEFS
/* File types */
#define DT_UNKNOWN 0
#define DT_FIFO 1
#define DT_CHR 2
#define DT_DIR 4
#define DT_BLK 6
#define DT_REG 8
#define DT_LNK 10
#define DT_SOCK 12
#define DT_WHT 14
#ifndef WIN32
#include <sys/stat.h>
#endif
/*
* Attribute flags.
*/
#define ATTR_MODE 1
#define ATTR_UID 2
#define ATTR_GID 4
#define ATTR_SIZE 8
#define ATTR_ATIME 16
#define ATTR_MTIME 32
#define ATTR_CTIME 64
struct iattr {
unsigned int ia_valid;
unsigned ia_mode;
unsigned ia_uid;
unsigned ia_gid;
unsigned ia_size;
unsigned ia_atime;
unsigned ia_mtime;
unsigned ia_ctime;
unsigned int ia_attr_flags;
};
#endif
#define KERN_DEBUG
#else
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/stat.h>
#endif
#endif
/*
* 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 Martin Fouts <Martin.Fouts@palmsource.com>
*
* 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_CONFIG_H__
#define __YAFFS_CONFIG_H__
#ifdef YAFFS_OUT_OF_TREE
/* DO NOT UNSET THESE THREE. YAFFS2 will not compile if you do. */
#define CONFIG_YAFFS_FS
#define CONFIG_YAFFS_YAFFS1
#define CONFIG_YAFFS_YAFFS2
/* These options are independent of each other. Select those that matter. */
/* Default: Not selected */
/* Meaning: Yaffs does its own ECC, rather than using MTD ECC */
//#define CONFIG_YAFFS_DOES_ECC
/* Default: Not selected */
/* Meaning: ECC byte order is 'wrong'. Only meaningful if */
/* CONFIG_YAFFS_DOES_ECC is set */
//#define CONFIG_YAFFS_ECC_WRONG_ORDER
/* Default: Selected */
/* Meaning: Disables testing whether chunks are erased before writing to them*/
#define CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK
/* Default: Selected */
/* Meaning: Cache short names, taking more RAM, but faster look-ups */
#define CONFIG_YAFFS_SHORT_NAMES_IN_RAM
/* Default: 10 */
/* Meaning: set the count of blocks to reserve for checkpointing */
#define CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS 10
/*
Older-style on-NAND data format has a "pageStatus" byte to record
chunk/page state. This byte is zeroed when the page is discarded.
Choose this option if you have existing on-NAND data in this format
that you need to continue to support. New data written also uses the
older-style format.
Note: Use of this option generally requires that MTD's oob layout be
adjusted to use the older-style format. See notes on tags formats and
MTD versions in yaffs_mtdif1.c.
*/
/* Default: Not selected */
/* Meaning: Use older-style on-NAND data format with pageStatus byte */
//#define CONFIG_YAFFS_9BYTE_TAGS
#endif /* YAFFS_OUT_OF_TREE */
#endif /* __YAFFS_CONFIG_H__ */
#Makefile for mkyaffs
#
# NB this is not yet suitable for putting into the kernel tree.
# YAFFS: Yet another Flash File System. A NAND-flash specific file system.
#
# Copyright (C) 2002 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.
## Change or override KERNELDIR to your kernel
#KERNELDIR = /usr/src/kernel-headers-2.4.18
CFLAGS = -I/usr/include -I.. -O2 -Wall -DCONFIG_YAFFS_UTIL
CFLAGS+= -Wshadow -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Wmissing-declarations
CFLAGS+= -Wmissing-prototypes -Wredundant-decls -Wnested-externs -Winline
## Change if you are using a cross-compiler
MAKETOOLS =
CC=$(MAKETOOLS)gcc
COMMONLINKS = yaffs_ecc.c
COMMONOBJS = $(COMMONLINKS:.c=.o)
MKYAFFSSOURCES = mkyaffsimage.c
MKYAFFSIMAGEOBJS = $(MKYAFFSSOURCES:.c=.o)
MKYAFFS2SOURCES = mkyaffs2image.c
MKYAFFS2LINKS = yaffs_packedtags2.c yaffs_tagsvalidity.c
MKYAFFS2IMAGEOBJS = $(MKYAFFS2SOURCES:.c=.o) $(MKYAFFS2LINKS:.c=.o)
all: mkyaffsimage mkyaffs2image
$(COMMONLINKS) $(MKYAFFSLINKS) $(MKYAFFS2LINKS):
ln -s ../$@ $@
$(COMMONOBJS) $(MKYAFFSIMAGEOBJS) $(MKYAFFS2IMAGEOBJS) : %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
mkyaffsimage: $(COMMONOBJS) $(MKYAFFSIMAGEOBJS)
$(CC) -o $@ $(COMMONOBJS) $(MKYAFFSIMAGEOBJS)
mkyaffs2image: $(COMMONOBJS) $(MKYAFFS2IMAGEOBJS)
$(CC) -o $@ $(COMMONOBJS) $(MKYAFFS2IMAGEOBJS)
clean:
rm -f $(COMMONOBJS) $(MKYAFFSIMAGEOBJS) $(MKYAFFS2IMAGEOBJS) $(COMMONLINKS) $(MKYAFFSLINKS) $(MKYAFFS2LINKS) mkyaffsimage mkyaffs2image core
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* 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_CHECKPTRW_H__
#define __YAFFS_CHECKPTRW_H__
#include "yaffs_guts.h"
int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting);
int yaffs_CheckpointWrite(yaffs_Device *dev,const void *data, int nBytes);
int yaffs_CheckpointRead(yaffs_Device *dev,void *data, int nBytes);
int yaffs_GetCheckpointSum(yaffs_Device *dev, __u32 *sum);
int yaffs_CheckpointClose(yaffs_Device *dev);
int yaffs_CheckpointInvalidateStream(yaffs_Device *dev);
#endif
/*
* 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.
*/
/*
* This code implements the ECC algorithm used in SmartMedia.
*
* The ECC comprises 22 bits of parity information and is stuffed into 3 bytes.
* The two unused bit are set to 1.
* The ECC can correct single bit errors in a 256-byte page of data. Thus, two such ECC
* blocks are used on a 512-byte NAND page.
*
*/
/* Table generated by gen-ecc.c
* Using a table means we do not have to calculate p1..p4 and p1'..p4'
* for each byte of data. These are instead provided in a table in bits7..2.
* Bit 0 of each entry indicates whether the entry has an odd or even parity, and therefore
* this bytes influence on the line parity.
*/
const char *yaffs_ecc_c_version =
"$Id: yaffs_ecc.c,v 1.10 2007-12-13 15:35:17 wookey Exp $";
#include "yportenv.h"
#include "yaffs_ecc.h"
static const unsigned char column_parity_table[] = {
0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69,
0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00,
0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc,
0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95,
0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0,
0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99,
0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65,
0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c,
0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc,
0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5,
0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59,
0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30,
0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55,
0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c,
0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0,
0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9,
0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0,
0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9,
0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55,
0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c,
0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59,
0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30,
0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc,
0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5,
0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65,
0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c,
0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0,
0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99,
0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc,
0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95,
0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69,
0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00,
};
/* Count the bits in an unsigned char or a U32 */
static int yaffs_CountBits(unsigned char x)
{
int r = 0;
while (x) {
if (x & 1)
r++;
x >>= 1;
}
return r;
}
static int yaffs_CountBits32(unsigned x)
{
int r = 0;
while (x) {
if (x & 1)
r++;
x >>= 1;
}
return r;
}
/* Calculate the ECC for a 256-byte block of data */
void yaffs_ECCCalculate(const unsigned char *data, unsigned char *ecc)
{
unsigned int i;
unsigned char col_parity = 0;
unsigned char line_parity = 0;
unsigned char line_parity_prime = 0;
unsigned char t;
unsigned char b;
for (i = 0; i < 256; i++) {
b = column_parity_table[*data++];
col_parity ^= b;
if (b & 0x01) // odd number of bits in the byte
{
line_parity ^= i;
line_parity_prime ^= ~i;
}
}
ecc[2] = (~col_parity) | 0x03;
t = 0;
if (line_parity & 0x80)
t |= 0x80;
if (line_parity_prime & 0x80)
t |= 0x40;
if (line_parity & 0x40)
t |= 0x20;
if (line_parity_prime & 0x40)
t |= 0x10;
if (line_parity & 0x20)
t |= 0x08;
if (line_parity_prime & 0x20)
t |= 0x04;
if (line_parity & 0x10)
t |= 0x02;
if (line_parity_prime & 0x10)
t |= 0x01;
ecc[1] = ~t;
t = 0;
if (line_parity & 0x08)
t |= 0x80;
if (line_parity_prime & 0x08)
t |= 0x40;
if (line_parity & 0x04)
t |= 0x20;
if (line_parity_prime & 0x04)
t |= 0x10;
if (line_parity & 0x02)
t |= 0x08;
if (line_parity_prime & 0x02)
t |= 0x04;
if (line_parity & 0x01)
t |= 0x02;
if (line_parity_prime & 0x01)
t |= 0x01;
ecc[0] = ~t;
#ifdef CONFIG_YAFFS_ECC_WRONG_ORDER
// Swap the bytes into the wrong order
t = ecc[0];
ecc[0] = ecc[1];
ecc[1] = t;
#endif
}
/* Correct the ECC on a 256 byte block of data */
int yaffs_ECCCorrect(unsigned char *data, unsigned char *read_ecc,
const unsigned char *test_ecc)
{
unsigned char d0, d1, d2; /* deltas */
d0 = read_ecc[0] ^ test_ecc[0];
d1 = read_ecc[1] ^ test_ecc[1];
d2 = read_ecc[2] ^ test_ecc[2];
if ((d0 | d1 | d2) == 0)
return 0; /* no error */
if (((d0 ^ (d0 >> 1)) & 0x55) == 0x55 &&
((d1 ^ (d1 >> 1)) & 0x55) == 0x55 &&
((d2 ^ (d2 >> 1)) & 0x54) == 0x54) {
/* Single bit (recoverable) error in data */
unsigned byte;
unsigned bit;
#ifdef CONFIG_YAFFS_ECC_WRONG_ORDER
// swap the bytes to correct for the wrong order
unsigned char t;
t = d0;
d0 = d1;
d1 = t;
#endif
bit = byte = 0;
if (d1 & 0x80)
byte |= 0x80;
if (d1 & 0x20)
byte |= 0x40;
if (d1 & 0x08)
byte |= 0x20;
if (d1 & 0x02)
byte |= 0x10;
if (d0 & 0x80)
byte |= 0x08;
if (d0 & 0x20)
byte |= 0x04;
if (d0 & 0x08)
byte |= 0x02;
if (d0 & 0x02)
byte |= 0x01;
if (d2 & 0x80)
bit |= 0x04;
if (d2 & 0x20)
bit |= 0x02;
if (d2 & 0x08)
bit |= 0x01;
data[byte] ^= (1 << bit);
return 1; /* Corrected the error */
}
if ((yaffs_CountBits(d0) +
yaffs_CountBits(d1) +
yaffs_CountBits(d2)) == 1) {
/* Reccoverable error in ecc */
read_ecc[0] = test_ecc[0];
read_ecc[1] = test_ecc[1];
read_ecc[2] = test_ecc[2];
return 1; /* Corrected the error */
}
/* Unrecoverable error */
return -1;
}
/*
* ECCxxxOther does ECC calcs on arbitrary n bytes of data
*/
void yaffs_ECCCalculateOther(const unsigned char *data, unsigned nBytes,
yaffs_ECCOther * eccOther)
{
unsigned int i;
unsigned char col_parity = 0;
unsigned line_parity = 0;
unsigned line_parity_prime = 0;
unsigned char b;
for (i = 0; i < nBytes; i++) {
b = column_parity_table[*data++];
col_parity ^= b;
if (b & 0x01) {
/* odd number of bits in the byte */
line_parity ^= i;
line_parity_prime ^= ~i;
}
}
eccOther->colParity = (col_parity >> 2) & 0x3f;
eccOther->lineParity = line_parity;
eccOther->lineParityPrime = line_parity_prime;
}
int yaffs_ECCCorrectOther(unsigned char *data, unsigned nBytes,
yaffs_ECCOther * read_ecc,
const yaffs_ECCOther * test_ecc)
{
unsigned char cDelta; /* column parity delta */
unsigned lDelta; /* line parity delta */
unsigned lDeltaPrime; /* line parity delta */
unsigned bit;
cDelta = read_ecc->colParity ^ test_ecc->colParity;
lDelta = read_ecc->lineParity ^ test_ecc->lineParity;
lDeltaPrime = read_ecc->lineParityPrime ^ test_ecc->lineParityPrime;
if ((cDelta | lDelta | lDeltaPrime) == 0)
return 0; /* no error */
if (lDelta == ~lDeltaPrime &&
(((cDelta ^ (cDelta >> 1)) & 0x15) == 0x15))
{
/* Single bit (recoverable) error in data */
bit = 0;
if (cDelta & 0x20)
bit |= 0x04;
if (cDelta & 0x08)
bit |= 0x02;
if (cDelta & 0x02)
bit |= 0x01;
if(lDelta >= nBytes)
return -1;
data[lDelta] ^= (1 << bit);
return 1; /* corrected */
}
if ((yaffs_CountBits32(lDelta) + yaffs_CountBits32(lDeltaPrime) +
yaffs_CountBits(cDelta)) == 1) {
/* Reccoverable error in ecc */
*read_ecc = *test_ecc;
return 1; /* corrected */
}
/* Unrecoverable error */
return -1;
}
/*
* 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.
*/
/*
* This code implements the ECC algorithm used in SmartMedia.
*
* The ECC comprises 22 bits of parity information and is stuffed into 3 bytes.
* The two unused bit are set to 1.
* The ECC can correct single bit errors in a 256-byte page of data. Thus, two such ECC
* blocks are used on a 512-byte NAND page.
*
*/
#ifndef __YAFFS_ECC_H__
#define __YAFFS_ECC_H__
typedef struct {
unsigned char colParity;
unsigned lineParity;
unsigned lineParityPrime;
} yaffs_ECCOther;
void yaffs_ECCCalculate(const unsigned char *data, unsigned char *ecc);
int yaffs_ECCCorrect(unsigned char *data, unsigned char *read_ecc,
const unsigned char *test_ecc);
void yaffs_ECCCalculateOther(const unsigned char *data, unsigned nBytes,
yaffs_ECCOther * ecc);
int yaffs_ECCCorrectOther(unsigned char *data, unsigned nBytes,
yaffs_ECCOther * read_ecc,
const yaffs_ECCOther * test_ecc);
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* 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_QSORT_H__
#define __YAFFS_QSORT_H__
extern void yaffs_qsort (void *const base, size_t total_elems, size_t size,
int (*cmp)(const void *, const void *));
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment