📄 flsim.c
字号:
vol.read = sim_read; vol.map = sim_map; /* decide on which Translation Layer to work with */ if (simDoc->conf.flags & INFTL_ENABLED) { vol.flags &= (~NFTL_ENABLED); vol.flags |= INFTL_ENABLED; vol.readBBT = sim_read_BBT; } if (simDoc->conf.flags & NFTL_ENABLED) { vol.flags &= (~INFTL_ENABLED); vol.flags |= NFTL_ENABLED; } /* * Fill in data fields and access methods in struct FLFlash. * * NOTE: 'vol.type' was set to NOT_FLASH, and 'vol.mediaType' * to NOT_DOC_TYPE in flflash.c. */ vol.flags = (word) simDoc->conf.flags; vol.interleaving = (Sword) simDoc->conf.interlv; vol.chipSize = (dword) simDoc->conf.chip_size; vol.noOfChips = (word) simDoc->conf.chips; vol.noOfFloors = (byte) simDoc->conf.floors; vol.erasableBlockSize = (dword) simDoc->conf.block_size; vol.pageSize = (word) simDoc->conf.page_size; return flOK;}/* -------------------------------------------------------------------------- * * * * s i m _ r e a d * * * * Read up to one 512-byte block from flash. * * * * Parameters: * * vol : pointer identifying drive * * addr : address to read from * * buf : buffer to read to * * len : number of bytes to read (up to sector size) * * mode : EXTRA flag etc. * * * * Returns: * * * * flOK on success, otherwise respective error code * * * * -------------------------------------------------------------------------- */ static FLStatus sim_read ( FLFlash vol, CardAddress addr, void FAR1 * buf, dword len, word mode ){ FLSim_t * simDoc; FLSimConf_t * conf; long start_page; int offset; int bytes; int extra_per_sector; int sector_boundary; char * p; char * p2; /* simDoc configuration */ simDoc = (FLSim_t *) vol.mtdVars; conf = &simDoc->conf; /* part of page's extra area per sector */ extra_per_sector = conf->page_extra_size / (conf->page_size / SECTOR_SIZE); /* arguement sanity check */ start_page = addr / conf->page_size; offset = (int) (addr % conf->page_size); if (mode & EXTRA) { /* out-of-bound ? */ if( start_page > ((conf->chips * conf->chip_size) / conf->page_size) ) { DEBUG_PRINT(("FLSim: ERROR, out-of-bound EXTRA read.\n")); return flBadParameter; } /* 'EXTRA' read/write is limited to single extra area */ offset = conf->page_size + (extra_per_sector * (offset / SECTOR_SIZE)) + (offset % SECTOR_SIZE); if( (offset + len) > (conf->page_size + conf->page_extra_size) ) { DEBUG_PRINT(("FLSim: ERROR, reading past end of extra area.\n")); return flBadParameter; } } else { /* out-of-bound ? */ if( (addr + len) > (conf->chips * conf->chip_size) ) { DEBUG_PRINT(("FLSim: ERROR, out-of-bound read.\n")); return flBadParameter; } if( (mode & (EDC | PARTIAL_EDC)) == EDC ) { /* read/write must be aligned at and multiple of SECTOR_SIZE */ if( (addr % SECTOR_SIZE) != 0 ) { DEBUG_PRINT(("FLSim: ERROR, unaligned EDC read.\n")); return flBadParameter; } if( (len % SECTOR_SIZE) != 0 ) { DEBUG_PRINT(("FLSim: ERROR, EDC read isn't multiple of 512.\n")); return flBadParameter; } } } /* read data from simDoc */ if (mode & EXTRA) { /* 'EXTRA' read/write is limited to single extra area */ p = simDoc->flash + (int)(start_page * (conf->page_size + conf->page_extra_size)) + offset; tffscpy (buf, p, (int)len); /* update MTD statistics */ simDoc->stats.extra_read ++; simDoc->stats.bytes_extra_read += len; } else { /* read pages; 1st and last pages can be partial */ p = simDoc->flash + (int)(start_page * (conf->page_size + conf->page_extra_size)); while (len > 0) { /* read page */ bytes = conf->page_size - offset; if (bytes > len) bytes = (int)len; tffscpy (buf, p + offset, bytes); /* on full sectors, check EDC (if requested) */ sector_boundary = 0; p2 = p + conf->page_size; while (sector_boundary < conf->page_size) { if( (offset <= sector_boundary) && ((sector_boundary + SECTOR_SIZE) <= (offset + bytes)) ) { /* check for corrupted EDC/ECC checksum */ if( ((mode & (EDC | PARTIAL_EDC)) == EDC) && (conf->ecc_size > 0) ) { if( memcmp(p2, sim_dummy_edc, conf->ecc_size) != 0 ) { DEBUG_PRINT(("FLSim: ERROR, corrupted ECC/EDC.\n")); return flDataError; } } } sector_boundary += SECTOR_SIZE; p2 += extra_per_sector; } /* update MTD statistics */ simDoc->stats.pages_read ++; simDoc->stats.bytes_read += bytes; /* move on to next page */ offset = 0; len -= bytes; buf = (char FAR1 *)buf + bytes; p += (conf->page_size + conf->page_extra_size); } } return flOK;}/* -------------------------------------------------------------------------- * * * * s i m _ w r i t e * * * * This is MTD standard "write" routine. * * * * Parameters: * * * * vol : pointer identifying drive * * addr : address of sector to write to * * buf : buffer to write from * * len : number of bytes to write * * mode : OVERWRITE, EDC flags etc. * * * * Returns: * * * * flOK on success, otherwise respective error code * * * * -------------------------------------------------------------------------- */static FLStatus sim_write ( FLFlash vol, CardAddress addr, const void FAR1 * buf, dword len, word mode ){ FLSim_t * simDoc; FLSimConf_t * conf; long start_page; int offset; int bytes; int extra_per_sector; int iPage; int sector_boundary; char * p; char * p2; char ppp; static char sectorFlags[2] = { (char) 0x55, (char) 0x55 }; /* simDoc configuration */ simDoc = (FLSim_t *) vol.mtdVars; conf = &simDoc->conf; /* part of page's extra area per sector */ extra_per_sector = conf->page_extra_size / (conf->page_size / SECTOR_SIZE); /* arguement sanity check */ start_page = addr / conf->page_size; offset = (int) (addr % conf->page_size); if (mode & EXTRA) { /* out-of-bound ? */ if( start_page > ((conf->chips * conf->chip_size) / conf->page_size) ) { DEBUG_PRINT(("FLSim: ERROR, out-of-bound EXTRA write.\n")); return flBadParameter; } /* 'EXTRA' read/write is limited to single extra area */ offset = conf->page_size + (extra_per_sector * (offset / SECTOR_SIZE)) + (offset % SECTOR_SIZE); if( (offset + len) > (conf->page_size + conf->page_extra_size) ) { DEBUG_PRINT(("FLSim: ERROR, writing past end of extra area.\n")); return flBadParameter; } } else { /* out-of-bound ? */ if( (addr + len) > (conf->chips * conf->chip_size) ) { DEBUG_PRINT(("FLSim: ERROR, out-of-bound write.\n")); return flBadParameter; } if( (mode & (EDC | PARTIAL_EDC)) == EDC ) { /* read/write must be aligned at and multiple of SECTOR_SIZE */ if( (addr % SECTOR_SIZE) != 0 ) { DEBUG_PRINT(("FLSim: ERROR, unaligned EDC write.\n")); return flBadParameter; } if( (len % SECTOR_SIZE) != 0 ) { DEBUG_PRINT(("FLSim: ERROR, EDC write isn't multiple of 512.\n")); return flBadParameter; } } } /* write data to simDoc */ if (mode & EXTRA) { /* over PPP limit ? */ checkStatus( sim_chk_ppp(simDoc, start_page, NULL) ); /* 'EXTRA' read/write is limited to single extra area */ p = simDoc->flash + (int)(start_page * (conf->page_size + conf->page_extra_size)) + offset; /* check if it's possible to write new data over existing one */ checkStatus( sim_chk_overwrite(p, buf, (int)len) ); tffscpy (p, buf, (int)len); /* update MTD statistics */ simDoc->stats.extra_written ++; simDoc->stats.bytes_extra_written += len; } else { /* write pages; 1st and last pages can be partial */ p = simDoc->flash + (int)(start_page * (conf->page_size + conf->page_extra_size)); iPage = 0; while (len > 0) { /* over PPP limit ? */ checkStatus( sim_chk_ppp(simDoc, start_page + iPage, &ppp) ); iPage ++; /* if not clean page, check if possible to overwrite existing data */ bytes = conf->page_size - offset; if (bytes > len) bytes = (int)len; if (ppp > 0) checkStatus( sim_chk_overwrite(p + offset, buf, bytes) ); /* write data to this page */ tffscpy (p + offset, buf, bytes); /* on full sectors, write EDC (if requested) and 2-byte sector flags */ sector_boundary = 0; p2 = p + conf->page_size; while (sector_boundary < conf->page_size) { if( (offset <= sector_boundary) && ((sector_boundary + SECTOR_SIZE) <= (offset + bytes)) ) { /* write EDC */ if( ((mode & (EDC | PARTIAL_EDC)) == EDC) && (conf->ecc_size > 0) ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -