/*
 * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of ARM nor the names of its contributors may be used
 * to endorse or promote products derived from this software without specific
 * prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */


#include <stddef.h>
#include <assert.h>
#include "io_storage.h"
#include "io_driver.h"


#define MAX_DEVICES(plat_data)						\
	(sizeof((plat_data)->devices)/sizeof((plat_data)->devices[0]))


/* Storage for a fixed maximum number of IO entities, definable by platform */
static struct io_entity entity_pool[MAX_IO_HANDLES];

/* Simple way of tracking used storage - each entry is NULL or a pointer to an
 * entity */
static struct io_entity *entity_map[MAX_IO_HANDLES];

/* Track number of allocated entities */
static unsigned int entity_count;


/* Used to keep a reference to platform-specific data */
static struct io_plat_data *platform_data;


#if DEBUG	/* Extra validation functions only used in debug builds */

/* Return a boolean value indicating whether a device connector is valid */
static int is_valid_dev_connector(const struct io_dev_connector *dev_con)
{
	int result = (dev_con != NULL) && (dev_con->dev_open != NULL);
	return result;
}


/* Return a boolean value indicating whether a device handle is valid */
static int is_valid_dev(io_dev_handle handle)
{
	const struct io_dev_info *dev = handle;
	int result = (dev != NULL) && (dev->funcs != NULL) &&
			(dev->funcs->type != NULL) &&
			(dev->funcs->type() < IO_TYPE_MAX);
	return result;
}


/* Return a boolean value indicating whether an IO entity is valid */
static int is_valid_entity(io_handle handle)
{
	const struct io_entity *entity = handle;
	int result = (entity != NULL) && (is_valid_dev(entity->dev_handle));
	return result;
}


/* Return a boolean value indicating whether a seek mode is valid */
static int is_valid_seek_mode(io_seek_mode mode)
{
	return ((mode != IO_SEEK_INVALID) && (mode < IO_SEEK_MAX));
}

#endif	/* End of debug-only validation functions */


/* Open a connection to a specific device */
static int dev_open(const struct io_dev_connector *dev_con, void *dev_spec,
		struct io_dev_info **dev_info)
{
	int result = IO_FAIL;
	assert(dev_info != NULL);
	assert(is_valid_dev_connector(dev_con));

	result = dev_con->dev_open(dev_spec, dev_info);
	return result;
}


/* Set a handle to track an entity */
static void set_handle(io_handle *handle, struct io_entity *entity)
{
	assert(handle != NULL);
	*handle = entity;
}


/* Locate an entity in the pool, specified by address */
static int find_first_entity(struct io_entity *entity, unsigned int *index_out)
{
	int result = IO_FAIL;
	for (int index = 0; index < MAX_IO_HANDLES; ++index) {
		if (entity_map[index] == entity) {
			result = IO_SUCCESS;
			*index_out = index;
			break;
		}
	}
	return result;
}


/* Allocate an entity from the pool and return a pointer to it */
static int allocate_entity(struct io_entity **entity)
{
	int result = IO_FAIL;
	assert(entity != NULL);

	if (entity_count < MAX_IO_HANDLES) {
		unsigned int index = 0;
		result = find_first_entity(NULL, &index);
		assert(result == IO_SUCCESS);
		*entity = entity_map[index] = &entity_pool[index];
		++entity_count;
	} else
		result = IO_RESOURCES_EXHAUSTED;

	return result;
}


/* Release an entity back to the pool */
static int free_entity(struct io_entity *entity)
{
	int result = IO_FAIL;
	unsigned int index = 0;
	assert(entity != NULL);

	result = find_first_entity(entity, &index);
	if (result ==  IO_SUCCESS) {
		entity_map[index] = NULL;
		--entity_count;
	}

	return result;
}


/* Exported API */


/* Initialise the IO layer */
void io_init(struct io_plat_data *data)
{
	assert(data != NULL);
	platform_data = data;
}


/* Register a device driver */
int io_register_device(struct io_dev_info *dev_info)
{
	int result = IO_FAIL;
	assert(dev_info != NULL);
	assert(platform_data != NULL);

	unsigned int dev_count = platform_data->dev_count;

	if (dev_count < MAX_DEVICES(platform_data)) {
		platform_data->devices[dev_count] = dev_info;
		platform_data->dev_count++;
		result = IO_SUCCESS;
	} else {
		result = IO_RESOURCES_EXHAUSTED;
	}

	return result;
}


/* Open a connection to an IO device */
int io_dev_open(struct io_dev_connector *dev_con, void *dev_spec,
		io_dev_handle *handle)
{
	int result = IO_FAIL;
	assert(handle != NULL);

	result = dev_open(dev_con, dev_spec, handle);
	return result;
}


/* Initialise an IO device explicitly - to permit lazy initialisation or
 * re-initialisation */
int io_dev_init(struct io_dev_info *dev_handle, const void *init_params)
{
	int result = IO_FAIL;
	assert(dev_handle != NULL);
	assert(is_valid_dev(dev_handle));

	struct io_dev_info *dev = dev_handle;

	if (dev->funcs->dev_init != NULL) {
		result = dev->funcs->dev_init(dev, init_params);
	} else {
		/* Absence of registered function implies NOP here */
		result = IO_SUCCESS;
	}
	return result;
}


/* TODO: Consider whether an explicit "shutdown" API should be included */

/* Close a connection to a device */
int io_dev_close(io_dev_handle dev_handle)
{
	int result = IO_FAIL;
	assert(dev_handle != NULL);
	assert(is_valid_dev(dev_handle));

	struct io_dev_info *dev = dev_handle;

	if (dev->funcs->dev_close != NULL) {
		result = dev->funcs->dev_close(dev);
	} else {
		/* Absence of registered function implies NOP here */
		result = IO_SUCCESS;
	}

	return result;
}


/* Synchronous operations */


/* Open an IO entity */
int io_open(io_dev_handle dev_handle, const void *spec, io_handle *handle)
{
	int result = IO_FAIL;
	assert((spec != NULL) && (handle != NULL));
	assert(is_valid_dev(dev_handle));

	struct io_dev_info *dev = dev_handle;
	struct io_entity *entity;

	result = allocate_entity(&entity);

	if (result == IO_SUCCESS) {
		assert(dev->funcs->open != NULL);
		result = dev->funcs->open(dev, spec, entity);

		if (result == IO_SUCCESS) {
			entity->dev_handle = dev_handle;
			set_handle(handle, entity);
		} else
			free_entity(entity);
	}
	return result;
}


/* Seek to a specific position in an IO entity */
int io_seek(io_handle handle, io_seek_mode mode, ssize_t offset)
{
	int result = IO_FAIL;
	assert(is_valid_entity(handle) && is_valid_seek_mode(mode));

	struct io_entity *entity = handle;

	struct io_dev_info *dev = entity->dev_handle;

	if (dev->funcs->seek != NULL)
		result = dev->funcs->seek(entity, mode, offset);
	else
		result = IO_NOT_SUPPORTED;

	return result;
}


/* Determine the length of an IO entity */
int io_size(io_handle handle, size_t *length)
{
	int result = IO_FAIL;
	assert(is_valid_entity(handle) && (length != NULL));

	struct io_entity *entity = handle;

	struct io_dev_info *dev = entity->dev_handle;

	if (dev->funcs->size != NULL)
		result = dev->funcs->size(entity, length);
	else
		result = IO_NOT_SUPPORTED;

	return result;
}


/* Read data from an IO entity */
int io_read(io_handle handle, void *buffer, size_t length, size_t *length_read)
{
	int result = IO_FAIL;
	assert(is_valid_entity(handle) && (buffer != NULL));

	struct io_entity *entity = handle;

	struct io_dev_info *dev = entity->dev_handle;

	if (dev->funcs->read != NULL)
		result = dev->funcs->read(entity, buffer, length, length_read);
	else
		result = IO_NOT_SUPPORTED;

	return result;
}


/* Write data to an IO entity */
int io_write(io_handle handle, const void *buffer, size_t length,
		size_t *length_written)
{
	int result = IO_FAIL;
	assert(is_valid_entity(handle) && (buffer != NULL));

	struct io_entity *entity = handle;

	struct io_dev_info *dev = entity->dev_handle;

	if (dev->funcs->write != NULL) {
		result = dev->funcs->write(entity, buffer, length,
				length_written);
	} else
		result = IO_NOT_SUPPORTED;

	return result;
}


/* Close an IO entity */
int io_close(io_handle handle)
{
	int result = IO_FAIL;
	assert(is_valid_entity(handle));

	struct io_entity *entity = handle;

	struct io_dev_info *dev = entity->dev_handle;

	if (dev->funcs->close != NULL)
		result = dev->funcs->close(entity);
	else {
		/* Absence of registered function implies NOP here */
		result = IO_SUCCESS;
	}
	/* Ignore improbable free_entity failure */
	(void)free_entity(entity);

	return result;
}
