/* * tffs_nand.h * * Created on: 29.04.2014 * Author: tklaassen */ /*------------------------------------------------------------------------------------------*\ * * Copyright (C) 2004-2014 AVM GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA \*------------------------------------------------------------------------------------------*/ #ifndef TFFS_NAND_H_ #define TFFS_NAND_H_ #include #include #include #include #include #include "tffs_local.h" #define MIN_FREE_BLOCKS 0x2 #define OPT_FREE_BLOCKS 0x4 #define ANY_BLK_SEQ 0xffffffff #define TFFS_SEG_CLEARED 0xFFFFFFFF #define TFFS_ENTRY_MAGIC 0x544646535F4E3331 // TFFS_E31 #define MIN_WRITESIZE 0x1000 struct _TFFS_NAND_Entry { __be32 ID; __be32 Length; __be32 timestamp; __be32 revision_nr; __be32 segment_nr; __be32 next_segment; } __attribute__((packed)); struct _TFFS_NAND_OOB { __be32 ID; __be32 Length; __be32 Revision; } __attribute__((packed)); struct _TFFS_NAND_Entry_31 { __be64 magic; __be32 ID; __be32 Length; __be32 timestamp; __be32 revision_nr; __be32 segment_nr; __be32 next_segment; __be32 crc; } __attribute__((packed)); enum tffs_blk_state { tffs_blk_raw = 0, tffs_blk_bad, tffs_blk_init, tffs_blk_rescan, tffs_blk_active, }; enum tffs_srch_param { tffs_srch_min_spc, tffs_srch_max_spc, tffs_srch_min_seq, tffs_srch_max_seq, tffs_srch_min_erase, tffs_srch_max_erase, }; struct tffs_nand_ctx; struct TFFS_NAND_Entry; struct TFFS_NAND_Block { struct list_head blk_list; struct list_head blk_entry_list; // TODO: Don't need this here granted all blocks in a context have the same format. int (*write_entry)(struct tffs_nand_ctx *ctx, struct TFFS_NAND_Entry *entry, struct TFFS_NAND_Block *blk, uint8_t *data_buf, size_t data_len, size_t *retlen); int (*read_entry)(struct tffs_nand_ctx *ctx, struct TFFS_NAND_Entry *entry, loff_t offset, uint8_t *buffer, size_t *len); uint32_t entry_ver; size_t hdr_size; uint32_t sect_per_pg; uint32_t num_bad_pages; loff_t bad_pages[TFFS3_MAX_BADPAGES]; enum tffs_blk_state state; uint32_t needs_rewrite; loff_t blk_addr; uint32_t blkseq_nr; uint32_t erase_cnt; loff_t free_start; size_t free_space; size_t used_space; }; struct TFFS_Entry_Index; struct TFFS_NAND_SegChain; struct TFFS_NAND_Entry { struct list_head entry_list; struct list_head blk_entry_list; struct list_head segment_list; struct TFFS_NAND_Block *block_ptr; struct TFFS_NAND_SegChain *chain; loff_t blk_offset; size_t flash_len; // real length in flash, including padding and bad pages size_t padded_len; // real length in flash without bad pages uint32_t ID; uint32_t Length; time_t timestamp; uint32_t revision; uint32_t segment_nr; uint32_t next_segment; }; struct TFFS_NAND_SegChain { struct list_head rev_list; struct list_head segment_list; struct kref refcnt; struct TFFS_Entry_Index *idx; uint32_t ID; uint32_t revision; uint32_t complete; uint32_t corrupt_cnt; uint32_t prune; }; struct TFFS_Entry_Index { struct list_head index_list; struct list_head rev_list; uint32_t ID; uint32_t valid_rev; // highest revision number for ID with valid segment chain uint32_t max_rev; // highest revision number seen for ID, but data may be incomplete struct TFFS_NAND_SegChain *chain_ptr; }; struct TFFS_NAND_State { struct TFFS_NAND_Entry *curr_entry; struct TFFS_NAND_SegChain *chain; enum _tffs_id id; uint32_t corrupt_cnt; uint32_t finished; loff_t offset; uint32_t revision; uint32_t segment; uint32_t next_segment; uint32_t segment_size; }; struct tffs_nand_ctx { unsigned int mtd_num; loff_t raw_offset; struct mtd_info *mtd; uint8_t *rw_buffer; uint32_t buffer_size; uint32_t buffer_msk; uint32_t buffer_sft; uint64_t block_cnt; uint32_t pages_per_block; uint32_t sectors_per_page; uint32_t sector_size; uint32_t sector_sft; uint32_t sector_msk; uint32_t max_block_seq; struct { uint32_t no_oob:1; // NAND has no oob uint32_t got_tffs31_blocks:1; } flags; struct semaphore lock; struct TFFS_NAND_State panic_state; struct TFFS_NAND_Entry panic_entries[2]; struct mtd_info *panic_mtd; unsigned int in_panic_mode; struct tffs3_nand_funcs *panic_funcs; loff_t panic_offset; struct list_head blk_list; struct list_head entry_list; struct list_head index_list; void *notify_priv; tffs3_notify_fn notify_cb; }; #endif /* TFFS_NAND_H_ */ /* vim: set sw=4 ts=4 et ai cc=80 : */