takashi kadono / Mbed OS Nucleo446_SSD1331

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Wed Oct 10 00:33:53 2018 +0000
Revision:
0:8fdf9a60065b
how to make mbed librry

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kadonotakashi 0:8fdf9a60065b 1 /* mbed Microcontroller Library
kadonotakashi 0:8fdf9a60065b 2 * Copyright (c) 2017 ARM Limited
kadonotakashi 0:8fdf9a60065b 3 *
kadonotakashi 0:8fdf9a60065b 4 * Licensed under the Apache License, Version 2.0 (the "License");
kadonotakashi 0:8fdf9a60065b 5 * you may not use this file except in compliance with the License.
kadonotakashi 0:8fdf9a60065b 6 * You may obtain a copy of the License at
kadonotakashi 0:8fdf9a60065b 7 *
kadonotakashi 0:8fdf9a60065b 8 * http://www.apache.org/licenses/LICENSE-2.0
kadonotakashi 0:8fdf9a60065b 9 *
kadonotakashi 0:8fdf9a60065b 10 * Unless required by applicable law or agreed to in writing, software
kadonotakashi 0:8fdf9a60065b 11 * distributed under the License is distributed on an "AS IS" BASIS,
kadonotakashi 0:8fdf9a60065b 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kadonotakashi 0:8fdf9a60065b 13 * See the License for the specific language governing permissions and
kadonotakashi 0:8fdf9a60065b 14 * limitations under the License.
kadonotakashi 0:8fdf9a60065b 15 */
kadonotakashi 0:8fdf9a60065b 16
kadonotakashi 0:8fdf9a60065b 17 #include "MBRBlockDevice.h"
kadonotakashi 0:8fdf9a60065b 18 #include "mbed_critical.h"
kadonotakashi 0:8fdf9a60065b 19 #include <algorithm>
kadonotakashi 0:8fdf9a60065b 20
kadonotakashi 0:8fdf9a60065b 21
kadonotakashi 0:8fdf9a60065b 22 // On disk structures, all entries are little endian
kadonotakashi 0:8fdf9a60065b 23 MBED_PACKED(struct) mbr_entry {
kadonotakashi 0:8fdf9a60065b 24 uint8_t status;
kadonotakashi 0:8fdf9a60065b 25 uint8_t chs_start[3];
kadonotakashi 0:8fdf9a60065b 26 uint8_t type;
kadonotakashi 0:8fdf9a60065b 27 uint8_t chs_stop[3];
kadonotakashi 0:8fdf9a60065b 28 uint32_t lba_offset;
kadonotakashi 0:8fdf9a60065b 29 uint32_t lba_size;
kadonotakashi 0:8fdf9a60065b 30 };
kadonotakashi 0:8fdf9a60065b 31
kadonotakashi 0:8fdf9a60065b 32 MBED_PACKED(struct) mbr_table {
kadonotakashi 0:8fdf9a60065b 33 struct mbr_entry entries[4];
kadonotakashi 0:8fdf9a60065b 34 uint8_t signature[2];
kadonotakashi 0:8fdf9a60065b 35 };
kadonotakashi 0:8fdf9a60065b 36
kadonotakashi 0:8fdf9a60065b 37 // Little-endian conversion, should compile to noop
kadonotakashi 0:8fdf9a60065b 38 // if system is little-endian
kadonotakashi 0:8fdf9a60065b 39 static inline uint32_t tole32(uint32_t a)
kadonotakashi 0:8fdf9a60065b 40 {
kadonotakashi 0:8fdf9a60065b 41 union {
kadonotakashi 0:8fdf9a60065b 42 uint32_t u32;
kadonotakashi 0:8fdf9a60065b 43 uint8_t u8[4];
kadonotakashi 0:8fdf9a60065b 44 } w;
kadonotakashi 0:8fdf9a60065b 45
kadonotakashi 0:8fdf9a60065b 46 w.u8[0] = a >> 0;
kadonotakashi 0:8fdf9a60065b 47 w.u8[1] = a >> 8;
kadonotakashi 0:8fdf9a60065b 48 w.u8[2] = a >> 16;
kadonotakashi 0:8fdf9a60065b 49 w.u8[3] = a >> 24;
kadonotakashi 0:8fdf9a60065b 50
kadonotakashi 0:8fdf9a60065b 51 return w.u32;
kadonotakashi 0:8fdf9a60065b 52 }
kadonotakashi 0:8fdf9a60065b 53
kadonotakashi 0:8fdf9a60065b 54 static inline uint32_t fromle32(uint32_t a)
kadonotakashi 0:8fdf9a60065b 55 {
kadonotakashi 0:8fdf9a60065b 56 return tole32(a);
kadonotakashi 0:8fdf9a60065b 57 }
kadonotakashi 0:8fdf9a60065b 58
kadonotakashi 0:8fdf9a60065b 59 static void tochs(uint32_t lba, uint8_t chs[3])
kadonotakashi 0:8fdf9a60065b 60 {
kadonotakashi 0:8fdf9a60065b 61 uint32_t sector = std::min<uint32_t>(lba, 0xfffffd)+1;
kadonotakashi 0:8fdf9a60065b 62 chs[0] = (sector >> 6) & 0xff;
kadonotakashi 0:8fdf9a60065b 63 chs[1] = ((sector >> 0) & 0x3f) | ((sector >> 16) & 0xc0);
kadonotakashi 0:8fdf9a60065b 64 chs[2] = (sector >> 14) & 0xff;
kadonotakashi 0:8fdf9a60065b 65 }
kadonotakashi 0:8fdf9a60065b 66
kadonotakashi 0:8fdf9a60065b 67
kadonotakashi 0:8fdf9a60065b 68 // Partition after address are turned into absolute
kadonotakashi 0:8fdf9a60065b 69 // addresses, assumes bd is initialized
kadonotakashi 0:8fdf9a60065b 70 static int partition_absolute(
kadonotakashi 0:8fdf9a60065b 71 BlockDevice *bd, int part, uint8_t type,
kadonotakashi 0:8fdf9a60065b 72 bd_size_t offset, bd_size_t size)
kadonotakashi 0:8fdf9a60065b 73 {
kadonotakashi 0:8fdf9a60065b 74 // Allocate smallest buffer necessary to write MBR
kadonotakashi 0:8fdf9a60065b 75 uint32_t buffer_size = std::max<uint32_t>(bd->get_program_size(), sizeof(struct mbr_table));
kadonotakashi 0:8fdf9a60065b 76
kadonotakashi 0:8fdf9a60065b 77 // Prevent alignment issues
kadonotakashi 0:8fdf9a60065b 78 if(buffer_size % bd->get_program_size() != 0) {
kadonotakashi 0:8fdf9a60065b 79 buffer_size += bd->get_program_size() - (buffer_size % bd->get_program_size());
kadonotakashi 0:8fdf9a60065b 80 }
kadonotakashi 0:8fdf9a60065b 81
kadonotakashi 0:8fdf9a60065b 82 uint8_t *buffer = new uint8_t[buffer_size];
kadonotakashi 0:8fdf9a60065b 83
kadonotakashi 0:8fdf9a60065b 84 // Check for existing MBR
kadonotakashi 0:8fdf9a60065b 85 int err = bd->read(buffer, 512-buffer_size, buffer_size);
kadonotakashi 0:8fdf9a60065b 86 if (err) {
kadonotakashi 0:8fdf9a60065b 87 delete[] buffer;
kadonotakashi 0:8fdf9a60065b 88 return err;
kadonotakashi 0:8fdf9a60065b 89 }
kadonotakashi 0:8fdf9a60065b 90
kadonotakashi 0:8fdf9a60065b 91 struct mbr_table *table = reinterpret_cast<struct mbr_table*>(
kadonotakashi 0:8fdf9a60065b 92 &buffer[buffer_size - sizeof(struct mbr_table)]);
kadonotakashi 0:8fdf9a60065b 93 if (table->signature[0] != 0x55 || table->signature[1] != 0xaa) {
kadonotakashi 0:8fdf9a60065b 94 // Setup default values for MBR
kadonotakashi 0:8fdf9a60065b 95 table->signature[0] = 0x55;
kadonotakashi 0:8fdf9a60065b 96 table->signature[1] = 0xaa;
kadonotakashi 0:8fdf9a60065b 97 memset(table->entries, 0, sizeof(table->entries));
kadonotakashi 0:8fdf9a60065b 98 }
kadonotakashi 0:8fdf9a60065b 99
kadonotakashi 0:8fdf9a60065b 100 // Setup new partition
kadonotakashi 0:8fdf9a60065b 101 MBED_ASSERT(part >= 1 && part <= 4);
kadonotakashi 0:8fdf9a60065b 102 table->entries[part-1].status = 0x00; // inactive (not bootable)
kadonotakashi 0:8fdf9a60065b 103 table->entries[part-1].type = type;
kadonotakashi 0:8fdf9a60065b 104
kadonotakashi 0:8fdf9a60065b 105 // lba dimensions
kadonotakashi 0:8fdf9a60065b 106 MBED_ASSERT(bd->is_valid_erase(offset, size));
kadonotakashi 0:8fdf9a60065b 107 uint32_t sector = std::max<uint32_t>(bd->get_erase_size(), 512);
kadonotakashi 0:8fdf9a60065b 108 uint32_t lba_offset = offset / sector;
kadonotakashi 0:8fdf9a60065b 109 uint32_t lba_size = size / sector;
kadonotakashi 0:8fdf9a60065b 110 table->entries[part-1].lba_offset = tole32(lba_offset);
kadonotakashi 0:8fdf9a60065b 111 table->entries[part-1].lba_size = tole32(lba_size);
kadonotakashi 0:8fdf9a60065b 112
kadonotakashi 0:8fdf9a60065b 113 // chs dimensions
kadonotakashi 0:8fdf9a60065b 114 tochs(lba_offset, table->entries[part-1].chs_start);
kadonotakashi 0:8fdf9a60065b 115 tochs(lba_offset+lba_size-1, table->entries[part-1].chs_stop);
kadonotakashi 0:8fdf9a60065b 116
kadonotakashi 0:8fdf9a60065b 117 // Check that we don't overlap other entries
kadonotakashi 0:8fdf9a60065b 118 for (int i = 1; i <= 4; i++) {
kadonotakashi 0:8fdf9a60065b 119 if (i != part && table->entries[i-1].type != 0x00) {
kadonotakashi 0:8fdf9a60065b 120 uint32_t neighbor_lba_offset = fromle32(table->entries[i-1].lba_offset);
kadonotakashi 0:8fdf9a60065b 121 uint32_t neighbor_lba_size = fromle32(table->entries[i-1].lba_size);
kadonotakashi 0:8fdf9a60065b 122 MBED_ASSERT(
kadonotakashi 0:8fdf9a60065b 123 (lba_offset >= neighbor_lba_offset + neighbor_lba_size) ||
kadonotakashi 0:8fdf9a60065b 124 (lba_offset + lba_size <= neighbor_lba_offset));
kadonotakashi 0:8fdf9a60065b 125 (void)neighbor_lba_offset;
kadonotakashi 0:8fdf9a60065b 126 (void)neighbor_lba_size;
kadonotakashi 0:8fdf9a60065b 127 }
kadonotakashi 0:8fdf9a60065b 128 }
kadonotakashi 0:8fdf9a60065b 129
kadonotakashi 0:8fdf9a60065b 130 // Write out MBR
kadonotakashi 0:8fdf9a60065b 131 err = bd->erase(0, bd->get_erase_size());
kadonotakashi 0:8fdf9a60065b 132 if (err) {
kadonotakashi 0:8fdf9a60065b 133 delete[] buffer;
kadonotakashi 0:8fdf9a60065b 134 return err;
kadonotakashi 0:8fdf9a60065b 135 }
kadonotakashi 0:8fdf9a60065b 136
kadonotakashi 0:8fdf9a60065b 137 err = bd->program(buffer, 512-buffer_size, buffer_size);
kadonotakashi 0:8fdf9a60065b 138 delete[] buffer;
kadonotakashi 0:8fdf9a60065b 139 return err;
kadonotakashi 0:8fdf9a60065b 140 }
kadonotakashi 0:8fdf9a60065b 141
kadonotakashi 0:8fdf9a60065b 142 int MBRBlockDevice::partition(BlockDevice *bd, int part, uint8_t type, bd_addr_t start)
kadonotakashi 0:8fdf9a60065b 143 {
kadonotakashi 0:8fdf9a60065b 144 int err = bd->init();
kadonotakashi 0:8fdf9a60065b 145 if (err) {
kadonotakashi 0:8fdf9a60065b 146 return err;
kadonotakashi 0:8fdf9a60065b 147 }
kadonotakashi 0:8fdf9a60065b 148
kadonotakashi 0:8fdf9a60065b 149 // Calculate dimensions
kadonotakashi 0:8fdf9a60065b 150 bd_size_t offset = ((int64_t)start < 0) ? -start : start;
kadonotakashi 0:8fdf9a60065b 151 bd_size_t size = bd->size();
kadonotakashi 0:8fdf9a60065b 152
kadonotakashi 0:8fdf9a60065b 153 if (offset < 512) {
kadonotakashi 0:8fdf9a60065b 154 offset += std::max<uint32_t>(bd->get_erase_size(), 512);
kadonotakashi 0:8fdf9a60065b 155 }
kadonotakashi 0:8fdf9a60065b 156
kadonotakashi 0:8fdf9a60065b 157 size -= offset;
kadonotakashi 0:8fdf9a60065b 158
kadonotakashi 0:8fdf9a60065b 159 err = partition_absolute(bd, part, type, offset, size);
kadonotakashi 0:8fdf9a60065b 160 if (err) {
kadonotakashi 0:8fdf9a60065b 161 return err;
kadonotakashi 0:8fdf9a60065b 162 }
kadonotakashi 0:8fdf9a60065b 163
kadonotakashi 0:8fdf9a60065b 164 err = bd->deinit();
kadonotakashi 0:8fdf9a60065b 165 if (err) {
kadonotakashi 0:8fdf9a60065b 166 return err;
kadonotakashi 0:8fdf9a60065b 167 }
kadonotakashi 0:8fdf9a60065b 168
kadonotakashi 0:8fdf9a60065b 169 return 0;
kadonotakashi 0:8fdf9a60065b 170 }
kadonotakashi 0:8fdf9a60065b 171
kadonotakashi 0:8fdf9a60065b 172 int MBRBlockDevice::partition(BlockDevice *bd, int part, uint8_t type,
kadonotakashi 0:8fdf9a60065b 173 bd_addr_t start, bd_addr_t stop)
kadonotakashi 0:8fdf9a60065b 174 {
kadonotakashi 0:8fdf9a60065b 175 int err = bd->init();
kadonotakashi 0:8fdf9a60065b 176 if (err) {
kadonotakashi 0:8fdf9a60065b 177 return err;
kadonotakashi 0:8fdf9a60065b 178 }
kadonotakashi 0:8fdf9a60065b 179
kadonotakashi 0:8fdf9a60065b 180 // Calculate dimensions
kadonotakashi 0:8fdf9a60065b 181 bd_size_t offset = ((int64_t)start < 0) ? -start : start;
kadonotakashi 0:8fdf9a60065b 182 bd_size_t size = ((int64_t)stop < 0) ? -stop : stop;
kadonotakashi 0:8fdf9a60065b 183
kadonotakashi 0:8fdf9a60065b 184 if (offset < 512) {
kadonotakashi 0:8fdf9a60065b 185 offset += std::max<uint32_t>(bd->get_erase_size(), 512);
kadonotakashi 0:8fdf9a60065b 186 }
kadonotakashi 0:8fdf9a60065b 187
kadonotakashi 0:8fdf9a60065b 188 size -= offset;
kadonotakashi 0:8fdf9a60065b 189
kadonotakashi 0:8fdf9a60065b 190 err = partition_absolute(bd, part, type, offset, size);
kadonotakashi 0:8fdf9a60065b 191 if (err) {
kadonotakashi 0:8fdf9a60065b 192 return err;
kadonotakashi 0:8fdf9a60065b 193 }
kadonotakashi 0:8fdf9a60065b 194
kadonotakashi 0:8fdf9a60065b 195 err = bd->deinit();
kadonotakashi 0:8fdf9a60065b 196 if (err) {
kadonotakashi 0:8fdf9a60065b 197 return err;
kadonotakashi 0:8fdf9a60065b 198 }
kadonotakashi 0:8fdf9a60065b 199
kadonotakashi 0:8fdf9a60065b 200 return 0;
kadonotakashi 0:8fdf9a60065b 201 }
kadonotakashi 0:8fdf9a60065b 202
kadonotakashi 0:8fdf9a60065b 203 MBRBlockDevice::MBRBlockDevice(BlockDevice *bd, int part)
kadonotakashi 0:8fdf9a60065b 204 : _bd(bd), _offset(0), _size(0), _type(0), _part(part), _init_ref_count(0), _is_initialized(false)
kadonotakashi 0:8fdf9a60065b 205 {
kadonotakashi 0:8fdf9a60065b 206 MBED_ASSERT(_part >= 1 && _part <= 4);
kadonotakashi 0:8fdf9a60065b 207 }
kadonotakashi 0:8fdf9a60065b 208
kadonotakashi 0:8fdf9a60065b 209 int MBRBlockDevice::init()
kadonotakashi 0:8fdf9a60065b 210 {
kadonotakashi 0:8fdf9a60065b 211 uint32_t buffer_size;
kadonotakashi 0:8fdf9a60065b 212 uint8_t *buffer = 0;
kadonotakashi 0:8fdf9a60065b 213 struct mbr_table *table;
kadonotakashi 0:8fdf9a60065b 214 bd_size_t sector;
kadonotakashi 0:8fdf9a60065b 215 int err;
kadonotakashi 0:8fdf9a60065b 216
kadonotakashi 0:8fdf9a60065b 217 uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1);
kadonotakashi 0:8fdf9a60065b 218
kadonotakashi 0:8fdf9a60065b 219 if (val != 1) {
kadonotakashi 0:8fdf9a60065b 220 return BD_ERROR_OK;
kadonotakashi 0:8fdf9a60065b 221 }
kadonotakashi 0:8fdf9a60065b 222
kadonotakashi 0:8fdf9a60065b 223 err = _bd->init();
kadonotakashi 0:8fdf9a60065b 224 if (err) {
kadonotakashi 0:8fdf9a60065b 225 goto fail;
kadonotakashi 0:8fdf9a60065b 226 }
kadonotakashi 0:8fdf9a60065b 227
kadonotakashi 0:8fdf9a60065b 228 // Allocate smallest buffer necessary to write MBR
kadonotakashi 0:8fdf9a60065b 229 buffer_size = std::max<uint32_t>(_bd->get_read_size(), sizeof(struct mbr_table));
kadonotakashi 0:8fdf9a60065b 230 buffer = new uint8_t[buffer_size];
kadonotakashi 0:8fdf9a60065b 231
kadonotakashi 0:8fdf9a60065b 232 err = _bd->read(buffer, 512-buffer_size, buffer_size);
kadonotakashi 0:8fdf9a60065b 233 if (err) {
kadonotakashi 0:8fdf9a60065b 234 goto fail;
kadonotakashi 0:8fdf9a60065b 235 }
kadonotakashi 0:8fdf9a60065b 236
kadonotakashi 0:8fdf9a60065b 237 // Check for valid table
kadonotakashi 0:8fdf9a60065b 238 table = reinterpret_cast<struct mbr_table*>(&buffer[buffer_size - sizeof(struct mbr_table)]);
kadonotakashi 0:8fdf9a60065b 239 if (table->signature[0] != 0x55 || table->signature[1] != 0xaa) {
kadonotakashi 0:8fdf9a60065b 240 err = BD_ERROR_INVALID_MBR;
kadonotakashi 0:8fdf9a60065b 241 goto fail;
kadonotakashi 0:8fdf9a60065b 242 }
kadonotakashi 0:8fdf9a60065b 243
kadonotakashi 0:8fdf9a60065b 244 // Check for valid entry
kadonotakashi 0:8fdf9a60065b 245 // 0x00 = no entry
kadonotakashi 0:8fdf9a60065b 246 // 0x05, 0x0f = extended partitions, currently not supported
kadonotakashi 0:8fdf9a60065b 247 if ((table->entries[_part-1].type == 0x00 ||
kadonotakashi 0:8fdf9a60065b 248 table->entries[_part-1].type == 0x05 ||
kadonotakashi 0:8fdf9a60065b 249 table->entries[_part-1].type == 0x0f)) {
kadonotakashi 0:8fdf9a60065b 250 err = BD_ERROR_INVALID_PARTITION;
kadonotakashi 0:8fdf9a60065b 251 goto fail;
kadonotakashi 0:8fdf9a60065b 252 }
kadonotakashi 0:8fdf9a60065b 253
kadonotakashi 0:8fdf9a60065b 254 // Get partition attributes
kadonotakashi 0:8fdf9a60065b 255 sector = std::max<uint32_t>(_bd->get_erase_size(), 512);
kadonotakashi 0:8fdf9a60065b 256 _type = table->entries[_part-1].type;
kadonotakashi 0:8fdf9a60065b 257 _offset = fromle32(table->entries[_part-1].lba_offset) * sector;
kadonotakashi 0:8fdf9a60065b 258 _size = fromle32(table->entries[_part-1].lba_size) * sector;
kadonotakashi 0:8fdf9a60065b 259
kadonotakashi 0:8fdf9a60065b 260 // Check that block addresses are valid
kadonotakashi 0:8fdf9a60065b 261 if (!_bd->is_valid_erase(_offset, _size)) {
kadonotakashi 0:8fdf9a60065b 262 err = BD_ERROR_INVALID_PARTITION;
kadonotakashi 0:8fdf9a60065b 263 goto fail;
kadonotakashi 0:8fdf9a60065b 264 }
kadonotakashi 0:8fdf9a60065b 265
kadonotakashi 0:8fdf9a60065b 266 _is_initialized = true;
kadonotakashi 0:8fdf9a60065b 267 delete[] buffer;
kadonotakashi 0:8fdf9a60065b 268 return BD_ERROR_OK;
kadonotakashi 0:8fdf9a60065b 269
kadonotakashi 0:8fdf9a60065b 270 fail:
kadonotakashi 0:8fdf9a60065b 271 delete[] buffer;
kadonotakashi 0:8fdf9a60065b 272 _is_initialized = false;
kadonotakashi 0:8fdf9a60065b 273 _init_ref_count = 0;
kadonotakashi 0:8fdf9a60065b 274 return err;
kadonotakashi 0:8fdf9a60065b 275 }
kadonotakashi 0:8fdf9a60065b 276
kadonotakashi 0:8fdf9a60065b 277 int MBRBlockDevice::deinit()
kadonotakashi 0:8fdf9a60065b 278 {
kadonotakashi 0:8fdf9a60065b 279 if (!_is_initialized) {
kadonotakashi 0:8fdf9a60065b 280 return BD_ERROR_OK;
kadonotakashi 0:8fdf9a60065b 281 }
kadonotakashi 0:8fdf9a60065b 282
kadonotakashi 0:8fdf9a60065b 283 uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1);
kadonotakashi 0:8fdf9a60065b 284
kadonotakashi 0:8fdf9a60065b 285 if (val) {
kadonotakashi 0:8fdf9a60065b 286 return BD_ERROR_OK;
kadonotakashi 0:8fdf9a60065b 287 }
kadonotakashi 0:8fdf9a60065b 288
kadonotakashi 0:8fdf9a60065b 289 _is_initialized = false;
kadonotakashi 0:8fdf9a60065b 290 return _bd->deinit();
kadonotakashi 0:8fdf9a60065b 291 }
kadonotakashi 0:8fdf9a60065b 292
kadonotakashi 0:8fdf9a60065b 293 int MBRBlockDevice::sync()
kadonotakashi 0:8fdf9a60065b 294 {
kadonotakashi 0:8fdf9a60065b 295 if (!_is_initialized) {
kadonotakashi 0:8fdf9a60065b 296 return BD_ERROR_DEVICE_ERROR;
kadonotakashi 0:8fdf9a60065b 297 }
kadonotakashi 0:8fdf9a60065b 298
kadonotakashi 0:8fdf9a60065b 299 return _bd->sync();
kadonotakashi 0:8fdf9a60065b 300 }
kadonotakashi 0:8fdf9a60065b 301
kadonotakashi 0:8fdf9a60065b 302 int MBRBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size)
kadonotakashi 0:8fdf9a60065b 303 {
kadonotakashi 0:8fdf9a60065b 304 MBED_ASSERT(is_valid_read(addr, size));
kadonotakashi 0:8fdf9a60065b 305 if (!_is_initialized) {
kadonotakashi 0:8fdf9a60065b 306 return BD_ERROR_DEVICE_ERROR;
kadonotakashi 0:8fdf9a60065b 307 }
kadonotakashi 0:8fdf9a60065b 308
kadonotakashi 0:8fdf9a60065b 309 return _bd->read(b, addr + _offset, size);
kadonotakashi 0:8fdf9a60065b 310 }
kadonotakashi 0:8fdf9a60065b 311
kadonotakashi 0:8fdf9a60065b 312 int MBRBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size)
kadonotakashi 0:8fdf9a60065b 313 {
kadonotakashi 0:8fdf9a60065b 314 MBED_ASSERT(is_valid_program(addr, size));
kadonotakashi 0:8fdf9a60065b 315 if (!_is_initialized) {
kadonotakashi 0:8fdf9a60065b 316 return BD_ERROR_DEVICE_ERROR;
kadonotakashi 0:8fdf9a60065b 317 }
kadonotakashi 0:8fdf9a60065b 318
kadonotakashi 0:8fdf9a60065b 319 return _bd->program(b, addr + _offset, size);
kadonotakashi 0:8fdf9a60065b 320 }
kadonotakashi 0:8fdf9a60065b 321
kadonotakashi 0:8fdf9a60065b 322 int MBRBlockDevice::erase(bd_addr_t addr, bd_size_t size)
kadonotakashi 0:8fdf9a60065b 323 {
kadonotakashi 0:8fdf9a60065b 324 MBED_ASSERT(is_valid_erase(addr, size));
kadonotakashi 0:8fdf9a60065b 325 if (!_is_initialized) {
kadonotakashi 0:8fdf9a60065b 326 return BD_ERROR_DEVICE_ERROR;
kadonotakashi 0:8fdf9a60065b 327 }
kadonotakashi 0:8fdf9a60065b 328
kadonotakashi 0:8fdf9a60065b 329 return _bd->erase(addr + _offset, size);
kadonotakashi 0:8fdf9a60065b 330 }
kadonotakashi 0:8fdf9a60065b 331
kadonotakashi 0:8fdf9a60065b 332 bd_size_t MBRBlockDevice::get_read_size() const
kadonotakashi 0:8fdf9a60065b 333 {
kadonotakashi 0:8fdf9a60065b 334 if (!_is_initialized) {
kadonotakashi 0:8fdf9a60065b 335 return 0;
kadonotakashi 0:8fdf9a60065b 336 }
kadonotakashi 0:8fdf9a60065b 337
kadonotakashi 0:8fdf9a60065b 338 return _bd->get_read_size();
kadonotakashi 0:8fdf9a60065b 339 }
kadonotakashi 0:8fdf9a60065b 340
kadonotakashi 0:8fdf9a60065b 341 bd_size_t MBRBlockDevice::get_program_size() const
kadonotakashi 0:8fdf9a60065b 342 {
kadonotakashi 0:8fdf9a60065b 343 if (!_is_initialized) {
kadonotakashi 0:8fdf9a60065b 344 return 0;
kadonotakashi 0:8fdf9a60065b 345 }
kadonotakashi 0:8fdf9a60065b 346
kadonotakashi 0:8fdf9a60065b 347 return _bd->get_program_size();
kadonotakashi 0:8fdf9a60065b 348 }
kadonotakashi 0:8fdf9a60065b 349
kadonotakashi 0:8fdf9a60065b 350 bd_size_t MBRBlockDevice::get_erase_size() const
kadonotakashi 0:8fdf9a60065b 351 {
kadonotakashi 0:8fdf9a60065b 352 if (!_is_initialized) {
kadonotakashi 0:8fdf9a60065b 353 return 0;
kadonotakashi 0:8fdf9a60065b 354 }
kadonotakashi 0:8fdf9a60065b 355
kadonotakashi 0:8fdf9a60065b 356 return _bd->get_erase_size();
kadonotakashi 0:8fdf9a60065b 357 }
kadonotakashi 0:8fdf9a60065b 358
kadonotakashi 0:8fdf9a60065b 359 bd_size_t MBRBlockDevice::get_erase_size(bd_addr_t addr) const
kadonotakashi 0:8fdf9a60065b 360 {
kadonotakashi 0:8fdf9a60065b 361 if (!_is_initialized) {
kadonotakashi 0:8fdf9a60065b 362 return 0;
kadonotakashi 0:8fdf9a60065b 363 }
kadonotakashi 0:8fdf9a60065b 364
kadonotakashi 0:8fdf9a60065b 365 return _bd->get_erase_size(_offset + addr);
kadonotakashi 0:8fdf9a60065b 366 }
kadonotakashi 0:8fdf9a60065b 367
kadonotakashi 0:8fdf9a60065b 368 int MBRBlockDevice::get_erase_value() const
kadonotakashi 0:8fdf9a60065b 369 {
kadonotakashi 0:8fdf9a60065b 370 if (!_is_initialized) {
kadonotakashi 0:8fdf9a60065b 371 return 0;
kadonotakashi 0:8fdf9a60065b 372 }
kadonotakashi 0:8fdf9a60065b 373
kadonotakashi 0:8fdf9a60065b 374 return _bd->get_erase_value();
kadonotakashi 0:8fdf9a60065b 375 }
kadonotakashi 0:8fdf9a60065b 376
kadonotakashi 0:8fdf9a60065b 377 bd_size_t MBRBlockDevice::size() const
kadonotakashi 0:8fdf9a60065b 378 {
kadonotakashi 0:8fdf9a60065b 379 return _size;
kadonotakashi 0:8fdf9a60065b 380 }
kadonotakashi 0:8fdf9a60065b 381
kadonotakashi 0:8fdf9a60065b 382 bd_size_t MBRBlockDevice::get_partition_start() const
kadonotakashi 0:8fdf9a60065b 383 {
kadonotakashi 0:8fdf9a60065b 384 return _offset;
kadonotakashi 0:8fdf9a60065b 385 }
kadonotakashi 0:8fdf9a60065b 386
kadonotakashi 0:8fdf9a60065b 387 bd_size_t MBRBlockDevice::get_partition_stop() const
kadonotakashi 0:8fdf9a60065b 388 {
kadonotakashi 0:8fdf9a60065b 389 return _offset+_size;
kadonotakashi 0:8fdf9a60065b 390 }
kadonotakashi 0:8fdf9a60065b 391
kadonotakashi 0:8fdf9a60065b 392 uint8_t MBRBlockDevice::get_partition_type() const
kadonotakashi 0:8fdf9a60065b 393 {
kadonotakashi 0:8fdf9a60065b 394 return _type;
kadonotakashi 0:8fdf9a60065b 395 }
kadonotakashi 0:8fdf9a60065b 396
kadonotakashi 0:8fdf9a60065b 397 int MBRBlockDevice::get_partition_number() const
kadonotakashi 0:8fdf9a60065b 398 {
kadonotakashi 0:8fdf9a60065b 399 return _part;
kadonotakashi 0:8fdf9a60065b 400 }