1 1.5 andvar /* $NetBSD: ebh.h,v 1.5 2025/01/08 11:39:50 andvar Exp $ */ 2 1.1 ahoka 3 1.1 ahoka /*- 4 1.1 ahoka * Copyright (c) 2010 Department of Software Engineering, 5 1.1 ahoka * University of Szeged, Hungary 6 1.1 ahoka * Copyright (c) 2010 David Tengeri <dtengeri (at) inf.u-szeged.hu> 7 1.1 ahoka * Copyright (c) 2010 Adam Hoka <ahoka (at) NetBSD.org> 8 1.1 ahoka * All rights reserved. 9 1.1 ahoka * 10 1.1 ahoka * This code is derived from software contributed to The NetBSD Foundation 11 1.1 ahoka * by the Department of Software Engineering, University of Szeged, Hungary 12 1.1 ahoka * 13 1.1 ahoka * Redistribution and use in source and binary forms, with or without 14 1.1 ahoka * modification, are permitted provided that the following conditions 15 1.1 ahoka * are met: 16 1.1 ahoka * 1. Redistributions of source code must retain the above copyright 17 1.1 ahoka * notice, this list of conditions and the following disclaimer. 18 1.1 ahoka * 2. Redistributions in binary form must reproduce the above copyright 19 1.1 ahoka * notice, this list of conditions and the following disclaimer in the 20 1.1 ahoka * documentation and/or other materials provided with the distribution. 21 1.1 ahoka * 22 1.1 ahoka * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 1.1 ahoka * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 1.1 ahoka * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 1.1 ahoka * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 1.1 ahoka * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 1.1 ahoka * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 1.1 ahoka * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 1.1 ahoka * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 1.1 ahoka * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 1.1 ahoka * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 1.1 ahoka * SUCH DAMAGE. 33 1.1 ahoka */ 34 1.1 ahoka 35 1.1 ahoka #ifndef EBH_H_ 36 1.1 ahoka #define EBH_H_ 37 1.1 ahoka 38 1.2 ttoth #ifdef _KERNEL 39 1.1 ahoka #include <sys/param.h> 40 1.1 ahoka #include <sys/kernel.h> 41 1.1 ahoka #include <sys/cdefs.h> 42 1.1 ahoka #include <sys/stdint.h> 43 1.1 ahoka #include <sys/types.h> 44 1.1 ahoka #include <sys/tree.h> 45 1.1 ahoka #include <sys/queue.h> 46 1.1 ahoka #include <sys/kmem.h> 47 1.1 ahoka #include <sys/endian.h> 48 1.1 ahoka #include <sys/rwlock.h> 49 1.1 ahoka #include <sys/condvar.h> 50 1.1 ahoka #include <sys/mutex.h> 51 1.1 ahoka #include <sys/kthread.h> 52 1.1 ahoka 53 1.1 ahoka #include <dev/flash/flash.h> 54 1.2 ttoth #include "debug.h" 55 1.2 ttoth #include "ebh_misc.h" 56 1.2 ttoth #endif /* _KERNEL */ 57 1.1 ahoka 58 1.2 ttoth #include "ebh_media.h" 59 1.2 ttoth 60 1.2 ttoth /** 61 1.2 ttoth * struct chfs_eb_hdr - in-memory representation of eraseblock headers 62 1.2 ttoth * @ec_hdr: erase counter header ob eraseblock 63 1.2 ttoth * @u.nor_hdr: eraseblock header on NOR flash 64 1.2 ttoth * @u.nand_hdr: eraseblock header on NAND flash 65 1.2 ttoth */ 66 1.2 ttoth struct chfs_eb_hdr { 67 1.2 ttoth struct chfs_eb_ec_hdr ec_hdr; 68 1.2 ttoth union { 69 1.2 ttoth struct chfs_nor_eb_hdr nor_hdr; 70 1.2 ttoth struct chfs_nand_eb_hdr nand_hdr; 71 1.2 ttoth } u; 72 1.2 ttoth }; 73 1.2 ttoth 74 1.2 ttoth #ifdef _KERNEL 75 1.1 ahoka /* Maximum retries when getting new PEB before exit with failure */ 76 1.1 ahoka #define CHFS_MAX_GET_PEB_RETRIES 2 77 1.1 ahoka 78 1.1 ahoka /** 79 1.1 ahoka * LEB status 80 1.1 ahoka * 81 1.1 ahoka */ 82 1.1 ahoka enum { 83 1.1 ahoka EBH_LEB_UNMAPPED = -1, 84 1.1 ahoka EBH_LEB_MAPPED, 85 1.1 ahoka EBH_LEB_DIRTY, 86 1.1 ahoka EBH_LEB_INVALID, 87 1.1 ahoka EBH_LEB_ERASE, 88 1.1 ahoka EBH_LEB_ERASED, 89 1.1 ahoka EBH_LEB_FREE, 90 1.1 ahoka }; 91 1.1 ahoka 92 1.1 ahoka /** 93 1.1 ahoka * EB header status 94 1.1 ahoka */ 95 1.1 ahoka enum { 96 1.1 ahoka EBHDR_LEB_OK = 0, 97 1.1 ahoka EBHDR_LEB_DIRTY, 98 1.1 ahoka EBHDR_LEB_INVALIDATED, 99 1.1 ahoka EBHDR_LEB_BADMAGIC, 100 1.1 ahoka EBHDR_LEB_BADCRC, 101 1.1 ahoka EBHDR_LEB_FREE, 102 1.1 ahoka EBHDR_LEB_NO_HDR, 103 1.1 ahoka }; 104 1.1 ahoka 105 1.1 ahoka struct chfs_ebh; 106 1.1 ahoka 107 1.1 ahoka /** 108 1.4 dholland * struct chfs_ltree_entry - an entry in the lock tree 109 1.1 ahoka * @rb: RB-node of the tree 110 1.1 ahoka * @lnr: logical eraseblock number 111 1.1 ahoka * @users: counts the tasks that are using or want to use the eraseblock 112 1.1 ahoka * @mutex: read/write mutex to lock the eraseblock 113 1.1 ahoka */ 114 1.1 ahoka struct chfs_ltree_entry { 115 1.1 ahoka RB_ENTRY(chfs_ltree_entry) rb; 116 1.1 ahoka int lnr; 117 1.1 ahoka int users; 118 1.1 ahoka krwlock_t mutex; 119 1.1 ahoka }; 120 1.1 ahoka 121 1.1 ahoka /* Generate structure for Lock tree's red-black tree */ 122 1.1 ahoka RB_HEAD(ltree_rbtree, chfs_ltree_entry); 123 1.1 ahoka 124 1.1 ahoka 125 1.1 ahoka /** 126 1.5 andvar * struct chfs_scan_leb - scanning information about a physical eraseblock 127 1.1 ahoka * @erase_cnt: erase counter 128 1.1 ahoka * @pebnr: physical eraseblock number 129 1.1 ahoka * @info: the status of the PEB's eraseblock header when NOR serial when NAND 130 1.1 ahoka * @u.list: link in one of the eraseblock list 131 1.1 ahoka * @u.rb: link in the used RB-tree of chfs_scan_info 132 1.1 ahoka */ 133 1.1 ahoka struct chfs_scan_leb { 134 1.1 ahoka int erase_cnt; 135 1.1 ahoka int pebnr; 136 1.1 ahoka int lnr; 137 1.1 ahoka uint64_t info; 138 1.1 ahoka union { 139 1.1 ahoka TAILQ_ENTRY(chfs_scan_leb) queue; 140 1.1 ahoka RB_ENTRY(chfs_scan_leb) rb; 141 1.1 ahoka } u; 142 1.1 ahoka }; 143 1.1 ahoka 144 1.1 ahoka TAILQ_HEAD(scan_leb_queue, chfs_scan_leb); 145 1.1 ahoka RB_HEAD(scan_leb_used_rbtree, chfs_scan_leb); 146 1.1 ahoka 147 1.1 ahoka 148 1.1 ahoka /** 149 1.1 ahoka * struct chfs_scan_info - chfs scanning information 150 1.1 ahoka * @corrupted: queue of corrupted physical eraseblocks 151 1.1 ahoka * @free: queue of free physical eraseblocks 152 1.1 ahoka * @erase: queue of the physical eraseblocks signed to erase 153 1.1 ahoka * @erased: queue of physical eraseblocks that contain no header 154 1.1 ahoka * @used: RB-tree of used PEBs describing by chfs_scan_leb 155 1.1 ahoka * @sum_of_ec: summary of erase counters 156 1.1 ahoka * @num_of_eb: number of free and used eraseblocks 157 1.1 ahoka * @bad_peb_cnt: counter of bad eraseblocks 158 1.1 ahoka * 159 1.1 ahoka * This structure contains information about the scanning for further 160 1.1 ahoka * processing. 161 1.1 ahoka */ 162 1.1 ahoka struct chfs_scan_info { 163 1.1 ahoka struct scan_leb_queue corrupted; 164 1.1 ahoka struct scan_leb_queue free; 165 1.1 ahoka struct scan_leb_queue erase; 166 1.1 ahoka struct scan_leb_queue erased; 167 1.1 ahoka struct scan_leb_used_rbtree used; 168 1.1 ahoka uint64_t sum_of_ec; 169 1.1 ahoka int num_of_eb; 170 1.1 ahoka int bad_peb_cnt; 171 1.1 ahoka }; 172 1.1 ahoka 173 1.1 ahoka /** 174 1.1 ahoka * struct chfs_peb - PEB information for erasing and wear leveling 175 1.1 ahoka * @erase_cnt: erase counter of the physical eraseblock 176 1.1 ahoka * @pebnr: physical eraseblock number 177 1.1 ahoka * @u.queue: link to the queue of the PEBs waiting for erase 178 1.1 ahoka * @u.rb: link to the RB-tree to the free PEBs 179 1.1 ahoka */ 180 1.1 ahoka struct chfs_peb { 181 1.1 ahoka int erase_cnt; 182 1.1 ahoka int pebnr; 183 1.1 ahoka union { 184 1.1 ahoka TAILQ_ENTRY(chfs_peb) queue; 185 1.1 ahoka RB_ENTRY(chfs_peb) rb; 186 1.1 ahoka } u; 187 1.1 ahoka }; 188 1.1 ahoka 189 1.1 ahoka /* Generate queue and rb-tree structures. */ 190 1.1 ahoka TAILQ_HEAD(peb_queue, chfs_peb); 191 1.1 ahoka RB_HEAD(peb_free_rbtree, chfs_peb); 192 1.1 ahoka RB_HEAD(peb_in_use_rbtree, chfs_peb); 193 1.1 ahoka 194 1.1 ahoka 195 1.1 ahoka /* 196 1.1 ahoka * struct chfs_ebh_ops - collection of operations which 197 1.1 ahoka * depends on flash type 198 1.1 ahoka * *************************************************************************** * 199 1.1 ahoka * Direct flash operations: 200 1.1 ahoka * 201 1.1 ahoka * @read_eb_hdr: read eraseblock header from media 202 1.1 ahoka * @write_eb_hdr: write eraseblock header to media 203 1.1 ahoka * @check_eb_hdr: validates eraseblock header 204 1.1 ahoka * @mark_eb_hdr_dirty_flash: marks eraseblock dirty on flash 205 1.1 ahoka * @invalidate_eb_hdr: invalidates eraseblock header 206 1.1 ahoka * @mark_eb_hdr_free: marks eraseblock header free (after erase) 207 1.1 ahoka * *************************************************************************** * 208 1.1 ahoka * Scanning operations: 209 1.1 ahoka * 210 1.1 ahoka * @process_eb: process an eraseblock information at scan 211 1.1 ahoka * *************************************************************************** * 212 1.1 ahoka * Misc operations: 213 1.1 ahoka * 214 1.1 ahoka * @create_eb_hdr: creates an eraseblock header based on flash type 215 1.1 ahoka * @calc_data_offs: calculates where the data starts 216 1.1 ahoka */ 217 1.1 ahoka struct chfs_ebh_ops { 218 1.1 ahoka int (*read_eb_hdr)(struct chfs_ebh *ebh, int pebnr, 219 1.1 ahoka struct chfs_eb_hdr *ebhdr); 220 1.1 ahoka int (*write_eb_hdr)(struct chfs_ebh *ebh, int pebnr, 221 1.1 ahoka struct chfs_eb_hdr *ebhdr); 222 1.1 ahoka int (*check_eb_hdr)(struct chfs_ebh *ebh, void *buf); 223 1.1 ahoka int (*mark_eb_hdr_dirty_flash)(struct chfs_ebh *ebh, int pebnr, int lid); 224 1.1 ahoka int (*invalidate_eb_hdr)(struct chfs_ebh *ebh, int pebnr); 225 1.1 ahoka int (*mark_eb_hdr_free)(struct chfs_ebh *ebh, int pebnr, int ec); 226 1.1 ahoka 227 1.1 ahoka int (*process_eb)(struct chfs_ebh *ebh, struct chfs_scan_info *si, 228 1.1 ahoka int pebnr, struct chfs_eb_hdr *ebhdr); 229 1.1 ahoka 230 1.1 ahoka int (*create_eb_hdr)(struct chfs_eb_hdr *ebhdr, int lnr); 231 1.1 ahoka int (*calc_data_offs)(struct chfs_ebh *ebh, int pebnr, int offset); 232 1.1 ahoka }; 233 1.1 ahoka 234 1.1 ahoka /** 235 1.1 ahoka * struct erase_thread - background thread for erasing 236 1.1 ahoka * @thread: pointer to thread structure 237 1.1 ahoka * @wakeup: conditional variable for sleeping if there isn't any job to do 238 1.1 ahoka * @running: flag to signal a thread shutdown 239 1.1 ahoka */ 240 1.1 ahoka struct erase_thread { 241 1.1 ahoka lwp_t *eth_thread; 242 1.1 ahoka kcondvar_t eth_wakeup; 243 1.1 ahoka bool eth_running; 244 1.1 ahoka }; 245 1.1 ahoka 246 1.1 ahoka 247 1.1 ahoka /** 248 1.1 ahoka * struct chfs_ebh - eraseblock handler descriptor 249 1.1 ahoka * @mtd: mtd device descriptor 250 1.1 ahoka * @eb_size: eraseblock size 251 1.1 ahoka * @peb_nr: number of PEBs 252 1.1 ahoka * @lmap: LEB to PEB mapping 253 1.1 ahoka * @layout_map: the LEBs layout (NOT USED YET) 254 1.1 ahoka * @ltree: the lock tree 255 1.1 ahoka * @ltree_lock: protects the tree 256 1.1 ahoka * @alc_mutex: serializes "atomic LEB change" operation 257 1.5 andvar * @free: RB-tree of the free eraseblocks 258 1.1 ahoka * @in_use: RB-tree of PEBs are in use 259 1.1 ahoka * @to_erase: list of the PEBs waiting for erase 260 1.1 ahoka * @fully_erased: list of PEBs that have been erased but don't have header 261 1.1 ahoka * @erase_lock: list and tree lock for fully_erased and to_erase lists and 262 1.1 ahoka * for the free RB-tree 263 1.5 andvar * @bg_erase: background thread for erasing PEBs. 264 1.1 ahoka * @ops: collection of operations which depends on flash type 265 1.1 ahoka * @max_serial: max serial number of eraseblocks, only used on NAND 266 1.1 ahoka */ 267 1.1 ahoka struct chfs_ebh { 268 1.1 ahoka struct peb_free_rbtree free; 269 1.1 ahoka struct peb_in_use_rbtree in_use; 270 1.1 ahoka struct peb_queue to_erase; 271 1.1 ahoka struct peb_queue fully_erased; 272 1.1 ahoka struct erase_thread bg_erase; 273 1.1 ahoka device_t flash_dev; 274 1.1 ahoka const struct flash_interface *flash_if; 275 1.1 ahoka struct chfs_ebh_ops *ops; 276 1.1 ahoka uint64_t *max_serial; 277 1.1 ahoka int *lmap; 278 1.1 ahoka //int *layout_map; 279 1.1 ahoka struct ltree_rbtree ltree; 280 1.1 ahoka //struct mutex alc_mutex; 281 1.1 ahoka kmutex_t ltree_lock; 282 1.1 ahoka kmutex_t alc_mutex; 283 1.1 ahoka kmutex_t erase_lock; 284 1.1 ahoka size_t eb_size; 285 1.1 ahoka size_t peb_nr; 286 1.1 ahoka flash_size_t flash_size; 287 1.1 ahoka }; 288 1.1 ahoka 289 1.1 ahoka /** 290 1.1 ahoka * struct chfs_erase_info_priv - private information for erase 291 1.1 ahoka * @ebh: eraseblock handler 292 1.1 ahoka * @peb: physical eraseblock information 293 1.1 ahoka */ 294 1.1 ahoka struct chfs_erase_info_priv { 295 1.1 ahoka struct chfs_ebh *ebh; 296 1.1 ahoka struct chfs_peb *peb; 297 1.1 ahoka }; 298 1.1 ahoka 299 1.1 ahoka /* ebh.c */ 300 1.1 ahoka 301 1.1 ahoka int ebh_open(struct chfs_ebh *ebh, dev_t dev); 302 1.1 ahoka int ebh_close(struct chfs_ebh *ebh); 303 1.1 ahoka int ebh_read_leb(struct chfs_ebh *ebh, int lnr, char *buf, 304 1.1 ahoka uint32_t offset, size_t len, size_t *retlen); 305 1.1 ahoka int ebh_write_leb(struct chfs_ebh *ebh, int lnr, char *buf, 306 1.1 ahoka uint32_t offset, size_t len, size_t *retlen); 307 1.1 ahoka int ebh_erase_leb(struct chfs_ebh *ebh, int lnr); 308 1.1 ahoka int ebh_map_leb(struct chfs_ebh *ebh, int lnr); 309 1.1 ahoka int ebh_unmap_leb(struct chfs_ebh *ebh, int lnr); 310 1.1 ahoka int ebh_is_mapped(struct chfs_ebh *ebh, int lnr); 311 1.1 ahoka int ebh_change_leb(struct chfs_ebh *ebh, int lnr, char *buf, 312 1.1 ahoka size_t len, size_t *retlen); 313 1.1 ahoka 314 1.2 ttoth #endif /* _KERNEL */ 315 1.1 ahoka 316 1.1 ahoka #endif /* EBH_H_ */ 317