示例#1
0
int blocklevel_read(struct blocklevel_device *bl, uint32_t pos, void *buf, uint32_t len)
{
	int rc;
	struct ecc64 *buffer;
	uint32_t ecc_len = ecc_buffer_size(len);

	if (!bl || !bl->read || !buf) {
		errno = EINVAL;
		return FLASH_ERR_PARM_ERROR;
	}

	if (!ecc_protected(bl, pos, len)) {
		return bl->read(bl, pos, buf, len);
	}

	buffer = malloc(ecc_len);
	if (!buffer) {
		errno = ENOMEM;
		return FLASH_ERR_MALLOC_FAILED;
	}

	rc = bl->read(bl, pos, buffer, ecc_len);
	if (rc)
		goto out;

	if (memcpy_from_ecc(buf, buffer, len)) {
		errno = EBADF;
		rc = FLASH_ERR_ECC_INVALID;
	}

out:
	free(buffer);
	return rc;
}
示例#2
0
/*
 * This provides a wrapper around flash_read on ECCed data
 * len is length of data without ECC attached
 */
int flash_read_corrected(struct blocklevel_device *bl, uint32_t pos, void *buf,
		uint32_t len, bool ecc)
{
	struct ecc64 *bufecc;
	uint32_t copylen;
	int rc;
	uint8_t ret;

	if (!ecc)
		return flash_read(bl, pos, buf, len);

	/* Copy the buffer in chunks */
	bufecc = malloc(ecc_buffer_size(COPY_BUFFER_LENGTH));
	if (!bufecc)
		return FLASH_ERR_MALLOC_FAILED;

	while (len > 0) {
		/* What's left to copy? */
		copylen = MIN(len, COPY_BUFFER_LENGTH);

		/* Read ECCed data from flash */
		rc = flash_read(bl, pos, bufecc, ecc_buffer_size(copylen));
		if (rc)
			goto err;

		/* Extract data from ECCed data */
		ret = memcpy_from_ecc(buf, bufecc, copylen);
		if (ret) {
			rc = FLASH_ERR_ECC_INVALID;
			goto err;
		}

		/* Update for next copy */
		len -= copylen;
		buf = (uint8_t *)buf + copylen;
		pos += ecc_buffer_size(copylen);
	}

	rc = 0;

err:
	free(bufecc);
	return rc;
}