📄 yaffs_flashif.c
字号:
/* * YAFFS: Yet another FFS. A NAND-flash specific file system. * yaffs_ramdisk.c: yaffs ram disk component * * Copyright (C) 2002 Aleph One Ltd. * * Created by Charles Manning <charles@aleph1.co.uk> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * */// This provides a ram disk under yaffs.// NB this is not intended for NAND emulation.// Use this with dev->useNANDECC enabled, then ECC overheads are not required.#include "yportenv.h"#include "devextras.h"#include "yaffs_guts.h"#include "yaffs_flashif.h"#ifdef CONFIG_YAFFS_NOR_FLASH#include "..\bsp\flash.h"#define SPARE_STATE_FREE 0xFFFF#define SPARE_STATE_USED 0x0000int yflash_WriteChunkToNAND(yaffs_Device *dev, long chunkInNAND, const __u8 *data, yaffs_Spare *spare){ INT32U start = (((chunkInNAND / YAFFS_CHUNKS_PER_BLOCK) - dev->startBlock) * NOR_FLASH_BLOCK_SIZE) + ((chunkInNAND % YAFFS_CHUNKS_PER_BLOCK) * NOR_FLASH_VPAGE_SIZE); INT16U state; if (data != NULL) { if (flash_write(start, (INT8U *)data, YAFFS_BYTES_PER_CHUNK) < 0) { T(YAFFS_TRACE_ERROR, (TSTR("**>> flash: Write data to page %ld failed\n"), chunkInNAND)); return YAFFS_FAIL; } } if (spare != NULL) { if (flash_read((start+YAFFS_BYTES_PER_CHUNK+NOR_FLASH_SPARE_SIZE-sizeof(state)), (INT8U *)&state, sizeof(state)) < 0) { T(YAFFS_TRACE_ERROR, (TSTR("**>> flash: Read 1st state from page %ld failed\n"), chunkInNAND)); return YAFFS_FAIL; } if (state == SPARE_STATE_FREE) { if (flash_write((start+YAFFS_BYTES_PER_CHUNK), (INT8U *)spare, YAFFS_BYTES_PER_SPARE) < 0) { T(YAFFS_TRACE_ERROR, (TSTR("**>> flash: Write 1st spare to page %ld failed\n"), chunkInNAND)); return YAFFS_FAIL; } state = SPARE_STATE_USED; if (flash_write((start+YAFFS_BYTES_PER_CHUNK+NOR_FLASH_SPARE_SIZE-sizeof(state)), (INT8U *)&state, sizeof(state)) < 0) { T(YAFFS_TRACE_ERROR, (TSTR("**>> flash: Write 1st state to page %ld failed\n"), chunkInNAND)); return YAFFS_FAIL; } return YAFFS_OK; } if (flash_read((start+YAFFS_BYTES_PER_CHUNK+(2UL*NOR_FLASH_SPARE_SIZE)-sizeof(state)), (INT8U *)&state, sizeof(state)) < 0) { T(YAFFS_TRACE_ERROR, (TSTR("**>> flash: Read 2nd state from page %ld failed\n"), chunkInNAND)); return YAFFS_FAIL; } if (state == SPARE_STATE_FREE) { if (flash_write((start+YAFFS_BYTES_PER_CHUNK+NOR_FLASH_SPARE_SIZE), (INT8U *)spare, YAFFS_BYTES_PER_SPARE) < 0) { T(YAFFS_TRACE_ERROR, (TSTR("**>> flash: Write 2nd spare to page %ld failed\n"), chunkInNAND)); return YAFFS_FAIL; } state = SPARE_STATE_USED; if (flash_write((start+YAFFS_BYTES_PER_CHUNK+(2UL*NOR_FLASH_SPARE_SIZE)-sizeof(state)), (INT8U *)&state, sizeof(state)) < 0) { T(YAFFS_TRACE_ERROR, (TSTR("**>> flash: Write 2nd state to page %ld failed\n"), chunkInNAND)); return YAFFS_FAIL; } return YAFFS_OK; } T(YAFFS_TRACE_ERROR, (TSTR("**>> flash: No free spare for write in page %ld\n"), chunkInNAND)); return YAFFS_FAIL; } return YAFFS_OK;}int yflash_ReadChunkFromNAND(yaffs_Device *dev, long chunkInNAND, __u8 *data, yaffs_Spare *spare){ INT32U start = (((chunkInNAND / YAFFS_CHUNKS_PER_BLOCK) - dev->startBlock) * NOR_FLASH_BLOCK_SIZE) + ((chunkInNAND % YAFFS_CHUNKS_PER_BLOCK) * NOR_FLASH_VPAGE_SIZE); INT16U state; if (data != NULL) { memset(data, 0xFF, YAFFS_BYTES_PER_CHUNK); if (flash_read(start, (INT8U *)data, YAFFS_BYTES_PER_CHUNK) < 0) { T(YAFFS_TRACE_ERROR, (TSTR("**>> flash: Read data from page %ld failed\n"), chunkInNAND)); return YAFFS_FAIL; } } if (spare != NULL) { memset(spare, 0xFF, YAFFS_BYTES_PER_SPARE); if (dev->useNANDECC) { struct yaffs_NANDSpare *nsp = (struct yaffs_NANDSpare *)spare; nsp->eccres1 = 0; nsp->eccres2 = 0; } if (flash_read((start+YAFFS_BYTES_PER_CHUNK+(2UL*NOR_FLASH_SPARE_SIZE)-sizeof(state)), (INT8U *)&state, sizeof(state)) < 0) { T(YAFFS_TRACE_ERROR, (TSTR("**>> flash: Read 2nd state from page %ld failed\n"), chunkInNAND)); return YAFFS_FAIL; } if (state == SPARE_STATE_USED) { if (flash_read((start+YAFFS_BYTES_PER_CHUNK+NOR_FLASH_SPARE_SIZE), (INT8U *)spare, YAFFS_BYTES_PER_SPARE) < 0) { T(YAFFS_TRACE_ERROR, (TSTR("**>> flash: Read 2nd spare from page %ld failed\n"), chunkInNAND)); return YAFFS_FAIL; } return YAFFS_OK; } if (flash_read((start+YAFFS_BYTES_PER_CHUNK+NOR_FLASH_SPARE_SIZE-sizeof(state)), (INT8U *)&state, sizeof(state)) < 0) { T(YAFFS_TRACE_ERROR, (TSTR("**>> flash: Read 1st state from page %ld failed\n"), chunkInNAND)); return YAFFS_FAIL; } if (state == SPARE_STATE_USED) { if (flash_read((start+YAFFS_BYTES_PER_CHUNK), (INT8U *)spare, YAFFS_BYTES_PER_SPARE) < 0) { T(YAFFS_TRACE_ERROR, (TSTR("**>> flash: Read 1st spare from page %ld failed\n"), chunkInNAND)); return YAFFS_FAIL; } return YAFFS_OK; } } return YAFFS_OK;}int yflash_EraseBlockInNAND(yaffs_Device *dev, long blockNumber){ if ((blockNumber < dev->startBlock) || (blockNumber > dev->endBlock)) { T(YAFFS_TRACE_ERROR, (TSTR("**>> flash: Illegal block number %ld to erase\n"), blockNumber)); return YAFFS_FAIL; } if (flash_erase((blockNumber - dev->startBlock) * NOR_FLASH_BLOCK_SIZE) < 0) { T(YAFFS_TRACE_ERROR, (TSTR("**>> flash: Erase flash device block %ld failed\n"), blockNumber)); return YAFFS_FAIL; } return YAFFS_OK;}int yflash_InitialiseNAND(yaffs_Device *dev){ if (flash_init() < 0) { T(YAFFS_TRACE_ERROR, (TSTR("**>> flash: Can't find flash device supported\n"))); return YAFFS_FAIL; }#if 1 dev->useNANDECC = 1; // force on useNANDECC which gets faked, this saves us doing ECC checks.#endif return YAFFS_OK;}#elseint yflash_WriteChunkToNAND(yaffs_Device *dev, long chunkInNAND, const __u8 *data, yaffs_Spare *spare){ return YAFFS_FAIL;}int yflash_ReadChunkFromNAND(yaffs_Device *dev, long chunkInNAND, __u8 *data, yaffs_Spare *spare){ return YAFFS_FAIL;}int yflash_EraseBlockInNAND(yaffs_Device *dev, long blockNumber){ return YAFFS_FAIL;}int yflash_InitialiseNAND(yaffs_Device *dev){ return YAFFS_FAIL;}#endif /* CONFIG_YAFFS_NOR_FLASH */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -