📄 nandmtd.c
字号:
for ( ; length > 0 ; ) { if (writeNow > length) writeNow = length; /* turn off EDC on partial block write*/ status = writeOnePage(&vol, address, temp, writeNow, writeNow != 512 ? (modes & ~EDC) : modes); if (status != flOK) break;#ifdef VERIFY_AFTER_WRITE status = readOnePage (&vol, address, (char FAR1 *)flReadback, writeNow, (writeNow != SECTOR_SIZE ? (modes & ~EDC) : modes)); if((status != flOK) || (tffscmp(temp, flReadback, writeNow) != 0)) { status = flWriteFault; break; }#endif length -= writeNow; address += writeNow; temp += writeNow; /* align at sector */ writeNow = page; } return flOK ;}/*----------------------------------------------------------------------*//* n a n d E r a s e *//* *//* Erase number of blocks. This routine will be registered as the *//* erase routine for this MTD. *//* *//* Author: 王辉 Date:2004-8-21 *//* *//* Parameters: *//* vol : Pointer identifying drive *//* blockNo : First block to erase. *//* blocksToErase : Number of blocks to erase. *//* *//* Returns: *//* FLStatus : 0 on success, otherwise failed. *//* *//*----------------------------------------------------------------------*/static FLStatus nandMTDErase( FLFlash vol, int blockNo, /* start' block (0 .. chipNoOfBlocks-1)*/ int blocksToErase) /* Number of blocks to be erased */{ int i; FLStatus status = flOK; if (flWriteProtected(vol.socket)) return flWriteProtect; /* blockNo %= thisVars->noOfBlocks; */ /* within flash device */ if ( blockNo + blocksToErase > thisVars->noOfBlocks ) /* accross device boundary */ return flBadParameter; #ifdef DEBUG_PRINT DEBUG_PRINT("firstBlock = 0x%x, numOfBlock = 0x%x\n", blockNo, blocksToErase); #endif for ( i=0; i < blocksToErase; i++, blockNo++ ) { unsigned short pageNo = blockNo * PAGES_PER_BLOCK ; WRITE_COMMAND(SETUP_ERASE); WRITE_ADDRESS((unsigned char)pageNo); /* A9 ~ A16 */ WRITE_ADDRESS((unsigned char)(pageNo >> 8)); /* A17 ~ A22 */ WRITE_COMMAND(CONFIRM_ERASE); waitForReady(); if(readStatus() & FAIL) { status = flWriteFault; /* erase operation failed */ } #ifdef DEBUG_PRINT DEBUG_PRINT("ERASE: blockNo = 0x%x\n", blockNo); #endif if (status != flOK) /* reset flash device and abort */ { #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: erase failed in K9F6408U0C.\n"); #endif WRITE_COMMAND(RESET_FLASH); waitForReady(); break ; } } /* block loop */ return status;}/*----------------------------------------------------------------------*//* c d s n M a p *//* *//* Map through buffer. This routine will be registered as the map *//* routine for this MTD. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* address : Flash address to be mapped. *//* length : number of bytes to map. *//* *//* Returns: *//* Pointer to the buffer data was mapped to. *//* *//*----------------------------------------------------------------------*/static void FAR0 * nandMTDMap ( FLFlash vol, CardAddress address, int length ){ /* address -= 0x1000000;*/ nandMTDRead(&vol,address,thisBuffer,length, 0); vol.socket->remapped = TRUE; return (void FAR0 *)thisBuffer;}/*----------------------------------------------------------------------*//* i s K n o w n M e d i a *//* *//* Check if this flash media is supported. Initialize relevant fields *//* in data structures. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* vendorId_P : vendor ID read from chip. *//* chipId_p : chip ID read from chip. *//* dev : dev chips were accessed before this one. *//* *//* Returns: *//* TRUE if this media is supported, FALSE otherwise. *//* *//*----------------------------------------------------------------------*/static FLBoolean isKnownMedia( FLFlash vol, unsigned short vendorId_p, unsigned short chipId_p, int dev ){ if (dev == 1) { thisVars->vendorID = vendorId_p; /* remember for next chips */ thisVars->chipID = chipId_p; if (vendorId_p == 0xEC) /* Samsung */ { switch (chipId_p) { case 0x64: /* 2M */ case 0xEA: vol.type = KM29N16000_FLASH ; vol.chipSize = 0x200000L; return TRUE; case 0xE5: case 0xE3: /* 4M */ vol.type = KM29N32000_FLASH; vol.flags |= BIG_PAGE; vol.chipSize = 0x400000L; return TRUE; case 0xE6: /* 8M */ vol.type = K9F6408X0C_FLASH; vol.flags |= BIG_PAGE; vol.chipSize = 0x800000L; return TRUE; } } else if (vendorId_p == 0x8F) /* National */ { switch (chipId_p) { case 0x64: /* 2M */ vol.type = NM29N16_FLASH; vol.chipSize = 0x200000L; return TRUE; } } else if (vendorId_p == 0x98) /* Toshiba */ { vol.flags |= FULL_PAGE; /* no partial page programming */ switch (chipId_p) { case 0x64: /* 2M */ case 0xEA: vol.type = TC5816_FLASH; vol.chipSize = 0x200000L; return TRUE; case 0x6B: /* 4M */ case 0xE5: vol.type = TC5832_FLASH; vol.flags |= BIG_PAGE; vol.chipSize = 0x400000L; return TRUE; case 0xE6: /* 8M */ vol.type = TC5816_FLASH; vol.flags |= BIG_PAGE; vol.chipSize = 0x800000L; return TRUE; } } } else /* dev != 0*/ if( (vendorId_p == thisVars->vendorID) && (chipId_p == thisVars->chipID) ) return TRUE ; return FALSE ;}/*----------------------------------------------------------------------*//* r e a d F l a s h I D *//* *//* Read vendor and chip IDs, count flash devices. Initialize relevant *//* fields in data structures. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* interface : Pointer to window. *//* dev : dev chips were accessed before this one. *//* *//* Returns: *//* TRUE if this media is supported, FALSE otherwise. *//* *//*----------------------------------------------------------------------*/static int readFlashID (FLFlash vol, int dev){ unsigned char vendorId_p, chipId_p; WRITE_COMMAND(RESET_FLASH); waitForReady(); WRITE_COMMAND(READ_ID); WRITE_ADDRESS(0x00); /* Address. 1cycle */ READ_DATA(vendorId_p); READ_DATA(chipId_p); if (isKnownMedia(&vol, vendorId_p, chipId_p, dev) != TRUE) /* no chip or diff.*/ return FALSE ; /* type of flash */ /* set flash parameters*/ if ( dev == 1 ) { thisVars->pageAreaSize = 0x100 * vol.interleaving; thisVars->pageSize = (vol.flags & BIG_PAGE ? 0x200 : 0x100) * vol.interleaving; thisVars->tailSize = (vol.flags & BIG_PAGE ? 16 : 8) * vol.interleaving; thisVars->pageMask = thisVars->pageSize - 1 ; vol.erasableBlockSize = PAGES_PER_BLOCK * thisVars->pageSize; thisVars->noOfBlocks = (unsigned short)( (vol.chipSize * vol.interleaving) / vol.erasableBlockSize ) ; } return TRUE ;}/*----------------------------------------------------------------------*//* n a n d M T D I d e n t i f y *//* *//* Identify flash. This routine will be registered as the *//* identification routine for this MTD. *//* *//* Returns: *//* FLStatus: 0 on success, otherwise failed. *//* *//*----------------------------------------------------------------------*/FLStatus nandMTDIdentify(FLFlash vol){#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: Entering K9F6408U0C identification routine\n");#endif flSetWindowBusWidth(vol.socket,8);/* use 16-bits */ flSetWindowSpeed(vol.socket,120); /* 120 nsec. */ flSetWindowSize(vol.socket,2); /* 4 KBytes */ vol.mtdVars = &mtdVars[flSocketNoOf(vol.socket)]; /* get pointer to buffer (we assume SINGLE_BUFFER is not defined) */ thisVars->buffer = flBufferOf(flSocketNoOf(vol.socket)); vol.interleaving = 1; vol.noOfChips = 1; /* 以1为起始 */ if(readFlashID(&vol, vol.noOfChips) != TRUE ) { #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: did not identify K9F6408U0C flash media.\n"); #endif return flUnknownMedia; } /* Register our flash handlers */ vol.write = nandMTDWrite; vol.erase = nandMTDErase; vol.read = nandMTDRead; vol.map = nandMTDMap; vol.flags |= SUSPEND_FOR_WRITE;#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: Identified K9F6408U0C.\n");#endif return flOK;}#if FALSE/*----------------------------------------------------------------------*//* f l R e g i s t e r N A N D *//* *//* Registers this MTD for use *//* *//* Parameters: *//* None *//* *//* Returns: *//* FLStatus : 0 on success, otherwise failure *//*----------------------------------------------------------------------*/FLStatus flRegisterNAND(void){ if (noOfMTDs >= MTDS) return flTooManyComponents; mtdTable[noOfMTDs++] = nandMTDIdentify; return flOK;}#endif /* FALSE */-
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -