📄 cfiscs.c
字号:
status = (*flashPtr & SR_VPP_ERROR) ? flVppFailure : flWriteFault; *flashPtr = CLEAR_STATUS; } *flashPtr = READ_ARRAY; }#ifdef SOCKET_12_VOLTS if (thisCFI->vpp) flDontNeedVpp(vol.socket);#endif flashPtr = (FlashWPTR) flMap(vol.socket, address); /* verify the data */ if (status == flOK && tffscmp((void FAR0 *) flashPtr,buffer,length)) { #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: CFISCS write failed in verification.\n"); #endif status = flWriteFault; } return status;}/************************************************************************//* Auxiliary routines for cfiscsByteErase *//************************************************************************//*----------------------------------------------------------------------*//* m a k e C o m m a n d *//* *//* Create a command to write to the flash. This routine is used for *//* byte mode, write command to the relevant chip and 0xff to the other *//* chip if interleaving is greater than 1, or write the command if *//* interleaving is 1. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* command : Command to be written to the media *//* chip : first chip (0) or second chip (1) *//* *//* Returns: *//* The command that should be written to the media *//*----------------------------------------------------------------------*/static unsigned short makeCommand(FLFlash vol, unsigned short command, int chip){ if ((vol.interleaving == 1) || (chip == 0)) return command | 0xff00; else return (command << 8) | 0xff;}/*----------------------------------------------------------------------*//* g e t D a t a *//* *//* Read the lower byte or the upper byte from a given word. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* wordData : the given word *//* chip : if chip = 0 read lower byte *//* if chip = 1 read upper byte *//* *//* Returns: *//* The byte that was read. *//*----------------------------------------------------------------------*/static unsigned char getData(FLFlash vol, unsigned short wordData, int chip){ if ((vol.interleaving == 1) || (chip == 0)) return (unsigned char)wordData; /* lower byte */ else return (unsigned char)(wordData >> 8); /* upper byte */}/*----------------------------------------------------------------------*//* c f i s c s B y t e E r a s e *//* *//* Erase one or more contiguous Flash erasable blocks in a byte-mode. *//* *//* This routine will be registered as the MTD flash.erase routine *//* *//* Parameters: *//* vol : Pointer identifying drive *//* firstErasableBlock : Number of first block to erase *//* numOfErasableBlocks: Number of blocks to erase *//* *//* Returns: *//* FLStatus : 0 on success, failed otherwise *//*----------------------------------------------------------------------*/static FLStatus cfiscsByteErase(FLFlash vol, int firstErasableBlock, int numOfErasableBlocks){ int iBlock; /* Set timeout to 5 seconds from now */ unsigned long writeTimeout = flMsecCounter + 5000; FLStatus status = flOK; /* unless proven otherwise */ if (flWriteProtected(vol.socket)) return flWriteProtect;#ifdef SOCKET_12_VOLTS if (thisCFI->vpp) checkStatus(flNeedVpp(vol.socket));#endif for (iBlock = 0; iBlock < numOfErasableBlocks && status == flOK; iBlock++) { int j; FLBoolean finished; /*FlashWPTR flashPtr = (FlashWPTR)*/ /* andrayk@m-sys.com */ FlashPTR flashPtr = (FlashPTR) vol.map(&vol, (firstErasableBlock + iBlock) * vol.erasableBlockSize, vol.interleaving); for (j = 0; j * 2 < vol.interleaving; j++) { /* access chips in pairs */ int i; for (i = 0; i < (vol.interleaving == 1 ? 1 : 2); i++) { /* write to each chip seperately */ if (thisCFI->optionalCommands & QUEUED_ERASE_SUPPORT) { do { flashPtr[j] = makeCommand(&vol, SETUP_QUEUE_ERASE, i); } while (!(getData(&vol, flashPtr[j], i) & SR_READY) && (flMsecCounter < writeTimeout)); if (!(getData(&vol, flashPtr[j], i) & SR_READY)) { #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: timeout error in CFISCS erase.\n"); #endif status = flWriteFault; } else flashPtr[j] = makeCommand(&vol, CONFIRM_ERASE, i); } else { flashPtr[j] = makeCommand(&vol, SETUP_BLOCK_ERASE, i); flashPtr[j] = makeCommand(&vol, CONFIRM_ERASE, i); } } } do {#ifdef BACKGROUND if (thisCFI->optionalCommands & SUSPEND_ERASE_SUPPORT) { while (flForeground(1) == BG_SUSPEND) { /* suspend */ for (j = 0; j < vol.interleaving; j += 2, flashPtr++) { int i; for (i = 0; i < (vol.interleaving == 1 ? 1 : 2); i++) { flashPtr[j] = makeCommand(&vol, READ_STATUS, i); if (!(getData(&vol, flashPtr[j], i) & SR_READY)) { flashPtr[j] = makeCommand(&vol, SUSPEND_ERASE, i); flashPtr[j] = makeCommand(&vol, READ_STATUS, i); while (!(getData(&vol, flashPtr[j], i) & SR_READY)) ; } flashPtr[j] = makeCommand(&vol, READ_ARRAY, i); } } } }#endif finished = TRUE; for (j = 0; j * 2 < vol.interleaving; j++) { int i; for (i = 0; i < (vol.interleaving == 1 ? 1 : 2); i++) { flashPtr[j] = makeCommand(&vol, READ_STATUS, i); if (!(getData(&vol, flashPtr[j], i) & SR_READY)) finished = FALSE; else if (getData(&vol, flashPtr[j], i) & SR_ERASE_SUSPEND) { flashPtr[j] = makeCommand(&vol, RESUME_ERASE, i); finished = FALSE; } else { if (getData(&vol, flashPtr[j], i) & WSM_ERROR) { #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: CFISCS erase error.\n"); #endif status = (getData(&vol, flashPtr[j], i) & SR_VPP_ERROR) ? flVppFailure : flWriteFault; flashPtr[j] = makeCommand(&vol, CLEAR_STATUS, i); } flashPtr[j] = makeCommand(&vol, READ_ARRAY, i); } } } } while (!finished); }#ifdef SOCKET_12_VOLTS if (thisCFI->vpp) flDontNeedVpp(vol.socket);#endif return status;}/*----------------------------------------------------------------------*//* c f i s c s W o r d E r a s e *//* *//* Erase one or more contiguous Flash erasable blocks in a word-mode *//* *//* This routine will be registered as the MTD flash.erase routine *//* *//* Parameters: *//* vol : Pointer identifying drive *//* firstErasableBlock : Number of first block to erase *//* numOfErasableBlocks: Number of blocks to erase *//* *//* Returns: *//* FLStatus : 0 on success, failed otherwise *//*----------------------------------------------------------------------*/static FLStatus cfiscsWordErase(FLFlash vol, int firstErasableBlock, int numOfErasableBlocks){ FLStatus status = flOK; /* unless proven otherwise */ int iBlock; /* Set timeout to 5 seconds from now */ unsigned long writeTimeout = flMsecCounter + 5000; if (flWriteProtected(vol.socket)) return flWriteProtect;#ifdef SOCKET_12_VOLTS if (thisCFI->vpp) checkStatus(flNeedVpp(vol.socket));#endif for (iBlock = 0; iBlock < numOfErasableBlocks && status == flOK; iBlock++) { FLBoolean finished; FlashWPTR flashPtr = (FlashWPTR) flMap(vol.socket,(firstErasableBlock + iBlock) * vol.erasableBlockSize); if (thisCFI->optionalCommands & QUEUED_ERASE_SUPPORT) { do { *flashPtr = SETUP_QUEUE_ERASE; } while (!(*flashPtr & SR_READY) && (flMsecCounter < writeTimeout)); if (!(*flashPtr & SR_READY)) { #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: timeout error in CFISCS erase.\n"); #endif status = flWriteFault; } else *flashPtr = CONFIRM_ERASE; } else { *flashPtr = SETUP_BLOCK_ERASE; *flashPtr = CONFIRM_ERASE; } do {#ifdef BACKGROUND if (thisCFI->optionalCommands & SUSPEND_ERASE_SUPPORT) { while (flForeground(1) == BG_SUSPEND) { /* suspend */ if (!(*flashPtr & SR_READY)) { *flashPtr = SUSPEND_ERASE; *flashPtr = READ_STATUS; while (!(*flashPtr & SR_READY)) ; } *flashPtr = READ_ARRAY; } }#endif finished = TRUE; if (!(*flashPtr & SR_READY)) finished = FALSE; else if (*flashPtr & SR_ERASE_SUSPEND) { *flashPtr = RESUME_ERASE; finished = FALSE; } else { if (*flashPtr & WSM_ERROR) { #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: CFISCS erase error.\n"); #endif status = (*flashPtr & SR_VPP_ERROR) ? flVppFailure : flWriteFault; *flashPtr = CLEAR_STATUS; } *flashPtr = READ_ARRAY; } } while (!finished); }#ifdef SOCKET_12_VOLTS if (thisCFI->vpp) flDontNeedVpp(vol.socket);#endif return status;}/*----------------------------------------------------------------------*//* c f i s c s I d e n t i f y *//* *//* Identifies media based on SCS/CFI and registers as an MTD for *//* such. *//* *//* This routine will be placed on the MTD list in custom.h. It must be *//* an extern routine. *//* *//* On successful identification, the Flash structure is filled out and *//* the write and erase routines registered. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* *//* Returns: *//* FLStatus : 0 on positive identificaion, failed otherwise *//*----------------------------------------------------------------------*/FLStatus cfiscsIdentify(FLFlash vol){ FlashWPTR flashPtr; char queryIdStr[ID_STR_LENGTH + 1] = QUERY_ID_STR;#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: entering CFISCS identification routine.\n");#endif flSetWindowBusWidth(vol.socket, 16);/* use 16-bits */ flSetWindowSpeed(vol.socket, 120); /* 120 nsec. */ flSetWindowSize(vol.socket, 2); /* 8 KBytes */ vol.mtdVars = &mtdVars[flSocketNoOf(vol.socket)]; /* try word mode first */ flashPtr = (FlashWPTR)flMap(vol.socket, 0); flashPtr[0x55] = QUERY; if ((flashPtr[0x10] == (unsigned short)queryIdStr[0]) && (flashPtr[0x11] == (unsigned short)queryIdStr[1]) && (flashPtr[0x12] == (unsigned short)queryIdStr[2])) { vol.type = (flashPtr[0] << 8) | flashPtr[1]; vol.interleaving = 1; thisCFI->wordMode = TRUE; vol.write = cfiscsWordWrite; vol.erase = cfiscsWordErase; checkStatus(getWordCFI(&vol)); #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: identified 16-bit CFISCS.\n"); #endif } else { /* Use standard identification routine to detect byte-mode */ checkStatus(cfiscsByteIdentify(&vol)); thisCFI->wordMode = FALSE; vol.write = cfiscsByteWrite; vol.erase = cfiscsByteErase; checkStatus(getByteCFI(&vol)); #ifdef DEBUG_PRINT DEBUG_PRINT("Debug: identified 8-bit CFISCS.\n"); #endif } checkStatus(thisCFI->wordMode ? cfiscsWordSize(&vol) : cfiscsByteSize(&vol)); return flOK;}#if FALSE/*----------------------------------------------------------------------*//* f l R e g i s t e r C F I S C S *//* *//* Registers this MTD for use *//* *//* Parameters: *//* None *//* *//* Returns: *//* FLStatus : 0 on success, otherwise failure *//*----------------------------------------------------------------------*/FLStatus flRegisterCFISCS(void){ if (noOfMTDs >= MTDS) return flTooManyComponents; mtdTable[noOfMTDs++] = cfiscsIdentify; return flOK;}#endif /* FALSE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -