/*
 *  acpi_utils.c - ACPI Utility Functions ($Revision: 10 $)
 *
 *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
 *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or (at
 *  your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>

#define _COMPONENT		ACPI_BUS_COMPONENT
ACPI_MODULE_NAME("acpi_utils")

/* --------------------------------------------------------------------------
                            Object Evaluation Helpers
   -------------------------------------------------------------------------- */
#ifdef ACPI_DEBUG_OUTPUT
#define acpi_util_eval_error(h,p,s) {\
	char prefix[80] = {'\0'};\
	struct acpi_buffer buffer = {sizeof(prefix), prefix};\
	acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);\
	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s\n",\
		(char *) prefix, p, acpi_format_exception(s))); }
#else
#define acpi_util_eval_error(h,p,s)
#endif
acpi_status
acpi_extract_package(union acpi_object *package,
		     struct acpi_buffer *format, struct acpi_buffer *buffer)
{
	u32 size_required = 0;
	u32 tail_offset = 0;
	char *format_string = NULL;
	u32 format_count = 0;
	u32 i = 0;
	u8 *head = NULL;
	u8 *tail = NULL;

	ACPI_FUNCTION_TRACE("acpi_extract_package");

	if (!package || (package->type != ACPI_TYPE_PACKAGE)
	    || (package->package.count < 1)) {
		ACPI_DEBUG_PRINT((ACPI_DB_WARN,
				  "Invalid 'package' argument\n"));
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	if (!format || !format->pointer || (format->length < 1)) {
		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid 'format' argument\n"));
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	if (!buffer) {
		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid 'buffer' argument\n"));
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	format_count = (format->length / sizeof(char)) - 1;
	if (format_count > package->package.count) {
		ACPI_DEBUG_PRINT((ACPI_DB_WARN,
				  "Format specifies more objects [%d] than exist in package [%d].",
				  format_count, package->package.count));
		return_ACPI_STATUS(AE_BAD_DATA);
	}

	format_string = (char *)format->pointer;

	/*
	 * Calculate size_required.
	 */
	for (i = 0; i < format_count; i++) {

		union acpi_object *element = &(package->package.elements[i]);

		if (!element) {
			return_ACPI_STATUS(AE_BAD_DATA);
		}

		switch (element->type) {

		case ACPI_TYPE_INTEGER:
			switch (format_string[i]) {
			case 'N':
				size_required += sizeof(acpi_integer);
				tail_offset += sizeof(acpi_integer);
				break;
			case 'S':
				size_required +=
				    sizeof(char *) + sizeof(acpi_integer) +
				    sizeof(char);
				tail_offset += sizeof(char *);
				break;
			default:
				ACPI_DEBUG_PRINT((ACPI_DB_WARN,
						  "Invalid package element [%d]: got number, expecing [%c].\n",
						  i, format_string[i]));
				return_ACPI_STATUS(AE_BAD_DATA);
				break;
			}
			break;

		case ACPI_TYPE_STRING:
		case ACPI_TYPE_BUFFER:
			switch (format_string[i]) {
			case 'S':
				size_required +=
				    sizeof(char *) +
				    (element->string.length * sizeof(char)) +
				    sizeof(char);
				tail_offset += sizeof(char *);
				break;
			case 'B':
				size_required +=
				    sizeof(u8 *) +
				    (element->buffer.length * sizeof(u8));
				tail_offset += sizeof(u8 *);
				break;
			default:
				ACPI_DEBUG_PRINT((ACPI_DB_WARN,
						  "Invalid package element [%d] got string/buffer, expecing [%c].\n",
						  i, format_string[i]));
				return_ACPI_STATUS(AE_BAD_DATA);
				break;
			}
			break;

		case ACPI_TYPE_PACKAGE:
		default:
			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
					  "Found unsupported element at index=%d\n",
					  i));
			/* TBD: handle nested packages... */
			return_ACPI_STATUS(AE_SUPPORT);
			break;
		}
	}

	/*
	 * Validate output buffer.
	 */
	if (buffer->length < size_required) {
		buffer->length = size_required;
		return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
	} else if (buffer->length != size_required || !buffer->pointer) {
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	head = buffer->pointer;
	tail = buffer->pointer + tail_offset;

	/*
	 * Extract package data.
	 */
	for (i = 0; i < format_count; i++) {

		u8 **pointer = NULL;
		union acpi_object *element = &(package->package.elements[i]);

		if (!element) {
			return_ACPI_STATUS(AE_BAD_DATA);
		}

		switch (element->type) {

		case ACPI_TYPE_INTEGER:
			switch (format_string[i]) {
			case 'N':
				*((acpi_integer *) head) =
				    element->integer.value;
				head += sizeof(acpi_integer);
				break;
			case 'S':
				pointer = (u8 **) head;
				*pointer = tail;
				*((acpi_integer *) tail) =
				    element->integer.value;
				head += sizeof(acpi_integer *);
				tail += sizeof(acpi_integer);
				/* NULL terminate string */
				*tail = (char)0;
				tail += sizeof(char);
				break;
			default:
				/* Should never get here */
				break;
			}
			break;

		case ACPI_TYPE_STRING:
		case ACPI_TYPE_BUFFER:
			switch (format_string[i]) {
			case 'S':
				pointer = (u8 **) head;
				*pointer = tail;
				memcpy(tail, element->string.pointer,
				       element->string.length);
				head += sizeof(char *);
				tail += element->string.length * sizeof(char);
				/* NULL terminate string */
				*tail = (char)0;
				tail += sizeof(char);
				break;
			case 'B':
				pointer = (u8 **) head;
				*pointer = tail;
				memcpy(tail, element->buffer.pointer,
				       element->buffer.length);
				head += sizeof(u8 *);
				tail += element->buffer.length * sizeof(u8);
				break;
			default:
				/* Should never get here */
				break;
			}
			break;

		case ACPI_TYPE_PACKAGE:
			/* TBD: handle nested packages... */
		default:
			/* Should never get here */
			break;
		}
	}

	return_ACPI_STATUS(AE_OK);
}

EXPORT_SYMBOL(acpi_extract_package);

acpi_status
acpi_evaluate_integer(acpi_handle handle,
		      acpi_string pathname,
		      struct acpi_object_list *arguments, unsigned long *data)
{
	acpi_status status = AE_OK;
	union acpi_object *element;
	struct acpi_buffer buffer = { 0, NULL };

	ACPI_FUNCTION_TRACE("acpi_evaluate_integer");

	if (!data)
		return_ACPI_STATUS(AE_BAD_PARAMETER);

	element = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
	if (!element)
		return_ACPI_STATUS(AE_NO_MEMORY);

	memset(element, 0, sizeof(union acpi_object));
	buffer.length = sizeof(union acpi_object);
	buffer.pointer = element;
	status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
	if (ACPI_FAILURE(status)) {
		acpi_util_eval_error(handle, pathname, status);
		kfree(element);
		return_ACPI_STATUS(status);
	}

	if (element->type != ACPI_TYPE_INTEGER) {
		acpi_util_eval_error(handle, pathname, AE_BAD_DATA);
		kfree(element);
		return_ACPI_STATUS(AE_BAD_DATA);
	}

	*data = element->integer.value;
	kfree(element);

	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%lu]\n", *data));

	return_ACPI_STATUS(AE_OK);
}

EXPORT_SYMBOL(acpi_evaluate_integer);

#if 0
acpi_status
acpi_evaluate_string(acpi_handle handle,
		     acpi_string pathname,
		     acpi_object_list * arguments, acpi_string * data)
{
	acpi_status status = AE_OK;
	acpi_object *element = NULL;
	acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };

	ACPI_FUNCTION_TRACE("acpi_evaluate_string");

	if (!data)
		return_ACPI_STATUS(AE_BAD_PARAMETER);

	status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
	if (ACPI_FAILURE(status)) {
		acpi_util_eval_error(handle, pathname, status);
		return_ACPI_STATUS(status);
	}

	element = (acpi_object *) buffer.pointer;

	if ((element->type != ACPI_TYPE_STRING)
	    || (element->type != ACPI_TYPE_BUFFER)
	    || !element->string.length) {
		acpi_util_eval_error(handle, pathname, AE_BAD_DATA);
		return_ACPI_STATUS(AE_BAD_DATA);
	}

	*data = kmalloc(element->string.length + 1, GFP_KERNEL);
	if (!data) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Memory allocation error\n"));
		return_VALUE(-ENOMEM);
	}
	memset(*data, 0, element->string.length + 1);

	memcpy(*data, element->string.pointer, element->string.length);

	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%s]\n", *data));

	acpi_os_free(buffer.pointer);

	return_ACPI_STATUS(AE_OK);
}
#endif

acpi_status
acpi_evaluate_reference(acpi_handle handle,
			acpi_string pathname,
			struct acpi_object_list *arguments,
			struct acpi_handle_list *list)
{
	acpi_status status = AE_OK;
	union acpi_object *package = NULL;
	union acpi_object *element = NULL;
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	u32 i = 0;

	ACPI_FUNCTION_TRACE("acpi_evaluate_reference");

	if (!list) {
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	/* Evaluate object. */

	status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
	if (ACPI_FAILURE(status))
		goto end;

	package = (union acpi_object *)buffer.pointer;

	if ((buffer.length == 0) || !package) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
				  "No return object (len %X ptr %p)\n",
				  (unsigned)buffer.length, package));
		status = AE_BAD_DATA;
		acpi_util_eval_error(handle, pathname, status);
		goto end;
	}
	if (package->type != ACPI_TYPE_PACKAGE) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
				  "Expecting a [Package], found type %X\n",
				  package->type));
		status = AE_BAD_DATA;
		acpi_util_eval_error(handle, pathname, status);
		goto end;
	}
	if (!package->package.count) {
		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
				  "[Package] has zero elements (%p)\n",
				  package));
		status = AE_BAD_DATA;
		acpi_util_eval_error(handle, pathname, status);
		goto end;
	}

	if (package->package.count > ACPI_MAX_HANDLES) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}
	list->count = package->package.count;

	/* Extract package data. */

	for (i = 0; i < list->count; i++) {

		element = &(package->package.elements[i]);

		if (element->type != ACPI_TYPE_ANY) {
			status = AE_BAD_DATA;
			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
					  "Expecting a [Reference] package element, found type %X\n",
					  element->type));
			acpi_util_eval_error(handle, pathname, status);
			break;
		}

		/* Get the  acpi_handle. */

		list->handles[i] = element->reference.handle;
		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found reference [%p]\n",
				  list->handles[i]));
	}

      end:
	if (ACPI_FAILURE(status)) {
		list->count = 0;
		//kfree(list->handles);
	}

	acpi_os_free(buffer.pointer);

	return_ACPI_STATUS(status);
}

EXPORT_SYMBOL(acpi_evaluate_reference);
