]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/fs/fat/v2_0/src/fatfs_tcache.c
Initial revision
[karo-tx-redboot.git] / packages / fs / fat / v2_0 / src / fatfs_tcache.c
1 //==========================================================================
2 //
3 //      fatfs_tcache.c
4 //
5 //      FAT file system FAT table cache functions
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 2003 Savin Zlobec 
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // -------------------------------------------
37 //####ECOSGPLCOPYRIGHTEND####
38 //==========================================================================
39 //#####DESCRIPTIONBEGIN####
40 //
41 // Author(s):           savin 
42 // Date:                2003-06-27
43 //
44 //####DESCRIPTIONEND####
45 //
46 //==========================================================================
47
48 #include <pkgconf/fs_fat.h>
49 #include <pkgconf/infra.h>
50 #include <cyg/kernel/kapi.h>
51 #include <cyg/infra/cyg_type.h>
52 #include <cyg/infra/cyg_ass.h>
53 #include <cyg/infra/cyg_trac.h>
54 #include <cyg/infra/diag.h>
55 #include <sys/types.h>
56
57 #include "fatfs.h"
58
59 //==========================================================================
60 // Defines & macros 
61
62 #define TC_INC FATFS_FAT_TABLE_CACHE_INCREMENT
63
64 #ifdef CYGDBG_USE_ASSERTS
65 # define USE_ASSERTS 1
66 #endif
67
68 #ifdef FATFS_TRACE_FAT_TABLE_CACHE
69 # define TTC 1
70 #else
71 # define TTC 0
72 #endif
73
74 //==========================================================================
75 // Private functions 
76
77 //--------------------------------------------------------------------------
78 // tcache_increment()
79 // Allocates or reallocates memory for FAT table cache.
80 // Returns true is allocation succeded. 
81
82 static bool 
83 tcache_increment(fatfs_disk_t *disk, fatfs_tcache_t *tcache)
84 {
85     CYG_TRACE2(TTC, "max_size=%d size=%d", tcache->max_size, tcache->size);
86
87     if (NULL == tcache->clusters)
88     {
89         tcache->clusters = 
90             (cyg_uint32 *)cyg_mempool_var_try_alloc(disk->tcache_mpool_h, 
91                                                     TC_INC*sizeof(cyg_uint32));
92
93         if (NULL == tcache->clusters)
94             return false;
95
96         tcache->max_size = TC_INC;
97     }
98     else
99     {
100         cyg_uint32 *newc;
101
102         newc = (cyg_uint32 *)cyg_mempool_var_try_alloc(disk->tcache_mpool_h,
103             (tcache->max_size+TC_INC)*sizeof(cyg_uint32));
104
105         if (NULL == newc)
106             return false;
107
108         memcpy(newc, tcache->clusters, (tcache->max_size*sizeof(cyg_uint32)));
109         cyg_mempool_var_free(disk->tcache_mpool_h, tcache->clusters);
110         
111         tcache->clusters = newc;
112         tcache->max_size += TC_INC;
113     }
114
115     CYG_TRACE2(TTC, "max_size=%d size=%d", tcache->max_size, tcache->size);
116
117     return true;
118 }
119
120 //==========================================================================
121 // Exported functions 
122
123 //--------------------------------------------------------------------------
124 // fatfs_tcache_create()
125 // Creates FAT table caches memory pool.
126
127 int  
128 fatfs_tcache_create(fatfs_disk_t *disk, cyg_uint32 mem_size)
129 {
130     disk->tcache_mem = (cyg_uint8 *)malloc(mem_size);
131     if (NULL == disk->tcache_mem)
132         return ENOMEM;
133     
134     cyg_mempool_var_create(disk->tcache_mem, mem_size, 
135                            &disk->tcache_mpool_h, &disk->tcache_mpool);
136     return ENOERR;
137 }
138
139 //--------------------------------------------------------------------------
140 // fatfs_tcache_delete()
141 // Deletes FAT table caches memory pool.
142
143 void 
144 fatfs_tcache_delete(fatfs_disk_t *disk)
145 {
146     cyg_mempool_var_delete(disk->tcache_mpool_h);
147     free(disk->tcache_mem);
148 }
149
150 //--------------------------------------------------------------------------
151 // fatfs_tcache_init()
152 // Initializes FAT table cache structure.
153
154 void
155 fatfs_tcache_init(fatfs_disk_t *disk, fatfs_tcache_t *tcache)
156 {
157     CYG_CHECK_DATA_PTRC(tcache);
158
159     tcache->clusters = NULL;
160     tcache->size     = 0;
161     tcache->max_size = 0;
162 }
163
164 //--------------------------------------------------------------------------
165 // fatfs_tcache_flush()
166 // Frees given tcache.
167
168 void
169 fatfs_tcache_flush(fatfs_disk_t *disk, fatfs_tcache_t *tcache)
170 {
171     CYG_CHECK_DATA_PTRC(tcache);
172
173     if (tcache->clusters != NULL)
174     {
175         cyg_mempool_var_free(disk->tcache_mpool_h, tcache->clusters);
176         tcache->clusters = NULL;    
177         tcache->size     = 0;
178         tcache->max_size = 0;
179     }
180 }
181
182 //--------------------------------------------------------------------------
183 // fatfs_tcache_get()
184 // Gets the cluster from cache at given position.
185 // Returns true if cluster in cache. 
186
187 bool
188 fatfs_tcache_get(fatfs_disk_t   *disk,
189                  fatfs_tcache_t *tcache, 
190                  cyg_uint32      num, 
191                  cyg_uint32     *cluster)
192 {
193     CYG_CHECK_DATA_PTRC(tcache);
194     CYG_TRACE2(TTC, "size=%d max_size=%d", tcache->size, tcache->max_size);
195     
196     // Check if requested cluster is cached
197     if (num >= tcache->size)
198     {
199         CYG_TRACE1(TTC, "cluster num=%d not in tcache", num);
200         return false;
201     }
202     
203     *cluster = tcache->clusters[num];  
204     CYG_TRACE2(TTC, "got cluster=%d num=%d from tcache", *cluster, num);
205     return true;
206 }
207
208 //--------------------------------------------------------------------------
209 // fatfs_tcache_get()
210 // Gets last cluster in cache.
211 // Returns false if cache is empty.
212
213 bool
214 fatfs_tcache_get_last(fatfs_disk_t   *disk,
215                       fatfs_tcache_t *tcache, 
216                       cyg_uint32     *num, 
217                       cyg_uint32     *cluster)
218 {
219     CYG_CHECK_DATA_PTRC(tcache);
220     CYG_TRACE2(TTC, "size=%d max_size=%d", tcache->size, tcache->max_size);
221     
222     // Check if we have something in cache
223     if (tcache->size == 0)
224         return false;
225    
226     *num = tcache->size - 1; 
227     *cluster = tcache->clusters[*num];  
228     CYG_TRACE2(TTC, "got last cluster=%d num=%d from tcache", *cluster, *num);
229     return true;
230 }
231
232 //--------------------------------------------------------------------------
233 // fatfs_tcache_set()
234 // Sets given cluster in cache at given position.
235 // There can't be any holes in cache (ie in order to set cluster
236 // at position N all clusters from 0 to N-1 must be set before)
237 // Returns true if set succeded.
238
239 bool
240 fatfs_tcache_set(fatfs_disk_t   *disk,
241                  fatfs_tcache_t *tcache, 
242                  cyg_uint32      num, 
243                  cyg_uint32      cluster)
244 {
245     CYG_CHECK_DATA_PTRC(tcache);
246     CYG_TRACE4(TTC, "num=%d cluster=%d tcache size=%d max_size=%d", 
247         num, cluster, tcache->size, tcache->max_size);
248
249     if (num > tcache->size)
250     {
251         CYG_TRACE0(TTC, "won't make a hole in tcache");
252         return false;
253     }
254     
255     if (num < tcache->size)
256     {
257         CYG_TRACE2(TTC, "set cluster=%d num=%d in tcache", cluster, num);
258         tcache->clusters[num] = cluster;
259         return true;
260     }
261
262     // Here num is equal to size - check if we need to increment cache 
263     if (tcache->size == tcache->max_size)
264     {
265         // If we can't get memory to increment the cache
266         // try to flush dead nodes fat table cache
267         if (!tcache_increment(disk, tcache))
268         {
269             fatfs_node_flush_dead_tcache(disk); 
270             if (!tcache_increment(disk, tcache))
271                 return false;
272         }
273     }
274     
275     tcache->size++;
276     tcache->clusters[num] = cluster;
277
278     CYG_TRACE2(TTC, "added cluster=%d num=%d to tcache", cluster, num);
279
280     return true;
281 }
282
283 // -------------------------------------------------------------------------
284 // EOF fatfs_tcache.c