📄 yaffs_nandif.c
字号:
/*
* YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
*
* Copyright (C) 2002-2007 Aleph One Ltd.
* for Toby Churchill Ltd and Brightstar Engineering
*
* Created by Charles Manning <charles@aleph1.co.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include "yportenv.h"
#include "yaffs_guts.h"
#include "devextras.h"
#include "yaffs_nandif.h"
#include "yaffs_packedtags2.h"
#if 0
static unsigned char *DevBufferIn(yaffs_Device *dev)
{
yfsd_WinCEDevice *cedev = (yfsd_WinCEDevice *)(dev->genericDevice);
return cedev->bufferIn;
}
static unsigned char *DevBufferOut(yaffs_Device *dev)
{
yfsd_WinCEDevice *cedev = (yfsd_WinCEDevice *)(dev->genericDevice);
return cedev->bufferOut;
}
static unsigned DevBufferSize(yaffs_Device *dev)
{
yfsd_WinCEDevice *cedev = (yfsd_WinCEDevice *)(dev->genericDevice);
return cedev->bufferSize;
}
#endif
/* 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 ynandif_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND,
const __u8 * data,
const yaffs_ExtendedTags * tags)
{
int retval = 0;
yaffs_PackedTags2 pt;
void *spare;
unsigned spareSize = 0;
unsigned char *bufferIn = DevBufferIn(dev);
unsigned char *bufferOut = DevBufferOut(dev);
unsigned bufferSize = DevBufferSize(dev);
T(YAFFS_TRACE_MTD,
(TSTR
("nandmtd2_WriteChunkWithTagsToNAND chunk %d data %p tags %p"
TENDSTR), chunkInNAND, data, tags));
/* 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(dev->inbandTags){
yaffs_PackedTags2TagsPart *pt2tp;
pt2tp = (yaffs_PackedTags2TagsPart *)(data + dev->nDataBytesPerChunk);
yaffs_PackTags2TagsPart(pt2tp,tags);
spare = NULL;
spareSize = 0;
}
else{
yaffs_PackTags2(&pt, tags);
spare = &pt;
spareSize = sizeof(yaffs_PackedTags2);
}
yramsim_WritePage(chunkInNAND,
data, dev->totalBytesPerChunk, spare, spareSize);
return YAFFS_OK;
}
int ynandif_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
__u8 * data, yaffs_ExtendedTags * tags)
{
yaffs_PackedTags2 pt;
int localData = 0;
void *spare = NULL;
unsigned spareSize;
int eccStatus; //0 = ok, 1 = fixed, -1 = unfixed
unsigned char *bufferIn = DevBufferIn(dev);
unsigned char *bufferOut = DevBufferOut(dev);
unsigned bufferSize = DevBufferSize(dev);
T(YAFFS_TRACE_MTD,
(TSTR
("nandmtd2_ReadChunkWithTagsFromNAND chunk %d data %p tags %p"
TENDSTR), chunkInNAND, data, tags));
if(!tags){
spare = NULL;
spareSize = 0;
}else if(dev->inbandTags){
if(!data) {
localData = 1;
data = yaffs_GetTempBuffer(dev,__LINE__);
}
spare = NULL;
spareSize = 0;
}
else {
spare = &pt;
spareSize = sizeof(yaffs_PackedTags2);
}
yramsim_ReadPage(chunkInNAND,
data,data ? dev->totalBytesPerChunk : 0,
spare,spareSize,
&eccStatus);
if(dev->inbandTags){
if(tags){
yaffs_PackedTags2TagsPart * pt2tp;
pt2tp = (yaffs_PackedTags2TagsPart *)&data[dev->nDataBytesPerChunk];
yaffs_UnpackTags2TagsPart(tags,pt2tp);
}
}
else {
if (tags){
yaffs_UnpackTags2(tags, &pt);
}
}
if(tags && tags->chunkUsed){
if(eccStatus == 0)
tags->eccResult = YAFFS_ECC_RESULT_NO_ERROR;
else if(eccStatus < 0)
tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
else
tags->eccResult = YAFFS_ECC_RESULT_FIXED;
}
if(localData)
yaffs_ReleaseTempBuffer(dev,data,__LINE__);
return YAFFS_OK;
}
int ynandif_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockId)
{
yramsim_MarkBlockBad(blockId);
return YAFFS_OK;
}
int ynandif_EraseBlockInNAND(struct yaffs_DeviceStruct *dev, int blockId)
{
yramsim_EraseBlock(blockId);
return YAFFS_OK;
}
static int ynandif_IsBlockOk(struct yaffs_DeviceStruct *dev, int blockId)
{
return yramsim_CheckBlockOk(blockId);
}
int ynandif_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockId, yaffs_BlockState *state, __u32 *sequenceNumber)
{
unsigned chunkNo;
yaffs_ExtendedTags tags;
*sequenceNumber = 0;
chunkNo = blockId * dev->nChunksPerBlock;
if(!ynandif_IsBlockOk(dev,blockId)){
*state = YAFFS_BLOCK_STATE_DEAD;
}
else
{
ynandif_ReadChunkWithTagsFromNAND(dev,chunkNo,NULL,&tags);
if(!tags.chunkUsed)
{
*state = YAFFS_BLOCK_STATE_EMPTY;
}
else
{
*state = YAFFS_BLOCK_STATE_NEEDS_SCANNING;
*sequenceNumber = tags.sequenceNumber;
}
}
return YAFFS_OK;
}
int ynandif_GetGeometry(yaffs_Device *dev, ynandif_Geometry *geometry)
{
yramsim_Geometry g;
yramsim_GetGeometry(&g);
geometry->startBlock = g.startBlock;
geometry->endBlock = g.endBlock;
geometry->dataSize = g.dataSize;
geometry->spareSize = g.spareSize;
geometry->pagesPerBlock = g.pagesPerBlock;
geometry->hasECC = g.hasECC;
geometry->inbandTags = g.inbandTags;
geometry->useYaffs2 = g.useYaffs2;
return YAFFS_OK;
}
int ynandif_InitialiseNAND(yaffs_Device *dev)
{
yramsim_Initialise();
return YAFFS_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -