Go to the documentation of this file.00001 #include "debug.h"
00002 #include "nand.h"
00003 #include "in_nand.h"
00004 #include "stat.h"
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <string.h>
00008
00009 #include <sys/stat.h>
00010 #include <sys/types.h>
00011
00012 #define NAND_FREE_PAGE -1
00013
00014 struct config_nand config_nand;
00015 static struct blk_info *nandblk=NULL;
00016
00017 FILE *fp;
00018
00019
00020
00021
00022 _u8 bit_find(_u32 number) {
00023 _u8 cnt=0;
00024 _u32 orig=number;
00025 while(number) {
00026 number>>=1;
00027 cnt++;
00028 }
00029 if(((_u32)(1<<(cnt-1)))<orig) return cnt;
00030 return cnt-1;
00031 }
00032
00033
00034
00035
00036
00037 int nand_open(void) {
00038 unsigned int i,j;
00039 _u32 datablks;
00040
00041 if(nandblk) nand_close();
00042
00043 config_nand.sect_per_page = SECT_PER_PAGE;
00044 config_nand.page_per_blk = PAGE_PER_BLK;
00045 config_nand.totalsize = TOTALSIZE_GB;
00046 config_nand.extrablks = EXTRABLKS;
00047
00048 datablks = config_nand.totalsize*1024*1024*2/config_nand.sect_per_page/config_nand.page_per_blk ;
00049
00050 config_nand.numblks = datablks + config_nand.extrablks;
00051
00052 config_nand.bit_sect_per_page = bit_find(config_nand.sect_per_page);
00053 config_nand.bit_page_per_blk = bit_find(config_nand.page_per_blk);
00054
00055 nandblk = (struct blk_info *)malloc(sizeof(struct blk_info)*config_nand.numblks);
00056 if(nandblk == NULL) {
00057 error("Out of memory\n");
00058 return -1;
00059 }
00060
00061 memset( nandblk, 0xFF, sizeof(struct blk_info) * config_nand.numblks);
00062
00063 for(i=0;i<config_nand.numblks;i++) {
00064 nandblk[i].cnterase = 0;
00065 nandblk[i].numwrite = 0;
00066 nandblk[i].numvalid = 0;
00067 nandblk[i].last_touched = 0;
00068 nandblk[i].pages = (_u32 *)malloc(sizeof(_u32) * config_nand.page_per_blk);
00069 for(j=0;j<config_nand.page_per_blk;j++) {
00070 nandblk[i].pages[j]=NAND_FREE_PAGE;
00071 }
00072 };
00073
00074 nand_stat_reset();
00075
00076 return 0;
00077 }
00078
00079
00080
00081
00082 void nand_close() {
00083 unsigned int i;
00084 if(nandblk) {
00085 for(i=0;i<config_nand.numblks;i++) {
00086 if(nandblk[i].pages) free(nandblk[i].pages);
00087 }
00088 free(nandblk);
00089 nandblk = NULL;
00090 }
00091
00092 }
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 _t_sect nand_page_read(unsigned int blk_no, unsigned int page_no,
00103 unsigned int lsn, int optStat) {
00104
00105
00106
00107
00108
00109 assert(blk_no < config_nand.numblks);
00110 assert(page_no < config_nand.page_per_blk);
00111 if(optStat==NAND_REQ_DATA) {
00112 assert(nandblk[blk_no].pages[page_no] == lsn);
00113 }
00114
00115 switch(optStat) {
00116 case NAND_REQ_GC:
00117 nand_stat.gc.read+=1;
00118 break;
00119 case NAND_REQ_DATA:
00120 default:
00121 nand_stat.data.read+=1;
00122 break;
00123 }
00124
00125 return nandblk[blk_no].pages[page_no];
00126 }
00127
00128
00129
00130
00131
00132
00133
00134
00135 void nand_page_write(unsigned int blk_no, unsigned int page_no,
00136 unsigned int lsn, int optStat) {
00137
00138
00139
00140
00141
00142
00143 assert(blk_no < config_nand.numblks);
00144 assert(page_no < config_nand.page_per_blk);
00145 assert(page_no >= nandblk[blk_no].last_touched);
00146 assert(nandblk[blk_no].pages[page_no] == NAND_FREE_PAGE);
00147
00148 nandblk[blk_no].pages[page_no] = lsn;
00149
00150 nandblk[blk_no].numwrite++;
00151 nandblk[blk_no].numvalid++;
00152 nandblk[blk_no].last_touched = page_no+1;
00153
00154 switch(optStat) {
00155 case NAND_REQ_GC:
00156 nand_stat.gc.write+=1;
00157 break;
00158 case NAND_REQ_DATA:
00159 default:
00160 nand_stat.data.write+=1;
00161 break;
00162 }
00163 }
00164
00165
00166
00167
00168
00169
00170 void nand_block_erase(unsigned int blk_no, int optStat) {
00171 int i;
00172
00173 assert(blk_no < config_nand.numblks);
00174
00175 nandblk[blk_no].cnterase += 1;
00176 nandblk[blk_no].numwrite = 0;
00177 nandblk[blk_no].numvalid = 0;
00178 nandblk[blk_no].last_touched = 0;
00179
00180 for(i=0;i<config_nand.page_per_blk;i++) {
00181 nandblk[blk_no].pages[i] = NAND_FREE_PAGE;
00182 }
00183
00184 switch(optStat) {
00185 case NAND_REQ_DATA:
00186 case NAND_REQ_GC:
00187 default:
00188 nand_stat.gc.erase += 1;
00189 break;
00190 }
00191 }
00192
00193