📄 wamdmtd.c
字号:
/* Parameters: *//* vol : Pointer identifying drive *//* firstBlock : Number of first block to erase *//* numOfBlocks : Number of blocks to erase *//* *//* Returns: *//* FLStatus : 0 on success, failed otherwise *//*----------------------------------------------------------------------*/static FLStatus flwAmdMTDErase (FLFlash vol, int firstBlock, int numOfBlocks){ FlashWPTR flashPtr; FLBoolean finished; int iBlock; if ( flWriteProtected(vol.socket) ) return flWriteProtect; for (iBlock = 0; iBlock < numOfBlocks; iBlock++) { flashPtr = (FlashWPTR) vol.map( &vol, (firstBlock + iBlock) * vol.erasableBlockSize, vol.interleaving); flUpdateUnlockAddrs (&vol, flashPtr); flwAmdCommand (&vol, 0, SETUP_ERASE); flwAmdCommand (&vol, 0, SECTOR_ERASE); do {#ifdef BACKGROUND while (flForeground(1) == BG_SUSPEND) { /* suspend */ for (i = 0; i < interleave; i++) { flashPtr[i] = SUSPEND_ERASE; /* Wait for D6 to stop toggling */ while ((flashPtr[i] ^ flashPtr[i]) & D6) ; } } /* while (foreground..) */#endif finished = TRUE; if (*wFlashPtr != 0xffff) { if( ((*wFlashPtr & 0xff & D5) && ((*wFlashPtr & 0xff) != 0xff)) || ((*wFlashPtr & 0xff00 & (0x100 * D5)) && ((*wFlashPtr & 0xff00) != 0xff00)) ) { *wFlashPtr = READ_ARRAY; return flWriteFault; } finished = FALSE; } } while (!finished); } return flOK;}/*----------------------------------------------------------------------*//* f l w A m d I d e n t i f y *//* *//* Identify the AMD Flash media. *//* Sets the value of flash.type (JEDEC id) & FLFlash.interleaving. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* amdCmdRoutine : Routine to read-id AMD/Fujitsu style at *//* a specific location. If null, Intel procedure *//* is used. *//* idOffset : Chip offset to use for identification *//* *//*----------------------------------------------------------------------*/void flwAmdIdentify (FLFlash vol, void (*amdCmdRoutine)(FLFlash vol, CardAddress, unsigned short), CardAddress idOffset){ unsigned short resetCmd = amdCmdRoutine ? READ_ARRAY : INTEL_READ_ARRAY; FlashWPTR flashPtr = (FlashWPTR) flMap (vol.socket, idOffset); vol.noOfChips = 0; flashPtr[0] = resetCmd; /* Reset chips */ flashPtr[0] = resetCmd; /* Once again for luck */ if (amdCmdRoutine) /* use AMD unlock sequence */ { flUpdateUnlockAddrs (&vol, flashPtr); amdCmdRoutine (&vol, idOffset, READ_ID); } else flashPtr[0] = READ_ID; /* use Intel-style */ vol.type = (FlashType) ((flashPtr[0] & 0xff00) | (flashPtr[1] & 0xff)); flashPtr[0] = resetCmd;}/*----------------------------------------------------------------------*//* f l w A m d S i z e *//* *//* Identify the card size for AMD Flash. *//* Sets the value of flash.noOfChips. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* amdCmdRoutine : Routine to read-id AMD/Fujitsu style at *//* a specific location. If null, Intel procedure *//* is used. *//* idOffset : Chip offset to use for identification *//* *//* Returns: *//* FLStatus : 0 = OK, otherwise failed (invalid Flash array)*//*----------------------------------------------------------------------*/FLStatus flwAmdSize (FLFlash vol, void (*amdCmdRoutine)(FLFlash vol, CardAddress, unsigned short), CardAddress idOffset){ unsigned short resetCmd = amdCmdRoutine ? READ_ARRAY : INTEL_READ_ARRAY; FlashWPTR flashPtr = (FlashWPTR) vol.map (&vol, idOffset, 0); if (amdCmdRoutine) /* use AMD unlock sequence */ { flUpdateUnlockAddrs(&vol, flashPtr); amdCmdRoutine (&vol, idOffset, READ_ID); } else flashPtr[0] = READ_ID; /* use Intel-style */ /* We left the first chip in Read ID mode, so that we can */ /* discover an address wraparound. */ for (vol.noOfChips = 1; vol.noOfChips < 2000; vol.noOfChips++) { flashPtr = (FlashWPTR) vol.map (&vol, vol.noOfChips * vol.chipSize + idOffset, 0); /* Read ID from the chips without issuing a READ_ID command. */ /* Check for address wraparound to the first chip. */ if ((FlashType)((flashPtr[0] & 0xff00) | (flashPtr[1] & 0xff)) == vol.type) break; /* wraparound to the first chip */ /* Check if chip displays the same JEDEC id and interleaving */ if (amdCmdRoutine) /* AMD: use unlock sequence */ { flUpdateUnlockAddrs (&vol, flashPtr); amdCmdRoutine (&vol, vol.noOfChips * vol.chipSize + idOffset, READ_ID); } else flashPtr[0] = READ_ID; /* use Intel-style */ if ((FlashType) ((flashPtr[0] & 0xff00) | (flashPtr[1] & 0xff)) != vol.type) { /* This "chip" doesn't respond correctly, so we're done */ break; } flashPtr[0] = resetCmd; } flashPtr = (FlashWPTR) vol.map (&vol, idOffset, 0); flashPtr[0] = resetCmd; /* reset the original chip */ return (vol.noOfChips == 0) ? flUnknownMedia : flOK;}/*----------------------------------------------------------------------*//* f l w A m d M T D I d e n t i f y *//* *//* Identifies AMD flash media accessible in 16-bit mode only. *//* *//* This routine will be placed on the MTD list in CUSTOM.C. 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 = OK, otherwise failed (invalid Flash array)*//*----------------------------------------------------------------------*/FLStatus flwAmdMTDIdentify (FLFlash vol){ FlashWPTR baseFlashPtr; flSetWindowBusWidth (vol.socket,16); /* use 16-bits */ flSetWindowSpeed (vol.socket,120); /* 120 nsec. */ /* place to store all the AMD-specific flash parametes */ vol.mtdVars = &mtdVars[flSocketNoOf(vol.socket)]; thisVars->unlockAddr1 = NULL; vol.interleaving = 2; flwAmdIdentify (&vol, flwAmdCommand, 0); if (vol.type == Am29F016_FLASH || vol.type == Fuj29F016_FLASH || vol.type == Am29F016C_FLASH || vol.type == Fuj29F016C_FLASH || vol.type == Am29LV017_FLASH || vol.type == Fuj29LV017_FLASH) vol.chipSize = 0x200000l * vol.interleaving; else if (vol.type == Fuj29F080_FLASH || vol.type == Am29F080_FLASH || vol.type == Fuj29LV080_FLASH || vol.type == Am29LV080_FLASH || vol.type == Fuj29LV008_FLASH || vol.type == Am29LV008_FLASH) vol.chipSize = 0x100000l * vol.interleaving; else if (vol.type == Fuj29F040_FLASH || vol.type == Am29F040_FLASH) vol.chipSize = 0x80000l * vol.interleaving; else return flUnknownMedia; /* find where the window is */ baseFlashPtr = (FlashWPTR) vol.map (&vol, (CardAddress)0, vol.interleaving); flUpdateUnlockAddrs (&vol, baseFlashPtr); checkStatus( flwAmdSize(&vol, flwAmdCommand, 0) ); vol.erasableBlockSize = 0x10000l * vol.interleaving; vol.flags |= SUSPEND_FOR_WRITE; /* Register our flash handlers */ vol.write = flwAmdMTDWrite; vol.erase = flwAmdMTDErase; return flOK;}#if FALSE/*----------------------------------------------------------------------*//* f l R e g i s t e r W A M D M T D *//* *//* Registers this MTD for use *//* *//* Parameters: *//* None *//* *//*----------------------------------------------------------------------*/FLStatus flRegisterWAMDMTD (void){ if (noOfMTDs >= MTDS) return flTooManyComponents; mtdTable[noOfMTDs++] = flwAmdMTDIdentify; return flOK;}#endif /* FALSE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -