1 /* $NetBSD: ebh.c,v 1.11 2025/01/08 11:39:50 andvar Exp $ */ 2 3 /*- 4 * Copyright (c) 2010 Department of Software Engineering, 5 * University of Szeged, Hungary 6 * Copyright (C) 2009 Ferenc Havasi <havasi@inf.u-szeged.hu> 7 * Copyright (C) 2009 Zoltan Sogor <weth@inf.u-szeged.hu> 8 * Copyright (C) 2009 David Tengeri <dtengeri@inf.u-szeged.hu> 9 * Copyright (C) 2009 Tamas Toth <ttoth@inf.u-szeged.hu> 10 * Copyright (C) 2010 Adam Hoka <ahoka@NetBSD.org> 11 * All rights reserved. 12 * 13 * This code is derived from software contributed to The NetBSD Foundation 14 * by the Department of Software Engineering, University of Szeged, Hungary 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions 18 * are met: 19 * 1. Redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer. 21 * 2. Redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 26 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 28 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 32 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 33 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 */ 37 38 #include "ebh.h" 39 40 /*****************************************************************************/ 41 /* Flash specific operations */ 42 /*****************************************************************************/ 43 int nor_create_eb_hdr(struct chfs_eb_hdr *ebhdr, int lnr); 44 int nand_create_eb_hdr(struct chfs_eb_hdr *ebhdr, int lnr); 45 int nor_calc_data_offs(struct chfs_ebh *ebh, int pebnr, int offset); 46 int nand_calc_data_offs(struct chfs_ebh *ebh, int pebnr, int offset); 47 int nor_read_eb_hdr(struct chfs_ebh *ebh, int pebnr, struct chfs_eb_hdr *ebhdr); 48 int nand_read_eb_hdr(struct chfs_ebh *ebh, int pebnr, struct chfs_eb_hdr *ebhdr); 49 int nor_write_eb_hdr(struct chfs_ebh *ebh, int pebnr, struct chfs_eb_hdr *ebhdr); 50 int nand_write_eb_hdr(struct chfs_ebh *ebh, int pebnr,struct chfs_eb_hdr *ebhdr); 51 int nor_check_eb_hdr(struct chfs_ebh *ebh, void *buf); 52 int nand_check_eb_hdr(struct chfs_ebh *ebh, void *buf); 53 int nor_mark_eb_hdr_dirty_flash(struct chfs_ebh *ebh, int pebnr, int lid); 54 int nor_invalidate_eb_hdr(struct chfs_ebh *ebh, int pebnr); 55 int mark_eb_hdr_free(struct chfs_ebh *ebh, int pebnr, int ec); 56 57 int ltree_entry_cmp(struct chfs_ltree_entry *le1, struct chfs_ltree_entry *le2); 58 int peb_in_use_cmp(struct chfs_peb *peb1, struct chfs_peb *peb2); 59 int peb_free_cmp(struct chfs_peb *peb1, struct chfs_peb *peb2); 60 int add_peb_to_erase_queue(struct chfs_ebh *ebh, int pebnr, int ec,struct peb_queue *queue); 61 struct chfs_peb * find_peb_in_use(struct chfs_ebh *ebh, int pebnr); 62 int add_peb_to_free(struct chfs_ebh *ebh, int pebnr, int ec); 63 int add_peb_to_in_use(struct chfs_ebh *ebh, int pebnr, int ec); 64 void erase_callback(struct flash_erase_instruction *ei); 65 int free_peb(struct chfs_ebh *ebh); 66 int release_peb(struct chfs_ebh *ebh, int pebnr); 67 void erase_thread(void *data); 68 static void erase_thread_start(struct chfs_ebh *ebh); 69 static void erase_thread_stop(struct chfs_ebh *ebh); 70 int scan_leb_used_cmp(struct chfs_scan_leb *sleb1, struct chfs_scan_leb *sleb2); 71 int nor_scan_add_to_used(struct chfs_ebh *ebh, struct chfs_scan_info *si,struct chfs_eb_hdr *ebhdr, int pebnr, int leb_status); 72 int nor_process_eb(struct chfs_ebh *ebh, struct chfs_scan_info *si, 73 int pebnr, struct chfs_eb_hdr *ebhdr); 74 int nand_scan_add_to_used(struct chfs_ebh *ebh, struct chfs_scan_info *si,struct chfs_eb_hdr *ebhdr, int pebnr); 75 int nand_process_eb(struct chfs_ebh *ebh, struct chfs_scan_info *si, 76 int pebnr, struct chfs_eb_hdr *ebhdr); 77 struct chfs_scan_info *chfs_scan(struct chfs_ebh *ebh); 78 void scan_info_destroy(struct chfs_scan_info *si); 79 int scan_media(struct chfs_ebh *ebh); 80 int get_peb(struct chfs_ebh *ebh); 81 /** 82 * nor_create_eb_hdr - creates an eraseblock header for NOR flash 83 * @ebhdr: ebhdr to set 84 * @lnr: LEB number 85 */ 86 int 87 nor_create_eb_hdr(struct chfs_eb_hdr *ebhdr, int lnr) 88 { 89 ebhdr->u.nor_hdr.lid = htole32(lnr); 90 return 0; 91 } 92 93 /** 94 * nand_create_eb_hdr - creates an eraseblock header for NAND flash 95 * @ebhdr: ebhdr to set 96 * @lnr: LEB number 97 */ 98 int 99 nand_create_eb_hdr(struct chfs_eb_hdr *ebhdr, int lnr) 100 { 101 ebhdr->u.nand_hdr.lid = htole32(lnr); 102 return 0; 103 } 104 105 /** 106 * nor_calc_data_offs - calculates data offset on NOR flash 107 * @ebh: chfs eraseblock handler 108 * @pebnr: eraseblock number 109 * @offset: offset within the eraseblock 110 */ 111 int 112 nor_calc_data_offs(struct chfs_ebh *ebh, int pebnr, int offset) 113 { 114 return pebnr * ebh->flash_if->erasesize + offset + 115 CHFS_EB_EC_HDR_SIZE + CHFS_EB_HDR_NOR_SIZE; 116 } 117 118 /** 119 * nand_calc_data_offs - calculates data offset on NAND flash 120 * @ebh: chfs eraseblock handler 121 * @pebnr: eraseblock number 122 * @offset: offset within the eraseblock 123 */ 124 int 125 nand_calc_data_offs(struct chfs_ebh *ebh, int pebnr, int offset) 126 { 127 return pebnr * ebh->flash_if->erasesize + offset + 128 2 * ebh->flash_if->page_size; 129 } 130 131 /** 132 * nor_read_eb_hdr - read eraseblock header from NOR flash 133 * 134 * @ebh: chfs eraseblock handler 135 * @pebnr: eraseblock number 136 * @ebhdr: whereto store the data 137 * 138 * Reads the eraseblock header from media. 139 * Returns zero in case of success, error code in case of fail. 140 */ 141 int 142 nor_read_eb_hdr(struct chfs_ebh *ebh, 143 int pebnr, struct chfs_eb_hdr *ebhdr) 144 { 145 int ret; 146 size_t retlen; 147 off_t ofs = pebnr * ebh->flash_if->erasesize; 148 149 KASSERT(pebnr >= 0 && pebnr < ebh->peb_nr); 150 151 ret = flash_read(ebh->flash_dev, 152 ofs, CHFS_EB_EC_HDR_SIZE, 153 &retlen, (unsigned char *) &ebhdr->ec_hdr); 154 155 if (ret || retlen != CHFS_EB_EC_HDR_SIZE) 156 return ret; 157 158 ofs += CHFS_EB_EC_HDR_SIZE; 159 ret = flash_read(ebh->flash_dev, 160 ofs, CHFS_EB_HDR_NOR_SIZE, 161 &retlen, (unsigned char *) &ebhdr->u.nor_hdr); 162 163 if (ret || retlen != CHFS_EB_HDR_NOR_SIZE) 164 return ret; 165 166 return 0; 167 } 168 169 /** 170 * nand_read_eb_hdr - read eraseblock header from NAND flash 171 * 172 * @ebh: chfs eraseblock handler 173 * @pebnr: eraseblock number 174 * @ebhdr: whereto store the data 175 * 176 * Reads the eraseblock header from media. It is on the first two page. 177 * Returns zero in case of success, error code in case of fail. 178 */ 179 int 180 nand_read_eb_hdr(struct chfs_ebh *ebh, int pebnr, 181 struct chfs_eb_hdr *ebhdr) 182 { 183 int ret; 184 size_t retlen; 185 off_t ofs; 186 187 KASSERT(pebnr >= 0 && pebnr < ebh->peb_nr); 188 189 /* Read erase counter header from the first page. */ 190 ofs = pebnr * ebh->flash_if->erasesize; 191 ret = flash_read(ebh->flash_dev, 192 ofs, CHFS_EB_EC_HDR_SIZE, &retlen, 193 (unsigned char *) &ebhdr->ec_hdr); 194 if (ret || retlen != CHFS_EB_EC_HDR_SIZE) 195 return ret; 196 197 /* Read NAND eraseblock header from the second page */ 198 ofs += ebh->flash_if->page_size; 199 ret = flash_read(ebh->flash_dev, 200 ofs, CHFS_EB_HDR_NAND_SIZE, &retlen, 201 (unsigned char *) &ebhdr->u.nand_hdr); 202 if (ret || retlen != CHFS_EB_HDR_NAND_SIZE) 203 return ret; 204 205 return 0; 206 } 207 208 /** 209 * nor_write_eb_hdr - write eraseblock header to NOR flash 210 * 211 * @ebh: chfs eraseblock handler 212 * @pebnr: eraseblock number whereto write 213 * @ebh: ebh to write 214 * 215 * Writes the eraseblock header to media. 216 * Returns zero in case of success, error code in case of fail. 217 */ 218 int 219 nor_write_eb_hdr(struct chfs_ebh *ebh, int pebnr, struct chfs_eb_hdr *ebhdr) 220 { 221 int ret, crc; 222 size_t retlen; 223 224 off_t ofs = pebnr * ebh->flash_if->erasesize + CHFS_EB_EC_HDR_SIZE; 225 226 ebhdr->u.nor_hdr.lid = ebhdr->u.nor_hdr.lid 227 | htole32(CHFS_LID_NOT_DIRTY_BIT); 228 229 crc = crc32(0, (uint8_t *)&ebhdr->u.nor_hdr + 4, 230 CHFS_EB_HDR_NOR_SIZE - 4); 231 ebhdr->u.nand_hdr.crc = htole32(crc); 232 233 KASSERT(pebnr >= 0 && pebnr < ebh->peb_nr); 234 235 ret = flash_write(ebh->flash_dev, 236 ofs, CHFS_EB_HDR_NOR_SIZE, &retlen, 237 (unsigned char *) &ebhdr->u.nor_hdr); 238 239 if (ret || retlen != CHFS_EB_HDR_NOR_SIZE) 240 return ret; 241 242 return 0; 243 } 244 245 /** 246 * nand_write_eb_hdr - write eraseblock header to NAND flash 247 * 248 * @ebh: chfs eraseblock handler 249 * @pebnr: eraseblock number whereto write 250 * @ebh: ebh to write 251 * 252 * Writes the eraseblock header to media. 253 * Returns zero in case of success, error code in case of fail. 254 */ 255 int 256 nand_write_eb_hdr(struct chfs_ebh *ebh, int pebnr, 257 struct chfs_eb_hdr *ebhdr) 258 { 259 int ret, crc; 260 size_t retlen; 261 flash_off_t ofs; 262 263 KASSERT(pebnr >= 0 && pebnr < ebh->peb_nr); 264 265 ofs = pebnr * ebh->flash_if->erasesize + 266 ebh->flash_if->page_size; 267 268 ebhdr->u.nand_hdr.serial = htole64(++(*ebh->max_serial)); 269 270 crc = crc32(0, (uint8_t *)&ebhdr->u.nand_hdr + 4, 271 CHFS_EB_HDR_NAND_SIZE - 4); 272 ebhdr->u.nand_hdr.crc = htole32(crc); 273 274 ret = flash_write(ebh->flash_dev, ofs, 275 CHFS_EB_HDR_NAND_SIZE, &retlen, 276 (unsigned char *) &ebhdr->u.nand_hdr); 277 278 if (ret || retlen != CHFS_EB_HDR_NAND_SIZE) 279 return ret; 280 281 return 0; 282 } 283 284 /** 285 * nor_check_eb_hdr - check eraseblock header read from NOR flash 286 * 287 * @ebh: chfs eraseblock handler 288 * @buf: eraseblock header to check 289 * 290 * Returns eraseblock header status. 291 */ 292 int 293 nor_check_eb_hdr(struct chfs_ebh *ebh, void *buf) 294 { 295 uint32_t magic, crc, hdr_crc; 296 struct chfs_eb_hdr *ebhdr = buf; 297 le32 lid_save; 298 299 //check is there a header 300 if (check_pattern((void *) &ebhdr->ec_hdr, 301 0xFF, 0, CHFS_EB_EC_HDR_SIZE)) { 302 dbg_ebh("no header found\n"); 303 return EBHDR_LEB_NO_HDR; 304 } 305 306 // check magic 307 magic = le32toh(ebhdr->ec_hdr.magic); 308 if (magic != CHFS_MAGIC_BITMASK) { 309 dbg_ebh("bad magic bitmask(exp: %x found %x)\n", 310 CHFS_MAGIC_BITMASK, magic); 311 return EBHDR_LEB_BADMAGIC; 312 } 313 314 // check CRC_EC 315 hdr_crc = le32toh(ebhdr->ec_hdr.crc_ec); 316 crc = crc32(0, (uint8_t *) &ebhdr->ec_hdr + 8, 4); 317 if (hdr_crc != crc) { 318 dbg_ebh("bad crc_ec found\n"); 319 return EBHDR_LEB_BADCRC; 320 } 321 322 /* check if the PEB is free: magic, crc_ec and erase_cnt is good and 323 * everything else is FFF.. 324 */ 325 if (check_pattern((void *) &ebhdr->u.nor_hdr, 0xFF, 0, 326 CHFS_EB_HDR_NOR_SIZE)) { 327 dbg_ebh("free peb found\n"); 328 return EBHDR_LEB_FREE; 329 } 330 331 // check invalidated (CRC == LID == 0) 332 if (ebhdr->u.nor_hdr.crc == 0 && ebhdr->u.nor_hdr.lid == 0) { 333 dbg_ebh("invalidated ebhdr found\n"); 334 return EBHDR_LEB_INVALIDATED; 335 } 336 337 // check CRC 338 hdr_crc = le32toh(ebhdr->u.nor_hdr.crc); 339 lid_save = ebhdr->u.nor_hdr.lid; 340 341 // mark lid as not dirty for crc calc 342 ebhdr->u.nor_hdr.lid = ebhdr->u.nor_hdr.lid | htole32( 343 CHFS_LID_NOT_DIRTY_BIT); 344 crc = crc32(0, (uint8_t *) &ebhdr->u.nor_hdr + 4, 345 CHFS_EB_HDR_NOR_SIZE - 4); 346 // restore the original lid value in ebh 347 ebhdr->u.nor_hdr.lid = lid_save; 348 349 if (crc != hdr_crc) { 350 dbg_ebh("bad crc found\n"); 351 return EBHDR_LEB_BADCRC; 352 } 353 354 // check dirty 355 if (!(le32toh(lid_save) & CHFS_LID_NOT_DIRTY_BIT)) { 356 dbg_ebh("dirty ebhdr found\n"); 357 return EBHDR_LEB_DIRTY; 358 } 359 360 return EBHDR_LEB_OK; 361 } 362 363 /** 364 * nand_check_eb_hdr - check eraseblock header read from NAND flash 365 * 366 * @ebh: chfs eraseblock handler 367 * @buf: eraseblock header to check 368 * 369 * Returns eraseblock header status. 370 */ 371 int 372 nand_check_eb_hdr(struct chfs_ebh *ebh, void *buf) 373 { 374 uint32_t magic, crc, hdr_crc; 375 struct chfs_eb_hdr *ebhdr = buf; 376 377 //check is there a header 378 if (check_pattern((void *) &ebhdr->ec_hdr, 379 0xFF, 0, CHFS_EB_EC_HDR_SIZE)) { 380 dbg_ebh("no header found\n"); 381 return EBHDR_LEB_NO_HDR; 382 } 383 384 // check magic 385 magic = le32toh(ebhdr->ec_hdr.magic); 386 if (magic != CHFS_MAGIC_BITMASK) { 387 dbg_ebh("bad magic bitmask(exp: %x found %x)\n", 388 CHFS_MAGIC_BITMASK, magic); 389 return EBHDR_LEB_BADMAGIC; 390 } 391 392 // check CRC_EC 393 hdr_crc = le32toh(ebhdr->ec_hdr.crc_ec); 394 crc = crc32(0, (uint8_t *) &ebhdr->ec_hdr + 8, 4); 395 if (hdr_crc != crc) { 396 dbg_ebh("bad crc_ec found\n"); 397 return EBHDR_LEB_BADCRC; 398 } 399 400 /* check if the PEB is free: magic, crc_ec and erase_cnt is good and 401 * everything else is FFF.. 402 */ 403 if (check_pattern((void *) &ebhdr->u.nand_hdr, 0xFF, 0, 404 CHFS_EB_HDR_NAND_SIZE)) { 405 dbg_ebh("free peb found\n"); 406 return EBHDR_LEB_FREE; 407 } 408 409 // check CRC 410 hdr_crc = le32toh(ebhdr->u.nand_hdr.crc); 411 412 crc = crc32(0, (uint8_t *) &ebhdr->u.nand_hdr + 4, 413 CHFS_EB_HDR_NAND_SIZE - 4); 414 415 if (crc != hdr_crc) { 416 dbg_ebh("bad crc found\n"); 417 return EBHDR_LEB_BADCRC; 418 } 419 420 return EBHDR_LEB_OK; 421 } 422 423 /** 424 * nor_mark_eb_hdr_dirty_flash- mark eraseblock header dirty on NOR flash 425 * 426 * @ebh: chfs eraseblock handler 427 * @pebnr: eraseblock number 428 * @lid: leb id (its bit number 31 will be set to 0) 429 * 430 * It pulls the CHFS_LID_NOT_DIRTY_BIT to zero on flash. 431 * 432 * Returns zero in case of success, error code in case of fail. 433 */ 434 int 435 nor_mark_eb_hdr_dirty_flash(struct chfs_ebh *ebh, int pebnr, int lid) 436 { 437 int ret; 438 size_t retlen; 439 off_t ofs; 440 441 /* mark leb id dirty */ 442 lid = htole32(lid & CHFS_LID_DIRTY_BIT_MASK); 443 444 /* calculate position */ 445 ofs = pebnr * ebh->flash_if->erasesize + CHFS_EB_EC_HDR_SIZE 446 + CHFS_GET_MEMBER_POS(struct chfs_nor_eb_hdr , lid); 447 448 ret = flash_write(ebh->flash_dev, ofs, sizeof(lid), &retlen, 449 (unsigned char *) &lid); 450 if (ret || retlen != sizeof(lid)) { 451 chfs_err("can't mark peb dirty"); 452 return ret; 453 } 454 455 return 0; 456 } 457 458 /** 459 * nor_invalidate_eb_hdr - invalidate eraseblock header on NOR flash 460 * 461 * @ebh: chfs eraseblock handler 462 * @pebnr: eraseblock number 463 * 464 * Sets crc and lip field to zero. 465 * Returns zero in case of success, error code in case of fail. 466 */ 467 int 468 nor_invalidate_eb_hdr(struct chfs_ebh *ebh, int pebnr) 469 { 470 int ret; 471 size_t retlen; 472 off_t ofs; 473 char zero_buf[CHFS_INVALIDATE_SIZE]; 474 475 /* fill with zero */ 476 memset(zero_buf, 0x0, CHFS_INVALIDATE_SIZE); 477 478 /* calculate position (!!! lid is directly behind crc !!!) */ 479 ofs = pebnr * ebh->flash_if->erasesize + CHFS_EB_EC_HDR_SIZE 480 + CHFS_GET_MEMBER_POS(struct chfs_nor_eb_hdr, crc); 481 482 ret = flash_write(ebh->flash_dev, 483 ofs, CHFS_INVALIDATE_SIZE, &retlen, 484 (unsigned char *) &zero_buf); 485 if (ret || retlen != CHFS_INVALIDATE_SIZE) { 486 chfs_err("can't invalidate peb"); 487 return ret; 488 } 489 490 return 0; 491 } 492 493 /** 494 * mark_eb_hdr_free - free eraseblock header on NOR or NAND flash 495 * 496 * @ebh: chfs eraseblock handler 497 * @pebnr: eraseblock number 498 * @ec: erase counter of PEB 499 * 500 * Write out the magic and erase counter to the physical eraseblock. 501 * Returns zero in case of success, error code in case of fail. 502 */ 503 int 504 mark_eb_hdr_free(struct chfs_ebh *ebh, int pebnr, int ec) 505 { 506 int ret, crc; 507 size_t retlen; 508 off_t ofs; 509 struct chfs_eb_hdr *ebhdr; 510 ebhdr = kmem_alloc(sizeof(struct chfs_eb_hdr), KM_SLEEP); 511 512 ebhdr->ec_hdr.magic = htole32(CHFS_MAGIC_BITMASK); 513 ebhdr->ec_hdr.erase_cnt = htole32(ec); 514 crc = crc32(0, (uint8_t *) &ebhdr->ec_hdr + 8, 4); 515 ebhdr->ec_hdr.crc_ec = htole32(crc); 516 517 ofs = pebnr * ebh->flash_if->erasesize; 518 519 KASSERT(sizeof(ebhdr->ec_hdr) == CHFS_EB_EC_HDR_SIZE); 520 521 ret = flash_write(ebh->flash_dev, 522 ofs, CHFS_EB_EC_HDR_SIZE, &retlen, 523 (unsigned char *) &ebhdr->ec_hdr); 524 525 if (ret || retlen != CHFS_EB_EC_HDR_SIZE) { 526 chfs_err("can't mark peb as free: %d\n", pebnr); 527 kmem_free(ebhdr, sizeof(struct chfs_eb_hdr)); 528 return ret; 529 } 530 531 kmem_free(ebhdr, sizeof(struct chfs_eb_hdr)); 532 return 0; 533 } 534 535 /*****************************************************************************/ 536 /* End of Flash specific operations */ 537 /*****************************************************************************/ 538 539 /*****************************************************************************/ 540 /* Lock Tree */ 541 /*****************************************************************************/ 542 543 int 544 ltree_entry_cmp(struct chfs_ltree_entry *le1, 545 struct chfs_ltree_entry *le2) 546 { 547 return (le1->lnr - le2->lnr); 548 } 549 550 /* Generate functions for Lock tree's red-black tree */ 551 RB_PROTOTYPE( ltree_rbtree, chfs_ltree_entry, rb, ltree_entry_cmp); 552 RB_GENERATE( ltree_rbtree, chfs_ltree_entry, rb, ltree_entry_cmp); 553 554 555 /** 556 * ltree_lookup - looks up a logical eraseblock in the lock tree 557 * @ebh: chfs eraseblock handler 558 * @lid: identifier of the logical eraseblock 559 * 560 * This function returns a pointer to the wanted &struct chfs_ltree_entry 561 * if the logical eraseblock is in the lock tree, so it is locked, NULL 562 * otherwise. 563 * @ebh->ltree_lock has to be locked! 564 */ 565 static struct chfs_ltree_entry * 566 ltree_lookup(struct chfs_ebh *ebh, int lnr) 567 { 568 struct chfs_ltree_entry le, *result; 569 le.lnr = lnr; 570 result = RB_FIND(ltree_rbtree, &ebh->ltree, &le); 571 return result; 572 } 573 574 /** 575 * ltree_add_entry - add an entry to the lock tree 576 * @ebh: chfs eraseblock handler 577 * @lnr: identifier of the logical eraseblock 578 * 579 * This function adds a new logical eraseblock entry identified with @lnr to the 580 * lock tree. If the entry is already in the tree, it increases the user 581 * counter. 582 * Returns NULL if can not allocate memory for lock tree entry, or a pointer 583 * to the inserted entry otherwise. 584 */ 585 static struct chfs_ltree_entry * 586 ltree_add_entry(struct chfs_ebh *ebh, int lnr) 587 { 588 struct chfs_ltree_entry *le, *result; 589 590 le = kmem_alloc(sizeof(struct chfs_ltree_entry), KM_SLEEP); 591 592 le->lnr = lnr; 593 le->users = 1; 594 rw_init(&le->mutex); 595 596 //dbg_ebh("enter ltree lock\n"); 597 mutex_enter(&ebh->ltree_lock); 598 //dbg_ebh("insert\n"); 599 result = RB_INSERT(ltree_rbtree, &ebh->ltree, le); 600 //dbg_ebh("inserted\n"); 601 if (result) { 602 //The entry is already in the tree 603 result->users++; 604 kmem_free(le, sizeof(struct chfs_ltree_entry)); 605 } 606 else { 607 result = le; 608 } 609 mutex_exit(&ebh->ltree_lock); 610 611 return result; 612 } 613 614 /** 615 * leb_read_lock - lock a logical eraseblock for read 616 * @ebh: chfs eraseblock handler 617 * @lnr: identifier of the logical eraseblock 618 * 619 * Returns zero in case of success, error code in case of fail. 620 */ 621 static int 622 leb_read_lock(struct chfs_ebh *ebh, int lnr) 623 { 624 struct chfs_ltree_entry *le; 625 626 le = ltree_add_entry(ebh, lnr); 627 if (!le) 628 return ENOMEM; 629 630 rw_enter(&le->mutex, RW_READER); 631 return 0; 632 } 633 634 /** 635 * leb_read_unlock - unlock a logical eraseblock from read 636 * @ebh: chfs eraseblock handler 637 * @lnr: identifier of the logical eraseblock 638 * 639 * This function unlocks a logical eraseblock from read and delete it from the 640 * lock tree is there are no more users of it. 641 */ 642 static void 643 leb_read_unlock(struct chfs_ebh *ebh, int lnr) 644 { 645 struct chfs_ltree_entry *le; 646 647 mutex_enter(&ebh->ltree_lock); 648 //dbg_ebh("LOCK: ebh->ltree_lock spin locked in leb_read_unlock()\n"); 649 le = ltree_lookup(ebh, lnr); 650 if (!le) 651 goto out; 652 653 le->users -= 1; 654 KASSERT(le->users >= 0); 655 rw_exit(&le->mutex); 656 if (le->users == 0) { 657 le = RB_REMOVE(ltree_rbtree, &ebh->ltree, le); 658 if (le) { 659 rw_destroy(&le->mutex); 660 661 kmem_free(le, sizeof(struct chfs_ltree_entry)); 662 } 663 } 664 665 out: 666 mutex_exit(&ebh->ltree_lock); 667 //dbg_ebh("UNLOCK: ebh->ltree_lock spin unlocked in leb_read_unlock()\n"); 668 } 669 670 /** 671 * leb_write_lock - lock a logical eraseblock for write 672 * @ebh: chfs eraseblock handler 673 * @lnr: identifier of the logical eraseblock 674 * 675 * Returns zero in case of success, error code in case of fail. 676 */ 677 static int 678 leb_write_lock(struct chfs_ebh *ebh, int lnr) 679 { 680 struct chfs_ltree_entry *le; 681 682 le = ltree_add_entry(ebh, lnr); 683 if (!le) 684 return ENOMEM; 685 686 rw_enter(&le->mutex, RW_WRITER); 687 return 0; 688 } 689 690 /** 691 * leb_write_unlock - unlock a logical eraseblock from write 692 * @ebh: chfs eraseblock handler 693 * @lnr: identifier of the logical eraseblock 694 * 695 * This function unlocks a logical eraseblock from write and delete it from the 696 * lock tree is there are no more users of it. 697 */ 698 static void 699 leb_write_unlock(struct chfs_ebh *ebh, int lnr) 700 { 701 struct chfs_ltree_entry *le; 702 703 mutex_enter(&ebh->ltree_lock); 704 //dbg_ebh("LOCK: ebh->ltree_lock spin locked in leb_write_unlock()\n"); 705 le = ltree_lookup(ebh, lnr); 706 if (!le) 707 goto out; 708 709 le->users -= 1; 710 KASSERT(le->users >= 0); 711 rw_exit(&le->mutex); 712 if (le->users == 0) { 713 RB_REMOVE(ltree_rbtree, &ebh->ltree, le); 714 715 rw_destroy(&le->mutex); 716 717 kmem_free(le, sizeof(struct chfs_ltree_entry)); 718 } 719 720 out: 721 mutex_exit(&ebh->ltree_lock); 722 //dbg_ebh("UNLOCK: ebh->ltree_lock spin unlocked in leb_write_unlock()\n"); 723 } 724 725 /*****************************************************************************/ 726 /* End of Lock Tree */ 727 /*****************************************************************************/ 728 729 /*****************************************************************************/ 730 /* Erase related operations */ 731 /*****************************************************************************/ 732 733 /** 734 * If the first argument is smaller than the second, the function 735 * returns a value smaller than zero. If they are equal, the function re- 736 * turns zero. Otherwise, it should return a value greater than zero. 737 */ 738 int 739 peb_in_use_cmp(struct chfs_peb *peb1, struct chfs_peb *peb2) 740 { 741 return (peb1->pebnr - peb2->pebnr); 742 } 743 744 int 745 peb_free_cmp(struct chfs_peb *peb1, struct chfs_peb *peb2) 746 { 747 int comp; 748 749 comp = peb1->erase_cnt - peb2->erase_cnt; 750 if (0 == comp) 751 comp = peb1->pebnr - peb2->pebnr; 752 753 return comp; 754 } 755 756 /* Generate functions for in use PEB's red-black tree */ 757 RB_PROTOTYPE(peb_in_use_rbtree, chfs_peb, u.rb, peb_in_use_cmp); 758 RB_GENERATE(peb_in_use_rbtree, chfs_peb, u.rb, peb_in_use_cmp); 759 RB_PROTOTYPE(peb_free_rbtree, chfs_peb, u.rb, peb_free_cmp); 760 RB_GENERATE(peb_free_rbtree, chfs_peb, u.rb, peb_free_cmp); 761 762 /** 763 * add_peb_to_erase_queue: adds a PEB to to_erase/fully_erased queue 764 * @ebh - chfs eraseblock handler 765 * @pebnr - physical eraseblock's number 766 * @ec - erase counter of PEB 767 * @queue: the queue to add to 768 * 769 * This function adds a PEB to the erase queue specified by @queue. 770 * The @ebh->erase_lock must be locked before using this. 771 * Returns zero in case of success, error code in case of fail. 772 */ 773 int 774 add_peb_to_erase_queue(struct chfs_ebh *ebh, int pebnr, int ec, 775 struct peb_queue *queue) 776 { 777 struct chfs_peb *peb; 778 779 peb = kmem_alloc(sizeof(struct chfs_peb), KM_SLEEP); 780 781 peb->erase_cnt = ec; 782 peb->pebnr = pebnr; 783 784 TAILQ_INSERT_TAIL(queue, peb, u.queue); 785 786 return 0; 787 788 } 789 //TODO 790 /** 791 * find_peb_in_use - looks up a PEB in the RB-tree of used blocks 792 * @ebh - chfs eraseblock handler 793 * 794 * This function returns a pointer to the PEB found in the tree, 795 * NULL otherwise. 796 * The @ebh->erase_lock must be locked before using this. 797 */ 798 struct chfs_peb * 799 find_peb_in_use(struct chfs_ebh *ebh, int pebnr) 800 { 801 struct chfs_peb peb, *result; 802 peb.pebnr = pebnr; 803 result = RB_FIND(peb_in_use_rbtree, &ebh->in_use, &peb); 804 return result; 805 } 806 807 /** 808 * add_peb_to_free - adds a PEB to the RB-tree of free PEBs 809 * @ebh - chfs eraseblock handler 810 * @pebnr - physical eraseblock's number 811 * @ec - erase counter of PEB 812 * 813 * 814 * This function adds a physical eraseblock to the RB-tree of free PEBs 815 * stored in the @ebh. The key is the erase counter and pebnr. 816 * The @ebh->erase_lock must be locked before using this. 817 * Returns zero in case of success, error code in case of fail. 818 */ 819 int 820 add_peb_to_free(struct chfs_ebh *ebh, int pebnr, int ec) 821 { 822 struct chfs_peb *peb, *result; 823 824 peb = kmem_alloc(sizeof(struct chfs_peb), KM_SLEEP); 825 826 peb->erase_cnt = ec; 827 peb->pebnr = pebnr; 828 result = RB_INSERT(peb_free_rbtree, &ebh->free, peb); 829 if (result) { 830 kmem_free(peb, sizeof(struct chfs_peb)); 831 return 1; 832 } 833 834 return 0; 835 } 836 837 /** 838 * add_peb_to_in_use - adds a PEB to the RB-tree of used PEBs 839 * @ebh - chfs eraseblock handler 840 * @pebnr - physical eraseblock's number 841 * @ec - erase counter of PEB 842 * 843 * 844 * This function adds a physical eraseblock to the RB-tree of used PEBs 845 * stored in the @ebh. The key is pebnr. 846 * The @ebh->erase_lock must be locked before using this. 847 * Returns zero in case of success, error code in case of fail. 848 */ 849 int 850 add_peb_to_in_use(struct chfs_ebh *ebh, int pebnr, int ec) 851 { 852 struct chfs_peb *peb, *result; 853 854 peb = kmem_alloc(sizeof(struct chfs_peb), KM_SLEEP); 855 856 peb->erase_cnt = ec; 857 peb->pebnr = pebnr; 858 result = RB_INSERT(peb_in_use_rbtree, &ebh->in_use, peb); 859 if (result) { 860 kmem_free(peb, sizeof(struct chfs_peb)); 861 return 1; 862 } 863 864 return 0; 865 } 866 867 /** 868 * erase_callback - callback function for flash erase 869 * @ei: erase information 870 */ 871 void 872 erase_callback(struct flash_erase_instruction *ei) 873 { 874 int err; 875 struct chfs_erase_info_priv *priv = (void *) ei->ei_priv; 876 //dbg_ebh("ERASE_CALLBACK() CALLED\n"); 877 struct chfs_ebh *ebh = priv->ebh; 878 struct chfs_peb *peb = priv->peb; 879 880 peb->erase_cnt += 1; 881 882 if (ei->ei_state == FLASH_ERASE_DONE) { 883 884 /* Write out erase counter */ 885 err = ebh->ops->mark_eb_hdr_free(ebh, 886 peb->pebnr, peb->erase_cnt); 887 if (err) { 888 /* cannot mark PEB as free,so erase it again */ 889 chfs_err( 890 "cannot mark eraseblock as free, PEB: %d\n", 891 peb->pebnr); 892 mutex_enter(&ebh->erase_lock); 893 /*dbg_ebh("LOCK: ebh->erase_lock spin locked in erase_callback() " 894 "after mark ebhdr free\n");*/ 895 add_peb_to_erase_queue(ebh, peb->pebnr, peb->erase_cnt, 896 &ebh->to_erase); 897 mutex_exit(&ebh->erase_lock); 898 /*dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in erase_callback() " 899 "after mark ebhdr free\n");*/ 900 kmem_free(peb, sizeof(struct chfs_peb)); 901 return; 902 } 903 904 mutex_enter(&ebh->erase_lock); 905 /*dbg_ebh("LOCK: ebh->erase_lock spin locked in erase_callback()\n");*/ 906 err = add_peb_to_free(ebh, peb->pebnr, peb->erase_cnt); 907 mutex_exit(&ebh->erase_lock); 908 /*dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in erase_callback()\n");*/ 909 kmem_free(peb, sizeof(struct chfs_peb)); 910 } else { 911 /* 912 * Erase is finished, but there was a problem, 913 * so erase PEB again 914 */ 915 chfs_err("erase failed, state is: 0x%x\n", ei->ei_state); 916 add_peb_to_erase_queue(ebh, peb->pebnr, peb->erase_cnt, &ebh->to_erase); 917 kmem_free(peb, sizeof(struct chfs_peb)); 918 } 919 } 920 921 /** 922 * free_peb: free a PEB 923 * @ebh: chfs eraseblock handler 924 * 925 * This function erases the first physical eraseblock from one of the erase 926 * lists and adds to the RB-tree of free PEBs. 927 * Returns zero in case of success, error code in case of fail. 928 */ 929 int 930 free_peb(struct chfs_ebh *ebh) 931 { 932 int err, retries = 0; 933 off_t ofs; 934 struct chfs_peb *peb = NULL; 935 struct flash_erase_instruction *ei; 936 937 KASSERT(mutex_owned(&ebh->erase_lock)); 938 939 if (!TAILQ_EMPTY(&ebh->fully_erased)) { 940 //dbg_ebh("[FREE PEB] got a fully erased block\n"); 941 peb = TAILQ_FIRST(&ebh->fully_erased); 942 TAILQ_REMOVE(&ebh->fully_erased, peb, u.queue); 943 err = ebh->ops->mark_eb_hdr_free(ebh, 944 peb->pebnr, peb->erase_cnt); 945 if (err) { 946 goto out_free; 947 } 948 err = add_peb_to_free(ebh, peb->pebnr, peb->erase_cnt); 949 goto out_free; 950 } 951 /* Erase PEB */ 952 //dbg_ebh("[FREE PEB] erasing a block\n"); 953 peb = TAILQ_FIRST(&ebh->to_erase); 954 TAILQ_REMOVE(&ebh->to_erase, peb, u.queue); 955 mutex_exit(&ebh->erase_lock); 956 //dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in free_peb()\n"); 957 ofs = peb->pebnr * ebh->flash_if->erasesize; 958 959 /* XXX where do we free this? */ 960 ei = kmem_alloc(sizeof(struct flash_erase_instruction) 961 + sizeof(struct chfs_erase_info_priv), KM_SLEEP); 962 retry: 963 memset(ei, 0, sizeof(*ei)); 964 965 // ei->ei_if = ebh->flash_if; 966 ei->ei_addr = ofs; 967 ei->ei_len = ebh->flash_if->erasesize; 968 ei->ei_callback = erase_callback; 969 ei->ei_priv = (unsigned long) (&ei[1]); 970 971 ((struct chfs_erase_info_priv *) ei->ei_priv)->ebh = ebh; 972 ((struct chfs_erase_info_priv *) ei->ei_priv)->peb = peb; 973 974 err = flash_erase(ebh->flash_dev, ei); 975 dbg_ebh("erased peb: %d\n", peb->pebnr); 976 977 /* einval would mean we did something wrong */ 978 KASSERT(err != EINVAL); 979 980 if (err) { 981 dbg_ebh("errno: %d, ei->ei_state: %d\n", err, ei->ei_state); 982 if (CHFS_MAX_GET_PEB_RETRIES < ++retries && 983 ei->ei_state == FLASH_ERASE_FAILED) { 984 /* The block went bad mark it */ 985 dbg_ebh("ebh markbad! 0x%jx\n", (uintmax_t )ofs); 986 err = flash_block_markbad(ebh->flash_dev, ofs); 987 if (!err) { 988 ebh->peb_nr--; 989 } 990 991 goto out; 992 } 993 chfs_err("can not erase PEB: %d, try again\n", peb->pebnr); 994 goto retry; 995 } 996 997 out: 998 /* lock the erase_lock, because it was locked 999 * when the function was called */ 1000 mutex_enter(&ebh->erase_lock); 1001 return err; 1002 1003 out_free: 1004 kmem_free(peb, sizeof(struct chfs_peb)); 1005 return err; 1006 } 1007 1008 /** 1009 * release_peb - schedule an erase for the PEB 1010 * @ebh: chfs eraseblock handler 1011 * @pebnr: physical eraseblock number 1012 * 1013 * This function get the peb identified by @pebnr from the in_use RB-tree of 1014 * @ebh, removes it and schedule an erase for it. 1015 * 1016 * Returns zero on success, error code in case of fail. 1017 */ 1018 int 1019 release_peb(struct chfs_ebh *ebh, int pebnr) 1020 { 1021 int err = 0; 1022 struct chfs_peb *peb; 1023 1024 mutex_enter(&ebh->erase_lock); 1025 1026 //dbg_ebh("LOCK: ebh->erase_lock spin locked in release_peb()\n"); 1027 peb = find_peb_in_use(ebh, pebnr); 1028 if (!peb) { 1029 chfs_err("LEB is mapped, but is not in the 'in_use' " 1030 "tree of ebh\n"); 1031 goto out_unlock; 1032 } 1033 err = add_peb_to_erase_queue(ebh, peb->pebnr, peb->erase_cnt, 1034 &ebh->to_erase); 1035 1036 if (err) 1037 goto out_unlock; 1038 1039 RB_REMOVE(peb_in_use_rbtree, &ebh->in_use, peb); 1040 out_unlock: 1041 mutex_exit(&ebh->erase_lock); 1042 //dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in release_peb()" 1043 // " at out_unlock\n"); 1044 return err; 1045 } 1046 1047 /** 1048 * erase_thread - background thread for erasing PEBs 1049 * @data: pointer to the eraseblock handler 1050 */ 1051 /*void 1052 erase_thread(void *data) 1053 { 1054 struct chfs_ebh *ebh = data; 1055 1056 dbg_ebh("erase thread started\n"); 1057 while (ebh->bg_erase.eth_running) { 1058 int err; 1059 1060 mutex_enter(&ebh->erase_lock); 1061 dbg_ebh("LOCK: ebh->erase_lock spin locked in erase_thread()\n"); 1062 if (TAILQ_EMPTY(&ebh->to_erase) && TAILQ_EMPTY(&ebh->fully_erased)) { 1063 dbg_ebh("thread has nothing to do\n"); 1064 mutex_exit(&ebh->erase_lock); 1065 mutex_enter(&ebh->bg_erase.eth_thread_mtx); 1066 cv_timedwait_sig(&ebh->bg_erase.eth_wakeup, 1067 &ebh->bg_erase.eth_thread_mtx, mstohz(100)); 1068 mutex_exit(&ebh->bg_erase.eth_thread_mtx); 1069 1070 dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in erase_thread()\n"); 1071 continue; 1072 } 1073 mutex_exit(&ebh->erase_lock); 1074 dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in erase_thread()\n"); 1075 1076 err = free_peb(ebh); 1077 if (err) 1078 chfs_err("freeing PEB failed in the background thread: %d\n", err); 1079 1080 } 1081 dbg_ebh("erase thread stopped\n"); 1082 kthread_exit(0); 1083 }*/ 1084 1085 /** 1086 * erase_thread - background thread for erasing PEBs 1087 * @data: pointer to the eraseblock handler 1088 */ 1089 void 1090 erase_thread(void *data) { 1091 dbg_ebh("[EBH THREAD] erase thread started\n"); 1092 1093 struct chfs_ebh *ebh = data; 1094 int err; 1095 1096 mutex_enter(&ebh->erase_lock); 1097 while (ebh->bg_erase.eth_running) { 1098 if (TAILQ_EMPTY(&ebh->to_erase) && 1099 TAILQ_EMPTY(&ebh->fully_erased)) { 1100 cv_timedwait_sig(&ebh->bg_erase.eth_wakeup, 1101 &ebh->erase_lock, mstohz(100)); 1102 } else { 1103 /* XXX exiting this mutex is a bit odd here as 1104 * free_peb instantly reenters it... 1105 */ 1106 err = free_peb(ebh); 1107 mutex_exit(&ebh->erase_lock); 1108 if (err) { 1109 chfs_err("freeing PEB failed in the" 1110 " background thread: %d\n", err); 1111 } 1112 mutex_enter(&ebh->erase_lock); 1113 } 1114 } 1115 mutex_exit(&ebh->erase_lock); 1116 1117 dbg_ebh("[EBH THREAD] erase thread stopped\n"); 1118 kthread_exit(0); 1119 } 1120 1121 /** 1122 * erase_thread_start - init and start erase thread 1123 * @ebh: eraseblock handler 1124 */ 1125 static void 1126 erase_thread_start(struct chfs_ebh *ebh) 1127 { 1128 cv_init(&ebh->bg_erase.eth_wakeup, "ebheracv"); 1129 1130 ebh->bg_erase.eth_running = true; 1131 kthread_create(PRI_NONE, KTHREAD_MPSAFE | KTHREAD_MUSTJOIN, NULL, 1132 erase_thread, ebh, &ebh->bg_erase.eth_thread, "ebherase"); 1133 } 1134 1135 /** 1136 * erase_thread_stop - stop background erase thread 1137 * @ebh: eraseblock handler 1138 */ 1139 static void 1140 erase_thread_stop(struct chfs_ebh *ebh) 1141 { 1142 ebh->bg_erase.eth_running = false; 1143 cv_signal(&ebh->bg_erase.eth_wakeup); 1144 dbg_ebh("[EBH THREAD STOP] signaled\n"); 1145 1146 kthread_join(ebh->bg_erase.eth_thread); 1147 #ifdef BROKEN_KTH_JOIN 1148 kpause("chfsebhjointh", false, mstohz(1000), NULL); 1149 #endif 1150 1151 cv_destroy(&ebh->bg_erase.eth_wakeup); 1152 } 1153 1154 /*****************************************************************************/ 1155 /* End of Erase related operations */ 1156 /*****************************************************************************/ 1157 1158 /*****************************************************************************/ 1159 /* Scan related operations */ 1160 /*****************************************************************************/ 1161 int 1162 scan_leb_used_cmp(struct chfs_scan_leb *sleb1, struct chfs_scan_leb *sleb2) 1163 { 1164 return (sleb1->lnr - sleb2->lnr); 1165 } 1166 1167 RB_PROTOTYPE(scan_leb_used_rbtree, chfs_scan_leb, u.rb, scan_leb_used_cmp); 1168 RB_GENERATE(scan_leb_used_rbtree, chfs_scan_leb, u.rb, scan_leb_used_cmp); 1169 1170 /** 1171 * scan_add_to_queue - adds a physical eraseblock to one of the 1172 * eraseblock queue 1173 * @si: chfs scanning information 1174 * @pebnr: physical eraseblock number 1175 * @erase_cnt: erase counter of the physical eraseblock 1176 * @list: the list to add to 1177 * 1178 * This function adds a physical eraseblock to one of the lists in the scanning 1179 * information. 1180 * Returns zero in case of success, negative error code in case of fail. 1181 */ 1182 static int 1183 scan_add_to_queue(struct chfs_scan_info *si, int pebnr, int erase_cnt, 1184 struct scan_leb_queue *queue) 1185 { 1186 struct chfs_scan_leb *sleb; 1187 1188 sleb = kmem_alloc(sizeof(struct chfs_scan_leb), KM_SLEEP); 1189 1190 sleb->pebnr = pebnr; 1191 sleb->erase_cnt = erase_cnt; 1192 TAILQ_INSERT_TAIL(queue, sleb, u.queue); 1193 return 0; 1194 } 1195 1196 /* 1197 * nor_scan_add_to_used - add a physical eraseblock to the 1198 * used tree of scan info 1199 * @ebh: chfs eraseblock handler 1200 * @si: chfs scanning information 1201 * @ebhdr: eraseblock header 1202 * @pebnr: physical eraseblock number 1203 * @leb_status: the status of the PEB's eraseblock header 1204 * 1205 * This function adds a PEB to the used tree of the scanning information. 1206 * It handles the situations if there are more physical eraseblock referencing 1207 * to the same logical eraseblock. 1208 * Returns zero in case of success, error code in case of fail. 1209 */ 1210 int 1211 nor_scan_add_to_used(struct chfs_ebh *ebh, struct chfs_scan_info *si, 1212 struct chfs_eb_hdr *ebhdr, int pebnr, int leb_status) 1213 { 1214 int err, lnr, ec; 1215 struct chfs_scan_leb *sleb, *old; 1216 1217 lnr = CHFS_GET_LID(ebhdr->u.nor_hdr.lid); 1218 ec = le32toh(ebhdr->ec_hdr.erase_cnt); 1219 1220 sleb = kmem_alloc(sizeof(struct chfs_scan_leb), KM_SLEEP); 1221 1222 sleb->erase_cnt = ec; 1223 sleb->lnr = lnr; 1224 sleb->pebnr = pebnr; 1225 sleb->info = leb_status; 1226 1227 old = RB_INSERT(scan_leb_used_rbtree, &si->used, sleb); 1228 if (old) { 1229 kmem_free(sleb, sizeof(struct chfs_scan_leb)); 1230 /* There is already an eraseblock in the used tree */ 1231 /* If the new one is bad */ 1232 if (EBHDR_LEB_DIRTY == leb_status && 1233 EBHDR_LEB_OK == old->info) { 1234 return scan_add_to_queue(si, pebnr, ec, &si->erase); 1235 } else { 1236 err = scan_add_to_queue(si, old->pebnr, 1237 old->erase_cnt, &si->erase); 1238 if (err) { 1239 return err; 1240 } 1241 1242 old->erase_cnt = ec; 1243 old->lnr = lnr; 1244 old->pebnr = pebnr; 1245 old->info = leb_status; 1246 return 0; 1247 } 1248 } 1249 return 0; 1250 } 1251 1252 /** 1253 * nor_process eb -read the headers from NOR flash, check them and add to 1254 * the scanning information 1255 * @ebh: chfs eraseblock handler 1256 * @si: chfs scanning information 1257 * @pebnr: physical eraseblock number 1258 * 1259 * Returns zero in case of success, error code in case of fail. 1260 */ 1261 int 1262 nor_process_eb(struct chfs_ebh *ebh, struct chfs_scan_info *si, 1263 int pebnr, struct chfs_eb_hdr *ebhdr) 1264 { 1265 int err, erase_cnt, leb_status; 1266 1267 err = ebh->ops->read_eb_hdr(ebh, pebnr, ebhdr); 1268 if (err) 1269 return err; 1270 1271 erase_cnt = le32toh(ebhdr->ec_hdr.erase_cnt); 1272 dbg_ebh("erase_cnt: %d\n", erase_cnt); 1273 leb_status = ebh->ops->check_eb_hdr(ebh, ebhdr); 1274 if (EBHDR_LEB_BADMAGIC == leb_status || 1275 EBHDR_LEB_BADCRC == leb_status) { 1276 err = scan_add_to_queue(si, pebnr, erase_cnt, &si->corrupted); 1277 return err; 1278 } 1279 else if (EBHDR_LEB_FREE == leb_status) { 1280 err = scan_add_to_queue(si, pebnr, erase_cnt, &si->free); 1281 goto count_mean; 1282 } 1283 else if (EBHDR_LEB_NO_HDR == leb_status) { 1284 err = scan_add_to_queue(si, pebnr, erase_cnt, &si->erased); 1285 return err; 1286 } 1287 else if (EBHDR_LEB_INVALIDATED == leb_status) { 1288 err = scan_add_to_queue(si, pebnr, erase_cnt, &si->erase); 1289 return err; 1290 } 1291 1292 err = nor_scan_add_to_used(ebh, si, ebhdr, pebnr, leb_status); 1293 if (err) 1294 return err; 1295 1296 1297 count_mean: 1298 si->sum_of_ec += erase_cnt; 1299 si->num_of_eb++; 1300 1301 return err; 1302 } 1303 1304 /* 1305 * nand_scan_add_to_used - add a physical eraseblock to the 1306 * used tree of scan info 1307 * @ebh: chfs eraseblock handler 1308 * @si: chfs scanning information 1309 * @ebhdr: eraseblock header 1310 * @pebnr: physical eraseblock number 1311 * @leb_status: the status of the PEB's eraseblock header 1312 * 1313 * This function adds a PEB to the used tree of the scanning information. 1314 * It handles the situations if there are more physical eraseblock referencing 1315 * to the same logical eraseblock. 1316 * Returns zero in case of success, error code in case of fail. 1317 */ 1318 int 1319 nand_scan_add_to_used(struct chfs_ebh *ebh, struct chfs_scan_info *si, 1320 struct chfs_eb_hdr *ebhdr, int pebnr) 1321 { 1322 int err, lnr, ec; 1323 struct chfs_scan_leb *sleb, *old; 1324 uint64_t serial = le64toh(ebhdr->u.nand_hdr.serial); 1325 1326 lnr = CHFS_GET_LID(ebhdr->u.nor_hdr.lid); 1327 ec = le32toh(ebhdr->ec_hdr.erase_cnt); 1328 1329 sleb = kmem_alloc(sizeof(struct chfs_scan_leb), KM_SLEEP); 1330 1331 sleb->erase_cnt = ec; 1332 sleb->lnr = lnr; 1333 sleb->pebnr = pebnr; 1334 sleb->info = serial; 1335 1336 old = RB_INSERT(scan_leb_used_rbtree, &si->used, sleb); 1337 if (old) { 1338 kmem_free(sleb, sizeof(struct chfs_scan_leb)); 1339 /* There is already an eraseblock in the used tree */ 1340 /* If the new one is bad */ 1341 if (serial < old->info) 1342 return scan_add_to_queue(si, pebnr, ec, &si->erase); 1343 else { 1344 err = scan_add_to_queue(si, 1345 old->pebnr, old->erase_cnt, &si->erase); 1346 if (err) 1347 return err; 1348 1349 old->erase_cnt = ec; 1350 old->lnr = lnr; 1351 old->pebnr = pebnr; 1352 old->info = serial; 1353 return 0; 1354 } 1355 } 1356 return 0; 1357 } 1358 1359 /** 1360 * nand_process eb -read the headers from NAND flash, check them and add to the 1361 * scanning information 1362 * @ebh: chfs eraseblock handler 1363 * @si: chfs scanning information 1364 * @pebnr: physical eraseblock number 1365 * 1366 * Returns zero in case of success, error code in case of fail. 1367 */ 1368 int 1369 nand_process_eb(struct chfs_ebh *ebh, struct chfs_scan_info *si, 1370 int pebnr, struct chfs_eb_hdr *ebhdr) 1371 { 1372 int err, erase_cnt, leb_status; 1373 uint64_t max_serial; 1374 /* isbad() is defined on some ancient platforms, heh */ 1375 bool is_bad; 1376 1377 /* Check block is bad */ 1378 err = flash_block_isbad(ebh->flash_dev, 1379 pebnr * ebh->flash_if->erasesize, &is_bad); 1380 if (err) { 1381 chfs_err("checking block is bad failed\n"); 1382 return err; 1383 } 1384 if (is_bad) { 1385 si->bad_peb_cnt++; 1386 return 0; 1387 } 1388 1389 err = ebh->ops->read_eb_hdr(ebh, pebnr, ebhdr); 1390 if (err) 1391 return err; 1392 1393 erase_cnt = le32toh(ebhdr->ec_hdr.erase_cnt); 1394 leb_status = ebh->ops->check_eb_hdr(ebh, ebhdr); 1395 if (EBHDR_LEB_BADMAGIC == leb_status || 1396 EBHDR_LEB_BADCRC == leb_status) { 1397 err = scan_add_to_queue(si, pebnr, erase_cnt, &si->corrupted); 1398 return err; 1399 } 1400 else if (EBHDR_LEB_FREE == leb_status) { 1401 err = scan_add_to_queue(si, pebnr, erase_cnt, &si->free); 1402 goto count_mean; 1403 } 1404 else if (EBHDR_LEB_NO_HDR == leb_status) { 1405 err = scan_add_to_queue(si, pebnr, erase_cnt, &si->erased); 1406 return err; 1407 } 1408 1409 err = nand_scan_add_to_used(ebh, si, ebhdr, pebnr); 1410 if (err) 1411 return err; 1412 1413 max_serial = le64toh(ebhdr->u.nand_hdr.serial); 1414 if (max_serial > *ebh->max_serial) { 1415 *ebh->max_serial = max_serial; 1416 } 1417 1418 count_mean: 1419 si->sum_of_ec += erase_cnt; 1420 si->num_of_eb++; 1421 1422 return err; 1423 } 1424 1425 /** 1426 * chfs_scan - scans the media and returns information about it 1427 * @ebh: chfs eraseblock handler 1428 * 1429 * This function scans through the media and returns information about it or if 1430 * it fails NULL will be returned. 1431 */ 1432 struct chfs_scan_info * 1433 chfs_scan(struct chfs_ebh *ebh) 1434 { 1435 struct chfs_scan_info *si; 1436 struct chfs_eb_hdr *ebhdr; 1437 int pebnr, err; 1438 1439 si = kmem_alloc(sizeof(*si), KM_SLEEP); 1440 1441 TAILQ_INIT(&si->corrupted); 1442 TAILQ_INIT(&si->free); 1443 TAILQ_INIT(&si->erase); 1444 TAILQ_INIT(&si->erased); 1445 RB_INIT(&si->used); 1446 si->bad_peb_cnt = 0; 1447 si->num_of_eb = 0; 1448 si->sum_of_ec = 0; 1449 1450 ebhdr = kmem_alloc(sizeof(*ebhdr), KM_SLEEP); 1451 1452 for (pebnr = 0; pebnr < ebh->peb_nr; pebnr++) { 1453 dbg_ebh("processing PEB %d\n", pebnr); 1454 err = ebh->ops->process_eb(ebh, si, pebnr, ebhdr); 1455 if (err < 0) 1456 goto out_ebhdr; 1457 } 1458 kmem_free(ebhdr, sizeof(*ebhdr)); 1459 dbg_ebh("[CHFS_SCAN] scanning information collected\n"); 1460 return si; 1461 1462 out_ebhdr: 1463 kmem_free(ebhdr, sizeof(*ebhdr)); 1464 kmem_free(si, sizeof(*si)); 1465 return NULL; 1466 } 1467 1468 /** 1469 * scan_info_destroy - frees all lists and trees in the scanning information 1470 * @si: the scanning information 1471 */ 1472 void 1473 scan_info_destroy(struct chfs_scan_info *si) 1474 { 1475 EBH_QUEUE_DESTROY(&si->corrupted, 1476 struct chfs_scan_leb, u.queue); 1477 1478 EBH_QUEUE_DESTROY(&si->erase, 1479 struct chfs_scan_leb, u.queue); 1480 1481 EBH_QUEUE_DESTROY(&si->erased, 1482 struct chfs_scan_leb, u.queue); 1483 1484 EBH_QUEUE_DESTROY(&si->free, 1485 struct chfs_scan_leb, u.queue); 1486 1487 EBH_TREE_DESTROY(scan_leb_used_rbtree, 1488 &si->used, struct chfs_scan_leb); 1489 1490 kmem_free(si, sizeof(*si)); 1491 dbg_ebh("[SCAN_INFO_DESTROY] scanning information destroyed\n"); 1492 } 1493 1494 /** 1495 * scan_media - scan media 1496 * 1497 * @ebh - chfs eraseblock handler 1498 * 1499 * Returns zero in case of success, error code in case of fail. 1500 */ 1501 1502 int 1503 scan_media(struct chfs_ebh *ebh) 1504 { 1505 int err, i, avg_ec; 1506 struct chfs_scan_info *si; 1507 struct chfs_scan_leb *sleb; 1508 1509 si = chfs_scan(ebh); 1510 /* 1511 * Process the scan info, manage the eraseblock lists 1512 */ 1513 mutex_init(&ebh->ltree_lock, MUTEX_DEFAULT, IPL_NONE); 1514 mutex_init(&ebh->erase_lock, MUTEX_DEFAULT, IPL_NONE); 1515 RB_INIT(&ebh->ltree); 1516 RB_INIT(&ebh->free); 1517 RB_INIT(&ebh->in_use); 1518 TAILQ_INIT(&ebh->to_erase); 1519 TAILQ_INIT(&ebh->fully_erased); 1520 mutex_init(&ebh->alc_mutex, MUTEX_DEFAULT, IPL_NONE); 1521 1522 ebh->peb_nr -= si->bad_peb_cnt; 1523 1524 /* 1525 * Create background thread for erasing 1526 */ 1527 erase_thread_start(ebh); 1528 1529 ebh->lmap = kmem_alloc(ebh->peb_nr * sizeof(int), KM_SLEEP); 1530 1531 for (i = 0; i < ebh->peb_nr; i++) { 1532 ebh->lmap[i] = EBH_LEB_UNMAPPED; 1533 } 1534 1535 if (si->num_of_eb == 0) { 1536 /* The flash contains no data. */ 1537 avg_ec = 0; 1538 } 1539 else { 1540 avg_ec = (int) (si->sum_of_ec / si->num_of_eb); 1541 } 1542 dbg_ebh("num_of_eb: %d\n", si->num_of_eb); 1543 1544 mutex_enter(&ebh->erase_lock); 1545 1546 RB_FOREACH(sleb, scan_leb_used_rbtree, &si->used) { 1547 ebh->lmap[sleb->lnr] = sleb->pebnr; 1548 err = add_peb_to_in_use(ebh, sleb->pebnr, sleb->erase_cnt); 1549 if (err) 1550 goto out_free; 1551 } 1552 1553 TAILQ_FOREACH(sleb, &si->erased, u.queue) { 1554 err = add_peb_to_erase_queue(ebh, sleb->pebnr, avg_ec, 1555 &ebh->fully_erased); 1556 if (err) 1557 goto out_free; 1558 } 1559 1560 TAILQ_FOREACH(sleb, &si->erase, u.queue) { 1561 err = add_peb_to_erase_queue(ebh, sleb->pebnr, avg_ec, 1562 &ebh->to_erase); 1563 if (err) 1564 goto out_free; 1565 } 1566 1567 TAILQ_FOREACH(sleb, &si->free, u.queue) { 1568 err = add_peb_to_free(ebh, sleb->pebnr, sleb->erase_cnt); 1569 if (err) 1570 goto out_free; 1571 } 1572 1573 TAILQ_FOREACH(sleb, &si->corrupted, u.queue) { 1574 err = add_peb_to_erase_queue(ebh, sleb->pebnr, avg_ec, 1575 &ebh->to_erase); 1576 if (err) 1577 goto out_free; 1578 } 1579 mutex_exit(&ebh->erase_lock); 1580 scan_info_destroy(si); 1581 return 0; 1582 1583 out_free: 1584 mutex_exit(&ebh->erase_lock); 1585 kmem_free(ebh->lmap, ebh->peb_nr * sizeof(int)); 1586 scan_info_destroy(si); 1587 dbg_ebh("[SCAN_MEDIA] returning with error: %d\n", err); 1588 return err; 1589 } 1590 1591 /*****************************************************************************/ 1592 /* End of Scan related operations */ 1593 /*****************************************************************************/ 1594 1595 /** 1596 * ebh_open - opens mtd device and init eraseblock header 1597 * @ebh: eraseblock handler 1598 * @flash_nr: flash device number to use 1599 * 1600 * Returns zero in case of success, error code in case of fail. 1601 */ 1602 int 1603 ebh_open(struct chfs_ebh *ebh, dev_t dev) 1604 { 1605 int err; 1606 1607 ebh->flash_dev = flash_get_device(dev); 1608 if (!ebh->flash_dev) { 1609 aprint_error("ebh_open: cant get flash device\n"); 1610 return ENODEV; 1611 } 1612 1613 ebh->flash_if = flash_get_interface(dev); 1614 if (!ebh->flash_if) { 1615 aprint_error("ebh_open: cant get flash interface\n"); 1616 return ENODEV; 1617 } 1618 1619 ebh->flash_size = flash_get_size(dev); 1620 ebh->peb_nr = ebh->flash_size / ebh->flash_if->erasesize; 1621 // ebh->peb_nr = ebh->flash_if->size / ebh->flash_if->erasesize; 1622 /* Set up flash operations based on flash type */ 1623 ebh->ops = kmem_alloc(sizeof(struct chfs_ebh_ops), KM_SLEEP); 1624 1625 switch (ebh->flash_if->type) { 1626 case FLASH_TYPE_NOR: 1627 ebh->eb_size = ebh->flash_if->erasesize - 1628 CHFS_EB_EC_HDR_SIZE - CHFS_EB_HDR_NOR_SIZE; 1629 1630 ebh->ops->read_eb_hdr = nor_read_eb_hdr; 1631 ebh->ops->write_eb_hdr = nor_write_eb_hdr; 1632 ebh->ops->check_eb_hdr = nor_check_eb_hdr; 1633 ebh->ops->mark_eb_hdr_dirty_flash = 1634 nor_mark_eb_hdr_dirty_flash; 1635 ebh->ops->invalidate_eb_hdr = nor_invalidate_eb_hdr; 1636 ebh->ops->mark_eb_hdr_free = mark_eb_hdr_free; 1637 1638 ebh->ops->process_eb = nor_process_eb; 1639 1640 ebh->ops->create_eb_hdr = nor_create_eb_hdr; 1641 ebh->ops->calc_data_offs = nor_calc_data_offs; 1642 1643 ebh->max_serial = NULL; 1644 break; 1645 case FLASH_TYPE_NAND: 1646 ebh->eb_size = ebh->flash_if->erasesize - 1647 2 * ebh->flash_if->page_size; 1648 1649 ebh->ops->read_eb_hdr = nand_read_eb_hdr; 1650 ebh->ops->write_eb_hdr = nand_write_eb_hdr; 1651 ebh->ops->check_eb_hdr = nand_check_eb_hdr; 1652 ebh->ops->mark_eb_hdr_free = mark_eb_hdr_free; 1653 ebh->ops->mark_eb_hdr_dirty_flash = NULL; 1654 ebh->ops->invalidate_eb_hdr = NULL; 1655 1656 ebh->ops->process_eb = nand_process_eb; 1657 1658 ebh->ops->create_eb_hdr = nand_create_eb_hdr; 1659 ebh->ops->calc_data_offs = nand_calc_data_offs; 1660 1661 ebh->max_serial = kmem_alloc(sizeof(uint64_t), KM_SLEEP); 1662 1663 *ebh->max_serial = 0; 1664 break; 1665 default: 1666 return 1; 1667 } 1668 printf("opening ebh: eb_size: %zu\n", ebh->eb_size); 1669 err = scan_media(ebh); 1670 if (err) { 1671 dbg_ebh("Scan failed."); 1672 kmem_free(ebh->ops, sizeof(struct chfs_ebh_ops)); 1673 kmem_free(ebh, sizeof(struct chfs_ebh)); 1674 return err; 1675 } 1676 return 0; 1677 } 1678 1679 /** 1680 * ebh_close - close ebh 1681 * @ebh: eraseblock handler 1682 * Returns zero in case of success, error code in case of fail. 1683 */ 1684 int 1685 ebh_close(struct chfs_ebh *ebh) 1686 { 1687 erase_thread_stop(ebh); 1688 1689 EBH_TREE_DESTROY(peb_free_rbtree, &ebh->free, struct chfs_peb); 1690 EBH_TREE_DESTROY(peb_in_use_rbtree, &ebh->in_use, struct chfs_peb); 1691 1692 EBH_QUEUE_DESTROY(&ebh->fully_erased, struct chfs_peb, u.queue); 1693 EBH_QUEUE_DESTROY(&ebh->to_erase, struct chfs_peb, u.queue); 1694 1695 /* XXX HACK, see ebh.h */ 1696 EBH_TREE_DESTROY_MUTEX(ltree_rbtree, &ebh->ltree, 1697 struct chfs_ltree_entry); 1698 1699 KASSERT(!mutex_owned(&ebh->ltree_lock)); 1700 KASSERT(!mutex_owned(&ebh->alc_mutex)); 1701 KASSERT(!mutex_owned(&ebh->erase_lock)); 1702 1703 mutex_destroy(&ebh->ltree_lock); 1704 mutex_destroy(&ebh->alc_mutex); 1705 mutex_destroy(&ebh->erase_lock); 1706 1707 kmem_free(ebh->ops, sizeof(struct chfs_ebh_ops)); 1708 kmem_free(ebh, sizeof(struct chfs_ebh)); 1709 1710 return 0; 1711 } 1712 1713 /** 1714 * ebh_read_leb - read data from leb 1715 * @ebh: eraseblock handler 1716 * @lnr: logical eraseblock number 1717 * @buf: buffer to read to 1718 * @offset: offset from where to read 1719 * @len: bytes number to read 1720 * 1721 * Returns zero in case of success, error code in case of fail. 1722 */ 1723 int 1724 ebh_read_leb(struct chfs_ebh *ebh, int lnr, char *buf, uint32_t offset, 1725 size_t len, size_t *retlen) 1726 { 1727 int err, pebnr; 1728 off_t data_offset; 1729 1730 KASSERT(offset + len <= ebh->eb_size); 1731 1732 err = leb_read_lock(ebh, lnr); 1733 if (err) 1734 return err; 1735 1736 pebnr = ebh->lmap[lnr]; 1737 /* If PEB is not mapped the buffer is filled with 0xFF */ 1738 if (EBH_LEB_UNMAPPED == pebnr) { 1739 leb_read_unlock(ebh, lnr); 1740 memset(buf, 0xFF, len); 1741 return 0; 1742 } 1743 1744 /* Read data */ 1745 data_offset = ebh->ops->calc_data_offs(ebh, pebnr, offset); 1746 err = flash_read(ebh->flash_dev, data_offset, len, retlen, 1747 (unsigned char *) buf); 1748 if (err) 1749 goto out_free; 1750 1751 KASSERT(len == *retlen); 1752 1753 out_free: 1754 leb_read_unlock(ebh, lnr); 1755 return err; 1756 } 1757 1758 /** 1759 * get_peb: get a free physical eraseblock 1760 * @ebh - chfs eraseblock handler 1761 * 1762 * This function gets a free eraseblock from the ebh->free RB-tree. 1763 * The first entry will be returned and deleted from the tree. 1764 * The entries sorted by the erase counters, so the PEB with the smallest 1765 * erase counter will be added back. 1766 * If something goes bad a negative value will be returned. 1767 */ 1768 int 1769 get_peb(struct chfs_ebh *ebh) 1770 { 1771 int err, pebnr; 1772 struct chfs_peb *peb; 1773 1774 retry: 1775 mutex_enter(&ebh->erase_lock); 1776 //dbg_ebh("LOCK: ebh->erase_lock spin locked in get_peb()\n"); 1777 if (RB_EMPTY(&ebh->free)) { 1778 /*There is no more free PEBs in the tree*/ 1779 if (TAILQ_EMPTY(&ebh->to_erase) && 1780 TAILQ_EMPTY(&ebh->fully_erased)) { 1781 mutex_exit(&ebh->erase_lock); 1782 //dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in get_peb()\n"); 1783 return ENOSPC; 1784 } 1785 err = free_peb(ebh); 1786 1787 mutex_exit(&ebh->erase_lock); 1788 //dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in get_peb()\n"); 1789 1790 if (err) 1791 return err; 1792 goto retry; 1793 } 1794 peb = RB_MIN(peb_free_rbtree, &ebh->free); 1795 pebnr = peb->pebnr; 1796 RB_REMOVE(peb_free_rbtree, &ebh->free, peb); 1797 err = add_peb_to_in_use(ebh, peb->pebnr, peb->erase_cnt); 1798 if (err) 1799 pebnr = err; 1800 1801 kmem_free(peb, sizeof(struct chfs_peb)); 1802 1803 mutex_exit(&ebh->erase_lock); 1804 //dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in get_peb()\n"); 1805 1806 return pebnr; 1807 } 1808 1809 /** 1810 * ebh_write_leb - write data to leb 1811 * @ebh: eraseblock handler 1812 * @lnr: logical eraseblock number 1813 * @buf: data to write 1814 * @offset: offset where to write 1815 * @len: bytes number to write 1816 * 1817 * Returns zero in case of success, error code in case of fail. 1818 */ 1819 int 1820 ebh_write_leb(struct chfs_ebh *ebh, int lnr, char *buf, uint32_t offset, 1821 size_t len, size_t *retlen) 1822 { 1823 int err, pebnr, retries = 0; 1824 off_t data_offset; 1825 struct chfs_eb_hdr *ebhdr; 1826 1827 dbg("offset: %d | len: %zu | (offset+len): %zu " 1828 " | ebsize: %zu\n", offset, len, (offset+len), ebh->eb_size); 1829 1830 KASSERT(offset + len <= ebh->eb_size); 1831 1832 err = leb_write_lock(ebh, lnr); 1833 if (err) 1834 return err; 1835 1836 pebnr = ebh->lmap[lnr]; 1837 /* If the LEB is mapped write out data */ 1838 if (pebnr != EBH_LEB_UNMAPPED) { 1839 data_offset = ebh->ops->calc_data_offs(ebh, pebnr, offset); 1840 err = flash_write(ebh->flash_dev, data_offset, len, retlen, 1841 (unsigned char *) buf); 1842 1843 if (err) { 1844 chfs_err("error %d while writing %zu bytes to PEB " 1845 "%d:%ju, written %zu bytes\n", 1846 err, len, pebnr, (uintmax_t )offset, *retlen); 1847 } else { 1848 KASSERT(len == *retlen); 1849 } 1850 1851 leb_write_unlock(ebh, lnr); 1852 return err; 1853 } 1854 1855 /* 1856 * If the LEB is unmapped, get a free PEB and write the 1857 * eraseblock header first 1858 */ 1859 ebhdr = kmem_alloc(sizeof(struct chfs_eb_hdr), KM_SLEEP); 1860 1861 /* Setting up eraseblock header properties */ 1862 ebh->ops->create_eb_hdr(ebhdr, lnr); 1863 1864 retry: 1865 /* Getting a physical eraseblock from the wear leveling system */ 1866 pebnr = get_peb(ebh); 1867 if (pebnr < 0) { 1868 leb_write_unlock(ebh, lnr); 1869 kmem_free(ebhdr, sizeof(struct chfs_eb_hdr)); 1870 return pebnr; 1871 } 1872 1873 /* Write the eraseblock header to the media */ 1874 err = ebh->ops->write_eb_hdr(ebh, pebnr, ebhdr); 1875 if (err) { 1876 chfs_warn( 1877 "error writing eraseblock header: LEB %d , PEB %d\n", 1878 lnr, pebnr); 1879 goto write_error; 1880 } 1881 1882 /* Write out data */ 1883 if (len) { 1884 data_offset = ebh->ops->calc_data_offs(ebh, pebnr, offset); 1885 err = flash_write(ebh->flash_dev, 1886 data_offset, len, retlen, (unsigned char *) buf); 1887 if (err) { 1888 chfs_err("error %d while writing %zu bytes to PEB " 1889 " %d:%ju, written %zu bytes\n", 1890 err, len, pebnr, (uintmax_t )offset, *retlen); 1891 goto write_error; 1892 } 1893 } 1894 1895 ebh->lmap[lnr] = pebnr; 1896 leb_write_unlock(ebh, lnr); 1897 kmem_free(ebhdr, sizeof(struct chfs_eb_hdr)); 1898 1899 return 0; 1900 1901 write_error: err = release_peb(ebh, pebnr); 1902 // max retries (NOW: 2) 1903 if (err || CHFS_MAX_GET_PEB_RETRIES < ++retries) { 1904 leb_write_unlock(ebh, lnr); 1905 kmem_free(ebhdr, sizeof(struct chfs_eb_hdr)); 1906 return err; 1907 } 1908 goto retry; 1909 } 1910 1911 /** 1912 * ebh_erase_leb - erase a leb 1913 * @ebh: eraseblock handler 1914 * @lnr: leb number 1915 * 1916 * Returns zero in case of success, error code in case of fail. 1917 */ 1918 int 1919 ebh_erase_leb(struct chfs_ebh *ebh, int lnr) 1920 { 1921 int err, pebnr; 1922 1923 leb_write_lock(ebh, lnr); 1924 1925 pebnr = ebh->lmap[lnr]; 1926 if (pebnr < 0) { 1927 leb_write_unlock(ebh, lnr); 1928 return EBH_LEB_UNMAPPED; 1929 } 1930 err = release_peb(ebh, pebnr); 1931 if (err) 1932 goto out_unlock; 1933 1934 ebh->lmap[lnr] = EBH_LEB_UNMAPPED; 1935 cv_signal(&ebh->bg_erase.eth_wakeup); 1936 out_unlock: 1937 leb_write_unlock(ebh, lnr); 1938 return err; 1939 } 1940 1941 /** 1942 * ebh_map_leb - maps a PEB to LEB 1943 * @ebh: eraseblock handler 1944 * @lnr: leb number 1945 * 1946 * Returns zero on success, error code in case of fail 1947 */ 1948 int 1949 ebh_map_leb(struct chfs_ebh *ebh, int lnr) 1950 { 1951 int err, pebnr, retries = 0; 1952 struct chfs_eb_hdr *ebhdr; 1953 1954 ebhdr = kmem_alloc(sizeof(struct chfs_eb_hdr), KM_SLEEP); 1955 1956 err = leb_write_lock(ebh, lnr); 1957 if (err) { 1958 kmem_free(ebhdr, sizeof(struct chfs_eb_hdr)); 1959 return err; 1960 } 1961 1962 retry: 1963 pebnr = get_peb(ebh); 1964 if (pebnr < 0) { 1965 err = pebnr; 1966 goto out_unlock; 1967 } 1968 1969 ebh->ops->create_eb_hdr(ebhdr, lnr); 1970 1971 err = ebh->ops->write_eb_hdr(ebh, pebnr, ebhdr); 1972 if (err) { 1973 chfs_warn( 1974 "error writing eraseblock header: LEB %d , PEB %d\n", 1975 lnr, pebnr); 1976 goto write_error; 1977 } 1978 1979 ebh->lmap[lnr] = pebnr; 1980 1981 out_unlock: 1982 leb_write_unlock(ebh, lnr); 1983 return err; 1984 1985 write_error: 1986 err = release_peb(ebh, pebnr); 1987 // max retries (NOW: 2) 1988 if (err || CHFS_MAX_GET_PEB_RETRIES < ++retries) { 1989 leb_write_unlock(ebh, lnr); 1990 kmem_free(ebhdr, sizeof(struct chfs_eb_hdr)); 1991 return err; 1992 } 1993 goto retry; 1994 } 1995 1996 /** 1997 * ebh_unmap_leb - 1998 * @ebh: eraseblock handler 1999 * @lnr: leb number 2000 * 2001 * Returns zero on success, error code in case of fail. 2002 */ 2003 int 2004 ebh_unmap_leb(struct chfs_ebh *ebh, int lnr) 2005 { 2006 int err; 2007 2008 if (ebh_is_mapped(ebh, lnr) < 0) 2009 /* If the eraseblock already unmapped */ 2010 return 0; 2011 2012 err = ebh_erase_leb(ebh, lnr); 2013 2014 return err; 2015 } 2016 2017 /** 2018 * ebh_is_mapped - check if a PEB is mapped to @lnr 2019 * @ebh: eraseblock handler 2020 * @lnr: leb number 2021 * 2022 * Returns 0 if the logical eraseblock is mapped, negative error code otherwise. 2023 */ 2024 int 2025 ebh_is_mapped(struct chfs_ebh *ebh, int lnr) 2026 { 2027 int err, result; 2028 err = leb_read_lock(ebh, lnr); 2029 if (err) 2030 return err; 2031 2032 result = ebh->lmap[lnr]; 2033 leb_read_unlock(ebh, lnr); 2034 2035 return result; 2036 } 2037 2038 /** 2039 * ebh_change_leb - write the LEB to another PEB 2040 * @ebh: eraseblock handler 2041 * @lnr: leb number 2042 * @buf: data to write 2043 * @len: length of data 2044 * Returns zero in case of success, error code in case of fail. 2045 */ 2046 int 2047 ebh_change_leb(struct chfs_ebh *ebh, int lnr, char *buf, size_t len, 2048 size_t *retlen) 2049 { 2050 int err, pebnr, pebnr_old, retries = 0; 2051 off_t data_offset; 2052 2053 struct chfs_peb *peb = NULL; 2054 struct chfs_eb_hdr *ebhdr; 2055 2056 if (ebh_is_mapped(ebh, lnr) < 0) 2057 return EBH_LEB_UNMAPPED; 2058 2059 if (len == 0) { 2060 err = ebh_unmap_leb(ebh, lnr); 2061 if (err) 2062 return err; 2063 return ebh_map_leb(ebh, lnr); 2064 } 2065 2066 ebhdr = kmem_alloc(sizeof(struct chfs_eb_hdr), KM_SLEEP); 2067 2068 pebnr_old = ebh->lmap[lnr]; 2069 2070 mutex_enter(&ebh->alc_mutex); 2071 err = leb_write_lock(ebh, lnr); 2072 if (err) 2073 goto out_mutex; 2074 2075 if (ebh->ops->mark_eb_hdr_dirty_flash) { 2076 err = ebh->ops->mark_eb_hdr_dirty_flash(ebh, pebnr_old, lnr); 2077 if (err) 2078 goto out_unlock; 2079 } 2080 2081 /* Setting up eraseblock header properties */ 2082 ebh->ops->create_eb_hdr(ebhdr, lnr); 2083 2084 retry: 2085 /* Getting a physical eraseblock from the wear leveling system */ 2086 pebnr = get_peb(ebh); 2087 if (pebnr < 0) { 2088 leb_write_unlock(ebh, lnr); 2089 mutex_exit(&ebh->alc_mutex); 2090 kmem_free(ebhdr, sizeof(struct chfs_eb_hdr)); 2091 return pebnr; 2092 } 2093 2094 err = ebh->ops->write_eb_hdr(ebh, pebnr, ebhdr); 2095 if (err) { 2096 chfs_warn( 2097 "error writing eraseblock header: LEB %d , PEB %d", 2098 lnr, pebnr); 2099 goto write_error; 2100 } 2101 2102 /* Write out data */ 2103 data_offset = ebh->ops->calc_data_offs(ebh, pebnr, 0); 2104 err = flash_write(ebh->flash_dev, data_offset, len, retlen, 2105 (unsigned char *) buf); 2106 if (err) { 2107 chfs_err("error %d while writing %zu bytes to PEB %d:%ju," 2108 " written %zu bytes", 2109 err, len, pebnr, (uintmax_t)data_offset, *retlen); 2110 goto write_error; 2111 } 2112 2113 ebh->lmap[lnr] = pebnr; 2114 2115 if (ebh->ops->invalidate_eb_hdr) { 2116 err = ebh->ops->invalidate_eb_hdr(ebh, pebnr_old); 2117 if (err) 2118 goto out_unlock; 2119 } 2120 peb = find_peb_in_use(ebh, pebnr_old); 2121 err = release_peb(ebh, peb->pebnr); 2122 2123 out_unlock: 2124 leb_write_unlock(ebh, lnr); 2125 2126 out_mutex: 2127 mutex_exit(&ebh->alc_mutex); 2128 kmem_free(ebhdr, sizeof(struct chfs_eb_hdr)); 2129 kmem_free(peb, sizeof(struct chfs_peb)); 2130 return err; 2131 2132 write_error: 2133 err = release_peb(ebh, pebnr); 2134 //max retries (NOW: 2) 2135 if (err || CHFS_MAX_GET_PEB_RETRIES < ++retries) { 2136 leb_write_unlock(ebh, lnr); 2137 mutex_exit(&ebh->alc_mutex); 2138 kmem_free(ebhdr, sizeof(struct chfs_eb_hdr)); 2139 return err; 2140 } 2141 goto retry; 2142 } 2143 2144