Lines Matching defs:ebh

1 /*	$NetBSD: ebh.c,v 1.11 2025/01/08 11:39:50 andvar Exp $	*/
38 #include "ebh.h"
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);
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);
65 int free_peb(struct chfs_ebh *ebh);
66 int release_peb(struct chfs_ebh *ebh, int pebnr);
68 static void erase_thread_start(struct chfs_ebh *ebh);
69 static void erase_thread_stop(struct chfs_ebh *ebh);
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,
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,
77 struct chfs_scan_info *chfs_scan(struct chfs_ebh *ebh);
79 int scan_media(struct chfs_ebh *ebh);
80 int get_peb(struct chfs_ebh *ebh);
107 * @ebh: chfs eraseblock handler
112 nor_calc_data_offs(struct chfs_ebh *ebh, int pebnr, int offset)
114 return pebnr * ebh->flash_if->erasesize + offset +
120 * @ebh: chfs eraseblock handler
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;
134 * @ebh: chfs eraseblock handler
142 nor_read_eb_hdr(struct chfs_ebh *ebh,
147 off_t ofs = pebnr * ebh->flash_if->erasesize;
149 KASSERT(pebnr >= 0 && pebnr < ebh->peb_nr);
151 ret = flash_read(ebh->flash_dev,
159 ret = flash_read(ebh->flash_dev,
172 * @ebh: chfs eraseblock handler
180 nand_read_eb_hdr(struct chfs_ebh *ebh, int pebnr,
187 KASSERT(pebnr >= 0 && pebnr < ebh->peb_nr);
190 ofs = pebnr * ebh->flash_if->erasesize;
191 ret = flash_read(ebh->flash_dev,
198 ofs += ebh->flash_if->page_size;
199 ret = flash_read(ebh->flash_dev,
211 * @ebh: chfs eraseblock handler
213 * @ebh: ebh to write
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;
233 KASSERT(pebnr >= 0 && pebnr < ebh->peb_nr);
235 ret = flash_write(ebh->flash_dev,
248 * @ebh: chfs eraseblock handler
250 * @ebh: ebh to write
256 nand_write_eb_hdr(struct chfs_ebh *ebh, int pebnr,
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));
274 ret = flash_write(ebh->flash_dev, ofs,
287 * @ebh: chfs eraseblock handler
293 nor_check_eb_hdr(struct chfs_ebh *ebh, void *buf)
346 // restore the original lid value in ebh
366 * @ebh: chfs eraseblock handler
372 nand_check_eb_hdr(struct chfs_ebh *ebh, void *buf)
426 * @ebh: chfs eraseblock handler
435 nor_mark_eb_hdr_dirty_flash(struct chfs_ebh *ebh, int pebnr, int lid)
445 ofs = pebnr * ebh->flash_if->erasesize + CHFS_EB_EC_HDR_SIZE
448 ret = flash_write(ebh->flash_dev, ofs, sizeof(lid), &retlen,
461 * @ebh: chfs eraseblock handler
468 nor_invalidate_eb_hdr(struct chfs_ebh *ebh, int pebnr)
479 ofs = pebnr * ebh->flash_if->erasesize + CHFS_EB_EC_HDR_SIZE
482 ret = flash_write(ebh->flash_dev,
496 * @ebh: chfs eraseblock handler
504 mark_eb_hdr_free(struct chfs_ebh *ebh, int pebnr, int ec)
517 ofs = pebnr * ebh->flash_if->erasesize;
521 ret = flash_write(ebh->flash_dev,
557 * @ebh: chfs eraseblock handler
563 * @ebh->ltree_lock has to be locked!
566 ltree_lookup(struct chfs_ebh *ebh, int lnr)
570 result = RB_FIND(ltree_rbtree, &ebh->ltree, &le);
576 * @ebh: chfs eraseblock handler
586 ltree_add_entry(struct chfs_ebh *ebh, int lnr)
597 mutex_enter(&ebh->ltree_lock);
599 result = RB_INSERT(ltree_rbtree, &ebh->ltree, le);
609 mutex_exit(&ebh->ltree_lock);
616 * @ebh: chfs eraseblock handler
622 leb_read_lock(struct chfs_ebh *ebh, int lnr)
626 le = ltree_add_entry(ebh, lnr);
636 * @ebh: chfs eraseblock handler
643 leb_read_unlock(struct chfs_ebh *ebh, int lnr)
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);
657 le = RB_REMOVE(ltree_rbtree, &ebh->ltree, le);
666 mutex_exit(&ebh->ltree_lock);
667 //dbg_ebh("UNLOCK: ebh->ltree_lock spin unlocked in leb_read_unlock()\n");
672 * @ebh: chfs eraseblock handler
678 leb_write_lock(struct chfs_ebh *ebh, int lnr)
682 le = ltree_add_entry(ebh, lnr);
692 * @ebh: chfs eraseblock handler
699 leb_write_unlock(struct chfs_ebh *ebh, int lnr)
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);
713 RB_REMOVE(ltree_rbtree, &ebh->ltree, le);
721 mutex_exit(&ebh->ltree_lock);
722 //dbg_ebh("UNLOCK: ebh->ltree_lock spin unlocked in leb_write_unlock()\n");
764 * @ebh - chfs eraseblock handler
770 * The @ebh->erase_lock must be locked before using this.
774 add_peb_to_erase_queue(struct chfs_ebh *ebh, int pebnr, int ec,
792 * @ebh - chfs eraseblock handler
796 * The @ebh->erase_lock must be locked before using this.
799 find_peb_in_use(struct chfs_ebh *ebh, int pebnr)
803 result = RB_FIND(peb_in_use_rbtree, &ebh->in_use, &peb);
809 * @ebh - chfs eraseblock handler
815 * stored in the @ebh. The key is the erase counter and pebnr.
816 * The @ebh->erase_lock must be locked before using this.
820 add_peb_to_free(struct chfs_ebh *ebh, int pebnr, int ec)
828 result = RB_INSERT(peb_free_rbtree, &ebh->free, peb);
839 * @ebh - chfs eraseblock handler
845 * stored in the @ebh. The key is pebnr.
846 * The @ebh->erase_lock must be locked before using this.
850 add_peb_to_in_use(struct chfs_ebh *ebh, int pebnr, int ec)
858 result = RB_INSERT(peb_in_use_rbtree, &ebh->in_use, peb);
877 struct chfs_ebh *ebh = priv->ebh;
885 err = ebh->ops->mark_eb_hdr_free(ebh,
892 mutex_enter(&ebh->erase_lock);
893 /*dbg_ebh("LOCK: ebh->erase_lock spin locked in erase_callback() "
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() "
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");*/
916 add_peb_to_erase_queue(ebh, peb->pebnr, peb->erase_cnt, &ebh->to_erase);
923 * @ebh: chfs eraseblock handler
930 free_peb(struct chfs_ebh *ebh)
937 KASSERT(mutex_owned(&ebh->erase_lock));
939 if (!TAILQ_EMPTY(&ebh->fully_erased)) {
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,
948 err = add_peb_to_free(ebh, peb->pebnr, peb->erase_cnt);
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;
965 // ei->ei_if = ebh->flash_if;
967 ei->ei_len = ebh->flash_if->erasesize;
971 ((struct chfs_erase_info_priv *) ei->ei_priv)->ebh = ebh;
974 err = flash_erase(ebh->flash_dev, ei);
985 dbg_ebh("ebh markbad! 0x%jx\n", (uintmax_t )ofs);
986 err = flash_block_markbad(ebh->flash_dev, ofs);
988 ebh->peb_nr--;
1000 mutex_enter(&ebh->erase_lock);
1010 * @ebh: chfs eraseblock handler
1014 * @ebh, removes it and schedule an erase for it.
1019 release_peb(struct chfs_ebh *ebh, int pebnr)
1024 mutex_enter(&ebh->erase_lock);
1026 //dbg_ebh("LOCK: ebh->erase_lock spin locked in release_peb()\n");
1027 peb = find_peb_in_use(ebh, pebnr);
1030 "tree of ebh\n");
1033 err = add_peb_to_erase_queue(ebh, peb->pebnr, peb->erase_cnt,
1034 &ebh->to_erase);
1039 RB_REMOVE(peb_in_use_rbtree, &ebh->in_use, peb);
1041 mutex_exit(&ebh->erase_lock);
1042 //dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in release_peb()"
1054 struct chfs_ebh *ebh = data;
1057 while (ebh->bg_erase.eth_running) {
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)) {
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);
1070 dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in erase_thread()\n");
1073 mutex_exit(&ebh->erase_lock);
1074 dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in erase_thread()\n");
1076 err = free_peb(ebh);
1093 struct chfs_ebh *ebh = data;
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));
1106 err = free_peb(ebh);
1107 mutex_exit(&ebh->erase_lock);
1112 mutex_enter(&ebh->erase_lock);
1115 mutex_exit(&ebh->erase_lock);
1123 * @ebh: eraseblock handler
1126 erase_thread_start(struct chfs_ebh *ebh)
1128 cv_init(&ebh->bg_erase.eth_wakeup, "ebheracv");
1130 ebh->bg_erase.eth_running = true;
1132 erase_thread, ebh, &ebh->bg_erase.eth_thread, "ebherase");
1137 * @ebh: eraseblock handler
1140 erase_thread_stop(struct chfs_ebh *ebh)
1142 ebh->bg_erase.eth_running = false;
1143 cv_signal(&ebh->bg_erase.eth_wakeup);
1146 kthread_join(ebh->bg_erase.eth_thread);
1151 cv_destroy(&ebh->bg_erase.eth_wakeup);
1199 * @ebh: chfs eraseblock handler
1211 nor_scan_add_to_used(struct chfs_ebh *ebh, struct chfs_scan_info *si,
1255 * @ebh: chfs eraseblock handler
1262 nor_process_eb(struct chfs_ebh *ebh, struct chfs_scan_info *si,
1267 err = ebh->ops->read_eb_hdr(ebh, pebnr, ebhdr);
1273 leb_status = ebh->ops->check_eb_hdr(ebh, ebhdr);
1292 err = nor_scan_add_to_used(ebh, si, ebhdr, pebnr, leb_status);
1307 * @ebh: chfs eraseblock handler
1319 nand_scan_add_to_used(struct chfs_ebh *ebh, struct chfs_scan_info *si,
1362 * @ebh: chfs eraseblock handler
1369 nand_process_eb(struct chfs_ebh *ebh, struct chfs_scan_info *si,
1378 err = flash_block_isbad(ebh->flash_dev,
1379 pebnr * ebh->flash_if->erasesize, &is_bad);
1389 err = ebh->ops->read_eb_hdr(ebh, pebnr, ebhdr);
1394 leb_status = ebh->ops->check_eb_hdr(ebh, ebhdr);
1409 err = nand_scan_add_to_used(ebh, si, ebhdr, pebnr);
1414 if (max_serial > *ebh->max_serial) {
1415 *ebh->max_serial = max_serial;
1427 * @ebh: chfs eraseblock handler
1433 chfs_scan(struct chfs_ebh *ebh)
1452 for (pebnr = 0; pebnr < ebh->peb_nr; pebnr++) {
1454 err = ebh->ops->process_eb(ebh, si, pebnr, ebhdr);
1497 * @ebh - chfs eraseblock handler
1503 scan_media(struct chfs_ebh *ebh)
1509 si = chfs_scan(ebh);
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);
1522 ebh->peb_nr -= si->bad_peb_cnt;
1527 erase_thread_start(ebh);
1529 ebh->lmap = kmem_alloc(ebh->peb_nr * sizeof(int), KM_SLEEP);
1531 for (i = 0; i < ebh->peb_nr; i++) {
1532 ebh->lmap[i] = EBH_LEB_UNMAPPED;
1544 mutex_enter(&ebh->erase_lock);
1547 ebh->lmap[sleb->lnr] = sleb->pebnr;
1548 err = add_peb_to_in_use(ebh, sleb->pebnr, sleb->erase_cnt);
1554 err = add_peb_to_erase_queue(ebh, sleb->pebnr, avg_ec,
1555 &ebh->fully_erased);
1561 err = add_peb_to_erase_queue(ebh, sleb->pebnr, avg_ec,
1562 &ebh->to_erase);
1568 err = add_peb_to_free(ebh, sleb->pebnr, sleb->erase_cnt);
1574 err = add_peb_to_erase_queue(ebh, sleb->pebnr, avg_ec,
1575 &ebh->to_erase);
1579 mutex_exit(&ebh->erase_lock);
1584 mutex_exit(&ebh->erase_lock);
1585 kmem_free(ebh->lmap, ebh->peb_nr * sizeof(int));
1597 * @ebh: eraseblock handler
1603 ebh_open(struct chfs_ebh *ebh, dev_t dev)
1607 ebh->flash_dev = flash_get_device(dev);
1608 if (!ebh->flash_dev) {
1613 ebh->flash_if = flash_get_interface(dev);
1614 if (!ebh->flash_if) {
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;
1623 ebh->ops = kmem_alloc(sizeof(struct chfs_ebh_ops), KM_SLEEP);
1625 switch (ebh->flash_if->type) {
1627 ebh->eb_size = ebh->flash_if->erasesize -
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 =
1635 ebh->ops->invalidate_eb_hdr = nor_invalidate_eb_hdr;
1636 ebh->ops->mark_eb_hdr_free = mark_eb_hdr_free;
1638 ebh->ops->process_eb = nor_process_eb;
1640 ebh->ops->create_eb_hdr = nor_create_eb_hdr;
1641 ebh->ops->calc_data_offs = nor_calc_data_offs;
1643 ebh->max_serial = NULL;
1646 ebh->eb_size = ebh->flash_if->erasesize -
1647 2 * ebh->flash_if->page_size;
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;
1656 ebh->ops->process_eb = nand_process_eb;
1658 ebh->ops->create_eb_hdr = nand_create_eb_hdr;
1659 ebh->ops->calc_data_offs = nand_calc_data_offs;
1661 ebh->max_serial = kmem_alloc(sizeof(uint64_t), KM_SLEEP);
1663 *ebh->max_serial = 0;
1668 printf("opening ebh: eb_size: %zu\n", ebh->eb_size);
1669 err = scan_media(ebh);
1672 kmem_free(ebh->ops, sizeof(struct chfs_ebh_ops));
1673 kmem_free(ebh, sizeof(struct chfs_ebh));
1680 * ebh_close - close ebh
1681 * @ebh: eraseblock handler
1685 ebh_close(struct chfs_ebh *ebh)
1687 erase_thread_stop(ebh);
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);
1692 EBH_QUEUE_DESTROY(&ebh->fully_erased, struct chfs_peb, u.queue);
1693 EBH_QUEUE_DESTROY(&ebh->to_erase, struct chfs_peb, u.queue);
1695 /* XXX HACK, see ebh.h */
1696 EBH_TREE_DESTROY_MUTEX(ltree_rbtree, &ebh->ltree,
1699 KASSERT(!mutex_owned(&ebh->ltree_lock));
1700 KASSERT(!mutex_owned(&ebh->alc_mutex));
1701 KASSERT(!mutex_owned(&ebh->erase_lock));
1703 mutex_destroy(&ebh->ltree_lock);
1704 mutex_destroy(&ebh->alc_mutex);
1705 mutex_destroy(&ebh->erase_lock);
1707 kmem_free(ebh->ops, sizeof(struct chfs_ebh_ops));
1708 kmem_free(ebh, sizeof(struct chfs_ebh));
1715 * @ebh: eraseblock handler
1724 ebh_read_leb(struct chfs_ebh *ebh, int lnr, char *buf, uint32_t offset,
1730 KASSERT(offset + len <= ebh->eb_size);
1732 err = leb_read_lock(ebh, lnr);
1736 pebnr = ebh->lmap[lnr];
1739 leb_read_unlock(ebh, lnr);
1745 data_offset = ebh->ops->calc_data_offs(ebh, pebnr, offset);
1746 err = flash_read(ebh->flash_dev, data_offset, len, retlen,
1754 leb_read_unlock(ebh, lnr);
1760 * @ebh - chfs eraseblock handler
1762 * This function gets a free eraseblock from the ebh->free RB-tree.
1769 get_peb(struct chfs_ebh *ebh)
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)) {
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");
1785 err = free_peb(ebh);
1787 mutex_exit(&ebh->erase_lock);
1788 //dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in get_peb()\n");
1794 peb = RB_MIN(peb_free_rbtree, &ebh->free);
1796 RB_REMOVE(peb_free_rbtree, &ebh->free, peb);
1797 err = add_peb_to_in_use(ebh, peb->pebnr, peb->erase_cnt);
1803 mutex_exit(&ebh->erase_lock);
1804 //dbg_ebh("UNLOCK: ebh->erase_lock spin unlocked in get_peb()\n");
1811 * @ebh: eraseblock handler
1820 ebh_write_leb(struct chfs_ebh *ebh, int lnr, char *buf, uint32_t offset,
1828 " | ebsize: %zu\n", offset, len, (offset+len), ebh->eb_size);
1830 KASSERT(offset + len <= ebh->eb_size);
1832 err = leb_write_lock(ebh, lnr);
1836 pebnr = ebh->lmap[lnr];
1839 data_offset = ebh->ops->calc_data_offs(ebh, pebnr, offset);
1840 err = flash_write(ebh->flash_dev, data_offset, len, retlen,
1851 leb_write_unlock(ebh, lnr);
1862 ebh->ops->create_eb_hdr(ebhdr, lnr);
1866 pebnr = get_peb(ebh);
1868 leb_write_unlock(ebh, lnr);
1874 err = ebh->ops->write_eb_hdr(ebh, pebnr, ebhdr);
1884 data_offset = ebh->ops->calc_data_offs(ebh, pebnr, offset);
1885 err = flash_write(ebh->flash_dev,
1895 ebh->lmap[lnr] = pebnr;
1896 leb_write_unlock(ebh, lnr);
1901 write_error: err = release_peb(ebh, pebnr);
1904 leb_write_unlock(ebh, lnr);
1913 * @ebh: eraseblock handler
1919 ebh_erase_leb(struct chfs_ebh *ebh, int lnr)
1923 leb_write_lock(ebh, lnr);
1925 pebnr = ebh->lmap[lnr];
1927 leb_write_unlock(ebh, lnr);
1930 err = release_peb(ebh, pebnr);
1934 ebh->lmap[lnr] = EBH_LEB_UNMAPPED;
1935 cv_signal(&ebh->bg_erase.eth_wakeup);
1937 leb_write_unlock(ebh, lnr);
1943 * @ebh: eraseblock handler
1949 ebh_map_leb(struct chfs_ebh *ebh, int lnr)
1956 err = leb_write_lock(ebh, lnr);
1963 pebnr = get_peb(ebh);
1969 ebh->ops->create_eb_hdr(ebhdr, lnr);
1971 err = ebh->ops->write_eb_hdr(ebh, pebnr, ebhdr);
1979 ebh->lmap[lnr] = pebnr;
1982 leb_write_unlock(ebh, lnr);
1986 err = release_peb(ebh, pebnr);
1989 leb_write_unlock(ebh, lnr);
1998 * @ebh: eraseblock handler
2004 ebh_unmap_leb(struct chfs_ebh *ebh, int lnr)
2008 if (ebh_is_mapped(ebh, lnr) < 0)
2012 err = ebh_erase_leb(ebh, lnr);
2019 * @ebh: eraseblock handler
2025 ebh_is_mapped(struct chfs_ebh *ebh, int lnr)
2028 err = leb_read_lock(ebh, lnr);
2032 result = ebh->lmap[lnr];
2033 leb_read_unlock(ebh, lnr);
2040 * @ebh: eraseblock handler
2047 ebh_change_leb(struct chfs_ebh *ebh, int lnr, char *buf, size_t len,
2056 if (ebh_is_mapped(ebh, lnr) < 0)
2060 err = ebh_unmap_leb(ebh, lnr);
2063 return ebh_map_leb(ebh, lnr);
2068 pebnr_old = ebh->lmap[lnr];
2070 mutex_enter(&ebh->alc_mutex);
2071 err = leb_write_lock(ebh, lnr);
2075 if (ebh->ops->mark_eb_hdr_dirty_flash) {
2076 err = ebh->ops->mark_eb_hdr_dirty_flash(ebh, pebnr_old, lnr);
2082 ebh->ops->create_eb_hdr(ebhdr, lnr);
2086 pebnr = get_peb(ebh);
2088 leb_write_unlock(ebh, lnr);
2089 mutex_exit(&ebh->alc_mutex);
2094 err = ebh->ops->write_eb_hdr(ebh, pebnr, ebhdr);
2103 data_offset = ebh->ops->calc_data_offs(ebh, pebnr, 0);
2104 err = flash_write(ebh->flash_dev, data_offset, len, retlen,
2113 ebh->lmap[lnr] = pebnr;
2115 if (ebh->ops->invalidate_eb_hdr) {
2116 err = ebh->ops->invalidate_eb_hdr(ebh, pebnr_old);
2120 peb = find_peb_in_use(ebh, pebnr_old);
2121 err = release_peb(ebh, peb->pebnr);
2124 leb_write_unlock(ebh, lnr);
2127 mutex_exit(&ebh->alc_mutex);
2133 err = release_peb(ebh, pebnr);
2136 leb_write_unlock(ebh, lnr);
2137 mutex_exit(&ebh->alc_mutex);