/* Cypress West Bridge API source file (cyaslowlevel.c)
## ===========================
## Copyright (C) 2010  Cypress Semiconductor
##
## 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., 51 Franklin Street, Fifth Floor
## Boston, MA  02110-1301, USA.
## ===========================
*/

#include "../../include/linux/westbridge/cyashal.h"
#include "../../include/linux/westbridge/cyascast.h"
#include "../../include/linux/westbridge/cyasdevice.h"
#include "../../include/linux/westbridge/cyaslowlevel.h"
#include "../../include/linux/westbridge/cyasintr.h"
#include "../../include/linux/westbridge/cyaserr.h"
#include "../../include/linux/westbridge/cyasregs.h"

static const uint32_t cy_as_low_level_timeout_count = 65536 * 4;

/* Forward declaration */
static cy_as_return_status_t cy_as_send_one(cy_as_device *dev_p,
	cy_as_ll_request_response *req_p);

/*
* This array holds the size of the largest request we will ever recevie from
* the West Bridge device per context.  The size is in 16 bit words.  Note a
* size of 0xffff indicates that there will be no requests on this context
* from West Bridge.
*/
static uint16_t max_request_length[CY_RQT_CONTEXT_COUNT] = {
	8, /* CY_RQT_GENERAL_RQT_CONTEXT - CY_RQT_INITIALIZATION_COMPLETE */
	8, /* CY_RQT_RESOURCE_RQT_CONTEXT - none */
	8, /* CY_RQT_STORAGE_RQT_CONTEXT - CY_RQT_MEDIA_CHANGED */
	128, /* CY_RQT_USB_RQT_CONTEXT - CY_RQT_USB_EVENT */
	8 /* CY_RQT_TUR_RQT_CONTEXT - CY_RQT_TURBO_CMD_FROM_HOST */
};

/*
* For the given context, this function removes the request node at the head
* of the queue from the context.  This is called after all processing has
* occurred on the given request and response and we are ready to remove this
* entry from the queue.
*/
static void
cy_as_ll_remove_request_queue_head(cy_as_device *dev_p, cy_as_context *ctxt_p)
{
	uint32_t mask, state;
	cy_as_ll_request_list_node *node_p;

	(void)dev_p;
	cy_as_hal_assert(ctxt_p->request_queue_p != 0);

	mask = cy_as_hal_disable_interrupts();
	node_p = ctxt_p->request_queue_p;
	ctxt_p->request_queue_p = node_p->next;
	cy_as_hal_enable_interrupts(mask);

	node_p->callback = 0;
	node_p->rqt = 0;
	node_p->resp = 0;

	/*
	* note that the caller allocates and destroys the request and
	* response.  generally the destroy happens in the callback for
	* async requests and after the wait returns for sync.  the
	* request and response may not actually be destroyed but may be
	* managed in other ways as well.  it is the responsibilty of
	* the caller to deal with these in any case.  the caller can do
	* this in the request/response callback function.
	*/
	state = cy_as_hal_disable_interrupts();
	cy_as_hal_c_b_free(node_p);
	cy_as_hal_enable_interrupts(state);
}

/*
* For the context given, this function sends the next request to
* West Bridge via the mailbox register, if the next request is
* ready to be sent and has not already been sent.
*/
static void
cy_as_ll_send_next_request(cy_as_device *dev_p, cy_as_context *ctxt_p)
{
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;

	/*
	* ret == ret is equivalent to while (1) but eliminates compiler
	* warnings for some compilers.
	*/
	while (ret == ret) {
		cy_as_ll_request_list_node *node_p = ctxt_p->request_queue_p;
		if (node_p == 0)
			break;

		if (cy_as_request_get_node_state(node_p) !=
			CY_AS_REQUEST_LIST_STATE_QUEUED)
			break;

		cy_as_request_set_node_state(node_p,
			CY_AS_REQUEST_LIST_STATE_WAITING);
		ret = cy_as_send_one(dev_p, node_p->rqt);
		if (ret == CY_AS_ERROR_SUCCESS)
			break;

		/*
		* if an error occurs in sending the request, tell the requester
		* about the error and remove the request from the queue.
		*/
		cy_as_request_set_node_state(node_p,
			CY_AS_REQUEST_LIST_STATE_RECEIVED);
		node_p->callback(dev_p, ctxt_p->number,
			node_p->rqt, node_p->resp, ret);
		cy_as_ll_remove_request_queue_head(dev_p, ctxt_p);

		/*
		* this falls through to the while loop to send the next request
		* since the previous request did not get sent.
		*/
	}
}

/*
* This method removes an entry from the request queue of a given context.
* The entry is removed only if it is not in transit.
*/
cy_as_remove_request_result_t
cy_as_ll_remove_request(cy_as_device *dev_p, cy_as_context *ctxt_p,
	cy_as_ll_request_response *req_p, cy_bool force)
{
	uint32_t imask;
	cy_as_ll_request_list_node *node_p;
	cy_as_ll_request_list_node *tmp_p;
	uint32_t state;

	imask = cy_as_hal_disable_interrupts();
	if (ctxt_p->request_queue_p != 0 &&
		ctxt_p->request_queue_p->rqt == req_p) {
		node_p = ctxt_p->request_queue_p;
		if ((cy_as_request_get_node_state(node_p) ==
			CY_AS_REQUEST_LIST_STATE_WAITING) && (!force)) {
			cy_as_hal_enable_interrupts(imask);
			return cy_as_remove_request_in_transit;
		}

		ctxt_p->request_queue_p = node_p->next;
	} else {
		tmp_p = ctxt_p->request_queue_p;
		while (tmp_p != 0 && tmp_p->next != 0 &&
			tmp_p->next->rqt != req_p)
			tmp_p = tmp_p->next;

		if (tmp_p == 0 || tmp_p->next == 0) {
			cy_as_hal_enable_interrupts(imask);
			return cy_as_remove_request_not_found;
		}

		node_p = tmp_p->next;
		tmp_p->next = node_p->next;
	}

	if (node_p->callback)
		node_p->callback(dev_p, ctxt_p->number, node_p->rqt,
			node_p->resp, CY_AS_ERROR_CANCELED);

	state = cy_as_hal_disable_interrupts();
	cy_as_hal_c_b_free(node_p);
	cy_as_hal_enable_interrupts(state);

	cy_as_hal_enable_interrupts(imask);
	return cy_as_remove_request_sucessful;
}

void
cy_as_ll_remove_all_requests(cy_as_device *dev_p, cy_as_context *ctxt_p)
{
	cy_as_ll_request_list_node *node = ctxt_p->request_queue_p;

	while (node) {
		if (cy_as_request_get_node_state(ctxt_p->request_queue_p) !=
			CY_AS_REQUEST_LIST_STATE_RECEIVED)
			cy_as_ll_remove_request(dev_p, ctxt_p,
				node->rqt, cy_true);
		node = node->next;
	}
}

static cy_bool
cy_as_ll_is_in_queue(cy_as_context *ctxt_p, cy_as_ll_request_response *req_p)
{
	uint32_t mask;
	cy_as_ll_request_list_node *node_p;

	mask = cy_as_hal_disable_interrupts();
	node_p = ctxt_p->request_queue_p;
	while (node_p) {
		if (node_p->rqt == req_p) {
			cy_as_hal_enable_interrupts(mask);
			return cy_true;
		}
		node_p = node_p->next;
	}
	cy_as_hal_enable_interrupts(mask);
	return cy_false;
}

/*
* This is the handler for mailbox data when we are trying to send data
* to the West Bridge firmware.  The firmware may be trying to send us
* data and we need to queue this data to allow the firmware to move
* forward and be in a state to receive our request.  Here we just queue
* the data and it is processed at a later time by the mailbox interrupt
* handler.
*/
void
cy_as_ll_queue_mailbox_data(cy_as_device *dev_p)
{
	cy_as_context *ctxt_p;
	uint8_t context;
	uint16_t data[4];
	int32_t i;

	/* Read the data from mailbox 0 to determine what to do with the data */
	for (i = 3; i >= 0; i--)
		data[i] = cy_as_hal_read_register(dev_p->tag,
			cy_cast_int2U_int16(CY_AS_MEM_P0_MAILBOX0 + i));

	context = cy_as_mbox_get_context(data[0]);
	if (context >= CY_RQT_CONTEXT_COUNT) {
		cy_as_hal_print_message("mailbox request/response received "
			"with invalid context value (%d)\n", context);
		return;
	}

	ctxt_p = dev_p->context[context];

	/*
	* if we have queued too much data, drop future data.
	*/
	cy_as_hal_assert(ctxt_p->queue_index * sizeof(uint16_t) +
		sizeof(data) <= sizeof(ctxt_p->data_queue));

	for (i = 0; i < 4; i++)
		ctxt_p->data_queue[ctxt_p->queue_index++] = data[i];

	cy_as_hal_assert((ctxt_p->queue_index % 4) == 0);
	dev_p->ll_queued_data = cy_true;
}

void
cy_as_mail_box_process_data(cy_as_device *dev_p, uint16_t *data)
{
	cy_as_context *ctxt_p;
	uint8_t context;
	uint16_t *len_p;
	cy_as_ll_request_response *rec_p;
	uint8_t st;
	uint16_t src, dest;

	context = cy_as_mbox_get_context(data[0]);
	if (context >= CY_RQT_CONTEXT_COUNT) {
		cy_as_hal_print_message("mailbox request/response received "
		"with invalid context value (%d)\n", context);
		return;
	}

	ctxt_p = dev_p->context[context];

	if (cy_as_mbox_is_request(data[0])) {
		cy_as_hal_assert(ctxt_p->req_p != 0);
		rec_p = ctxt_p->req_p;
		len_p = &ctxt_p->request_length;

	} else {
		if (ctxt_p->request_queue_p == 0 ||
			cy_as_request_get_node_state(ctxt_p->request_queue_p)
			!= CY_AS_REQUEST_LIST_STATE_WAITING) {
			cy_as_hal_print_message("mailbox response received on "
				"context that was not expecting a response\n");
			cy_as_hal_print_message("  context: %d\n", context);
			cy_as_hal_print_message("  contents: 0x%04x 0x%04x "
				"0x%04x 0x%04x\n",
				data[0], data[1], data[2], data[3]);
			if (ctxt_p->request_queue_p != 0)
				cy_as_hal_print_message("  state: 0x%02x\n",
					ctxt_p->request_queue_p->state);
			return;
		}

		/* Make sure the request has an associated response */
		cy_as_hal_assert(ctxt_p->request_queue_p->resp != 0);

		rec_p = ctxt_p->request_queue_p->resp;
		len_p = &ctxt_p->request_queue_p->length;
	}

	if (rec_p->stored == 0) {
		/*
		* this is the first cycle of the response
		*/
		cy_as_ll_request_response__set_code(rec_p,
			cy_as_mbox_get_code(data[0]));
		cy_as_ll_request_response__set_context(rec_p, context);

		if (cy_as_mbox_is_last(data[0])) {
			/* This is a single cycle response */
			*len_p = rec_p->length;
			st = 1;
		} else {
			/* Ensure that enough memory has been
			 * reserved for the response. */
			cy_as_hal_assert(rec_p->length >= data[1]);
			*len_p = (data[1] < rec_p->length) ?
				data[1] : rec_p->length;
			st = 2;
		}
	} else
		st = 1;

	/* Trasnfer the data from the mailboxes to the response */
	while (rec_p->stored < *len_p && st < 4)
		rec_p->data[rec_p->stored++] = data[st++];

	if (cy_as_mbox_is_last(data[0])) {
		/* NB: The call-back that is made below can cause the
		 * addition of more data in this queue, thus causing
		 * a recursive overflow of the queue. this is prevented
		 * by removing the request entry that is currently
		 * being passed up from the data queue. if this is done,
		 * the queue only needs to be as long as two request
		 * entries from west bridge.
		*/
		if ((ctxt_p->rqt_index > 0) &&
			(ctxt_p->rqt_index <= ctxt_p->queue_index)) {
			dest = 0;
			src  = ctxt_p->rqt_index;

			while (src < ctxt_p->queue_index)
				ctxt_p->data_queue[dest++] =
					ctxt_p->data_queue[src++];

			ctxt_p->rqt_index = 0;
			ctxt_p->queue_index = dest;
			cy_as_hal_assert((ctxt_p->queue_index % 4) == 0);
		}

		if (ctxt_p->request_queue_p != 0 && rec_p ==
			ctxt_p->request_queue_p->resp) {
			/*
			* if this is the last cycle of the response, call the
			* callback and reset for the next response.
			*/
			cy_as_ll_request_response *resp_p =
				ctxt_p->request_queue_p->resp;
			resp_p->length = ctxt_p->request_queue_p->length;
			cy_as_request_set_node_state(ctxt_p->request_queue_p,
				CY_AS_REQUEST_LIST_STATE_RECEIVED);

			cy_as_device_set_in_callback(dev_p);
			ctxt_p->request_queue_p->callback(dev_p, context,
				ctxt_p->request_queue_p->rqt,
				resp_p, CY_AS_ERROR_SUCCESS);

			cy_as_device_clear_in_callback(dev_p);

			cy_as_ll_remove_request_queue_head(dev_p, ctxt_p);
			cy_as_ll_send_next_request(dev_p, ctxt_p);
		} else {
			/* Send the request to the appropriate
			 * module to handle */
			cy_as_ll_request_response *request_p = ctxt_p->req_p;
			ctxt_p->req_p = 0;
			if (ctxt_p->request_callback) {
				cy_as_device_set_in_callback(dev_p);
				ctxt_p->request_callback(dev_p, context,
					request_p, 0, CY_AS_ERROR_SUCCESS);
				cy_as_device_clear_in_callback(dev_p);
			}
			cy_as_ll_init_request(request_p, 0,
				context, request_p->length);
			ctxt_p->req_p = request_p;
		}
	}
}

/*
* This is the handler for processing queued mailbox data
*/
void
cy_as_mail_box_queued_data_handler(cy_as_device *dev_p)
{
	uint16_t i;

	/*
	 * if more data gets queued in between our entering this call
	 * and the end of the iteration on all contexts; we should
	 * continue processing the queued data.
	 */
	while (dev_p->ll_queued_data) {
		dev_p->ll_queued_data = cy_false;
		for (i = 0; i < CY_RQT_CONTEXT_COUNT; i++) {
			uint16_t offset;
			cy_as_context *ctxt_p = dev_p->context[i];
			cy_as_hal_assert((ctxt_p->queue_index % 4) == 0);

			offset = 0;
			while (offset < ctxt_p->queue_index) {
				ctxt_p->rqt_index = offset + 4;
				cy_as_mail_box_process_data(dev_p,
					ctxt_p->data_queue + offset);
				offset = ctxt_p->rqt_index;
			}
			ctxt_p->queue_index = 0;
		}
	}
}

/*
* This is the handler for the mailbox interrupt.  This function reads
* data from the mailbox registers until a complete request or response
* is received.  When a complete request is received, the callback
* associated with requests on that context is called.  When a complete
* response is recevied, the callback associated with the request that
* generated the reponse is called.
*/
void
cy_as_mail_box_interrupt_handler(cy_as_device *dev_p)
{
	cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE);

	/*
	* queue the mailbox data to preserve
	* order for later processing.
	*/
	cy_as_ll_queue_mailbox_data(dev_p);

	/*
	* process what was queued and anything that may be pending
	*/
	cy_as_mail_box_queued_data_handler(dev_p);
}

cy_as_return_status_t
cy_as_ll_start(cy_as_device *dev_p)
{
	uint16_t i;

	if (cy_as_device_is_low_level_running(dev_p))
		return CY_AS_ERROR_ALREADY_RUNNING;

	dev_p->ll_sending_rqt = cy_false;
	dev_p->ll_abort_curr_rqt = cy_false;

	for (i = 0; i < CY_RQT_CONTEXT_COUNT; i++) {
		dev_p->context[i] = (cy_as_context *)
			cy_as_hal_alloc(sizeof(cy_as_context));
		if (dev_p->context[i] == 0)
			return CY_AS_ERROR_OUT_OF_MEMORY;

		dev_p->context[i]->number = (uint8_t)i;
		dev_p->context[i]->request_callback = 0;
		dev_p->context[i]->request_queue_p = 0;
		dev_p->context[i]->last_node_p = 0;
		dev_p->context[i]->req_p = cy_as_ll_create_request(dev_p,
			0, (uint8_t)i, max_request_length[i]);
		dev_p->context[i]->queue_index = 0;

		if (!cy_as_hal_create_sleep_channel
			(&dev_p->context[i]->channel))
			return CY_AS_ERROR_CREATE_SLEEP_CHANNEL_FAILED;
	}

	cy_as_device_set_low_level_running(dev_p);
	return CY_AS_ERROR_SUCCESS;
}

/*
* Shutdown the low level communications module.  This operation will
* also cancel any queued low level requests.
*/
cy_as_return_status_t
cy_as_ll_stop(cy_as_device *dev_p)
{
	uint8_t i;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	cy_as_context *ctxt_p;
	uint32_t mask;

	for (i = 0; i < CY_RQT_CONTEXT_COUNT; i++) {
		ctxt_p = dev_p->context[i];
		if (!cy_as_hal_destroy_sleep_channel(&ctxt_p->channel))
			return CY_AS_ERROR_DESTROY_SLEEP_CHANNEL_FAILED;

		/*
		* now, free any queued requests and assocaited responses
		*/
		while (ctxt_p->request_queue_p) {
			uint32_t state;
			cy_as_ll_request_list_node *node_p =
				ctxt_p->request_queue_p;

			/* Mark this pair as in a cancel operation */
			cy_as_request_set_node_state(node_p,
				CY_AS_REQUEST_LIST_STATE_CANCELING);

			/* Tell the caller that we are canceling this request */
			/* NB: The callback is responsible for destroying the
			 * request and the response.  we cannot count on the
			 * contents of these two after calling the callback.
			*/
			node_p->callback(dev_p, i, node_p->rqt,
				node_p->resp, CY_AS_ERROR_CANCELED);

			/* Remove the pair from the queue */
			mask = cy_as_hal_disable_interrupts();
			ctxt_p->request_queue_p = node_p->next;
			cy_as_hal_enable_interrupts(mask);

			/* Free the list node */
			state = cy_as_hal_disable_interrupts();
			cy_as_hal_c_b_free(node_p);
			cy_as_hal_enable_interrupts(state);
		}

		cy_as_ll_destroy_request(dev_p, dev_p->context[i]->req_p);
		cy_as_hal_free(dev_p->context[i]);
		dev_p->context[i] = 0;

	}
	cy_as_device_set_low_level_stopped(dev_p);

	return ret;
}

void
cy_as_ll_init_request(cy_as_ll_request_response *req_p,
	uint16_t code, uint16_t context, uint16_t length)
{
	uint16_t totallen = sizeof(cy_as_ll_request_response) +
		(length - 1) * sizeof(uint16_t);

	cy_as_hal_mem_set(req_p, 0, totallen);
	req_p->length = length;
	cy_as_ll_request_response__set_code(req_p, code);
	cy_as_ll_request_response__set_context(req_p, context);
	cy_as_ll_request_response__set_request(req_p);
}

/*
* Create a new request.
*/
cy_as_ll_request_response *
cy_as_ll_create_request(cy_as_device *dev_p, uint16_t code,
	uint8_t context, uint16_t length)
{
	cy_as_ll_request_response *req_p;
	uint32_t state;
	uint16_t totallen = sizeof(cy_as_ll_request_response) +
		(length - 1) * sizeof(uint16_t);

	(void)dev_p;

	state = cy_as_hal_disable_interrupts();
	req_p = cy_as_hal_c_b_alloc(totallen);
	cy_as_hal_enable_interrupts(state);
	if (req_p)
		cy_as_ll_init_request(req_p, code, context, length);

	return req_p;
}

/*
* Destroy a request.
*/
void
cy_as_ll_destroy_request(cy_as_device *dev_p, cy_as_ll_request_response *req_p)
{
	uint32_t state;
	(void)dev_p;
	(void)req_p;

	state = cy_as_hal_disable_interrupts();
	cy_as_hal_c_b_free(req_p);
	cy_as_hal_enable_interrupts(state);

}

void
cy_as_ll_init_response(cy_as_ll_request_response *req_p, uint16_t length)
{
	uint16_t totallen = sizeof(cy_as_ll_request_response) +
		(length - 1) * sizeof(uint16_t);

	cy_as_hal_mem_set(req_p, 0, totallen);
	req_p->length = length;
	cy_as_ll_request_response__set_response(req_p);
}

/*
* Create a new response
*/
cy_as_ll_request_response *
cy_as_ll_create_response(cy_as_device *dev_p, uint16_t length)
{
	cy_as_ll_request_response *req_p;
	uint32_t state;
	uint16_t totallen = sizeof(cy_as_ll_request_response) +
		(length - 1) * sizeof(uint16_t);

	(void)dev_p;

	state = cy_as_hal_disable_interrupts();
	req_p = cy_as_hal_c_b_alloc(totallen);
	cy_as_hal_enable_interrupts(state);
	if (req_p)
		cy_as_ll_init_response(req_p, length);

	return req_p;
}

/*
* Destroy the new response
*/
void
cy_as_ll_destroy_response(cy_as_device *dev_p, cy_as_ll_request_response *req_p)
{
	uint32_t state;
	(void)dev_p;
	(void)req_p;

	state = cy_as_hal_disable_interrupts();
	cy_as_hal_c_b_free(req_p);
	cy_as_hal_enable_interrupts(state);
}

static uint16_t
cy_as_read_intr_status(
				   cy_as_device *dev_p)
{
	uint32_t mask;
	cy_bool bloop = cy_true;
	uint16_t v = 0, last = 0xffff;

	/*
	* before determining if the mailboxes are ready for more data,
	* we first check the mailbox interrupt to see if we need to
	* receive data.  this prevents a dead-lock condition that can
	* occur when both sides are trying to receive data.
	*/
	while (last == last) {
		/*
		* disable interrupts to be sure we don't process the mailbox
		* here and have the interrupt routine try to read this data
		* as well.
		*/
		mask = cy_as_hal_disable_interrupts();

		/*
		* see if there is data to be read.
		*/
		v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_P0_INTR_REG);
		if ((v & CY_AS_MEM_P0_INTR_REG_MBINT) == 0) {
			cy_as_hal_enable_interrupts(mask);
			break;
		}

		/*
		* queue the mailbox data for later processing.
		* this allows the firmware to move forward and
		* service the requst from the P port.
		*/
		cy_as_ll_queue_mailbox_data(dev_p);

		/*
		* enable interrupts again to service mailbox
		* interrupts appropriately
		*/
		cy_as_hal_enable_interrupts(mask);
	}

	/*
	* now, all data is received
	*/
	last = cy_as_hal_read_register(dev_p->tag,
		CY_AS_MEM_MCU_MB_STAT) & CY_AS_MEM_P0_MCU_MBNOTRD;
	while (bloop) {
		v = cy_as_hal_read_register(dev_p->tag,
		CY_AS_MEM_MCU_MB_STAT) & CY_AS_MEM_P0_MCU_MBNOTRD;
		if (v == last)
			break;

		last = v;
	}

	return v;
}

/*
* Send a single request or response using the mail box register.
* This function does not deal with the internal queues at all,
* but only sends the request or response across to the firmware
*/
static cy_as_return_status_t
cy_as_send_one(
			cy_as_device *dev_p,
			cy_as_ll_request_response *req_p)
{
	int i;
	uint16_t mb0, v;
	int32_t loopcount;
	uint32_t int_stat;

#ifdef _DEBUG
	if (cy_as_ll_request_response__is_request(req_p)) {
		switch (cy_as_ll_request_response__get_context(req_p)) {
		case CY_RQT_GENERAL_RQT_CONTEXT:
			cy_as_hal_assert(req_p->length * 2 + 2 <
				CY_CTX_GEN_MAX_DATA_SIZE);
			break;

		case CY_RQT_RESOURCE_RQT_CONTEXT:
			cy_as_hal_assert(req_p->length * 2 + 2 <
				CY_CTX_RES_MAX_DATA_SIZE);
			break;

		case CY_RQT_STORAGE_RQT_CONTEXT:
			cy_as_hal_assert(req_p->length * 2 + 2 <
				CY_CTX_STR_MAX_DATA_SIZE);
			break;

		case CY_RQT_USB_RQT_CONTEXT:
			cy_as_hal_assert(req_p->length * 2 + 2 <
				CY_CTX_USB_MAX_DATA_SIZE);
			break;
		}
	}
#endif

	/* Write the request to the mail box registers */
	if (req_p->length > 3) {
		uint16_t length = req_p->length;
		int which = 0;
		int st = 1;

		dev_p->ll_sending_rqt = cy_true;
		while (which < length) {
			loopcount = cy_as_low_level_timeout_count;
			do {
				v = cy_as_read_intr_status(dev_p);

			} while (v && loopcount-- > 0);

			if (v) {
				cy_as_hal_print_message(
					">>>>>> LOW LEVEL TIMEOUT "
					"%x %x %x %x\n",
					cy_as_hal_read_register(dev_p->tag,
						CY_AS_MEM_MCU_MAILBOX0),
					cy_as_hal_read_register(dev_p->tag,
						CY_AS_MEM_MCU_MAILBOX1),
					cy_as_hal_read_register(dev_p->tag,
						CY_AS_MEM_MCU_MAILBOX2),
					cy_as_hal_read_register(dev_p->tag,
						CY_AS_MEM_MCU_MAILBOX3));
				return CY_AS_ERROR_TIMEOUT;
			}

			if (dev_p->ll_abort_curr_rqt) {
				dev_p->ll_sending_rqt = cy_false;
				dev_p->ll_abort_curr_rqt = cy_false;
				return CY_AS_ERROR_CANCELED;
			}

			int_stat = cy_as_hal_disable_interrupts();

			/*
			 * check again whether the mailbox is free.
			 * it is possible that an ISR came in and
			 * wrote into the mailboxes since we last
			 * checked the status.
			 */
			v = cy_as_hal_read_register(dev_p->tag,
				CY_AS_MEM_MCU_MB_STAT) &
				CY_AS_MEM_P0_MCU_MBNOTRD;
			if (v) {
				/* Go back to the original check since
				 * the mailbox is not free. */
				cy_as_hal_enable_interrupts(int_stat);
				continue;
			}

			if (which == 0) {
				cy_as_hal_write_register(dev_p->tag,
					CY_AS_MEM_MCU_MAILBOX1, length);
				st = 2;
			} else {
				st = 1;
			}

			while ((which < length) && (st < 4)) {
				cy_as_hal_write_register(dev_p->tag,
					cy_cast_int2U_int16
						(CY_AS_MEM_MCU_MAILBOX0 + st),
						req_p->data[which++]);
				st++;
			}

			mb0 = req_p->box0;
			if (which == length) {
				dev_p->ll_sending_rqt = cy_false;
				mb0 |= CY_AS_REQUEST_RESPONSE_LAST_MASK;
			}

			if (dev_p->ll_abort_curr_rqt) {
				dev_p->ll_sending_rqt = cy_false;
				dev_p->ll_abort_curr_rqt = cy_false;
				cy_as_hal_enable_interrupts(int_stat);
				return CY_AS_ERROR_CANCELED;
			}

			cy_as_hal_write_register(dev_p->tag,
				CY_AS_MEM_MCU_MAILBOX0, mb0);

			/* Wait for the MBOX interrupt to be high */
			cy_as_hal_sleep150();
			cy_as_hal_enable_interrupts(int_stat);
		}
	} else {
check_mailbox_availability:
		/*
		* wait for the mailbox registers to become available. this
		* should be a very quick wait as the firmware is designed
		* to accept requests at interrupt time and queue them for
		* future processing.
		*/
		loopcount = cy_as_low_level_timeout_count;
		do {
			v = cy_as_read_intr_status(dev_p);

		} while (v && loopcount-- > 0);

		if (v) {
			cy_as_hal_print_message(
				">>>>>> LOW LEVEL TIMEOUT %x %x %x %x\n",
				cy_as_hal_read_register(dev_p->tag,
					CY_AS_MEM_MCU_MAILBOX0),
				cy_as_hal_read_register(dev_p->tag,
					CY_AS_MEM_MCU_MAILBOX1),
				cy_as_hal_read_register(dev_p->tag,
					CY_AS_MEM_MCU_MAILBOX2),
				cy_as_hal_read_register(dev_p->tag,
					CY_AS_MEM_MCU_MAILBOX3));
			return CY_AS_ERROR_TIMEOUT;
		}

		int_stat = cy_as_hal_disable_interrupts();

		/*
		 * check again whether the mailbox is free. it is
		 * possible that an ISR came in and wrote into the
		 * mailboxes since we last checked the status.
		 */
		v = cy_as_hal_read_register(dev_p->tag, CY_AS_MEM_MCU_MB_STAT) &
			CY_AS_MEM_P0_MCU_MBNOTRD;
		if (v) {
			/* Go back to the original check
			 * since the mailbox is not free. */
			cy_as_hal_enable_interrupts(int_stat);
			goto check_mailbox_availability;
		}

		/* Write the data associated with the request
		 * into the mbox registers 1 - 3 */
		v = 0;
		for (i = req_p->length - 1; i >= 0; i--)
			cy_as_hal_write_register(dev_p->tag,
				cy_cast_int2U_int16(CY_AS_MEM_MCU_MAILBOX1 + i),
				req_p->data[i]);

		/* Write the mbox register 0 to trigger the interrupt */
		cy_as_hal_write_register(dev_p->tag, CY_AS_MEM_MCU_MAILBOX0,
			req_p->box0 | CY_AS_REQUEST_RESPONSE_LAST_MASK);

		cy_as_hal_sleep150();
		cy_as_hal_enable_interrupts(int_stat);
	}

	return CY_AS_ERROR_SUCCESS;
}

/*
* This function queues a single request to be sent to the firmware.
*/
extern cy_as_return_status_t
cy_as_ll_send_request(
				  cy_as_device *dev_p,
				  /* The request to send */
				  cy_as_ll_request_response *req,
				  /* Storage for a reply, must be sure
				   * it is of sufficient size */
				  cy_as_ll_request_response *resp,
				  /* If true, this is a synchronous request */
				  cy_bool sync,
				  /* Callback to call when reply is received */
				  cy_as_response_callback cb
)
{
	cy_as_context *ctxt_p;
	uint16_t box0 = req->box0;
	uint8_t context;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	cy_as_ll_request_list_node *node_p;
	uint32_t mask, state;

	cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE);

	context = cy_as_mbox_get_context(box0);
	cy_as_hal_assert(context < CY_RQT_CONTEXT_COUNT);
	ctxt_p = dev_p->context[context];

	/* Allocate the list node */
	state = cy_as_hal_disable_interrupts();
	node_p = cy_as_hal_c_b_alloc(sizeof(cy_as_ll_request_list_node));
	cy_as_hal_enable_interrupts(state);

	if (node_p == 0)
		return CY_AS_ERROR_OUT_OF_MEMORY;

	/* Initialize the list node */
	node_p->callback = cb;
	node_p->length = 0;
	node_p->next = 0;
	node_p->resp = resp;
	node_p->rqt = req;
	node_p->state = CY_AS_REQUEST_LIST_STATE_QUEUED;
	if (sync)
		cy_as_request_node_set_sync(node_p);

	/* Put the request into the queue */
	mask = cy_as_hal_disable_interrupts();
	if (ctxt_p->request_queue_p == 0) {
		/* Empty queue */
		ctxt_p->request_queue_p = node_p;
		ctxt_p->last_node_p = node_p;
	} else {
		ctxt_p->last_node_p->next = node_p;
		ctxt_p->last_node_p = node_p;
	}
	cy_as_hal_enable_interrupts(mask);
	cy_as_ll_send_next_request(dev_p, ctxt_p);

	if (!cy_as_device_is_in_callback(dev_p)) {
		mask = cy_as_hal_disable_interrupts();
		cy_as_mail_box_queued_data_handler(dev_p);
		cy_as_hal_enable_interrupts(mask);
	}

	return ret;
}

static void
cy_as_ll_send_callback(
				   cy_as_device *dev_p,
				   uint8_t context,
				   cy_as_ll_request_response *rqt,
				   cy_as_ll_request_response *resp,
				   cy_as_return_status_t ret)
{
	(void)rqt;
	(void)resp;
	(void)ret;


	cy_as_hal_assert(dev_p->sig == CY_AS_DEVICE_HANDLE_SIGNATURE);

	/*
	* storage the state to return to the caller
	*/
	dev_p->ll_error = ret;

	/*
	* now wake the caller
	*/
	cy_as_hal_wake(&dev_p->context[context]->channel);
}

cy_as_return_status_t
cy_as_ll_send_request_wait_reply(
		cy_as_device *dev_p,
		/* The request to send */
		cy_as_ll_request_response *req,
		/* Storage for a reply, must be
		 * sure it is of sufficient size */
		cy_as_ll_request_response *resp
		)
{
	cy_as_return_status_t ret;
	uint8_t context;
	/* Larger 8 sec time-out to handle the init
	 * delay for slower storage devices in USB FS. */
	uint32_t loopcount = 800;
	cy_as_context *ctxt_p;

	/* Get the context for the request */
	context = cy_as_ll_request_response__get_context(req);
	cy_as_hal_assert(context < CY_RQT_CONTEXT_COUNT);
	ctxt_p = dev_p->context[context];

	ret = cy_as_ll_send_request(dev_p, req, resp,
		cy_true, cy_as_ll_send_callback);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	while (loopcount-- > 0) {
		/*
		* sleep while we wait on the response.  receiving the reply will
		* wake this thread.  we will wait, at most 2 seconds (10 ms*200
		* tries) before we timeout.  note if the reply arrives, we will
		* not sleep the entire 10 ms, just til the reply arrives.
		*/
		cy_as_hal_sleep_on(&ctxt_p->channel, 10);

		/*
		* if the request has left the queue, it means the request has
		* been sent and the reply has been received.  this means we can
		* return to the caller and be sure the reply has been received.
		*/
		if (!cy_as_ll_is_in_queue(ctxt_p, req))
			return dev_p->ll_error;
	}

	/* Remove the QueueListNode for this request. */
	cy_as_ll_remove_request(dev_p, ctxt_p, req, cy_true);

	return CY_AS_ERROR_TIMEOUT;
}

cy_as_return_status_t
cy_as_ll_register_request_callback(
			cy_as_device *dev_p,
			uint8_t context,
			cy_as_response_callback cb)
{
	cy_as_context *ctxt_p;
	cy_as_hal_assert(context < CY_RQT_CONTEXT_COUNT);
	ctxt_p = dev_p->context[context];

	ctxt_p->request_callback = cb;
	return CY_AS_ERROR_SUCCESS;
}

void
cy_as_ll_request_response__pack(
			cy_as_ll_request_response *req_p,
			uint32_t offset,
			uint32_t length,
			void *data_p)
{
	uint16_t dt;
	uint8_t *dp = (uint8_t *)data_p;

	while (length > 1) {
		dt = ((*dp++) << 8);
		dt |= (*dp++);
		cy_as_ll_request_response__set_word(req_p, offset, dt);
		offset++;
		length -= 2;
	}

	if (length == 1) {
		dt = (*dp << 8);
		cy_as_ll_request_response__set_word(req_p, offset, dt);
	}
}

void
cy_as_ll_request_response__unpack(
			cy_as_ll_request_response *req_p,
			uint32_t offset,
			uint32_t length,
			void *data_p)
{
	uint8_t *dp = (uint8_t *)data_p;

	while (length-- > 0) {
		uint16_t val = cy_as_ll_request_response__get_word
			(req_p, offset++);
		*dp++ = (uint8_t)((val >> 8) & 0xff);

		if (length) {
			length--;
			*dp++ = (uint8_t)(val & 0xff);
		}
	}
}

extern cy_as_return_status_t
cy_as_ll_send_status_response(
						 cy_as_device *dev_p,
						 uint8_t context,
						 uint16_t code,
						 uint8_t clear_storage)
{
	cy_as_return_status_t ret;
	cy_as_ll_request_response resp;
	cy_as_ll_request_response *resp_p = &resp;

	cy_as_hal_mem_set(resp_p, 0, sizeof(resp));
	resp_p->length = 1;
	cy_as_ll_request_response__set_response(resp_p);
	cy_as_ll_request_response__set_context(resp_p, context);

	if (clear_storage)
		cy_as_ll_request_response__set_clear_storage_flag(resp_p);

	cy_as_ll_request_response__set_code(resp_p, CY_RESP_SUCCESS_FAILURE);
	cy_as_ll_request_response__set_word(resp_p, 0, code);

	ret = cy_as_send_one(dev_p, resp_p);

	return ret;
}

extern cy_as_return_status_t
cy_as_ll_send_data_response(
					   cy_as_device *dev_p,
					   uint8_t context,
					   uint16_t code,
					   uint16_t length,
					   void *data)
{
	cy_as_ll_request_response *resp_p;
	uint16_t wlen;
	uint8_t respbuf[256];

	if (length > 192)
		return CY_AS_ERROR_INVALID_SIZE;

	/* Word length for bytes */
	wlen = length / 2;

	/* If byte length odd, add one more */
	if (length % 2)
		wlen++;

	/* One for the length of field */
	wlen++;

	resp_p = (cy_as_ll_request_response *)respbuf;
	cy_as_hal_mem_set(resp_p, 0, sizeof(respbuf));
	resp_p->length = wlen;
	cy_as_ll_request_response__set_context(resp_p, context);
	cy_as_ll_request_response__set_code(resp_p, code);

	cy_as_ll_request_response__set_word(resp_p, 0, length);
	cy_as_ll_request_response__pack(resp_p, 1, length, data);

	return cy_as_send_one(dev_p, resp_p);
}

static cy_bool
cy_as_ll_is_e_p_transfer_related_request(cy_as_ll_request_response *rqt_p,
	cy_as_end_point_number_t ep)
{
	uint16_t v;
	uint8_t  type = cy_as_ll_request_response__get_code(rqt_p);

	if (cy_as_ll_request_response__get_context(rqt_p) !=
		CY_RQT_USB_RQT_CONTEXT)
		return cy_false;

	/*
	 * when cancelling outstanding EP0 data transfers, any pending
	 * setup ACK requests also need to be cancelled.
	 */
	if ((ep == 0) && (type == CY_RQT_ACK_SETUP_PACKET))
		return cy_true;

	if (type != CY_RQT_USB_EP_DATA)
		return cy_false;

	v = cy_as_ll_request_response__get_word(rqt_p, 0);
	if ((cy_as_end_point_number_t)((v >> 13) & 1) != ep)
		return cy_false;

	return cy_true;
}

cy_as_return_status_t
cy_as_ll_remove_ep_data_requests(cy_as_device *dev_p,
	cy_as_end_point_number_t ep)
{
	cy_as_context *ctxt_p;
	cy_as_ll_request_list_node *node_p;
	uint32_t imask;

	/*
	* first, remove any queued requests
	*/
	ctxt_p = dev_p->context[CY_RQT_USB_RQT_CONTEXT];
	if (ctxt_p) {
		for (node_p = ctxt_p->request_queue_p; node_p;
			node_p = node_p->next) {
			if (cy_as_ll_is_e_p_transfer_related_request
			(node_p->rqt, ep)) {
				cy_as_ll_remove_request(dev_p, ctxt_p,
					node_p->rqt, cy_false);
				break;
			}
		}

		/*
		* now, deal with any request that may be in transit
		*/
		imask = cy_as_hal_disable_interrupts();

		if (ctxt_p->request_queue_p != 0 &&
			cy_as_ll_is_e_p_transfer_related_request
			(ctxt_p->request_queue_p->rqt, ep) &&
			cy_as_request_get_node_state(ctxt_p->request_queue_p) ==
			CY_AS_REQUEST_LIST_STATE_WAITING) {
			cy_as_hal_print_message("need to remove an in-transit "
				"request to antioch\n");

			/*
			* if the request has not been fully sent to west bridge
			* yet, abort sending. otherwise, terminate the request
			* with a CANCELED status. firmware will already have
			* terminated this transfer.
			*/
			if (dev_p->ll_sending_rqt)
				dev_p->ll_abort_curr_rqt = cy_true;
			else {
				uint32_t state;

				node_p = ctxt_p->request_queue_p;
				if (node_p->callback)
					node_p->callback(dev_p, ctxt_p->number,
						node_p->rqt, node_p->resp,
						CY_AS_ERROR_CANCELED);

				ctxt_p->request_queue_p = node_p->next;
				state = cy_as_hal_disable_interrupts();
				cy_as_hal_c_b_free(node_p);
				cy_as_hal_enable_interrupts(state);
			}
		}

		cy_as_hal_enable_interrupts(imask);
	}

	return CY_AS_ERROR_SUCCESS;
}
