int flash_store_contiguous_blocks_init_state_common()

in core/flash/flash_store_contiguous_blocks.c [610:710]


int flash_store_contiguous_blocks_init_state_common (
	const struct flash_store_contiguous_blocks *store, size_t block_count, size_t data_length,
	size_t extra_data)
{
	uint32_t sector_size;
	uint32_t device_size;

#ifdef FLASH_STORE_SUPPORT_NO_PARTIAL_PAGE_WRITE
	uint32_t write_size;
#endif
	int status;

	if ((store == NULL) || (store->state == NULL) || (store->flash == NULL)) {
		return FLASH_STORE_INVALID_ARGUMENT;
	}

	memset (store->state, 0, sizeof (struct flash_store_contiguous_blocks_state));

	status = store->flash->get_sector_size (store->flash, &sector_size);
	if (status != 0) {
		return status;
	}

	if (FLASH_REGION_OFFSET (store->base_addr, sector_size) != 0) {
		return FLASH_STORE_STORAGE_NOT_ALIGNED;
	}

	status = store->flash->get_device_size (store->flash, &device_size);
	if (status != 0) {
		return status;
	}

	if ((store->base_addr >= device_size) || (store->decreasing && (store->base_addr == 0))) {
		return FLASH_STORE_BAD_BASE_ADDRESS;
	}

	store->state->max_size = data_length;
	store->state->blocks = block_count;

	data_length += extra_data;
	if (store->variable) {
		data_length += FLASH_STORE_HEADER_LENGTH;
	}
	if (data_length > sector_size) {
		store->state->block_size = data_length;
	}
	else {
		store->state->block_size = sector_size;
	}

	store->state->block_size = (store->state->block_size + (sector_size - 1)) &
		FLASH_REGION_MASK (sector_size);
	if (!store->decreasing) {
		if ((store->base_addr + (store->state->block_size * store->state->blocks)) > device_size) {
			return FLASH_STORE_INSUFFICIENT_STORAGE;
		}
	}
	else {
		if ((store->state->block_size * (store->state->blocks - 1)) > store->base_addr) {
			return FLASH_STORE_INSUFFICIENT_STORAGE;
		}
	}

	if (store->variable) {
		store->state->max_size = store->state->block_size - FLASH_STORE_HEADER_LENGTH - extra_data;
		if (store->state->max_size > FLASH_STORE_MAX_DATA_SIZE) {
			return FLASH_STORE_BLOCK_TOO_LARGE;
		}
	}

#ifdef FLASH_STORE_SUPPORT_NO_PARTIAL_PAGE_WRITE
	status = store->flash->get_page_size (store->flash, &store->state->page_size);
	if (status != 0) {
		return status;
	}

	status = store->flash->minimum_write_per_page (store->flash, &write_size);
	if (status != 0) {
		return status;
	}

	if ((write_size != 1) &&
		(store->variable || (!store->variable && extra_data &&
		(FLASH_REGION_OFFSET (store->state->max_size, store->state->page_size) != 0)))) {
		/* We need to buffer full page writes at the beginning and/or end of the data. */
		store->state->page_buffer = platform_malloc (store->state->page_size);
		if (store->state->page_buffer == NULL) {
			return FLASH_STORE_NO_MEMORY;
		}
	}

	status = platform_mutex_init (&store->state->lock);
	if (status != 0) {
		platform_free (store->state->page_buffer);

		return status;
	}
#endif

	return 0;
}