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:
parent
73c75e0dd8
commit
56190ed0fc
35 changed files with 3171 additions and 27531 deletions
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
4
target/linux/generic/files/fs/yaffs2/NOTE.openwrt
Normal file
4
target/linux/generic/files/fs/yaffs2/NOTE.openwrt
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -12,32 +12,28 @@
|
|||
*/
|
||||
|
||||
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)
|
||||
return 0;
|
||||
T(YAFFS_TRACE_CHECKPOINT, (TSTR("checking blocks %d to %d"TENDSTR),
|
||||
|
@ -51,8 +47,7 @@ static int yaffs_CheckpointErase(yaffs_Device *dev)
|
|||
bi->blockState = YAFFS_BLOCK_STATE_EMPTY;
|
||||
dev->nErasedBlocks++;
|
||||
dev->nFreeChunks += dev->nChunksPerBlock;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
dev->markNANDBlockBad(dev, i);
|
||||
bi->blockState = YAFFS_BLOCK_STATE_DEAD;
|
||||
}
|
||||
|
@ -106,7 +101,8 @@ static void yaffs_CheckpointFindNextCheckpointBlock(yaffs_Device *dev)
|
|||
int chunk = i * dev->nChunksPerBlock;
|
||||
int realignedChunk = chunk - dev->chunkOffset;
|
||||
|
||||
dev->readChunkWithTagsFromNAND(dev,realignedChunk,NULL,&tags);
|
||||
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));
|
||||
|
||||
|
@ -142,7 +138,7 @@ int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting)
|
|||
return 0;
|
||||
|
||||
if (!dev->checkpointBuffer)
|
||||
dev->checkpointBuffer = YMALLOC_DMA(dev->nDataBytesPerChunk);
|
||||
dev->checkpointBuffer = YMALLOC_DMA(dev->totalBytesPerChunk);
|
||||
if (!dev->checkpointBuffer)
|
||||
return 0;
|
||||
|
||||
|
@ -163,8 +159,6 @@ int yaffs_CheckpointOpen(yaffs_Device *dev, int 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 */
|
||||
|
@ -191,7 +185,6 @@ int yaffs_GetCheckpointSum(yaffs_Device *dev, __u32 *sum)
|
|||
|
||||
static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
|
||||
{
|
||||
|
||||
int chunk;
|
||||
int realignedChunk;
|
||||
|
||||
|
@ -226,7 +219,8 @@ static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
|
|||
|
||||
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++;
|
||||
|
@ -257,9 +251,6 @@ int yaffs_CheckpointWrite(yaffs_Device *dev,const void *data, int nBytes)
|
|||
return -1;
|
||||
|
||||
while (i < nBytes && ok) {
|
||||
|
||||
|
||||
|
||||
dev->checkpointBuffer[dev->checkpointByteOffset] = *dataBytes;
|
||||
dev->checkpointSum += *dataBytes;
|
||||
dev->checkpointXor ^= *dataBytes;
|
||||
|
@ -273,7 +264,6 @@ int yaffs_CheckpointWrite(yaffs_Device *dev,const void *data, int nBytes)
|
|||
if (dev->checkpointByteOffset < 0 ||
|
||||
dev->checkpointByteOffset >= dev->nDataBytesPerChunk)
|
||||
ok = yaffs_CheckpointFlushBuffer(dev);
|
||||
|
||||
}
|
||||
|
||||
return i;
|
||||
|
@ -311,19 +301,21 @@ int yaffs_CheckpointRead(yaffs_Device *dev, void *data, int nBytes)
|
|||
if (dev->checkpointCurrentBlock < 0)
|
||||
ok = 0;
|
||||
else {
|
||||
|
||||
chunk = dev->checkpointCurrentBlock * dev->nChunksPerBlock +
|
||||
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->readChunkWithTagsFromNAND(dev,
|
||||
realignedChunk,
|
||||
dev->checkpointBuffer,
|
||||
&tags);
|
||||
|
||||
if (tags.chunkId != (dev->checkpointPageSequence + 1) ||
|
||||
tags.eccResult > YAFFS_ECC_RESULT_FIXED ||
|
||||
tags.sequenceNumber != YAFFS_SEQUENCE_CHECKPOINT_DATA)
|
||||
ok = 0;
|
||||
|
||||
|
@ -363,7 +355,7 @@ int yaffs_CheckpointClose(yaffs_Device *dev)
|
|||
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);
|
||||
|
@ -382,10 +374,8 @@ int yaffs_CheckpointClose(yaffs_Device *dev)
|
|||
YFREE(dev->checkpointBuffer);
|
||||
dev->checkpointBuffer = NULL;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int yaffs_CheckpointInvalidateStream(yaffs_Device *dev)
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -326,6 +323,4 @@ int yaffs_ECCCorrectOther(unsigned char *data, unsigned nBytes,
|
|||
/* Unrecoverable error */
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
34
target/linux/generic/files/fs/yaffs2/yaffs_getblockinfo.h
Normal file
34
target/linux/generic/files/fs/yaffs2/yaffs_getblockinfo.h
Normal 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
|
@ -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,7 +279,7 @@ 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 */
|
||||
|
@ -303,7 +305,7 @@ typedef struct {
|
|||
__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 */
|
||||
/* The following apply to directories, files, symlinks - not hard links */
|
||||
__u32 yst_mode; /* protection */
|
||||
|
||||
#ifdef CONFIG_YAFFS_WINCE
|
||||
|
@ -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 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;
|
||||
|
||||
|
@ -498,8 +504,7 @@ typedef struct {
|
|||
int structType;
|
||||
__u32 objectId;
|
||||
__u32 parentId;
|
||||
int chunkId;
|
||||
|
||||
int hdrChunk;
|
||||
yaffs_ObjectType variantType:3;
|
||||
__u8 deleted:1;
|
||||
__u8 softDeleted:1;
|
||||
|
@ -511,7 +516,6 @@ typedef struct {
|
|||
|
||||
int nDataChunks;
|
||||
__u32 fileSizeOrEquivalentObjectId;
|
||||
|
||||
} 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
|
||||
|
@ -573,6 +575,7 @@ struct yaffs_DeviceStruct {
|
|||
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,
|
||||
|
@ -583,7 +586,7 @@ struct yaffs_DeviceStruct {
|
|||
yaffs_ExtendedTags *tags);
|
||||
int (*markNANDBlockBad) (struct yaffs_DeviceStruct *dev, int blockNo);
|
||||
int (*queryNANDBlock) (struct yaffs_DeviceStruct *dev, int blockNo,
|
||||
yaffs_BlockState * state, int *sequenceNumber);
|
||||
yaffs_BlockState *state, __u32 *sequenceNumber);
|
||||
#endif
|
||||
|
||||
int isYaffs2;
|
||||
|
@ -599,6 +602,8 @@ struct yaffs_DeviceStruct {
|
|||
|
||||
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__
|
||||
|
||||
|
@ -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,7 +769,7 @@ 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 version;
|
||||
|
@ -797,18 +808,6 @@ typedef struct {
|
|||
__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 -----------------------*/
|
||||
|
||||
|
@ -821,7 +820,7 @@ 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_DeleteObject(yaffs_Object *obj);
|
||||
|
||||
int yaffs_GetObjectName(yaffs_Object *obj, YCHAR *name, int buffSize);
|
||||
int yaffs_GetObjectFileLength(yaffs_Object *obj);
|
||||
|
@ -899,4 +898,7 @@ 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
|
||||
|
|
|
@ -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;
|
||||
|
@ -75,14 +75,14 @@ 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)
|
||||
|
@ -139,14 +139,14 @@ 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)
|
||||
|
|
|
@ -18,6 +18,11 @@
|
|||
|
||||
#include "yaffs_guts.h"
|
||||
|
||||
#if (MTD_VERSION_CODE < MTD_VERSION(2, 6, 18))
|
||||
extern struct nand_oobinfo yaffs_oobinfo;
|
||||
extern struct nand_oobinfo yaffs_noeccinfo;
|
||||
#endif
|
||||
|
||||
int nandmtd_WriteChunkToNAND(yaffs_Device *dev, int chunkInNAND,
|
||||
const __u8 *data, const yaffs_Spare *spare);
|
||||
int nandmtd_ReadChunkFromNAND(yaffs_Device *dev, int chunkInNAND, __u8 *data,
|
||||
|
|
|
@ -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
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -288,7 +288,7 @@ int nandmtd1_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo)
|
|||
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;
|
||||
|
@ -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;
|
||||
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*/
|
||||
|
|
|
@ -23,6 +23,6 @@ int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
|
|||
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
|
||||
|
|
|
@ -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"
|
||||
|
||||
/* 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) {
|
||||
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
|
||||
yaffs_PackTags2(&pt, tags);
|
||||
|
||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
|
||||
ops.mode = MTD_OOB_AUTO;
|
||||
ops.ooblen = sizeof(pt);
|
||||
ops.len = dev->nDataBytesPerChunk;
|
||||
ops.ooblen = (dev->inbandTags) ? 0 : sizeof(pt);
|
||||
ops.len = dev->totalBytesPerChunk;
|
||||
ops.ooboffs = 0;
|
||||
ops.datbuf = (__u8 *)data;
|
||||
ops.oobbuf = (void *)&pt;
|
||||
ops.oobbuf = (dev->inbandTags) ? NULL : (void *)&pt;
|
||||
retval = mtd->write_oob(mtd, addr, &ops);
|
||||
} 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
|
||||
#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,
|
||||
mtd->write(mtd, addr, dev->totalBytesPerChunk, &dummy,
|
||||
data);
|
||||
if (tags)
|
||||
retval =
|
||||
mtd->write_oob(mtd, addr, mtd->oobsize, &dummy,
|
||||
(__u8 *) & pt);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -101,13 +99,14 @@ 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 (dev->inbandTags) {
|
||||
|
||||
if (!data) {
|
||||
localData = 1;
|
||||
data = yaffs_GetTempBuffer(dev, __LINE__);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
|
||||
if (data && !tags)
|
||||
retval = mtd->read(mtd, addr, dev->nDataBytesPerChunk,
|
||||
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)
|
||||
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 (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)));
|
||||
|
|
|
@ -24,6 +24,6 @@ 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
|
||||
|
|
|
@ -12,12 +12,13 @@
|
|||
*/
|
||||
|
||||
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,
|
||||
|
@ -98,7 +99,7 @@ int yaffs_MarkBlockBad(yaffs_Device * dev, int blockNo)
|
|||
int yaffs_QueryInitialBlockState(yaffs_Device *dev,
|
||||
int blockNo,
|
||||
yaffs_BlockState *state,
|
||||
unsigned *sequenceNumber)
|
||||
__u32 *sequenceNumber)
|
||||
{
|
||||
blockNo -= dev->blockOffset;
|
||||
|
||||
|
|
|
@ -22,13 +22,13 @@
|
|||
|
||||
int nandemul2k_WriteChunkWithTagsToNAND(struct yaffs_DeviceStruct *dev,
|
||||
int chunkInNAND, const __u8 *data,
|
||||
yaffs_ExtendedTags * tags);
|
||||
const yaffs_ExtendedTags *tags);
|
||||
int nandemul2k_ReadChunkWithTagsFromNAND(struct yaffs_DeviceStruct *dev,
|
||||
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);
|
||||
|
|
|
@ -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));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
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;
|
||||
|
@ -129,54 +180,27 @@ void yaffs_UnpackTags2(yaffs_ExtendedTags * t, yaffs_PackedTags2 * pt)
|
|||
&pt->ecc, &ecc);
|
||||
switch (result) {
|
||||
case 0:
|
||||
t->eccResult = YAFFS_ECC_RESULT_NO_ERROR;
|
||||
eccResult = YAFFS_ECC_RESULT_NO_ERROR;
|
||||
break;
|
||||
case 1:
|
||||
t->eccResult = YAFFS_ECC_RESULT_FIXED;
|
||||
eccResult = YAFFS_ECC_RESULT_FIXED;
|
||||
break;
|
||||
case -1:
|
||||
t->eccResult = YAFFS_ECC_RESULT_UNFIXED;
|
||||
eccResult = YAFFS_ECC_RESULT_UNFIXED;
|
||||
break;
|
||||
default:
|
||||
t->eccResult = YAFFS_ECC_RESULT_UNKNOWN;
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,11 @@ typedef struct {
|
|||
yaffs_ECCOther ecc;
|
||||
} yaffs_PackedTags2;
|
||||
|
||||
/* 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
|
||||
|
|
|
@ -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); \
|
||||
|
@ -42,7 +42,7 @@
|
|||
*pi++ = *pj; \
|
||||
*pj++ = t; \
|
||||
} 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;
|
||||
|
@ -51,18 +51,19 @@ 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)
|
||||
|
||||
|
@ -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;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#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);
|
||||
#ifdef NOTYET
|
||||
|
@ -74,11 +75,10 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tags->ecc = ecc;
|
||||
|
||||
|
@ -148,12 +148,11 @@ 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)
|
||||
{
|
||||
|
@ -252,8 +251,10 @@ 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,
|
||||
|
||||
memset(&nspare, 0, sizeof(nspare));
|
||||
|
||||
retVal = dev->readChunkFromNAND(dev, chunkInNAND, data,
|
||||
(yaffs_Spare *) &nspare);
|
||||
memcpy(spare, &nspare, sizeof(yaffs_Spare));
|
||||
if (data && doErrorCorrection) {
|
||||
|
@ -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 */
|
||||
|
@ -336,7 +336,7 @@ 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));
|
||||
|
||||
|
@ -401,25 +401,32 @@ static int yaffs_VerifyCompare(const __u8 * d0, const __u8 * d1,
|
|||
int yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(yaffs_Device *dev,
|
||||
int chunkInNAND,
|
||||
const __u8 *data,
|
||||
const yaffs_ExtendedTags *
|
||||
eTags)
|
||||
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);
|
||||
|
||||
}
|
||||
|
@ -435,7 +442,7 @@ int yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(yaffs_Device * dev,
|
|||
|
||||
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;
|
||||
|
|
|
@ -20,18 +20,17 @@
|
|||
int yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(yaffs_Device *dev,
|
||||
int chunkInNAND,
|
||||
const __u8 *data,
|
||||
const yaffs_ExtendedTags *
|
||||
tags);
|
||||
const yaffs_ExtendedTags *tags);
|
||||
int yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(yaffs_Device *dev,
|
||||
int chunkInNAND,
|
||||
__u8 *data,
|
||||
yaffs_ExtendedTags *
|
||||
tags);
|
||||
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);
|
||||
|
|
|
@ -17,6 +17,14 @@
|
|||
#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"
|
||||
|
@ -26,7 +34,10 @@
|
|||
#include "moduleconfig.h"
|
||||
|
||||
/* Linux kernel */
|
||||
|
||||
#include <linux/version.h>
|
||||
#define MTD_VERSION_CODE LINUX_VERSION_CODE
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
|
||||
#include <linux/config.h>
|
||||
#endif
|
||||
|
@ -40,6 +51,7 @@
|
|||
#define YCHAR char
|
||||
#define YUCHAR unsigned char
|
||||
#define _Y(x) x
|
||||
#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)
|
||||
|
@ -53,13 +65,13 @@
|
|||
#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
|
||||
|
@ -78,6 +90,7 @@
|
|||
|
||||
#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,6 +126,7 @@
|
|||
#define YCHAR char
|
||||
#define YUCHAR unsigned char
|
||||
#define _Y(x) x
|
||||
#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)
|
||||
|
@ -180,8 +196,8 @@ extern unsigned int yaffs_wr_attempts;
|
|||
|
||||
#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
Loading…
Reference in a new issue