1 //==========================================================================
5 // FAT file system FAT table cache functions
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 2003 eCosCentric Limited
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.
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
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.
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.
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.
36 // -------------------------------------------
37 //####ECOSGPLCOPYRIGHTEND####
38 //==========================================================================
39 //#####DESCRIPTIONBEGIN####
44 //####DESCRIPTIONEND####
46 //==========================================================================
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>
59 //==========================================================================
62 #define TC_INC FATFS_FAT_TABLE_CACHE_INCREMENT
64 #ifdef CYGDBG_USE_ASSERTS
65 # define USE_ASSERTS 1
68 #ifdef FATFS_TRACE_FAT_TABLE_CACHE
74 //==========================================================================
77 //--------------------------------------------------------------------------
79 // Allocates or reallocates memory for FAT table cache.
80 // Returns true is allocation succeded.
83 tcache_increment(fatfs_disk_t *disk, fatfs_tcache_t *tcache)
85 CYG_TRACE2(TTC, "max_size=%d size=%d", tcache->max_size, tcache->size);
87 if (NULL == tcache->clusters)
90 (cyg_uint32 *)cyg_mempool_var_try_alloc(disk->tcache_mpool_h,
91 TC_INC*sizeof(cyg_uint32));
93 if (NULL == tcache->clusters)
96 tcache->max_size = TC_INC;
102 newc = (cyg_uint32 *)cyg_mempool_var_try_alloc(disk->tcache_mpool_h,
103 (tcache->max_size+TC_INC)*sizeof(cyg_uint32));
108 memcpy(newc, tcache->clusters, (tcache->max_size*sizeof(cyg_uint32)));
109 cyg_mempool_var_free(disk->tcache_mpool_h, tcache->clusters);
111 tcache->clusters = newc;
112 tcache->max_size += TC_INC;
115 CYG_TRACE2(TTC, "max_size=%d size=%d", tcache->max_size, tcache->size);
120 //==========================================================================
121 // Exported functions
123 //--------------------------------------------------------------------------
124 // fatfs_tcache_create()
125 // Creates FAT table caches memory pool.
128 fatfs_tcache_create(fatfs_disk_t *disk, cyg_uint32 mem_size)
130 disk->tcache_mem = (cyg_uint8 *)malloc(mem_size);
131 if (NULL == disk->tcache_mem)
134 cyg_mempool_var_create(disk->tcache_mem, mem_size,
135 &disk->tcache_mpool_h, &disk->tcache_mpool);
139 //--------------------------------------------------------------------------
140 // fatfs_tcache_delete()
141 // Deletes FAT table caches memory pool.
144 fatfs_tcache_delete(fatfs_disk_t *disk)
146 cyg_mempool_var_delete(disk->tcache_mpool_h);
147 free(disk->tcache_mem);
150 //--------------------------------------------------------------------------
151 // fatfs_tcache_init()
152 // Initializes FAT table cache structure.
155 fatfs_tcache_init(fatfs_disk_t *disk, fatfs_tcache_t *tcache)
157 CYG_CHECK_DATA_PTRC(tcache);
159 tcache->clusters = NULL;
161 tcache->max_size = 0;
164 //--------------------------------------------------------------------------
165 // fatfs_tcache_flush()
166 // Frees given tcache.
169 fatfs_tcache_flush(fatfs_disk_t *disk, fatfs_tcache_t *tcache)
171 CYG_CHECK_DATA_PTRC(tcache);
173 if (tcache->clusters != NULL)
175 cyg_mempool_var_free(disk->tcache_mpool_h, tcache->clusters);
176 tcache->clusters = NULL;
178 tcache->max_size = 0;
182 //--------------------------------------------------------------------------
183 // fatfs_tcache_get()
184 // Gets the cluster from cache at given position.
185 // Returns true if cluster in cache.
188 fatfs_tcache_get(fatfs_disk_t *disk,
189 fatfs_tcache_t *tcache,
193 CYG_CHECK_DATA_PTRC(tcache);
194 CYG_TRACE2(TTC, "size=%d max_size=%d", tcache->size, tcache->max_size);
196 // Check if requested cluster is cached
197 if (num >= tcache->size)
199 CYG_TRACE1(TTC, "cluster num=%d not in tcache", num);
203 *cluster = tcache->clusters[num];
204 CYG_TRACE2(TTC, "got cluster=%d num=%d from tcache", *cluster, num);
208 //--------------------------------------------------------------------------
209 // fatfs_tcache_get()
210 // Gets last cluster in cache.
211 // Returns false if cache is empty.
214 fatfs_tcache_get_last(fatfs_disk_t *disk,
215 fatfs_tcache_t *tcache,
219 CYG_CHECK_DATA_PTRC(tcache);
220 CYG_TRACE2(TTC, "size=%d max_size=%d", tcache->size, tcache->max_size);
222 // Check if we have something in cache
223 if (tcache->size == 0)
226 *num = tcache->size - 1;
227 *cluster = tcache->clusters[*num];
228 CYG_TRACE2(TTC, "got last cluster=%d num=%d from tcache", *cluster, *num);
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.
240 fatfs_tcache_set(fatfs_disk_t *disk,
241 fatfs_tcache_t *tcache,
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);
249 if (num > tcache->size)
251 CYG_TRACE0(TTC, "won't make a hole in tcache");
255 if (num < tcache->size)
257 CYG_TRACE2(TTC, "set cluster=%d num=%d in tcache", cluster, num);
258 tcache->clusters[num] = cluster;
262 // Here num is equal to size - check if we need to increment cache
263 if (tcache->size == tcache->max_size)
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))
269 fatfs_node_flush_dead_tcache(disk);
270 if (!tcache_increment(disk, tcache))
276 tcache->clusters[num] = cluster;
278 CYG_TRACE2(TTC, "added cluster=%d num=%d to tcache", cluster, num);
283 // -------------------------------------------------------------------------
284 // EOF fatfs_tcache.c