aml_nftl.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. #ifndef __AML_NFTL_H
  2. #define __AML_NFTL_H
  3. #include <linux/kernel.h>
  4. #include <linux/types.h>
  5. #include <linux/errno.h>
  6. #include <linux/rbtree.h>
  7. #include <linux/platform_device.h>
  8. #include <linux/sched.h>
  9. #include <linux/slab.h>
  10. #include <linux/device.h>
  11. #include <linux/vmalloc.h>
  12. #include <linux/mutex.h>
  13. #include <linux/kthread.h>
  14. #include <linux/spinlock.h>
  15. #include <linux/notifier.h>
  16. #include <linux/mtd/blktrans.h>
  17. #include <linux/time.h>
  18. #pragma pack(1)
  19. typedef int16_t addr_sect_t; //-1 , free , 0~page , valid data
  20. typedef int16_t addr_blk_t;
  21. typedef int16_t erase_count_t;
  22. typedef int32_t addr_page_t;
  23. typedef int16_t addr_vtblk_t;
  24. typedef int32_t addr_logic_t;
  25. typedef int32_t addr_physical_t;
  26. typedef int16_t addr_linearblk_t;
  27. #define aml_nftl_malloc(n) kzalloc(n, GFP_KERNEL)
  28. #define aml_nftl_free kfree
  29. #define aml_nftl_dbg printk
  30. /**
  31. */
  32. //addr_sect_t nftl_get_sector(addr_sect_t addr,sect_map_t logic_map);
  33. //#define NFTL_DONT_CACHE_DATA
  34. #define AML_NFTL_MAGIC "aml_nftl"
  35. #define AML_NFTL_MAJOR 250
  36. #define TIMESTAMP_LENGTH 15
  37. #define MAX_TIMESTAMP_NUM ((1<<(TIMESTAMP_LENGTH-1))-1)
  38. #define MAX_PAGES_IN_BLOCK 256
  39. #define MAX_BLKS_PER_SECTOR 128
  40. #define MAX_BLK_NUM_PER_NODE 4
  41. #define BASIC_BLK_NUM_PER_NODE 2
  42. #define DEFAULT_SPLIT_UNIT 8
  43. #define NFTL_FAT_TABLE_NUM 8
  44. #define DEFAULT_SPLIT_UNIT_GARBAGE 8
  45. #define NFTL_BOUNCE_FREE 0
  46. #define NFTL_BOUNCE_USED 1
  47. #define NFTL_MAX_SCHEDULE_TIMEOUT 1000
  48. #define NFTL_FLUSH_DATA_TIME 8
  49. #define NFTL_CACHE_STATUS_IDLE 0
  50. #define NFTL_CACHE_STATUS_READY 1
  51. #define NFTL_CACHE_STATUS_READY_DONE 2
  52. #define NFTL_CACHE_STATUS_DONE 3
  53. #define NFTL_CACHE_FORCE_WRITE_LEN 16
  54. #define CACHE_CLEAR_ALL 1
  55. #define AML_NFTL_BOUNCE_SIZE 0x40000
  56. #define AML_LIMIT_FACTOR 4
  57. #define DO_COPY_PAGE 1
  58. #define DO_COPY_PAGE_TOTAL 2
  59. #define DO_COPY_PAGE_AVERAGELY 3
  60. #define AVERAGELY_COPY_NUM 2
  61. #define READ_OPERATION 0
  62. #define WRITE_OPERATION 1
  63. #define CACHE_LIST_NOT_FOUND 1
  64. #define WL_DELTA 397
  65. #define BLOCK_INIT_VALUE 0xffff
  66. #define MAKE_EC_BLK(ec, blk) ((ec<<16)|blk)
  67. #define SECTOR_GAP 0x1000
  68. #define SECTOR_GAP_MASK (SECTOR_GAP-1)
  69. #define ROOT_SECT (0*SECTOR_GAP)
  70. #define LEAF_SECT (1*SECTOR_GAP)
  71. #define SROOT_SECT (2*SECTOR_GAP)
  72. #define SLEAF_SECT (3*SECTOR_GAP)
  73. #define SEND_SECT (4*SECTOR_GAP)
  74. #define NODE_ROOT 0x1
  75. #define NODE_LEAF 0x2
  76. #define DEFAULT_IDLE_FREE_BLK 12
  77. #define STATUS_BAD_BLOCK 0
  78. #define STATUS_GOOD_BLOCK 1
  79. typedef enum {
  80. AML_NFTL_SUCCESS =0,
  81. AML_NFTL_FAILURE =1,
  82. AML_NFTL_INVALID_PARTITION =2,
  83. AML_NFTL_INVALID_ADDRESS =3,
  84. AML_NFTL_DELETED_SECTOR =4,
  85. AML_NFTL_FLUSH_ERROR =5,
  86. AML_NFTL_UNFORMATTED =6,
  87. AML_NFTL_UNWRITTEN_SECTOR =7,
  88. AML_NFTL_PAGENOTFOUND =0x08,
  89. AML_NFTL_NO_FREE_BLOCKS =0x10,
  90. AML_NFTL_STRUCTURE_FULL =0x11,
  91. AML_NFTL_NO_INVALID_BLOCKS =0x12,
  92. AML_NFTL_SECTORDELETED =0x50,
  93. AML_NFTL_ABT_FAILURE =0x51,
  94. AML_NFTL_MOUNTED_PARTITION =0,
  95. AML_NFTL_UNMOUNTED_PARTITION =1,
  96. AML_NFTL_SPAREAREA_ERROR =0x13,
  97. AML_NFTL_STATIC_WL_FINISH =0x14,
  98. AML_NFTL_BLKNOTFOUND =0x15
  99. }t_AML_NFTL_error;
  100. //typedef struct vtblk_node_s vtblk_node_t;
  101. //typedef struct phyblk_node_s phyblk_node_t;
  102. ///** storage structure ** /
  103. //typedef struct aml_nftl_oob_info_s nftl_oobinfo_t;
  104. struct nftl_oobinfo_t{
  105. addr_sect_t sect;
  106. erase_count_t ec; //00, Bad
  107. addr_vtblk_t vtblk; //-1 , free,-2~-10, Snapshot
  108. unsigned timestamp: 15;
  109. unsigned status_page: 1;
  110. };
  111. struct phyblk_node_t{
  112. erase_count_t ec;
  113. int16_t valid_sects;
  114. addr_vtblk_t vtblk;
  115. addr_sect_t last_write;//offset_validation
  116. int16_t status_page;
  117. int16_t timestamp;
  118. addr_sect_t phy_page_map[MAX_PAGES_IN_BLOCK];
  119. uint8_t phy_page_delete[MAX_PAGES_IN_BLOCK>>3];
  120. };
  121. struct vtblk_node_t {
  122. addr_blk_t phy_blk_addr;
  123. struct vtblk_node_t *next;
  124. };
  125. /*struct vtblk_special_node_t {
  126. struct vtblk_node_t *vtblk_node;
  127. addr_blk_t ext_phy_blk_addr;
  128. };*/
  129. struct write_cache_node {
  130. struct list_head list;
  131. unsigned char *buf;
  132. int8_t bounce_buf_num;
  133. uint32_t vt_sect_addr;
  134. unsigned char cache_fill_status[MAX_BLKS_PER_SECTOR]; //blk unit fill status every vitual sector
  135. };
  136. struct free_sects_list {
  137. struct list_head list;
  138. uint32_t vt_sect_addr;
  139. unsigned char free_blk_status[MAX_BLKS_PER_SECTOR];
  140. };
  141. struct wl_rb_t {
  142. struct rb_node rb_node;
  143. uint16_t blk; /*linear block*/
  144. uint16_t ec; /*erase count*/
  145. };
  146. struct wl_list_t {
  147. struct list_head list;
  148. addr_blk_t vt_blk; /*logical block*/
  149. addr_blk_t phy_blk;
  150. };
  151. struct gc_blk_list {
  152. struct list_head list;
  153. addr_blk_t gc_blk_addr;
  154. };
  155. /**
  156. * tree root & node count
  157. */
  158. struct wl_tree_t {
  159. struct rb_root root; /*tree root*/
  160. uint16_t count; /*number of nodes in this tree*/
  161. };
  162. struct aml_nftl_blk_t;
  163. struct aml_nftl_ops_t;
  164. struct aml_nftl_info_t;
  165. struct aml_nftl_wl_t;
  166. struct aml_nftl_ops_t{
  167. int (*read_page)(struct aml_nftl_info_t * aml_nftl_info, addr_blk_t blk_addr, addr_page_t page_addr, unsigned char *data_buf, unsigned char *nftl_oob_buf, int oob_len);
  168. int (*write_page)(struct aml_nftl_info_t * aml_nftl_info, addr_blk_t blk_addr, addr_page_t page_addr, unsigned char *data_buf, unsigned char *nftl_oob_buf, int oob_len);
  169. int (*read_page_oob)(struct aml_nftl_info_t *aml_nftl_info, addr_blk_t blk_addr, addr_page_t page_addr, unsigned char * nftl_oob_buf, int oob_len);
  170. int (* blk_isbad)(struct aml_nftl_info_t *aml_nftl_info, addr_blk_t blk_addr);
  171. int (* blk_mark_bad)(struct aml_nftl_info_t *aml_nftl_info, addr_blk_t blk_addr);
  172. int (* erase_block)(struct aml_nftl_info_t * aml_nftl_info, addr_blk_t blk_addr);
  173. };
  174. /**
  175. * weal leveling structure
  176. */
  177. struct aml_nftl_wl_t {
  178. /*tree for erased free blocks, dirty free blocks, used blocks*/
  179. struct wl_tree_t erased_root;
  180. struct wl_tree_t free_root;
  181. struct wl_tree_t used_root;
  182. /*list for dynamic wl(leaf blocks), read ecc error blocks*/
  183. struct wl_list_t readerr_head;
  184. struct list_head gc_blk_list;
  185. /*static wl threshold*/
  186. uint32_t wl_delta;
  187. uint32_t cur_delta;
  188. uint8_t gc_need_flag;
  189. addr_blk_t gc_start_block;
  190. addr_blk_t wait_gc_block;
  191. addr_sect_t page_copy_per_gc;
  192. /*
  193. * pages per physical block & total blocks, get from hardware layer,
  194. * init in function nftl_wl_init
  195. */
  196. uint16_t pages_per_blk;
  197. struct aml_nftl_info_t *aml_nftl_info;
  198. void (*add_free)(struct aml_nftl_wl_t *wl, addr_blk_t blk);
  199. void (*add_erased)(struct aml_nftl_wl_t *wl, addr_blk_t blk);
  200. void (*add_used)(struct aml_nftl_wl_t *wl, addr_blk_t blk);
  201. void (*add_gc)(struct aml_nftl_wl_t *wl, addr_blk_t blk);
  202. int32_t (*get_best_free)(struct aml_nftl_wl_t *wl, addr_blk_t *blk);
  203. /*nftl node info adapter function*/
  204. int (*garbage_one)(struct aml_nftl_wl_t *aml_nftl_wl, addr_blk_t vt_blk, uint8_t gc_flag);
  205. //int (*gc_structure_full)(struct aml_nftl_wl_t *aml_nftl_wl, addr_page_t logic_page_addr, unsigned char *buf);
  206. int (*garbage_collect)(struct aml_nftl_wl_t *aml_nftl_wl, uint8_t gc_flag);
  207. };
  208. struct aml_nftl_blk_t{
  209. struct mtd_blktrans_dev mbd;
  210. struct request *req;
  211. struct request_queue *queue;
  212. struct scatterlist *sg;
  213. struct notifier_block nb;
  214. struct timespec ts_write_start;
  215. char *bounce_buf;
  216. int8_t bounce_buf_free[NFTL_CACHE_FORCE_WRITE_LEN];
  217. struct scatterlist *bounce_sg;
  218. unsigned int bounce_sg_len;
  219. struct list_head cache_list;
  220. struct list_head free_list;
  221. struct mutex cache_mutex;
  222. int cache_sect_addr;
  223. unsigned char *cache_buf;
  224. uint8_t cache_buf_status;
  225. int8_t cache_buf_cnt;
  226. struct task_struct *nftl_thread;
  227. spinlock_t thread_lock;
  228. struct aml_nftl_info_t *aml_nftl_info;
  229. int (*read_data)(struct aml_nftl_blk_t *aml_nftl_blk, unsigned long block, unsigned nblk, unsigned char *buf);
  230. int (*write_data)(struct aml_nftl_blk_t *aml_nftl_blk, unsigned long block, unsigned nblk, unsigned char *buf);
  231. int (*write_cache_data)(struct aml_nftl_blk_t *aml_nftl_blk, uint8_t cache_flag);
  232. int (*search_cache_list)(struct aml_nftl_blk_t *aml_nftl_blk, uint32_t sect_addr, uint32_t blk_pos, uint32_t blk_num, unsigned char *buf);
  233. int (*add_cache_list)(struct aml_nftl_blk_t *aml_nftl_blk, uint32_t sect_addr, uint32_t blk_pos, uint32_t blk_num, unsigned char *buf);
  234. };
  235. struct aml_nftl_info_t{
  236. struct mtd_info *mtd;
  237. uint32_t writesize;
  238. uint32_t oobsize;
  239. uint32_t pages_per_blk;
  240. uint32_t startblock;
  241. uint32_t endBlock;
  242. uint32_t accessibleblocks;
  243. uint8_t isinitialised;
  244. uint16_t cur_split_blk;
  245. uint32_t fillfactor;
  246. addr_blk_t current_write_block;
  247. addr_sect_t continue_writed_sects;
  248. unsigned char *copy_page_buf;
  249. void **vtpmt;
  250. struct phyblk_node_t *phypmt;
  251. struct aml_nftl_ops_t *aml_nftl_ops;
  252. struct aml_nftl_wl_t *aml_nftl_wl;
  253. struct class cls;
  254. int (*read_page)(struct aml_nftl_info_t *aml_nftl_info, addr_blk_t blk_addr, addr_page_t page_addr, unsigned char *data_buf, unsigned char *nftl_oob_buf, int oob_len);
  255. int (*write_page)(struct aml_nftl_info_t *aml_nftl_info, addr_blk_t blk_addr, addr_page_t page_addr, unsigned char *data_buf, unsigned char *nftl_oob_buf, int oob_len);
  256. int (* copy_page)(struct aml_nftl_info_t *aml_nftl_info, addr_blk_t dest_blk_addr, addr_page_t dest_page, addr_blk_t src_blk_addr, addr_page_t src_page);
  257. int (*get_page_info)(struct aml_nftl_info_t *aml_nftl_info, addr_blk_t blk_addr, addr_page_t page_addr, unsigned char * nftl_oob_buf, int oob_len);
  258. int (* blk_isbad)(struct aml_nftl_info_t *aml_nftl_info, addr_blk_t blk_addr);
  259. int (* blk_mark_bad)(struct aml_nftl_info_t *aml_nftl_info, addr_blk_t blk_addr);
  260. int (* get_phy_sect_map)(struct aml_nftl_info_t *aml_nftl_info, addr_blk_t blk_addr);
  261. int (* erase_block)(struct aml_nftl_info_t *aml_nftl_info, addr_blk_t blk_addr);
  262. int (* delete_sector)(struct aml_nftl_info_t *aml_nftl_info,addr_page_t page,uint32_t len);
  263. int (*read_sect)(struct aml_nftl_info_t *aml_nftl_info, addr_page_t sect_addr, unsigned char *buf);
  264. int (*write_sect)(struct aml_nftl_info_t *aml_nftl_info, addr_page_t sect_addr, unsigned char *buf);
  265. void (*delete_sect)(struct aml_nftl_info_t *aml_nftl_info, addr_page_t sect_addr);
  266. void (*creat_structure)(struct aml_nftl_info_t *aml_nftl_info);
  267. };
  268. #pragma pack()
  269. static inline unsigned int aml_nftl_get_node_length(struct aml_nftl_info_t *aml_nftl_info, struct vtblk_node_t *vt_blk_node)
  270. {
  271. unsigned int node_length = 0;
  272. while (vt_blk_node != NULL) {
  273. node_length++;
  274. vt_blk_node = vt_blk_node->next;
  275. }
  276. return node_length;
  277. }
  278. extern void aml_nftl_ops_init(struct aml_nftl_info_t *aml_nftl_info);
  279. extern int aml_nftl_initialize(struct aml_nftl_blk_t *aml_nftl_blk);
  280. extern void aml_nftl_info_release(struct aml_nftl_info_t *aml_nftl_info);
  281. extern int aml_nftl_wl_init(struct aml_nftl_info_t *aml_nftl_info);
  282. extern int aml_nftl_check_node(struct aml_nftl_info_t *aml_nftl_info, addr_blk_t blk_addr);
  283. extern int aml_nftl_add_node(struct aml_nftl_info_t *aml_nftl_info, addr_blk_t logic_blk_addr, addr_blk_t phy_blk_addr);
  284. extern int aml_nftl_badblock_handle(struct aml_nftl_info_t *aml_nftl_info, addr_blk_t phy_blk_addr, addr_blk_t logic_blk_addr);
  285. #endif