📄 cfiscs.c
字号:
} return status; }#ifdef INTERLEAVED_MODE_REQUIRES_32BIT_WRITES/**************************************************************************** cfiscsInterleavedWordErase - Erase specified number of blocks** Given the first block and number of contiguous blocks to erase, this * routine will erase the content of the specified region. The routine does* not support features like "Suspend Erase" or "Queued Erase" so the device* stays busy until all specified blocks have been erased. These features need* to be supported by the TrueFFS core to be applicable here.** RETURNS:** ERRNO:** \NOMANUAL*/LOCAL FLStatus cfiscsInterleavedWordErase ( FLFlash vol, /* Pointer identifying drive */ int firstEraseBlock, /* First block to erase */ int numberOfEraseBlocks /* Number of contiguous blocks to erase */ ) { FLStatus status = flOK; /* unless proven otherwise */ int iBlock;#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: entering CFISCS Interleaved Word Erase routine.\n");#endif if (flWriteProtected(vol.socket)) return flWriteProtect;#ifdef SOCKET_12_VOLTS if (thisCFI->vpp) checkStatus(flNeedVpp(vol.socket));#endif for (iBlock = firstEraseBlock; iBlock < firstEraseBlock + numberOfEraseBlocks && status == flOK; iBlock++) { FLBoolean finished; FlashWPTR flashPtr = (FlashWPTR) flMap(vol.socket, iBlock * vol.erasableBlockSize); CFI_LONG_WRITE(flashPtr, (ULONG) (SETUP_BLOCK_ERASE <<16)|SETUP_BLOCK_ERASE); CFI_LONG_WRITE(flashPtr, (ULONG) (CONFIRM_ERASE <<16)|CONFIRM_ERASE); /* while (flashPtr[ix * thisCFI->interleaveFactor] != 0x80); */ do { finished = FALSE; if ((flashPtr[0] == SR_READY) && (flashPtr[1] == SR_READY)) { finished = TRUE; if (CFI_WORD_READ(flashPtr) & WSM_ERROR) {#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: CFISCS erase error on device one\n");#endif status = (CFI_WORD_READ(flashPtr) & SR_VPP_ERROR) ? flVppFailure : flWriteFault; CFI_LONG_WRITE(flashPtr, (ULONG) CLEAR_STATUS); } else if (CFI_WORD_READ(&flashPtr[1]) & WSM_ERROR) {#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: CFISCS erase error on device two\n");#endif status = ((CFI_WORD_READ(&flashPtr[1])) & (SR_VPP_ERROR)) ? flVppFailure : flWriteFault; CFI_LONG_WRITE(flashPtr, (ULONG) (CLEAR_STATUS <<16) & 0xffff0000); } CFI_LONG_WRITE(flashPtr, (ULONG) (READ_ARRAY <<16)|READ_ARRAY); } } while (!finished); }#ifdef SOCKET_12_VOLTS if (thisCFI->vpp) flDontNeedVpp(vol.socket);#endif return status; }#else /* !INTERLEAVED_MODE_REQUIRES_32BIT_WRITES *//**************************************************************************** cfiscsErase - Erase specified number of blocks** Given the first block and number of contiguous blocks to erase, this * routine will erase the content of the specified region. The routine does* not support features like "Suspend Erase" or "Queued Erase" so the device* stays busy until all specified blocks have been erased. These features need* to be supported by the TrueFFS core to be applicable here.** Each interleaved device is erased independently. The core does not* compensate for interleaving and expects interleaving to be handled here.** RETURNS:** ERRNO:** \NOMANUAL*/LOCAL FLStatus cfiscsErase ( FLFlash vol, /* Pointer identifying drive */ int firstEraseBlock, /* First block to erase */ int numberOfEraseBlocks /* Number of contiguous blocks to erase */ ) { FLStatus status = flOK; /* unless proven otherwise */ int iBlock; printf ("CFISCS: erasing logical block # %d, count = %d\n", firstEraseBlock, numberOfEraseBlocks); if (flWriteProtected(vol.socket)) {#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: Write protect error word erasing device.\n");#endif return flWriteProtect; }#ifdef SOCKET_12_VOLTS if (thisCFI->vpp) checkStatus(flNeedVpp(vol.socket));#endif for (iBlock = firstEraseBlock; iBlock < firstEraseBlock + numberOfEraseBlocks && status == flOK; iBlock++) { int ix; FLBoolean finished; FlashPTR flashPtr = (FlashPTR) flMap(vol.socket, iBlock * vol.erasableBlockSize); for (ix=0; ix < vol.interleaving; ix++) { flashPtr[ix * thisCFI->interleaveFactor] = SETUP_BLOCK_ERASE; flashPtr[ix * thisCFI->interleaveFactor] = CONFIRM_ERASE; flashPtr[ix * thisCFI->interleaveFactor] = CONFIRM_ERASE; while (flashPtr[ix * thisCFI->interleaveFactor] != 0x80); do { finished = TRUE; if (!(flashPtr[ix * thisCFI->interleaveFactor] & SR_READY)) finished = FALSE; else { if (flashPtr[ix * thisCFI->interleaveFactor] & WSM_ERROR) {#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: CFISCS erase error on device %d.\n", ix);#endif status = (flashPtr[ix * thisCFI->interleaveFactor] & SR_VPP_ERROR) ? flVppFailure : flWriteFault; flashPtr[ix * thisCFI->interleaveFactor] = CLEAR_STATUS; } flashPtr[ix * thisCFI->interleaveFactor] = READ_ARRAY; } } while (!finished); } if (numberOfEraseBlocks > 1) printf ("."); }#ifdef SOCKET_12_VOLTS if (thisCFI->vpp) flDontNeedVpp(vol.socket);#endif if (numberOfEraseBlocks > 1) printf ("\n"); return status; }/**************************************************************************** cfiscsDWordErase - Erase routine for devices on 32 bit bus.** This routine is instrumented specifically for the large detachable flash* module on the wrSbc85xx board. It contains implementation and* configuration specific code and is not meant for generic use.** RETURNS:** ERRNO:** \NOMANUAL*/LOCAL FLStatus cfiscsDWordErase ( FLFlash vol, /* Pointer identifying drive */ int firstEraseBlock, /* First block to erase */ int numberOfEraseBlocks /* Number of contiguous blocks to erase */ ) { FLStatus status = flOK; /* unless proven otherwise */ int iBlock; printf ("CFISCS: erasing logical block # %d, count = %d\n", firstEraseBlock, numberOfEraseBlocks); if (flWriteProtected(vol.socket)) return flWriteProtect;#ifdef SOCKET_12_VOLTS if (thisCFI->vpp) checkStatus(flNeedVpp(vol.socket));#endif for (iBlock = firstEraseBlock; iBlock < firstEraseBlock + numberOfEraseBlocks && status == flOK; iBlock++) { int ix; FLBoolean finished; FlashDPTR flashDPtr = (FlashDPTR) flMap(vol.socket, iBlock * vol.erasableBlockSize); for (ix=0; ix < vol.interleaving; ix++) { flashDPtr[ix * thisCFI->interleaveFactor] = (SETUP_BLOCK_ERASE <<24) | (SETUP_BLOCK_ERASE <<16) | (SETUP_BLOCK_ERASE <<8) | SETUP_BLOCK_ERASE; flashDPtr[ix * thisCFI->interleaveFactor] = (unsigned long) ((CONFIRM_ERASE<<24) | (CONFIRM_ERASE<<16) | (CONFIRM_ERASE<<8) | CONFIRM_ERASE); flashDPtr[ix * thisCFI->interleaveFactor] = (unsigned long) ((CONFIRM_ERASE<<24) | (CONFIRM_ERASE<<16) | (CONFIRM_ERASE<<8) | CONFIRM_ERASE); while (flashDPtr[ix * thisCFI->interleaveFactor] != 0x80808080); do { finished = TRUE; if (!(flashDPtr[ix * thisCFI->interleaveFactor] & SR_READY)) finished = FALSE; else { if (flashDPtr[ix * thisCFI->interleaveFactor] & WSM_ERROR) {#ifdef DEBUG_PRINT DEBUG_PRINT("Debug: CFISCS erase error on device %d.\n", ix);#endif status = (flashDPtr[ix * thisCFI->interleaveFactor] & SR_VPP_ERROR) ? flVppFailure : flWriteFault; flashDPtr[ix * thisCFI->interleaveFactor] = (CLEAR_STATUS<<24)| (CLEAR_STATUS<<16)| (CLEAR_STATUS<<8) | CLEAR_STATUS; } flashDPtr[ix * thisCFI->interleaveFactor] = (unsigned long) ((READ_ARRAY<<24)| (READ_ARRAY<<16)| (READ_ARRAY<<8) | READ_ARRAY); } } while (!finished); } if (numberOfEraseBlocks > 1) printf ("."); }#ifdef SOCKET_12_VOLTS if (thisCFI->vpp) flDontNeedVpp(vol.socket);#endif if (numberOfEraseBlocks > 1) printf ("\n"); return status; }#endif /* INTERLEAVED_MODE_REQUIRES_32BIT_WRITES *//**************************************************************************** cfiscsIdentify - Identification routine for devices conforming to CFI/SC** 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. ** RETURNS:* FLStatus : 0 on positive identification, failed otherwise ** ERRNO:** URL:http://developer.intel.com/design/flcomp/applnots/29220404.pdf ** \NOMANUAL*/FLStatus cfiscsIdentify ( FLFlash vol /* Pointer identifying drive */ ) { volatile FlashPTR flashPtr = (FlashPTR) flMap(vol.socket, 0); volatile FlashWPTR flashWPtr = (FlashWPTR) flashPtr; volatile FlashDPTR flashDPtr = (FlashDPTR) flashPtr; unsigned primaryTable, secondaryTable; char priIdStr[ID_STR_LENGTH + 1] = PRIMARY_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)]; /* Is this an 8 bit device */ flashPtr[0x55] = READ_ARRAY; flashPtr[0x55] = QUERY; if (flashPtr[0x10] == 0x51 && /* 'Q' */ flashPtr[0x11] == 0x52 && /* 'R' */ flashPtr[0x12] == 0x59) /* 'Y' */ {#ifdef DEBUG_PRINT DEBUG_PRINT ("Debug: detected single 8 bit device\n");#endif thisCFI->multiplier = 1; thisCFI->interleaveFactor = 1; vol.interleaving = 1; vol.type = (FlashType) ((flashPtr[0] << 8) | flashWPtr[1]); vol.write = cfiscsByteWrite; vol.erase = cfiscsErase; goto getCFI; } /* Reset to READ_ARRAY and retry. Maybe 16 bit addressing */ flashPtr[0x55] = READ_ARRAY; flashWPtr[0x55] = (USHORT) ((QUERY << 8) | QUERY); #if 0 /* Check for two interleaved 8 bit parts */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -