Пример #1
0
/*
 * Function: mmc_read
 * Arg     : Data address on card, o/p buffer & data length
 * Return  : 0 on Success, non zero on failure
 * Flow    : Read data from the card to out
 */
uint32_t mmc_read(uint64_t data_addr, uint32_t *out, uint32_t data_len)
{
	uint32_t ret = 0;
	uint32_t block_size;
	uint32_t read_size = SDHCI_ADMA_MAX_TRANS_SZ;
	void *dev;
	uint8_t *sptr = (uint8_t *)out;

	dev = target_mmc_device();
	block_size = mmc_get_device_blocksize();

	ASSERT(!(data_addr % block_size));
	ASSERT(!(data_len % block_size));

	/*
	 * dma onto write back memory is unsafe/nonportable,
	 * but callers to this routine normally provide
	 * write back buffers. Invalidate cache
	 * before read data from mmc.
         */
	arch_clean_invalidate_cache_range((addr_t)(out), 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 > read_size) {
			ret = mmc_sdhci_read((struct mmc_device *)dev, (void *)sptr, (data_addr / block_size), (read_size / block_size));
			if (ret)
			{
				dprintf(CRITICAL, "Failed Reading block @ %x\n",(unsigned int) (data_addr / block_size));
				return ret;
			}
			sptr += read_size;
			data_addr += read_size;
			data_len -= read_size;
		}

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

		if (ret)
			dprintf(CRITICAL, "Failed Reading block @ %x\n",(unsigned int) (data_addr / block_size));
	}
	else
	{
		ret = ufs_read((struct ufs_dev *) dev, data_addr, (addr_t)out, (data_len / block_size));
		if (ret)
		{
			dprintf(CRITICAL, "Error: UFS read failed writing to block: %llu\n", data_addr);
		}

		arch_invalidate_cache_range((addr_t)out, data_len);
	}

	return ret;
}
Пример #2
0
/*
 * Function: mmc_read
 * Arg     : Data address on card, o/p buffer & data length
 * Return  : 0 on Success, non zero on failure
 * Flow    : Read data from the card to out
 */
uint32_t mmc_read(uint64_t data_addr, uint32_t *out, uint32_t data_len)
{
	uint32_t ret = 0;
	uint32_t read_size = SDHCI_ADMA_MAX_TRANS_SZ;
	struct mmc_device *dev;
	uint8_t *sptr = (uint8_t *)out;

	ASSERT(!(data_addr % MMC_BLK_SZ));
	ASSERT(!(data_len % MMC_BLK_SZ));

	dev = 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 > read_size) {
		ret = mmc_sdhci_read(dev, (void *)sptr, (data_addr / MMC_BLK_SZ), (read_size / MMC_BLK_SZ));
		if (ret)
		{
			dprintf(CRITICAL, "Failed Reading block @ %x\n", (data_addr / MMC_BLK_SZ));
			return ret;
		}
		sptr += read_size;
		data_addr += read_size;
		data_len -= read_size;
	}

	if (data_len)
		ret = mmc_sdhci_read(dev, (void *)sptr, (data_addr / MMC_BLK_SZ), (data_len / MMC_BLK_SZ));

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

	return ret;
}