Commit 762a79f1 authored by 邱宗炽's avatar 邱宗炽

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 bdf0fabd b354104b
......@@ -1203,6 +1203,16 @@ CONFIG_RAMFS=y
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_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_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
......
......@@ -1182,6 +1182,10 @@ config EFS_FS
To compile the EFS file system support as a module, choose M here: the
module will be called efs.
# Patched by YAFFS
source "fs/yaffs2/Kconfig"
config JFFS2_FS
tristate "Journalling Flash File System v2 (JFFS2) support"
select CRC32
......
......@@ -118,3 +118,6 @@ obj-$(CONFIG_HPPFS) += hppfs/
obj-$(CONFIG_DEBUG_FS) += debugfs/
obj-$(CONFIG_OCFS2_FS) += ocfs2/
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.
/*
* 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_GETBLOCKINFO_H__
#define __YAFFS_GETBLOCKINFO_H__
#include "yaffs_guts.h"
/* Function to manipulate block info */
static Y_INLINE yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device * dev, int blk)
{
if (blk < dev->internalStartBlock || blk > dev->internalEndBlock) {
T(YAFFS_TRACE_ERROR,
(TSTR
("**>> yaffs: getBlockInfo block %d is not valid" TENDSTR),
blk));
YBUG();
}
return &dev->blockInfo[blk - dev->internalStartBlock];
}
#endif
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_MTDIF_H__
#define __YAFFS_MTDIF_H__
#include "yaffs_guts.h"
#if (MTD_VERSION_CODE < MTD_VERSION(2,6,18))
extern struct nand_oobinfo yaffs_oobinfo;
extern struct nand_oobinfo yaffs_noeccinfo;
#endif
int nandmtd_WriteChunkToNAND(yaffs_Device * dev, int chunkInNAND,
const __u8 * data, const yaffs_Spare * spare);
int nandmtd_ReadChunkFromNAND(yaffs_Device * dev, int chunkInNAND, __u8 * data,
yaffs_Spare * spare);
int nandmtd_EraseBlockInNAND(yaffs_Device * dev, int blockNumber);
int nandmtd_InitialiseNAND(yaffs_Device * dev);
#endif
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
*
* 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_MTDIF1_H__
#define __YAFFS_MTDIF1_H__
int nandmtd1_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND,
const __u8 * data, const yaffs_ExtendedTags * tags);
int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
__u8 * data, yaffs_ExtendedTags * tags);
int nandmtd1_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo);
int nandmtd1_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
yaffs_BlockState * state, int *sequenceNumber);
#endif
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_MTDIF2_H__
#define __YAFFS_MTDIF2_H__
#include "yaffs_guts.h"
int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND,
const __u8 * data,
const yaffs_ExtendedTags * tags);
int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
__u8 * data, yaffs_ExtendedTags * tags);
int nandmtd2_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo);
int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
yaffs_BlockState * state, int *sequenceNumber);
#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.
*/
const char *yaffs_nand_c_version =
"$Id: yaffs_nand.c,v 1.9 2008-05-05 07:58:58 charles Exp $";
#include "yaffs_nand.h"
#include "yaffs_tagscompat.h"
#include "yaffs_tagsvalidity.h"
#include "yaffs_getblockinfo.h"
int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
__u8 * buffer,
yaffs_ExtendedTags * tags)
{
int result;
yaffs_ExtendedTags localTags;
int realignedChunkInNAND = chunkInNAND - dev->chunkOffset;
/* If there are no tags provided, use local tags to get prioritised gc working */
if(!tags)
tags = &localTags;
if (dev->readChunkWithTagsFromNAND)
result = dev->readChunkWithTagsFromNAND(dev, realignedChunkInNAND, buffer,
tags);
else
result = yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(dev,
realignedChunkInNAND,
buffer,
tags);
if(tags &&
tags->eccResult > YAFFS_ECC_RESULT_NO_ERROR){
yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, chunkInNAND/dev->nChunksPerBlock);
yaffs_HandleChunkError(dev,bi);
}
return result;
}
int yaffs_WriteChunkWithTagsToNAND(yaffs_Device * dev,
int chunkInNAND,
const __u8 * buffer,
yaffs_ExtendedTags * tags)
{
chunkInNAND -= dev->chunkOffset;
if (tags) {
tags->sequenceNumber = dev->sequenceNumber;
tags->chunkUsed = 1;
if (!yaffs_ValidateTags(tags)) {
T(YAFFS_TRACE_ERROR,
(TSTR("Writing uninitialised tags" TENDSTR)));
YBUG();
}
T(YAFFS_TRACE_WRITE,
(TSTR("Writing chunk %d tags %d %d" TENDSTR), chunkInNAND,
tags->objectId, tags->chunkId));
} else {
T(YAFFS_TRACE_ERROR, (TSTR("Writing with no tags" TENDSTR)));
YBUG();
}
if (dev->writeChunkWithTagsToNAND)
return dev->writeChunkWithTagsToNAND(dev, chunkInNAND, buffer,
tags);
else
return yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(dev,
chunkInNAND,
buffer,
tags);
}
int yaffs_MarkBlockBad(yaffs_Device * dev, int blockNo)
{
blockNo -= dev->blockOffset;
;
if (dev->markNANDBlockBad)
return dev->markNANDBlockBad(dev, blockNo);
else
return yaffs_TagsCompatabilityMarkNANDBlockBad(dev, blockNo);
}
int yaffs_QueryInitialBlockState(yaffs_Device * dev,
int blockNo,
yaffs_BlockState * state,
__u32 *sequenceNumber)
{
blockNo -= dev->blockOffset;
if (dev->queryNANDBlock)
return dev->queryNANDBlock(dev, blockNo, state, sequenceNumber);
else
return yaffs_TagsCompatabilityQueryNANDBlock(dev, blockNo,
state,
sequenceNumber);
}
int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,
int blockInNAND)
{
int result;
blockInNAND -= dev->blockOffset;
dev->nBlockErasures++;
result = dev->eraseBlockInNAND(dev, blockInNAND);
return result;
}
int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev)
{
return dev->initialiseNAND(dev);
}
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.
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