Ejemplo n.º 1
0
static uint32_t mmc_zero_out(struct mmc_device* dev, uint32_t blk_addr, uint32_t num_blks)
{
	uint32_t *out;
	uint32_t block_size = mmc_get_device_blocksize();
	uint32_t erase_size = (block_size * num_blks);
	uint32_t scratch_size = target_get_max_flash_size();

	dprintf(INFO, "erasing 0x%x:0x%x\n", blk_addr, num_blks);

	if (erase_size <= scratch_size)
	{
		/* Use scratch address if the unaligned blocks */
		out = (uint32_t *) target_get_scratch_address();
	}
	else
	{
		dprintf(CRITICAL, "Erase Fail: Erase size: %u is bigger than scratch region\n", scratch_size);
		return 1;
	}

	memset((void *)out, 0, erase_size);

	/* Flush the data to memory before writing to storage */
	arch_clean_invalidate_cache_range((addr_t) out , erase_size);

	if (mmc_sdhci_write(dev, out, blk_addr, num_blks))
	{
		dprintf(CRITICAL, "failed to erase the partition: %x\n", blk_addr);
		return 1;
	}

	return 0;
}
Ejemplo n.º 2
0
/*
 * Function: mmc_write
 * Arg     : Data address on card, data length, i/p buffer
 * Return  : 0 on Success, non zero on failure
 * Flow    : Write the data from in to the card
 */
uint32_t mmc_write(uint64_t data_addr, uint32_t data_len, void *in)
{
	uint32_t val = 0;
	uint32_t write_size = SDHCI_ADMA_MAX_TRANS_SZ;
	uint8_t *sptr = (uint8_t *)in;
	struct mmc_device *dev;

	dev = target_mmc_device();

	ASSERT(!(data_addr % MMC_BLK_SZ));

	if (data_len % MMC_BLK_SZ)
		data_len = ROUNDUP(data_len, MMC_BLK_SZ);

	/* TODO: This function is aware of max data that can be
	 * tranferred using sdhci adma mode, need to have a cleaner
	 * implementation to keep this function independent of sdhci
	 * limitations
	 */
	while (data_len > write_size) {
		val = mmc_sdhci_write(dev, (void *)sptr, (data_addr / MMC_BLK_SZ), (write_size / MMC_BLK_SZ));
		if (val)
		{
			dprintf(CRITICAL, "Failed Writing block @ %x\n", (data_addr / MMC_BLK_SZ));
			return val;
		}
		sptr += write_size;
		data_addr += write_size;
		data_len -= write_size;
	}

	if (data_len)
		val = mmc_sdhci_write(dev, (void *)sptr, (data_addr / MMC_BLK_SZ), (data_len / MMC_BLK_SZ));

	if (val)
		dprintf(CRITICAL, "Failed Writing block @ %x\n", (data_addr / MMC_BLK_SZ));

	return val;
}
Ejemplo n.º 3
0
/*
 * Function: mmc_write
 * Arg     : Data address on card, data length, i/p buffer
 * Return  : 0 on Success, non zero on failure
 * Flow    : Write the data from in to the card
 */
uint32_t mmc_write(uint64_t data_addr, uint32_t data_len, void *in)
{
	uint32_t val = 0;
	int ret = 0;
	uint32_t block_size = 0;
	uint32_t write_size = SDHCI_ADMA_MAX_TRANS_SZ;
	uint8_t *sptr = (uint8_t *)in;
	void *dev;

	dev = target_mmc_device();

	block_size = mmc_get_device_blocksize();

	ASSERT(!(data_addr % block_size));

	if (data_len % block_size)
		data_len = ROUNDUP(data_len, block_size);

	/*
	 * Flush the cache before handing over the data to
	 * storage driver
	 */
	arch_clean_invalidate_cache_range((addr_t)in, data_len);

	if (target_mmc_device())
	{
		/* TODO: This function is aware of max data that can be
		 * tranferred using sdhci adma mode, need to have a cleaner
		 * implementation to keep this function independent of sdhci
		 * limitations
		 */
		while (data_len > write_size) {
			val = mmc_sdhci_write((struct mmc_device *)dev, (void *)sptr, (data_addr / block_size), (write_size / block_size));
			if (val)
			{
				dprintf(CRITICAL, "Failed Writing block @ %x\n",(unsigned int)(data_addr / block_size));
				return val;
			}
			sptr += write_size;
			data_addr += write_size;
			data_len -= write_size;
		}

		if (data_len)
			val = mmc_sdhci_write((struct mmc_device *)dev, (void *)sptr, (data_addr / block_size), (data_len / block_size));

		if (val)
			dprintf(CRITICAL, "Failed Writing block @ %x\n",(unsigned int)(data_addr / block_size));
	}
	else
	{
		ret = ufs_write((struct ufs_dev *)dev, data_addr, (addr_t)in, (data_len / block_size));

		if (ret)
		{
			dprintf(CRITICAL, "Error: UFS write failed writing to block: %llu\n", data_addr);
			val = 1;
		}
	}

	return val;
}