generic: fold yaffs_cvs_2009_04_24 patch to generic/files

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>

SVN-Revision: 34012
This commit is contained in:
Gabor Juhos 2012-10-30 14:58:13 +00:00
parent 73c75e0dd8
commit 56190ed0fc
35 changed files with 3171 additions and 27531 deletions

View file

@ -5,7 +5,7 @@
config YAFFS_FS
tristate "YAFFS2 file system support"
default n
depends on MTD
depends on MTD_BLOCK
select YAFFS_YAFFS1
select YAFFS_YAFFS2
help
@ -43,7 +43,8 @@ config YAFFS_9BYTE_TAGS
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.
older-style format. See notes on tags formats and MTD versions
in yaffs_mtdif1.c.
If unsure, say N.
@ -109,26 +110,6 @@ config YAFFS_DISABLE_LAZY_LOAD
If unsure, say N.
config YAFFS_CHECKPOINT_RESERVED_BLOCKS
int "Reserved blocks for checkpointing"
depends on YAFFS_YAFFS2
default 10
help
Give the number of Blocks to reserve for checkpointing.
Checkpointing saves the state at unmount so that mounting is
much faster as a scan of all the flash to regenerate this state
is not needed. These Blocks are reserved per partition, so if
you have very small partitions the default (10) may be a mess
for you. You can set this value to 0, but that does not mean
checkpointing is disabled at all. There only won't be any
specially reserved blocks for checkpointing, so if there is
enough free space on the filesystem, it will be used for
checkpointing.
If unsure, leave at default (10), but don't wonder if there are
always 2MB used on your large page device partition (10 x 2k
pagesize). When using small partitions or when being very small
on space, you probably want to set this to zero.
config YAFFS_DISABLE_WIDE_TNODES
bool "Turn off wide tnodes"

View file

@ -5,7 +5,6 @@
obj-$(CONFIG_YAFFS_FS) += yaffs.o
yaffs-y := yaffs_ecc.o yaffs_fs.o yaffs_guts.o yaffs_checkptrw.o
yaffs-y += yaffs_packedtags2.o yaffs_nand.o yaffs_qsort.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_mtdif1.o yaffs_packedtags1.o
yaffs-y += yaffs_mtdif.o yaffs_mtdif2.o
yaffs-y += yaffs_mtdif.o yaffs_mtdif1.o yaffs_mtdif2.o

View file

@ -0,0 +1,4 @@
The yaffs2 source has been fetched from the yaffs2 CVS tree.
URL: cvs.aleph1.co.uk
Version: 2009-09-24

View file

@ -14,194 +14,135 @@
*/
/*
* This file is just holds extra declarations used during development.
* Most of these are from kernel includes placed here so we can use them in
* applications.
* 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 WIN32
#define __inline__ __inline
#define new newHack
#endif
#if !(defined __KERNEL__) || (defined WIN32)
/* User space defines */
#if !(defined __KERNEL__)
/* Definition of types */
typedef unsigned char __u8;
typedef unsigned short __u16;
typedef unsigned __u32;
#endif
/*
* Simple doubly linked list implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole lists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
* This is a simple doubly linked list implementation that matches the
* way the Linux kernel doubly linked list implementation works.
*/
#define prefetch(x) 1
struct list_head {
struct list_head *next, *prev;
struct ylist_head {
struct ylist_head *next; /* next in chain */
struct ylist_head *prev; /* previous in chain */
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
/* Initialise a static list */
#define YLIST_HEAD(name) \
struct ylist_head name = { &(name), &(name)}
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
/* Initialise a list head to an empty list */
#define YINIT_LIST_HEAD(p) \
do { \
(p)->next = (p);\
(p)->prev = (p); \
} while (0)
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static __inline__ void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
/* Add an element to a list */
static __inline__ void ylist_add(struct ylist_head *newEntry,
struct ylist_head *list)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
struct ylist_head *listNext = list->next;
list->next = newEntry;
newEntry->prev = list;
newEntry->next = listNext;
listNext->prev = newEntry;
}
/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static __inline__ void list_add(struct list_head *new, struct list_head *head)
static __inline__ void ylist_add_tail(struct ylist_head *newEntry,
struct ylist_head *list)
{
__list_add(new, head, head->next);
struct ylist_head *listPrev = list->prev;
list->prev = newEntry;
newEntry->next = list;
newEntry->prev = listPrev;
listPrev->next = newEntry;
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static __inline__ void list_add_tail(struct list_head *new,
struct list_head *head)
/* 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)
{
__list_add(new, head->prev, head);
struct ylist_head *listNext = entry->next;
struct ylist_head *listPrev = entry->prev;
listNext->prev = listPrev;
listPrev->next = listNext;
}
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static __inline__ void __list_del(struct list_head *prev,
struct list_head *next)
static __inline__ void ylist_del_init(struct ylist_head *entry)
{
next->prev = prev;
prev->next = next;
ylist_del(entry);
entry->next = entry->prev = entry;
}
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty on entry does not return true after this, the entry is
* in an undefined state.
*/
static __inline__ void list_del(struct list_head *entry)
/* Test if the list is empty */
static __inline__ int ylist_empty(struct ylist_head *entry)
{
__list_del(entry->prev, entry->next);
return (entry->next == entry);
}
/**
* list_del_init - deletes entry from list and reinitialize it.
* @entry: the element to delete from the list.
/* 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.
*/
static __inline__ void list_del_init(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
#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
*/
static __inline__ int list_empty(struct list_head *head)
{
return head->next == head;
}
/**
* list_splice - join two lists
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static __inline__ void list_splice(struct list_head *list,
struct list_head *head)
{
struct list_head *first = list->next;
#define ylist_for_each(itervar, list) \
for (itervar = (list)->next; itervar != (list); itervar = itervar->next)
if (first != list) {
struct list_head *last = list->prev;
struct list_head *at = head->next;
#define ylist_for_each_safe(itervar, saveVar, list) \
for (itervar = (list)->next, saveVar = (list)->next->next; \
itervar != (list); itervar = saveVar, saveVar = saveVar->next)
first->prev = head;
head->next = first;
last->next = at;
at->prev = last;
}
}
#if !(defined __KERNEL__)
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next, prefetch(pos->next); pos != (head); \
pos = pos->next, prefetch(pos->next))
#ifndef WIN32
#include <sys/stat.h>
#endif
#ifdef CONFIG_YAFFS_PROVIDE_DEFS
/* File types */
/**
* list_for_each_safe - iterate over a list safe against removal
* of list entry
* @pos: the &struct list_head to use as a loop counter.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
/*
* File types
*/
#define DT_UNKNOWN 0
#define DT_FIFO 1
#define DT_CHR 2
@ -212,6 +153,7 @@ static __inline__ void list_splice(struct list_head *list,
#define DT_SOCK 12
#define DT_WHT 14
#ifndef WIN32
#include <sys/stat.h>
#endif
@ -227,10 +169,6 @@ static __inline__ void list_splice(struct list_head *list,
#define ATTR_ATIME 16
#define ATTR_MTIME 32
#define ATTR_CTIME 64
#define ATTR_ATIME_SET 128
#define ATTR_MTIME_SET 256
#define ATTR_FORCE 512 /* Not a change, but a change it */
#define ATTR_ATTR_FLAG 1024
struct iattr {
unsigned int ia_valid;
@ -244,21 +182,15 @@ struct iattr {
unsigned int ia_attr_flags;
};
#define KERN_DEBUG
#endif
#else
#ifndef WIN32
#include <linux/types.h>
#include <linux/list.h>
#include <linux/fs.h>
#include <linux/stat.h>
#endif
#endif
#if defined WIN32
#undef new
#endif
#endif

View file

@ -27,12 +27,12 @@
/* Default: Not selected */
/* Meaning: Yaffs does its own ECC, rather than using MTD ECC */
//#define CONFIG_YAFFS_DOES_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
/* #define CONFIG_YAFFS_ECC_WRONG_ORDER */
/* Default: Selected */
/* Meaning: Disables testing whether chunks are erased before writing to them*/
@ -54,11 +54,11 @@ 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.
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
/* #define CONFIG_YAFFS_9BYTE_TAGS */
#endif /* YAFFS_OUT_OF_TREE */

View file

@ -12,48 +12,43 @@
*/
const char *yaffs_checkptrw_c_version =
"$Id: yaffs_checkptrw.c,v 1.14 2007-05-15 20:07:40 charles Exp $";
"$Id: yaffs_checkptrw.c,v 1.18 2009-03-06 17:20:49 wookey Exp $";
#include "yaffs_checkptrw.h"
#include "yaffs_getblockinfo.h"
static int yaffs_CheckpointSpaceOk(yaffs_Device *dev)
{
int blocksAvailable = dev->nErasedBlocks - dev->nReservedBlocks;
T(YAFFS_TRACE_CHECKPOINT,
(TSTR("checkpt blocks available = %d" TENDSTR),
blocksAvailable));
return (blocksAvailable <= 0) ? 0 : 1;
}
static int yaffs_CheckpointErase(yaffs_Device *dev)
{
int i;
if(!dev->eraseBlockInNAND)
if (!dev->eraseBlockInNAND)
return 0;
T(YAFFS_TRACE_CHECKPOINT,(TSTR("checking blocks %d to %d"TENDSTR),
dev->internalStartBlock,dev->internalEndBlock));
T(YAFFS_TRACE_CHECKPOINT, (TSTR("checking blocks %d to %d"TENDSTR),
dev->internalStartBlock, dev->internalEndBlock));
for(i = dev->internalStartBlock; i <= dev->internalEndBlock; i++) {
yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,i);
if(bi->blockState == YAFFS_BLOCK_STATE_CHECKPOINT){
T(YAFFS_TRACE_CHECKPOINT,(TSTR("erasing checkpt block %d"TENDSTR),i));
if(dev->eraseBlockInNAND(dev,i- dev->blockOffset /* realign */)){
for (i = dev->internalStartBlock; i <= dev->internalEndBlock; i++) {
yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, i);
if (bi->blockState == YAFFS_BLOCK_STATE_CHECKPOINT) {
T(YAFFS_TRACE_CHECKPOINT, (TSTR("erasing checkpt block %d"TENDSTR), i));
if (dev->eraseBlockInNAND(dev, i - dev->blockOffset /* realign */)) {
bi->blockState = YAFFS_BLOCK_STATE_EMPTY;
dev->nErasedBlocks++;
dev->nFreeChunks += dev->nChunksPerBlock;
}
else {
dev->markNANDBlockBad(dev,i);
} else {
dev->markNANDBlockBad(dev, i);
bi->blockState = YAFFS_BLOCK_STATE_DEAD;
}
}
@ -71,23 +66,23 @@ static void yaffs_CheckpointFindNextErasedBlock(yaffs_Device *dev)
int blocksAvailable = dev->nErasedBlocks - dev->nReservedBlocks;
T(YAFFS_TRACE_CHECKPOINT,
(TSTR("allocating checkpt block: erased %d reserved %d avail %d next %d "TENDSTR),
dev->nErasedBlocks,dev->nReservedBlocks,blocksAvailable,dev->checkpointNextBlock));
dev->nErasedBlocks, dev->nReservedBlocks, blocksAvailable, dev->checkpointNextBlock));
if(dev->checkpointNextBlock >= 0 &&
dev->checkpointNextBlock <= dev->internalEndBlock &&
blocksAvailable > 0){
if (dev->checkpointNextBlock >= 0 &&
dev->checkpointNextBlock <= dev->internalEndBlock &&
blocksAvailable > 0) {
for(i = dev->checkpointNextBlock; i <= dev->internalEndBlock; i++){
yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,i);
if(bi->blockState == YAFFS_BLOCK_STATE_EMPTY){
for (i = dev->checkpointNextBlock; i <= dev->internalEndBlock; i++) {
yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, i);
if (bi->blockState == YAFFS_BLOCK_STATE_EMPTY) {
dev->checkpointNextBlock = i + 1;
dev->checkpointCurrentBlock = i;
T(YAFFS_TRACE_CHECKPOINT,(TSTR("allocating checkpt block %d"TENDSTR),i));
T(YAFFS_TRACE_CHECKPOINT, (TSTR("allocating checkpt block %d"TENDSTR), i));
return;
}
}
}
T(YAFFS_TRACE_CHECKPOINT,(TSTR("out of checkpt blocks"TENDSTR)));
T(YAFFS_TRACE_CHECKPOINT, (TSTR("out of checkpt blocks"TENDSTR)));
dev->checkpointNextBlock = -1;
dev->checkpointCurrentBlock = -1;
@ -98,30 +93,31 @@ static void yaffs_CheckpointFindNextCheckpointBlock(yaffs_Device *dev)
int i;
yaffs_ExtendedTags tags;
T(YAFFS_TRACE_CHECKPOINT,(TSTR("find next checkpt block: start: blocks %d next %d" TENDSTR),
T(YAFFS_TRACE_CHECKPOINT, (TSTR("find next checkpt block: start: blocks %d next %d" TENDSTR),
dev->blocksInCheckpoint, dev->checkpointNextBlock));
if(dev->blocksInCheckpoint < dev->checkpointMaxBlocks)
for(i = dev->checkpointNextBlock; i <= dev->internalEndBlock; i++){
if (dev->blocksInCheckpoint < dev->checkpointMaxBlocks)
for (i = dev->checkpointNextBlock; i <= dev->internalEndBlock; i++) {
int chunk = i * dev->nChunksPerBlock;
int realignedChunk = chunk - dev->chunkOffset;
dev->readChunkWithTagsFromNAND(dev,realignedChunk,NULL,&tags);
T(YAFFS_TRACE_CHECKPOINT,(TSTR("find next checkpt block: search: block %d oid %d seq %d eccr %d" TENDSTR),
i, tags.objectId,tags.sequenceNumber,tags.eccResult));
dev->readChunkWithTagsFromNAND(dev, realignedChunk,
NULL, &tags);
T(YAFFS_TRACE_CHECKPOINT, (TSTR("find next checkpt block: search: block %d oid %d seq %d eccr %d" TENDSTR),
i, tags.objectId, tags.sequenceNumber, tags.eccResult));
if(tags.sequenceNumber == YAFFS_SEQUENCE_CHECKPOINT_DATA){
if (tags.sequenceNumber == YAFFS_SEQUENCE_CHECKPOINT_DATA) {
/* Right kind of block */
dev->checkpointNextBlock = tags.objectId;
dev->checkpointCurrentBlock = i;
dev->checkpointBlockList[dev->blocksInCheckpoint] = i;
dev->blocksInCheckpoint++;
T(YAFFS_TRACE_CHECKPOINT,(TSTR("found checkpt block %d"TENDSTR),i));
T(YAFFS_TRACE_CHECKPOINT, (TSTR("found checkpt block %d"TENDSTR), i));
return;
}
}
T(YAFFS_TRACE_CHECKPOINT,(TSTR("found no more checkpt blocks"TENDSTR)));
T(YAFFS_TRACE_CHECKPOINT, (TSTR("found no more checkpt blocks"TENDSTR)));
dev->checkpointNextBlock = -1;
dev->checkpointCurrentBlock = -1;
@ -133,17 +129,17 @@ int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting)
/* Got the functions we need? */
if (!dev->writeChunkWithTagsToNAND ||
!dev->readChunkWithTagsFromNAND ||
!dev->eraseBlockInNAND ||
!dev->markNANDBlockBad)
!dev->readChunkWithTagsFromNAND ||
!dev->eraseBlockInNAND ||
!dev->markNANDBlockBad)
return 0;
if(forWriting && !yaffs_CheckpointSpaceOk(dev))
if (forWriting && !yaffs_CheckpointSpaceOk(dev))
return 0;
if(!dev->checkpointBuffer)
dev->checkpointBuffer = YMALLOC_DMA(dev->nDataBytesPerChunk);
if(!dev->checkpointBuffer)
if (!dev->checkpointBuffer)
dev->checkpointBuffer = YMALLOC_DMA(dev->totalBytesPerChunk);
if (!dev->checkpointBuffer)
return 0;
@ -159,12 +155,10 @@ int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting)
dev->checkpointNextBlock = dev->internalStartBlock;
/* Erase all the blocks in the checkpoint area */
if(forWriting){
memset(dev->checkpointBuffer,0,dev->nDataBytesPerChunk);
if (forWriting) {
memset(dev->checkpointBuffer, 0, dev->nDataBytesPerChunk);
dev->checkpointByteOffset = 0;
return yaffs_CheckpointErase(dev);
} else {
int i;
/* Set to a value that will kick off a read */
@ -174,7 +168,7 @@ int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting)
dev->blocksInCheckpoint = 0;
dev->checkpointMaxBlocks = (dev->internalEndBlock - dev->internalStartBlock)/16 + 2;
dev->checkpointBlockList = YMALLOC(sizeof(int) * dev->checkpointMaxBlocks);
for(i = 0; i < dev->checkpointMaxBlocks; i++)
for (i = 0; i < dev->checkpointMaxBlocks; i++)
dev->checkpointBlockList[i] = -1;
}
@ -191,18 +185,17 @@ int yaffs_GetCheckpointSum(yaffs_Device *dev, __u32 *sum)
static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
{
int chunk;
int realignedChunk;
yaffs_ExtendedTags tags;
if(dev->checkpointCurrentBlock < 0){
if (dev->checkpointCurrentBlock < 0) {
yaffs_CheckpointFindNextErasedBlock(dev);
dev->checkpointCurrentChunk = 0;
}
if(dev->checkpointCurrentBlock < 0)
if (dev->checkpointCurrentBlock < 0)
return 0;
tags.chunkDeleted = 0;
@ -210,10 +203,10 @@ static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
tags.chunkId = dev->checkpointPageSequence + 1;
tags.sequenceNumber = YAFFS_SEQUENCE_CHECKPOINT_DATA;
tags.byteCount = dev->nDataBytesPerChunk;
if(dev->checkpointCurrentChunk == 0){
if (dev->checkpointCurrentChunk == 0) {
/* First chunk we write for the block? Set block state to
checkpoint */
yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,dev->checkpointCurrentBlock);
yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, dev->checkpointCurrentBlock);
bi->blockState = YAFFS_BLOCK_STATE_CHECKPOINT;
dev->blocksInCheckpoint++;
}
@ -221,28 +214,29 @@ static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
chunk = dev->checkpointCurrentBlock * dev->nChunksPerBlock + dev->checkpointCurrentChunk;
T(YAFFS_TRACE_CHECKPOINT,(TSTR("checkpoint wite buffer nand %d(%d:%d) objid %d chId %d" TENDSTR),
chunk, dev->checkpointCurrentBlock, dev->checkpointCurrentChunk,tags.objectId,tags.chunkId));
T(YAFFS_TRACE_CHECKPOINT, (TSTR("checkpoint wite buffer nand %d(%d:%d) objid %d chId %d" TENDSTR),
chunk, dev->checkpointCurrentBlock, dev->checkpointCurrentChunk, tags.objectId, tags.chunkId));
realignedChunk = chunk - dev->chunkOffset;
dev->writeChunkWithTagsToNAND(dev,realignedChunk,dev->checkpointBuffer,&tags);
dev->writeChunkWithTagsToNAND(dev, realignedChunk,
dev->checkpointBuffer, &tags);
dev->checkpointByteOffset = 0;
dev->checkpointPageSequence++;
dev->checkpointCurrentChunk++;
if(dev->checkpointCurrentChunk >= dev->nChunksPerBlock){
if (dev->checkpointCurrentChunk >= dev->nChunksPerBlock) {
dev->checkpointCurrentChunk = 0;
dev->checkpointCurrentBlock = -1;
}
memset(dev->checkpointBuffer,0,dev->nDataBytesPerChunk);
memset(dev->checkpointBuffer, 0, dev->nDataBytesPerChunk);
return 1;
}
int yaffs_CheckpointWrite(yaffs_Device *dev,const void *data, int nBytes)
int yaffs_CheckpointWrite(yaffs_Device *dev, const void *data, int nBytes)
{
int i=0;
int i = 0;
int ok = 1;
@ -250,17 +244,14 @@ int yaffs_CheckpointWrite(yaffs_Device *dev,const void *data, int nBytes)
if(!dev->checkpointBuffer)
if (!dev->checkpointBuffer)
return 0;
if(!dev->checkpointOpenForWrite)
if (!dev->checkpointOpenForWrite)
return -1;
while(i < nBytes && ok) {
dev->checkpointBuffer[dev->checkpointByteOffset] = *dataBytes ;
while (i < nBytes && ok) {
dev->checkpointBuffer[dev->checkpointByteOffset] = *dataBytes;
dev->checkpointSum += *dataBytes;
dev->checkpointXor ^= *dataBytes;
@ -270,18 +261,17 @@ int yaffs_CheckpointWrite(yaffs_Device *dev,const void *data, int nBytes)
dev->checkpointByteCount++;
if(dev->checkpointByteOffset < 0 ||
if (dev->checkpointByteOffset < 0 ||
dev->checkpointByteOffset >= dev->nDataBytesPerChunk)
ok = yaffs_CheckpointFlushBuffer(dev);
}
return i;
return i;
}
int yaffs_CheckpointRead(yaffs_Device *dev, void *data, int nBytes)
{
int i=0;
int i = 0;
int ok = 1;
yaffs_ExtendedTags tags;
@ -291,52 +281,54 @@ int yaffs_CheckpointRead(yaffs_Device *dev, void *data, int nBytes)
__u8 *dataBytes = (__u8 *)data;
if(!dev->checkpointBuffer)
if (!dev->checkpointBuffer)
return 0;
if(dev->checkpointOpenForWrite)
if (dev->checkpointOpenForWrite)
return -1;
while(i < nBytes && ok) {
while (i < nBytes && ok) {
if(dev->checkpointByteOffset < 0 ||
dev->checkpointByteOffset >= dev->nDataBytesPerChunk) {
if (dev->checkpointByteOffset < 0 ||
dev->checkpointByteOffset >= dev->nDataBytesPerChunk) {
if(dev->checkpointCurrentBlock < 0){
if (dev->checkpointCurrentBlock < 0) {
yaffs_CheckpointFindNextCheckpointBlock(dev);
dev->checkpointCurrentChunk = 0;
}
if(dev->checkpointCurrentBlock < 0)
if (dev->checkpointCurrentBlock < 0)
ok = 0;
else {
chunk = dev->checkpointCurrentBlock * dev->nChunksPerBlock +
dev->checkpointCurrentChunk;
chunk = dev->checkpointCurrentBlock *
dev->nChunksPerBlock +
dev->checkpointCurrentChunk;
realignedChunk = chunk - dev->chunkOffset;
/* read in the next chunk */
/* printf("read checkpoint page %d\n",dev->checkpointPage); */
dev->readChunkWithTagsFromNAND(dev, realignedChunk,
dev->checkpointBuffer,
&tags);
/* read in the next chunk */
/* printf("read checkpoint page %d\n",dev->checkpointPage); */
dev->readChunkWithTagsFromNAND(dev,
realignedChunk,
dev->checkpointBuffer,
&tags);
if(tags.chunkId != (dev->checkpointPageSequence + 1) ||
tags.sequenceNumber != YAFFS_SEQUENCE_CHECKPOINT_DATA)
ok = 0;
if (tags.chunkId != (dev->checkpointPageSequence + 1) ||
tags.eccResult > YAFFS_ECC_RESULT_FIXED ||
tags.sequenceNumber != YAFFS_SEQUENCE_CHECKPOINT_DATA)
ok = 0;
dev->checkpointByteOffset = 0;
dev->checkpointPageSequence++;
dev->checkpointCurrentChunk++;
if(dev->checkpointCurrentChunk >= dev->nChunksPerBlock)
if (dev->checkpointCurrentChunk >= dev->nChunksPerBlock)
dev->checkpointCurrentBlock = -1;
}
}
if(ok){
if (ok) {
*dataBytes = dev->checkpointBuffer[dev->checkpointByteOffset];
dev->checkpointSum += *dataBytes;
dev->checkpointXor ^= *dataBytes;
@ -353,17 +345,17 @@ int yaffs_CheckpointRead(yaffs_Device *dev, void *data, int nBytes)
int yaffs_CheckpointClose(yaffs_Device *dev)
{
if(dev->checkpointOpenForWrite){
if(dev->checkpointByteOffset != 0)
if (dev->checkpointOpenForWrite) {
if (dev->checkpointByteOffset != 0)
yaffs_CheckpointFlushBuffer(dev);
} else {
int i;
for(i = 0; i < dev->blocksInCheckpoint && dev->checkpointBlockList[i] >= 0; i++){
yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,dev->checkpointBlockList[i]);
if(bi->blockState == YAFFS_BLOCK_STATE_EMPTY)
for (i = 0; i < dev->blocksInCheckpoint && dev->checkpointBlockList[i] >= 0; i++) {
yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, dev->checkpointBlockList[i]);
if (bi->blockState == YAFFS_BLOCK_STATE_EMPTY)
bi->blockState = YAFFS_BLOCK_STATE_CHECKPOINT;
else {
// Todo this looks odd...
/* Todo this looks odd... */
}
}
YFREE(dev->checkpointBlockList);
@ -374,27 +366,25 @@ int yaffs_CheckpointClose(yaffs_Device *dev)
dev->nErasedBlocks -= dev->blocksInCheckpoint;
T(YAFFS_TRACE_CHECKPOINT,(TSTR("checkpoint byte count %d" TENDSTR),
T(YAFFS_TRACE_CHECKPOINT, (TSTR("checkpoint byte count %d" TENDSTR),
dev->checkpointByteCount));
if(dev->checkpointBuffer){
if (dev->checkpointBuffer) {
/* free the buffer */
YFREE(dev->checkpointBuffer);
dev->checkpointBuffer = NULL;
return 1;
}
else
} else
return 0;
}
int yaffs_CheckpointInvalidateStream(yaffs_Device *dev)
{
/* Erase the first checksum block */
T(YAFFS_TRACE_CHECKPOINT,(TSTR("checkpoint invalidate"TENDSTR)));
T(YAFFS_TRACE_CHECKPOINT, (TSTR("checkpoint invalidate"TENDSTR)));
if(!yaffs_CheckpointSpaceOk(dev))
if (!yaffs_CheckpointSpaceOk(dev))
return 0;
return yaffs_CheckpointErase(dev);

View file

@ -20,9 +20,9 @@
int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting);
int yaffs_CheckpointWrite(yaffs_Device *dev,const void *data, int nBytes);
int yaffs_CheckpointWrite(yaffs_Device *dev, const void *data, int nBytes);
int yaffs_CheckpointRead(yaffs_Device *dev,void *data, int nBytes);
int yaffs_CheckpointRead(yaffs_Device *dev, void *data, int nBytes);
int yaffs_GetCheckpointSum(yaffs_Device *dev, __u32 *sum);

View file

@ -29,7 +29,7 @@
*/
const char *yaffs_ecc_c_version =
"$Id: yaffs_ecc.c,v 1.9 2007-02-14 01:09:06 wookey Exp $";
"$Id: yaffs_ecc.c,v 1.11 2009-03-06 17:20:50 wookey Exp $";
#include "yportenv.h"
@ -109,12 +109,10 @@ void yaffs_ECCCalculate(const unsigned char *data, unsigned char *ecc)
b = column_parity_table[*data++];
col_parity ^= b;
if (b & 0x01) // odd number of bits in the byte
{
if (b & 0x01) { /* odd number of bits in the byte */
line_parity ^= i;
line_parity_prime ^= ~i;
}
}
ecc[2] = (~col_parity) | 0x03;
@ -158,7 +156,7 @@ void yaffs_ECCCalculate(const unsigned char *data, unsigned char *ecc)
ecc[0] = ~t;
#ifdef CONFIG_YAFFS_ECC_WRONG_ORDER
// Swap the bytes into the wrong order
/* Swap the bytes into the wrong order */
t = ecc[0];
ecc[0] = ecc[1];
ecc[1] = t;
@ -189,7 +187,7 @@ int yaffs_ECCCorrect(unsigned char *data, unsigned char *read_ecc,
unsigned bit;
#ifdef CONFIG_YAFFS_ECC_WRONG_ORDER
// swap the bytes to correct for the wrong order
/* swap the bytes to correct for the wrong order */
unsigned char t;
t = d0;
@ -251,7 +249,7 @@ int yaffs_ECCCorrect(unsigned char *data, unsigned char *read_ecc,
* ECCxxxOther does ECC calcs on arbitrary n bytes of data
*/
void yaffs_ECCCalculateOther(const unsigned char *data, unsigned nBytes,
yaffs_ECCOther * eccOther)
yaffs_ECCOther *eccOther)
{
unsigned int i;
@ -278,8 +276,8 @@ void yaffs_ECCCalculateOther(const unsigned char *data, unsigned nBytes,
}
int yaffs_ECCCorrectOther(unsigned char *data, unsigned nBytes,
yaffs_ECCOther * read_ecc,
const yaffs_ECCOther * test_ecc)
yaffs_ECCOther *read_ecc,
const yaffs_ECCOther *test_ecc)
{
unsigned char cDelta; /* column parity delta */
unsigned lDelta; /* line parity delta */
@ -294,8 +292,7 @@ int yaffs_ECCCorrectOther(unsigned char *data, unsigned nBytes,
return 0; /* no error */
if (lDelta == ~lDeltaPrime &&
(((cDelta ^ (cDelta >> 1)) & 0x15) == 0x15))
{
(((cDelta ^ (cDelta >> 1)) & 0x15) == 0x15)) {
/* Single bit (recoverable) error in data */
bit = 0;
@ -307,7 +304,7 @@ int yaffs_ECCCorrectOther(unsigned char *data, unsigned nBytes,
if (cDelta & 0x02)
bit |= 0x01;
if(lDelta >= nBytes)
if (lDelta >= nBytes)
return -1;
data[lDelta] ^= (1 << bit);
@ -316,7 +313,7 @@ int yaffs_ECCCorrectOther(unsigned char *data, unsigned nBytes,
}
if ((yaffs_CountBits32(lDelta) + yaffs_CountBits32(lDeltaPrime) +
yaffs_CountBits(cDelta)) == 1) {
yaffs_CountBits(cDelta)) == 1) {
/* Reccoverable error in ecc */
*read_ecc = *test_ecc;
@ -326,6 +323,4 @@ int yaffs_ECCCorrectOther(unsigned char *data, unsigned nBytes,
/* Unrecoverable error */
return -1;
}

View file

@ -13,15 +13,15 @@
* 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.
*
*/
/*
* 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__
@ -34,11 +34,11 @@ typedef struct {
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);
const unsigned char *test_ecc);
void yaffs_ECCCalculateOther(const unsigned char *data, unsigned nBytes,
yaffs_ECCOther * ecc);
yaffs_ECCOther *ecc);
int yaffs_ECCCorrectOther(unsigned char *data, unsigned nBytes,
yaffs_ECCOther * read_ecc,
const yaffs_ECCOther * test_ecc);
yaffs_ECCOther *read_ecc,
const yaffs_ECCOther *test_ecc);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,34 @@
/*
* 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

File diff suppressed because it is too large Load diff

View file

@ -90,7 +90,7 @@
#define YAFFS_MAX_SHORT_OP_CACHES 20
#define YAFFS_N_TEMP_BUFFERS 4
#define YAFFS_N_TEMP_BUFFERS 6
/* We limit the number attempts at sucessfully saving a chunk of data.
* Small-page devices have 32 pages per block; large-page devices have 64.
@ -108,6 +108,9 @@
#define YAFFS_LOWEST_SEQUENCE_NUMBER 0x00001000
#define YAFFS_HIGHEST_SEQUENCE_NUMBER 0xEFFFFF00
/* Special sequence number for bad block that failed to be marked bad */
#define YAFFS_SEQUENCE_BAD_BLOCK 0xFFFF0000
/* ChunkCache is used for short read/write operations.*/
typedef struct {
struct yaffs_ObjectStruct *object;
@ -134,11 +137,10 @@ typedef struct {
typedef struct {
unsigned chunkId:20;
unsigned serialNumber:2;
unsigned byteCount:10;
unsigned byteCountLSB:10;
unsigned objectId:18;
unsigned ecc:12;
unsigned unusedStuff:2;
unsigned byteCountMSB:2;
} yaffs_Tags;
typedef union {
@ -277,13 +279,13 @@ typedef struct {
int softDeletions:10; /* number of soft deleted pages */
int pagesInUse:10; /* number of pages in use */
yaffs_BlockState blockState:4; /* One of the above block states */
unsigned blockState:4; /* One of the above block states. NB use unsigned because enum is sometimes an int */
__u32 needsRetiring:1; /* Data has failed on this block, need to get valid data off */
/* and retire the block. */
__u32 skipErasedCheck: 1; /* If this is set we can skip the erased check on this block */
__u32 gcPrioritise: 1; /* An ECC check or blank check has failed on this block.
/* and retire the block. */
__u32 skipErasedCheck:1; /* If this is set we can skip the erased check on this block */
__u32 gcPrioritise:1; /* An ECC check or blank check has failed on this block.
It should be prioritised for GC */
__u32 chunkErrorStrikes:3; /* How many times we've had ecc etc failures on this block and tried to reuse it */
__u32 chunkErrorStrikes:3; /* How many times we've had ecc etc failures on this block and tried to reuse it */
#ifdef CONFIG_YAFFS_YAFFS2
__u32 hasShrinkHeader:1; /* This block has at least one shrink object header */
@ -300,11 +302,11 @@ typedef struct {
/* Apply to everything */
int parentObjectId;
__u16 sum__NoLongerUsed; /* checksum of name. No longer used */
__u16 sum__NoLongerUsed; /* checksum of name. No longer used */
YCHAR name[YAFFS_MAX_NAME_LENGTH + 1];
/* Thes following apply to directories, files, symlinks - not hard links */
__u32 yst_mode; /* protection */
/* The following apply to directories, files, symlinks - not hard links */
__u32 yst_mode; /* protection */
#ifdef CONFIG_YAFFS_WINCE
__u32 notForWinCE[5];
@ -331,11 +333,14 @@ typedef struct {
__u32 win_ctime[2];
__u32 win_atime[2];
__u32 win_mtime[2];
__u32 roomToGrow[4];
#else
__u32 roomToGrow[10];
#endif
__u32 roomToGrow[6];
#endif
__u32 inbandShadowsObject;
__u32 inbandIsShrink;
__u32 reservedSpace[2];
int shadowsObject; /* This object header shadows the specified object if > 0 */
/* isShrink applies to object headers written when we shrink the file (ie resize) */
@ -381,7 +386,7 @@ typedef struct {
} yaffs_FileStructure;
typedef struct {
struct list_head children; /* list of child links */
struct ylist_head children; /* list of child links */
} yaffs_DirectoryStructure;
typedef struct {
@ -418,23 +423,24 @@ struct yaffs_ObjectStruct {
* still in the inode cache. Free of object is defered.
* until the inode is released.
*/
__u8 beingCreated:1; /* This object is still being created so skip some checks. */
__u8 serial; /* serial number of chunk in NAND. Cached here */
__u16 sum; /* sum of the name to speed searching */
struct yaffs_DeviceStruct *myDev; /* The device I'm on */
struct yaffs_DeviceStruct *myDev; /* The device I'm on */
struct list_head hashLink; /* list of objects in this hash bucket */
struct ylist_head hashLink; /* list of objects in this hash bucket */
struct list_head hardLinks; /* all the equivalent hard linked objects */
struct ylist_head hardLinks; /* all the equivalent hard linked objects */
/* directory structure stuff */
/* also used for linking up the free list */
struct yaffs_ObjectStruct *parent;
struct list_head siblings;
struct ylist_head siblings;
/* Where's my object header in NAND? */
int chunkId;
int hdrChunk;
int nDataChunks; /* Number of data chunks attached to the file. */
@ -485,7 +491,7 @@ struct yaffs_ObjectList_struct {
typedef struct yaffs_ObjectList_struct yaffs_ObjectList;
typedef struct {
struct list_head list;
struct ylist_head list;
int count;
} yaffs_ObjectBucket;
@ -495,11 +501,10 @@ typedef struct {
*/
typedef struct {
int structType;
int structType;
__u32 objectId;
__u32 parentId;
int chunkId;
int hdrChunk;
yaffs_ObjectType variantType:3;
__u8 deleted:1;
__u8 softDeleted:1;
@ -511,8 +516,7 @@ typedef struct {
int nDataChunks;
__u32 fileSizeOrEquivalentObjectId;
}yaffs_CheckpointObject;
} yaffs_CheckpointObject;
/*--------------------- Temporary buffers ----------------
*
@ -528,13 +532,13 @@ typedef struct {
/*----------------- Device ---------------------------------*/
struct yaffs_DeviceStruct {
struct list_head devList;
struct ylist_head devList;
const char *name;
/* Entry parameters set up way early. Yaffs sets up the rest.*/
int nDataBytesPerChunk; /* Should be a power of 2 >= 512 */
int nChunksPerBlock; /* does not need to be a power of 2 */
int nBytesPerSpare; /* spare area size */
int spareBytesPerChunk; /* spare area size */
int startBlock; /* Start block we're allowed to use */
int endBlock; /* End block we're allowed to use */
int nReservedBlocks; /* We want this tuneable so that we can reduce */
@ -544,9 +548,7 @@ struct yaffs_DeviceStruct {
/* Stuff used by the shared space checkpointing mechanism */
/* If this value is zero, then this mechanism is disabled */
int nCheckpointReservedBlocks; /* Blocks to reserve for checkpoint data */
/* int nCheckpointReservedBlocks; */ /* Blocks to reserve for checkpoint data */
int nShortOpCaches; /* If <= 0, then short op caching is disabled, else
@ -560,30 +562,31 @@ struct yaffs_DeviceStruct {
void *genericDevice; /* Pointer to device context
* On an mtd this holds the mtd pointer.
*/
void *superBlock;
void *superBlock;
/* NAND access functions (Must be set before calling YAFFS)*/
int (*writeChunkToNAND) (struct yaffs_DeviceStruct * dev,
int chunkInNAND, const __u8 * data,
const yaffs_Spare * spare);
int (*readChunkFromNAND) (struct yaffs_DeviceStruct * dev,
int chunkInNAND, __u8 * data,
yaffs_Spare * spare);
int (*eraseBlockInNAND) (struct yaffs_DeviceStruct * dev,
int blockInNAND);
int (*initialiseNAND) (struct yaffs_DeviceStruct * dev);
int (*writeChunkToNAND) (struct yaffs_DeviceStruct *dev,
int chunkInNAND, const __u8 *data,
const yaffs_Spare *spare);
int (*readChunkFromNAND) (struct yaffs_DeviceStruct *dev,
int chunkInNAND, __u8 *data,
yaffs_Spare *spare);
int (*eraseBlockInNAND) (struct yaffs_DeviceStruct *dev,
int blockInNAND);
int (*initialiseNAND) (struct yaffs_DeviceStruct *dev);
int (*deinitialiseNAND) (struct yaffs_DeviceStruct *dev);
#ifdef CONFIG_YAFFS_YAFFS2
int (*writeChunkWithTagsToNAND) (struct yaffs_DeviceStruct * dev,
int chunkInNAND, const __u8 * data,
const yaffs_ExtendedTags * tags);
int (*readChunkWithTagsFromNAND) (struct yaffs_DeviceStruct * dev,
int chunkInNAND, __u8 * data,
yaffs_ExtendedTags * tags);
int (*markNANDBlockBad) (struct yaffs_DeviceStruct * dev, int blockNo);
int (*queryNANDBlock) (struct yaffs_DeviceStruct * dev, int blockNo,
yaffs_BlockState * state, int *sequenceNumber);
int (*writeChunkWithTagsToNAND) (struct yaffs_DeviceStruct *dev,
int chunkInNAND, const __u8 *data,
const yaffs_ExtendedTags *tags);
int (*readChunkWithTagsFromNAND) (struct yaffs_DeviceStruct *dev,
int chunkInNAND, __u8 *data,
yaffs_ExtendedTags *tags);
int (*markNANDBlockBad) (struct yaffs_DeviceStruct *dev, int blockNo);
int (*queryNANDBlock) (struct yaffs_DeviceStruct *dev, int blockNo,
yaffs_BlockState *state, __u32 *sequenceNumber);
#endif
int isYaffs2;
@ -595,10 +598,12 @@ struct yaffs_DeviceStruct {
void (*removeObjectCallback)(struct yaffs_ObjectStruct *obj);
/* Callback to mark the superblock dirsty */
void (*markSuperBlockDirty)(void * superblock);
void (*markSuperBlockDirty)(void *superblock);
int wideTnodesDisabled; /* Set to disable wide tnodes */
YCHAR *pathDividers; /* String of legal path dividers */
/* End of stuff that must be set before initialisation. */
@ -615,16 +620,14 @@ struct yaffs_DeviceStruct {
__u32 tnodeWidth;
__u32 tnodeMask;
/* Stuff to support various file offses to chunk/offset translations */
/* "Crumbs" for nDataBytesPerChunk not being a power of 2 */
__u32 crumbMask;
__u32 crumbShift;
__u32 crumbsPerChunk;
/* Straight shifting for nDataBytesPerChunk being a power of 2 */
__u32 chunkShift;
__u32 chunkMask;
/* Stuff for figuring out file offset to chunk conversions */
__u32 chunkShift; /* Shift value */
__u32 chunkDiv; /* Divisor after shifting: 1 for power-of-2 sizes */
__u32 chunkMask; /* Mask to use for power-of-2 case */
/* Stuff to handle inband tags */
int inbandTags;
__u32 totalBytesPerChunk;
#ifdef __KERNEL__
@ -633,7 +636,7 @@ struct yaffs_DeviceStruct {
__u8 *spareBuffer; /* For mtdif2 use. Don't know the size of the buffer
* at compile time so we have to allocate it.
*/
void (*putSuperFunc) (struct super_block * sb);
void (*putSuperFunc) (struct super_block *sb);
#endif
int isMounted;
@ -663,6 +666,8 @@ struct yaffs_DeviceStruct {
__u32 checkpointSum;
__u32 checkpointXor;
int nCheckpointBlocksRequired; /* Number of blocks needed to store current checkpoint set */
/* Block Info */
yaffs_BlockInfo *blockInfo;
__u8 *chunkBits; /* bitmap of chunks in use */
@ -684,11 +689,15 @@ struct yaffs_DeviceStruct {
yaffs_TnodeList *allocatedTnodeList;
int isDoingGC;
int gcBlock;
int gcChunk;
int nObjectsCreated;
yaffs_Object *freeObjects;
int nFreeObjects;
int nHardLinks;
yaffs_ObjectList *allocatedObjectList;
yaffs_ObjectBucket objectBucket[YAFFS_NOBJECT_BUCKETS];
@ -745,8 +754,10 @@ struct yaffs_DeviceStruct {
int nBackgroundDeletions; /* Count of background deletions. */
/* Temporary buffer management */
yaffs_TempBuffer tempBuffer[YAFFS_N_TEMP_BUFFERS];
int maxTemp;
int tempInUse;
int unmanagedTempAllocations;
int unmanagedTempDeallocations;
@ -758,9 +769,9 @@ struct yaffs_DeviceStruct {
typedef struct yaffs_DeviceStruct yaffs_Device;
/* The static layout of bllock usage etc is stored in the super block header */
/* The static layout of block usage etc is stored in the super block header */
typedef struct {
int StructType;
int StructType;
int version;
int checkpointStartBlock;
int checkpointEndBlock;
@ -773,7 +784,7 @@ typedef struct {
* must be preserved over unmount/mount cycles.
*/
typedef struct {
int structType;
int structType;
int nErasedBlocks;
int allocationBlock; /* Current block being allocated off */
__u32 allocationPage;
@ -791,57 +802,45 @@ typedef struct {
typedef struct {
int structType;
__u32 magic;
__u32 version;
__u32 head;
int structType;
__u32 magic;
__u32 version;
__u32 head;
} yaffs_CheckpointValidity;
/* 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];
}
/*----------------------- YAFFS Functions -----------------------*/
int yaffs_GutsInitialise(yaffs_Device * dev);
void yaffs_Deinitialise(yaffs_Device * dev);
int yaffs_GutsInitialise(yaffs_Device *dev);
void yaffs_Deinitialise(yaffs_Device *dev);
int yaffs_GetNumberOfFreeChunks(yaffs_Device * dev);
int yaffs_GetNumberOfFreeChunks(yaffs_Device *dev);
int yaffs_RenameObject(yaffs_Object * oldDir, const YCHAR * oldName,
yaffs_Object * newDir, const YCHAR * newName);
int yaffs_RenameObject(yaffs_Object *oldDir, const YCHAR *oldName,
yaffs_Object *newDir, const YCHAR *newName);
int yaffs_Unlink(yaffs_Object * dir, const YCHAR * name);
int yaffs_DeleteFile(yaffs_Object * obj);
int yaffs_Unlink(yaffs_Object *dir, const YCHAR *name);
int yaffs_DeleteObject(yaffs_Object *obj);
int yaffs_GetObjectName(yaffs_Object * obj, YCHAR * name, int buffSize);
int yaffs_GetObjectFileLength(yaffs_Object * obj);
int yaffs_GetObjectInode(yaffs_Object * obj);
unsigned yaffs_GetObjectType(yaffs_Object * obj);
int yaffs_GetObjectLinkCount(yaffs_Object * obj);
int yaffs_GetObjectName(yaffs_Object *obj, YCHAR *name, int buffSize);
int yaffs_GetObjectFileLength(yaffs_Object *obj);
int yaffs_GetObjectInode(yaffs_Object *obj);
unsigned yaffs_GetObjectType(yaffs_Object *obj);
int yaffs_GetObjectLinkCount(yaffs_Object *obj);
int yaffs_SetAttributes(yaffs_Object * obj, struct iattr *attr);
int yaffs_GetAttributes(yaffs_Object * obj, struct iattr *attr);
int yaffs_SetAttributes(yaffs_Object *obj, struct iattr *attr);
int yaffs_GetAttributes(yaffs_Object *obj, struct iattr *attr);
/* File operations */
int yaffs_ReadDataFromFile(yaffs_Object * obj, __u8 * buffer, loff_t offset,
int nBytes);
int yaffs_WriteDataToFile(yaffs_Object * obj, const __u8 * buffer, loff_t offset,
int nBytes, int writeThrough);
int yaffs_ResizeFile(yaffs_Object * obj, loff_t newSize);
int yaffs_ReadDataFromFile(yaffs_Object *obj, __u8 *buffer, loff_t offset,
int nBytes);
int yaffs_WriteDataToFile(yaffs_Object *obj, const __u8 *buffer, loff_t offset,
int nBytes, int writeThrough);
int yaffs_ResizeFile(yaffs_Object *obj, loff_t newSize);
yaffs_Object *yaffs_MknodFile(yaffs_Object * parent, const YCHAR * name,
__u32 mode, __u32 uid, __u32 gid);
int yaffs_FlushFile(yaffs_Object * obj, int updateTime);
yaffs_Object *yaffs_MknodFile(yaffs_Object *parent, const YCHAR *name,
__u32 mode, __u32 uid, __u32 gid);
int yaffs_FlushFile(yaffs_Object *obj, int updateTime);
/* Flushing and checkpointing */
void yaffs_FlushEntireDeviceCache(yaffs_Device *dev);
@ -850,33 +849,33 @@ int yaffs_CheckpointSave(yaffs_Device *dev);
int yaffs_CheckpointRestore(yaffs_Device *dev);
/* Directory operations */
yaffs_Object *yaffs_MknodDirectory(yaffs_Object * parent, const YCHAR * name,
__u32 mode, __u32 uid, __u32 gid);
yaffs_Object *yaffs_FindObjectByName(yaffs_Object * theDir, const YCHAR * name);
int yaffs_ApplyToDirectoryChildren(yaffs_Object * theDir,
yaffs_Object *yaffs_MknodDirectory(yaffs_Object *parent, const YCHAR *name,
__u32 mode, __u32 uid, __u32 gid);
yaffs_Object *yaffs_FindObjectByName(yaffs_Object *theDir, const YCHAR *name);
int yaffs_ApplyToDirectoryChildren(yaffs_Object *theDir,
int (*fn) (yaffs_Object *));
yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device * dev, __u32 number);
yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device *dev, __u32 number);
/* Link operations */
yaffs_Object *yaffs_Link(yaffs_Object * parent, const YCHAR * name,
yaffs_Object * equivalentObject);
yaffs_Object *yaffs_Link(yaffs_Object *parent, const YCHAR *name,
yaffs_Object *equivalentObject);
yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object * obj);
yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object *obj);
/* Symlink operations */
yaffs_Object *yaffs_MknodSymLink(yaffs_Object * parent, const YCHAR * name,
yaffs_Object *yaffs_MknodSymLink(yaffs_Object *parent, const YCHAR *name,
__u32 mode, __u32 uid, __u32 gid,
const YCHAR * alias);
YCHAR *yaffs_GetSymlinkAlias(yaffs_Object * obj);
const YCHAR *alias);
YCHAR *yaffs_GetSymlinkAlias(yaffs_Object *obj);
/* Special inodes (fifos, sockets and devices) */
yaffs_Object *yaffs_MknodSpecial(yaffs_Object * parent, const YCHAR * name,
yaffs_Object *yaffs_MknodSpecial(yaffs_Object *parent, const YCHAR *name,
__u32 mode, __u32 uid, __u32 gid, __u32 rdev);
/* Special directories */
yaffs_Object *yaffs_Root(yaffs_Device * dev);
yaffs_Object *yaffs_LostNFound(yaffs_Device * dev);
yaffs_Object *yaffs_Root(yaffs_Device *dev);
yaffs_Object *yaffs_LostNFound(yaffs_Device *dev);
#ifdef CONFIG_YAFFS_WINCE
/* CONFIG_YAFFS_WINCE special stuff */
@ -885,18 +884,21 @@ void yfsd_WinFileTimeNow(__u32 target[2]);
#ifdef __KERNEL__
void yaffs_HandleDeferedFree(yaffs_Object * obj);
void yaffs_HandleDeferedFree(yaffs_Object *obj);
#endif
/* Debug dump */
int yaffs_DumpObject(yaffs_Object * obj);
int yaffs_DumpObject(yaffs_Object *obj);
void yaffs_GutsTest(yaffs_Device * dev);
void yaffs_GutsTest(yaffs_Device *dev);
/* A few useful functions */
void yaffs_InitialiseTags(yaffs_ExtendedTags * tags);
void yaffs_DeleteChunk(yaffs_Device * dev, int chunkId, int markNAND, int lyn);
int yaffs_CheckFF(__u8 * buffer, int nBytes);
void yaffs_InitialiseTags(yaffs_ExtendedTags *tags);
void yaffs_DeleteChunk(yaffs_Device *dev, int chunkId, int markNAND, int lyn);
int yaffs_CheckFF(__u8 *buffer, int nBytes);
void yaffs_HandleChunkError(yaffs_Device *dev, yaffs_BlockInfo *bi);
__u8 *yaffs_GetTempBuffer(yaffs_Device *dev, int lineNo);
void yaffs_ReleaseTempBuffer(yaffs_Device *dev, __u8 *buffer, int lineNo);
#endif

View file

@ -12,7 +12,7 @@
*/
const char *yaffs_mtdif_c_version =
"$Id: yaffs_mtdif.c,v 1.19 2007-02-14 01:09:06 wookey Exp $";
"$Id: yaffs_mtdif.c,v 1.22 2009-03-06 17:20:51 wookey Exp $";
#include "yportenv.h"
@ -24,7 +24,7 @@ const char *yaffs_mtdif_c_version =
#include "linux/time.h"
#include "linux/mtd/nand.h"
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18))
#if (MTD_VERSION_CODE < MTD_VERSION(2, 6, 18))
static struct nand_oobinfo yaffs_oobinfo = {
.useecc = 1,
.eccbytes = 6,
@ -36,7 +36,7 @@ static struct nand_oobinfo yaffs_noeccinfo = {
};
#endif
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
static inline void translate_spare2oob(const yaffs_Spare *spare, __u8 *oob)
{
oob[0] = spare->tagByte0;
@ -45,8 +45,8 @@ static inline void translate_spare2oob(const yaffs_Spare *spare, __u8 *oob)
oob[3] = spare->tagByte3;
oob[4] = spare->tagByte4;
oob[5] = spare->tagByte5 & 0x3f;
oob[5] |= spare->blockStatus == 'Y' ? 0: 0x80;
oob[5] |= spare->pageStatus == 0 ? 0: 0x40;
oob[5] |= spare->blockStatus == 'Y' ? 0 : 0x80;
oob[5] |= spare->pageStatus == 0 ? 0 : 0x40;
oob[6] = spare->tagByte6;
oob[7] = spare->tagByte7;
}
@ -71,18 +71,18 @@ static inline void translate_oob2spare(yaffs_Spare *spare, __u8 *oob)
}
#endif
int nandmtd_WriteChunkToNAND(yaffs_Device * dev, int chunkInNAND,
const __u8 * data, const yaffs_Spare * spare)
int nandmtd_WriteChunkToNAND(yaffs_Device *dev, int chunkInNAND,
const __u8 *data, const yaffs_Spare *spare)
{
struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
struct mtd_oob_ops ops;
#endif
size_t dummy;
int retval = 0;
loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
__u8 spareAsBytes[8]; /* OOB */
if (data && !spare)
@ -135,18 +135,18 @@ int nandmtd_WriteChunkToNAND(yaffs_Device * dev, int chunkInNAND,
return YAFFS_FAIL;
}
int nandmtd_ReadChunkFromNAND(yaffs_Device * dev, int chunkInNAND, __u8 * data,
yaffs_Spare * spare)
int nandmtd_ReadChunkFromNAND(yaffs_Device *dev, int chunkInNAND, __u8 *data,
yaffs_Spare *spare)
{
struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
struct mtd_oob_ops ops;
#endif
size_t dummy;
int retval = 0;
loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
__u8 spareAsBytes[8]; /* OOB */
if (data && !spare)
@ -205,7 +205,7 @@ int nandmtd_ReadChunkFromNAND(yaffs_Device * dev, int chunkInNAND, __u8 * data,
return YAFFS_FAIL;
}
int nandmtd_EraseBlockInNAND(yaffs_Device * dev, int blockNumber)
int nandmtd_EraseBlockInNAND(yaffs_Device *dev, int blockNumber)
{
struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
__u32 addr =
@ -234,7 +234,7 @@ int nandmtd_EraseBlockInNAND(yaffs_Device * dev, int blockNumber)
return YAFFS_FAIL;
}
int nandmtd_InitialiseNAND(yaffs_Device * dev)
int nandmtd_InitialiseNAND(yaffs_Device *dev)
{
return YAFFS_OK;
}

View file

@ -18,10 +18,15 @@
#include "yaffs_guts.h"
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);
#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

View file

@ -26,7 +26,7 @@
#include "yportenv.h"
#include "yaffs_guts.h"
#include "yaffs_packedtags1.h"
#include "yaffs_tagscompat.h" // for yaffs_CalcTagsECC
#include "yaffs_tagscompat.h" /* for yaffs_CalcTagsECC */
#include "linux/kernel.h"
#include "linux/version.h"
@ -34,9 +34,9 @@
#include "linux/mtd/mtd.h"
/* Don't compile this module if we don't have MTD's mtd_oob_ops interface */
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
const char *yaffs_mtdif1_c_version = "$Id: yaffs_mtdif1.c,v 1.3 2007/05/15 20:16:11 ian Exp $";
const char *yaffs_mtdif1_c_version = "$Id: yaffs_mtdif1.c,v 1.10 2009-03-09 07:41:10 charles Exp $";
#ifndef CONFIG_YAFFS_9BYTE_TAGS
# define YTAG1_SIZE 8
@ -89,9 +89,9 @@ static struct nand_ecclayout nand_oob_16 = {
* Returns YAFFS_OK or YAFFS_FAIL.
*/
int nandmtd1_WriteChunkWithTagsToNAND(yaffs_Device *dev,
int chunkInNAND, const __u8 * data, const yaffs_ExtendedTags * etags)
int chunkInNAND, const __u8 *data, const yaffs_ExtendedTags *etags)
{
struct mtd_info * mtd = dev->genericDevice;
struct mtd_info *mtd = dev->genericDevice;
int chunkBytes = dev->nDataBytesPerChunk;
loff_t addr = ((loff_t)chunkInNAND) * chunkBytes;
struct mtd_oob_ops ops;
@ -146,7 +146,7 @@ int nandmtd1_WriteChunkWithTagsToNAND(yaffs_Device *dev,
/* Return with empty ExtendedTags but add eccResult.
*/
static int rettags(yaffs_ExtendedTags * etags, int eccResult, int retval)
static int rettags(yaffs_ExtendedTags *etags, int eccResult, int retval)
{
if (etags) {
memset(etags, 0, sizeof(*etags));
@ -169,9 +169,9 @@ static int rettags(yaffs_ExtendedTags * etags, int eccResult, int retval)
* Returns YAFFS_OK or YAFFS_FAIL.
*/
int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev,
int chunkInNAND, __u8 * data, yaffs_ExtendedTags * etags)
int chunkInNAND, __u8 *data, yaffs_ExtendedTags *etags)
{
struct mtd_info * mtd = dev->genericDevice;
struct mtd_info *mtd = dev->genericDevice;
int chunkBytes = dev->nDataBytesPerChunk;
loff_t addr = ((loff_t)chunkInNAND) * chunkBytes;
int eccres = YAFFS_ECC_RESULT_NO_ERROR;
@ -189,7 +189,7 @@ int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev,
ops.datbuf = data;
ops.oobbuf = (__u8 *)&pt1;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
#if (MTD_VERSION_CODE < MTD_VERSION(2, 6, 20))
/* In MTD 2.6.18 to 2.6.19 nand_base.c:nand_do_read_oob() has a bug;
* help it out with ops.len = ops.ooblen when ops.datbuf == NULL.
*/
@ -284,11 +284,11 @@ int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev,
*/
int nandmtd1_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo)
{
struct mtd_info * mtd = dev->genericDevice;
struct mtd_info *mtd = dev->genericDevice;
int blocksize = dev->nChunksPerBlock * dev->nDataBytesPerChunk;
int retval;
yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, "marking block %d bad", blockNo);
yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, "marking block %d bad\n", blockNo);
retval = mtd->block_markbad(mtd, (loff_t)blocksize * blockNo);
return (retval) ? YAFFS_FAIL : YAFFS_OK;
@ -298,7 +298,7 @@ int nandmtd1_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo)
*
* Returns YAFFS_OK or YAFFS_FAIL.
*/
static int nandmtd1_TestPrerequists(struct mtd_info * mtd)
static int nandmtd1_TestPrerequists(struct mtd_info *mtd)
{
/* 2.6.18 has mtd->ecclayout->oobavail */
/* 2.6.21 has mtd->ecclayout->oobavail and mtd->oobavail */
@ -323,10 +323,11 @@ static int nandmtd1_TestPrerequists(struct mtd_info * mtd)
* Always returns YAFFS_OK.
*/
int nandmtd1_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
yaffs_BlockState * pState, int *pSequenceNumber)
yaffs_BlockState *pState, __u32 *pSequenceNumber)
{
struct mtd_info * mtd = dev->genericDevice;
struct mtd_info *mtd = dev->genericDevice;
int chunkNo = blockNo * dev->nChunksPerBlock;
loff_t addr = (loff_t)chunkNo * dev->nDataBytesPerChunk;
yaffs_ExtendedTags etags;
int state = YAFFS_BLOCK_STATE_DEAD;
int seqnum = 0;
@ -335,21 +336,22 @@ int nandmtd1_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
/* We don't yet have a good place to test for MTD config prerequists.
* Do it here as we are called during the initial scan.
*/
if (nandmtd1_TestPrerequists(mtd) != YAFFS_OK) {
if (nandmtd1_TestPrerequists(mtd) != YAFFS_OK)
return YAFFS_FAIL;
}
retval = nandmtd1_ReadChunkWithTagsFromNAND(dev, chunkNo, NULL, &etags);
etags.blockBad = (mtd->block_isbad)(mtd, addr);
if (etags.blockBad) {
yaffs_trace(YAFFS_TRACE_BAD_BLOCKS,
"block %d is marked bad", blockNo);
"block %d is marked bad\n", blockNo);
state = YAFFS_BLOCK_STATE_DEAD;
}
else if (etags.chunkUsed) {
} else if (etags.eccResult != YAFFS_ECC_RESULT_NO_ERROR) {
/* bad tags, need to look more closely */
state = YAFFS_BLOCK_STATE_NEEDS_SCANNING;
} else if (etags.chunkUsed) {
state = YAFFS_BLOCK_STATE_NEEDS_SCANNING;
seqnum = etags.sequenceNumber;
}
else {
} else {
state = YAFFS_BLOCK_STATE_EMPTY;
}
@ -360,4 +362,4 @@ int nandmtd1_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
return YAFFS_OK;
}
#endif /*KERNEL_VERSION*/
#endif /*MTD_VERSION*/

View file

@ -14,15 +14,15 @@
#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_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_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);
yaffs_BlockState *state, __u32 *sequenceNumber);
#endif

View file

@ -14,7 +14,7 @@
/* mtd interface for YAFFS2 */
const char *yaffs_mtdif2_c_version =
"$Id: yaffs_mtdif2.c,v 1.17 2007-02-14 01:09:06 wookey Exp $";
"$Id: yaffs_mtdif2.c,v 1.23 2009-03-06 17:20:53 wookey Exp $";
#include "yportenv.h"
@ -27,19 +27,23 @@ const char *yaffs_mtdif2_c_version =
#include "yaffs_packedtags2.h"
int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND,
const __u8 * data,
const yaffs_ExtendedTags * tags)
/* NB For use with inband tags....
* We assume that the data buffer is of size totalBytersPerChunk so that we can also
* use it to load the tags.
*/
int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device *dev, int chunkInNAND,
const __u8 *data,
const yaffs_ExtendedTags *tags)
{
struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
struct mtd_oob_ops ops;
#else
size_t dummy;
#endif
int retval = 0;
loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
loff_t addr;
yaffs_PackedTags2 pt;
@ -48,46 +52,40 @@ int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND,
("nandmtd2_WriteChunkWithTagsToNAND chunk %d data %p tags %p"
TENDSTR), chunkInNAND, data, tags));
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
if (tags)
yaffs_PackTags2(&pt, tags);
else
BUG(); /* both tags and data should always be present */
if (data) {
ops.mode = MTD_OOB_AUTO;
ops.ooblen = sizeof(pt);
ops.len = dev->nDataBytesPerChunk;
ops.ooboffs = 0;
ops.datbuf = (__u8 *)data;
ops.oobbuf = (void *)&pt;
retval = mtd->write_oob(mtd, addr, &ops);
addr = ((loff_t) chunkInNAND) * dev->totalBytesPerChunk;
/* For yaffs2 writing there must be both data and tags.
* If we're using inband tags, then the tags are stuffed into
* the end of the data buffer.
*/
if (!data || !tags)
BUG();
else if (dev->inbandTags) {
yaffs_PackedTags2TagsPart *pt2tp;
pt2tp = (yaffs_PackedTags2TagsPart *)(data + dev->nDataBytesPerChunk);
yaffs_PackTags2TagsPart(pt2tp, tags);
} else
BUG(); /* both tags and data should always be present */
#else
if (tags) {
yaffs_PackTags2(&pt, tags);
}
if (data && tags) {
if (dev->useNANDECC)
retval =
mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
&dummy, data, (__u8 *) & pt, NULL);
else
retval =
mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
&dummy, data, (__u8 *) & pt, NULL);
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
ops.mode = MTD_OOB_AUTO;
ops.ooblen = (dev->inbandTags) ? 0 : sizeof(pt);
ops.len = dev->totalBytesPerChunk;
ops.ooboffs = 0;
ops.datbuf = (__u8 *)data;
ops.oobbuf = (dev->inbandTags) ? NULL : (void *)&pt;
retval = mtd->write_oob(mtd, addr, &ops);
#else
if (!dev->inbandTags) {
retval =
mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
&dummy, data, (__u8 *) &pt, NULL);
} else {
if (data)
retval =
mtd->write(mtd, addr, dev->nDataBytesPerChunk, &dummy,
data);
if (tags)
retval =
mtd->write_oob(mtd, addr, mtd->oobsize, &dummy,
(__u8 *) & pt);
retval =
mtd->write(mtd, addr, dev->totalBytesPerChunk, &dummy,
data);
}
#endif
@ -97,17 +95,18 @@ int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND,
return YAFFS_FAIL;
}
int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
__u8 * data, yaffs_ExtendedTags * tags)
int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
__u8 *data, yaffs_ExtendedTags *tags)
{
struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
struct mtd_oob_ops ops;
#endif
size_t dummy;
int retval = 0;
int localData = 0;
loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
loff_t addr = ((loff_t) chunkInNAND) * dev->totalBytesPerChunk;
yaffs_PackedTags2 pt;
@ -116,9 +115,20 @@ int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
("nandmtd2_ReadChunkWithTagsFromNAND chunk %d data %p tags %p"
TENDSTR), chunkInNAND, data, tags));
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
if (data && !tags)
retval = mtd->read(mtd, addr, dev->nDataBytesPerChunk,
if (dev->inbandTags) {
if (!data) {
localData = 1;
data = yaffs_GetTempBuffer(dev, __LINE__);
}
}
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
if (dev->inbandTags || (data && !tags))
retval = mtd->read(mtd, addr, dev->totalBytesPerChunk,
&dummy, data);
else if (tags) {
ops.mode = MTD_OOB_AUTO;
@ -130,38 +140,42 @@ int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
retval = mtd->read_oob(mtd, addr, &ops);
}
#else
if (data && tags) {
if (dev->useNANDECC) {
retval =
mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk,
if (!dev->inbandTags && data && tags) {
retval = mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk,
&dummy, data, dev->spareBuffer,
NULL);
} else {
retval =
mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk,
&dummy, data, dev->spareBuffer,
NULL);
}
} else {
if (data)
retval =
mtd->read(mtd, addr, dev->nDataBytesPerChunk, &dummy,
data);
if (tags)
if (!dev->inbandTags && tags)
retval =
mtd->read_oob(mtd, addr, mtd->oobsize, &dummy,
dev->spareBuffer);
}
#endif
memcpy(&pt, dev->spareBuffer, sizeof(pt));
if (tags)
yaffs_UnpackTags2(tags, &pt);
if (dev->inbandTags) {
if (tags) {
yaffs_PackedTags2TagsPart *pt2tp;
pt2tp = (yaffs_PackedTags2TagsPart *)&data[dev->nDataBytesPerChunk];
yaffs_UnpackTags2TagsPart(tags, pt2tp);
}
} else {
if (tags) {
memcpy(&pt, dev->spareBuffer, sizeof(pt));
yaffs_UnpackTags2(tags, &pt);
}
}
if(tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
if (localData)
yaffs_ReleaseTempBuffer(dev, data, __LINE__);
if (tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
if (retval == 0)
return YAFFS_OK;
else
@ -178,7 +192,7 @@ int nandmtd2_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo)
retval =
mtd->block_markbad(mtd,
blockNo * dev->nChunksPerBlock *
dev->nDataBytesPerChunk);
dev->totalBytesPerChunk);
if (retval == 0)
return YAFFS_OK;
@ -188,7 +202,7 @@ int nandmtd2_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo)
}
int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
yaffs_BlockState * state, int *sequenceNumber)
yaffs_BlockState *state, __u32 *sequenceNumber)
{
struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
int retval;
@ -198,7 +212,7 @@ int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
retval =
mtd->block_isbad(mtd,
blockNo * dev->nChunksPerBlock *
dev->nDataBytesPerChunk);
dev->totalBytesPerChunk);
if (retval) {
T(YAFFS_TRACE_MTD, (TSTR("block is bad" TENDSTR)));

View file

@ -17,13 +17,13 @@
#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_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);
yaffs_BlockState *state, __u32 *sequenceNumber);
#endif

View file

@ -12,16 +12,17 @@
*/
const char *yaffs_nand_c_version =
"$Id: yaffs_nand.c,v 1.7 2007-02-14 01:09:06 wookey Exp $";
"$Id: yaffs_nand.c,v 1.10 2009-03-06 17:20:54 wookey 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 yaffs_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
__u8 *buffer,
yaffs_ExtendedTags *tags)
{
int result;
yaffs_ExtendedTags localTags;
@ -29,7 +30,7 @@ int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
int realignedChunkInNAND = chunkInNAND - dev->chunkOffset;
/* If there are no tags provided, use local tags to get prioritised gc working */
if(!tags)
if (!tags)
tags = &localTags;
if (dev->readChunkWithTagsFromNAND)
@ -40,20 +41,20 @@ int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
realignedChunkInNAND,
buffer,
tags);
if(tags &&
tags->eccResult > YAFFS_ECC_RESULT_NO_ERROR){
if (tags &&
tags->eccResult > YAFFS_ECC_RESULT_NO_ERROR) {
yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, chunkInNAND/dev->nChunksPerBlock);
yaffs_HandleChunkError(dev,bi);
yaffs_HandleChunkError(dev, bi);
}
return result;
}
int yaffs_WriteChunkWithTagsToNAND(yaffs_Device * dev,
int yaffs_WriteChunkWithTagsToNAND(yaffs_Device *dev,
int chunkInNAND,
const __u8 * buffer,
yaffs_ExtendedTags * tags)
const __u8 *buffer,
yaffs_ExtendedTags *tags)
{
chunkInNAND -= dev->chunkOffset;
@ -84,7 +85,7 @@ int yaffs_WriteChunkWithTagsToNAND(yaffs_Device * dev,
tags);
}
int yaffs_MarkBlockBad(yaffs_Device * dev, int blockNo)
int yaffs_MarkBlockBad(yaffs_Device *dev, int blockNo)
{
blockNo -= dev->blockOffset;
@ -95,10 +96,10 @@ int yaffs_MarkBlockBad(yaffs_Device * dev, int blockNo)
return yaffs_TagsCompatabilityMarkNANDBlockBad(dev, blockNo);
}
int yaffs_QueryInitialBlockState(yaffs_Device * dev,
int yaffs_QueryInitialBlockState(yaffs_Device *dev,
int blockNo,
yaffs_BlockState * state,
unsigned *sequenceNumber)
yaffs_BlockState *state,
__u32 *sequenceNumber)
{
blockNo -= dev->blockOffset;

View file

@ -19,21 +19,21 @@
int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
__u8 * buffer,
yaffs_ExtendedTags * tags);
int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
__u8 *buffer,
yaffs_ExtendedTags *tags);
int yaffs_WriteChunkWithTagsToNAND(yaffs_Device * dev,
int chunkInNAND,
const __u8 * buffer,
yaffs_ExtendedTags * tags);
int yaffs_WriteChunkWithTagsToNAND(yaffs_Device *dev,
int chunkInNAND,
const __u8 *buffer,
yaffs_ExtendedTags *tags);
int yaffs_MarkBlockBad(yaffs_Device * dev, int blockNo);
int yaffs_MarkBlockBad(yaffs_Device *dev, int blockNo);
int yaffs_QueryInitialBlockState(yaffs_Device * dev,
int blockNo,
yaffs_BlockState * state,
unsigned *sequenceNumber);
int yaffs_QueryInitialBlockState(yaffs_Device *dev,
int blockNo,
yaffs_BlockState *state,
unsigned *sequenceNumber);
int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,
int blockInNAND);

View file

@ -21,14 +21,14 @@
#include "yaffs_guts.h"
int nandemul2k_WriteChunkWithTagsToNAND(struct yaffs_DeviceStruct *dev,
int chunkInNAND, const __u8 * data,
yaffs_ExtendedTags * tags);
int chunkInNAND, const __u8 *data,
const yaffs_ExtendedTags *tags);
int nandemul2k_ReadChunkWithTagsFromNAND(struct yaffs_DeviceStruct *dev,
int chunkInNAND, __u8 * data,
yaffs_ExtendedTags * tags);
int chunkInNAND, __u8 *data,
yaffs_ExtendedTags *tags);
int nandemul2k_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo);
int nandemul2k_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
yaffs_BlockState * state, int *sequenceNumber);
yaffs_BlockState *state, __u32 *sequenceNumber);
int nandemul2k_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,
int blockInNAND);
int nandemul2k_InitialiseNAND(struct yaffs_DeviceStruct *dev);

View file

@ -14,7 +14,7 @@
#include "yaffs_packedtags1.h"
#include "yportenv.h"
void yaffs_PackTags1(yaffs_PackedTags1 * pt, const yaffs_ExtendedTags * t)
void yaffs_PackTags1(yaffs_PackedTags1 *pt, const yaffs_ExtendedTags *t)
{
pt->chunkId = t->chunkId;
pt->serialNumber = t->serialNumber;
@ -27,7 +27,7 @@ void yaffs_PackTags1(yaffs_PackedTags1 * pt, const yaffs_ExtendedTags * t)
}
void yaffs_UnpackTags1(yaffs_ExtendedTags * t, const yaffs_PackedTags1 * pt)
void yaffs_UnpackTags1(yaffs_ExtendedTags *t, const yaffs_PackedTags1 *pt)
{
static const __u8 allFF[] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@ -35,9 +35,8 @@ void yaffs_UnpackTags1(yaffs_ExtendedTags * t, const yaffs_PackedTags1 * pt)
if (memcmp(allFF, pt, sizeof(yaffs_PackedTags1))) {
t->blockBad = 0;
if (pt->shouldBeFF != 0xFFFFFFFF) {
if (pt->shouldBeFF != 0xFFFFFFFF)
t->blockBad = 1;
}
t->chunkUsed = 1;
t->objectId = pt->objectId;
t->chunkId = pt->chunkId;
@ -47,6 +46,5 @@ void yaffs_UnpackTags1(yaffs_ExtendedTags * t, const yaffs_PackedTags1 * pt)
t->serialNumber = pt->serialNumber;
} else {
memset(t, 0, sizeof(yaffs_ExtendedTags));
}
}

View file

@ -32,6 +32,6 @@ typedef struct {
} yaffs_PackedTags1;
void yaffs_PackTags1(yaffs_PackedTags1 * pt, const yaffs_ExtendedTags * t);
void yaffs_UnpackTags1(yaffs_ExtendedTags * t, const yaffs_PackedTags1 * pt);
void yaffs_PackTags1(yaffs_PackedTags1 *pt, const yaffs_ExtendedTags *t);
void yaffs_UnpackTags1(yaffs_ExtendedTags *t, const yaffs_PackedTags1 *pt);
#endif

View file

@ -37,60 +37,68 @@
#define EXTRA_OBJECT_TYPE_SHIFT (28)
#define EXTRA_OBJECT_TYPE_MASK ((0x0F) << EXTRA_OBJECT_TYPE_SHIFT)
static void yaffs_DumpPackedTags2(const yaffs_PackedTags2 * pt)
static void yaffs_DumpPackedTags2TagsPart(const yaffs_PackedTags2TagsPart *ptt)
{
T(YAFFS_TRACE_MTD,
(TSTR("packed tags obj %d chunk %d byte %d seq %d" TENDSTR),
pt->t.objectId, pt->t.chunkId, pt->t.byteCount,
pt->t.sequenceNumber));
ptt->objectId, ptt->chunkId, ptt->byteCount,
ptt->sequenceNumber));
}
static void yaffs_DumpPackedTags2(const yaffs_PackedTags2 *pt)
{
yaffs_DumpPackedTags2TagsPart(&pt->t);
}
static void yaffs_DumpTags2(const yaffs_ExtendedTags * t)
static void yaffs_DumpTags2(const yaffs_ExtendedTags *t)
{
T(YAFFS_TRACE_MTD,
(TSTR
("ext.tags eccres %d blkbad %d chused %d obj %d chunk%d byte "
"%d del %d ser %d seq %d"
("ext.tags eccres %d blkbad %d chused %d obj %d chunk%d byte %d del %d ser %d seq %d"
TENDSTR), t->eccResult, t->blockBad, t->chunkUsed, t->objectId,
t->chunkId, t->byteCount, t->chunkDeleted, t->serialNumber,
t->sequenceNumber));
}
void yaffs_PackTags2(yaffs_PackedTags2 * pt, const yaffs_ExtendedTags * t)
void yaffs_PackTags2TagsPart(yaffs_PackedTags2TagsPart *ptt,
const yaffs_ExtendedTags *t)
{
pt->t.chunkId = t->chunkId;
pt->t.sequenceNumber = t->sequenceNumber;
pt->t.byteCount = t->byteCount;
pt->t.objectId = t->objectId;
ptt->chunkId = t->chunkId;
ptt->sequenceNumber = t->sequenceNumber;
ptt->byteCount = t->byteCount;
ptt->objectId = t->objectId;
if (t->chunkId == 0 && t->extraHeaderInfoAvailable) {
/* Store the extra header info instead */
/* We save the parent object in the chunkId */
pt->t.chunkId = EXTRA_HEADER_INFO_FLAG
ptt->chunkId = EXTRA_HEADER_INFO_FLAG
| t->extraParentObjectId;
if (t->extraIsShrinkHeader) {
pt->t.chunkId |= EXTRA_SHRINK_FLAG;
}
if (t->extraShadows) {
pt->t.chunkId |= EXTRA_SHADOWS_FLAG;
}
if (t->extraIsShrinkHeader)
ptt->chunkId |= EXTRA_SHRINK_FLAG;
if (t->extraShadows)
ptt->chunkId |= EXTRA_SHADOWS_FLAG;
pt->t.objectId &= ~EXTRA_OBJECT_TYPE_MASK;
pt->t.objectId |=
ptt->objectId &= ~EXTRA_OBJECT_TYPE_MASK;
ptt->objectId |=
(t->extraObjectType << EXTRA_OBJECT_TYPE_SHIFT);
if (t->extraObjectType == YAFFS_OBJECT_TYPE_HARDLINK) {
pt->t.byteCount = t->extraEquivalentObjectId;
} else if (t->extraObjectType == YAFFS_OBJECT_TYPE_FILE) {
pt->t.byteCount = t->extraFileLength;
} else {
pt->t.byteCount = 0;
}
if (t->extraObjectType == YAFFS_OBJECT_TYPE_HARDLINK)
ptt->byteCount = t->extraEquivalentObjectId;
else if (t->extraObjectType == YAFFS_OBJECT_TYPE_FILE)
ptt->byteCount = t->extraFileLength;
else
ptt->byteCount = 0;
}
yaffs_DumpPackedTags2(pt);
yaffs_DumpPackedTags2TagsPart(ptt);
yaffs_DumpTags2(t);
}
void yaffs_PackTags2(yaffs_PackedTags2 *pt, const yaffs_ExtendedTags *t)
{
yaffs_PackTags2TagsPart(&pt->t, t);
#ifndef YAFFS_IGNORE_TAGS_ECC
{
@ -101,20 +109,63 @@ void yaffs_PackTags2(yaffs_PackedTags2 * pt, const yaffs_ExtendedTags * t)
#endif
}
void yaffs_UnpackTags2(yaffs_ExtendedTags * t, yaffs_PackedTags2 * pt)
void yaffs_UnpackTags2TagsPart(yaffs_ExtendedTags *t,
yaffs_PackedTags2TagsPart *ptt)
{
memset(t, 0, sizeof(yaffs_ExtendedTags));
yaffs_InitialiseTags(t);
if (ptt->sequenceNumber != 0xFFFFFFFF) {
t->blockBad = 0;
t->chunkUsed = 1;
t->objectId = ptt->objectId;
t->chunkId = ptt->chunkId;
t->byteCount = ptt->byteCount;
t->chunkDeleted = 0;
t->serialNumber = 0;
t->sequenceNumber = ptt->sequenceNumber;
/* Do extra header info stuff */
if (ptt->chunkId & EXTRA_HEADER_INFO_FLAG) {
t->chunkId = 0;
t->byteCount = 0;
t->extraHeaderInfoAvailable = 1;
t->extraParentObjectId =
ptt->chunkId & (~(ALL_EXTRA_FLAGS));
t->extraIsShrinkHeader =
(ptt->chunkId & EXTRA_SHRINK_FLAG) ? 1 : 0;
t->extraShadows =
(ptt->chunkId & EXTRA_SHADOWS_FLAG) ? 1 : 0;
t->extraObjectType =
ptt->objectId >> EXTRA_OBJECT_TYPE_SHIFT;
t->objectId &= ~EXTRA_OBJECT_TYPE_MASK;
if (t->extraObjectType == YAFFS_OBJECT_TYPE_HARDLINK)
t->extraEquivalentObjectId = ptt->byteCount;
else
t->extraFileLength = ptt->byteCount;
}
}
yaffs_DumpPackedTags2TagsPart(ptt);
yaffs_DumpTags2(t);
}
void yaffs_UnpackTags2(yaffs_ExtendedTags *t, yaffs_PackedTags2 *pt)
{
yaffs_ECCResult eccResult = YAFFS_ECC_RESULT_NO_ERROR;
if (pt->t.sequenceNumber != 0xFFFFFFFF) {
/* Page is in use */
#ifdef YAFFS_IGNORE_TAGS_ECC
{
t->eccResult = YAFFS_ECC_RESULT_NO_ERROR;
}
#else
#ifndef YAFFS_IGNORE_TAGS_ECC
{
yaffs_ECCOther ecc;
int result;
@ -127,56 +178,29 @@ void yaffs_UnpackTags2(yaffs_ExtendedTags * t, yaffs_PackedTags2 * pt)
sizeof
(yaffs_PackedTags2TagsPart),
&pt->ecc, &ecc);
switch(result){
case 0:
t->eccResult = YAFFS_ECC_RESULT_NO_ERROR;
break;
case 1:
t->eccResult = YAFFS_ECC_RESULT_FIXED;
break;
case -1:
t->eccResult = YAFFS_ECC_RESULT_UNFIXED;
break;
default:
t->eccResult = YAFFS_ECC_RESULT_UNKNOWN;
switch (result) {
case 0:
eccResult = YAFFS_ECC_RESULT_NO_ERROR;
break;
case 1:
eccResult = YAFFS_ECC_RESULT_FIXED;
break;
case -1:
eccResult = YAFFS_ECC_RESULT_UNFIXED;
break;
default:
eccResult = YAFFS_ECC_RESULT_UNKNOWN;
}
}
#endif
t->blockBad = 0;
t->chunkUsed = 1;
t->objectId = pt->t.objectId;
t->chunkId = pt->t.chunkId;
t->byteCount = pt->t.byteCount;
t->chunkDeleted = 0;
t->serialNumber = 0;
t->sequenceNumber = pt->t.sequenceNumber;
/* Do extra header info stuff */
if (pt->t.chunkId & EXTRA_HEADER_INFO_FLAG) {
t->chunkId = 0;
t->byteCount = 0;
t->extraHeaderInfoAvailable = 1;
t->extraParentObjectId =
pt->t.chunkId & (~(ALL_EXTRA_FLAGS));
t->extraIsShrinkHeader =
(pt->t.chunkId & EXTRA_SHRINK_FLAG) ? 1 : 0;
t->extraShadows =
(pt->t.chunkId & EXTRA_SHADOWS_FLAG) ? 1 : 0;
t->extraObjectType =
pt->t.objectId >> EXTRA_OBJECT_TYPE_SHIFT;
t->objectId &= ~EXTRA_OBJECT_TYPE_MASK;
if (t->extraObjectType == YAFFS_OBJECT_TYPE_HARDLINK) {
t->extraEquivalentObjectId = pt->t.byteCount;
} else {
t->extraFileLength = pt->t.byteCount;
}
}
}
yaffs_UnpackTags2TagsPart(t, &pt->t);
t->eccResult = eccResult;
yaffs_DumpPackedTags2(pt);
yaffs_DumpTags2(t);
}

View file

@ -33,6 +33,11 @@ typedef struct {
yaffs_ECCOther ecc;
} yaffs_PackedTags2;
void yaffs_PackTags2(yaffs_PackedTags2 * pt, const yaffs_ExtendedTags * t);
void yaffs_UnpackTags2(yaffs_ExtendedTags * t, yaffs_PackedTags2 * pt);
/* Full packed tags with ECC, used for oob tags */
void yaffs_PackTags2(yaffs_PackedTags2 *pt, const yaffs_ExtendedTags *t);
void yaffs_UnpackTags2(yaffs_ExtendedTags *t, yaffs_PackedTags2 *pt);
/* Only the tags part (no ECC for use with inband tags */
void yaffs_PackTags2TagsPart(yaffs_PackedTags2TagsPart *pt, const yaffs_ExtendedTags *t);
void yaffs_UnpackTags2TagsPart(yaffs_ExtendedTags *t, yaffs_PackedTags2TagsPart *pt);
#endif

View file

@ -28,12 +28,12 @@
*/
#include "yportenv.h"
//#include <linux/string.h>
/* #include <linux/string.h> */
/*
* Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
*/
#define swapcode(TYPE, parmi, parmj, n) { \
#define swapcode(TYPE, parmi, parmj, n) do { \
long i = (n) / sizeof (TYPE); \
register TYPE *pi = (TYPE *) (parmi); \
register TYPE *pj = (TYPE *) (parmj); \
@ -41,28 +41,29 @@
register TYPE t = *pi; \
*pi++ = *pj; \
*pj++ = t; \
} while (--i > 0); \
}
} while (--i > 0); \
} while (0)
#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
es % sizeof(long) ? 2 : es == sizeof(long) ? 0 : 1;
static __inline void
swapfunc(char *a, char *b, int n, int swaptype)
{
if (swaptype <= 1)
swapcode(long, a, b, n)
swapcode(long, a, b, n);
else
swapcode(char, a, b, n)
swapcode(char, a, b, n);
}
#define swap(a, b) \
#define yswap(a, b) do { \
if (swaptype == 0) { \
long t = *(long *)(a); \
*(long *)(a) = *(long *)(b); \
*(long *)(b) = t; \
} else \
swapfunc(a, b, es, swaptype)
swapfunc(a, b, es, swaptype); \
} while (0)
#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
@ -70,12 +71,12 @@ static __inline char *
med3(char *a, char *b, char *c, int (*cmp)(const void *, const void *))
{
return cmp(a, b) < 0 ?
(cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
:(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
(cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a))
: (cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c));
}
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
void
@ -92,7 +93,7 @@ loop: SWAPINIT(a, es);
for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es)
for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
pl -= es)
swap(pl, pl - es);
yswap(pl, pl - es);
return;
}
pm = (char *)a + (n / 2) * es;
@ -107,7 +108,7 @@ loop: SWAPINIT(a, es);
}
pm = med3(pl, pm, pn, cmp);
}
swap(a, pm);
yswap(a, pm);
pa = pb = (char *)a + es;
pc = pd = (char *)a + (n - 1) * es;
@ -115,7 +116,7 @@ loop: SWAPINIT(a, es);
while (pb <= pc && (r = cmp(pb, a)) <= 0) {
if (r == 0) {
swap_cnt = 1;
swap(pa, pb);
yswap(pa, pb);
pa += es;
}
pb += es;
@ -123,14 +124,14 @@ loop: SWAPINIT(a, es);
while (pb <= pc && (r = cmp(pc, a)) >= 0) {
if (r == 0) {
swap_cnt = 1;
swap(pc, pd);
yswap(pc, pd);
pd -= es;
}
pc -= es;
}
if (pb > pc)
break;
swap(pb, pc);
yswap(pb, pc);
swap_cnt = 1;
pb += es;
pc -= es;
@ -139,7 +140,7 @@ loop: SWAPINIT(a, es);
for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
pl -= es)
swap(pl, pl - es);
yswap(pl, pl - es);
return;
}
@ -148,9 +149,11 @@ loop: SWAPINIT(a, es);
vecswap(a, pb - r, r);
r = min((long)(pd - pc), (long)(pn - pd - es));
vecswap(pb, pn - r, r);
if ((r = pb - pa) > es)
r = pb - pa;
if (r > es)
yaffs_qsort(a, r / es, es, cmp);
if ((r = pd - pc) > es) {
r = pd - pc;
if (r > es) {
/* Iterate rather than recurse to save stack space */
a = pn - r;
n = r / es;

View file

@ -17,7 +17,7 @@
#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 *));
extern void yaffs_qsort(void *const base, size_t total_elems, size_t size,
int (*cmp)(const void *, const void *));
#endif

View file

@ -14,16 +14,17 @@
#include "yaffs_guts.h"
#include "yaffs_tagscompat.h"
#include "yaffs_ecc.h"
#include "yaffs_getblockinfo.h"
static void yaffs_HandleReadDataError(yaffs_Device * dev, int chunkInNAND);
static void yaffs_HandleReadDataError(yaffs_Device *dev, int chunkInNAND);
#ifdef NOTYET
static void yaffs_CheckWrittenBlock(yaffs_Device * dev, int chunkInNAND);
static void yaffs_HandleWriteChunkOk(yaffs_Device * dev, int chunkInNAND,
const __u8 * data,
const yaffs_Spare * spare);
static void yaffs_HandleUpdateChunk(yaffs_Device * dev, int chunkInNAND,
const yaffs_Spare * spare);
static void yaffs_HandleWriteChunkError(yaffs_Device * dev, int chunkInNAND);
static void yaffs_CheckWrittenBlock(yaffs_Device *dev, int chunkInNAND);
static void yaffs_HandleWriteChunkOk(yaffs_Device *dev, int chunkInNAND,
const __u8 *data,
const yaffs_Spare *spare);
static void yaffs_HandleUpdateChunk(yaffs_Device *dev, int chunkInNAND,
const yaffs_Spare *spare);
static void yaffs_HandleWriteChunkError(yaffs_Device *dev, int chunkInNAND);
#endif
static const char yaffs_countBitsTable[256] = {
@ -54,13 +55,13 @@ int yaffs_CountBits(__u8 x)
/********** Tags ECC calculations *********/
void yaffs_CalcECC(const __u8 * data, yaffs_Spare * spare)
void yaffs_CalcECC(const __u8 *data, yaffs_Spare *spare)
{
yaffs_ECCCalculate(data, spare->ecc1);
yaffs_ECCCalculate(&data[256], spare->ecc2);
}
void yaffs_CalcTagsECC(yaffs_Tags * tags)
void yaffs_CalcTagsECC(yaffs_Tags *tags)
{
/* Calculate an ecc */
@ -74,9 +75,8 @@ void yaffs_CalcTagsECC(yaffs_Tags * tags)
for (i = 0; i < 8; i++) {
for (j = 1; j & 0xff; j <<= 1) {
bit++;
if (b[i] & j) {
if (b[i] & j)
ecc ^= bit;
}
}
}
@ -84,7 +84,7 @@ void yaffs_CalcTagsECC(yaffs_Tags * tags)
}
int yaffs_CheckECCOnTags(yaffs_Tags * tags)
int yaffs_CheckECCOnTags(yaffs_Tags *tags)
{
unsigned ecc = tags->ecc;
@ -115,8 +115,8 @@ int yaffs_CheckECCOnTags(yaffs_Tags * tags)
/********** Tags **********/
static void yaffs_LoadTagsIntoSpare(yaffs_Spare * sparePtr,
yaffs_Tags * tagsPtr)
static void yaffs_LoadTagsIntoSpare(yaffs_Spare *sparePtr,
yaffs_Tags *tagsPtr)
{
yaffs_TagsUnion *tu = (yaffs_TagsUnion *) tagsPtr;
@ -132,8 +132,8 @@ static void yaffs_LoadTagsIntoSpare(yaffs_Spare * sparePtr,
sparePtr->tagByte7 = tu->asBytes[7];
}
static void yaffs_GetTagsFromSpare(yaffs_Device * dev, yaffs_Spare * sparePtr,
yaffs_Tags * tagsPtr)
static void yaffs_GetTagsFromSpare(yaffs_Device *dev, yaffs_Spare *sparePtr,
yaffs_Tags *tagsPtr)
{
yaffs_TagsUnion *tu = (yaffs_TagsUnion *) tagsPtr;
int result;
@ -148,21 +148,20 @@ static void yaffs_GetTagsFromSpare(yaffs_Device * dev, yaffs_Spare * sparePtr,
tu->asBytes[7] = sparePtr->tagByte7;
result = yaffs_CheckECCOnTags(tagsPtr);
if (result > 0) {
if (result > 0)
dev->tagsEccFixed++;
} else if (result < 0) {
else if (result < 0)
dev->tagsEccUnfixed++;
}
}
static void yaffs_SpareInitialise(yaffs_Spare * spare)
static void yaffs_SpareInitialise(yaffs_Spare *spare)
{
memset(spare, 0xFF, sizeof(yaffs_Spare));
}
static int yaffs_WriteChunkToNAND(struct yaffs_DeviceStruct *dev,
int chunkInNAND, const __u8 * data,
yaffs_Spare * spare)
int chunkInNAND, const __u8 *data,
yaffs_Spare *spare)
{
if (chunkInNAND < dev->startBlock * dev->nChunksPerBlock) {
T(YAFFS_TRACE_ERROR,
@ -177,9 +176,9 @@ static int yaffs_WriteChunkToNAND(struct yaffs_DeviceStruct *dev,
static int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,
int chunkInNAND,
__u8 * data,
yaffs_Spare * spare,
yaffs_ECCResult * eccResult,
__u8 *data,
yaffs_Spare *spare,
yaffs_ECCResult *eccResult,
int doErrorCorrection)
{
int retVal;
@ -252,9 +251,11 @@ static int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,
/* Must allocate enough memory for spare+2*sizeof(int) */
/* for ecc results from device. */
struct yaffs_NANDSpare nspare;
retVal =
dev->readChunkFromNAND(dev, chunkInNAND, data,
(yaffs_Spare *) & nspare);
memset(&nspare, 0, sizeof(nspare));
retVal = dev->readChunkFromNAND(dev, chunkInNAND, data,
(yaffs_Spare *) &nspare);
memcpy(spare, &nspare, sizeof(yaffs_Spare));
if (data && doErrorCorrection) {
if (nspare.eccres1 > 0) {
@ -302,8 +303,7 @@ static int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,
static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,
int chunkInNAND)
{
static int init = 0;
static int init;
static __u8 cmpbuf[YAFFS_BYTES_PER_CHUNK];
static __u8 data[YAFFS_BYTES_PER_CHUNK];
/* Might as well always allocate the larger size for */
@ -331,12 +331,12 @@ static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,
* Functions for robustisizing
*/
static void yaffs_HandleReadDataError(yaffs_Device * dev, int chunkInNAND)
static void yaffs_HandleReadDataError(yaffs_Device *dev, int chunkInNAND)
{
int blockInNAND = chunkInNAND / dev->nChunksPerBlock;
/* Mark the block for retirement */
yaffs_GetBlockInfo(dev, blockInNAND)->needsRetiring = 1;
yaffs_GetBlockInfo(dev, blockInNAND + dev->blockOffset)->needsRetiring = 1;
T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
(TSTR("**>>Block %d marked for retirement" TENDSTR), blockInNAND));
@ -348,22 +348,22 @@ static void yaffs_HandleReadDataError(yaffs_Device * dev, int chunkInNAND)
}
#ifdef NOTYET
static void yaffs_CheckWrittenBlock(yaffs_Device * dev, int chunkInNAND)
static void yaffs_CheckWrittenBlock(yaffs_Device *dev, int chunkInNAND)
{
}
static void yaffs_HandleWriteChunkOk(yaffs_Device * dev, int chunkInNAND,
const __u8 * data,
const yaffs_Spare * spare)
static void yaffs_HandleWriteChunkOk(yaffs_Device *dev, int chunkInNAND,
const __u8 *data,
const yaffs_Spare *spare)
{
}
static void yaffs_HandleUpdateChunk(yaffs_Device * dev, int chunkInNAND,
const yaffs_Spare * spare)
static void yaffs_HandleUpdateChunk(yaffs_Device *dev, int chunkInNAND,
const yaffs_Spare *spare)
{
}
static void yaffs_HandleWriteChunkError(yaffs_Device * dev, int chunkInNAND)
static void yaffs_HandleWriteChunkError(yaffs_Device *dev, int chunkInNAND)
{
int blockInNAND = chunkInNAND / dev->nChunksPerBlock;
@ -373,8 +373,8 @@ static void yaffs_HandleWriteChunkError(yaffs_Device * dev, int chunkInNAND)
yaffs_DeleteChunk(dev, chunkInNAND, 1, __LINE__);
}
static int yaffs_VerifyCompare(const __u8 * d0, const __u8 * d1,
const yaffs_Spare * s0, const yaffs_Spare * s1)
static int yaffs_VerifyCompare(const __u8 *d0, const __u8 *d1,
const yaffs_Spare *s0, const yaffs_Spare *s1)
{
if (memcmp(d0, d1, YAFFS_BYTES_PER_CHUNK) != 0 ||
@ -398,28 +398,35 @@ static int yaffs_VerifyCompare(const __u8 * d0, const __u8 * d1,
}
#endif /* NOTYET */
int yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(yaffs_Device * dev,
int chunkInNAND,
const __u8 * data,
const yaffs_ExtendedTags *
eTags)
int yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(yaffs_Device *dev,
int chunkInNAND,
const __u8 *data,
const yaffs_ExtendedTags *eTags)
{
yaffs_Spare spare;
yaffs_Tags tags;
yaffs_SpareInitialise(&spare);
if (eTags->chunkDeleted) {
if (eTags->chunkDeleted)
spare.pageStatus = 0;
} else {
else {
tags.objectId = eTags->objectId;
tags.chunkId = eTags->chunkId;
tags.byteCount = eTags->byteCount;
tags.byteCountLSB = eTags->byteCount & 0x3ff;
if (dev->nDataBytesPerChunk >= 1024)
tags.byteCountMSB = (eTags->byteCount >> 10) & 3;
else
tags.byteCountMSB = 3;
tags.serialNumber = eTags->serialNumber;
if (!dev->useNANDECC && data) {
if (!dev->useNANDECC && data)
yaffs_CalcECC(data, &spare);
}
yaffs_LoadTagsIntoSpare(&spare, &tags);
}
@ -427,15 +434,15 @@ int yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(yaffs_Device * dev,
return yaffs_WriteChunkToNAND(dev, chunkInNAND, data, &spare);
}
int yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(yaffs_Device * dev,
int yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(yaffs_Device *dev,
int chunkInNAND,
__u8 * data,
yaffs_ExtendedTags * eTags)
__u8 *data,
yaffs_ExtendedTags *eTags)
{
yaffs_Spare spare;
yaffs_Tags tags;
yaffs_ECCResult eccResult;
yaffs_ECCResult eccResult = YAFFS_ECC_RESULT_UNKNOWN;
static yaffs_Spare spareFF;
static int init;
@ -466,7 +473,11 @@ int yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(yaffs_Device * dev,
eTags->objectId = tags.objectId;
eTags->chunkId = tags.chunkId;
eTags->byteCount = tags.byteCount;
eTags->byteCount = tags.byteCountLSB;
if (dev->nDataBytesPerChunk >= 1024)
eTags->byteCount |= (((unsigned) tags.byteCountMSB) << 10);
eTags->serialNumber = tags.serialNumber;
}
}
@ -497,9 +508,9 @@ int yaffs_TagsCompatabilityMarkNANDBlockBad(struct yaffs_DeviceStruct *dev,
}
int yaffs_TagsCompatabilityQueryNANDBlock(struct yaffs_DeviceStruct *dev,
int blockNo, yaffs_BlockState *
state,
int *sequenceNumber)
int blockNo,
yaffs_BlockState *state,
__u32 *sequenceNumber)
{
yaffs_Spare spare0, spare1;

View file

@ -17,24 +17,23 @@
#define __YAFFS_TAGSCOMPAT_H__
#include "yaffs_guts.h"
int yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(yaffs_Device * dev,
int chunkInNAND,
const __u8 * data,
const yaffs_ExtendedTags *
tags);
int yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(yaffs_Device * dev,
int chunkInNAND,
__u8 * data,
yaffs_ExtendedTags *
tags);
int yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(yaffs_Device *dev,
int chunkInNAND,
const __u8 *data,
const yaffs_ExtendedTags *tags);
int yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(yaffs_Device *dev,
int chunkInNAND,
__u8 *data,
yaffs_ExtendedTags *tags);
int yaffs_TagsCompatabilityMarkNANDBlockBad(struct yaffs_DeviceStruct *dev,
int blockNo);
int yaffs_TagsCompatabilityQueryNANDBlock(struct yaffs_DeviceStruct *dev,
int blockNo, yaffs_BlockState *
state, int *sequenceNumber);
int blockNo,
yaffs_BlockState *state,
__u32 *sequenceNumber);
void yaffs_CalcTagsECC(yaffs_Tags * tags);
int yaffs_CheckECCOnTags(yaffs_Tags * tags);
void yaffs_CalcTagsECC(yaffs_Tags *tags);
int yaffs_CheckECCOnTags(yaffs_Tags *tags);
int yaffs_CountBits(__u8 byte);
#endif

View file

@ -13,14 +13,14 @@
#include "yaffs_tagsvalidity.h"
void yaffs_InitialiseTags(yaffs_ExtendedTags * tags)
void yaffs_InitialiseTags(yaffs_ExtendedTags *tags)
{
memset(tags, 0, sizeof(yaffs_ExtendedTags));
tags->validMarker0 = 0xAAAAAAAA;
tags->validMarker1 = 0x55555555;
}
int yaffs_ValidateTags(yaffs_ExtendedTags * tags)
int yaffs_ValidateTags(yaffs_ExtendedTags *tags)
{
return (tags->validMarker0 == 0xAAAAAAAA &&
tags->validMarker1 == 0x55555555);

View file

@ -19,6 +19,6 @@
#include "yaffs_guts.h"
void yaffs_InitialiseTags(yaffs_ExtendedTags * tags);
int yaffs_ValidateTags(yaffs_ExtendedTags * tags);
void yaffs_InitialiseTags(yaffs_ExtendedTags *tags);
int yaffs_ValidateTags(yaffs_ExtendedTags *tags);
#endif

View file

@ -17,17 +17,28 @@
#ifndef __YPORTENV_H__
#define __YPORTENV_H__
/*
* Define the MTD version in terms of Linux Kernel versions
* This allows yaffs to be used independantly of the kernel
* as well as with it.
*/
#define MTD_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
#if defined CONFIG_YAFFS_WINCE
#include "ywinceenv.h"
#elif defined __KERNEL__
#elif defined __KERNEL__
#include "moduleconfig.h"
/* Linux kernel */
#include <linux/version.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
#define MTD_VERSION_CODE LINUX_VERSION_CODE
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
#include <linux/config.h>
#endif
#include <linux/kernel.h>
@ -40,12 +51,13 @@
#define YCHAR char
#define YUCHAR unsigned char
#define _Y(x) x
#define yaffs_strcpy(a,b) strcpy(a,b)
#define yaffs_strncpy(a,b,c) strncpy(a,b,c)
#define yaffs_strncmp(a,b,c) strncmp(a,b,c)
#define yaffs_strlen(s) strlen(s)
#define yaffs_sprintf sprintf
#define yaffs_toupper(a) toupper(a)
#define yaffs_strcat(a, b) strcat(a, b)
#define yaffs_strcpy(a, b) strcpy(a, b)
#define yaffs_strncpy(a, b, c) strncpy(a, b, c)
#define yaffs_strncmp(a, b, c) strncmp(a, b, c)
#define yaffs_strlen(s) strlen(s)
#define yaffs_sprintf sprintf
#define yaffs_toupper(a) toupper(a)
#define Y_INLINE inline
@ -53,19 +65,19 @@
#define YAFFS_LOSTNFOUND_PREFIX "obj"
/* #define YPRINTF(x) printk x */
#define YMALLOC(x) kmalloc(x,GFP_KERNEL)
#define YMALLOC(x) kmalloc(x, GFP_NOFS)
#define YFREE(x) kfree(x)
#define YMALLOC_ALT(x) vmalloc(x)
#define YFREE_ALT(x) vfree(x)
#define YMALLOC_DMA(x) YMALLOC(x)
// KR - added for use in scan so processes aren't blocked indefinitely.
/* KR - added for use in scan so processes aren't blocked indefinitely. */
#define YYIELD() schedule()
#define YAFFS_ROOT_MODE 0666
#define YAFFS_LOSTNFOUND_MODE 0666
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
#define Y_CURRENT_TIME CURRENT_TIME.tv_sec
#define Y_TIME_CONVERT(x) (x).tv_sec
#else
@ -73,11 +85,12 @@
#define Y_TIME_CONVERT(x) (x)
#endif
#define yaffs_SumCompare(x,y) ((x) == (y))
#define yaffs_strcmp(a,b) strcmp(a,b)
#define yaffs_SumCompare(x, y) ((x) == (y))
#define yaffs_strcmp(a, b) strcmp(a, b)
#define TENDSTR "\n"
#define TSTR(x) KERN_WARNING x
#define TCONT(x) x
#define TOUT(p) printk p
#define yaffs_trace(mask, fmt, args...) \
@ -90,6 +103,8 @@
#elif defined CONFIG_YAFFS_DIRECT
#define MTD_VERSION_CODE MTD_VERSION(2, 6, 22)
/* Direct interface */
#include "ydirectenv.h"
@ -111,11 +126,12 @@
#define YCHAR char
#define YUCHAR unsigned char
#define _Y(x) x
#define yaffs_strcpy(a,b) strcpy(a,b)
#define yaffs_strncpy(a,b,c) strncpy(a,b,c)
#define yaffs_strlen(s) strlen(s)
#define yaffs_sprintf sprintf
#define yaffs_toupper(a) toupper(a)
#define yaffs_strcat(a, b) strcat(a, b)
#define yaffs_strcpy(a, b) strcpy(a, b)
#define yaffs_strncpy(a, b, c) strncpy(a, b, c)
#define yaffs_strlen(s) strlen(s)
#define yaffs_sprintf sprintf
#define yaffs_toupper(a) toupper(a)
#define Y_INLINE inline
@ -133,8 +149,8 @@
#define YAFFS_ROOT_MODE 0666
#define YAFFS_LOSTNFOUND_MODE 0666
#define yaffs_SumCompare(x,y) ((x) == (y))
#define yaffs_strcmp(a,b) strcmp(a,b)
#define yaffs_SumCompare(x, y) ((x) == (y))
#define yaffs_strcmp(a, b) strcmp(a, b)
#else
/* Should have specified a configuration type */
@ -178,10 +194,10 @@ extern unsigned int yaffs_wr_attempts;
#define YAFFS_TRACE_ALWAYS 0xF0000000
#define T(mask,p) do{ if((mask) & (yaffs_traceMask | YAFFS_TRACE_ALWAYS)) TOUT(p);} while(0)
#define T(mask, p) do { if ((mask) & (yaffs_traceMask | YAFFS_TRACE_ALWAYS)) TOUT(p); } while (0)
#ifndef CONFIG_YAFFS_WINCE
#define YBUG() T(YAFFS_TRACE_BUG,(TSTR("==>> yaffs bug: " __FILE__ " %d" TENDSTR),__LINE__))
#ifndef YBUG
#define YBUG() do {T(YAFFS_TRACE_BUG, (TSTR("==>> yaffs bug: " __FILE__ " %d" TENDSTR), __LINE__)); } while (0)
#endif
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff