1 /*
2  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
3  *
4  * Copyright (C) 2002-2007 Aleph One Ltd.
5  *   for Toby Churchill Ltd and Brightstar Engineering
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  * yaffscfg.c  The configuration for the "direct" use of yaffs.
16  *
17  * This file is intended to be modified to your requirements.
18  * There is no need to redistribute this file.
19  */
20 
21 /* XXX U-BOOT XXX */
22 #include <common.h>
23 
24 #include <config.h>
25 #include "nand.h"
26 #include "yaffscfg.h"
27 #include "yaffsfs.h"
28 #include "yaffs_packedtags2.h"
29 #include "yaffs_mtdif.h"
30 #include "yaffs_mtdif2.h"
31 #if 0
32 #include <errno.h>
33 #else
34 #include "malloc.h"
35 #endif
36 
37 unsigned yaffs_traceMask = 0x0; /* Disable logging */
38 static int yaffs_errno = 0;
39 
yaffsfs_SetError(int err)40 void yaffsfs_SetError(int err)
41 {
42 	//Do whatever to set error
43 	yaffs_errno = err;
44 }
45 
yaffsfs_GetError(void)46 int yaffsfs_GetError(void)
47 {
48 	return yaffs_errno;
49 }
50 
yaffsfs_Lock(void)51 void yaffsfs_Lock(void)
52 {
53 }
54 
yaffsfs_Unlock(void)55 void yaffsfs_Unlock(void)
56 {
57 }
58 
yaffsfs_CurrentTime(void)59 __u32 yaffsfs_CurrentTime(void)
60 {
61 	return 0;
62 }
63 
yaffs_malloc(size_t size)64 void *yaffs_malloc(size_t size)
65 {
66 	return malloc(size);
67 }
68 
yaffs_free(void * ptr)69 void yaffs_free(void *ptr)
70 {
71 	free(ptr);
72 }
73 
yaffsfs_LocalInitialisation(void)74 void yaffsfs_LocalInitialisation(void)
75 {
76 	// Define locking semaphore.
77 }
78 
79 // Configuration for:
80 // /ram  2MB ramdisk
81 // /boot 2MB boot disk (flash)
82 // /flash 14MB flash disk (flash)
83 // NB Though /boot and /flash occupy the same physical device they
84 // are still disticnt "yaffs_Devices. You may think of these as "partitions"
85 // using non-overlapping areas in the same device.
86 //
87 
88 #include "yaffs_ramdisk.h"
89 #include "yaffs_flashif.h"
90 
91 static int isMounted = 0;
92 #define MOUNT_POINT "/flash"
93 extern nand_info_t nand_info[];
94 
95 /* XXX U-BOOT XXX */
96 #if 0
97 static yaffs_Device ramDev;
98 static yaffs_Device bootDev;
99 static yaffs_Device flashDev;
100 #endif
101 
102 static yaffsfs_DeviceConfiguration yaffsfs_config[] = {
103 /* XXX U-BOOT XXX */
104 #if 0
105 	{ "/ram", &ramDev},
106 	{ "/boot", &bootDev},
107 	{ "/flash", &flashDev},
108 #else
109 	{ MOUNT_POINT, 0},
110 #endif
111 	{(void *)0,(void *)0}
112 };
113 
114 
yaffs_StartUp(void)115 int yaffs_StartUp(void)
116 {
117 	struct mtd_info *mtd = &nand_info[0];
118 	int yaffsVersion = 2;
119 	int nBlocks;
120 
121 	yaffs_Device *flashDev = calloc(1, sizeof(yaffs_Device));
122 	yaffsfs_config[0].dev = flashDev;
123 
124 	/* store the mtd device for later use */
125 	flashDev->genericDevice = mtd;
126 
127 	// Stuff to configure YAFFS
128 	// Stuff to initialise anything special (eg lock semaphore).
129 	yaffsfs_LocalInitialisation();
130 
131 	// Set up devices
132 
133 /* XXX U-BOOT XXX */
134 #if 0
135 	// /ram
136 	ramDev.nBytesPerChunk = 512;
137 	ramDev.nChunksPerBlock = 32;
138 	ramDev.nReservedBlocks = 2; // Set this smaller for RAM
139 	ramDev.startBlock = 1; // Can't use block 0
140 	ramDev.endBlock = 127; // Last block in 2MB.
141 	ramDev.useNANDECC = 1;
142 	ramDev.nShortOpCaches = 0;	// Disable caching on this device.
143 	ramDev.genericDevice = (void *) 0;	// Used to identify the device in fstat.
144 	ramDev.writeChunkWithTagsToNAND = yramdisk_WriteChunkWithTagsToNAND;
145 	ramDev.readChunkWithTagsFromNAND = yramdisk_ReadChunkWithTagsFromNAND;
146 	ramDev.eraseBlockInNAND = yramdisk_EraseBlockInNAND;
147 	ramDev.initialiseNAND = yramdisk_InitialiseNAND;
148 
149 	// /boot
150 	bootDev.nBytesPerChunk = 612;
151 	bootDev.nChunksPerBlock = 32;
152 	bootDev.nReservedBlocks = 5;
153 	bootDev.startBlock = 1; // Can't use block 0
154 	bootDev.endBlock = 127; // Last block in 2MB.
155 	bootDev.useNANDECC = 0; // use YAFFS's ECC
156 	bootDev.nShortOpCaches = 10; // Use caches
157 	bootDev.genericDevice = (void *) 1;	// Used to identify the device in fstat.
158 	bootDev.writeChunkToNAND = yflash_WriteChunkToNAND;
159 	bootDev.readChunkFromNAND = yflash_ReadChunkFromNAND;
160 	bootDev.eraseBlockInNAND = yflash_EraseBlockInNAND;
161 	bootDev.initialiseNAND = yflash_InitialiseNAND;
162 #endif
163 
164 		// /flash
165 	flashDev->nReservedBlocks = 5;
166 //  flashDev->nShortOpCaches = (options.no_cache) ? 0 : 10;
167 	flashDev->nShortOpCaches = 10; // Use caches
168 	flashDev->useNANDECC = 0; // do not use YAFFS's ECC
169 
170 	if (yaffsVersion == 2)
171 	{
172 		flashDev->writeChunkWithTagsToNAND = nandmtd2_WriteChunkWithTagsToNAND;
173 		flashDev->readChunkWithTagsFromNAND = nandmtd2_ReadChunkWithTagsFromNAND;
174 		flashDev->markNANDBlockBad = nandmtd2_MarkNANDBlockBad;
175 		flashDev->queryNANDBlock = nandmtd2_QueryNANDBlock;
176 		flashDev->spareBuffer = YMALLOC(mtd->oobsize);
177 		flashDev->isYaffs2 = 1;
178 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
179 		flashDev->nDataBytesPerChunk = mtd->writesize;
180 		flashDev->nChunksPerBlock = mtd->erasesize / mtd->writesize;
181 #else
182 		flashDev->nDataBytesPerChunk = mtd->oobblock;
183 		flashDev->nChunksPerBlock = mtd->erasesize / mtd->oobblock;
184 #endif
185 		nBlocks = mtd->size / mtd->erasesize;
186 
187 		flashDev->nCheckpointReservedBlocks = 10;
188 		flashDev->startBlock = 0;
189 		flashDev->endBlock = nBlocks - 1;
190 	}
191 	else
192 	{
193 		flashDev->writeChunkToNAND = nandmtd_WriteChunkToNAND;
194 		flashDev->readChunkFromNAND = nandmtd_ReadChunkFromNAND;
195 		flashDev->isYaffs2 = 0;
196 		nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
197 		flashDev->startBlock = 320;
198 		flashDev->endBlock = nBlocks - 1;
199 		flashDev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
200 		flashDev->nDataBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
201 	}
202 
203 	/* ... and common functions */
204 	flashDev->eraseBlockInNAND = nandmtd_EraseBlockInNAND;
205 	flashDev->initialiseNAND = nandmtd_InitialiseNAND;
206 
207 	yaffs_initialise(yaffsfs_config);
208 
209 	return 0;
210 }
211 
212 
make_a_file(char * yaffsName,char bval,int sizeOfFile)213 void make_a_file(char *yaffsName,char bval,int sizeOfFile)
214 {
215 	int outh;
216 	int i;
217 	unsigned char buffer[100];
218 
219 	outh = yaffs_open(yaffsName, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
220 	if (outh < 0)
221 	{
222 		printf("Error opening file: %d\n", outh);
223 		return;
224 	}
225 
226 	memset(buffer,bval,100);
227 
228 	do{
229 		i = sizeOfFile;
230 		if(i > 100) i = 100;
231 		sizeOfFile -= i;
232 
233 		yaffs_write(outh,buffer,i);
234 
235 	} while (sizeOfFile > 0);
236 
237 
238 	yaffs_close(outh);
239 }
240 
read_a_file(char * fn)241 void read_a_file(char *fn)
242 {
243 	int h;
244 	int i = 0;
245 	unsigned char b;
246 
247 	h = yaffs_open(fn, O_RDWR,0);
248 	if(h<0)
249 	{
250 		printf("File not found\n");
251 		return;
252 	}
253 
254 	while(yaffs_read(h,&b,1)> 0)
255 	{
256 		printf("%02x ",b);
257 		i++;
258 		if(i > 32)
259 		{
260 		   printf("\n");
261 		   i = 0;;
262 		 }
263 	}
264 	printf("\n");
265 	yaffs_close(h);
266 }
267 
cmd_yaffs_mount(char * mp)268 void cmd_yaffs_mount(char *mp)
269 {
270 	yaffs_StartUp();
271 	int retval = yaffs_mount(mp);
272 	if( retval != -1)
273 		isMounted = 1;
274 	else
275 		printf("Error mounting %s, return value: %d\n", mp, yaffsfs_GetError());
276 }
277 
checkMount(void)278 static void checkMount(void)
279 {
280 	if( !isMounted )
281 	{
282 		cmd_yaffs_mount(MOUNT_POINT);
283 	}
284 }
285 
cmd_yaffs_umount(char * mp)286 void cmd_yaffs_umount(char *mp)
287 {
288 	checkMount();
289 	if( yaffs_unmount(mp) == -1)
290 		printf("Error umounting %s, return value: %d\n", mp, yaffsfs_GetError());
291 }
292 
cmd_yaffs_write_file(char * yaffsName,char bval,int sizeOfFile)293 void cmd_yaffs_write_file(char *yaffsName,char bval,int sizeOfFile)
294 {
295 	checkMount();
296 	make_a_file(yaffsName,bval,sizeOfFile);
297 }
298 
299 
cmd_yaffs_read_file(char * fn)300 void cmd_yaffs_read_file(char *fn)
301 {
302 	checkMount();
303 	read_a_file(fn);
304 }
305 
306 
cmd_yaffs_mread_file(char * fn,char * addr)307 void cmd_yaffs_mread_file(char *fn, char *addr)
308 {
309 	int h;
310 	struct yaffs_stat s;
311 
312 	checkMount();
313 
314 	yaffs_stat(fn,&s);
315 
316 	printf ("Copy %s to 0x%08x... ", fn, addr);
317 	h = yaffs_open(fn, O_RDWR,0);
318 	if(h<0)
319 	{
320 		printf("File not found\n");
321 		return;
322 	}
323 
324 	yaffs_read(h,addr,(int)s.st_size);
325 	printf("\t[DONE]\n");
326 
327 	yaffs_close(h);
328 }
329 
330 
cmd_yaffs_mwrite_file(char * fn,char * addr,int size)331 void cmd_yaffs_mwrite_file(char *fn, char *addr, int size)
332 {
333 	int outh;
334 
335 	checkMount();
336 	outh = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
337 	if (outh < 0)
338 	{
339 		printf("Error opening file: %d\n", outh);
340 	}
341 
342 	yaffs_write(outh,addr,size);
343 
344 	yaffs_close(outh);
345 }
346 
347 
cmd_yaffs_ls(const char * mountpt,int longlist)348 void cmd_yaffs_ls(const char *mountpt, int longlist)
349 {
350 	int i;
351 	yaffs_DIR *d;
352 	yaffs_dirent *de;
353 	struct yaffs_stat stat;
354 	char tempstr[255];
355 
356 	checkMount();
357 	d = yaffs_opendir(mountpt);
358 
359 	if(!d)
360 	{
361 		printf("opendir failed\n");
362 	}
363 	else
364 	{
365 		for(i = 0; (de = yaffs_readdir(d)) != NULL; i++)
366 		{
367 			if (longlist)
368 			{
369 				sprintf(tempstr, "%s/%s", mountpt, de->d_name);
370 				yaffs_stat(tempstr, &stat);
371 				printf("%-25s\t%7d\n",de->d_name, stat.st_size);
372 			}
373 			else
374 			{
375 				printf("%s\n",de->d_name);
376 			}
377 		}
378 	}
379 }
380 
381 
cmd_yaffs_mkdir(const char * dir)382 void cmd_yaffs_mkdir(const char *dir)
383 {
384 	checkMount();
385 
386 	int retval = yaffs_mkdir(dir, 0);
387 
388 	if ( retval < 0)
389 		printf("yaffs_mkdir returning error: %d\n", retval);
390 }
391 
cmd_yaffs_rmdir(const char * dir)392 void cmd_yaffs_rmdir(const char *dir)
393 {
394 	checkMount();
395 
396 	int retval = yaffs_rmdir(dir);
397 
398 	if ( retval < 0)
399 		printf("yaffs_rmdir returning error: %d\n", retval);
400 }
401 
cmd_yaffs_rm(const char * path)402 void cmd_yaffs_rm(const char *path)
403 {
404 	checkMount();
405 
406 	int retval = yaffs_unlink(path);
407 
408 	if ( retval < 0)
409 		printf("yaffs_unlink returning error: %d\n", retval);
410 }
411 
cmd_yaffs_mv(const char * oldPath,const char * newPath)412 void cmd_yaffs_mv(const char *oldPath, const char *newPath)
413 {
414 	checkMount();
415 
416 	int retval = yaffs_rename(newPath, oldPath);
417 
418 	if ( retval < 0)
419 		printf("yaffs_unlink returning error: %d\n", retval);
420 }
421