1/* 2 * YAFFS: Yet another FFS. A NAND-flash specific file system. 3 * yaffs_ramdisk.c: yaffs ram disk component 4 * 5 * Copyright (C) 2002 Aleph One Ltd. 6 * 7 * Created by Charles Manning <charles@aleph1.co.uk> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 * 13 */ 14 15// This provides a YAFFS nand emulation on a file. 16// THis is only intended as test code to test persistence etc. 17 18const char *yaffs_flashif_c_version = "$Id: yaffs_fileem.c,v 1.1 2004/11/03 08:29:28 charles Exp $"; 19 20 21#include "yportenv.h" 22 23#include "yaffs_flashif.h" 24#include "yaffs_guts.h" 25 26#include "devextras.h" 27 28#include <sys/types.h> 29#include <sys/stat.h> 30#include <fcntl.h> 31#include <unistd.h> 32 33 34 35#define SIZE_IN_MB 16 36 37#define BLOCK_SIZE (32 * 528) 38#define BLOCKS_PER_MEG ((1024*1024)/(32 * 512)) 39 40 41 42typedef struct 43{ 44 __u8 data[528]; // Data + spare 45} yflash_Page; 46 47typedef struct 48{ 49 yflash_Page page[32]; // The pages in the block 50 51} yflash_Block; 52 53 54 55typedef struct 56{ 57 int handle; 58 int nBlocks; 59} yflash_Device; 60 61static yflash_Device filedisk; 62 63static int CheckInit(yaffs_Device *dev) 64{ 65 static int initialised = 0; 66 67 int i; 68 69 70 int fSize; 71 int written; 72 73 yflash_Page p; 74 75 if(initialised) 76 { 77 return YAFFS_OK; 78 } 79 80 initialised = 1; 81 82 83 filedisk.nBlocks = (SIZE_IN_MB * 1024 * 1024)/(16 * 1024); 84 85 filedisk.handle = open("yaffsemfile", O_RDWR | O_CREAT, S_IREAD | S_IWRITE); 86 87 if(filedisk.handle < 0) 88 { 89 perror("Failed to open yaffs emulation file"); 90 return YAFFS_FAIL; 91 } 92 93 94 fSize = lseek(filedisk.handle,0,SEEK_END); 95 96 if(fSize < SIZE_IN_MB * 1024 * 1024) 97 { 98 printf("Creating yaffs emulation file\n"); 99 100 lseek(filedisk.handle,0,SEEK_SET); 101 102 memset(&p,0xff,sizeof(yflash_Page)); 103 104 for(i = 0; i < SIZE_IN_MB * 1024 * 1024; i+= 512) 105 { 106 written = write(filedisk.handle,&p,sizeof(yflash_Page)); 107 108 if(written != sizeof(yflash_Page)) 109 { 110 printf("Write failed\n"); 111 return YAFFS_FAIL; 112 } 113 } 114 } 115 116 return 1; 117} 118 119int yflash_WriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_Spare *spare) 120{ 121 int written; 122 123 CheckInit(dev); 124 125 126 127 if(data) 128 { 129 lseek(filedisk.handle,chunkInNAND * 528,SEEK_SET); 130 written = write(filedisk.handle,data,512); 131 132 if(written != 512) return YAFFS_FAIL; 133 } 134 135 if(spare) 136 { 137 lseek(filedisk.handle,chunkInNAND * 528 + 512,SEEK_SET); 138 written = write(filedisk.handle,spare,16); 139 140 if(written != 16) return YAFFS_FAIL; 141 } 142 143 144 return YAFFS_OK; 145 146} 147 148 149int yflash_ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare) 150{ 151 int nread; 152 153 CheckInit(dev); 154 155 156 157 if(data) 158 { 159 lseek(filedisk.handle,chunkInNAND * 528,SEEK_SET); 160 nread = read(filedisk.handle,data,512); 161 162 if(nread != 512) return YAFFS_FAIL; 163 } 164 165 if(spare) 166 { 167 lseek(filedisk.handle,chunkInNAND * 528 + 512,SEEK_SET); 168 nread= read(filedisk.handle,spare,16); 169 170 if(nread != 16) return YAFFS_FAIL; 171 } 172 173 174 return YAFFS_OK; 175 176} 177 178 179int yflash_EraseBlockInNAND(yaffs_Device *dev, int blockNumber) 180{ 181 182 int i; 183 184 CheckInit(dev); 185 186 if(blockNumber < 0 || blockNumber >= filedisk.nBlocks) 187 { 188 T(YAFFS_TRACE_ALWAYS,("Attempt to erase non-existant block %d\n",blockNumber)); 189 return YAFFS_FAIL; 190 } 191 else 192 { 193 194 yflash_Page pg; 195 196 memset(&pg,0xff,sizeof(yflash_Page)); 197 198 lseek(filedisk.handle, blockNumber * 32 * 528, SEEK_SET); 199 200 for(i = 0; i < 32; i++) 201 { 202 write(filedisk.handle,&pg,528); 203 } 204 return YAFFS_OK; 205 } 206 207} 208 209int yflash_InitialiseNAND(yaffs_Device *dev) 210{ 211 dev->useNANDECC = 1; // force on useNANDECC which gets faked. 212 // This saves us doing ECC checks. 213 214 return YAFFS_OK; 215} 216 217 218