Ejemplo n.º 1
0
LOCAL FLStatus v28F128J3Erase
    (
    FLFlash vol,
    int     firstErasableBlock,
    int     numOfErasableBlocks
    )
    {
    UINT32 * block = NULL;
    UINT32 status = V28F128J3_STATUS_READY;
    UINT32 timeout = 0;
    int i;

    if (flWriteProtected(vol.socket))
	    return flWriteProtect;

    for (i = firstErasableBlock; i < firstErasableBlock + numOfErasableBlocks; i++)
	{
	    block = (UINT32 *)vol.map(&vol, i * vol.erasableBlockSize, 0);

#ifdef DEBUG_PRINT
        DEBUG_PRINT("Erasing block#%03d @ 0x%08x ...\r", i, block);
#endif

    	/* set timeout = 5s */
    	timeout = flMsecCounter + V28F128J3_OP_TIMEOUT;
        V28F128J3_READ_STATUS(block);
        do
        {
            status = *block;
            if (flMsecCounter >= timeout)
                break;
        } while ((status & V28F128J3_STATUS_READY_MASK) != V28F128J3_STATUS_READY);

        if ((status & V28F128J3_STATUS_ERR_MASK) != 0)
            V28F128J3_CLEAR_STATUS(block);

        V28F128J3_ERASE_BLOCK(block);
        V28F128J3_ERASE_CONFIRM(block);

    	/* set timeout = 5s */
    	timeout = flMsecCounter + V28F128J3_OP_TIMEOUT;
        do
        {
            status = *block;
            if (flMsecCounter >= timeout)
            {
                V28F128J3_RESET(block);
                return flTimedOut;
            }
        } while ((status & V28F128J3_STATUS_READY_MASK) != V28F128J3_STATUS_READY);

        /* check erase error bit */
    	if (status & V28F128J3_STATUS_ERA_ERR_MASK)
        {
            V28F128J3_RESET(block);
    		return flWriteFault;
        }
	}

    V28F128J3_RESET(block);
    return flOK;
    }
Ejemplo n.º 2
0
LOCAL  FLStatus cfiAmdErase
(
    FLFlash vol,                 /* Pointer identifying drive      */
    int firstErasableBlock,      /* Number of first block to erase */
    int numOfErasableBlocks      /* Number of blocks to erase      */
    )
    {
    int i;
    UINT32 unlock1 = 0;
    UINT32 unlock2 = 0;
    UINT32 erase_setup = 0;
    UINT32 erase_sector = 0;
    int thisSector = firstErasableBlock;
    int sectorsToErase = numOfErasableBlocks;
    UINT32 * unlockAddr1;
    UINT32 * unlockAddr2;

    if (flWriteProtected(vol.socket))
        return flWriteProtect;

    /* Setup the commands first */

    for (i = 0; i < thisCFI->multiplier; i++)
        {
        unlock1      |= AMD_UNLOCK_1 << (i * 8);
        unlock2      |= AMD_UNLOCK_2 << (i * 8);
        erase_setup  |= AMD_SETUP_ERASE << (i * 8);
        erase_sector |= AMD_SECTOR_ERASE << (i * 8);
        }

    for ( ; thisSector < firstErasableBlock + sectorsToErase; thisSector++)
        {
        int i;
        FLBoolean finished;
        FlashPTR flashPtr;

#ifdef DEBUG_PRINT 
        DEBUG_PRINT("Clearing sector %d\n", thisSector);
#endif 

        /* we know we are on a unit boundary so mapBase is not necessary */
        flashPtr = (FlashPTR)
                   vol.map(&vol, thisCFI->secInfo[thisSector].sectorBaseAdrs, 0);

        unlockAddr1 = (UINT32 *)((long)flashPtr + (thisCFI->unlockAddr1 *thisCFI->multiplier));
        unlockAddr2 = (UINT32 *)((long)flashPtr + (thisCFI->unlockAddr2 *thisCFI->multiplier));

        *(UINT16 *)unlockAddr1 = unlock1;
        *(UINT16 *)unlockAddr2 = unlock2;
        *(UINT16 *)unlockAddr1 = erase_setup;
        *(UINT16 *)unlockAddr1 = unlock1;
        *(UINT16 *)unlockAddr2 = unlock2;
        *(UINT16 *)flashPtr = erase_sector;

        do 
            {
            finished = TRUE;

            for (i = 0;i < thisCFI->multiplier;i += thisCFI->interleaveWidth)
                {
                if (flashPtr[i] != 0xff)
                    {
                    if ((flashPtr[i] & AMD_D5) && flashPtr[i] != 0xff)
                        {
                        int x;
                        UINT32 c;

                        for (x = 0, c = 0; x < thisCFI->multiplier; x++)
                            c |= AMD_READ_ARRAY << (x * 8);
                        flashPtr[i] = c;
#ifdef DEBUG_PRINT
                        DEBUG_PRINT("Debug: erase failed in AMD MTD.\n");
#endif
                        return flWriteFault;
                        }
                    finished = FALSE;
                    }
                }
            } while (!finished);
        }

    return flOK;
    }
Ejemplo n.º 3
0
LOCAL FLStatus v28F128J3Write
    (
    FLFlash         vol,
    CardAddress     address,
    const void FAR1 *buffer,
    int             length,
    int             overwrite
    )
    {
    UINT8  *unaligned;
    UINT8  *buf = (UINT8 *)buffer;
    UINT32  left = length;
    UINT32 *aligned;
    UINT32  data, num;
    int     i;

    if (flWriteProtected(vol.socket))
	    return flWriteProtect;

    /* calculate the program addr, make sure it's 32-bit aligned */
    unaligned = (UINT8 *)vol.map (&vol, address, 0);
    num = (UINT32)unaligned & 0x3;
    aligned = (UINT32 *)((UINT32)unaligned - num);

    if (num != 0)
    {
        data = *aligned;

        for (i = num ; i < 4; i++)
        {
            data &= ~(0xFF << ((3 - i) * 8));
            data |= ((*(buf + i - num)) << ((3 - i) * 8));
        }

        if (v28F128J3Program(aligned, data) != flOK)
            return flWriteFault;

        buf  += (4 - num);
        left -= (4 - num);
        aligned++;
    }

    while (left >= 4)
    {
        data = *(UINT32 *)buf;

        if (v28F128J3Program (aligned, data) != flOK)
            return flWriteFault;

        buf  += 4;
        left -= 4;
        aligned++;
    }

    if (left > 0)
    {
        data = *aligned;

        for (i = 0 ; i < left; i++)
        {
            data &= ~(0xFF << ((3 - i) * 8));
            data |= ((*(buf + i)) << ((3 - i) * 8));
        }

        if (v28F128J3Program (aligned, data) != flOK)
            return flWriteFault;
    }

    if (tffscmp((void FAR0 *)unaligned, buffer, length))
    {
#ifdef DEBUG_PRINT
        DEBUG_PRINT("[v28F128J3Write]: data double check error @ 0x%08x ...\n", unaligned);
#endif
        return flWriteFault;
    }

    return flOK;
    }
Ejemplo n.º 4
0
LOCAL FLStatus cfiAmdWrite
    (
    FLFlash vol,                  /* Pointer identifying drive         */
    CardAddress address,          /* Card address to write to          */
    const void FAR1 *buffer,      /* Address of data to write          */
    int length,                   /* Number of bytes to write          */
    FLBoolean overwrite           /* Mode: TRUE overwrite;FALSE erased */
    )
    {
    /* Set timeout to 5 seconds from now */
    unsigned long writeTimeout = flMsecCounter + 5000;
    int cLength;
    CardAddress cAddr = address;
    FlashPTR base;
    FlashPTR flashPtr;
    UINT32 unlock1 = 0;
    UINT32 unlock2 = 0;
    UINT32 setup_write = 0;
    UINT32 read_array = 0;
    int i;
    CFI_WORD  tmpWord;

#define bFlashPtr  flashPtr
#define bBuffer ((const unsigned char FAR1 *) buffer)
#define wFlashPtr ((FlashWPTR) flashPtr)
#define wBuffer ((const unsigned short FAR1 *) buffer)
#define dFlashPtr ((FlashDPTR) flashPtr)
#define dBuffer ((const unsigned long FAR1 *) buffer)

    /* Setup the commands first */
    for (i = 0; i < thisCFI->multiplier; i++)
        {
        unlock1     |= AMD_UNLOCK_1 << (i * 8);
        unlock2     |= AMD_UNLOCK_2 << (i * 8);
        setup_write |= AMD_SETUP_WRITE << (i * 8);
        read_array  |= AMD_READ_ARRAY << (i * 8);
        }

    if (flWriteProtected(vol.socket))
        return flWriteProtect;

    i = 0; 
    while ((thisCFI->secInfo[i].sectorBaseAdrs <= address) && (i < thisCFI->sectorsInCFI))
        i++;
    i--;

    base = (FlashPTR)
           vol.map(&vol, thisCFI->secInfo[i].sectorBaseAdrs,
                   vol.interleaving * thisCFI->interleaveWidth);

    flashPtr = (FlashPTR)
               vol.map(&vol, address,
                       vol.interleaving * thisCFI->interleaveWidth);

    cLength = length;

    if (vol.interleaving * thisCFI->interleaveWidth == 1)
        {
        while (cLength >= 2)
            {
            *(USHORT *)(base + 
                        (thisCFI->unlockAddr1 * thisCFI->multiplier)) = unlock1;
            *(USHORT *)(base + 
                        (thisCFI->unlockAddr2 * thisCFI->multiplier)) = unlock2;
            *(USHORT *)(base + 
                        (thisCFI->unlockAddr1 * thisCFI->multiplier)) = setup_write;

            *wFlashPtr = *wBuffer;

            while ((wFlashPtr[0] != wBuffer[0]) && 
                   (flMsecCounter < writeTimeout))
                {
                if (((wFlashPtr[0] & AMD_D5) && 
                     ((wFlashPtr[0] ^ wBuffer[0]) &   0xff)))
                    {
                    wFlashPtr[0] = read_array;
#ifdef DEBUG_PRINT
                    DEBUG_PRINT("Debug: write failed in AMD MTD.\n");
#endif
                    return flWriteFault;
                    }
                }

            cLength -= 2;
            cAddr   += 2;
            buffer  = (const void FAR1 *)((UINT32)buffer+2);
            flashPtr += 2;
            }

        if (cLength > 0)
            {
            /* copy data from flash to tmpWord */
            tmpWord.ushort = wFlashPtr[0];

            /* now fill in the left over byte */
            tmpWord.uchar[0] = *(char *)buffer;

            *(USHORT *)(base + 
                        (thisCFI->unlockAddr1 * thisCFI->multiplier)) = unlock1;
            *(USHORT *)(base + 
                        (thisCFI->unlockAddr2 * thisCFI->multiplier)) = unlock2;
            *(USHORT *)(base + 
                        (thisCFI->unlockAddr1 * thisCFI->multiplier)) = setup_write;

            *wFlashPtr = tmpWord.ushort;

            while ((wFlashPtr[0] != tmpWord.ushort) && 
                   (flMsecCounter < writeTimeout))
                {
                if (((wFlashPtr[0] & AMD_D5) && 
                     ((wFlashPtr[0] ^ tmpWord.ushort) &   0xff)))
                    {
                    wFlashPtr[0] = read_array;
#ifdef DEBUG_PRINT
                    DEBUG_PRINT("Debug: write failed in AMD MTD.\n");
#endif
                    return flWriteFault;
                    }
                }
            cAddr += cLength;
            buffer = (const void FAR1 *)((UINT32)buffer + cLength);
            flashPtr = flashPtr + cLength;
            cLength = 0;
            }
        /* cfiAmdLeftoverBytesWrite(&vol, buffer, flashPtr, cLength); */
        }

    flashPtr -= length;
    buffer = (unsigned char *)buffer - length; /* bBuffer -= length; */

    if (tffscmp((void FAR0 *) flashPtr,buffer,length))
        {
#ifdef DEBUG_PRINT
        DEBUG_PRINT("Debug: write failed in AMD MTD on verification.\n");
#endif
        return flWriteFault;
        }

    return flOK;
    }