1 /*
2 This file is part of UFFS, the Ultra-low-cost Flash File System.
3
4 Copyright (C) 2005-2009 Ricky Zheng <[email protected]>
5
6 UFFS is free software; you can redistribute it and/or modify it under
7 the GNU Library General Public License as published by the Free Software
8 Foundation; either version 2 of the License, or (at your option) any
9 later version.
10
11 UFFS is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 or GNU Library General Public License, as applicable, for more details.
15
16 You should have received a copy of the GNU General Public License
17 and GNU Library General Public License along with UFFS; if not, write
18 to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20
21 As a special exception, if other files instantiate templates or use
22 macros or inline functions from this file, or you compile this file
23 and link it with other works to produce a work based on this file,
24 this file does not by itself cause the resulting work to be covered
25 by the GNU General Public License. However the source code for this
26 file must still be made available in accordance with section (3) of
27 the GNU General Public License v2.
28
29 This exception does not invalidate any other reasons why a work based
30 on this file might be covered by the GNU General Public License.
31 */
32
33 /**
34 * \file uffs_init.c
35 * \brief initialize uffs file system device
36 * \author Ricky Zheng, created 12th May, 2005
37 */
38
39 #include "uffs_config.h"
40 #include "uffs/uffs_types.h"
41 #include "uffs/uffs_public.h"
42 #include "uffs/uffs_tree.h"
43 #include "uffs/uffs_fs.h"
44 #include "uffs/uffs_badblock.h"
45 #include "uffs/uffs_utils.h"
46 #include <string.h>
47
48 #define PFX "init: "
49
uffs_InitDeviceConfig(uffs_Device * dev)50 static URET uffs_InitDeviceConfig(uffs_Device *dev)
51 {
52 if (dev->cfg.dirty_groups == 0)
53 dev->cfg.dirty_groups = MAX_DIRTY_BUF_GROUPS;
54
55 if (!uffs_Assert(dev->cfg.dirty_groups >= 1 && dev->cfg.dirty_groups <= MAX_DIRTY_BUF_GROUPS,
56 "invalid config: dirty_groups = %d\n", dev->cfg.dirty_groups))
57 return U_FAIL;
58
59 #if CONFIG_USE_STATIC_MEMORY_ALLOCATOR > 0
60 dev->cfg.bc_caches = MAX_CACHED_BLOCK_INFO;
61 dev->cfg.page_buffers = MAX_PAGE_BUFFERS;
62 dev->cfg.dirty_pages = MAX_DIRTY_PAGES_IN_A_BLOCK;
63 dev->cfg.reserved_free_blocks = MINIMUN_ERASED_BLOCK;
64 #else
65 if (dev->cfg.bc_caches == 0)
66 dev->cfg.bc_caches = MAX_CACHED_BLOCK_INFO;
67 if (dev->cfg.page_buffers == 0)
68 dev->cfg.page_buffers = MAX_PAGE_BUFFERS;
69 if (dev->cfg.dirty_pages == 0)
70 dev->cfg.dirty_pages = MAX_DIRTY_PAGES_IN_A_BLOCK;
71 if (dev->cfg.reserved_free_blocks == 0)
72 dev->cfg.reserved_free_blocks = MINIMUN_ERASED_BLOCK;
73
74 if (!uffs_Assert(dev->cfg.page_buffers - CLONE_BUFFERS_THRESHOLD >= 3, "invalid config: page_buffers = %d\n", dev->cfg.page_buffers))
75 return U_FAIL;
76
77 #endif
78 return U_SUCC;
79 }
80
uffs_InitDevice(uffs_Device * dev)81 URET uffs_InitDevice(uffs_Device *dev)
82 {
83 URET ret;
84
85 ret = uffs_InitDeviceConfig(dev);
86 if (ret != U_SUCC)
87 return U_FAIL;
88
89 if (dev->mem.init) {
90 if (dev->mem.init(dev) != U_SUCC) {
91 uffs_Perror(UFFS_MSG_SERIOUS, "Init memory allocator fail.");
92 return U_FAIL;
93 }
94 }
95
96 memset(&(dev->st), 0, sizeof(uffs_FlashStat));
97
98 uffs_DeviceInitLock(dev);
99 uffs_BadBlockInit(dev);
100
101
102 if (uffs_FlashInterfaceInit(dev) != U_SUCC) {
103 uffs_Perror(UFFS_MSG_SERIOUS, "Can't initialize flash interface !");
104 goto fail;
105 }
106
107 uffs_Perror(UFFS_MSG_NOISY, "init page buf");
108 ret = uffs_BufInit(dev, dev->cfg.page_buffers, dev->cfg.dirty_pages);
109 if (ret != U_SUCC) {
110 uffs_Perror(UFFS_MSG_DEAD, "Initialize page buffers fail");
111 goto fail;
112 }
113 uffs_Perror(UFFS_MSG_NOISY, "init block info cache");
114 ret = uffs_BlockInfoInitCache(dev, dev->cfg.bc_caches);
115 if (ret != U_SUCC) {
116 uffs_Perror(UFFS_MSG_DEAD, "Initialize block info fail");
117 goto fail;
118 }
119
120 ret = uffs_TreeInit(dev);
121 if (ret != U_SUCC) {
122 uffs_Perror(UFFS_MSG_SERIOUS, "fail to init tree buffers");
123 goto fail;
124 }
125
126 ret = uffs_BuildTree(dev);
127 if (ret != U_SUCC) {
128 uffs_Perror(UFFS_MSG_SERIOUS, "fail to build tree");
129 goto fail;
130 }
131
132 return U_SUCC;
133
134 fail:
135 uffs_DeviceReleaseLock(dev);
136
137 return U_FAIL;
138 }
139
uffs_ReleaseDevice(uffs_Device * dev)140 URET uffs_ReleaseDevice(uffs_Device *dev)
141 {
142 URET ret;
143
144 ret = uffs_BlockInfoReleaseCache(dev);
145 if (ret != U_SUCC) {
146 uffs_Perror(UFFS_MSG_SERIOUS, "fail to release block info.");
147 goto ext;
148 }
149
150 ret = uffs_BufReleaseAll(dev);
151 if (ret != U_SUCC) {
152 uffs_Perror(UFFS_MSG_SERIOUS, "fail to release page buffers");
153 goto ext;
154 }
155
156 ret = uffs_TreeRelease(dev);
157 if (ret != U_SUCC) {
158 uffs_Perror(UFFS_MSG_SERIOUS, "fail to release tree buffers!");
159 goto ext;
160 }
161
162 ret = uffs_FlashInterfaceRelease(dev);
163 if (ret != U_SUCC) {
164 uffs_Perror(UFFS_MSG_SERIOUS, "fail to release tree buffers!");
165 goto ext;
166 }
167
168 if (dev->mem.release)
169 ret = dev->mem.release(dev);
170
171 if (ret != U_SUCC) {
172 uffs_Perror(UFFS_MSG_SERIOUS, "fail to release memory allocator!");
173 }
174
175 uffs_DeviceReleaseLock(dev);
176
177 ext:
178 return ret;
179
180 }
181
uffs_InitFileSystemObjects(void)182 URET uffs_InitFileSystemObjects(void)
183 {
184 if (uffs_InitObjectBuf() == U_SUCC) {
185 if (uffs_DirEntryBufInit() == U_SUCC) {
186 uffs_InitGlobalFsLock();
187 return U_SUCC;
188 }
189 }
190
191 return U_FAIL;
192 }
193
uffs_ReleaseFileSystemObjects(void)194 URET uffs_ReleaseFileSystemObjects(void)
195 {
196 if (uffs_ReleaseObjectBuf() == U_SUCC) {
197 if (uffs_DirEntryBufRelease() == U_SUCC) {
198 uffs_ReleaseGlobalFsLock();
199 return U_SUCC;
200 }
201 }
202
203 return U_FAIL;
204 }
205