xref: /openbmc/u-boot/fs/yaffs2/yaffs_guts.h (revision 0e8cc8bd)
1*0e8cc8bdSWilliam Juul /*
2*0e8cc8bdSWilliam Juul  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
3*0e8cc8bdSWilliam Juul  *
4*0e8cc8bdSWilliam Juul  * Copyright (C) 2002-2007 Aleph One Ltd.
5*0e8cc8bdSWilliam Juul  *   for Toby Churchill Ltd and Brightstar Engineering
6*0e8cc8bdSWilliam Juul  *
7*0e8cc8bdSWilliam Juul  * Created by Charles Manning <charles@aleph1.co.uk>
8*0e8cc8bdSWilliam Juul  *
9*0e8cc8bdSWilliam Juul  * This program is free software; you can redistribute it and/or modify
10*0e8cc8bdSWilliam Juul  * it under the terms of the GNU Lesser General Public License version 2.1 as
11*0e8cc8bdSWilliam Juul  * published by the Free Software Foundation.
12*0e8cc8bdSWilliam Juul  *
13*0e8cc8bdSWilliam Juul  * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
14*0e8cc8bdSWilliam Juul  */
15*0e8cc8bdSWilliam Juul 
16*0e8cc8bdSWilliam Juul #ifndef __YAFFS_GUTS_H__
17*0e8cc8bdSWilliam Juul #define __YAFFS_GUTS_H__
18*0e8cc8bdSWilliam Juul 
19*0e8cc8bdSWilliam Juul #include "devextras.h"
20*0e8cc8bdSWilliam Juul #include "yportenv.h"
21*0e8cc8bdSWilliam Juul 
22*0e8cc8bdSWilliam Juul #define YAFFS_OK	1
23*0e8cc8bdSWilliam Juul #define YAFFS_FAIL  0
24*0e8cc8bdSWilliam Juul 
25*0e8cc8bdSWilliam Juul /* Give us a  Y=0x59,
26*0e8cc8bdSWilliam Juul  * Give us an A=0x41,
27*0e8cc8bdSWilliam Juul  * Give us an FF=0xFF
28*0e8cc8bdSWilliam Juul  * Give us an S=0x53
29*0e8cc8bdSWilliam Juul  * And what have we got...
30*0e8cc8bdSWilliam Juul  */
31*0e8cc8bdSWilliam Juul #define YAFFS_MAGIC			0x5941FF53
32*0e8cc8bdSWilliam Juul 
33*0e8cc8bdSWilliam Juul #define YAFFS_NTNODES_LEVEL0	  	16
34*0e8cc8bdSWilliam Juul #define YAFFS_TNODES_LEVEL0_BITS	4
35*0e8cc8bdSWilliam Juul #define YAFFS_TNODES_LEVEL0_MASK	0xf
36*0e8cc8bdSWilliam Juul 
37*0e8cc8bdSWilliam Juul #define YAFFS_NTNODES_INTERNAL 		(YAFFS_NTNODES_LEVEL0 / 2)
38*0e8cc8bdSWilliam Juul #define YAFFS_TNODES_INTERNAL_BITS 	(YAFFS_TNODES_LEVEL0_BITS - 1)
39*0e8cc8bdSWilliam Juul #define YAFFS_TNODES_INTERNAL_MASK	0x7
40*0e8cc8bdSWilliam Juul #define YAFFS_TNODES_MAX_LEVEL		6
41*0e8cc8bdSWilliam Juul 
42*0e8cc8bdSWilliam Juul #ifndef CONFIG_YAFFS_NO_YAFFS1
43*0e8cc8bdSWilliam Juul #define YAFFS_BYTES_PER_SPARE		16
44*0e8cc8bdSWilliam Juul #define YAFFS_BYTES_PER_CHUNK		512
45*0e8cc8bdSWilliam Juul #define YAFFS_CHUNK_SIZE_SHIFT		9
46*0e8cc8bdSWilliam Juul #define YAFFS_CHUNKS_PER_BLOCK		32
47*0e8cc8bdSWilliam Juul #define YAFFS_BYTES_PER_BLOCK		(YAFFS_CHUNKS_PER_BLOCK*YAFFS_BYTES_PER_CHUNK)
48*0e8cc8bdSWilliam Juul #endif
49*0e8cc8bdSWilliam Juul 
50*0e8cc8bdSWilliam Juul #define YAFFS_MIN_YAFFS2_CHUNK_SIZE 	1024
51*0e8cc8bdSWilliam Juul #define YAFFS_MIN_YAFFS2_SPARE_SIZE	32
52*0e8cc8bdSWilliam Juul 
53*0e8cc8bdSWilliam Juul #define YAFFS_MAX_CHUNK_ID		0x000FFFFF
54*0e8cc8bdSWilliam Juul 
55*0e8cc8bdSWilliam Juul #define YAFFS_UNUSED_OBJECT_ID		0x0003FFFF
56*0e8cc8bdSWilliam Juul 
57*0e8cc8bdSWilliam Juul #define YAFFS_ALLOCATION_NOBJECTS	100
58*0e8cc8bdSWilliam Juul #define YAFFS_ALLOCATION_NTNODES	100
59*0e8cc8bdSWilliam Juul #define YAFFS_ALLOCATION_NLINKS		100
60*0e8cc8bdSWilliam Juul 
61*0e8cc8bdSWilliam Juul #define YAFFS_NOBJECT_BUCKETS		256
62*0e8cc8bdSWilliam Juul 
63*0e8cc8bdSWilliam Juul 
64*0e8cc8bdSWilliam Juul #define YAFFS_OBJECT_SPACE		0x40000
65*0e8cc8bdSWilliam Juul 
66*0e8cc8bdSWilliam Juul #define YAFFS_CHECKPOINT_VERSION 	3
67*0e8cc8bdSWilliam Juul 
68*0e8cc8bdSWilliam Juul #ifdef CONFIG_YAFFS_UNICODE
69*0e8cc8bdSWilliam Juul #define YAFFS_MAX_NAME_LENGTH		127
70*0e8cc8bdSWilliam Juul #define YAFFS_MAX_ALIAS_LENGTH		79
71*0e8cc8bdSWilliam Juul #else
72*0e8cc8bdSWilliam Juul #define YAFFS_MAX_NAME_LENGTH		255
73*0e8cc8bdSWilliam Juul #define YAFFS_MAX_ALIAS_LENGTH		159
74*0e8cc8bdSWilliam Juul #endif
75*0e8cc8bdSWilliam Juul 
76*0e8cc8bdSWilliam Juul #define YAFFS_SHORT_NAME_LENGTH		15
77*0e8cc8bdSWilliam Juul 
78*0e8cc8bdSWilliam Juul /* Some special object ids for pseudo objects */
79*0e8cc8bdSWilliam Juul #define YAFFS_OBJECTID_ROOT		1
80*0e8cc8bdSWilliam Juul #define YAFFS_OBJECTID_LOSTNFOUND	2
81*0e8cc8bdSWilliam Juul #define YAFFS_OBJECTID_UNLINKED		3
82*0e8cc8bdSWilliam Juul #define YAFFS_OBJECTID_DELETED		4
83*0e8cc8bdSWilliam Juul 
84*0e8cc8bdSWilliam Juul /* Sseudo object ids for checkpointing */
85*0e8cc8bdSWilliam Juul #define YAFFS_OBJECTID_SB_HEADER	0x10
86*0e8cc8bdSWilliam Juul #define YAFFS_OBJECTID_CHECKPOINT_DATA	0x20
87*0e8cc8bdSWilliam Juul #define YAFFS_SEQUENCE_CHECKPOINT_DATA  0x21
88*0e8cc8bdSWilliam Juul 
89*0e8cc8bdSWilliam Juul /* */
90*0e8cc8bdSWilliam Juul 
91*0e8cc8bdSWilliam Juul #define YAFFS_MAX_SHORT_OP_CACHES	20
92*0e8cc8bdSWilliam Juul 
93*0e8cc8bdSWilliam Juul #define YAFFS_N_TEMP_BUFFERS		4
94*0e8cc8bdSWilliam Juul 
95*0e8cc8bdSWilliam Juul /* We limit the number attempts at sucessfully saving a chunk of data.
96*0e8cc8bdSWilliam Juul  * Small-page devices have 32 pages per block; large-page devices have 64.
97*0e8cc8bdSWilliam Juul  * Default to something in the order of 5 to 10 blocks worth of chunks.
98*0e8cc8bdSWilliam Juul  */
99*0e8cc8bdSWilliam Juul #define YAFFS_WR_ATTEMPTS		(5*64)
100*0e8cc8bdSWilliam Juul 
101*0e8cc8bdSWilliam Juul /* Sequence numbers are used in YAFFS2 to determine block allocation order.
102*0e8cc8bdSWilliam Juul  * The range is limited slightly to help distinguish bad numbers from good.
103*0e8cc8bdSWilliam Juul  * This also allows us to perhaps in the future use special numbers for
104*0e8cc8bdSWilliam Juul  * special purposes.
105*0e8cc8bdSWilliam Juul  * EFFFFF00 allows the allocation of 8 blocks per second (~1Mbytes) for 15 years,
106*0e8cc8bdSWilliam Juul  * and is a larger number than the lifetime of a 2GB device.
107*0e8cc8bdSWilliam Juul  */
108*0e8cc8bdSWilliam Juul #define YAFFS_LOWEST_SEQUENCE_NUMBER	0x00001000
109*0e8cc8bdSWilliam Juul #define YAFFS_HIGHEST_SEQUENCE_NUMBER	0xEFFFFF00
110*0e8cc8bdSWilliam Juul 
111*0e8cc8bdSWilliam Juul /* ChunkCache is used for short read/write operations.*/
112*0e8cc8bdSWilliam Juul typedef struct {
113*0e8cc8bdSWilliam Juul 	struct yaffs_ObjectStruct *object;
114*0e8cc8bdSWilliam Juul 	int chunkId;
115*0e8cc8bdSWilliam Juul 	int lastUse;
116*0e8cc8bdSWilliam Juul 	int dirty;
117*0e8cc8bdSWilliam Juul 	int nBytes;		/* Only valid if the cache is dirty */
118*0e8cc8bdSWilliam Juul 	int locked;		/* Can't push out or flush while locked. */
119*0e8cc8bdSWilliam Juul #ifdef CONFIG_YAFFS_YAFFS2
120*0e8cc8bdSWilliam Juul 	__u8 *data;
121*0e8cc8bdSWilliam Juul #else
122*0e8cc8bdSWilliam Juul 	__u8 data[YAFFS_BYTES_PER_CHUNK];
123*0e8cc8bdSWilliam Juul #endif
124*0e8cc8bdSWilliam Juul } yaffs_ChunkCache;
125*0e8cc8bdSWilliam Juul 
126*0e8cc8bdSWilliam Juul 
127*0e8cc8bdSWilliam Juul 
128*0e8cc8bdSWilliam Juul /* Tags structures in RAM
129*0e8cc8bdSWilliam Juul  * NB This uses bitfield. Bitfields should not straddle a u32 boundary otherwise
130*0e8cc8bdSWilliam Juul  * the structure size will get blown out.
131*0e8cc8bdSWilliam Juul  */
132*0e8cc8bdSWilliam Juul 
133*0e8cc8bdSWilliam Juul #ifndef CONFIG_YAFFS_NO_YAFFS1
134*0e8cc8bdSWilliam Juul typedef struct {
135*0e8cc8bdSWilliam Juul 	unsigned chunkId:20;
136*0e8cc8bdSWilliam Juul 	unsigned serialNumber:2;
137*0e8cc8bdSWilliam Juul 	unsigned byteCount:10;
138*0e8cc8bdSWilliam Juul 	unsigned objectId:18;
139*0e8cc8bdSWilliam Juul 	unsigned ecc:12;
140*0e8cc8bdSWilliam Juul 	unsigned unusedStuff:2;
141*0e8cc8bdSWilliam Juul 
142*0e8cc8bdSWilliam Juul } yaffs_Tags;
143*0e8cc8bdSWilliam Juul 
144*0e8cc8bdSWilliam Juul typedef union {
145*0e8cc8bdSWilliam Juul 	yaffs_Tags asTags;
146*0e8cc8bdSWilliam Juul 	__u8 asBytes[8];
147*0e8cc8bdSWilliam Juul } yaffs_TagsUnion;
148*0e8cc8bdSWilliam Juul 
149*0e8cc8bdSWilliam Juul #endif
150*0e8cc8bdSWilliam Juul 
151*0e8cc8bdSWilliam Juul /* Stuff used for extended tags in YAFFS2 */
152*0e8cc8bdSWilliam Juul 
153*0e8cc8bdSWilliam Juul typedef enum {
154*0e8cc8bdSWilliam Juul 	YAFFS_ECC_RESULT_UNKNOWN,
155*0e8cc8bdSWilliam Juul 	YAFFS_ECC_RESULT_NO_ERROR,
156*0e8cc8bdSWilliam Juul 	YAFFS_ECC_RESULT_FIXED,
157*0e8cc8bdSWilliam Juul 	YAFFS_ECC_RESULT_UNFIXED
158*0e8cc8bdSWilliam Juul } yaffs_ECCResult;
159*0e8cc8bdSWilliam Juul 
160*0e8cc8bdSWilliam Juul typedef enum {
161*0e8cc8bdSWilliam Juul 	YAFFS_OBJECT_TYPE_UNKNOWN,
162*0e8cc8bdSWilliam Juul 	YAFFS_OBJECT_TYPE_FILE,
163*0e8cc8bdSWilliam Juul 	YAFFS_OBJECT_TYPE_SYMLINK,
164*0e8cc8bdSWilliam Juul 	YAFFS_OBJECT_TYPE_DIRECTORY,
165*0e8cc8bdSWilliam Juul 	YAFFS_OBJECT_TYPE_HARDLINK,
166*0e8cc8bdSWilliam Juul 	YAFFS_OBJECT_TYPE_SPECIAL
167*0e8cc8bdSWilliam Juul } yaffs_ObjectType;
168*0e8cc8bdSWilliam Juul 
169*0e8cc8bdSWilliam Juul #define YAFFS_OBJECT_TYPE_MAX YAFFS_OBJECT_TYPE_SPECIAL
170*0e8cc8bdSWilliam Juul 
171*0e8cc8bdSWilliam Juul typedef struct {
172*0e8cc8bdSWilliam Juul 
173*0e8cc8bdSWilliam Juul 	unsigned validMarker0;
174*0e8cc8bdSWilliam Juul 	unsigned chunkUsed;	/*  Status of the chunk: used or unused */
175*0e8cc8bdSWilliam Juul 	unsigned objectId;	/* If 0 then this is not part of an object (unused) */
176*0e8cc8bdSWilliam Juul 	unsigned chunkId;	/* If 0 then this is a header, else a data chunk */
177*0e8cc8bdSWilliam Juul 	unsigned byteCount;	/* Only valid for data chunks */
178*0e8cc8bdSWilliam Juul 
179*0e8cc8bdSWilliam Juul 	/* The following stuff only has meaning when we read */
180*0e8cc8bdSWilliam Juul 	yaffs_ECCResult eccResult;
181*0e8cc8bdSWilliam Juul 	unsigned blockBad;
182*0e8cc8bdSWilliam Juul 
183*0e8cc8bdSWilliam Juul 	/* YAFFS 1 stuff */
184*0e8cc8bdSWilliam Juul 	unsigned chunkDeleted;	/* The chunk is marked deleted */
185*0e8cc8bdSWilliam Juul 	unsigned serialNumber;	/* Yaffs1 2-bit serial number */
186*0e8cc8bdSWilliam Juul 
187*0e8cc8bdSWilliam Juul 	/* YAFFS2 stuff */
188*0e8cc8bdSWilliam Juul 	unsigned sequenceNumber;	/* The sequence number of this block */
189*0e8cc8bdSWilliam Juul 
190*0e8cc8bdSWilliam Juul 	/* Extra info if this is an object header (YAFFS2 only) */
191*0e8cc8bdSWilliam Juul 
192*0e8cc8bdSWilliam Juul 	unsigned extraHeaderInfoAvailable;	/* There is extra info available if this is not zero */
193*0e8cc8bdSWilliam Juul 	unsigned extraParentObjectId;	/* The parent object */
194*0e8cc8bdSWilliam Juul 	unsigned extraIsShrinkHeader;	/* Is it a shrink header? */
195*0e8cc8bdSWilliam Juul 	unsigned extraShadows;		/* Does this shadow another object? */
196*0e8cc8bdSWilliam Juul 
197*0e8cc8bdSWilliam Juul 	yaffs_ObjectType extraObjectType;	/* What object type? */
198*0e8cc8bdSWilliam Juul 
199*0e8cc8bdSWilliam Juul 	unsigned extraFileLength;		/* Length if it is a file */
200*0e8cc8bdSWilliam Juul 	unsigned extraEquivalentObjectId;	/* Equivalent object Id if it is a hard link */
201*0e8cc8bdSWilliam Juul 
202*0e8cc8bdSWilliam Juul 	unsigned validMarker1;
203*0e8cc8bdSWilliam Juul 
204*0e8cc8bdSWilliam Juul } yaffs_ExtendedTags;
205*0e8cc8bdSWilliam Juul 
206*0e8cc8bdSWilliam Juul /* Spare structure for YAFFS1 */
207*0e8cc8bdSWilliam Juul typedef struct {
208*0e8cc8bdSWilliam Juul 	__u8 tagByte0;
209*0e8cc8bdSWilliam Juul 	__u8 tagByte1;
210*0e8cc8bdSWilliam Juul 	__u8 tagByte2;
211*0e8cc8bdSWilliam Juul 	__u8 tagByte3;
212*0e8cc8bdSWilliam Juul 	__u8 pageStatus;	/* set to 0 to delete the chunk */
213*0e8cc8bdSWilliam Juul 	__u8 blockStatus;
214*0e8cc8bdSWilliam Juul 	__u8 tagByte4;
215*0e8cc8bdSWilliam Juul 	__u8 tagByte5;
216*0e8cc8bdSWilliam Juul 	__u8 ecc1[3];
217*0e8cc8bdSWilliam Juul 	__u8 tagByte6;
218*0e8cc8bdSWilliam Juul 	__u8 tagByte7;
219*0e8cc8bdSWilliam Juul 	__u8 ecc2[3];
220*0e8cc8bdSWilliam Juul } yaffs_Spare;
221*0e8cc8bdSWilliam Juul 
222*0e8cc8bdSWilliam Juul /*Special structure for passing through to mtd */
223*0e8cc8bdSWilliam Juul struct yaffs_NANDSpare {
224*0e8cc8bdSWilliam Juul 	yaffs_Spare spare;
225*0e8cc8bdSWilliam Juul 	int eccres1;
226*0e8cc8bdSWilliam Juul 	int eccres2;
227*0e8cc8bdSWilliam Juul };
228*0e8cc8bdSWilliam Juul 
229*0e8cc8bdSWilliam Juul /* Block data in RAM */
230*0e8cc8bdSWilliam Juul 
231*0e8cc8bdSWilliam Juul typedef enum {
232*0e8cc8bdSWilliam Juul 	YAFFS_BLOCK_STATE_UNKNOWN = 0,
233*0e8cc8bdSWilliam Juul 
234*0e8cc8bdSWilliam Juul 	YAFFS_BLOCK_STATE_SCANNING,
235*0e8cc8bdSWilliam Juul 	YAFFS_BLOCK_STATE_NEEDS_SCANNING,
236*0e8cc8bdSWilliam Juul 	/* The block might have something on it (ie it is allocating or full, perhaps empty)
237*0e8cc8bdSWilliam Juul 	 * but it needs to be scanned to determine its true state.
238*0e8cc8bdSWilliam Juul 	 * This state is only valid during yaffs_Scan.
239*0e8cc8bdSWilliam Juul 	 * NB We tolerate empty because the pre-scanner might be incapable of deciding
240*0e8cc8bdSWilliam Juul 	 * However, if this state is returned on a YAFFS2 device, then we expect a sequence number
241*0e8cc8bdSWilliam Juul 	 */
242*0e8cc8bdSWilliam Juul 
243*0e8cc8bdSWilliam Juul 	YAFFS_BLOCK_STATE_EMPTY,
244*0e8cc8bdSWilliam Juul 	/* This block is empty */
245*0e8cc8bdSWilliam Juul 
246*0e8cc8bdSWilliam Juul 	YAFFS_BLOCK_STATE_ALLOCATING,
247*0e8cc8bdSWilliam Juul 	/* This block is partially allocated.
248*0e8cc8bdSWilliam Juul 	 * At least one page holds valid data.
249*0e8cc8bdSWilliam Juul 	 * This is the one currently being used for page
250*0e8cc8bdSWilliam Juul 	 * allocation. Should never be more than one of these
251*0e8cc8bdSWilliam Juul 	 */
252*0e8cc8bdSWilliam Juul 
253*0e8cc8bdSWilliam Juul 	YAFFS_BLOCK_STATE_FULL,
254*0e8cc8bdSWilliam Juul 	/* All the pages in this block have been allocated.
255*0e8cc8bdSWilliam Juul 	 */
256*0e8cc8bdSWilliam Juul 
257*0e8cc8bdSWilliam Juul 	YAFFS_BLOCK_STATE_DIRTY,
258*0e8cc8bdSWilliam Juul 	/* All pages have been allocated and deleted.
259*0e8cc8bdSWilliam Juul 	 * Erase me, reuse me.
260*0e8cc8bdSWilliam Juul 	 */
261*0e8cc8bdSWilliam Juul 
262*0e8cc8bdSWilliam Juul 	YAFFS_BLOCK_STATE_CHECKPOINT,
263*0e8cc8bdSWilliam Juul 	/* This block is assigned to holding checkpoint data.
264*0e8cc8bdSWilliam Juul 	 */
265*0e8cc8bdSWilliam Juul 
266*0e8cc8bdSWilliam Juul 	YAFFS_BLOCK_STATE_COLLECTING,
267*0e8cc8bdSWilliam Juul 	/* This block is being garbage collected */
268*0e8cc8bdSWilliam Juul 
269*0e8cc8bdSWilliam Juul 	YAFFS_BLOCK_STATE_DEAD
270*0e8cc8bdSWilliam Juul 	/* This block has failed and is not in use */
271*0e8cc8bdSWilliam Juul } yaffs_BlockState;
272*0e8cc8bdSWilliam Juul 
273*0e8cc8bdSWilliam Juul #define	YAFFS_NUMBER_OF_BLOCK_STATES (YAFFS_BLOCK_STATE_DEAD + 1)
274*0e8cc8bdSWilliam Juul 
275*0e8cc8bdSWilliam Juul 
276*0e8cc8bdSWilliam Juul typedef struct {
277*0e8cc8bdSWilliam Juul 
278*0e8cc8bdSWilliam Juul 	int softDeletions:10;	/* number of soft deleted pages */
279*0e8cc8bdSWilliam Juul 	int pagesInUse:10;	/* number of pages in use */
280*0e8cc8bdSWilliam Juul 	unsigned blockState:4;	/* One of the above block states. NB use unsigned because enum is sometimes an int */
281*0e8cc8bdSWilliam Juul 	__u32 needsRetiring:1;	/* Data has failed on this block, need to get valid data off */
282*0e8cc8bdSWilliam Juul                         	/* and retire the block. */
283*0e8cc8bdSWilliam Juul 	__u32 skipErasedCheck: 1; /* If this is set we can skip the erased check on this block */
284*0e8cc8bdSWilliam Juul 	__u32 gcPrioritise: 1; 	/* An ECC check or blank check has failed on this block.
285*0e8cc8bdSWilliam Juul 				   It should be prioritised for GC */
286*0e8cc8bdSWilliam Juul         __u32 chunkErrorStrikes:3; /* How many times we've had ecc etc failures on this block and tried to reuse it */
287*0e8cc8bdSWilliam Juul 
288*0e8cc8bdSWilliam Juul #ifdef CONFIG_YAFFS_YAFFS2
289*0e8cc8bdSWilliam Juul 	__u32 hasShrinkHeader:1; /* This block has at least one shrink object header */
290*0e8cc8bdSWilliam Juul 	__u32 sequenceNumber;	 /* block sequence number for yaffs2 */
291*0e8cc8bdSWilliam Juul #endif
292*0e8cc8bdSWilliam Juul 
293*0e8cc8bdSWilliam Juul } yaffs_BlockInfo;
294*0e8cc8bdSWilliam Juul 
295*0e8cc8bdSWilliam Juul /* -------------------------- Object structure -------------------------------*/
296*0e8cc8bdSWilliam Juul /* This is the object structure as stored on NAND */
297*0e8cc8bdSWilliam Juul 
298*0e8cc8bdSWilliam Juul typedef struct {
299*0e8cc8bdSWilliam Juul 	yaffs_ObjectType type;
300*0e8cc8bdSWilliam Juul 
301*0e8cc8bdSWilliam Juul 	/* Apply to everything  */
302*0e8cc8bdSWilliam Juul 	int parentObjectId;
303*0e8cc8bdSWilliam Juul 	__u16 sum__NoLongerUsed;	/* checksum of name. No longer used */
304*0e8cc8bdSWilliam Juul 	YCHAR name[YAFFS_MAX_NAME_LENGTH + 1];
305*0e8cc8bdSWilliam Juul 
306*0e8cc8bdSWilliam Juul 	/* Thes following apply to directories, files, symlinks - not hard links */
307*0e8cc8bdSWilliam Juul 	__u32 yst_mode;		/* protection */
308*0e8cc8bdSWilliam Juul 
309*0e8cc8bdSWilliam Juul #ifdef CONFIG_YAFFS_WINCE
310*0e8cc8bdSWilliam Juul 	__u32 notForWinCE[5];
311*0e8cc8bdSWilliam Juul #else
312*0e8cc8bdSWilliam Juul 	__u32 yst_uid;
313*0e8cc8bdSWilliam Juul 	__u32 yst_gid;
314*0e8cc8bdSWilliam Juul 	__u32 yst_atime;
315*0e8cc8bdSWilliam Juul 	__u32 yst_mtime;
316*0e8cc8bdSWilliam Juul 	__u32 yst_ctime;
317*0e8cc8bdSWilliam Juul #endif
318*0e8cc8bdSWilliam Juul 
319*0e8cc8bdSWilliam Juul 	/* File size  applies to files only */
320*0e8cc8bdSWilliam Juul 	int fileSize;
321*0e8cc8bdSWilliam Juul 
322*0e8cc8bdSWilliam Juul 	/* Equivalent object id applies to hard links only. */
323*0e8cc8bdSWilliam Juul 	int equivalentObjectId;
324*0e8cc8bdSWilliam Juul 
325*0e8cc8bdSWilliam Juul 	/* Alias is for symlinks only. */
326*0e8cc8bdSWilliam Juul 	YCHAR alias[YAFFS_MAX_ALIAS_LENGTH + 1];
327*0e8cc8bdSWilliam Juul 
328*0e8cc8bdSWilliam Juul 	__u32 yst_rdev;		/* device stuff for block and char devices (major/min) */
329*0e8cc8bdSWilliam Juul 
330*0e8cc8bdSWilliam Juul #ifdef CONFIG_YAFFS_WINCE
331*0e8cc8bdSWilliam Juul 	__u32 win_ctime[2];
332*0e8cc8bdSWilliam Juul 	__u32 win_atime[2];
333*0e8cc8bdSWilliam Juul 	__u32 win_mtime[2];
334*0e8cc8bdSWilliam Juul 	__u32 roomToGrow[4];
335*0e8cc8bdSWilliam Juul #else
336*0e8cc8bdSWilliam Juul 	__u32 roomToGrow[10];
337*0e8cc8bdSWilliam Juul #endif
338*0e8cc8bdSWilliam Juul 
339*0e8cc8bdSWilliam Juul 	int shadowsObject;	/* This object header shadows the specified object if > 0 */
340*0e8cc8bdSWilliam Juul 
341*0e8cc8bdSWilliam Juul 	/* isShrink applies to object headers written when we shrink the file (ie resize) */
342*0e8cc8bdSWilliam Juul 	__u32 isShrink;
343*0e8cc8bdSWilliam Juul 
344*0e8cc8bdSWilliam Juul } yaffs_ObjectHeader;
345*0e8cc8bdSWilliam Juul 
346*0e8cc8bdSWilliam Juul /*--------------------------- Tnode -------------------------- */
347*0e8cc8bdSWilliam Juul 
348*0e8cc8bdSWilliam Juul union yaffs_Tnode_union {
349*0e8cc8bdSWilliam Juul #ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG
350*0e8cc8bdSWilliam Juul 	union yaffs_Tnode_union *internal[YAFFS_NTNODES_INTERNAL + 1];
351*0e8cc8bdSWilliam Juul #else
352*0e8cc8bdSWilliam Juul 	union yaffs_Tnode_union *internal[YAFFS_NTNODES_INTERNAL];
353*0e8cc8bdSWilliam Juul #endif
354*0e8cc8bdSWilliam Juul /*	__u16 level0[YAFFS_NTNODES_LEVEL0]; */
355*0e8cc8bdSWilliam Juul 
356*0e8cc8bdSWilliam Juul };
357*0e8cc8bdSWilliam Juul 
358*0e8cc8bdSWilliam Juul typedef union yaffs_Tnode_union yaffs_Tnode;
359*0e8cc8bdSWilliam Juul 
360*0e8cc8bdSWilliam Juul struct yaffs_TnodeList_struct {
361*0e8cc8bdSWilliam Juul 	struct yaffs_TnodeList_struct *next;
362*0e8cc8bdSWilliam Juul 	yaffs_Tnode *tnodes;
363*0e8cc8bdSWilliam Juul };
364*0e8cc8bdSWilliam Juul 
365*0e8cc8bdSWilliam Juul typedef struct yaffs_TnodeList_struct yaffs_TnodeList;
366*0e8cc8bdSWilliam Juul 
367*0e8cc8bdSWilliam Juul /*------------------------  Object -----------------------------*/
368*0e8cc8bdSWilliam Juul /* An object can be one of:
369*0e8cc8bdSWilliam Juul  * - a directory (no data, has children links
370*0e8cc8bdSWilliam Juul  * - a regular file (data.... not prunes :->).
371*0e8cc8bdSWilliam Juul  * - a symlink [symbolic link] (the alias).
372*0e8cc8bdSWilliam Juul  * - a hard link
373*0e8cc8bdSWilliam Juul  */
374*0e8cc8bdSWilliam Juul 
375*0e8cc8bdSWilliam Juul typedef struct {
376*0e8cc8bdSWilliam Juul 	__u32 fileSize;
377*0e8cc8bdSWilliam Juul 	__u32 scannedFileSize;
378*0e8cc8bdSWilliam Juul 	__u32 shrinkSize;
379*0e8cc8bdSWilliam Juul 	int topLevel;
380*0e8cc8bdSWilliam Juul 	yaffs_Tnode *top;
381*0e8cc8bdSWilliam Juul } yaffs_FileStructure;
382*0e8cc8bdSWilliam Juul 
383*0e8cc8bdSWilliam Juul typedef struct {
384*0e8cc8bdSWilliam Juul 	struct list_head children;	/* list of child links */
385*0e8cc8bdSWilliam Juul } yaffs_DirectoryStructure;
386*0e8cc8bdSWilliam Juul 
387*0e8cc8bdSWilliam Juul typedef struct {
388*0e8cc8bdSWilliam Juul 	YCHAR *alias;
389*0e8cc8bdSWilliam Juul } yaffs_SymLinkStructure;
390*0e8cc8bdSWilliam Juul 
391*0e8cc8bdSWilliam Juul typedef struct {
392*0e8cc8bdSWilliam Juul 	struct yaffs_ObjectStruct *equivalentObject;
393*0e8cc8bdSWilliam Juul 	__u32 equivalentObjectId;
394*0e8cc8bdSWilliam Juul } yaffs_HardLinkStructure;
395*0e8cc8bdSWilliam Juul 
396*0e8cc8bdSWilliam Juul typedef union {
397*0e8cc8bdSWilliam Juul 	yaffs_FileStructure fileVariant;
398*0e8cc8bdSWilliam Juul 	yaffs_DirectoryStructure directoryVariant;
399*0e8cc8bdSWilliam Juul 	yaffs_SymLinkStructure symLinkVariant;
400*0e8cc8bdSWilliam Juul 	yaffs_HardLinkStructure hardLinkVariant;
401*0e8cc8bdSWilliam Juul } yaffs_ObjectVariant;
402*0e8cc8bdSWilliam Juul 
403*0e8cc8bdSWilliam Juul struct yaffs_ObjectStruct {
404*0e8cc8bdSWilliam Juul 	__u8 deleted:1;		/* This should only apply to unlinked files. */
405*0e8cc8bdSWilliam Juul 	__u8 softDeleted:1;	/* it has also been soft deleted */
406*0e8cc8bdSWilliam Juul 	__u8 unlinked:1;	/* An unlinked file. The file should be in the unlinked directory.*/
407*0e8cc8bdSWilliam Juul 	__u8 fake:1;		/* A fake object has no presence on NAND. */
408*0e8cc8bdSWilliam Juul 	__u8 renameAllowed:1;	/* Some objects are not allowed to be renamed. */
409*0e8cc8bdSWilliam Juul 	__u8 unlinkAllowed:1;
410*0e8cc8bdSWilliam Juul 	__u8 dirty:1;		/* the object needs to be written to flash */
411*0e8cc8bdSWilliam Juul 	__u8 valid:1;		/* When the file system is being loaded up, this
412*0e8cc8bdSWilliam Juul 				 * object might be created before the data
413*0e8cc8bdSWilliam Juul 				 * is available (ie. file data records appear before the header).
414*0e8cc8bdSWilliam Juul 				 */
415*0e8cc8bdSWilliam Juul 	__u8 lazyLoaded:1;	/* This object has been lazy loaded and is missing some detail */
416*0e8cc8bdSWilliam Juul 
417*0e8cc8bdSWilliam Juul 	__u8 deferedFree:1;	/* For Linux kernel. Object is removed from NAND, but is
418*0e8cc8bdSWilliam Juul 				 * still in the inode cache. Free of object is defered.
419*0e8cc8bdSWilliam Juul 				 * until the inode is released.
420*0e8cc8bdSWilliam Juul 				 */
421*0e8cc8bdSWilliam Juul 
422*0e8cc8bdSWilliam Juul 	__u8 serial;		/* serial number of chunk in NAND. Cached here */
423*0e8cc8bdSWilliam Juul 	__u16 sum;		/* sum of the name to speed searching */
424*0e8cc8bdSWilliam Juul 
425*0e8cc8bdSWilliam Juul 	struct yaffs_DeviceStruct *myDev;	/* The device I'm on */
426*0e8cc8bdSWilliam Juul 
427*0e8cc8bdSWilliam Juul 	struct list_head hashLink;	/* list of objects in this hash bucket */
428*0e8cc8bdSWilliam Juul 
429*0e8cc8bdSWilliam Juul 	struct list_head hardLinks;	/* all the equivalent hard linked objects */
430*0e8cc8bdSWilliam Juul 
431*0e8cc8bdSWilliam Juul 	/* directory structure stuff */
432*0e8cc8bdSWilliam Juul 	/* also used for linking up the free list */
433*0e8cc8bdSWilliam Juul 	struct yaffs_ObjectStruct *parent;
434*0e8cc8bdSWilliam Juul 	struct list_head siblings;
435*0e8cc8bdSWilliam Juul 
436*0e8cc8bdSWilliam Juul 	/* Where's my object header in NAND? */
437*0e8cc8bdSWilliam Juul 	int chunkId;
438*0e8cc8bdSWilliam Juul 
439*0e8cc8bdSWilliam Juul 	int nDataChunks;	/* Number of data chunks attached to the file. */
440*0e8cc8bdSWilliam Juul 
441*0e8cc8bdSWilliam Juul 	__u32 objectId;		/* the object id value */
442*0e8cc8bdSWilliam Juul 
443*0e8cc8bdSWilliam Juul 	__u32 yst_mode;
444*0e8cc8bdSWilliam Juul 
445*0e8cc8bdSWilliam Juul #ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM
446*0e8cc8bdSWilliam Juul 	YCHAR shortName[YAFFS_SHORT_NAME_LENGTH + 1];
447*0e8cc8bdSWilliam Juul #endif
448*0e8cc8bdSWilliam Juul 
449*0e8cc8bdSWilliam Juul #ifndef __KERNEL__
450*0e8cc8bdSWilliam Juul 	__u32 inUse;
451*0e8cc8bdSWilliam Juul #endif
452*0e8cc8bdSWilliam Juul 
453*0e8cc8bdSWilliam Juul #ifdef CONFIG_YAFFS_WINCE
454*0e8cc8bdSWilliam Juul 	__u32 win_ctime[2];
455*0e8cc8bdSWilliam Juul 	__u32 win_mtime[2];
456*0e8cc8bdSWilliam Juul 	__u32 win_atime[2];
457*0e8cc8bdSWilliam Juul #else
458*0e8cc8bdSWilliam Juul 	__u32 yst_uid;
459*0e8cc8bdSWilliam Juul 	__u32 yst_gid;
460*0e8cc8bdSWilliam Juul 	__u32 yst_atime;
461*0e8cc8bdSWilliam Juul 	__u32 yst_mtime;
462*0e8cc8bdSWilliam Juul 	__u32 yst_ctime;
463*0e8cc8bdSWilliam Juul #endif
464*0e8cc8bdSWilliam Juul 
465*0e8cc8bdSWilliam Juul 	__u32 yst_rdev;
466*0e8cc8bdSWilliam Juul 
467*0e8cc8bdSWilliam Juul #ifdef __KERNEL__
468*0e8cc8bdSWilliam Juul 	struct inode *myInode;
469*0e8cc8bdSWilliam Juul 
470*0e8cc8bdSWilliam Juul #endif
471*0e8cc8bdSWilliam Juul 
472*0e8cc8bdSWilliam Juul 	yaffs_ObjectType variantType;
473*0e8cc8bdSWilliam Juul 
474*0e8cc8bdSWilliam Juul 	yaffs_ObjectVariant variant;
475*0e8cc8bdSWilliam Juul 
476*0e8cc8bdSWilliam Juul };
477*0e8cc8bdSWilliam Juul 
478*0e8cc8bdSWilliam Juul typedef struct yaffs_ObjectStruct yaffs_Object;
479*0e8cc8bdSWilliam Juul 
480*0e8cc8bdSWilliam Juul struct yaffs_ObjectList_struct {
481*0e8cc8bdSWilliam Juul 	yaffs_Object *objects;
482*0e8cc8bdSWilliam Juul 	struct yaffs_ObjectList_struct *next;
483*0e8cc8bdSWilliam Juul };
484*0e8cc8bdSWilliam Juul 
485*0e8cc8bdSWilliam Juul typedef struct yaffs_ObjectList_struct yaffs_ObjectList;
486*0e8cc8bdSWilliam Juul 
487*0e8cc8bdSWilliam Juul typedef struct {
488*0e8cc8bdSWilliam Juul 	struct list_head list;
489*0e8cc8bdSWilliam Juul 	int count;
490*0e8cc8bdSWilliam Juul } yaffs_ObjectBucket;
491*0e8cc8bdSWilliam Juul 
492*0e8cc8bdSWilliam Juul 
493*0e8cc8bdSWilliam Juul /* yaffs_CheckpointObject holds the definition of an object as dumped
494*0e8cc8bdSWilliam Juul  * by checkpointing.
495*0e8cc8bdSWilliam Juul  */
496*0e8cc8bdSWilliam Juul 
497*0e8cc8bdSWilliam Juul typedef struct {
498*0e8cc8bdSWilliam Juul         int structType;
499*0e8cc8bdSWilliam Juul 	__u32 objectId;
500*0e8cc8bdSWilliam Juul 	__u32 parentId;
501*0e8cc8bdSWilliam Juul 	int chunkId;
502*0e8cc8bdSWilliam Juul 
503*0e8cc8bdSWilliam Juul 	yaffs_ObjectType variantType:3;
504*0e8cc8bdSWilliam Juul 	__u8 deleted:1;
505*0e8cc8bdSWilliam Juul 	__u8 softDeleted:1;
506*0e8cc8bdSWilliam Juul 	__u8 unlinked:1;
507*0e8cc8bdSWilliam Juul 	__u8 fake:1;
508*0e8cc8bdSWilliam Juul 	__u8 renameAllowed:1;
509*0e8cc8bdSWilliam Juul 	__u8 unlinkAllowed:1;
510*0e8cc8bdSWilliam Juul 	__u8 serial;
511*0e8cc8bdSWilliam Juul 
512*0e8cc8bdSWilliam Juul 	int nDataChunks;
513*0e8cc8bdSWilliam Juul 	__u32 fileSizeOrEquivalentObjectId;
514*0e8cc8bdSWilliam Juul 
515*0e8cc8bdSWilliam Juul }yaffs_CheckpointObject;
516*0e8cc8bdSWilliam Juul 
517*0e8cc8bdSWilliam Juul /*--------------------- Temporary buffers ----------------
518*0e8cc8bdSWilliam Juul  *
519*0e8cc8bdSWilliam Juul  * These are chunk-sized working buffers. Each device has a few
520*0e8cc8bdSWilliam Juul  */
521*0e8cc8bdSWilliam Juul 
522*0e8cc8bdSWilliam Juul typedef struct {
523*0e8cc8bdSWilliam Juul 	__u8 *buffer;
524*0e8cc8bdSWilliam Juul 	int line;	/* track from whence this buffer was allocated */
525*0e8cc8bdSWilliam Juul 	int maxLine;
526*0e8cc8bdSWilliam Juul } yaffs_TempBuffer;
527*0e8cc8bdSWilliam Juul 
528*0e8cc8bdSWilliam Juul /*----------------- Device ---------------------------------*/
529*0e8cc8bdSWilliam Juul 
530*0e8cc8bdSWilliam Juul struct yaffs_DeviceStruct {
531*0e8cc8bdSWilliam Juul 	struct list_head devList;
532*0e8cc8bdSWilliam Juul 	const char *name;
533*0e8cc8bdSWilliam Juul 
534*0e8cc8bdSWilliam Juul 	/* Entry parameters set up way early. Yaffs sets up the rest.*/
535*0e8cc8bdSWilliam Juul 	int nDataBytesPerChunk;	/* Should be a power of 2 >= 512 */
536*0e8cc8bdSWilliam Juul 	int nChunksPerBlock;	/* does not need to be a power of 2 */
537*0e8cc8bdSWilliam Juul 	int nBytesPerSpare;	/* spare area size */
538*0e8cc8bdSWilliam Juul 	int startBlock;		/* Start block we're allowed to use */
539*0e8cc8bdSWilliam Juul 	int endBlock;		/* End block we're allowed to use */
540*0e8cc8bdSWilliam Juul 	int nReservedBlocks;	/* We want this tuneable so that we can reduce */
541*0e8cc8bdSWilliam Juul 				/* reserved blocks on NOR and RAM. */
542*0e8cc8bdSWilliam Juul 
543*0e8cc8bdSWilliam Juul 
544*0e8cc8bdSWilliam Juul 	/* Stuff used by the shared space checkpointing mechanism */
545*0e8cc8bdSWilliam Juul 	/* If this value is zero, then this mechanism is disabled */
546*0e8cc8bdSWilliam Juul 
547*0e8cc8bdSWilliam Juul 	int nCheckpointReservedBlocks; /* Blocks to reserve for checkpoint data */
548*0e8cc8bdSWilliam Juul 
549*0e8cc8bdSWilliam Juul 
550*0e8cc8bdSWilliam Juul 
551*0e8cc8bdSWilliam Juul 
552*0e8cc8bdSWilliam Juul 	int nShortOpCaches;	/* If <= 0, then short op caching is disabled, else
553*0e8cc8bdSWilliam Juul 				 * the number of short op caches (don't use too many)
554*0e8cc8bdSWilliam Juul 				 */
555*0e8cc8bdSWilliam Juul 
556*0e8cc8bdSWilliam Juul 	int useHeaderFileSize;	/* Flag to determine if we should use file sizes from the header */
557*0e8cc8bdSWilliam Juul 
558*0e8cc8bdSWilliam Juul 	int useNANDECC;		/* Flag to decide whether or not to use NANDECC */
559*0e8cc8bdSWilliam Juul 
560*0e8cc8bdSWilliam Juul 	void *genericDevice;	/* Pointer to device context
561*0e8cc8bdSWilliam Juul 				 * On an mtd this holds the mtd pointer.
562*0e8cc8bdSWilliam Juul 				 */
563*0e8cc8bdSWilliam Juul         void *superBlock;
564*0e8cc8bdSWilliam Juul 
565*0e8cc8bdSWilliam Juul 	/* NAND access functions (Must be set before calling YAFFS)*/
566*0e8cc8bdSWilliam Juul 
567*0e8cc8bdSWilliam Juul 	int (*writeChunkToNAND) (struct yaffs_DeviceStruct * dev,
568*0e8cc8bdSWilliam Juul 				 int chunkInNAND, const __u8 * data,
569*0e8cc8bdSWilliam Juul 				 const yaffs_Spare * spare);
570*0e8cc8bdSWilliam Juul 	int (*readChunkFromNAND) (struct yaffs_DeviceStruct * dev,
571*0e8cc8bdSWilliam Juul 				  int chunkInNAND, __u8 * data,
572*0e8cc8bdSWilliam Juul 				  yaffs_Spare * spare);
573*0e8cc8bdSWilliam Juul 	int (*eraseBlockInNAND) (struct yaffs_DeviceStruct * dev,
574*0e8cc8bdSWilliam Juul 				 int blockInNAND);
575*0e8cc8bdSWilliam Juul 	int (*initialiseNAND) (struct yaffs_DeviceStruct * dev);
576*0e8cc8bdSWilliam Juul 
577*0e8cc8bdSWilliam Juul #ifdef CONFIG_YAFFS_YAFFS2
578*0e8cc8bdSWilliam Juul 	int (*writeChunkWithTagsToNAND) (struct yaffs_DeviceStruct * dev,
579*0e8cc8bdSWilliam Juul 					 int chunkInNAND, const __u8 * data,
580*0e8cc8bdSWilliam Juul 					 const yaffs_ExtendedTags * tags);
581*0e8cc8bdSWilliam Juul 	int (*readChunkWithTagsFromNAND) (struct yaffs_DeviceStruct * dev,
582*0e8cc8bdSWilliam Juul 					  int chunkInNAND, __u8 * data,
583*0e8cc8bdSWilliam Juul 					  yaffs_ExtendedTags * tags);
584*0e8cc8bdSWilliam Juul 	int (*markNANDBlockBad) (struct yaffs_DeviceStruct * dev, int blockNo);
585*0e8cc8bdSWilliam Juul 	int (*queryNANDBlock) (struct yaffs_DeviceStruct * dev, int blockNo,
586*0e8cc8bdSWilliam Juul 			       yaffs_BlockState * state, int *sequenceNumber);
587*0e8cc8bdSWilliam Juul #endif
588*0e8cc8bdSWilliam Juul 
589*0e8cc8bdSWilliam Juul 	int isYaffs2;
590*0e8cc8bdSWilliam Juul 
591*0e8cc8bdSWilliam Juul 	/* The removeObjectCallback function must be supplied by OS flavours that
592*0e8cc8bdSWilliam Juul 	 * need it. The Linux kernel does not use this, but yaffs direct does use
593*0e8cc8bdSWilliam Juul 	 * it to implement the faster readdir
594*0e8cc8bdSWilliam Juul 	 */
595*0e8cc8bdSWilliam Juul 	void (*removeObjectCallback)(struct yaffs_ObjectStruct *obj);
596*0e8cc8bdSWilliam Juul 
597*0e8cc8bdSWilliam Juul 	/* Callback to mark the superblock dirsty */
598*0e8cc8bdSWilliam Juul 	void (*markSuperBlockDirty)(void * superblock);
599*0e8cc8bdSWilliam Juul 
600*0e8cc8bdSWilliam Juul 	int wideTnodesDisabled; /* Set to disable wide tnodes */
601*0e8cc8bdSWilliam Juul 
602*0e8cc8bdSWilliam Juul 
603*0e8cc8bdSWilliam Juul 	/* End of stuff that must be set before initialisation. */
604*0e8cc8bdSWilliam Juul 
605*0e8cc8bdSWilliam Juul 	/* Checkpoint control. Can be set before or after initialisation */
606*0e8cc8bdSWilliam Juul 	__u8 skipCheckpointRead;
607*0e8cc8bdSWilliam Juul 	__u8 skipCheckpointWrite;
608*0e8cc8bdSWilliam Juul 
609*0e8cc8bdSWilliam Juul 	/* Runtime parameters. Set up by YAFFS. */
610*0e8cc8bdSWilliam Juul 
611*0e8cc8bdSWilliam Juul 	__u16 chunkGroupBits;	/* 0 for devices <= 32MB. else log2(nchunks) - 16 */
612*0e8cc8bdSWilliam Juul 	__u16 chunkGroupSize;	/* == 2^^chunkGroupBits */
613*0e8cc8bdSWilliam Juul 
614*0e8cc8bdSWilliam Juul 	/* Stuff to support wide tnodes */
615*0e8cc8bdSWilliam Juul 	__u32 tnodeWidth;
616*0e8cc8bdSWilliam Juul 	__u32 tnodeMask;
617*0e8cc8bdSWilliam Juul 
618*0e8cc8bdSWilliam Juul 	/* Stuff to support various file offses to chunk/offset translations */
619*0e8cc8bdSWilliam Juul 	/* "Crumbs" for nDataBytesPerChunk not being a power of 2 */
620*0e8cc8bdSWilliam Juul 	__u32 crumbMask;
621*0e8cc8bdSWilliam Juul 	__u32 crumbShift;
622*0e8cc8bdSWilliam Juul 	__u32 crumbsPerChunk;
623*0e8cc8bdSWilliam Juul 
624*0e8cc8bdSWilliam Juul 	/* Straight shifting for nDataBytesPerChunk being a power of 2 */
625*0e8cc8bdSWilliam Juul 	__u32 chunkShift;
626*0e8cc8bdSWilliam Juul 	__u32 chunkMask;
627*0e8cc8bdSWilliam Juul 
628*0e8cc8bdSWilliam Juul 
629*0e8cc8bdSWilliam Juul #ifdef __KERNEL__
630*0e8cc8bdSWilliam Juul 
631*0e8cc8bdSWilliam Juul 	struct semaphore sem;	/* Semaphore for waiting on erasure.*/
632*0e8cc8bdSWilliam Juul 	struct semaphore grossLock;	/* Gross locking semaphore */
633*0e8cc8bdSWilliam Juul 	__u8 *spareBuffer;	/* For mtdif2 use. Don't know the size of the buffer
634*0e8cc8bdSWilliam Juul 				 * at compile time so we have to allocate it.
635*0e8cc8bdSWilliam Juul 				 */
636*0e8cc8bdSWilliam Juul 	void (*putSuperFunc) (struct super_block * sb);
637*0e8cc8bdSWilliam Juul #endif
638*0e8cc8bdSWilliam Juul 
639*0e8cc8bdSWilliam Juul 	int isMounted;
640*0e8cc8bdSWilliam Juul 
641*0e8cc8bdSWilliam Juul 	int isCheckpointed;
642*0e8cc8bdSWilliam Juul 
643*0e8cc8bdSWilliam Juul 
644*0e8cc8bdSWilliam Juul 	/* Stuff to support block offsetting to support start block zero */
645*0e8cc8bdSWilliam Juul 	int internalStartBlock;
646*0e8cc8bdSWilliam Juul 	int internalEndBlock;
647*0e8cc8bdSWilliam Juul 	int blockOffset;
648*0e8cc8bdSWilliam Juul 	int chunkOffset;
649*0e8cc8bdSWilliam Juul 
650*0e8cc8bdSWilliam Juul 
651*0e8cc8bdSWilliam Juul 	/* Runtime checkpointing stuff */
652*0e8cc8bdSWilliam Juul 	int checkpointPageSequence;   /* running sequence number of checkpoint pages */
653*0e8cc8bdSWilliam Juul 	int checkpointByteCount;
654*0e8cc8bdSWilliam Juul 	int checkpointByteOffset;
655*0e8cc8bdSWilliam Juul 	__u8 *checkpointBuffer;
656*0e8cc8bdSWilliam Juul 	int checkpointOpenForWrite;
657*0e8cc8bdSWilliam Juul 	int blocksInCheckpoint;
658*0e8cc8bdSWilliam Juul 	int checkpointCurrentChunk;
659*0e8cc8bdSWilliam Juul 	int checkpointCurrentBlock;
660*0e8cc8bdSWilliam Juul 	int checkpointNextBlock;
661*0e8cc8bdSWilliam Juul 	int *checkpointBlockList;
662*0e8cc8bdSWilliam Juul 	int checkpointMaxBlocks;
663*0e8cc8bdSWilliam Juul 	__u32 checkpointSum;
664*0e8cc8bdSWilliam Juul 	__u32 checkpointXor;
665*0e8cc8bdSWilliam Juul 
666*0e8cc8bdSWilliam Juul 	/* Block Info */
667*0e8cc8bdSWilliam Juul 	yaffs_BlockInfo *blockInfo;
668*0e8cc8bdSWilliam Juul 	__u8 *chunkBits;	/* bitmap of chunks in use */
669*0e8cc8bdSWilliam Juul 	unsigned blockInfoAlt:1;	/* was allocated using alternative strategy */
670*0e8cc8bdSWilliam Juul 	unsigned chunkBitsAlt:1;	/* was allocated using alternative strategy */
671*0e8cc8bdSWilliam Juul 	int chunkBitmapStride;	/* Number of bytes of chunkBits per block.
672*0e8cc8bdSWilliam Juul 				 * Must be consistent with nChunksPerBlock.
673*0e8cc8bdSWilliam Juul 				 */
674*0e8cc8bdSWilliam Juul 
675*0e8cc8bdSWilliam Juul 	int nErasedBlocks;
676*0e8cc8bdSWilliam Juul 	int allocationBlock;	/* Current block being allocated off */
677*0e8cc8bdSWilliam Juul 	__u32 allocationPage;
678*0e8cc8bdSWilliam Juul 	int allocationBlockFinder;	/* Used to search for next allocation block */
679*0e8cc8bdSWilliam Juul 
680*0e8cc8bdSWilliam Juul 	/* Runtime state */
681*0e8cc8bdSWilliam Juul 	int nTnodesCreated;
682*0e8cc8bdSWilliam Juul 	yaffs_Tnode *freeTnodes;
683*0e8cc8bdSWilliam Juul 	int nFreeTnodes;
684*0e8cc8bdSWilliam Juul 	yaffs_TnodeList *allocatedTnodeList;
685*0e8cc8bdSWilliam Juul 
686*0e8cc8bdSWilliam Juul 	int isDoingGC;
687*0e8cc8bdSWilliam Juul 
688*0e8cc8bdSWilliam Juul 	int nObjectsCreated;
689*0e8cc8bdSWilliam Juul 	yaffs_Object *freeObjects;
690*0e8cc8bdSWilliam Juul 	int nFreeObjects;
691*0e8cc8bdSWilliam Juul 
692*0e8cc8bdSWilliam Juul 	yaffs_ObjectList *allocatedObjectList;
693*0e8cc8bdSWilliam Juul 
694*0e8cc8bdSWilliam Juul 	yaffs_ObjectBucket objectBucket[YAFFS_NOBJECT_BUCKETS];
695*0e8cc8bdSWilliam Juul 
696*0e8cc8bdSWilliam Juul 	int nFreeChunks;
697*0e8cc8bdSWilliam Juul 
698*0e8cc8bdSWilliam Juul 	int currentDirtyChecker;	/* Used to find current dirtiest block */
699*0e8cc8bdSWilliam Juul 
700*0e8cc8bdSWilliam Juul 	__u32 *gcCleanupList;	/* objects to delete at the end of a GC. */
701*0e8cc8bdSWilliam Juul 	int nonAggressiveSkip;	/* GC state/mode */
702*0e8cc8bdSWilliam Juul 
703*0e8cc8bdSWilliam Juul 	/* Statistcs */
704*0e8cc8bdSWilliam Juul 	int nPageWrites;
705*0e8cc8bdSWilliam Juul 	int nPageReads;
706*0e8cc8bdSWilliam Juul 	int nBlockErasures;
707*0e8cc8bdSWilliam Juul 	int nErasureFailures;
708*0e8cc8bdSWilliam Juul 	int nGCCopies;
709*0e8cc8bdSWilliam Juul 	int garbageCollections;
710*0e8cc8bdSWilliam Juul 	int passiveGarbageCollections;
711*0e8cc8bdSWilliam Juul 	int nRetriedWrites;
712*0e8cc8bdSWilliam Juul 	int nRetiredBlocks;
713*0e8cc8bdSWilliam Juul 	int eccFixed;
714*0e8cc8bdSWilliam Juul 	int eccUnfixed;
715*0e8cc8bdSWilliam Juul 	int tagsEccFixed;
716*0e8cc8bdSWilliam Juul 	int tagsEccUnfixed;
717*0e8cc8bdSWilliam Juul 	int nDeletions;
718*0e8cc8bdSWilliam Juul 	int nUnmarkedDeletions;
719*0e8cc8bdSWilliam Juul 
720*0e8cc8bdSWilliam Juul 	int hasPendingPrioritisedGCs; /* We think this device might have pending prioritised gcs */
721*0e8cc8bdSWilliam Juul 
722*0e8cc8bdSWilliam Juul 	/* Special directories */
723*0e8cc8bdSWilliam Juul 	yaffs_Object *rootDir;
724*0e8cc8bdSWilliam Juul 	yaffs_Object *lostNFoundDir;
725*0e8cc8bdSWilliam Juul 
726*0e8cc8bdSWilliam Juul 	/* Buffer areas for storing data to recover from write failures TODO
727*0e8cc8bdSWilliam Juul 	 *      __u8            bufferedData[YAFFS_CHUNKS_PER_BLOCK][YAFFS_BYTES_PER_CHUNK];
728*0e8cc8bdSWilliam Juul 	 *      yaffs_Spare bufferedSpare[YAFFS_CHUNKS_PER_BLOCK];
729*0e8cc8bdSWilliam Juul 	 */
730*0e8cc8bdSWilliam Juul 
731*0e8cc8bdSWilliam Juul 	int bufferedBlock;	/* Which block is buffered here? */
732*0e8cc8bdSWilliam Juul 	int doingBufferedBlockRewrite;
733*0e8cc8bdSWilliam Juul 
734*0e8cc8bdSWilliam Juul 	yaffs_ChunkCache *srCache;
735*0e8cc8bdSWilliam Juul 	int srLastUse;
736*0e8cc8bdSWilliam Juul 
737*0e8cc8bdSWilliam Juul 	int cacheHits;
738*0e8cc8bdSWilliam Juul 
739*0e8cc8bdSWilliam Juul 	/* Stuff for background deletion and unlinked files.*/
740*0e8cc8bdSWilliam Juul 	yaffs_Object *unlinkedDir;	/* Directory where unlinked and deleted files live. */
741*0e8cc8bdSWilliam Juul 	yaffs_Object *deletedDir;	/* Directory where deleted objects are sent to disappear. */
742*0e8cc8bdSWilliam Juul 	yaffs_Object *unlinkedDeletion;	/* Current file being background deleted.*/
743*0e8cc8bdSWilliam Juul 	int nDeletedFiles;		/* Count of files awaiting deletion;*/
744*0e8cc8bdSWilliam Juul 	int nUnlinkedFiles;		/* Count of unlinked files. */
745*0e8cc8bdSWilliam Juul 	int nBackgroundDeletions;	/* Count of background deletions. */
746*0e8cc8bdSWilliam Juul 
747*0e8cc8bdSWilliam Juul 
748*0e8cc8bdSWilliam Juul 	yaffs_TempBuffer tempBuffer[YAFFS_N_TEMP_BUFFERS];
749*0e8cc8bdSWilliam Juul 	int maxTemp;
750*0e8cc8bdSWilliam Juul 	int unmanagedTempAllocations;
751*0e8cc8bdSWilliam Juul 	int unmanagedTempDeallocations;
752*0e8cc8bdSWilliam Juul 
753*0e8cc8bdSWilliam Juul 	/* yaffs2 runtime stuff */
754*0e8cc8bdSWilliam Juul 	unsigned sequenceNumber;	/* Sequence number of currently allocating block */
755*0e8cc8bdSWilliam Juul 	unsigned oldestDirtySequence;
756*0e8cc8bdSWilliam Juul 
757*0e8cc8bdSWilliam Juul };
758*0e8cc8bdSWilliam Juul 
759*0e8cc8bdSWilliam Juul typedef struct yaffs_DeviceStruct yaffs_Device;
760*0e8cc8bdSWilliam Juul 
761*0e8cc8bdSWilliam Juul /* The static layout of bllock usage etc is stored in the super block header */
762*0e8cc8bdSWilliam Juul typedef struct {
763*0e8cc8bdSWilliam Juul         int StructType;
764*0e8cc8bdSWilliam Juul 	int version;
765*0e8cc8bdSWilliam Juul 	int checkpointStartBlock;
766*0e8cc8bdSWilliam Juul 	int checkpointEndBlock;
767*0e8cc8bdSWilliam Juul 	int startBlock;
768*0e8cc8bdSWilliam Juul 	int endBlock;
769*0e8cc8bdSWilliam Juul 	int rfu[100];
770*0e8cc8bdSWilliam Juul } yaffs_SuperBlockHeader;
771*0e8cc8bdSWilliam Juul 
772*0e8cc8bdSWilliam Juul /* The CheckpointDevice structure holds the device information that changes at runtime and
773*0e8cc8bdSWilliam Juul  * must be preserved over unmount/mount cycles.
774*0e8cc8bdSWilliam Juul  */
775*0e8cc8bdSWilliam Juul typedef struct {
776*0e8cc8bdSWilliam Juul         int structType;
777*0e8cc8bdSWilliam Juul 	int nErasedBlocks;
778*0e8cc8bdSWilliam Juul 	int allocationBlock;	/* Current block being allocated off */
779*0e8cc8bdSWilliam Juul 	__u32 allocationPage;
780*0e8cc8bdSWilliam Juul 	int nFreeChunks;
781*0e8cc8bdSWilliam Juul 
782*0e8cc8bdSWilliam Juul 	int nDeletedFiles;		/* Count of files awaiting deletion;*/
783*0e8cc8bdSWilliam Juul 	int nUnlinkedFiles;		/* Count of unlinked files. */
784*0e8cc8bdSWilliam Juul 	int nBackgroundDeletions;	/* Count of background deletions. */
785*0e8cc8bdSWilliam Juul 
786*0e8cc8bdSWilliam Juul 	/* yaffs2 runtime stuff */
787*0e8cc8bdSWilliam Juul 	unsigned sequenceNumber;	/* Sequence number of currently allocating block */
788*0e8cc8bdSWilliam Juul 	unsigned oldestDirtySequence;
789*0e8cc8bdSWilliam Juul 
790*0e8cc8bdSWilliam Juul } yaffs_CheckpointDevice;
791*0e8cc8bdSWilliam Juul 
792*0e8cc8bdSWilliam Juul 
793*0e8cc8bdSWilliam Juul typedef struct {
794*0e8cc8bdSWilliam Juul     int structType;
795*0e8cc8bdSWilliam Juul     __u32 magic;
796*0e8cc8bdSWilliam Juul     __u32 version;
797*0e8cc8bdSWilliam Juul     __u32 head;
798*0e8cc8bdSWilliam Juul } yaffs_CheckpointValidity;
799*0e8cc8bdSWilliam Juul 
800*0e8cc8bdSWilliam Juul /* Function to manipulate block info */
801*0e8cc8bdSWilliam Juul static Y_INLINE yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device * dev, int blk)
802*0e8cc8bdSWilliam Juul {
803*0e8cc8bdSWilliam Juul 	if (blk < dev->internalStartBlock || blk > dev->internalEndBlock) {
804*0e8cc8bdSWilliam Juul 		T(YAFFS_TRACE_ERROR,
805*0e8cc8bdSWilliam Juul 		  (TSTR
806*0e8cc8bdSWilliam Juul 		   ("**>> yaffs: getBlockInfo block %d is not valid" TENDSTR),
807*0e8cc8bdSWilliam Juul 		   blk));
808*0e8cc8bdSWilliam Juul 		YBUG();
809*0e8cc8bdSWilliam Juul 	}
810*0e8cc8bdSWilliam Juul 	return &dev->blockInfo[blk - dev->internalStartBlock];
811*0e8cc8bdSWilliam Juul }
812*0e8cc8bdSWilliam Juul 
813*0e8cc8bdSWilliam Juul /*----------------------- YAFFS Functions -----------------------*/
814*0e8cc8bdSWilliam Juul 
815*0e8cc8bdSWilliam Juul int yaffs_GutsInitialise(yaffs_Device * dev);
816*0e8cc8bdSWilliam Juul void yaffs_Deinitialise(yaffs_Device * dev);
817*0e8cc8bdSWilliam Juul 
818*0e8cc8bdSWilliam Juul int yaffs_GetNumberOfFreeChunks(yaffs_Device * dev);
819*0e8cc8bdSWilliam Juul 
820*0e8cc8bdSWilliam Juul int yaffs_RenameObject(yaffs_Object * oldDir, const YCHAR * oldName,
821*0e8cc8bdSWilliam Juul 		       yaffs_Object * newDir, const YCHAR * newName);
822*0e8cc8bdSWilliam Juul 
823*0e8cc8bdSWilliam Juul int yaffs_Unlink(yaffs_Object * dir, const YCHAR * name);
824*0e8cc8bdSWilliam Juul int yaffs_DeleteFile(yaffs_Object * obj);
825*0e8cc8bdSWilliam Juul 
826*0e8cc8bdSWilliam Juul int yaffs_GetObjectName(yaffs_Object * obj, YCHAR * name, int buffSize);
827*0e8cc8bdSWilliam Juul int yaffs_GetObjectFileLength(yaffs_Object * obj);
828*0e8cc8bdSWilliam Juul int yaffs_GetObjectInode(yaffs_Object * obj);
829*0e8cc8bdSWilliam Juul unsigned yaffs_GetObjectType(yaffs_Object * obj);
830*0e8cc8bdSWilliam Juul int yaffs_GetObjectLinkCount(yaffs_Object * obj);
831*0e8cc8bdSWilliam Juul 
832*0e8cc8bdSWilliam Juul int yaffs_SetAttributes(yaffs_Object * obj, struct iattr *attr);
833*0e8cc8bdSWilliam Juul int yaffs_GetAttributes(yaffs_Object * obj, struct iattr *attr);
834*0e8cc8bdSWilliam Juul 
835*0e8cc8bdSWilliam Juul /* File operations */
836*0e8cc8bdSWilliam Juul int yaffs_ReadDataFromFile(yaffs_Object * obj, __u8 * buffer, loff_t offset,
837*0e8cc8bdSWilliam Juul 			   int nBytes);
838*0e8cc8bdSWilliam Juul int yaffs_WriteDataToFile(yaffs_Object * obj, const __u8 * buffer, loff_t offset,
839*0e8cc8bdSWilliam Juul 			  int nBytes, int writeThrough);
840*0e8cc8bdSWilliam Juul int yaffs_ResizeFile(yaffs_Object * obj, loff_t newSize);
841*0e8cc8bdSWilliam Juul 
842*0e8cc8bdSWilliam Juul yaffs_Object *yaffs_MknodFile(yaffs_Object * parent, const YCHAR * name,
843*0e8cc8bdSWilliam Juul 			      __u32 mode, __u32 uid, __u32 gid);
844*0e8cc8bdSWilliam Juul int yaffs_FlushFile(yaffs_Object * obj, int updateTime);
845*0e8cc8bdSWilliam Juul 
846*0e8cc8bdSWilliam Juul /* Flushing and checkpointing */
847*0e8cc8bdSWilliam Juul void yaffs_FlushEntireDeviceCache(yaffs_Device *dev);
848*0e8cc8bdSWilliam Juul 
849*0e8cc8bdSWilliam Juul int yaffs_CheckpointSave(yaffs_Device *dev);
850*0e8cc8bdSWilliam Juul int yaffs_CheckpointRestore(yaffs_Device *dev);
851*0e8cc8bdSWilliam Juul 
852*0e8cc8bdSWilliam Juul /* Directory operations */
853*0e8cc8bdSWilliam Juul yaffs_Object *yaffs_MknodDirectory(yaffs_Object * parent, const YCHAR * name,
854*0e8cc8bdSWilliam Juul 				   __u32 mode, __u32 uid, __u32 gid);
855*0e8cc8bdSWilliam Juul yaffs_Object *yaffs_FindObjectByName(yaffs_Object * theDir, const YCHAR * name);
856*0e8cc8bdSWilliam Juul int yaffs_ApplyToDirectoryChildren(yaffs_Object * theDir,
857*0e8cc8bdSWilliam Juul 				   int (*fn) (yaffs_Object *));
858*0e8cc8bdSWilliam Juul 
859*0e8cc8bdSWilliam Juul yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device * dev, __u32 number);
860*0e8cc8bdSWilliam Juul 
861*0e8cc8bdSWilliam Juul /* Link operations */
862*0e8cc8bdSWilliam Juul yaffs_Object *yaffs_Link(yaffs_Object * parent, const YCHAR * name,
863*0e8cc8bdSWilliam Juul 			 yaffs_Object * equivalentObject);
864*0e8cc8bdSWilliam Juul 
865*0e8cc8bdSWilliam Juul yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object * obj);
866*0e8cc8bdSWilliam Juul 
867*0e8cc8bdSWilliam Juul /* Symlink operations */
868*0e8cc8bdSWilliam Juul yaffs_Object *yaffs_MknodSymLink(yaffs_Object * parent, const YCHAR * name,
869*0e8cc8bdSWilliam Juul 				 __u32 mode, __u32 uid, __u32 gid,
870*0e8cc8bdSWilliam Juul 				 const YCHAR * alias);
871*0e8cc8bdSWilliam Juul YCHAR *yaffs_GetSymlinkAlias(yaffs_Object * obj);
872*0e8cc8bdSWilliam Juul 
873*0e8cc8bdSWilliam Juul /* Special inodes (fifos, sockets and devices) */
874*0e8cc8bdSWilliam Juul yaffs_Object *yaffs_MknodSpecial(yaffs_Object * parent, const YCHAR * name,
875*0e8cc8bdSWilliam Juul 				 __u32 mode, __u32 uid, __u32 gid, __u32 rdev);
876*0e8cc8bdSWilliam Juul 
877*0e8cc8bdSWilliam Juul /* Special directories */
878*0e8cc8bdSWilliam Juul yaffs_Object *yaffs_Root(yaffs_Device * dev);
879*0e8cc8bdSWilliam Juul yaffs_Object *yaffs_LostNFound(yaffs_Device * dev);
880*0e8cc8bdSWilliam Juul 
881*0e8cc8bdSWilliam Juul #ifdef CONFIG_YAFFS_WINCE
882*0e8cc8bdSWilliam Juul /* CONFIG_YAFFS_WINCE special stuff */
883*0e8cc8bdSWilliam Juul void yfsd_WinFileTimeNow(__u32 target[2]);
884*0e8cc8bdSWilliam Juul #endif
885*0e8cc8bdSWilliam Juul 
886*0e8cc8bdSWilliam Juul #ifdef __KERNEL__
887*0e8cc8bdSWilliam Juul 
888*0e8cc8bdSWilliam Juul void yaffs_HandleDeferedFree(yaffs_Object * obj);
889*0e8cc8bdSWilliam Juul #endif
890*0e8cc8bdSWilliam Juul 
891*0e8cc8bdSWilliam Juul /* Debug dump  */
892*0e8cc8bdSWilliam Juul int yaffs_DumpObject(yaffs_Object * obj);
893*0e8cc8bdSWilliam Juul 
894*0e8cc8bdSWilliam Juul void yaffs_GutsTest(yaffs_Device * dev);
895*0e8cc8bdSWilliam Juul 
896*0e8cc8bdSWilliam Juul /* A few useful functions */
897*0e8cc8bdSWilliam Juul void yaffs_InitialiseTags(yaffs_ExtendedTags * tags);
898*0e8cc8bdSWilliam Juul void yaffs_DeleteChunk(yaffs_Device * dev, int chunkId, int markNAND, int lyn);
899*0e8cc8bdSWilliam Juul int yaffs_CheckFF(__u8 * buffer, int nBytes);
900*0e8cc8bdSWilliam Juul void yaffs_HandleChunkError(yaffs_Device *dev, yaffs_BlockInfo *bi);
901*0e8cc8bdSWilliam Juul 
902*0e8cc8bdSWilliam Juul #endif
903