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