⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 yaffs_tagscompat.c

📁 YAFFS和YASFF2文件系统的源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
{	dev->nBlockErasures++;	return dev->eraseBlockInNAND(dev,blockInNAND);}int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev){	return dev->initialiseNAND(dev);}#endif#if 0static int yaffs_WriteNewChunkToNAND(struct yaffs_DeviceStruct *dev, const __u8 *data, yaffs_Spare *spare,int useReserve){	int chunk;	int writeOk = 1;	int attempts = 0;	unsigned char rbData[YAFFS_BYTES_PER_CHUNK];	yaffs_Spare rbSpare;	do{		chunk = yaffs_AllocateChunk(dev,useReserve);		if(chunk >= 0)		{			// First check this chunk is erased...#ifndef CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK			writeOk = yaffs_CheckChunkErased(dev,chunk);#endif			if(!writeOk)			{				T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs chunk %d was not erased" TENDSTR),chunk));			}			else			{				writeOk =  yaffs_WriteChunkToNAND(dev,chunk,data,spare);			}			attempts++;			if(writeOk)			{				// Readback & verify				// If verify fails, then delete this chunk and try again				// To verify we compare everything except the block and				// page status bytes.				// NB We check a raw read without ECC correction applied				yaffs_ReadChunkFromNAND(dev,chunk,rbData,&rbSpare,0);#ifndef CONFIG_YAFFS_DISABLE_WRITE_VERIFY				if(!yaffs_VerifyCompare(data,rbData,spare,&rbSpare))				{					// Didn't verify					T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs write verify failed on chunk %d" TENDSTR), chunk));					writeOk = 0;				}#endif			}			if(writeOk)			{				// Copy the data into the write buffer.				// NB We do this at the end to prevent duplicates in the case of a write error.				//Todo				yaffs_HandleWriteChunkOk(dev,chunk,data,spare);			}			else			{				yaffs_HandleWriteChunkError(dev,chunk);			}		}	} while(chunk >= 0 && ! writeOk);	if(attempts > 1)	{		T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs write required %d attempts" TENDSTR),attempts));		dev->nRetriedWrites+= (attempts - 1);	}	return chunk;}#endif///// Functions for robustisizing////#if 0static void yaffs_RetireBlock(yaffs_Device *dev,int blockInNAND){	// Ding the blockStatus in the first two pages of the block.	yaffs_Spare spare;	memset(&spare, 0xff,sizeof(yaffs_Spare));	spare.blockStatus = 0;	// TODO change this retirement marking for other NAND types	yaffs_WriteChunkToNAND(dev, blockInNAND * dev->nChunksPerBlock, NULL , &spare);	yaffs_WriteChunkToNAND(dev, blockInNAND * dev->nChunksPerBlock + 1, NULL , &spare);	yaffs_GetBlockInfo(dev,blockInNAND)->blockState = YAFFS_BLOCK_STATE_DEAD;	dev->nRetiredBlocks++;}#endif#if 0static int yaffs_RewriteBufferedBlock(yaffs_Device *dev){	dev->doingBufferedBlockRewrite = 1;	//	//	Remove erased chunks	//  Rewrite existing chunks to a new block	//	Set current write block to the new block	dev->doingBufferedBlockRewrite = 0;	return 1;}#endifstatic void yaffs_HandleReadDataError(yaffs_Device *dev,int chunkInNAND){	int blockInNAND = chunkInNAND/dev->nChunksPerBlock;	// Mark the block for retirement	yaffs_GetBlockInfo(dev,blockInNAND)->needsRetiring = 1;	T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,(TSTR("**>>Block %d marked for retirement" TENDSTR),blockInNAND));	//TODO	// Just do a garbage collection on the affected block then retire the block	// NB recursion}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){	int blockInNAND = chunkInNAND/dev->nChunksPerBlock;	// Mark the block for retirement	yaffs_GetBlockInfo(dev,blockInNAND)->needsRetiring = 1;	// Delete the chunk	yaffs_DeleteChunk(dev,chunkInNAND,1,__LINE__);}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 ||		s0->tagByte0 != s1->tagByte0 ||		s0->tagByte1 != s1->tagByte1 ||		s0->tagByte2 != s1->tagByte2 ||		s0->tagByte3 != s1->tagByte3 ||		s0->tagByte4 != s1->tagByte4 ||		s0->tagByte5 != s1->tagByte5 ||		s0->tagByte6 != s1->tagByte6 ||		s0->tagByte7 != s1->tagByte7 ||		s0->ecc1[0]  != s1->ecc1[0]  ||		s0->ecc1[1]  != s1->ecc1[1]  ||		s0->ecc1[2]  != s1->ecc1[2]  ||		s0->ecc2[0]  != s1->ecc2[0]  ||		s0->ecc2[1]  != s1->ecc2[1]  ||		s0->ecc2[2]  != s1->ecc2[2] )		{			return 0;		}	return 1;}#if 0typedef struct{	unsigned validMarker0;	unsigned chunkUsed;		    //  Status of the chunk: used or unused	unsigned objectId;			// If 0 then this is not part of an object (unused)	unsigned chunkId;			// If 0 then this is a header	unsigned byteCount;		    // Only valid for data chunks	// The following stuff only has meaning when we read	yaffs_ECCResult eccResult;  // Only valid when we read.	unsigned blockBad;			// Only valid on reading	// YAFFS 1 stuff		unsigned chunkDeleted;		// The chunk is marked deleted	unsigned serialNumber; 		// Yaffs1 2-bit serial number		// YAFFS2 stuff	unsigned sequenceNumber; 	// The sequence number of this block	unsigned validMarker1;} yaffs_ExtendedTags;typedef struct{       unsigned chunkId:20;    unsigned serialNumber:2;    unsigned byteCount:10;    unsigned objectId:18;    unsigned ecc:12;    unsigned unusedStuff:2;} yaffs_Tags;#endifint 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)	{		spare.pageStatus = 0;	}	else	{		tags.objectId = eTags->objectId;		tags.chunkId = eTags->chunkId;		tags.byteCount = eTags->byteCount;		tags.serialNumber = eTags->serialNumber;				 yaffs_LoadTagsIntoSpare(&spare,&tags);			}		return yaffs_WriteChunkToNAND(dev,chunkInNAND,data,&spare);}int yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_ExtendedTags *eTags){	yaffs_Spare spare;	yaffs_Tags tags;	yaffs_ECCResult eccResult;		if(yaffs_ReadChunkFromNAND(dev,chunkInNAND,data,&spare,&eccResult,1))	{		 int deleted = (yaffs_CountBits(spare.pageStatus) < 7) ? 1 : 0;					 yaffs_GetTagsFromSpare(dev,&spare,&tags);		 		 eTags->chunkDeleted = deleted;		 eTags->objectId = tags.objectId;		 eTags->chunkId = tags.chunkId;		 eTags->byteCount = tags.byteCount;		 eTags->serialNumber = tags.serialNumber;		 eTags->eccResult = eccResult;		 eTags->blockBad = 0; // We're reading it therefore it is not a bad block		 		 return YAFFS_OK;	}	else	{ 		return YAFFS_FAIL;	}}int yaffs_TagsCompatabilityMarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockInNAND){	yaffs_Spare spare;	memset(&spare, 0xff,sizeof(yaffs_Spare));	spare.blockStatus = 0;	yaffs_WriteChunkToNAND(dev, blockInNAND * dev->nChunksPerBlock, NULL , &spare);	yaffs_WriteChunkToNAND(dev, blockInNAND * dev->nChunksPerBlock + 1, NULL , &spare);		return YAFFS_OK;	}int yaffs_TagsCompatabilityQueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, yaffs_BlockState *state, int *sequenceNumber){          yaffs_Spare spare0,spare1;     static yaffs_Spare spareFF;     static int init;     yaffs_ECCResult dummy;          if(!init)     {	     memset(&spareFF,0xFF,sizeof(spareFF));	     init = 1;     }          *sequenceNumber = 0;          yaffs_ReadChunkFromNAND(dev,blockNo * dev->nChunksPerBlock,NULL,&spare0,&dummy,1);     yaffs_ReadChunkFromNAND(dev,blockNo * dev->nChunksPerBlock + 1,NULL,&spare1,&dummy,1);          if(yaffs_CountBits(spare0.blockStatus & spare1.blockStatus) < 7)     	*state = YAFFS_BLOCK_STATE_DEAD;     else if(memcmp(&spareFF,&spare0,sizeof(spareFF)) == 0)         *state = YAFFS_BLOCK_STATE_EMPTY;     else	 *state = YAFFS_BLOCK_STATE_NEEDS_SCANNING;       return YAFFS_OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -