コード例 #1
0
ファイル: vsvfl.c プロジェクト: Cephrus/openiBoot
static int add_block_to_scrub_list(vfl_vsvfl_device_t *_vfl, uint32_t _ce, uint32_t _block) {
	if(is_block_in_scrub_list(_vfl, _ce, _block))
			return 0;

	if(_vfl->contexts[_ce].scrub_list_length > 0x13) {
		bufferPrintf("vfl: too many scrubs!\r\n");
		return 0;
	}

	if(!vfl_check_checksum(_vfl, _ce))
		system_panic("vfl_add_block_to_scrub_list: failed checksum\r\n");

	_vfl->contexts[_ce].scrub_list[_vfl->contexts[_ce].scrub_list_length++] = _block;
	vfl_gen_checksum(_vfl, _ce);
	return vsvfl_store_vfl_cxt(_vfl, _ce);
}
コード例 #2
0
ファイル: vsvfl.c プロジェクト: snapite/openiBoot
static error_t vfl_vsvfl_erase_single_block(vfl_device_t *_vfl, uint32_t _vbn, int _replaceBadBlock) {
    vfl_vsvfl_device_t *vfl = CONTAINER_OF(vfl_vsvfl_device_t, vfl, _vfl);
    uint32_t bank;

    // In order to erase a single virtual block, we have to erase the matching
    // blocks across all banks.
    for (bank = 0; bank < vfl->geometry.banks_total; bank++) {
        uint32_t pBlock, pCE, blockRemapped;

        // Find the physical block before bad-block remapping.
        virtual_block_to_physical_block(vfl, bank, _vbn, &pBlock);
        pCE = bank % vfl->geometry.num_ce;
        vfl->blockBuffer[bank] = pBlock;

        if (is_block_in_scrub_list(vfl, pCE, pBlock)) {
            // TODO: this.
            system_panic("vsvfl: scrub list support not yet!\r\n");
        }

        // Remap the block and calculate its physical number (considering bank address space).
        blockRemapped = remap_block(vfl, pCE, pBlock, 0);
        vfl->blockBuffer[bank] = blockRemapped % vfl->geometry.blocks_per_bank
                                 + (blockRemapped / vfl->geometry.blocks_per_bank) * vfl->geometry.bank_address_space;
    }

    // TODO: H2FMI erase multiple blocks. Currently we erase the blocks one by one.
    // Actually, the block buffer is used for erase multiple blocks, so we won't use it here.
    uint32_t status = EINVAL;

    for (bank = 0; bank < vfl->geometry.banks_total; bank++) {
        uint32_t pBlock, pCE, tries;

        virtual_block_to_physical_block(vfl, bank, _vbn, &pBlock);
        pCE = bank % vfl->geometry.num_ce;

        // Try to erase each block at most 3 times.
        for (tries = 0; tries < 3; tries++) {
            uint32_t blockRemapped, bankStart, blockOffset;

            blockRemapped = remap_block(vfl, pCE, pBlock, 0);
            bankStart = (blockRemapped / vfl->geometry.blocks_per_bank) * vfl->geometry.bank_address_space;
            blockOffset = blockRemapped % vfl->geometry.blocks_per_bank;

            status = nand_device_erase_single_block(vfl->device, pCE, bankStart + blockOffset);
            if (status == 0)
                break;

            // TODO: add block map support.
            //mark_bad_block(vfl, pCE, pBlock, status);
            bufferPrintf("vfl: failed erasing physical block %d on bank %d. status: 0x%08x\r\n",
                         blockRemapped, bank, status);

            if (!_replaceBadBlock)
                return EINVAL;

            // TODO: complete bad block replacement.
            system_panic("vfl: found a bad block. we don't treat those for now. sorry!\r\n");
        }
    }

    if (status)
        system_panic("vfl: failed to erase virtual block %d!\r\n", _vbn);

    return 0;
}