コード例 #1
0
//------------------------------------------------------------------------------
/// Unmaps a logical block by releasing the corresponding physical block (if
/// any).
/// Returns 0 if successful; otherwise returns a NandCommon_ERROR code.
/// \param mapped  Pointer to a MappedNandFlash instance.
/// \param logicalBlock  Number of logical block to unmap.
//------------------------------------------------------------------------------
unsigned char MappedNandFlash_Unmap(
    struct MappedNandFlash *mapped,
    unsigned short logicalBlock)
{
    signed short physicalBlock = mapped->logicalMapping[logicalBlock];
    unsigned char error;

    TRACE_INFO("MappedNandFlash_Unmap(LB#%d)\r\n", logicalBlock);
    ASSERT(
        logicalBlock < ManagedNandFlash_GetDeviceSizeInBlocks(MANAGED(mapped)),
        "MappedNandFlash_Unmap: logicalBlock out-of-range\r\n");

    if (physicalBlock != -1) {

        error = ManagedNandFlash_ReleaseBlock(MANAGED(mapped), physicalBlock);
        if (error) {

            return error;
        }
    }
    mapped->logicalMapping[logicalBlock] = -1;
    mapped->mappingModified = 1;

    return 0;
}
コード例 #2
0
//------------------------------------------------------------------------------
/// Maps a logical block number to an actual physical block. This allocates
/// the physical block (meaning it must be FREE), and releases the previous
/// block being replaced (if any).
/// Returns 0 if successful; otherwise returns a NandCommon_ERROR_xxx code.
/// \param mapped  Pointer to a MappedNandFlash instance.
/// \param logicalBlock  Logical block number to map.
/// \param physicalBlock  Physical block to map to the logical one.
//------------------------------------------------------------------------------
unsigned char MappedNandFlash_Map(
    struct MappedNandFlash *mapped,
    unsigned short logicalBlock,
    unsigned short physicalBlock)
{
    unsigned char error;
    signed short oldPhysicalBlock;

    TRACE_INFO("MappedNandFlash_Map(LB#%d -> PB#%d)\r\n",
               logicalBlock, physicalBlock);
    ASSERT(
       logicalBlock < ManagedNandFlash_GetDeviceSizeInBlocks(MANAGED(mapped)),
       "MappedNandFlash_Map: logicalBlock out-of-range\r\n");
    ASSERT(
       physicalBlock < ManagedNandFlash_GetDeviceSizeInBlocks(MANAGED(mapped)),
       "MappedNandFlash_Map: physicalBlock out-of-range\r\n");

    // Allocate physical block
    error = ManagedNandFlash_AllocateBlock(MANAGED(mapped), physicalBlock);
    if (error) {

        return error;
    }

    // Release currently mapped block (if any)
    oldPhysicalBlock = mapped->logicalMapping[logicalBlock];
    if (oldPhysicalBlock != -1) {

        error =
            ManagedNandFlash_ReleaseBlock(MANAGED(mapped), oldPhysicalBlock);
        if (error) {

            return error;
        }
    }

    // Set mapping
    mapped->logicalMapping[logicalBlock] = physicalBlock;
    mapped->mappingModified = 1;

    return 0;
}
コード例 #3
0
/**
 * \brief  Maps a logical block number to an actual physical block. This allocates
 * the physical block (meaning it must be FREE), and releases the previous
 * block being replaced (if any).
 * \param mapped  Pointer to a MappedNandFlash instance.
 * \param logicalBlock  Logical block number to map.
 * \param physicalBlock  Physical block to map to the logical one.
 * \return  0 if successful; otherwise returns a NandCommon_ERROR_xxx code.
 */
unsigned char MappedNandFlash_Map(
    struct MappedNandFlash *mapped,
    unsigned short logicalBlock,
    unsigned short physicalBlock)
{
    unsigned char error;
    signed short oldPhysicalBlock;

    TRACE_INFO("MappedNandFlash_Map(LB#%d -> PB#%d)\n\r",
               logicalBlock, physicalBlock);
    assert( logicalBlock < ManagedNandFlash_GetDeviceSizeInBlocks(MANAGED(mapped)) ) ; /* "MappedNandFlash_Map: logicalBlock out-of-range\n\r" */
    assert( physicalBlock < ManagedNandFlash_GetDeviceSizeInBlocks(MANAGED(mapped)) ) ; /* "MappedNandFlash_Map: physicalBlock out-of-range\n\r" */

    /* Allocate physical block*/
    error = ManagedNandFlash_AllocateBlock(MANAGED(mapped), physicalBlock);
    if ( error )
    {
        return error;
    }

    /* Release currently mapped block (if any)*/
    oldPhysicalBlock = mapped->logicalMapping[logicalBlock];
    if (oldPhysicalBlock != -1)
    {
        error = ManagedNandFlash_ReleaseBlock(MANAGED(mapped), oldPhysicalBlock);
        if ( error )
        {
            return error;
        }
    }

    /* Set mapping*/
    mapped->logicalMapping[logicalBlock] = physicalBlock;
    mapped->mappingModified = 1;

    return 0;
}
コード例 #4
0
/**
 * \brief  Saves the logical mapping on a FREE, unmapped physical block. Allocates the
 * new block, releases the previous one (if any) and save the mapping.
 *
 * \param mapped  Pointer to a MappedNandFlash instance.
 * \param physicalBlock  Physical block number.
 * \return  0 if successful; otherwise, returns NandCommon_ERROR_WRONGSTATUS
 * if the block is not LIVE, or a NandCommon_ERROR code.
 */
unsigned char MappedNandFlash_SaveLogicalMapping(
    struct MappedNandFlash *mapped,
    unsigned short physicalBlock)
{
    unsigned char error;
    unsigned char data[NandCommon_MAXPAGEDATASIZE];
    unsigned short pageDataSize =
                    NandFlashModel_GetPageDataSize(MODEL(mapped));
    /*unsigned short numBlocks =
                    ManagedNandFlash_GetDeviceSizeInBlocks(MANAGED(mapped));*/
    unsigned int i;
    unsigned int remainingSize;
    unsigned char *currentBuffer;
    unsigned short currentPage;
    unsigned int writeSize;
    signed short previousPhysicalBlock;

    TRACE_INFO("MappedNandFlash_SaveLogicalMapping(B#%d)\n\r", physicalBlock);

    /* If mapping has not been modified, do nothing*/
    if (!mapped->mappingModified) {

        return 0;
    }

    /* Allocate new block*/
    error = ManagedNandFlash_AllocateBlock(MANAGED(mapped), physicalBlock);
    if (error) {

        return error;
    }

    /* Save mapping*/
    previousPhysicalBlock = mapped->logicalMappingBlock;
    mapped->logicalMappingBlock = physicalBlock;

    /* Save actual mapping in pages #1-#XXX*/
    currentBuffer = (unsigned char *) mapped->logicalMapping;
    remainingSize = sizeof(mapped->logicalMapping);
    currentPage = 1;
    while (remainingSize > 0) {

        writeSize = min(remainingSize, pageDataSize);
        memset(data, 0xFF, pageDataSize);
        memcpy(data, currentBuffer, writeSize);
        error = ManagedNandFlash_WritePage(MANAGED(mapped),
                                           physicalBlock,
                                           currentPage,
                                           data,
                                           0);
        if (error) {

            TRACE_ERROR(
             "MappedNandFlash_SaveLogicalMapping: Failed to write mapping\n\r");
            return error;
        }

        currentBuffer += writeSize;
        remainingSize -= writeSize;
        currentPage++;
    }

    /* Mark page #0 of block with a distinguishible pattern, so the mapping can
       be retrieved at startup*/
    for (i=0; i < pageDataSize; i++) {

        data[i] = PATTERN(i);
    }
    error = ManagedNandFlash_WritePage(MANAGED(mapped),
                                       physicalBlock, 0,
                                       data, 0);
    if (error) {

        TRACE_ERROR(
            "MappedNandFlash_SaveLogicalMapping: Failed to write pattern\n\r");
        return error;
    }

    /* Mapping is not modified anymore*/
    mapped->mappingModified = 0;

    /* Release previous block (if any)*/
    if (previousPhysicalBlock != -1) {

        TRACE_DEBUG("Previous physical block was #%d\n\r",
                    previousPhysicalBlock);
        error = ManagedNandFlash_ReleaseBlock(MANAGED(mapped),
                                              previousPhysicalBlock);
        if (error) {

            return error;
        }
    }

    TRACE_INFO("Mapping saved on block #%d\n\r", physicalBlock);

    return 0;
}
コード例 #5
0
/**
 * \brief  Loads the logical mapping contained in the given physical block.
 * block contains the mapping, its index is stored in the provided variable (if
 * pointer is not 0).
 *
 * \param mapped  Pointer to a MappedNandFlash instance.
 * \param physicalBlock  Physical block number.
 * \return  0 if successful; otherwise, returns a NandCommon_ERROR code.
 */
static unsigned char LoadLogicalMapping(
    struct MappedNandFlash *mapped,
    unsigned short physicalBlock)
{
    unsigned char error;
    unsigned char data[NandCommon_MAXPAGEDATASIZE];
    unsigned short pageDataSize =
                    NandFlashModel_GetPageDataSize(MODEL(mapped));
    unsigned short numBlocks =
                    ManagedNandFlash_GetDeviceSizeInBlocks(MANAGED(mapped));
    unsigned int remainingSize;
    unsigned char *currentBuffer;
    unsigned short currentPage;
    unsigned int readSize;
    unsigned int i;
    unsigned char status;
    signed short logicalBlock;
    /*signed short firstBlock, lastBlock;*/

    TRACE_INFO("LoadLogicalMapping(B#%d)\n\r", physicalBlock);

    /* Load mapping from pages #1 - #XXX of block*/
    currentBuffer = (unsigned char *) mapped->logicalMapping;
    remainingSize = sizeof(mapped->logicalMapping);
    currentPage = 1;
    while (remainingSize > 0) {

        /* Read page*/
        readSize = min(remainingSize, pageDataSize);
        error = ManagedNandFlash_ReadPage(MANAGED(mapped),
                                          physicalBlock,
                                          currentPage,
                                          data,
                                          0);
        if (error) {

            TRACE_ERROR(
                      "LoadLogicalMapping: Failed to load mapping\n\r");
            return error;
        }

        /* Copy page info*/
        memcpy(currentBuffer, data, readSize);

        currentBuffer += readSize;
        remainingSize -= readSize;
        currentPage++;
    }

    /* Store mapping block index*/
    mapped->logicalMappingBlock = physicalBlock;

    /* Power-loss recovery*/
    for (i=0; i < numBlocks; i++) {

        /* Check that this is not the logical mapping block*/
        if (i != physicalBlock) {

            status = mapped->managed.blockStatuses[i].status;
            logicalBlock = MappedNandFlash_PhysicalToLogical(mapped, i);

            /* Block is LIVE*/
            if (status == NandBlockStatus_LIVE) {

                /* Block is not mapped -> release it*/
                if (logicalBlock == -1) {

                    TRACE_WARNING_WP("-I- Release unmapped LIVE #%d\n\r",
                                     i);
                    ManagedNandFlash_ReleaseBlock(MANAGED(mapped), i);
                }
            }
            /* Block is DIRTY*/
            else if (status == NandBlockStatus_DIRTY) {

                /* Block is mapped -> fake it as live*/
                if (logicalBlock != -1) {

                    TRACE_WARNING_WP("-I- Mark mapped DIRTY #%d -> LIVE\n\r",
                                     i);
                    mapped->managed.blockStatuses[i].status =
                                                    NandBlockStatus_LIVE;
                }
            }
            /* Block is FREE or BAD*/
            else {

                /* Block is mapped -> remove it from mapping*/
                if (logicalBlock != -1) {

                    TRACE_WARNING_WP("-I- Unmap FREE or BAD #%d\n\r", i);
                    mapped->logicalMapping[logicalBlock] = -1;
                }
            }
        }
    }

    TRACE_WARNING_WP("-I- Mapping loaded from block #%d\n\r", physicalBlock);

    return 0;
}
コード例 #6
0
//------------------------------------------------------------------------------
/// Loads the logical mapping contained in the given physical block.
/// Returns 0 if successful; otherwise, returns a NandCommon_ERROR code.
/// \param mapped  Pointer to a MappedNandFlash instance.
/// \param physicalBlock  Physical block number.
//------------------------------------------------------------------------------
static unsigned char LoadLogicalMapping(
    struct MappedNandFlash *mapped,
    unsigned short physicalBlock)
{
    unsigned char error;
    unsigned short pageDataSize =
                    NandFlashModel_GetPageDataSize(MODEL(mapped));
    unsigned short numBlocks =
                    ManagedNandFlash_GetDeviceSizeInBlocks(MANAGED(mapped));
    unsigned char *pDataBuffer =  RawNandFlash_GetDataBuffer(RAW(mapped));
    unsigned int remainingSize;
    unsigned char *currentBuffer;
    unsigned short currentPage;
    unsigned int readSize;
    unsigned int i;
    unsigned char status;
    signed short logicalBlock;
    //signed short firstBlock, lastBlock;

    TRACE_INFO("LoadLogicalMapping(B#%d)\r\n", physicalBlock);

    // Load mapping from pages #1 - #XXX of block
    currentBuffer = (unsigned char *) mapped->logicalMapping;
    remainingSize = sizeof(mapped->logicalMapping);
    currentPage = 1;
    while (remainingSize > 0) {

        // Read page
        readSize = min(remainingSize, pageDataSize);
        error = ManagedNandFlash_ReadPage(MANAGED(mapped),
                                          physicalBlock,
                                          currentPage,
                                          pDataBuffer,
                                          0);
        if (error) {

            RawNandFlash_ReleaseDataBuffer(RAW(mapped));
            TRACE_ERROR(
                      "LoadLogicalMapping: Failed to load mapping\r\n");
            return error;
        }

        // Copy page info
        memcpy(currentBuffer, pDataBuffer, readSize);

        currentBuffer += readSize;
        remainingSize -= readSize;
        currentPage++;
    }

    // Store mapping block index
    mapped->logicalMappingBlock = physicalBlock;

    // Power-loss recovery
    for (i=0; i < numBlocks; i++) {

        // Check that this is not the logical mapping block
        if (i != physicalBlock) {

            status = mapped->managed.blockStatuses[i].status;
            logicalBlock = MappedNandFlash_PhysicalToLogical(mapped, i);

            // Block is LIVE
            if (status == NandBlockStatus_LIVE) {

                // Block is not mapped -> release it
                if (logicalBlock == -1) {

                    TRACE_WARNING_WP("-I- Release unmapped LIVE #%d\r\n",
                                     i);
                    ManagedNandFlash_ReleaseBlock(MANAGED(mapped), i);
                }
            }
            // Block is DIRTY
            else if (status == NandBlockStatus_DIRTY) {

                // Block is mapped -> fake it as live
                if (logicalBlock != -1) {

                    TRACE_WARNING_WP("-I- Mark mapped DIRTY #%d -> LIVE\r\n",
                                     i);
                    mapped->managed.blockStatuses[i].status =
                                                    NandBlockStatus_LIVE;
                }
            }
            // Block is FREE or BAD
            else {

                // Block is mapped -> remove it from mapping
                if (logicalBlock != -1) {

                    TRACE_WARNING_WP("-I- Unmap FREE or BAD #%d\r\n", i);
                    mapped->logicalMapping[logicalBlock] = -1;
                }
            }
        }
    }

    RawNandFlash_ReleaseDataBuffer(RAW(mapped));
    TRACE_WARNING_WP("-I- Mapping loaded from block #%d\r\n", physicalBlock);

    return 0;
}