1 // Copyright 2018 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <inc/config.h> 8 9 #if INC_NDM 10 #include <stdlib.h> 11 #include <string.h> 12 #include <stdio_tfs.h> 13 #include <errno.h> 14 15 #include <sys.h> 16 #include <modules.h> 17 #include <kprivate/ndm.h> 18 19 /***********************************************************************/ 20 /* Configuration */ 21 /***********************************************************************/ 22 #undef NDM_DEBUG 23 #define NDM_DEBUG FALSE // TRUE for TargetNDM debug output 24 #define RDBACK_CHECK FALSE // TRUE for metadata read-back check 25 26 /***********************************************************************/ 27 /* Symbol Definitions */ 28 /***********************************************************************/ 29 #define CTRL_SIG_SZ 7 // ctrl sig bytes 30 #define CTRL_SIG "NDMTA01" 31 32 // 33 // Location in control header of all header fields. A header consists of: 34 // - 2 bytes of current page number in this control sequence 35 // - 2 bytes of last page number in this control sequence 36 // - 4 bytes of sequence number 37 // - 4 bytes of CRC 38 // 39 #define HDR_CURR_LOC 0 40 #define HDR_LAST_LOC 2 41 #define HDR_SEQ_LOC 4 42 #define HDR_CRC_LOC 8 43 #define HDR_SIZE 12 44 #define CTRL_DATA_START 12 45 46 // Control scan flag value 47 #define PARTIAL_SCAN 2 48 49 // Actions that can cause a block to go bad 50 #define ERASE_BLOCK 1 51 #define WRITE_PAGE 2// 52 53 // 54 // Layout for the spare area: 55 // - byte 0 - bad block mark byte 56 // - bytes 1 - 14 - reserved for the above layers - will be ECC-ed 57 // - byte 15 - NDM regular page mark byte 58 // - rest are left to the driver to place ECC codes in them 59 // 60 #define EB_BBLOCK_MARK 0 61 #define EB_FRST_RESERVED 1 62 #define EB_LAST_RESERVED 14 63 #define EB_REG_MARK 15 // NDM control page iff zero 64 65 /***********************************************************************/ 66 /* Type Declarations */ 67 /***********************************************************************/ 68 69 // <key, value> pair 70 typedef struct { 71 ui32 key; // vblk 72 ui32 val; // pblk 73 } Pair; 74 75 // NDM Control Block 76 struct ndm { 77 CircLink link; // linked list of NDM devices 78 ui32 num_vblks; // number of virtual blocks 79 SEM sem; // access semaphore 80 ui8* main_buf; // main page data buffer 81 ui8* spare_buf; // spare area buffer 82 ui8* tmp_spare; // temp buffer for driver transfer routine 83 ui32* init_bad_blk; // initial bad blocks list 84 Pair* run_bad_blk; // running bad blocks list 85 ui32 num_rbb; // number of blocks in running bad block list 86 ui32 num_bad_blks; // current total number of bad blocks 87 ui32 frst_reserved; // first block reserved for NDM 88 ui32 free_virt_blk; // next free block NDM uses for bad virtual 89 ui32 free_ctrl_blk; // next free block NDM uses for bad control 90 ui32 ctrl_blk0; // two blocks used for control info 91 ui32 ctrl_blk1; 92 ui32 frst_ctrl_page; // first page of control information 93 ui32 last_ctrl_page; // last page of control information 94 ui32 next_ctrl_start; // starting page of next control write 95 ui32 ctrl_pages; // number of control pages 96 ui32 ctrl_seq; // control information sequence number 97 ui32 xfr_tblk; // interrupted 'transfer to' block 98 ui32 xfr_fblk; // interrupted 'transfer from' block 99 ui32 xfr_bad_po; // bad page offset in 'transfer from' block 100 ui32 last_wr_vbn; // last virtual block number written to 101 ui32 last_wr_pbn; // last physical block number written to 102 ui32 last_rd_vbn; // last virtual block number read from 103 ui32 last_rd_pbn; // last physical block number read from 104 ui32 flags; // option flags 105 106 // Partition Information 107 ui32 num_partitions; 108 NDMPartition* partitions; 109 110 // Driver Functions 111 int (*write_page)(ui32 pn, const ui8* data, ui8* spare, int action, void* dev); 112 int (*write_pages)(ui32 pn, ui32 count, const ui8* data, ui8* spare, int action, void* dev); 113 int (*read_page)(ui32 pn, ui8* data, ui8* spare, void* dev); 114 int (*read_pages)(ui32 pn, ui32 count, ui8* data, ui8* spare, void* dev); 115 int (*xfr_page)(ui32 old_pn, ui32 new_pn, ui8* data, ui8* old_spare, ui8* new_spare, 116 int encode_spare, void* dev); 117 #if INC_FFS_NDM_MLC || INC_FTL_NDM_MLC 118 ui32 (*pair_offset)(ui32 page_offset, void* dev); 119 #endif 120 int (*read_decode_spare)(ui32 pn, ui8* spare, void* dev); 121 int (*read_spare)(ui32 pn, ui8* spare, void* dev); 122 int (*page_blank)(ui32 pn, ui8* data, ui8* spare, void* dev); 123 #if INC_FTL_NDM 124 int (*check_page)(ui32 pn, ui8* data, ui8* spr, int* stat, void* dev); 125 #endif 126 int (*erase_block)(ui32 pn, void* dev); 127 #if INC_FTL_NDM || INC_FFS_NDM 128 int (*is_block_bad)(ui32 pn, void* dev); 129 #endif 130 131 // Device Dependent Variables 132 void* dev; // optional value set by driver 133 void* dev_ndm; // driver/ndm handle used with transfer page 134 ui32 num_dev_blks; // number of device blocks 135 ui32 block_size; // block size in bytes 136 ui32 max_bad_blks; // maximum number of bad blocks 137 ui32 pgs_per_blk; // number of pages in a block 138 ui32 page_size; // page size in bytes 139 ui8 eb_size; // spare area size in bytes 140 ui8 dev_type; // NAND device type 141 }; 142 143 /***********************************************************************/ 144 /* Variable Declarations */ 145 /***********************************************************************/ 146 extern CircLink NdmDevs; 147 extern SEM NdmSem; 148 149 /***********************************************************************/ 150 /* Function Prototypes */ 151 /***********************************************************************/ 152 int ndmInitBadBlock(CNDM ndm, ui32 b); 153 int ndmWrCtrl(NDM ndm); 154 void ndmCkMeta(NDM ndm); 155 int ndmMarkBadBlock(NDM ndm, ui32 arg, ui32 action); 156 void* ndmAddFatFTL(NDM ndm, ui32 part_num, FtlNdmVol* ftl, FatVol* fat); 157 158 #if NDM_DEBUG 159 int printf(const char*, ...); 160 #endif 161 162 #endif // INC_NDM 163