1 /* $NetBSD: ebh.c,v 1.6 2015/02/07 04:21:11 christos Exp $ */
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.
13 * This code is derived from software contributed to The NetBSD Foundation
14 * by the Department of Software Engineering, University of Szeged, Hungary
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
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.
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
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
);
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
);
82 * nor_create_eb_hdr - creates an eraseblock header for NOR flash
83 * @ebhdr: ebhdr to set
87 nor_create_eb_hdr(struct chfs_eb_hdr
*ebhdr
, int lnr
)
89 ebhdr
->u
.nor_hdr
.lid
= htole32(lnr
);
94 * nand_create_eb_hdr - creates an eraseblock header for NAND flash
95 * @ebhdr: ebhdr to set
99 nand_create_eb_hdr(struct chfs_eb_hdr
*ebhdr
, int lnr
)
101 ebhdr
->u
.nand_hdr
.lid
= htole32(lnr
);
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
112 nor_calc_data_offs(struct chfs_ebh
*ebh
, int pebnr
, int offset
)
114 return pebnr
* ebh
->flash_if
->erasesize
+ offset
+
115 CHFS_EB_EC_HDR_SIZE
+ CHFS_EB_HDR_NOR_SIZE
;
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
125 nand_calc_data_offs(struct chfs_ebh
*ebh
, int pebnr
, int offset
)
127 return pebnr
* ebh
->flash_if
->erasesize
+ offset
+
128 2 * ebh
->flash_if
->page_size
;
132 * nor_read_eb_hdr - read ereaseblock header from NOR flash
134 * @ebh: chfs eraseblock handler
135 * @pebnr: eraseblock number
136 * @ebhdr: whereto store the data
138 * Reads the eraseblock header from media.
139 * Returns zero in case of success, error code in case of fail.
142 nor_read_eb_hdr(struct chfs_ebh
*ebh
,
143 int pebnr
, struct chfs_eb_hdr
*ebhdr
)
147 off_t ofs
= pebnr
* ebh
->flash_if
->erasesize
;
149 KASSERT(pebnr
>= 0 && pebnr
< ebh
->peb_nr
);
151 ret
= flash_read(ebh
->flash_dev
,
152 ofs
, CHFS_EB_EC_HDR_SIZE
,
153 &retlen
, (unsigned char *) &ebhdr
->ec_hdr
);
155 if (ret
|| retlen
!= CHFS_EB_EC_HDR_SIZE
)
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
);
163 if (ret
|| retlen
!= CHFS_EB_HDR_NOR_SIZE
)
170 * nand_read_eb_hdr - read ereaseblock header from NAND flash
172 * @ebh: chfs eraseblock handler
173 * @pebnr: eraseblock number
174 * @ebhdr: whereto store the data
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.
180 nand_read_eb_hdr(struct chfs_ebh
*ebh
, int pebnr
,
181 struct chfs_eb_hdr
*ebhdr
)
187 KASSERT(pebnr
>= 0 && pebnr
< ebh
->peb_nr
);
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
)
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
)
209 * nor_write_eb_hdr - write ereaseblock header to NOR flash
211 * @ebh: chfs eraseblock handler
212 * @pebnr: eraseblock number whereto write
215 * Writes the eraseblock header to media.
216 * Returns zero in case of success, error code in case of fail.
219 nor_write_eb_hdr(struct chfs_ebh
*ebh
, int pebnr
, struct chfs_eb_hdr
*ebhdr
)
224 off_t ofs
= pebnr
* ebh
->flash_if
->erasesize
+ CHFS_EB_EC_HDR_SIZE
;
226 ebhdr
->u
.nor_hdr
.lid
= ebhdr
->u
.nor_hdr
.lid
227 | htole32(CHFS_LID_NOT_DIRTY_BIT
);
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
);
233 KASSERT(pebnr
>= 0 && pebnr
< ebh
->peb_nr
);
235 ret
= flash_write(ebh
->flash_dev
,
236 ofs
, CHFS_EB_HDR_NOR_SIZE
, &retlen
,
237 (unsigned char *) &ebhdr
->u
.nor_hdr
);
239 if (ret
|| retlen
!= CHFS_EB_HDR_NOR_SIZE
)
246 * nand_write_eb_hdr - write ereaseblock header to NAND flash
248 * @ebh: chfs eraseblock handler
249 * @pebnr: eraseblock number whereto write
252 * Writes the eraseblock header to media.
253 * Returns zero in case of success, error code in case of fail.
256 nand_write_eb_hdr(struct chfs_ebh
*ebh
, int pebnr
,
257 struct chfs_eb_hdr
*ebhdr
)
263 KASSERT(pebnr
>= 0 && pebnr
< ebh
->peb_nr
);
265 ofs
= pebnr
* ebh
->flash_if
->erasesize
+
266 ebh
->flash_if
->page_size
;
268 ebhdr
->u
.nand_hdr
.serial
= htole64(++(*ebh
->max_serial
));
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
);
274 ret
= flash_write(ebh
->flash_dev
, ofs
,
275 CHFS_EB_HDR_NAND_SIZE
, &retlen
,
276 (unsigned char *) &ebhdr
->u
.nand_hdr
);
278 if (ret
|| retlen
!= CHFS_EB_HDR_NAND_SIZE
)
285 * nor_check_eb_hdr - check ereaseblock header read from NOR flash
287 * @ebh: chfs eraseblock handler
288 * @buf: eraseblock header to check
290 * Returns eraseblock header status.
293 nor_check_eb_hdr(struct chfs_ebh
*ebh
, void *buf
)
295 uint32_t magic
, crc
, hdr_crc
;
296 struct chfs_eb_hdr
*ebhdr
= buf
;
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
;
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
;
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
;
322 /* check if the PEB is free: magic, crc_ec and erase_cnt is good and
323 * everything else is FFF..
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
;
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
;
338 hdr_crc
= le32toh(ebhdr
->u
.nor_hdr
.crc
);
339 lid_save
= ebhdr
->u
.nor_hdr
.lid
;
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
;
349 if (crc
!= hdr_crc
) {
350 dbg_ebh("bad crc found\n");
351 return EBHDR_LEB_BADCRC
;
355 if (!(le32toh(lid_save
) & CHFS_LID_NOT_DIRTY_BIT
)) {
356 dbg_ebh("dirty ebhdr found\n");
357 return EBHDR_LEB_DIRTY
;
364 * nand_check_eb_hdr - check ereaseblock header read from NAND flash
366 * @ebh: chfs eraseblock handler
367 * @buf: eraseblock header to check
369 * Returns eraseblock header status.
372 nand_check_eb_hdr(struct chfs_ebh
*ebh
, void *buf
)
374 uint32_t magic
, crc
, hdr_crc
;
375 struct chfs_eb_hdr
*ebhdr
= buf
;
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
;
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
;
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
;
400 /* check if the PEB is free: magic, crc_ec and erase_cnt is good and
401 * everything else is FFF..
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
;
410 hdr_crc
= le32toh(ebhdr
->u
.nand_hdr
.crc
);
412 crc
= crc32(0, (uint8_t *) &ebhdr
->u
.nand_hdr
+ 4,
413 CHFS_EB_HDR_NAND_SIZE
- 4);
415 if (crc
!= hdr_crc
) {
416 dbg_ebh("bad crc found\n");
417 return EBHDR_LEB_BADCRC
;
424 * nor_mark_eb_hdr_dirty_flash- mark ereaseblock header dirty on NOR flash
426 * @ebh: chfs eraseblock handler
427 * @pebnr: eraseblock number
428 * @lid: leb id (its bit number 31 will be set to 0)
430 * It pulls the CHFS_LID_NOT_DIRTY_BIT to zero on flash.
432 * Returns zero in case of success, error code in case of fail.
435 nor_mark_eb_hdr_dirty_flash(struct chfs_ebh
*ebh
, int pebnr
, int lid
)
441 /* mark leb id dirty */
442 lid
= htole32(lid
& CHFS_LID_DIRTY_BIT_MASK
);
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
);
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");
459 * nor_invalidate_eb_hdr - invalidate ereaseblock header on NOR flash
461 * @ebh: chfs eraseblock handler
462 * @pebnr: eraseblock number
464 * Sets crc and lip field to zero.
465 * Returns zero in case of success, error code in case of fail.
468 nor_invalidate_eb_hdr(struct chfs_ebh
*ebh
, int pebnr
)
473 char zero_buf
[CHFS_INVALIDATE_SIZE
];
476 memset(zero_buf
, 0x0, CHFS_INVALIDATE_SIZE
);
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
);
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");
494 * mark_eb_hdr_free - free ereaseblock header on NOR or NAND flash
496 * @ebh: chfs eraseblock handler
497 * @pebnr: eraseblock number
498 * @ec: erase counter of PEB
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.
504 mark_eb_hdr_free(struct chfs_ebh
*ebh
, int pebnr
, int ec
)
509 struct chfs_eb_hdr
*ebhdr
;
510 ebhdr
= kmem_alloc(sizeof(struct chfs_eb_hdr
), KM_SLEEP
);
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
);
517 ofs
= pebnr
* ebh
->flash_if
->erasesize
;
519 KASSERT(sizeof(ebhdr
->ec_hdr
) == CHFS_EB_EC_HDR_SIZE
);
521 ret
= flash_write(ebh
->flash_dev
,
522 ofs
, CHFS_EB_EC_HDR_SIZE
, &retlen
,
523 (unsigned char *) &ebhdr
->ec_hdr
);
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
));
531 kmem_free(ebhdr
, sizeof(struct chfs_eb_hdr
));
535 /*****************************************************************************/
536 /* End of Flash specific operations */
537 /*****************************************************************************/
539 /*****************************************************************************/
541 /*****************************************************************************/
544 ltree_entry_cmp(struct chfs_ltree_entry
*le1
,
545 struct chfs_ltree_entry
*le2
)
547 return (le1
->lnr
- le2
->lnr
);
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
);
556 * ltree_lookup - looks up a logical eraseblock in the lock tree
557 * @ebh: chfs eraseblock handler
558 * @lid: identifier of the logical eraseblock
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
563 * @ebh->ltree_lock has to be locked!
565 static struct chfs_ltree_entry
*
566 ltree_lookup(struct chfs_ebh
*ebh
, int lnr
)
568 struct chfs_ltree_entry le
, *result
;
570 result
= RB_FIND(ltree_rbtree
, &ebh
->ltree
, &le
);
575 * ltree_add_entry - add an entry to the lock tree
576 * @ebh: chfs eraseblock handler
577 * @lnr: identifier of the logical eraseblock
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
582 * Returns NULL if can not allocate memory for lock tree entry, or a pointer
583 * to the inserted entry otherwise.
585 static struct chfs_ltree_entry
*
586 ltree_add_entry(struct chfs_ebh
*ebh
, int lnr
)
588 struct chfs_ltree_entry
*le
, *result
;
590 le
= kmem_alloc(sizeof(struct chfs_ltree_entry
), KM_SLEEP
);
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");
602 //The entry is already in the tree
604 kmem_free(le
, sizeof(struct chfs_ltree_entry
));
609 mutex_exit(&ebh
->ltree_lock
);
615 * leb_read_lock - lock a logical eraseblock for read
616 * @ebh: chfs eraseblock handler
617 * @lnr: identifier of the logical eraseblock
619 * Returns zero in case of success, error code in case of fail.
622 leb_read_lock(struct chfs_ebh
*ebh
, int lnr
)
624 struct chfs_ltree_entry
*le
;
626 le
= ltree_add_entry(ebh
, lnr
);
630 rw_enter(&le
->mutex
, RW_READER
);
635 * leb_read_unlock - unlock a logical eraseblock from read
636 * @ebh: chfs eraseblock handler
637 * @lnr: identifier of the logical eraseblock
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.
643 leb_read_unlock(struct chfs_ebh
*ebh
, int lnr
)
645 struct chfs_ltree_entry
*le
;
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
);
654 KASSERT(le
->users
>= 0);
656 if (le
->users
== 0) {
657 le
= RB_REMOVE(ltree_rbtree
, &ebh
->ltree
, le
);
659 KASSERT(!rw_lock_held(&le
->mutex
));
660 rw_destroy(&le
->mutex
);
662 kmem_free(le
, sizeof(struct chfs_ltree_entry
));
667 mutex_exit(&ebh
->ltree_lock
);
668 //dbg_ebh("UNLOCK: ebh->ltree_lock spin unlocked in leb_read_unlock()\n");
672 * leb_write_lock - lock a logical eraseblock for write
673 * @ebh: chfs eraseblock handler
674 * @lnr: identifier of the logical eraseblock
676 * Returns zero in case of success, error code in case of fail.
679 leb_write_lock(struct chfs_ebh
*ebh
, int lnr
)
681 struct chfs_ltree_entry
*le
;
683 le
= ltree_add_entry(ebh
, lnr
);
687 rw_enter(&le
->mutex
, RW_WRITER
);
692 * leb_write_unlock - unlock a logical eraseblock from write
693 * @ebh: chfs eraseblock handler
694 * @lnr: identifier of the logical eraseblock
696 * This function unlocks a logical eraseblock from write and delete it from the
697 * lock tree is there are no more users of it.
700 leb_write_unlock(struct chfs_ebh
*ebh
, int lnr
)
702 struct chfs_ltree_entry
*le
;
704 mutex_enter(&ebh
->ltree_lock
);
705 //dbg_ebh("LOCK: ebh->ltree_lock spin locked in leb_write_unlock()\n");
706 le
= ltree_lookup(ebh
, lnr
);
711 KASSERT(le
->users
>= 0);
713 if (le
->users
== 0) {
714 RB_REMOVE(ltree_rbtree
, &ebh
->ltree
, le
);
716 KASSERT(!rw_lock_held(&le
->mutex
));
717 rw_destroy(&le
->mutex
);
719 kmem_free(le
, sizeof(struct chfs_ltree_entry
));
723 mutex_exit(&ebh
->ltree_lock
);
724 //dbg_ebh("UNLOCK: ebh->ltree_lock spin unlocked in leb_write_unlock()\n");
727 /*****************************************************************************/
728 /* End of Lock Tree */
729 /*****************************************************************************/
731 /*****************************************************************************/
732 /* Erase related operations */
733 /*****************************************************************************/
736 * If the first argument is smaller than the second, the function
737 * returns a value smaller than zero. If they are equal, the function re-
738 * turns zero. Otherwise, it should return a value greater than zero.
741 peb_in_use_cmp(struct chfs_peb
*peb1
, struct chfs_peb
*peb2
)
743 return (peb1
->pebnr
- peb2
->pebnr
);
747 peb_free_cmp(struct chfs_peb
*peb1
, struct chfs_peb
*peb2
)
751 comp
= peb1
->erase_cnt
- peb2
->erase_cnt
;
753 comp
= peb1
->pebnr
- peb2
->pebnr
;
758 /* Generate functions for in use PEB's red-black tree */
759 RB_PROTOTYPE(peb_in_use_rbtree
, chfs_peb
, u
.rb
, peb_in_use_cmp
);
760 RB_GENERATE(peb_in_use_rbtree
, chfs_peb
, u
.rb
, peb_in_use_cmp
);
761 RB_PROTOTYPE(peb_free_rbtree
, chfs_peb
, u
.rb
, peb_free_cmp
);
762 RB_GENERATE(peb_free_rbtree
, chfs_peb
, u
.rb
, peb_free_cmp
);
765 * add_peb_to_erase_queue: adds a PEB to to_erase/fully_erased queue
766 * @ebh - chfs eraseblock handler
767 * @pebnr - physical eraseblock's number
768 * @ec - erase counter of PEB
769 * @queue: the queue to add to
771 * This function adds a PEB to the erase queue specified by @queue.
772 * The @ebh->erase_lock must be locked before using this.
773 * Returns zero in case of success, error code in case of fail.
776 add_peb_to_erase_queue(struct chfs_ebh
*ebh
, int pebnr
, int ec
,
777 struct peb_queue
*queue
)
779 struct chfs_peb
*peb
;
781 peb
= kmem_alloc(sizeof(struct chfs_peb
), KM_SLEEP
);
786 TAILQ_INSERT_TAIL(queue
, peb
, u
.queue
);
793 * find_peb_in_use - looks up a PEB in the RB-tree of used blocks
794 * @ebh - chfs eraseblock handler
796 * This function returns a pointer to the PEB found in the tree,
798 * The @ebh->erase_lock must be locked before using this.
801 find_peb_in_use(struct chfs_ebh
*ebh
, int pebnr
)
803 struct chfs_peb peb
, *result
;
805 result
= RB_FIND(peb_in_use_rbtree
, &ebh
->in_use
, &peb
);
810 * add_peb_to_free - adds a PEB to the RB-tree of free PEBs
811 * @ebh - chfs eraseblock handler
812 * @pebnr - physical eraseblock's number
813 * @ec - erase counter of PEB
816 * This function adds a physical eraseblock to the RB-tree of free PEBs
817 * stored in the @ebh. The key is the erase counter and pebnr.
818 * The @ebh->erase_lock must be locked before using this.
819 * Returns zero in case of success, error code in case of fail.
822 add_peb_to_free(struct chfs_ebh
*ebh
, int pebnr
, int ec
)
824 struct chfs_peb
*peb
, *result
;
826 peb
= kmem_alloc(sizeof(struct chfs_peb
), KM_SLEEP
);
830 result
= RB_INSERT(peb_free_rbtree
, &ebh
->free
, peb
);
832 kmem_free(peb
, sizeof(struct chfs_peb
));
840 * add_peb_to_in_use - adds a PEB to the RB-tree of used PEBs
841 * @ebh - chfs eraseblock handler
842 * @pebnr - physical eraseblock's number
843 * @ec - erase counter of PEB
846 * This function adds a physical eraseblock to the RB-tree of used PEBs
847 * stored in the @ebh. The key is pebnr.
848 * The @ebh->erase_lock must be locked before using this.
849 * Returns zero in case of success, error code in case of fail.
852 add_peb_to_in_use(struct chfs_ebh
*ebh
, int pebnr
, int ec
)
854 struct chfs_peb
*peb
, *result
;
856 peb
= kmem_alloc(sizeof(struct chfs_peb
), KM_SLEEP
);
860 result
= RB_INSERT(peb_in_use_rbtree
, &ebh
->in_use
, peb
);
862 kmem_free(peb
, sizeof(struct chfs_peb
));
870 * erase_callback - callback function for flash erase
871 * @ei: erase information
874 erase_callback(struct flash_erase_instruction
*ei
)
877 struct chfs_erase_info_priv
*priv
= (void *) ei
->ei_priv
;
878 //dbg_ebh("ERASE_CALLBACK() CALLED\n");
879 struct chfs_ebh
*ebh
= priv
->ebh
;
880 struct chfs_peb
*peb
= priv
->peb
;
884 if (ei
->ei_state
== FLASH_ERASE_DONE
) {
886 /* Write out erase counter */
887 err
= ebh
->ops
->mark_eb_hdr_free(ebh
,
888 peb
->pebnr
, peb
->erase_cnt
);
890 /* cannot mark PEB as free,so erase it again */
892 "cannot mark eraseblock as free, PEB: %d\n",
894 mutex_enter(&ebh
->erase_lock
);
895 /*dbg_ebh("LOCK: ebh->erase_lock spin locked in erase_callback() "
896 "after mark ebhdr free\n");*/
897 add_peb_to_erase_queue(ebh
, peb
->pebnr
, peb
->erase_cnt
,
899 mutex_exit(&ebh
->erase_lock
);
900 /*dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in erase_callback() "
901 "after mark ebhdr free\n");*/
902 kmem_free(peb
, sizeof(struct chfs_peb
));
906 mutex_enter(&ebh
->erase_lock
);
907 /*dbg_ebh("LOCK: ebh->erase_lock spin locked in erase_callback()\n");*/
908 err
= add_peb_to_free(ebh
, peb
->pebnr
, peb
->erase_cnt
);
909 mutex_exit(&ebh
->erase_lock
);
910 /*dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in erase_callback()\n");*/
911 kmem_free(peb
, sizeof(struct chfs_peb
));
914 * Erase is finished, but there was a problem,
917 chfs_err("erase failed, state is: 0x%x\n", ei
->ei_state
);
918 add_peb_to_erase_queue(ebh
, peb
->pebnr
, peb
->erase_cnt
, &ebh
->to_erase
);
919 kmem_free(peb
, sizeof(struct chfs_peb
));
924 * free_peb: free a PEB
925 * @ebh: chfs eraseblock handler
927 * This function erases the first physical eraseblock from one of the erase
928 * lists and adds to the RB-tree of free PEBs.
929 * Returns zero in case of succes, error code in case of fail.
932 free_peb(struct chfs_ebh
*ebh
)
934 int err
, retries
= 0;
936 struct chfs_peb
*peb
= NULL
;
937 struct flash_erase_instruction
*ei
;
939 KASSERT(mutex_owned(&ebh
->erase_lock
));
941 if (!TAILQ_EMPTY(&ebh
->fully_erased
)) {
942 //dbg_ebh("[FREE PEB] got a fully erased block\n");
943 peb
= TAILQ_FIRST(&ebh
->fully_erased
);
944 TAILQ_REMOVE(&ebh
->fully_erased
, peb
, u
.queue
);
945 err
= ebh
->ops
->mark_eb_hdr_free(ebh
,
946 peb
->pebnr
, peb
->erase_cnt
);
950 err
= add_peb_to_free(ebh
, peb
->pebnr
, peb
->erase_cnt
);
954 //dbg_ebh("[FREE PEB] eraseing a block\n");
955 peb
= TAILQ_FIRST(&ebh
->to_erase
);
956 TAILQ_REMOVE(&ebh
->to_erase
, peb
, u
.queue
);
957 mutex_exit(&ebh
->erase_lock
);
958 //dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in free_peb()\n");
959 ofs
= peb
->pebnr
* ebh
->flash_if
->erasesize
;
961 /* XXX where do we free this? */
962 ei
= kmem_alloc(sizeof(struct flash_erase_instruction
)
963 + sizeof(struct chfs_erase_info_priv
), KM_SLEEP
);
965 memset(ei
, 0, sizeof(*ei
));
967 // ei->ei_if = ebh->flash_if;
969 ei
->ei_len
= ebh
->flash_if
->erasesize
;
970 ei
->ei_callback
= erase_callback
;
971 ei
->ei_priv
= (unsigned long) (&ei
[1]);
973 ((struct chfs_erase_info_priv
*) ei
->ei_priv
)->ebh
= ebh
;
974 ((struct chfs_erase_info_priv
*) ei
->ei_priv
)->peb
= peb
;
976 err
= flash_erase(ebh
->flash_dev
, ei
);
977 dbg_ebh("erased peb: %d\n", peb
->pebnr
);
979 /* einval would mean we did something wrong */
980 KASSERT(err
!= EINVAL
);
983 dbg_ebh("errno: %d, ei->ei_state: %d\n", err
, ei
->ei_state
);
984 if (CHFS_MAX_GET_PEB_RETRIES
< ++retries
&&
985 ei
->ei_state
== FLASH_ERASE_FAILED
) {
986 /* The block went bad mark it */
987 dbg_ebh("ebh markbad! 0x%jx\n", (uintmax_t )ofs
);
988 err
= flash_block_markbad(ebh
->flash_dev
, ofs
);
995 chfs_err("can not erase PEB: %d, try again\n", peb
->pebnr
);
1000 /* lock the erase_lock, because it was locked
1001 * when the function was called */
1002 mutex_enter(&ebh
->erase_lock
);
1006 kmem_free(peb
, sizeof(struct chfs_peb
));
1011 * release_peb - schedule an erase for the PEB
1012 * @ebh: chfs eraseblock handler
1013 * @pebnr: physical eraseblock number
1015 * This function get the peb identified by @pebnr from the in_use RB-tree of
1016 * @ebh, removes it and schedule an erase for it.
1018 * Returns zero on success, error code in case of fail.
1021 release_peb(struct chfs_ebh
*ebh
, int pebnr
)
1024 struct chfs_peb
*peb
;
1026 mutex_enter(&ebh
->erase_lock
);
1028 //dbg_ebh("LOCK: ebh->erase_lock spin locked in release_peb()\n");
1029 peb
= find_peb_in_use(ebh
, pebnr
);
1031 chfs_err("LEB is mapped, but is not in the 'in_use' "
1035 err
= add_peb_to_erase_queue(ebh
, peb
->pebnr
, peb
->erase_cnt
,
1041 RB_REMOVE(peb_in_use_rbtree
, &ebh
->in_use
, peb
);
1043 mutex_exit(&ebh
->erase_lock
);
1044 //dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in release_peb()"
1045 // " at out_unlock\n");
1050 * erase_thread - background thread for erasing PEBs
1051 * @data: pointer to the eraseblock handler
1054 erase_thread(void *data)
1056 struct chfs_ebh *ebh = data;
1058 dbg_ebh("erase thread started\n");
1059 while (ebh->bg_erase.eth_running) {
1062 mutex_enter(&ebh->erase_lock);
1063 dbg_ebh("LOCK: ebh->erase_lock spin locked in erase_thread()\n");
1064 if (TAILQ_EMPTY(&ebh->to_erase) && TAILQ_EMPTY(&ebh->fully_erased)) {
1065 dbg_ebh("thread has nothing to do\n");
1066 mutex_exit(&ebh->erase_lock);
1067 mutex_enter(&ebh->bg_erase.eth_thread_mtx);
1068 cv_timedwait_sig(&ebh->bg_erase.eth_wakeup,
1069 &ebh->bg_erase.eth_thread_mtx, mstohz(100));
1070 mutex_exit(&ebh->bg_erase.eth_thread_mtx);
1072 dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in erase_thread()\n");
1075 mutex_exit(&ebh->erase_lock);
1076 dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in erase_thread()\n");
1078 err = free_peb(ebh);
1080 chfs_err("freeing PEB failed in the background thread: %d\n", err);
1083 dbg_ebh("erase thread stopped\n");
1088 * erase_thread - background thread for erasing PEBs
1089 * @data: pointer to the eraseblock handler
1092 erase_thread(void *data
) {
1093 dbg_ebh("[EBH THREAD] erase thread started\n");
1095 struct chfs_ebh
*ebh
= data
;
1098 mutex_enter(&ebh
->erase_lock
);
1099 while (ebh
->bg_erase
.eth_running
) {
1100 if (TAILQ_EMPTY(&ebh
->to_erase
) &&
1101 TAILQ_EMPTY(&ebh
->fully_erased
)) {
1102 cv_timedwait_sig(&ebh
->bg_erase
.eth_wakeup
,
1103 &ebh
->erase_lock
, mstohz(100));
1105 /* XXX exiting this mutex is a bit odd here as
1106 * free_peb instantly reenters it...
1108 err
= free_peb(ebh
);
1109 mutex_exit(&ebh
->erase_lock
);
1111 chfs_err("freeing PEB failed in the"
1112 " background thread: %d\n", err
);
1114 mutex_enter(&ebh
->erase_lock
);
1117 mutex_exit(&ebh
->erase_lock
);
1119 dbg_ebh("[EBH THREAD] erase thread stopped\n");
1124 * erase_thread_start - init and start erase thread
1125 * @ebh: eraseblock handler
1128 erase_thread_start(struct chfs_ebh
*ebh
)
1130 cv_init(&ebh
->bg_erase
.eth_wakeup
, "ebheracv");
1132 ebh
->bg_erase
.eth_running
= true;
1133 kthread_create(PRI_NONE
, KTHREAD_MPSAFE
| KTHREAD_MUSTJOIN
, NULL
,
1134 erase_thread
, ebh
, &ebh
->bg_erase
.eth_thread
, "ebherase");
1138 * erase_thread_stop - stop background erase thread
1139 * @ebh: eraseblock handler
1142 erase_thread_stop(struct chfs_ebh
*ebh
)
1144 ebh
->bg_erase
.eth_running
= false;
1145 cv_signal(&ebh
->bg_erase
.eth_wakeup
);
1146 dbg_ebh("[EBH THREAD STOP] signaled\n");
1148 kthread_join(ebh
->bg_erase
.eth_thread
);
1149 #ifdef BROKEN_KTH_JOIN
1150 kpause("chfsebhjointh", false, mstohz(1000), NULL
);
1153 cv_destroy(&ebh
->bg_erase
.eth_wakeup
);
1156 /*****************************************************************************/
1157 /* End of Erase related operations */
1158 /*****************************************************************************/
1160 /*****************************************************************************/
1161 /* Scan related operations */
1162 /*****************************************************************************/
1164 scan_leb_used_cmp(struct chfs_scan_leb
*sleb1
, struct chfs_scan_leb
*sleb2
)
1166 return (sleb1
->lnr
- sleb2
->lnr
);
1169 RB_PROTOTYPE(scan_leb_used_rbtree
, chfs_scan_leb
, u
.rb
, scan_leb_used_cmp
);
1170 RB_GENERATE(scan_leb_used_rbtree
, chfs_scan_leb
, u
.rb
, scan_leb_used_cmp
);
1173 * scan_add_to_queue - adds a physical eraseblock to one of the
1175 * @si: chfs scanning information
1176 * @pebnr: physical eraseblock number
1177 * @erase_cnt: erase counter of the physical eraseblock
1178 * @list: the list to add to
1180 * This function adds a physical eraseblock to one of the lists in the scanning
1182 * Returns zero in case of success, negative error code in case of fail.
1185 scan_add_to_queue(struct chfs_scan_info
*si
, int pebnr
, int erase_cnt
,
1186 struct scan_leb_queue
*queue
)
1188 struct chfs_scan_leb
*sleb
;
1190 sleb
= kmem_alloc(sizeof(struct chfs_scan_leb
), KM_SLEEP
);
1192 sleb
->pebnr
= pebnr
;
1193 sleb
->erase_cnt
= erase_cnt
;
1194 TAILQ_INSERT_TAIL(queue
, sleb
, u
.queue
);
1199 * nor_scan_add_to_used - add a physical eraseblock to the
1200 * used tree of scan info
1201 * @ebh: chfs eraseblock handler
1202 * @si: chfs scanning information
1203 * @ebhdr: eraseblock header
1204 * @pebnr: physical eraseblock number
1205 * @leb_status: the status of the PEB's eraseblock header
1207 * This function adds a PEB to the used tree of the scanning information.
1208 * It handles the situations if there are more physical eraseblock referencing
1209 * to the same logical eraseblock.
1210 * Returns zero in case of success, error code in case of fail.
1213 nor_scan_add_to_used(struct chfs_ebh
*ebh
, struct chfs_scan_info
*si
,
1214 struct chfs_eb_hdr
*ebhdr
, int pebnr
, int leb_status
)
1217 struct chfs_scan_leb
*sleb
, *old
;
1219 lnr
= CHFS_GET_LID(ebhdr
->u
.nor_hdr
.lid
);
1220 ec
= le32toh(ebhdr
->ec_hdr
.erase_cnt
);
1222 sleb
= kmem_alloc(sizeof(struct chfs_scan_leb
), KM_SLEEP
);
1224 sleb
->erase_cnt
= ec
;
1226 sleb
->pebnr
= pebnr
;
1227 sleb
->info
= leb_status
;
1229 old
= RB_INSERT(scan_leb_used_rbtree
, &si
->used
, sleb
);
1231 kmem_free(sleb
, sizeof(struct chfs_scan_leb
));
1232 /* There is already an eraseblock in the used tree */
1233 /* If the new one is bad */
1234 if (EBHDR_LEB_DIRTY
== leb_status
&&
1235 EBHDR_LEB_OK
== old
->info
) {
1236 return scan_add_to_queue(si
, pebnr
, ec
, &si
->erase
);
1238 err
= scan_add_to_queue(si
, old
->pebnr
,
1239 old
->erase_cnt
, &si
->erase
);
1244 old
->erase_cnt
= ec
;
1247 old
->info
= leb_status
;
1255 * nor_process eb -read the headers from NOR flash, check them and add to
1256 * the scanning information
1257 * @ebh: chfs eraseblock handler
1258 * @si: chfs scanning information
1259 * @pebnr: physical eraseblock number
1261 * Returns zero in case of success, error code in case of fail.
1264 nor_process_eb(struct chfs_ebh
*ebh
, struct chfs_scan_info
*si
,
1265 int pebnr
, struct chfs_eb_hdr
*ebhdr
)
1267 int err
, erase_cnt
, leb_status
;
1269 err
= ebh
->ops
->read_eb_hdr(ebh
, pebnr
, ebhdr
);
1273 erase_cnt
= le32toh(ebhdr
->ec_hdr
.erase_cnt
);
1274 dbg_ebh("erase_cnt: %d\n", erase_cnt
);
1275 leb_status
= ebh
->ops
->check_eb_hdr(ebh
, ebhdr
);
1276 if (EBHDR_LEB_BADMAGIC
== leb_status
||
1277 EBHDR_LEB_BADCRC
== leb_status
) {
1278 err
= scan_add_to_queue(si
, pebnr
, erase_cnt
, &si
->corrupted
);
1281 else if (EBHDR_LEB_FREE
== leb_status
) {
1282 err
= scan_add_to_queue(si
, pebnr
, erase_cnt
, &si
->free
);
1285 else if (EBHDR_LEB_NO_HDR
== leb_status
) {
1286 err
= scan_add_to_queue(si
, pebnr
, erase_cnt
, &si
->erased
);
1289 else if (EBHDR_LEB_INVALIDATED
== leb_status
) {
1290 err
= scan_add_to_queue(si
, pebnr
, erase_cnt
, &si
->erase
);
1294 err
= nor_scan_add_to_used(ebh
, si
, ebhdr
, pebnr
, leb_status
);
1300 si
->sum_of_ec
+= erase_cnt
;
1307 * nand_scan_add_to_used - add a physical eraseblock to the
1308 * used tree of scan info
1309 * @ebh: chfs eraseblock handler
1310 * @si: chfs scanning information
1311 * @ebhdr: eraseblock header
1312 * @pebnr: physical eraseblock number
1313 * @leb_status: the status of the PEB's eraseblock header
1315 * This function adds a PEB to the used tree of the scanning information.
1316 * It handles the situations if there are more physical eraseblock referencing
1317 * to the same logical eraseblock.
1318 * Returns zero in case of success, error code in case of fail.
1321 nand_scan_add_to_used(struct chfs_ebh
*ebh
, struct chfs_scan_info
*si
,
1322 struct chfs_eb_hdr
*ebhdr
, int pebnr
)
1325 struct chfs_scan_leb
*sleb
, *old
;
1326 uint64_t serial
= le64toh(ebhdr
->u
.nand_hdr
.serial
);
1328 lnr
= CHFS_GET_LID(ebhdr
->u
.nor_hdr
.lid
);
1329 ec
= le32toh(ebhdr
->ec_hdr
.erase_cnt
);
1331 sleb
= kmem_alloc(sizeof(struct chfs_scan_leb
), KM_SLEEP
);
1333 sleb
->erase_cnt
= ec
;
1335 sleb
->pebnr
= pebnr
;
1336 sleb
->info
= serial
;
1338 old
= RB_INSERT(scan_leb_used_rbtree
, &si
->used
, sleb
);
1340 kmem_free(sleb
, sizeof(struct chfs_scan_leb
));
1341 /* There is already an eraseblock in the used tree */
1342 /* If the new one is bad */
1343 if (serial
< old
->info
)
1344 return scan_add_to_queue(si
, pebnr
, ec
, &si
->erase
);
1346 err
= scan_add_to_queue(si
,
1347 old
->pebnr
, old
->erase_cnt
, &si
->erase
);
1351 old
->erase_cnt
= ec
;
1362 * nand_process eb -read the headers from NAND flash, check them and add to the
1363 * scanning information
1364 * @ebh: chfs eraseblock handler
1365 * @si: chfs scanning information
1366 * @pebnr: physical eraseblock number
1368 * Returns zero in case of success, error code in case of fail.
1371 nand_process_eb(struct chfs_ebh
*ebh
, struct chfs_scan_info
*si
,
1372 int pebnr
, struct chfs_eb_hdr
*ebhdr
)
1374 int err
, erase_cnt
, leb_status
;
1375 uint64_t max_serial
;
1376 /* isbad() is defined on some ancient platforms, heh */
1379 /* Check block is bad */
1380 err
= flash_block_isbad(ebh
->flash_dev
,
1381 pebnr
* ebh
->flash_if
->erasesize
, &is_bad
);
1383 chfs_err("checking block is bad failed\n");
1391 err
= ebh
->ops
->read_eb_hdr(ebh
, pebnr
, ebhdr
);
1395 erase_cnt
= le32toh(ebhdr
->ec_hdr
.erase_cnt
);
1396 leb_status
= ebh
->ops
->check_eb_hdr(ebh
, ebhdr
);
1397 if (EBHDR_LEB_BADMAGIC
== leb_status
||
1398 EBHDR_LEB_BADCRC
== leb_status
) {
1399 err
= scan_add_to_queue(si
, pebnr
, erase_cnt
, &si
->corrupted
);
1402 else if (EBHDR_LEB_FREE
== leb_status
) {
1403 err
= scan_add_to_queue(si
, pebnr
, erase_cnt
, &si
->free
);
1406 else if (EBHDR_LEB_NO_HDR
== leb_status
) {
1407 err
= scan_add_to_queue(si
, pebnr
, erase_cnt
, &si
->erased
);
1411 err
= nand_scan_add_to_used(ebh
, si
, ebhdr
, pebnr
);
1415 max_serial
= le64toh(ebhdr
->u
.nand_hdr
.serial
);
1416 if (max_serial
> *ebh
->max_serial
) {
1417 *ebh
->max_serial
= max_serial
;
1421 si
->sum_of_ec
+= erase_cnt
;
1428 * chfs_scan - scans the media and returns informations about it
1429 * @ebh: chfs eraseblock handler
1431 * This function scans through the media and returns information about it or if
1432 * it fails NULL will be returned.
1434 struct chfs_scan_info
*
1435 chfs_scan(struct chfs_ebh
*ebh
)
1437 struct chfs_scan_info
*si
;
1438 struct chfs_eb_hdr
*ebhdr
;
1441 si
= kmem_alloc(sizeof(*si
), KM_SLEEP
);
1443 TAILQ_INIT(&si
->corrupted
);
1444 TAILQ_INIT(&si
->free
);
1445 TAILQ_INIT(&si
->erase
);
1446 TAILQ_INIT(&si
->erased
);
1448 si
->bad_peb_cnt
= 0;
1452 ebhdr
= kmem_alloc(sizeof(*ebhdr
), KM_SLEEP
);
1454 for (pebnr
= 0; pebnr
< ebh
->peb_nr
; pebnr
++) {
1455 dbg_ebh("processing PEB %d\n", pebnr
);
1456 err
= ebh
->ops
->process_eb(ebh
, si
, pebnr
, ebhdr
);
1460 kmem_free(ebhdr
, sizeof(*ebhdr
));
1461 dbg_ebh("[CHFS_SCAN] scanning information collected\n");
1465 kmem_free(ebhdr
, sizeof(*ebhdr
));
1466 kmem_free(si
, sizeof(*si
));
1471 * scan_info_destroy - frees all lists and trees in the scanning information
1472 * @si: the scanning information
1475 scan_info_destroy(struct chfs_scan_info
*si
)
1477 EBH_QUEUE_DESTROY(&si
->corrupted
,
1478 struct chfs_scan_leb
, u
.queue
);
1480 EBH_QUEUE_DESTROY(&si
->erase
,
1481 struct chfs_scan_leb
, u
.queue
);
1483 EBH_QUEUE_DESTROY(&si
->erased
,
1484 struct chfs_scan_leb
, u
.queue
);
1486 EBH_QUEUE_DESTROY(&si
->free
,
1487 struct chfs_scan_leb
, u
.queue
);
1489 EBH_TREE_DESTROY(scan_leb_used_rbtree
,
1490 &si
->used
, struct chfs_scan_leb
);
1492 kmem_free(si
, sizeof(*si
));
1493 dbg_ebh("[SCAN_INFO_DESTROY] scanning information destroyed\n");
1497 * scan_media - scan media
1499 * @ebh - chfs eraseblock handler
1501 * Returns zero in case of success, error code in case of fail.
1505 scan_media(struct chfs_ebh
*ebh
)
1508 struct chfs_scan_info
*si
;
1509 struct chfs_scan_leb
*sleb
;
1511 si
= chfs_scan(ebh
);
1513 * Process the scan info, manage the eraseblock lists
1515 mutex_init(&ebh
->ltree_lock
, MUTEX_DEFAULT
, IPL_NONE
);
1516 mutex_init(&ebh
->erase_lock
, MUTEX_DEFAULT
, IPL_NONE
);
1517 RB_INIT(&ebh
->ltree
);
1518 RB_INIT(&ebh
->free
);
1519 RB_INIT(&ebh
->in_use
);
1520 TAILQ_INIT(&ebh
->to_erase
);
1521 TAILQ_INIT(&ebh
->fully_erased
);
1522 mutex_init(&ebh
->alc_mutex
, MUTEX_DEFAULT
, IPL_NONE
);
1524 ebh
->peb_nr
-= si
->bad_peb_cnt
;
1527 * Create background thread for erasing
1529 erase_thread_start(ebh
);
1531 ebh
->lmap
= kmem_alloc(ebh
->peb_nr
* sizeof(int), KM_SLEEP
);
1533 for (i
= 0; i
< ebh
->peb_nr
; i
++) {
1534 ebh
->lmap
[i
] = EBH_LEB_UNMAPPED
;
1537 if (si
->num_of_eb
== 0) {
1538 /* The flash contains no data. */
1542 avg_ec
= (int) (si
->sum_of_ec
/ si
->num_of_eb
);
1544 dbg_ebh("num_of_eb: %d\n", si
->num_of_eb
);
1546 mutex_enter(&ebh
->erase_lock
);
1548 RB_FOREACH(sleb
, scan_leb_used_rbtree
, &si
->used
) {
1549 ebh
->lmap
[sleb
->lnr
] = sleb
->pebnr
;
1550 err
= add_peb_to_in_use(ebh
, sleb
->pebnr
, sleb
->erase_cnt
);
1555 TAILQ_FOREACH(sleb
, &si
->erased
, u
.queue
) {
1556 err
= add_peb_to_erase_queue(ebh
, sleb
->pebnr
, avg_ec
,
1557 &ebh
->fully_erased
);
1562 TAILQ_FOREACH(sleb
, &si
->erase
, u
.queue
) {
1563 err
= add_peb_to_erase_queue(ebh
, sleb
->pebnr
, avg_ec
,
1569 TAILQ_FOREACH(sleb
, &si
->free
, u
.queue
) {
1570 err
= add_peb_to_free(ebh
, sleb
->pebnr
, sleb
->erase_cnt
);
1575 TAILQ_FOREACH(sleb
, &si
->corrupted
, u
.queue
) {
1576 err
= add_peb_to_erase_queue(ebh
, sleb
->pebnr
, avg_ec
,
1581 mutex_exit(&ebh
->erase_lock
);
1582 scan_info_destroy(si
);
1586 mutex_exit(&ebh
->erase_lock
);
1587 kmem_free(ebh
->lmap
, ebh
->peb_nr
* sizeof(int));
1588 scan_info_destroy(si
);
1589 dbg_ebh("[SCAN_MEDIA] returning with error: %d\n", err
);
1593 /*****************************************************************************/
1594 /* End of Scan related operations */
1595 /*****************************************************************************/
1598 * ebh_open - opens mtd device and init ereaseblock header
1599 * @ebh: eraseblock handler
1600 * @flash_nr: flash device number to use
1602 * Returns zero in case of success, error code in case of fail.
1605 ebh_open(struct chfs_ebh
*ebh
, dev_t dev
)
1609 ebh
->flash_dev
= flash_get_device(dev
);
1610 if (!ebh
->flash_dev
) {
1611 aprint_error("ebh_open: cant get flash device\n");
1615 ebh
->flash_if
= flash_get_interface(dev
);
1616 if (!ebh
->flash_if
) {
1617 aprint_error("ebh_open: cant get flash interface\n");
1621 ebh
->flash_size
= flash_get_size(dev
);
1622 ebh
->peb_nr
= ebh
->flash_size
/ ebh
->flash_if
->erasesize
;
1623 // ebh->peb_nr = ebh->flash_if->size / ebh->flash_if->erasesize;
1624 /* Set up flash operations based on flash type */
1625 ebh
->ops
= kmem_alloc(sizeof(struct chfs_ebh_ops
), KM_SLEEP
);
1627 switch (ebh
->flash_if
->type
) {
1628 case FLASH_TYPE_NOR
:
1629 ebh
->eb_size
= ebh
->flash_if
->erasesize
-
1630 CHFS_EB_EC_HDR_SIZE
- CHFS_EB_HDR_NOR_SIZE
;
1632 ebh
->ops
->read_eb_hdr
= nor_read_eb_hdr
;
1633 ebh
->ops
->write_eb_hdr
= nor_write_eb_hdr
;
1634 ebh
->ops
->check_eb_hdr
= nor_check_eb_hdr
;
1635 ebh
->ops
->mark_eb_hdr_dirty_flash
=
1636 nor_mark_eb_hdr_dirty_flash
;
1637 ebh
->ops
->invalidate_eb_hdr
= nor_invalidate_eb_hdr
;
1638 ebh
->ops
->mark_eb_hdr_free
= mark_eb_hdr_free
;
1640 ebh
->ops
->process_eb
= nor_process_eb
;
1642 ebh
->ops
->create_eb_hdr
= nor_create_eb_hdr
;
1643 ebh
->ops
->calc_data_offs
= nor_calc_data_offs
;
1645 ebh
->max_serial
= NULL
;
1647 case FLASH_TYPE_NAND
:
1648 ebh
->eb_size
= ebh
->flash_if
->erasesize
-
1649 2 * ebh
->flash_if
->page_size
;
1651 ebh
->ops
->read_eb_hdr
= nand_read_eb_hdr
;
1652 ebh
->ops
->write_eb_hdr
= nand_write_eb_hdr
;
1653 ebh
->ops
->check_eb_hdr
= nand_check_eb_hdr
;
1654 ebh
->ops
->mark_eb_hdr_free
= mark_eb_hdr_free
;
1655 ebh
->ops
->mark_eb_hdr_dirty_flash
= NULL
;
1656 ebh
->ops
->invalidate_eb_hdr
= NULL
;
1658 ebh
->ops
->process_eb
= nand_process_eb
;
1660 ebh
->ops
->create_eb_hdr
= nand_create_eb_hdr
;
1661 ebh
->ops
->calc_data_offs
= nand_calc_data_offs
;
1663 ebh
->max_serial
= kmem_alloc(sizeof(uint64_t), KM_SLEEP
);
1665 *ebh
->max_serial
= 0;
1670 printf("opening ebh: eb_size: %zu\n", ebh
->eb_size
);
1671 err
= scan_media(ebh
);
1673 dbg_ebh("Scan failed.");
1674 kmem_free(ebh
->ops
, sizeof(struct chfs_ebh_ops
));
1675 kmem_free(ebh
, sizeof(struct chfs_ebh
));
1682 * ebh_close - close ebh
1683 * @ebh: eraseblock handler
1684 * Returns zero in case of success, error code in case of fail.
1687 ebh_close(struct chfs_ebh
*ebh
)
1689 erase_thread_stop(ebh
);
1691 EBH_TREE_DESTROY(peb_free_rbtree
, &ebh
->free
, struct chfs_peb
);
1692 EBH_TREE_DESTROY(peb_in_use_rbtree
, &ebh
->in_use
, struct chfs_peb
);
1694 EBH_QUEUE_DESTROY(&ebh
->fully_erased
, struct chfs_peb
, u
.queue
);
1695 EBH_QUEUE_DESTROY(&ebh
->to_erase
, struct chfs_peb
, u
.queue
);
1697 /* XXX HACK, see ebh.h */
1698 EBH_TREE_DESTROY_MUTEX(ltree_rbtree
, &ebh
->ltree
,
1699 struct chfs_ltree_entry
);
1701 KASSERT(!mutex_owned(&ebh
->ltree_lock
));
1702 KASSERT(!mutex_owned(&ebh
->alc_mutex
));
1703 KASSERT(!mutex_owned(&ebh
->erase_lock
));
1705 mutex_destroy(&ebh
->ltree_lock
);
1706 mutex_destroy(&ebh
->alc_mutex
);
1707 mutex_destroy(&ebh
->erase_lock
);
1709 kmem_free(ebh
->ops
, sizeof(struct chfs_ebh_ops
));
1710 kmem_free(ebh
, sizeof(struct chfs_ebh
));
1716 * ebh_read_leb - read data from leb
1717 * @ebh: eraseblock handler
1718 * @lnr: logical eraseblock number
1719 * @buf: buffer to read to
1720 * @offset: offset from where to read
1721 * @len: bytes number to read
1723 * Returns zero in case of success, error code in case of fail.
1726 ebh_read_leb(struct chfs_ebh
*ebh
, int lnr
, char *buf
, uint32_t offset
,
1727 size_t len
, size_t *retlen
)
1732 KASSERT(offset
+ len
<= ebh
->eb_size
);
1734 err
= leb_read_lock(ebh
, lnr
);
1738 pebnr
= ebh
->lmap
[lnr
];
1739 /* If PEB is not mapped the buffer is filled with 0xFF */
1740 if (EBH_LEB_UNMAPPED
== pebnr
) {
1741 leb_read_unlock(ebh
, lnr
);
1742 memset(buf
, 0xFF, len
);
1747 data_offset
= ebh
->ops
->calc_data_offs(ebh
, pebnr
, offset
);
1748 err
= flash_read(ebh
->flash_dev
, data_offset
, len
, retlen
,
1749 (unsigned char *) buf
);
1753 KASSERT(len
== *retlen
);
1756 leb_read_unlock(ebh
, lnr
);
1761 * get_peb: get a free physical eraseblock
1762 * @ebh - chfs eraseblock handler
1764 * This function gets a free eraseblock from the ebh->free RB-tree.
1765 * The fist entry will be returned and deleted from the tree.
1766 * The entries sorted by the erase counters, so the PEB with the smallest
1767 * erase counter will be added back.
1768 * If something goes bad a negative value will be returned.
1771 get_peb(struct chfs_ebh
*ebh
)
1774 struct chfs_peb
*peb
;
1777 mutex_enter(&ebh
->erase_lock
);
1778 //dbg_ebh("LOCK: ebh->erase_lock spin locked in get_peb()\n");
1779 if (RB_EMPTY(&ebh
->free
)) {
1780 /*There is no more free PEBs in the tree*/
1781 if (TAILQ_EMPTY(&ebh
->to_erase
) &&
1782 TAILQ_EMPTY(&ebh
->fully_erased
)) {
1783 mutex_exit(&ebh
->erase_lock
);
1784 //dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in get_peb()\n");
1787 err
= free_peb(ebh
);
1789 mutex_exit(&ebh
->erase_lock
);
1790 //dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in get_peb()\n");
1796 peb
= RB_MIN(peb_free_rbtree
, &ebh
->free
);
1798 RB_REMOVE(peb_free_rbtree
, &ebh
->free
, peb
);
1799 err
= add_peb_to_in_use(ebh
, peb
->pebnr
, peb
->erase_cnt
);
1803 kmem_free(peb
, sizeof(struct chfs_peb
));
1805 mutex_exit(&ebh
->erase_lock
);
1806 //dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in get_peb()\n");
1812 * ebh_write_leb - write data to leb
1813 * @ebh: eraseblock handler
1814 * @lnr: logical eraseblock number
1815 * @buf: data to write
1816 * @offset: offset where to write
1817 * @len: bytes number to write
1819 * Returns zero in case of success, error code in case of fail.
1822 ebh_write_leb(struct chfs_ebh
*ebh
, int lnr
, char *buf
, uint32_t offset
,
1823 size_t len
, size_t *retlen
)
1825 int err
, pebnr
, retries
= 0;
1827 struct chfs_eb_hdr
*ebhdr
;
1829 dbg("offset: %d | len: %zu | (offset+len): %zu "
1830 " | ebsize: %zu\n", offset
, len
, (offset
+len
), ebh
->eb_size
);
1832 KASSERT(offset
+ len
<= ebh
->eb_size
);
1834 err
= leb_write_lock(ebh
, lnr
);
1838 pebnr
= ebh
->lmap
[lnr
];
1839 /* If the LEB is mapped write out data */
1840 if (pebnr
!= EBH_LEB_UNMAPPED
) {
1841 data_offset
= ebh
->ops
->calc_data_offs(ebh
, pebnr
, offset
);
1842 err
= flash_write(ebh
->flash_dev
, data_offset
, len
, retlen
,
1843 (unsigned char *) buf
);
1846 chfs_err("error %d while writing %zu bytes to PEB "
1847 "%d:%ju, written %zu bytes\n",
1848 err
, len
, pebnr
, (uintmax_t )offset
, *retlen
);
1850 KASSERT(len
== *retlen
);
1853 leb_write_unlock(ebh
, lnr
);
1858 * If the LEB is unmapped, get a free PEB and write the
1859 * eraseblock header first
1861 ebhdr
= kmem_alloc(sizeof(struct chfs_eb_hdr
), KM_SLEEP
);
1863 /* Setting up eraseblock header properties */
1864 ebh
->ops
->create_eb_hdr(ebhdr
, lnr
);
1867 /* Getting a physical eraseblock from the wear leveling system */
1868 pebnr
= get_peb(ebh
);
1870 leb_write_unlock(ebh
, lnr
);
1871 kmem_free(ebhdr
, sizeof(struct chfs_eb_hdr
));
1875 /* Write the eraseblock header to the media */
1876 err
= ebh
->ops
->write_eb_hdr(ebh
, pebnr
, ebhdr
);
1879 "error writing eraseblock header: LEB %d , PEB %d\n",
1884 /* Write out data */
1886 data_offset
= ebh
->ops
->calc_data_offs(ebh
, pebnr
, offset
);
1887 err
= flash_write(ebh
->flash_dev
,
1888 data_offset
, len
, retlen
, (unsigned char *) buf
);
1890 chfs_err("error %d while writing %zu bytes to PEB "
1891 " %d:%ju, written %zu bytes\n",
1892 err
, len
, pebnr
, (uintmax_t )offset
, *retlen
);
1897 ebh
->lmap
[lnr
] = pebnr
;
1898 leb_write_unlock(ebh
, lnr
);
1899 kmem_free(ebhdr
, sizeof(struct chfs_eb_hdr
));
1903 write_error
: err
= release_peb(ebh
, pebnr
);
1904 // max retries (NOW: 2)
1905 if (err
|| CHFS_MAX_GET_PEB_RETRIES
< ++retries
) {
1906 leb_write_unlock(ebh
, lnr
);
1907 kmem_free(ebhdr
, sizeof(struct chfs_eb_hdr
));
1914 * ebh_erase_leb - erase a leb
1915 * @ebh: eraseblock handler
1918 * Returns zero in case of success, error code in case of fail.
1921 ebh_erase_leb(struct chfs_ebh
*ebh
, int lnr
)
1925 leb_write_lock(ebh
, lnr
);
1927 pebnr
= ebh
->lmap
[lnr
];
1929 leb_write_unlock(ebh
, lnr
);
1930 return EBH_LEB_UNMAPPED
;
1932 err
= release_peb(ebh
, pebnr
);
1936 ebh
->lmap
[lnr
] = EBH_LEB_UNMAPPED
;
1937 cv_signal(&ebh
->bg_erase
.eth_wakeup
);
1939 leb_write_unlock(ebh
, lnr
);
1944 * ebh_map_leb - maps a PEB to LEB
1945 * @ebh: eraseblock handler
1948 * Returns zero on success, error code in case of fail
1951 ebh_map_leb(struct chfs_ebh
*ebh
, int lnr
)
1953 int err
, pebnr
, retries
= 0;
1954 struct chfs_eb_hdr
*ebhdr
;
1956 ebhdr
= kmem_alloc(sizeof(struct chfs_eb_hdr
), KM_SLEEP
);
1958 err
= leb_write_lock(ebh
, lnr
);
1960 kmem_free(ebhdr
, sizeof(struct chfs_eb_hdr
));
1965 pebnr
= get_peb(ebh
);
1971 ebh
->ops
->create_eb_hdr(ebhdr
, lnr
);
1973 err
= ebh
->ops
->write_eb_hdr(ebh
, pebnr
, ebhdr
);
1976 "error writing eraseblock header: LEB %d , PEB %d\n",
1981 ebh
->lmap
[lnr
] = pebnr
;
1984 leb_write_unlock(ebh
, lnr
);
1988 err
= release_peb(ebh
, pebnr
);
1989 // max retries (NOW: 2)
1990 if (err
|| CHFS_MAX_GET_PEB_RETRIES
< ++retries
) {
1991 leb_write_unlock(ebh
, lnr
);
1992 kmem_free(ebhdr
, sizeof(struct chfs_eb_hdr
));
2000 * @ebh: eraseblock handler
2003 * Retruns zero on success, error code in case of fail.
2006 ebh_unmap_leb(struct chfs_ebh
*ebh
, int lnr
)
2010 if (ebh_is_mapped(ebh
, lnr
) < 0)
2011 /* If the eraseblock already unmapped */
2014 err
= ebh_erase_leb(ebh
, lnr
);
2020 * ebh_is_mapped - check if a PEB is mapped to @lnr
2021 * @ebh: eraseblock handler
2024 * Retruns 0 if the logical eraseblock is mapped, negative error code otherwise.
2027 ebh_is_mapped(struct chfs_ebh
*ebh
, int lnr
)
2030 err
= leb_read_lock(ebh
, lnr
);
2034 result
= ebh
->lmap
[lnr
];
2035 leb_read_unlock(ebh
, lnr
);
2041 * ebh_change_leb - write the LEB to another PEB
2042 * @ebh: eraseblock handler
2044 * @buf: data to write
2045 * @len: length of data
2046 * Returns zero in case of success, error code in case of fail.
2049 ebh_change_leb(struct chfs_ebh
*ebh
, int lnr
, char *buf
, size_t len
,
2052 int err
, pebnr
, pebnr_old
, retries
= 0;
2055 struct chfs_peb
*peb
= NULL
;
2056 struct chfs_eb_hdr
*ebhdr
;
2058 if (ebh_is_mapped(ebh
, lnr
) < 0)
2059 return EBH_LEB_UNMAPPED
;
2062 err
= ebh_unmap_leb(ebh
, lnr
);
2065 return ebh_map_leb(ebh
, lnr
);
2068 ebhdr
= kmem_alloc(sizeof(struct chfs_eb_hdr
), KM_SLEEP
);
2070 pebnr_old
= ebh
->lmap
[lnr
];
2072 mutex_enter(&ebh
->alc_mutex
);
2073 err
= leb_write_lock(ebh
, lnr
);
2077 if (ebh
->ops
->mark_eb_hdr_dirty_flash
) {
2078 err
= ebh
->ops
->mark_eb_hdr_dirty_flash(ebh
, pebnr_old
, lnr
);
2083 /* Setting up eraseblock header properties */
2084 ebh
->ops
->create_eb_hdr(ebhdr
, lnr
);
2087 /* Getting a physical eraseblock from the wear leveling system */
2088 pebnr
= get_peb(ebh
);
2090 leb_write_unlock(ebh
, lnr
);
2091 mutex_exit(&ebh
->alc_mutex
);
2092 kmem_free(ebhdr
, sizeof(struct chfs_eb_hdr
));
2096 err
= ebh
->ops
->write_eb_hdr(ebh
, pebnr
, ebhdr
);
2099 "error writing eraseblock header: LEB %d , PEB %d",
2104 /* Write out data */
2105 data_offset
= ebh
->ops
->calc_data_offs(ebh
, pebnr
, 0);
2106 err
= flash_write(ebh
->flash_dev
, data_offset
, len
, retlen
,
2107 (unsigned char *) buf
);
2109 chfs_err("error %d while writing %zu bytes to PEB %d:%ju,"
2110 " written %zu bytes",
2111 err
, len
, pebnr
, (uintmax_t)data_offset
, *retlen
);
2115 ebh
->lmap
[lnr
] = pebnr
;
2117 if (ebh
->ops
->invalidate_eb_hdr
) {
2118 err
= ebh
->ops
->invalidate_eb_hdr(ebh
, pebnr_old
);
2122 peb
= find_peb_in_use(ebh
, pebnr_old
);
2123 err
= release_peb(ebh
, peb
->pebnr
);
2126 leb_write_unlock(ebh
, lnr
);
2129 mutex_exit(&ebh
->alc_mutex
);
2130 kmem_free(ebhdr
, sizeof(struct chfs_eb_hdr
));
2131 kmem_free(peb
, sizeof(struct chfs_peb
));
2135 err
= release_peb(ebh
, pebnr
);
2136 //max retries (NOW: 2)
2137 if (err
|| CHFS_MAX_GET_PEB_RETRIES
< ++retries
) {
2138 leb_write_unlock(ebh
, lnr
);
2139 mutex_exit(&ebh
->alc_mutex
);
2140 kmem_free(ebhdr
, sizeof(struct chfs_eb_hdr
));