コード例 #1
0
/**
*	@fn			spi_flash_erase
*	@brief		Erase from data from SPI flash
*	@param[IN]	u32Offset
*					Address to write to at the SPI flash
*	@param[IN]	u32Sz
*					Data size
*	@return		Status of execution
*	@note		Data size is limited by the SPI flash size only
*/ 
sint8 spi_flash_erase(uint32 u32Offset, uint32 u32Sz)
{
	uint32 i = 0;
	sint8 ret = M2M_SUCCESS;
	uint8  tmp = 0;
#ifdef PROFILING
	uint32 t;
	t = GetTickCount();
#endif
	M2M_PRINT("\r\n>Start erasing...\r\n");
	for(i = u32Offset; i < (u32Sz +u32Offset); i += (16*FLASH_PAGE_SZ))
	{
		ret += spi_flash_write_enable();
		ret += spi_flash_read_status_reg(&tmp);
		ret += spi_flash_sector_erase(i + 10);
		ret += spi_flash_read_status_reg(&tmp);
		do
		{
			if(ret != M2M_SUCCESS) goto ERR;
			ret += spi_flash_read_status_reg(&tmp);
		}while(tmp & 0x01);
		
	}
	M2M_PRINT("Done\r\n");
#ifdef PROFILING
	M2M_PRINT("#Erase time = %f sec\n", (GetTickCount()-t)/1000.0);
#endif
ERR:
	return ret;
}
コード例 #2
0
ファイル: spi-flash.c プロジェクト: mirsys/xboot
static u64_t spi_flash_write(struct block_t * blk, u8_t * buf, u64_t blkno, u64_t blkcnt)
{
	struct spi_flash_private_data_t * dat = (struct spi_flash_private_data_t *)blk->priv;
	u64_t addr = blkno * blk->blksz;
	s64_t count = blkcnt * blk->blksz;
	u8_t * pbuf = buf;
	u64_t i;

	if(dat->id->flags & SECTOR_4K)
	{
		for(i = 0; i < blkcnt; i++)
			spi_flash_sector_erase_4k(dat->dev, addr + i * blk->blksz);
	}
	else
	{
		for(i = 0; i < blkcnt; i++)
			spi_flash_sector_erase(dat->dev, addr + i * blk->blksz);
	}

	while(count > 0)
	{
		spi_flash_write_one_page(dat->dev, addr, pbuf);
		addr += 256;
		pbuf += 256;
		count -= 256;
	}
	return blkcnt;
}
コード例 #3
0
void handle_erase_block(struct cfw_message *msg)
{
    ll_storage_erase_block_req_msg_t * req = (ll_storage_erase_block_req_msg_t *) msg;
    ll_storage_erase_block_rsp_msg_t * resp = (ll_storage_erase_block_rsp_msg_t *) cfw_alloc_rsp_msg(msg,
            MSG_ID_LL_ERASE_BLOCK_RSP, sizeof(*resp));

    flash_device_t flash;
    uint16_t flash_id = 0;
    int16_t partition_index = -1;
    uint32_t i = 0;
    DRIVER_API_RC ret = DRV_RC_FAIL;

    if (req->no_blks == 0) {
        pr_debug(LOG_MODULE_MAIN, "LL Storage Service - Write Block: Invalid write size");
        ret = DRV_RC_INVALID_OPERATION;
        goto send;
    }

    for (i = 0; i < ll_storage_config.no_part; i++)
        if (ll_storage_config.partitions[i].partition_id == req->partition_id) {
            flash_id = ll_storage_config.partitions[i].flash_id;
            partition_index = i;
            break;
        }

    if (partition_index == -1) {
        pr_debug(LOG_MODULE_MAIN, "LL Storage Service - Write Block: Invalid partition ID");
        ret = DRV_RC_FAIL;
        goto send;
    }

    uint16_t last_block = ll_storage_config.partitions[partition_index].start_block + req->st_blk + req->no_blks - 1;

    if (last_block > ll_storage_config.partitions[partition_index].end_block) {
        pr_debug(LOG_MODULE_MAIN, "LL Storage Service - Write Block: Partition overflow");
        ret = DRV_RC_OUT_OF_MEM;
        goto send;
    }

    flash = flash_devices[flash_id];

    if (flash.flash_location == EMBEDDED_FLASH)
    {
        ret = soc_flash_block_erase(ll_storage_config.partitions[partition_index].start_block + req->st_blk, req->no_blks);
    }
#ifdef CONFIG_SPI_FLASH
    else
    {
        // SERIAL_FLASH
        ret = spi_flash_sector_erase((struct device *)&pf_sba_device_flash_spi0,
            ll_storage_config.partitions[partition_index].start_block + req->st_blk, req->no_blks);
    }
#endif

send:
    resp->rsp_header.status = ret;
    cfw_send_message(resp);
}
コード例 #4
0
ファイル: wmt_sf.c プロジェクト: josh64x2/apc-rock
/*
	We could store these in the mtd structure, but we only support 1 device..
	static struct mtd_info *mtd_info;
*/
static int sf_erase(struct mtd_info *mtd, struct erase_info *instr)
{
	int ret;
	struct wmt_sf_info_t *info = (struct wmt_sf_info_t *)mtd->priv;
	struct sfreg_t *sfreg = info->reg;

	REG32_VAL(PMCEU_ADDR) |= SF_CLOCK_EN;

	ret = spi_flash_sector_erase((unsigned long)instr->addr, sfreg);

	if (ret != ERR_OK) {
		printk(KERN_ERR "sf_erase() error at address 0x%lx \n", (unsigned long)instr->addr);
		return -EINVAL;
	}
	instr->state = MTD_ERASE_DONE;
	mtd_erase_callback(instr);

	REG32_VAL(PMCEU_ADDR) &= ~(SF_CLOCK_EN);

	return 0;
}
コード例 #5
0
void handle_write_partition(struct cfw_message *msg)
{
    ll_storage_write_partition_req_msg_t * req = (ll_storage_write_partition_req_msg_t *) msg;
    ll_storage_write_partition_rsp_msg_t * resp = (ll_storage_write_partition_rsp_msg_t *) cfw_alloc_rsp_msg(msg,
            MSG_ID_LL_WRITE_PARTITION_RSP, sizeof(*resp));

    flash_device_t flash;
    uint16_t flash_id = 0;
    int16_t partition_index = -1;
    uint32_t i = 0;
    uint32_t size = 0;
    unsigned int retlen = 0;
    DRIVER_API_RC ret = DRV_RC_FAIL;

    if ((req->write_type == WRITE_REQ) && (req->buffer == NULL)) {
        pr_debug(LOG_MODULE_MAIN, "LL Storage Service - Write Data: Invalid write buffer");
        ret = DRV_RC_INVALID_CONFIG;
        goto send;
    }

    if ((req->write_type == WRITE_REQ) && (req->size == 0)) {
        pr_debug(LOG_MODULE_MAIN, "LL Storage Service - Write Data: Invalid write size");
        ret = DRV_RC_INVALID_OPERATION;
        goto send;
    }

    for (i = 0; i < ll_storage_config.no_part; i++)
        if (ll_storage_config.partitions[i].partition_id == req->partition_id) {
            flash_id = ll_storage_config.partitions[i].flash_id;
            partition_index = i;
            break;
        }

    if (partition_index == -1) {
        pr_debug(LOG_MODULE_MAIN, "LL Storage Service - Write Data: Invalid partition ID");
        ret = DRV_RC_FAIL;
        goto send;
    }

    flash = flash_devices[flash_id];

    if ((req->write_type == WRITE_REQ) &&
            (((ll_storage_config.partitions[partition_index].start_block * flash.block_size) + (req->st_offset + req->size))
            > (ll_storage_config.partitions[partition_index].end_block * flash.block_size))) {
        pr_debug(LOG_MODULE_MAIN, "LL Storage Service - Write Data: Partition overflow");
        ret = DRV_RC_OUT_OF_MEM;
        goto send;
    }

    size = req->size / sizeof (uint32_t) + !!(req->size % sizeof (uint32_t));

    if (req->write_type == ERASE_REQ) {
        if (flash.flash_location == EMBEDDED_FLASH) {
            ret = soc_flash_block_erase(ll_storage_config.partitions[partition_index].start_block,
                    (ll_storage_config.partitions[partition_index].end_block - ll_storage_config.partitions[partition_index].start_block) + 1);
#ifdef CONFIG_SPI_FLASH
        } else {// SERIAL_FLASH
            ret = spi_flash_sector_erase((struct device *)&pf_sba_device_flash_spi0,
                    ll_storage_config.partitions[partition_index].start_block,
                    (ll_storage_config.partitions[partition_index].end_block - ll_storage_config.partitions[partition_index].start_block) + 1);
#endif
        }
    } else {
        uint32_t address = ((ll_storage_config.partitions[partition_index].start_block * flash.block_size) + req->st_offset);

        if (flash.flash_location == EMBEDDED_FLASH) {
            ret = soc_flash_write(address, size, &retlen, req->buffer);
#ifdef CONFIG_SPI_FLASH
        } else {// SERIAL_FLASH
            ret = spi_flash_write((struct device *)&pf_sba_device_flash_spi0,
                                  address, size, &retlen, req->buffer);
#endif
        }

        resp->actual_size = (retlen * sizeof(uint32_t)) - (((req->size % sizeof(uint32_t)))
             ? (4 - (req->size % sizeof(uint32_t))):0);
    }

send:
    resp->rsp_header.status = ret;
    resp->write_type = req->write_type;
    cfw_send_message(resp);
}