Skip to content

Commit 6f6ea14

Browse files
author
David Saada
committed
Add some logic related to initialization to various block devices
- Add an initialization flag on which BD actions depend (fail if uninitialized). - Fix behavior of init reference count if first initialization fails
1 parent 96af5a4 commit 6f6ea14

12 files changed

+282
-35
lines changed

features/filesystem/bd/BufferedBlockDevice.cpp

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ static inline uint32_t align_down(bd_size_t val, bd_size_t size)
2626
}
2727

2828
BufferedBlockDevice::BufferedBlockDevice(BlockDevice *bd)
29-
: _bd(bd), _bd_program_size(0), _curr_aligned_addr(0), _flushed(true), _cache(0), _init_ref_count(0)
29+
: _bd(bd), _bd_program_size(0), _curr_aligned_addr(0), _flushed(true), _cache(0), _init_ref_count(0), _is_initialized(false)
3030
{
3131
}
3232

@@ -57,11 +57,16 @@ int BufferedBlockDevice::init()
5757
_curr_aligned_addr = _bd->size();
5858
_flushed = true;
5959

60-
return 0;
60+
_is_initialized = true;
61+
return BD_ERROR_OK;
6162
}
6263

6364
int BufferedBlockDevice::deinit()
6465
{
66+
if (!_is_initialized) {
67+
return BD_ERROR_OK;
68+
}
69+
6570
uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1);
6671

6772
if (val) {
@@ -70,11 +75,16 @@ int BufferedBlockDevice::deinit()
7075

7176
delete[] _cache;
7277
_cache = 0;
78+
_is_initialized = false;
7379
return _bd->deinit();
7480
}
7581

7682
int BufferedBlockDevice::flush()
7783
{
84+
if (!_is_initialized) {
85+
return BD_ERROR_DEVICE_ERROR;
86+
}
87+
7888
if (!_flushed) {
7989
int ret = _bd->program(_cache, _curr_aligned_addr, _bd_program_size);
8090
if (ret) {
@@ -87,6 +97,10 @@ int BufferedBlockDevice::flush()
8797

8898
int BufferedBlockDevice::sync()
8999
{
100+
if (!_is_initialized) {
101+
return BD_ERROR_DEVICE_ERROR;
102+
}
103+
90104
int ret = flush();
91105
if (ret) {
92106
return ret;
@@ -97,6 +111,10 @@ int BufferedBlockDevice::sync()
97111
int BufferedBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size)
98112
{
99113
MBED_ASSERT(_cache);
114+
if (!_is_initialized) {
115+
return BD_ERROR_DEVICE_ERROR;
116+
}
117+
100118
bool moved_unit = false;
101119

102120
bd_addr_t aligned_addr = align_down(addr, _bd_program_size);
@@ -132,7 +150,10 @@ int BufferedBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size)
132150

133151
int BufferedBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size)
134152
{
135-
MBED_ASSERT(_cache);
153+
if (!_is_initialized) {
154+
return BD_ERROR_DEVICE_ERROR;
155+
}
156+
136157
int ret;
137158
bool moved_unit = false;
138159

@@ -196,12 +217,19 @@ int BufferedBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size)
196217
int BufferedBlockDevice::erase(bd_addr_t addr, bd_size_t size)
197218
{
198219
MBED_ASSERT(is_valid_erase(addr, size));
220+
if (!_is_initialized) {
221+
return BD_ERROR_DEVICE_ERROR;
222+
}
223+
199224
return _bd->erase(addr, size);
200225
}
201226

202227
int BufferedBlockDevice::trim(bd_addr_t addr, bd_size_t size)
203228
{
204229
MBED_ASSERT(is_valid_erase(addr, size));
230+
if (!_is_initialized) {
231+
return BD_ERROR_DEVICE_ERROR;
232+
}
205233

206234
if ((_curr_aligned_addr >= addr) && (_curr_aligned_addr <= addr + size)) {
207235
_flushed = true;
@@ -222,20 +250,36 @@ bd_size_t BufferedBlockDevice::get_program_size() const
222250

223251
bd_size_t BufferedBlockDevice::get_erase_size() const
224252
{
253+
if (!_is_initialized) {
254+
return BD_ERROR_DEVICE_ERROR;
255+
}
256+
225257
return _bd->get_erase_size();
226258
}
227259

228260
bd_size_t BufferedBlockDevice::get_erase_size(bd_addr_t addr) const
229261
{
262+
if (!_is_initialized) {
263+
return BD_ERROR_DEVICE_ERROR;
264+
}
265+
230266
return _bd->get_erase_size(addr);
231267
}
232268

233269
int BufferedBlockDevice::get_erase_value() const
234270
{
271+
if (!_is_initialized) {
272+
return BD_ERROR_DEVICE_ERROR;
273+
}
274+
235275
return _bd->get_erase_value();
236276
}
237277

238278
bd_size_t BufferedBlockDevice::size() const
239279
{
280+
if (!_is_initialized) {
281+
return BD_ERROR_DEVICE_ERROR;
282+
}
283+
240284
return _bd->size();
241285
}

features/filesystem/bd/BufferedBlockDevice.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ class BufferedBlockDevice : public BlockDevice {
154154
bool _flushed;
155155
uint8_t *_cache;
156156
uint32_t _init_ref_count;
157+
bool _is_initialized;
157158

158159
/** Flush data in cache
159160
*

features/filesystem/bd/ChainingBlockDevice.cpp

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
ChainingBlockDevice::ChainingBlockDevice(BlockDevice **bds, size_t bd_count)
2222
: _bds(bds), _bd_count(bd_count)
2323
, _read_size(0), _program_size(0), _erase_size(0), _size(0)
24-
, _erase_value(-1), _init_ref_count(0)
24+
, _erase_value(-1), _init_ref_count(0), _is_initialized(false)
2525
{
2626
}
2727

@@ -32,6 +32,7 @@ static bool is_aligned(uint64_t x, uint64_t alignment)
3232

3333
int ChainingBlockDevice::init()
3434
{
35+
int err;
3536
uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1);
3637

3738
if (val != 1) {
@@ -49,9 +50,9 @@ int ChainingBlockDevice::init()
4950
// the constructor since some block devices may need to be
5051
// initialized before they know their block size/count
5152
for (size_t i = 0; i < _bd_count; i++) {
52-
int err = _bds[i]->init();
53+
err = _bds[i]->init();
5354
if (err) {
54-
return err;
55+
goto fail;
5556
}
5657

5758
bd_size_t read = _bds[i]->get_read_size();
@@ -85,11 +86,21 @@ int ChainingBlockDevice::init()
8586
_size += _bds[i]->size();
8687
}
8788

88-
return 0;
89+
_is_initialized = true;
90+
return BD_ERROR_OK;
91+
92+
fail:
93+
_is_initialized = false;
94+
_init_ref_count = 0;
95+
return err;
8996
}
9097

9198
int ChainingBlockDevice::deinit()
9299
{
100+
if (!_is_initialized) {
101+
return BD_ERROR_OK;
102+
}
103+
93104
uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1);
94105

95106
if (val) {
@@ -103,11 +114,16 @@ int ChainingBlockDevice::deinit()
103114
}
104115
}
105116

106-
return 0;
117+
_is_initialized = false;
118+
return BD_ERROR_OK;
107119
}
108120

109121
int ChainingBlockDevice::sync()
110122
{
123+
if (!_is_initialized) {
124+
return BD_ERROR_DEVICE_ERROR;
125+
}
126+
111127
for (size_t i = 0; i < _bd_count; i++) {
112128
int err = _bds[i]->sync();
113129
if (err) {
@@ -121,6 +137,10 @@ int ChainingBlockDevice::sync()
121137
int ChainingBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size)
122138
{
123139
MBED_ASSERT(is_valid_read(addr, size));
140+
if (!_is_initialized) {
141+
return BD_ERROR_DEVICE_ERROR;
142+
}
143+
124144
uint8_t *buffer = static_cast<uint8_t*>(b);
125145

126146
// Find block devices containing blocks, may span multiple block devices
@@ -152,6 +172,10 @@ int ChainingBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size)
152172
int ChainingBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size)
153173
{
154174
MBED_ASSERT(is_valid_program(addr, size));
175+
if (!_is_initialized) {
176+
return BD_ERROR_DEVICE_ERROR;
177+
}
178+
155179
const uint8_t *buffer = static_cast<const uint8_t*>(b);
156180

157181
// Find block devices containing blocks, may span multiple block devices
@@ -183,6 +207,9 @@ int ChainingBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size)
183207
int ChainingBlockDevice::erase(bd_addr_t addr, bd_size_t size)
184208
{
185209
MBED_ASSERT(is_valid_erase(addr, size));
210+
if (!_is_initialized) {
211+
return BD_ERROR_DEVICE_ERROR;
212+
}
186213

187214
// Find block devices containing blocks, may span multiple block devices
188215
for (size_t i = 0; i < _bd_count && size > 0; i++) {
@@ -226,6 +253,10 @@ bd_size_t ChainingBlockDevice::get_erase_size() const
226253

227254
bd_size_t ChainingBlockDevice::get_erase_size(bd_addr_t addr) const
228255
{
256+
if (!_is_initialized) {
257+
return BD_ERROR_DEVICE_ERROR;
258+
}
259+
229260
bd_addr_t bd_start_addr = 0;
230261
for (size_t i = 0; i < _bd_count; i++) {
231262
bd_size_t bdsize = _bds[i]->size();

features/filesystem/bd/ChainingBlockDevice.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ class ChainingBlockDevice : public BlockDevice
176176
bd_size_t _size;
177177
int _erase_value;
178178
uint32_t _init_ref_count;
179+
bool _is_initialized;
179180
};
180181

181182

0 commit comments

Comments
 (0)