Example #1
0
static bool write_bmt_to_flash(u8 *dat, u8 *oob)
{
    bool need_erase = true;
    MSG(INIT, "Try to write BMT\n");

	MSG(INIT, "bmt_block_index = 0x%x\n", bmt_block_index);
    if (bmt_block_index == 0)
    {
        // if we don't have index, we don't need to erase found block as it has been erased in find_available_block()
        need_erase = false;
		MSG(INIT, "set need_erase = 0x%x\n", need_erase);
        if ( !(bmt_block_index = find_available_block(true)) )
        {
            MSG(INIT, "Cannot find an available block for BMT\n");
            return false;
        }
    }

    MSG(INIT, "Find BMT block: 0x%x\n", bmt_block_index);
    MSG(INIT, "need_erase = 0x%x\n", need_erase);
    // write bmt to flash
    if (need_erase)
    {
        if (!nand_erase_bmt(OFFSET(bmt_block_index)))
        {
            MSG(INIT, "BMT block erase fail, mark bad: 0x%x\n", bmt_block_index);
            mark_block_bad_bmt(OFFSET(bmt_block_index));
            // bmt.bad_count++;

            bmt_block_index = 0;
            return write_bmt_to_flash(dat, oob);        // recursive call
        }
    }

    if ( !nand_write_page_bmt(PAGE_ADDR(bmt_block_index), dat, oob) )
    {
        MSG(INIT, "Write BMT data fail, need to write again\n");
        mark_block_bad_bmt(OFFSET(bmt_block_index));
        // bmt.bad_count++;

        bmt_block_index = 0;
        return write_bmt_to_flash(dat, oob);        // recursive call
    }

    MSG(INIT, "Write BMT data to block 0x%x success\n", bmt_block_index);
    return true;
}
Example #2
0
static int find_available_block_reserve(int block)
{
    int i;

    for (i = block + 1; i < reserve_block; i++)
    {
        if (!nand_block_bad_bmt(OFFSET(i)))
        {
            if (nand_erase_bmt(OFFSET(i)))
            {
                // MSG(INIT, "return 0x%x\n", i);
                return i;
            }
            else
                mark_block_bad_bmt(i);
        }
    }

    return 0;
}
Example #3
0
static bool write_bmt_to_flash(u8 *dat, u8 *oob)
{
    bool need_erase = true;
    MSG("Try to write BMT\n");
    
    if (bmt_block_index == 0)
    {
        // if we don't have index, we don't need to erase found block as it has been erased in find_available_block()
        need_erase = false;     
        if ( !(bmt_block_index = find_available_block(true)) )
        {
            MSG("Cannot find an available block for BMT\n");
            return false;
        }
    }
   
    // write bmt to flash
    if (need_erase)
    {
        if (nand_erase_bmt(OFFSET(bmt_block_index)))
        {
            MSG("BMT block erase fail, mark bad: 0x%x\n", bmt_block_index);
            mark_block_bad_bmt(OFFSET(bmt_block_index), BMT_BADBLOCK_GENERATE_LATER);
            
            bmt_block_index = 0;
            return write_bmt_to_flash(dat, oob);        // recursive call 
        }
    }

    if ( nand_write_page_bmt(PAGE_ADDR(bmt_block_index), dat, oob) )
    {
        MSG("Write BMT data fail \n");
        mark_block_bad_bmt(OFFSET(bmt_block_index), BMT_BADBLOCK_GENERATE_LATER);
        
        bmt_block_index = 0;
        return write_bmt_to_flash(dat, oob);        // recursive call 
    }

    MSG("Write BMT to block %d success\n", bmt_block_index);
    return true;
}
Example #4
0
/*************************************************************************
* Find an available block and erase.                                     *
* start_from_end: if true, find available block from end of flash.       *
*                 else, find from the beginning of the pool              *
* need_erase: if true, all unmapped blocks in the pool will be erased    *
*************************************************************************/
static int find_available_block(bool start_from_end)
{
    int i;                      // , j;
    int block = system_block_count;
    int direction;
    MSG(INIT, "Try to find_available_block, pool_erase: %d\n", pool_erased);
    if (!pool_erased)
    {
        MSG(INIT, "Erase all un-mapped blocks in pool\n");
        for (i = 0; i < bmt_block_count; i++)
        {
            if (block == bmt_block_index)
            {
                MSG(INIT, "Skip bmt block 0x%x\n", block);
                continue;
            }

            if (nand_block_bad_bmt(OFFSET(block + i)))
            {
                MSG(INIT, "Skip bad block 0x%x\n", block + i);
                continue;
            }

            if (is_block_mapped(block + i) >= 0)
            {
                MSG(INIT, "Skip mapped block 0x%x\n", block + i);
                continue;
            }

            if (!nand_erase_bmt(OFFSET(block + i)))
            {
                MSG(INIT, "Erase block 0x%x failed\n", block + i);
                mark_block_bad_bmt(OFFSET(block + i));
            }
        }

        pool_erased = 1;
    }

    if (start_from_end)
    {
        block = total_block_count - 1;
        direction = -1;
    } else
    {
        block = system_block_count;
        direction = 1;
    }

    for (i = 0; i < bmt_block_count; i++, block += direction)
    {
        if (block == bmt_block_index)
        {
            MSG(INIT, "Skip bmt block 0x%x\n", block);
            continue;
        }

        if (nand_block_bad_bmt(OFFSET(block)))
        {
            MSG(INIT, "Skip bad block 0x%x\n", block);
            continue;
        }

        if (is_block_mapped(block) >= 0)
        {
            MSG(INIT, "Skip mapped block 0x%x\n", block);
            continue;
        }

        MSG(INIT, "Find block 0x%x available\n", block);
        return block;
    }

    return 0;
}
Example #5
0
/*************************************************************************
* Find an available block and erase.                                     *
* start_from_end: if true, find available block from end of flash.       *
*                 else, find from the beginning of the pool              *
* need_erase: if true, all unmapped blocks in the pool will be erased    *
*************************************************************************/
static int find_available_block(bool start_from_end)
{
    int i;
    int block = system_block_count;
    int direction;
    MSG("Try to find_available_block, pool_erase: %d\n", pool_erased);

    // erase all un-mapped blocks in pool when finding avaliable block
    if (!pool_erased)
    {
        for (i = 0; i < bmt_block_count; i++)
        {
	        if ((block + i) == bmt_block_index)    
	        {
	            MSG("Skip bmt block %d \n", block + i);
	            continue;
	        }            

	        if ((block + i) == bbt_block_index)    
	        {
	            MSG("Skip bbt block %d \n", block + i);
	            continue;
	        }  
	        
	        if (nand_block_bad_bmt(OFFSET(block + i), BAD_BLOCK_RAW) || nand_block_bad_bmt(OFFSET(block + i), BMT_BADBLOCK_GENERATE_LATER))
            {
                MSG("Skip bad block %d \n", block + i);
                continue;
            }

            if (is_block_mapped(block + i) >= 0)
            {
                MSG("Skip mapped block %d \n", block + i);
                continue;
            }

            if (nand_erase_bmt(OFFSET(block + i)))
            {
                MSG("Erase block %d fail\n", block + i);
                mark_block_bad_bmt(OFFSET(block + i), BMT_BADBLOCK_GENERATE_LATER);
            }
        }

        pool_erased = 1;
    }

    if (start_from_end)
    {
        block = total_block_count - 1;
        direction = -1;
    }
    else
    {
        block = system_block_count;
        direction = 1;
    }

    for (i = 0; i < bmt_block_count; i++, block += direction)
    {
        if (block == bmt_block_index)
        {
            MSG("Skip bmt block %d \n", block);
            continue;
        }

        if (block == bbt_block_index)
        {
            MSG("Skip bbt block %d \n", block);
            continue;
        }
        
        if (nand_block_bad_bmt(OFFSET(block), BAD_BLOCK_RAW) || nand_block_bad_bmt(OFFSET(block), BMT_BADBLOCK_GENERATE_LATER))
        {
            MSG("Skip bad block %d \n", block);
            continue;
        }

        if (is_block_mapped(block) >= 0)
        {
            MSG("Skip mapped block %d \n", block);
            continue;
        }

        MSG("Find block %d available\n", block);
        return block;
    }

    return 0;
}