/* Cypress West Bridge API source file (cyasstorage.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.
## ===========================
*/

/*
* Storage Design
*
* The storage module is fairly straight forward once the
* DMA and LOWLEVEL modules have been designed.  The
* storage module simple takes requests from the user, queues
* the associated DMA requests for action, and then sends
* the low level requests to the West Bridge firmware.
*
*/

#include "../../include/linux/westbridge/cyashal.h"
#include "../../include/linux/westbridge/cyasstorage.h"
#include "../../include/linux/westbridge/cyaserr.h"
#include "../../include/linux/westbridge/cyasdevice.h"
#include "../../include/linux/westbridge/cyaslowlevel.h"
#include "../../include/linux/westbridge/cyasdma.h"
#include "../../include/linux/westbridge/cyasregs.h"

/* Map a pre-V1.2 media type to the V1.2+ bus number */
cy_as_return_status_t
cy_an_map_bus_from_media_type(cy_as_device *dev_p,
	cy_as_media_type type, cy_as_bus_number_t *bus)
{
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	uint8_t code = (uint8_t)(1 << type);
	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	if (!cy_as_device_is_configured(dev_p))
		return CY_AS_ERROR_NOT_CONFIGURED;

	if (!cy_as_device_is_firmware_loaded(dev_p))
		return CY_AS_ERROR_NO_FIRMWARE;


	if (dev_p->media_supported[0] & code) {
		if (dev_p->media_supported[1] & code) {
			/*
			 * this media type could be supported on multiple
			 * buses. so, report an address resolution error.
			 */
			ret = CY_AS_ERROR_ADDRESS_RESOLUTION_ERROR;
		} else
			*bus = 0;
	} else {
		if (dev_p->media_supported[1] & code)
			*bus = 1;
		else
			ret = CY_AS_ERROR_NO_SUCH_MEDIA;
	}

	return ret;
}

static uint16_t
create_address(cy_as_bus_number_t bus, uint32_t device, uint8_t unit)
{
	cy_as_hal_assert(bus >= 0  && bus < CY_AS_MAX_BUSES);
	cy_as_hal_assert(device < 16);

	return (uint16_t)(((uint8_t)bus << 12) | (device << 8) | unit);
}

cy_as_media_type
cy_as_storage_get_media_from_address(uint16_t v)
{
	cy_as_media_type media = cy_as_media_max_media_value;

	switch (v & 0xFF) {
	case 0x00:
		break;
	case 0x01:
		media = cy_as_media_nand;
		break;
	case 0x02:
		media = cy_as_media_sd_flash;
		break;
	case 0x04:
		media = cy_as_media_mmc_flash;
		break;
	case 0x08:
		media = cy_as_media_ce_ata;
		break;
	case 0x10:
		media = cy_as_media_sdio;
		break;
	default:
		cy_as_hal_assert(0);
			break;
	}

	return media;
}

cy_as_bus_number_t
cy_as_storage_get_bus_from_address(uint16_t v)
{
	cy_as_bus_number_t bus = (cy_as_bus_number_t)((v >> 12) & 0x0f);
	cy_as_hal_assert(bus >= 0 && bus < CY_AS_MAX_BUSES);
	return bus;
}

uint32_t
cy_as_storage_get_device_from_address(uint16_t v)
{
	return (uint32_t)((v >> 8) & 0x0f);
}

static uint8_t
get_unit_from_address(uint16_t v)
{
	return (uint8_t)(v & 0xff);
}

static cy_as_return_status_t
cy_as_map_bad_addr(uint16_t val)
{
	cy_as_return_status_t ret = CY_AS_ERROR_INVALID_RESPONSE;

	switch (val) {
	case 0:
		ret = CY_AS_ERROR_NO_SUCH_BUS;
		break;
	case 1:
		ret = CY_AS_ERROR_NO_SUCH_DEVICE;
		break;
	case 2:
		ret = CY_AS_ERROR_NO_SUCH_UNIT;
		break;
	case 3:
		ret = CY_AS_ERROR_INVALID_BLOCK;
		break;
	}

	return ret;
}

static void
my_storage_request_callback(cy_as_device *dev_p,
		uint8_t context,
		cy_as_ll_request_response *req_p,
		cy_as_ll_request_response *resp_p,
		cy_as_return_status_t ret)
{
	uint16_t val;
	uint16_t addr;
	cy_as_bus_number_t bus;
	uint32_t device;
	cy_as_device_handle h = (cy_as_device_handle)dev_p;
	cy_as_dma_end_point *ep_p = NULL;

	(void)resp_p;
	(void)context;
	(void)ret;

	switch (cy_as_ll_request_response__get_code(req_p)) {
	case CY_RQT_MEDIA_CHANGED:
		cy_as_ll_send_status_response(dev_p,
			CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0);

		/* Media has either been inserted or removed */
		addr = cy_as_ll_request_response__get_word(req_p, 0);

		bus = cy_as_storage_get_bus_from_address(addr);
		device = cy_as_storage_get_device_from_address(addr);

		/* Clear the entry for this device to force re-query later */
		cy_as_hal_mem_set(&(dev_p->storage_device_info[bus][device]), 0,
			sizeof(dev_p->storage_device_info[bus][device]));

		val = cy_as_ll_request_response__get_word(req_p, 1);
		if (dev_p->storage_event_cb_ms) {
			if (val == 1)
				dev_p->storage_event_cb_ms(h, bus,
					device, cy_as_storage_removed, 0);
			else
				dev_p->storage_event_cb_ms(h, bus,
					device, cy_as_storage_inserted, 0);
		} else if (dev_p->storage_event_cb) {
			if (val == 1)
				dev_p->storage_event_cb(h, bus,
					cy_as_storage_removed, 0);
			else
				dev_p->storage_event_cb(h, bus,
					cy_as_storage_inserted, 0);
		}

		break;

	case CY_RQT_ANTIOCH_CLAIM:
		cy_as_ll_send_status_response(dev_p,
			CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0);
		if (dev_p->storage_event_cb || dev_p->storage_event_cb_ms) {
			val = cy_as_ll_request_response__get_word(req_p, 0);
			if (dev_p->storage_event_cb_ms) {
				if (val & 0x0100)
					dev_p->storage_event_cb_ms(h, 0, 0,
						cy_as_storage_antioch, 0);
				if (val & 0x0200)
					dev_p->storage_event_cb_ms(h, 1, 0,
						cy_as_storage_antioch, 0);
			} else {
				if (val & 0x01)
					dev_p->storage_event_cb(h,
						cy_as_media_nand,
						cy_as_storage_antioch, 0);
				if (val & 0x02)
					dev_p->storage_event_cb(h,
						cy_as_media_sd_flash,
						cy_as_storage_antioch, 0);
				if (val & 0x04)
					dev_p->storage_event_cb(h,
						cy_as_media_mmc_flash,
						cy_as_storage_antioch, 0);
				if (val & 0x08)
					dev_p->storage_event_cb(h,
						cy_as_media_ce_ata,
						cy_as_storage_antioch, 0);
			}
		}
		break;

	case CY_RQT_ANTIOCH_RELEASE:
		cy_as_ll_send_status_response(dev_p,
			CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0);
		val = cy_as_ll_request_response__get_word(req_p, 0);
		if (dev_p->storage_event_cb_ms) {
			if (val & 0x0100)
				dev_p->storage_event_cb_ms(h, 0, 0,
					cy_as_storage_processor, 0);
			if (val & 0x0200)
				dev_p->storage_event_cb_ms(h, 1, 0,
					cy_as_storage_processor, 0);
		} else if (dev_p->storage_event_cb) {
			if (val & 0x01)
				dev_p->storage_event_cb(h,
					cy_as_media_nand,
					cy_as_storage_processor, 0);
			if (val & 0x02)
				dev_p->storage_event_cb(h,
					cy_as_media_sd_flash,
					cy_as_storage_processor, 0);
			if (val & 0x04)
				dev_p->storage_event_cb(h,
					cy_as_media_mmc_flash,
					cy_as_storage_processor, 0);
			if (val & 0x08)
				dev_p->storage_event_cb(h,
					cy_as_media_ce_ata,
					cy_as_storage_processor, 0);
		}
		break;


	case CY_RQT_SDIO_INTR:
		cy_as_ll_send_status_response(dev_p,
			CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0);
		val = cy_as_ll_request_response__get_word(req_p, 0);
		if (dev_p->storage_event_cb_ms) {
			if (val & 0x0100)
				dev_p->storage_event_cb_ms(h, 1, 0,
					cy_as_sdio_interrupt, 0);
			else
				dev_p->storage_event_cb_ms(h, 0, 0,
					cy_as_sdio_interrupt, 0);

		} else if (dev_p->storage_event_cb) {
			dev_p->storage_event_cb(h,
				cy_as_media_sdio, cy_as_sdio_interrupt, 0);
		}
		break;

	case CY_RQT_P2S_DMA_START:
		/* Do the DMA setup for the waiting operation. */
		cy_as_ll_send_status_response(dev_p,
			CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0);
		cy_as_device_set_p2s_dma_start_recvd(dev_p);
		if (dev_p->storage_oper == cy_as_op_read) {
			ep_p = CY_AS_NUM_EP(dev_p, CY_AS_P2S_READ_ENDPOINT);
			cy_as_dma_end_point_set_stopped(ep_p);
			cy_as_dma_kick_start(dev_p, CY_AS_P2S_READ_ENDPOINT);
		} else {
			ep_p = CY_AS_NUM_EP(dev_p, CY_AS_P2S_WRITE_ENDPOINT);
			cy_as_dma_end_point_set_stopped(ep_p);
			cy_as_dma_kick_start(dev_p, CY_AS_P2S_WRITE_ENDPOINT);
		}
		break;

	default:
		cy_as_hal_print_message("invalid request received "
			"on storage context\n");
		val = req_p->box0;
		cy_as_ll_send_data_response(dev_p, CY_RQT_STORAGE_RQT_CONTEXT,
			CY_RESP_INVALID_REQUEST, sizeof(val), &val);
		break;
	}
}

static cy_as_return_status_t
is_storage_active(cy_as_device *dev_p)
{
	if (!cy_as_device_is_configured(dev_p))
		return CY_AS_ERROR_NOT_CONFIGURED;

	if (!cy_as_device_is_firmware_loaded(dev_p))
		return CY_AS_ERROR_NO_FIRMWARE;

	if (dev_p->storage_count == 0)
		return CY_AS_ERROR_NOT_RUNNING;

	if (cy_as_device_is_in_suspend_mode(dev_p))
		return CY_AS_ERROR_IN_SUSPEND;

	return CY_AS_ERROR_SUCCESS;
}

static void
cy_as_storage_func_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);

static cy_as_return_status_t
my_handle_response_no_data(cy_as_device *dev_p,
				cy_as_ll_request_response *req_p,
				cy_as_ll_request_response *reply_p)
{
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;

	if (cy_as_ll_request_response__get_code(reply_p) !=
		CY_RESP_SUCCESS_FAILURE) {
		ret = CY_AS_ERROR_INVALID_RESPONSE;
		goto destroy;
	}

	ret = cy_as_ll_request_response__get_word(reply_p, 0);

destroy:
	cy_as_ll_destroy_request(dev_p, req_p);
	cy_as_ll_destroy_response(dev_p, reply_p);

	return ret;
}

static cy_as_return_status_t
my_handle_response_storage_start(cy_as_device *dev_p,
			cy_as_ll_request_response *req_p,
			cy_as_ll_request_response *reply_p,
			cy_as_return_status_t ret)
{
	if (ret != CY_AS_ERROR_SUCCESS)
		goto destroy;

	if (cy_as_ll_request_response__get_code(reply_p) !=
		CY_RESP_SUCCESS_FAILURE) {
		ret = CY_AS_ERROR_INVALID_RESPONSE;
		goto destroy;
	}

	ret = cy_as_ll_request_response__get_word(reply_p, 0);
	if (dev_p->storage_count > 0 && ret ==
	CY_AS_ERROR_ALREADY_RUNNING)
		ret = CY_AS_ERROR_SUCCESS;

	ret = cy_as_dma_enable_end_point(dev_p,
		CY_AS_P2S_WRITE_ENDPOINT, cy_true, cy_as_direction_in);
	if (ret != CY_AS_ERROR_SUCCESS)
		goto destroy;

	ret = cy_as_dma_set_max_dma_size(dev_p,
		CY_AS_P2S_WRITE_ENDPOINT, CY_AS_STORAGE_EP_SIZE);
	if (ret != CY_AS_ERROR_SUCCESS)
		goto destroy;

	ret = cy_as_dma_enable_end_point(dev_p,
		CY_AS_P2S_READ_ENDPOINT, cy_true, cy_as_direction_out);
	if (ret != CY_AS_ERROR_SUCCESS)
		goto destroy;

	ret = cy_as_dma_set_max_dma_size(dev_p,
		CY_AS_P2S_READ_ENDPOINT, CY_AS_STORAGE_EP_SIZE);
	if (ret != CY_AS_ERROR_SUCCESS)
		goto destroy;

	cy_as_ll_register_request_callback(dev_p,
		CY_RQT_STORAGE_RQT_CONTEXT, my_storage_request_callback);

	/* Create the request/response used for storage reads and writes. */
	dev_p->storage_rw_req_p  = cy_as_ll_create_request(dev_p,
		0, CY_RQT_STORAGE_RQT_CONTEXT, 5);
	if (dev_p->storage_rw_req_p == 0) {
		ret = CY_AS_ERROR_OUT_OF_MEMORY;
		goto destroy;
	}

	dev_p->storage_rw_resp_p = cy_as_ll_create_response(dev_p, 5);
	if (dev_p->storage_rw_resp_p == 0) {
		cy_as_ll_destroy_request(dev_p, dev_p->storage_rw_req_p);
		ret = CY_AS_ERROR_OUT_OF_MEMORY;
	}

destroy:
	cy_as_ll_destroy_request(dev_p, req_p);
	cy_as_ll_destroy_response(dev_p, reply_p);

	/* Increment the storage count only if
	 * the above functionality succeeds.*/
	if (ret == CY_AS_ERROR_SUCCESS) {
		if (dev_p->storage_count == 0) {
			cy_as_hal_mem_set(dev_p->storage_device_info,
				0, sizeof(dev_p->storage_device_info));
			dev_p->is_storage_only_mode = cy_false;
		}

		dev_p->storage_count++;
	}

	cy_as_device_clear_s_s_s_pending(dev_p);

	return ret;
}

cy_as_return_status_t
cy_as_storage_start(cy_as_device_handle handle,
				   cy_as_function_callback cb,
				   uint32_t client)
{
	cy_as_ll_request_response *req_p, *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	cy_as_device *dev_p = (cy_as_device *)handle;

	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	if (!cy_as_device_is_configured(dev_p))
		return CY_AS_ERROR_NOT_CONFIGURED;

	if (!cy_as_device_is_firmware_loaded(dev_p))
		return CY_AS_ERROR_NO_FIRMWARE;

	if (cy_as_device_is_in_suspend_mode(dev_p))
		return CY_AS_ERROR_IN_SUSPEND;

	if (cy_as_device_is_s_s_s_pending(dev_p))
		return CY_AS_ERROR_STARTSTOP_PENDING;

	cy_as_device_set_s_s_s_pending(dev_p);

	if (dev_p->storage_count == 0) {
		/* Create the request to send to the West Bridge device */
		req_p = cy_as_ll_create_request(dev_p,
			CY_RQT_START_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 1);
		if (req_p == 0) {
			cy_as_device_clear_s_s_s_pending(dev_p);
			return CY_AS_ERROR_OUT_OF_MEMORY;
		}

		/* Reserve space for the reply, the reply data
		 * will not exceed one word */
		reply_p = cy_as_ll_create_response(dev_p, 1);
		if (reply_p == 0) {
			cy_as_device_clear_s_s_s_pending(dev_p);
			cy_as_ll_destroy_request(dev_p, req_p);
			return CY_AS_ERROR_OUT_OF_MEMORY;
		}

		if (cb == 0) {
			ret = cy_as_ll_send_request_wait_reply(dev_p,
				req_p, reply_p);
			if (ret != CY_AS_ERROR_SUCCESS)
				goto destroy;

			return my_handle_response_storage_start(dev_p,
				req_p, reply_p, ret);
		} else {
			ret = cy_as_misc_send_request(dev_p, cb, client,
				CY_FUNCT_CB_STOR_START, 0, dev_p->func_cbs_stor,
				CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
				cy_as_storage_func_callback);

			if (ret != CY_AS_ERROR_SUCCESS)
				goto destroy;

			/* The request and response are freed as
			 * part of the FuncCallback */
			return ret;
		}

destroy:
		cy_as_ll_destroy_request(dev_p, req_p);
		cy_as_ll_destroy_response(dev_p, reply_p);
	} else {
		dev_p->storage_count++;
		if (cb)
			cb(handle, ret, client, CY_FUNCT_CB_STOR_START, 0);
	}

	cy_as_device_clear_s_s_s_pending(dev_p);

	return ret;
}


static cy_as_return_status_t
my_handle_response_storage_stop(cy_as_device *dev_p,
				cy_as_ll_request_response *req_p,
				cy_as_ll_request_response *reply_p,
				cy_as_return_status_t ret)
{
	if (ret != CY_AS_ERROR_SUCCESS)
		goto destroy;

	if (cy_as_ll_request_response__get_code(reply_p) !=
		CY_RESP_SUCCESS_FAILURE) {
		ret = CY_AS_ERROR_INVALID_RESPONSE;
		goto destroy;
	}

destroy:
	cy_as_ll_destroy_request(dev_p, req_p);
	cy_as_ll_destroy_response(dev_p, reply_p);

	if (ret == CY_AS_ERROR_SUCCESS) {
		cy_as_ll_destroy_request(dev_p, dev_p->storage_rw_req_p);
		cy_as_ll_destroy_response(dev_p, dev_p->storage_rw_resp_p);
		dev_p->storage_count--;
	}

	cy_as_device_clear_s_s_s_pending(dev_p);

	return ret;
}
cy_as_return_status_t
cy_as_storage_stop(cy_as_device_handle handle,
				  cy_as_function_callback cb,
				  uint32_t client)
{
	cy_as_ll_request_response *req_p , *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;

	cy_as_device *dev_p = (cy_as_device *)handle;

	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	ret = is_storage_active(dev_p);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	if (cy_as_device_is_storage_async_pending(dev_p))
		return CY_AS_ERROR_ASYNC_PENDING;

	if (cy_as_device_is_s_s_s_pending(dev_p))
		return CY_AS_ERROR_STARTSTOP_PENDING;

	cy_as_device_set_s_s_s_pending(dev_p);

	if (dev_p->storage_count == 1) {

		/* Create the request to send to the West Bridge device */
		req_p = cy_as_ll_create_request(dev_p,
			CY_RQT_STOP_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 0);
		if (req_p == 0) {
			cy_as_device_clear_s_s_s_pending(dev_p);
			return CY_AS_ERROR_OUT_OF_MEMORY;
		}

		/* Reserve space for the reply, the reply data
		 * will not exceed one word */
		reply_p = cy_as_ll_create_response(dev_p, 1);
		if (reply_p == 0) {
			cy_as_device_clear_s_s_s_pending(dev_p);
			cy_as_ll_destroy_request(dev_p, req_p);
			return CY_AS_ERROR_OUT_OF_MEMORY;
		}

		if (cb == 0) {
			ret = cy_as_ll_send_request_wait_reply(dev_p,
				req_p, reply_p);
			if (ret != CY_AS_ERROR_SUCCESS)
				goto destroy;

			return my_handle_response_storage_stop(dev_p,
				req_p, reply_p, ret);
		} else {
			ret = cy_as_misc_send_request(dev_p, cb, client,
				CY_FUNCT_CB_STOR_STOP, 0, dev_p->func_cbs_stor,
				CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
				cy_as_storage_func_callback);

			if (ret != CY_AS_ERROR_SUCCESS)
				goto destroy;

			/* The request and response are freed
			 * as part of the MiscFuncCallback */
			return ret;
		}

destroy:
		cy_as_ll_destroy_request(dev_p, req_p);
		cy_as_ll_destroy_response(dev_p, reply_p);
	} else if (dev_p->storage_count > 1) {
		dev_p->storage_count--;
		if (cb)
			cb(handle, ret, client, CY_FUNCT_CB_STOR_STOP, 0);
	}

	cy_as_device_clear_s_s_s_pending(dev_p);

	return ret;
}

cy_as_return_status_t
cy_as_storage_register_callback(cy_as_device_handle handle,
	cy_as_storage_event_callback callback)
{
	cy_as_device *dev_p = (cy_as_device *)handle;
	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	if (!cy_as_device_is_configured(dev_p))
		return CY_AS_ERROR_NOT_CONFIGURED;

	if (!cy_as_device_is_firmware_loaded(dev_p))
		return CY_AS_ERROR_NO_FIRMWARE;

	if (dev_p->storage_count == 0)
		return CY_AS_ERROR_NOT_RUNNING;

	dev_p->storage_event_cb = NULL;
	dev_p->storage_event_cb_ms = callback;

	return CY_AS_ERROR_SUCCESS;
}



static cy_as_return_status_t
my_handle_response_storage_claim(cy_as_device *dev_p,
			cy_as_ll_request_response *req_p,
			cy_as_ll_request_response *reply_p)
{
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;

	if (cy_as_ll_request_response__get_code(reply_p) ==
		CY_RESP_NO_SUCH_ADDRESS) {
		ret = cy_as_map_bad_addr(
			cy_as_ll_request_response__get_word(reply_p, 3));
		goto destroy;
	}

	if (cy_as_ll_request_response__get_code(reply_p) !=
		CY_RESP_MEDIA_CLAIMED_RELEASED) {
		ret = CY_AS_ERROR_INVALID_RESPONSE;
		goto destroy;
	}

	/* The response must be about the address I am
	 * trying to claim or the firmware is broken */
	if ((cy_as_storage_get_bus_from_address(
			cy_as_ll_request_response__get_word(req_p, 0)) !=
		cy_as_storage_get_bus_from_address(
			cy_as_ll_request_response__get_word(reply_p, 0))) ||
		(cy_as_storage_get_device_from_address(
			cy_as_ll_request_response__get_word(req_p, 0)) !=
		cy_as_storage_get_device_from_address(
			cy_as_ll_request_response__get_word(reply_p, 0)))) {
		ret = CY_AS_ERROR_INVALID_RESPONSE;
		goto destroy;
	}

	if (cy_as_ll_request_response__get_word(reply_p, 1) != 1)
		ret = CY_AS_ERROR_NOT_ACQUIRED;

destroy:
	cy_as_ll_destroy_request(dev_p, req_p);
	cy_as_ll_destroy_response(dev_p, reply_p);

	return ret;
}

static cy_as_return_status_t
my_storage_claim(cy_as_device *dev_p,
				void *data,
				cy_as_bus_number_t bus,
				uint32_t device,
				uint16_t req_flags,
				cy_as_function_callback cb,
				uint32_t client)
{
	cy_as_ll_request_response *req_p , *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;

	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	ret = is_storage_active(dev_p);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	if (dev_p->mtp_count > 0)
		return CY_AS_ERROR_NOT_VALID_IN_MTP;

	/* Create the request to send to the West Bridge device */
	req_p = cy_as_ll_create_request(dev_p,
		CY_RQT_CLAIM_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 1);
	if (req_p == 0)
		return CY_AS_ERROR_OUT_OF_MEMORY;

	cy_as_ll_request_response__set_word(req_p,
		0, create_address(bus, device, 0));

	/* Reserve space for the reply, the reply data will
	 * not exceed one word */
	reply_p = cy_as_ll_create_response(dev_p, 4);
	if (reply_p == 0) {
		cy_as_ll_destroy_request(dev_p, req_p);
		return CY_AS_ERROR_OUT_OF_MEMORY;
	}

	if (cb == 0) {
		ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		return my_handle_response_storage_claim(dev_p, req_p, reply_p);
	} else {
		ret = cy_as_misc_send_request(dev_p, cb, client,
			CY_FUNCT_CB_STOR_CLAIM, data, dev_p->func_cbs_stor,
			req_flags, req_p, reply_p,
			cy_as_storage_func_callback);

		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		/* The request and response are freed as part of
		 * the MiscFuncCallback */
		return ret;
	}

destroy:
	cy_as_ll_destroy_request(dev_p, req_p);
	cy_as_ll_destroy_response(dev_p, reply_p);

	return ret;
}

cy_as_return_status_t
cy_as_storage_claim(cy_as_device_handle handle,
				   cy_as_bus_number_t bus,
				   uint32_t device,
				   cy_as_function_callback cb,
				   uint32_t client)
{
	cy_as_device *dev_p = (cy_as_device *)handle;

	if (bus < 0 || bus >= CY_AS_MAX_BUSES)
		return CY_AS_ERROR_NO_SUCH_BUS;

	return my_storage_claim(dev_p, NULL, bus, device,
		CY_AS_REQUEST_RESPONSE_MS, cb, client);
}

static cy_as_return_status_t
my_handle_response_storage_release(cy_as_device *dev_p,
				cy_as_ll_request_response *req_p,
				cy_as_ll_request_response *reply_p)
{
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;

	if (cy_as_ll_request_response__get_code(reply_p) ==
		CY_RESP_NO_SUCH_ADDRESS) {
		ret = cy_as_map_bad_addr(
			cy_as_ll_request_response__get_word(reply_p, 3));
		goto destroy;
	}

	if (cy_as_ll_request_response__get_code(reply_p) !=
		CY_RESP_MEDIA_CLAIMED_RELEASED) {
		ret = CY_AS_ERROR_INVALID_RESPONSE;
		goto destroy;
	}

	/* The response must be about the address I am
	 * trying to release or the firmware is broken */
	if ((cy_as_storage_get_bus_from_address(
			cy_as_ll_request_response__get_word(req_p, 0)) !=
		cy_as_storage_get_bus_from_address(
			cy_as_ll_request_response__get_word(reply_p, 0))) ||
		(cy_as_storage_get_device_from_address(
			cy_as_ll_request_response__get_word(req_p, 0)) !=
		cy_as_storage_get_device_from_address(
			cy_as_ll_request_response__get_word(reply_p, 0)))) {
		ret = CY_AS_ERROR_INVALID_RESPONSE;
		goto destroy;
	}


	if (cy_as_ll_request_response__get_word(reply_p, 1) != 0)
		ret = CY_AS_ERROR_NOT_RELEASED;

destroy:
	cy_as_ll_destroy_request(dev_p, req_p);
	cy_as_ll_destroy_response(dev_p, reply_p);

	return ret;
}

static cy_as_return_status_t
my_storage_release(cy_as_device *dev_p,
					void *data,
					cy_as_bus_number_t bus,
					uint32_t device,
					uint16_t req_flags,
					cy_as_function_callback cb,
					uint32_t client)
{
	cy_as_ll_request_response *req_p , *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;

	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	ret = is_storage_active(dev_p);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	if (dev_p->mtp_count > 0)
		return CY_AS_ERROR_NOT_VALID_IN_MTP;

	/* Create the request to send to the West Bridge device */
	req_p = cy_as_ll_create_request(dev_p, CY_RQT_RELEASE_STORAGE,
		CY_RQT_STORAGE_RQT_CONTEXT, 1);
	if (req_p == 0)
		return CY_AS_ERROR_OUT_OF_MEMORY;

	cy_as_ll_request_response__set_word(
		req_p, 0, create_address(bus, device, 0));

	/* Reserve space for the reply, the reply
	 * data will not exceed one word */
	reply_p = cy_as_ll_create_response(dev_p, 4);
	if (reply_p == 0) {
		cy_as_ll_destroy_request(dev_p, req_p);
		return CY_AS_ERROR_OUT_OF_MEMORY;
	}

	if (cb == 0) {
		ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		return my_handle_response_storage_release(
			dev_p, req_p, reply_p);
	} else {
		ret = cy_as_misc_send_request(dev_p, cb, client,
			CY_FUNCT_CB_STOR_RELEASE, data, dev_p->func_cbs_stor,
			req_flags, req_p, reply_p,
			cy_as_storage_func_callback);

		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		/* The request and response are freed as
		 * part of the MiscFuncCallback */
		return ret;
	}

destroy:
	cy_as_ll_destroy_request(dev_p, req_p);
	cy_as_ll_destroy_response(dev_p, reply_p);

	return ret;
}

cy_as_return_status_t
cy_as_storage_release(cy_as_device_handle handle,
				   cy_as_bus_number_t bus,
				   uint32_t device,
				   cy_as_function_callback cb,
				   uint32_t client)
{
	cy_as_device *dev_p = (cy_as_device *)handle;

	if (bus < 0 || bus >= CY_AS_MAX_BUSES)
		return CY_AS_ERROR_NO_SUCH_BUS;

	return my_storage_release(dev_p, NULL, bus, device,
		CY_AS_REQUEST_RESPONSE_MS, cb, client);
}

static cy_as_return_status_t
my_handle_response_storage_query_bus(cy_as_device *dev_p,
				cy_as_ll_request_response *req_p,
				cy_as_ll_request_response *reply_p,
				uint32_t *count)
{
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	uint8_t code = cy_as_ll_request_response__get_code(reply_p);
	uint16_t v;

	if (code == CY_RESP_NO_SUCH_ADDRESS) {
		ret = CY_AS_ERROR_NO_SUCH_BUS;
		goto destroy;
	}

	if (code != CY_RESP_BUS_DESCRIPTOR) {
		ret = CY_AS_ERROR_INVALID_RESPONSE;
		goto destroy;
	}

	/*
	 * verify that the response corresponds to the bus that was queried.
	 */
	if (cy_as_storage_get_bus_from_address(
		cy_as_ll_request_response__get_word(req_p, 0)) !=
		cy_as_storage_get_bus_from_address(
		cy_as_ll_request_response__get_word(reply_p, 0))) {
		ret = CY_AS_ERROR_INVALID_RESPONSE;
		goto destroy;
	}

	v = cy_as_ll_request_response__get_word(reply_p, 1);
	if (req_p->flags & CY_AS_REQUEST_RESPONSE_MS) {
		/*
		 * this request is only for the count of devices
		 * on the bus. there is no need to check the media type.
		 */
		if (v)
			*count = 1;
		else
			*count = 0;
	} else {
		/*
		 * this request is for the count of devices of a
		 * particular type. we need to check whether the media
		 * type found matches the queried type.
		 */
		cy_as_media_type queried = (cy_as_media_type)
			cy_as_ll_request_response__get_word(req_p, 1);
		cy_as_media_type found =
			cy_as_storage_get_media_from_address(v);

		if (queried == found)
			*count = 1;
		else
			*count = 0;
	}

destroy:
	cy_as_ll_destroy_request(dev_p, req_p);
	cy_as_ll_destroy_response(dev_p, reply_p);

	return ret;
}

cy_as_return_status_t
my_storage_query_bus(cy_as_device *dev_p,
						cy_as_bus_number_t bus,
						cy_as_media_type   type,
						uint16_t req_flags,
						uint32_t *count,
						cy_as_function_callback cb,
						uint32_t client)
{
	cy_as_return_status_t ret;
	cy_as_ll_request_response *req_p, *reply_p;
	cy_as_funct_c_b_type cb_type = CY_FUNCT_CB_STOR_QUERYBUS;

	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	ret = is_storage_active(dev_p);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	/* Create the request to send to the Antioch device */
	req_p = cy_as_ll_create_request(dev_p,
		CY_RQT_QUERY_BUS, CY_RQT_STORAGE_RQT_CONTEXT, 2);
	if (req_p == 0)
		return CY_AS_ERROR_OUT_OF_MEMORY;

	cy_as_ll_request_response__set_word(req_p,
		0, create_address(bus, 0, 0));
	cy_as_ll_request_response__set_word(req_p, 1, (uint16_t)type);

	/* Reserve space for the reply, the reply data
	 * will not exceed two words. */
	reply_p = cy_as_ll_create_response(dev_p, 2);
	if (reply_p == 0) {
		cy_as_ll_destroy_request(dev_p, req_p);
		return CY_AS_ERROR_OUT_OF_MEMORY;
	}

	if (cb == 0) {
		ret = cy_as_ll_send_request_wait_reply(dev_p,
			req_p, reply_p);
		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		req_p->flags |= req_flags;
		return my_handle_response_storage_query_bus(dev_p,
			req_p, reply_p, count);
	} else {
		if (req_flags == CY_AS_REQUEST_RESPONSE_EX)
			cb_type = CY_FUNCT_CB_STOR_QUERYMEDIA;

		ret = cy_as_misc_send_request(dev_p, cb, client, cb_type,
			count, dev_p->func_cbs_stor, req_flags,
			req_p, reply_p, cy_as_storage_func_callback);

		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		/* The request and response are freed as part of
		 * the MiscFuncCallback */
		return ret;
	}

destroy:
	cy_as_ll_destroy_request(dev_p, req_p);
	cy_as_ll_destroy_response(dev_p, reply_p);

	return ret;
}

cy_as_return_status_t
cy_as_storage_query_bus(cy_as_device_handle handle,
						cy_as_bus_number_t bus,
						uint32_t *count,
						cy_as_function_callback cb,
						uint32_t client)
{
	cy_as_device *dev_p = (cy_as_device *)handle;

	return my_storage_query_bus(dev_p, bus, cy_as_media_max_media_value,
		CY_AS_REQUEST_RESPONSE_MS, count, cb, client);
}

cy_as_return_status_t
cy_as_storage_query_media(cy_as_device_handle handle,
						cy_as_media_type type,
						uint32_t *count,
						cy_as_function_callback cb,
						uint32_t client)
{
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	cy_as_bus_number_t bus;

	cy_as_device *dev_p = (cy_as_device *)handle;

	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	ret = is_storage_active(dev_p);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	ret = cy_an_map_bus_from_media_type(dev_p, type, &bus);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	return my_storage_query_bus(dev_p, bus, type, CY_AS_REQUEST_RESPONSE_EX,
			count, cb, client);
}

static cy_as_return_status_t
my_handle_response_storage_query_device(cy_as_device *dev_p,
				cy_as_ll_request_response *req_p,
				cy_as_ll_request_response *reply_p,
				void *data_p)
{
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	uint16_t v;
	cy_as_bus_number_t bus;
	cy_as_media_type type;
	uint32_t device;
	cy_bool removable;
	cy_bool writeable;
	cy_bool locked;
	uint16_t block_size;
	uint32_t number_units;
	uint32_t number_eus;

	if (cy_as_ll_request_response__get_code(reply_p)
		== CY_RESP_NO_SUCH_ADDRESS) {
		ret = cy_as_map_bad_addr(
			cy_as_ll_request_response__get_word(reply_p, 3));
		goto destroy;
	}

	if (cy_as_ll_request_response__get_code(reply_p) !=
	CY_RESP_DEVICE_DESCRIPTOR) {
		ret = CY_AS_ERROR_INVALID_RESPONSE;
		goto destroy;
	}

	/* Unpack the response */
	v = cy_as_ll_request_response__get_word(reply_p, 0);
	type = cy_as_storage_get_media_from_address(v);
	bus  = cy_as_storage_get_bus_from_address(v);
	device = cy_as_storage_get_device_from_address(v);

	block_size = cy_as_ll_request_response__get_word(reply_p, 1);

	v = cy_as_ll_request_response__get_word(reply_p, 2);
	removable = (v & 0x8000) ? cy_true : cy_false;
	writeable = (v & 0x0100) ? cy_true : cy_false;
	locked = (v & 0x0200) ? cy_true : cy_false;
	number_units = (v & 0xff);

	number_eus  = (cy_as_ll_request_response__get_word(reply_p, 3) << 16)
		| cy_as_ll_request_response__get_word(reply_p, 4);

	/* Store the results based on the version of originating function */
	if (req_p->flags & CY_AS_REQUEST_RESPONSE_MS) {
		cy_as_storage_query_device_data  *store_p =
			(cy_as_storage_query_device_data *)data_p;

		/* Make sure the response is about the address we asked
		 * about - if not, firmware error */
		if ((bus != store_p->bus) || (device != store_p->device)) {
			ret = CY_AS_ERROR_INVALID_RESPONSE;
			goto destroy;
		}

		store_p->desc_p.type = type;
		store_p->desc_p.removable = removable;
		store_p->desc_p.writeable = writeable;
		store_p->desc_p.block_size = block_size;
		store_p->desc_p.number_units = number_units;
		store_p->desc_p.locked = locked;
		store_p->desc_p.erase_unit_size = number_eus;
		dev_p->storage_device_info[bus][device] = store_p->desc_p;
	} else {
		cy_as_storage_query_device_data_dep	*store_p =
			(cy_as_storage_query_device_data_dep *)data_p;

		/* Make sure the response is about the address we asked
		 * about - if not, firmware error */
		if ((type != store_p->type) || (device != store_p->device)) {
			ret = CY_AS_ERROR_INVALID_RESPONSE;
			goto destroy;
		}

		store_p->desc_p.type = type;
		store_p->desc_p.removable = removable;
		store_p->desc_p.writeable = writeable;
		store_p->desc_p.block_size = block_size;
		store_p->desc_p.number_units = number_units;
		store_p->desc_p.locked = locked;
		store_p->desc_p.erase_unit_size = number_eus;
		dev_p->storage_device_info[bus][device] = store_p->desc_p;
	}

destroy:
	cy_as_ll_destroy_request(dev_p, req_p);
	cy_as_ll_destroy_response(dev_p, reply_p);

	return ret;
}

static cy_as_return_status_t
my_storage_query_device(cy_as_device *dev_p,
						void *data_p,
						uint16_t req_flags,
						cy_as_bus_number_t bus,
						uint32_t device,
						cy_as_function_callback cb,
						uint32_t client)
{
	cy_as_ll_request_response *req_p , *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;

	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	ret = is_storage_active(dev_p);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	/* Create the request to send to the Antioch device */
	req_p = cy_as_ll_create_request(dev_p,
		CY_RQT_QUERY_DEVICE, CY_RQT_STORAGE_RQT_CONTEXT, 1);
	if (req_p == 0)
		return CY_AS_ERROR_OUT_OF_MEMORY;

	cy_as_ll_request_response__set_word(req_p, 0,
		create_address(bus, device, 0));

	/* Reserve space for the reply, the reply data
	 * will not exceed five words. */
	reply_p = cy_as_ll_create_response(dev_p, 5);
	if (reply_p == 0) {
		cy_as_ll_destroy_request(dev_p, req_p);
		return CY_AS_ERROR_OUT_OF_MEMORY;
	}

	if (cb == 0) {
		ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		req_p->flags |= req_flags;
		return my_handle_response_storage_query_device(dev_p,
			req_p, reply_p, data_p);
	} else {

		ret = cy_as_misc_send_request(dev_p, cb, client,
			CY_FUNCT_CB_STOR_QUERYDEVICE, data_p,
			dev_p->func_cbs_stor, req_flags, req_p,
			reply_p, cy_as_storage_func_callback);

		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		/* The request and response are freed as part of the
		 * MiscFuncCallback */
		return ret;
	}

destroy:
	cy_as_ll_destroy_request(dev_p, req_p);
	cy_as_ll_destroy_response(dev_p, reply_p);

	return ret;
}

cy_as_return_status_t
cy_as_storage_query_device(cy_as_device_handle handle,
			cy_as_storage_query_device_data *data_p,
			cy_as_function_callback cb,
			uint32_t client)
{
	cy_as_device *dev_p = (cy_as_device *)handle;
	return my_storage_query_device(dev_p, data_p,
		CY_AS_REQUEST_RESPONSE_MS, data_p->bus,
			data_p->device, cb, client);
}

static cy_as_return_status_t
my_handle_response_storage_query_unit(cy_as_device *dev_p,
			cy_as_ll_request_response *req_p,
			cy_as_ll_request_response *reply_p,
			void *data_p)
{
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	cy_as_bus_number_t bus;
	uint32_t device;
	uint32_t unit;
	cy_as_media_type type;
	uint16_t block_size;
	uint32_t start_block;
	uint32_t unit_size;
	uint16_t v;

	if (cy_as_ll_request_response__get_code(reply_p) ==
	CY_RESP_NO_SUCH_ADDRESS) {
		ret = cy_as_map_bad_addr(
			cy_as_ll_request_response__get_word(reply_p, 3));
		goto destroy;
	}

	if (cy_as_ll_request_response__get_code(reply_p) !=
	CY_RESP_UNIT_DESCRIPTOR) {
		ret = CY_AS_ERROR_INVALID_RESPONSE;
		goto destroy;
	}

	/* Unpack the response */
	v	  = cy_as_ll_request_response__get_word(reply_p, 0);
	bus	= cy_as_storage_get_bus_from_address(v);
	device = cy_as_storage_get_device_from_address(v);
	unit   = get_unit_from_address(v);

	type   = cy_as_storage_get_media_from_address(
		cy_as_ll_request_response__get_word(reply_p, 1));

	block_size = cy_as_ll_request_response__get_word(reply_p, 2);
	start_block = cy_as_ll_request_response__get_word(reply_p, 3)
		| (cy_as_ll_request_response__get_word(reply_p, 4) << 16);
	unit_size = cy_as_ll_request_response__get_word(reply_p, 5)
		| (cy_as_ll_request_response__get_word(reply_p, 6) << 16);

	/* Store the results based on the version of
	 * originating function */
	if (req_p->flags & CY_AS_REQUEST_RESPONSE_MS) {
		cy_as_storage_query_unit_data  *store_p =
			(cy_as_storage_query_unit_data *)data_p;

		/* Make sure the response is about the address we
		 * asked about - if not, firmware error */
		if (bus != store_p->bus || device != store_p->device ||
		unit != store_p->unit) {
			ret = CY_AS_ERROR_INVALID_RESPONSE;
			goto destroy;
		}

		store_p->desc_p.type = type;
		store_p->desc_p.block_size = block_size;
		store_p->desc_p.start_block = start_block;
		store_p->desc_p.unit_size = unit_size;
	} else {
		cy_as_storage_query_unit_data_dep *store_p =
			(cy_as_storage_query_unit_data_dep *)data_p;

		/* Make sure the response is about the media type we asked
		 * about - if not, firmware error */
		if ((type != store_p->type) || (device != store_p->device) ||
		(unit != store_p->unit)) {
			ret = CY_AS_ERROR_INVALID_RESPONSE;
			goto destroy;
		}

		store_p->desc_p.type = type;
		store_p->desc_p.block_size = block_size;
		store_p->desc_p.start_block = start_block;
		store_p->desc_p.unit_size = unit_size;
	}

	dev_p->storage_device_info[bus][device].type = type;
	dev_p->storage_device_info[bus][device].block_size = block_size;

destroy:
	cy_as_ll_destroy_request(dev_p, req_p);
	cy_as_ll_destroy_response(dev_p, reply_p);

	return ret;
}

static cy_as_return_status_t
my_storage_query_unit(cy_as_device *dev_p,
					void *data_p,
					uint16_t req_flags,
					cy_as_bus_number_t bus,
					uint32_t device,
					uint32_t unit,
					cy_as_function_callback cb,
					uint32_t client)
{
	cy_as_ll_request_response *req_p , *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;

	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	ret = is_storage_active(dev_p);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	/* Create the request to send to the West Bridge device */
	req_p = cy_as_ll_create_request(dev_p,
	CY_RQT_QUERY_UNIT, CY_RQT_STORAGE_RQT_CONTEXT, 1);
	if (req_p == 0)
		return CY_AS_ERROR_OUT_OF_MEMORY;

	if (device > 255)
		return CY_AS_ERROR_NO_SUCH_DEVICE;

	if (unit > 255)
		return CY_AS_ERROR_NO_SUCH_UNIT;

	cy_as_ll_request_response__set_word(req_p, 0,
		create_address(bus, device, (uint8_t)unit));

	/* Reserve space for the reply, the reply data
	 * will be of seven words. */
	reply_p = cy_as_ll_create_response(dev_p, 7);
	if (reply_p == 0) {
		cy_as_ll_destroy_request(dev_p, req_p);
		return CY_AS_ERROR_OUT_OF_MEMORY;
	}

	if (cb == 0) {
		ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		req_p->flags |= req_flags;
		return my_handle_response_storage_query_unit(dev_p,
			req_p, reply_p, data_p);
	} else {

		ret = cy_as_misc_send_request(dev_p, cb, client,
			CY_FUNCT_CB_STOR_QUERYUNIT, data_p,
			dev_p->func_cbs_stor, req_flags, req_p, reply_p,
			cy_as_storage_func_callback);

		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		/* The request and response are freed
		 * as part of the MiscFuncCallback */
		return ret;
	}

destroy:
	cy_as_ll_destroy_request(dev_p, req_p);
	cy_as_ll_destroy_response(dev_p, reply_p);

	return ret;
}

cy_as_return_status_t
cy_as_storage_query_unit(cy_as_device_handle handle,
				cy_as_storage_query_unit_data *data_p,
				cy_as_function_callback cb,
				uint32_t client)
{
	cy_as_device *dev_p = (cy_as_device *)handle;
	return my_storage_query_unit(dev_p, data_p, CY_AS_REQUEST_RESPONSE_MS,
		data_p->bus, data_p->device, data_p->unit, cb, client);
}


static cy_as_return_status_t
cy_as_get_block_size(cy_as_device *dev_p,
					cy_as_bus_number_t bus,
					uint32_t device,
					cy_as_function_callback cb)
{
	cy_as_ll_request_response *req_p , *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;

	/* Create the request to send to the West Bridge device */
	req_p = cy_as_ll_create_request(dev_p, CY_RQT_QUERY_DEVICE,
		CY_RQT_STORAGE_RQT_CONTEXT, 1);
	if (req_p == 0)
		return CY_AS_ERROR_OUT_OF_MEMORY;

	cy_as_ll_request_response__set_word(req_p, 0,
		create_address(bus, device, 0));

	reply_p = cy_as_ll_create_response(dev_p, 4);
	if (reply_p == 0) {
		cy_as_ll_destroy_request(dev_p, req_p);
		return CY_AS_ERROR_OUT_OF_MEMORY;
	}

	if (cb == 0) {
		ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		if (cy_as_ll_request_response__get_code(reply_p)
		== CY_RESP_NO_SUCH_ADDRESS) {
			ret = CY_AS_ERROR_NO_SUCH_BUS;
			goto destroy;
		}

		if (cy_as_ll_request_response__get_code(reply_p) !=
		CY_RESP_DEVICE_DESCRIPTOR) {
			ret = CY_AS_ERROR_INVALID_RESPONSE;
			goto destroy;
		}

		/* Make sure the response is about the media type we asked
		 * about - if not, firmware error */
		if ((cy_as_storage_get_bus_from_address
			(cy_as_ll_request_response__get_word(reply_p, 0))
			!= bus) || (cy_as_storage_get_device_from_address
			(cy_as_ll_request_response__get_word(reply_p, 0))
			!= device)) {
			ret = CY_AS_ERROR_INVALID_RESPONSE;
			goto destroy;
		}


		dev_p->storage_device_info[bus][device].block_size =
			cy_as_ll_request_response__get_word(reply_p, 1);
	} else
		ret = CY_AS_ERROR_INVALID_REQUEST;

destroy:
	cy_as_ll_destroy_request(dev_p, req_p);
	cy_as_ll_destroy_response(dev_p, reply_p);

	return ret;
}

cy_as_return_status_t
my_storage_device_control(
		cy_as_device		  *dev_p,
		cy_as_bus_number_t	  bus,
		uint32_t			 device,
		cy_bool			   card_detect_en,
		cy_bool			   write_prot_en,
				cy_as_storage_card_detect config_detect,
		cy_as_function_callback cb,
		uint32_t			 client)
{
	cy_as_ll_request_response *req_p , *reply_p;
	cy_as_return_status_t ret;
	cy_bool use_gpio = cy_false;

	(void)device;

	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	if (!cy_as_device_is_configured(dev_p))
		return CY_AS_ERROR_NOT_CONFIGURED;

	if (!cy_as_device_is_firmware_loaded(dev_p))
		return CY_AS_ERROR_NO_FIRMWARE;

	if (cy_as_device_is_in_suspend_mode(dev_p))
		return CY_AS_ERROR_IN_SUSPEND;

	if (bus < 0 || bus >= CY_AS_MAX_BUSES)
		return CY_AS_ERROR_NO_SUCH_BUS;

	if (device >= CY_AS_MAX_STORAGE_DEVICES)
		return CY_AS_ERROR_NO_SUCH_DEVICE;

	/* If SD is not supported on the specified bus,
	 * then return ERROR */
	if ((dev_p->media_supported[bus] == 0) ||
		(dev_p->media_supported[bus] & (1<<cy_as_media_nand)))
		return CY_AS_ERROR_NOT_SUPPORTED;

	if (config_detect == cy_as_storage_detect_GPIO)
		use_gpio = cy_true;
	else if (config_detect == cy_as_storage_detect_SDAT_3)
		use_gpio = cy_false;
	else
		return CY_AS_ERROR_INVALID_PARAMETER;

	/* Create the request to send to the West Bridge device */
	req_p = cy_as_ll_create_request(dev_p,
		CY_RQT_SD_INTERFACE_CONTROL, CY_RQT_STORAGE_RQT_CONTEXT, 2);
	if (req_p == 0)
		return CY_AS_ERROR_OUT_OF_MEMORY;

	cy_as_ll_request_response__set_word(req_p,
		0, create_address(bus, device, 0));
	cy_as_ll_request_response__set_word(req_p,
		1, (((uint16_t)card_detect_en << 8) |
		((uint16_t)use_gpio << 1) | (uint16_t)write_prot_en));

	reply_p = cy_as_ll_create_response(dev_p, 1);
	if (reply_p == 0) {
		cy_as_ll_destroy_request(dev_p, req_p);
		return CY_AS_ERROR_OUT_OF_MEMORY;
	}

	if (cb == 0) {
		ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		if (cy_as_ll_request_response__get_code(reply_p) !=
		CY_RESP_SUCCESS_FAILURE) {
			ret = CY_AS_ERROR_INVALID_RESPONSE;
			goto destroy;
		}

		ret = cy_as_ll_request_response__get_word(reply_p, 0);
	} else {

		ret = cy_as_misc_send_request(dev_p, cb, client,
			CY_FUNCT_CB_STOR_DEVICECONTROL,
			0, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX,
			req_p, reply_p, cy_as_storage_func_callback);

		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		/* The request and response are freed as part of the
		 * MiscFuncCallback */
		return ret;
	}
destroy:
	cy_as_ll_destroy_request(dev_p, req_p);
	cy_as_ll_destroy_response(dev_p, reply_p);

	return ret;
}

cy_as_return_status_t
cy_as_storage_device_control(cy_as_device_handle handle,
					cy_as_bus_number_t bus,
					uint32_t device,
					cy_bool card_detect_en,
					cy_bool write_prot_en,
					cy_as_storage_card_detect config_detect,
					cy_as_function_callback cb,
					uint32_t client)
{
	cy_as_device *dev_p = (cy_as_device *)handle;

	return my_storage_device_control(dev_p, bus, device, card_detect_en,
		write_prot_en, config_detect, cb, client);
}

static void
cy_as_async_storage_callback(cy_as_device *dev_p,
	cy_as_end_point_number_t ep, void *buf_p, uint32_t size,
	cy_as_return_status_t ret)
{
	cy_as_storage_callback_dep cb;
	cy_as_storage_callback cb_ms;

	(void)size;
	(void)buf_p;
	(void)ep;

	cy_as_device_clear_storage_async_pending(dev_p);

	/*
	* if the LL request callback has already been called,
	* the user callback has to be called from here.
	*/
	if (!dev_p->storage_wait) {
			cy_as_hal_assert(dev_p->storage_cb != NULL ||
				dev_p->storage_cb_ms != NULL);
			cb = dev_p->storage_cb;
			cb_ms = dev_p->storage_cb_ms;

			dev_p->storage_cb = 0;
			dev_p->storage_cb_ms = 0;

			if (ret == CY_AS_ERROR_SUCCESS)
				ret = dev_p->storage_error;

		if (cb_ms) {
			cb_ms((cy_as_device_handle)dev_p,
				dev_p->storage_bus_index,
				dev_p->storage_device_index,
				dev_p->storage_unit,
				dev_p->storage_block_addr,
				dev_p->storage_oper, ret);
		} else {
			cb((cy_as_device_handle)dev_p,
				dev_p->storage_device_info
				[dev_p->storage_bus_index]
				[dev_p->storage_device_index].type,
				dev_p->storage_device_index,
				dev_p->storage_unit,
				dev_p->storage_block_addr,
				dev_p->storage_oper, ret);
		}
	} else
		dev_p->storage_error = ret;
}

static void
cy_as_async_storage_reply_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)
{
	cy_as_storage_callback_dep cb;
	cy_as_storage_callback cb_ms;
	uint8_t reqtype;
	(void)rqt;
	(void)context;

	reqtype = cy_as_ll_request_response__get_code(rqt);

	if (ret == CY_AS_ERROR_SUCCESS) {
		if (cy_as_ll_request_response__get_code(resp) ==
			CY_RESP_ANTIOCH_DEFERRED_ERROR) {
			ret = cy_as_ll_request_response__get_word
				(resp, 0) & 0x00FF;
		} else if (cy_as_ll_request_response__get_code(resp) !=
			CY_RESP_SUCCESS_FAILURE) {
			ret = CY_AS_ERROR_INVALID_RESPONSE;
		}
	}

	if (ret != CY_AS_ERROR_SUCCESS) {
		if (reqtype == CY_RQT_READ_BLOCK)
			cy_as_dma_cancel(dev_p,
				dev_p->storage_read_endpoint, ret);
		else
			cy_as_dma_cancel(dev_p,
				dev_p->storage_write_endpoint, ret);
	}

	dev_p->storage_wait = cy_false;

	/*
	* if the DMA callback has already been called, the
	* user callback has to be called from here.
	*/
	if (!cy_as_device_is_storage_async_pending(dev_p)) {
		cy_as_hal_assert(dev_p->storage_cb != NULL ||
			dev_p->storage_cb_ms != NULL);
		cb = dev_p->storage_cb;
		cb_ms = dev_p->storage_cb_ms;

		dev_p->storage_cb = 0;
		dev_p->storage_cb_ms = 0;

		if (ret == CY_AS_ERROR_SUCCESS)
			ret = dev_p->storage_error;

		if (cb_ms) {
			cb_ms((cy_as_device_handle)dev_p,
				dev_p->storage_bus_index,
				dev_p->storage_device_index,
				dev_p->storage_unit,
				dev_p->storage_block_addr,
				dev_p->storage_oper, ret);
		} else {
			cb((cy_as_device_handle)dev_p,
				dev_p->storage_device_info
				[dev_p->storage_bus_index]
				[dev_p->storage_device_index].type,
				dev_p->storage_device_index,
				dev_p->storage_unit,
				dev_p->storage_block_addr,
				dev_p->storage_oper, ret);
		}
	} else
		dev_p->storage_error = ret;
}

static cy_as_return_status_t
cy_as_storage_async_oper(cy_as_device *dev_p, cy_as_end_point_number_t ep,
		uint8_t reqtype, uint16_t req_flags, cy_as_bus_number_t bus,
		uint32_t device, uint32_t unit, uint32_t block, void *data_p,
		uint16_t num_blocks, cy_as_storage_callback_dep callback,
		cy_as_storage_callback callback_ms)
{
	uint32_t mask;
	cy_as_ll_request_response *req_p , *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;

	ret = is_storage_active(dev_p);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	if (bus < 0 || bus >= CY_AS_MAX_BUSES)
		return CY_AS_ERROR_NO_SUCH_BUS;

	if (device >= CY_AS_MAX_STORAGE_DEVICES)
		return CY_AS_ERROR_NO_SUCH_DEVICE;

	if (unit > 255)
		return CY_AS_ERROR_NO_SUCH_UNIT;

	/* We are supposed to return sucess if the number of
	* blocks is zero
	*/
	if (num_blocks == 0) {
		if (callback_ms)
			callback_ms((cy_as_device_handle)dev_p,
				bus, device, unit, block,
				((reqtype == CY_RQT_WRITE_BLOCK)
				? cy_as_op_write : cy_as_op_read),
				CY_AS_ERROR_SUCCESS);
		else
			callback((cy_as_device_handle)dev_p,
				dev_p->storage_device_info[bus][device].type,
				device, unit, block,
				((reqtype == CY_RQT_WRITE_BLOCK) ?
					cy_as_op_write : cy_as_op_read),
				CY_AS_ERROR_SUCCESS);

		return CY_AS_ERROR_SUCCESS;
	}

	if (dev_p->storage_device_info[bus][device].block_size == 0)
			return CY_AS_ERROR_QUERY_DEVICE_NEEDED;

	/*
	* since async operations can be triggered by interrupt
	* code, we must insure that we do not get multiple
	* async operations going at one time and protect this
	* test and set operation from interrupts. also need to
	* check for pending async MTP writes
	*/
	mask = cy_as_hal_disable_interrupts();
	if ((cy_as_device_is_storage_async_pending(dev_p)) ||
	(dev_p->storage_wait) ||
	(cy_as_device_is_usb_async_pending(dev_p, 6))) {
		cy_as_hal_enable_interrupts(mask);
		return CY_AS_ERROR_ASYNC_PENDING;
	}

	cy_as_device_set_storage_async_pending(dev_p);
	cy_as_device_clear_p2s_dma_start_recvd(dev_p);
	cy_as_hal_enable_interrupts(mask);

	/*
	* storage information about the currently outstanding request
	*/
	dev_p->storage_cb = callback;
	dev_p->storage_cb_ms = callback_ms;
	dev_p->storage_bus_index = bus;
	dev_p->storage_device_index = device;
	dev_p->storage_unit = unit;
	dev_p->storage_block_addr = block;

	/* Initialise the request to send to the West Bridge. */
	req_p = dev_p->storage_rw_req_p;
	cy_as_ll_init_request(req_p, reqtype, CY_RQT_STORAGE_RQT_CONTEXT, 5);

	/* Initialise the space for reply from the West Bridge. */
	reply_p = dev_p->storage_rw_resp_p;
	cy_as_ll_init_response(reply_p, 5);

	/* Remember which version of the API originated the request */
	req_p->flags |= req_flags;

	/* Setup the DMA request and adjust the storage
	 * operation if we are reading */
	if (reqtype == CY_RQT_READ_BLOCK) {
		ret = cy_as_dma_queue_request(dev_p, ep, data_p,
			dev_p->storage_device_info[bus][device].block_size
			* num_blocks, cy_false, cy_true,
			cy_as_async_storage_callback);
		dev_p->storage_oper = cy_as_op_read;
	} else if (reqtype == CY_RQT_WRITE_BLOCK) {
		ret = cy_as_dma_queue_request(dev_p, ep, data_p,
			dev_p->storage_device_info[bus][device].block_size *
			num_blocks, cy_false, cy_false,
			cy_as_async_storage_callback);
		dev_p->storage_oper = cy_as_op_write;
	}

	if (ret != CY_AS_ERROR_SUCCESS) {
		cy_as_device_clear_storage_async_pending(dev_p);
		return ret;
	}

	cy_as_ll_request_response__set_word(req_p,
		0, create_address(bus, (uint8_t)device, (uint8_t)unit));
	cy_as_ll_request_response__set_word(req_p,
		1, (uint16_t)((block >> 16) & 0xffff));
	cy_as_ll_request_response__set_word(req_p,
		2, (uint16_t)(block & 0xffff));
	cy_as_ll_request_response__set_word(req_p,
		3, (uint16_t)((num_blocks >> 8) & 0x00ff));
	cy_as_ll_request_response__set_word(req_p,
		4, (uint16_t)((num_blocks << 8) & 0xff00));

	/* Set the burst mode flag. */
	if (dev_p->is_storage_only_mode)
		req_p->data[4] |= 0x0001;

	/* Send the request and wait for completion
	 * of storage request */
	dev_p->storage_wait = cy_true;
	ret = cy_as_ll_send_request(dev_p, req_p, reply_p,
		cy_true, cy_as_async_storage_reply_callback);
	if (ret != CY_AS_ERROR_SUCCESS) {
		cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_CANCELED);
		cy_as_device_clear_storage_async_pending(dev_p);
	}

	return ret;
}

static void
cy_as_sync_storage_callback(cy_as_device *dev_p,
	cy_as_end_point_number_t ep, void *buf_p,
	uint32_t size, cy_as_return_status_t err)
{
	(void)ep;
	(void)buf_p;
	(void)size;

	dev_p->storage_error = err;
}

static void
cy_as_sync_storage_reply_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)
{
	uint8_t reqtype;
	(void)rqt;

	reqtype = cy_as_ll_request_response__get_code(rqt);

	if (cy_as_ll_request_response__get_code(resp) ==
	CY_RESP_ANTIOCH_DEFERRED_ERROR) {
		ret = cy_as_ll_request_response__get_word(resp, 0) & 0x00FF;

		if (ret != CY_AS_ERROR_SUCCESS) {
			if (reqtype == CY_RQT_READ_BLOCK)
				cy_as_dma_cancel(dev_p,
					dev_p->storage_read_endpoint, ret);
			else
				cy_as_dma_cancel(dev_p,
					dev_p->storage_write_endpoint, ret);
		}
	} else if (cy_as_ll_request_response__get_code(resp) !=
	CY_RESP_SUCCESS_FAILURE) {
		ret = CY_AS_ERROR_INVALID_RESPONSE;
	}

	dev_p->storage_wait = cy_false;
	dev_p->storage_error = ret;

	/* Wake any threads/processes that are waiting on
	 * the read/write completion. */
	cy_as_hal_wake(&dev_p->context[context]->channel);
}

static cy_as_return_status_t
cy_as_storage_sync_oper(cy_as_device *dev_p,
	cy_as_end_point_number_t ep, uint8_t reqtype,
	cy_as_bus_number_t bus, uint32_t device,
	uint32_t unit, uint32_t block, void *data_p,
	uint16_t num_blocks)
{
	cy_as_ll_request_response *req_p , *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	cy_as_context *ctxt_p;
	uint32_t loopcount = 200;

	ret = is_storage_active(dev_p);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	if (bus < 0 || bus >= CY_AS_MAX_BUSES)
		return CY_AS_ERROR_NO_SUCH_BUS;

	if (device >= CY_AS_MAX_STORAGE_DEVICES)
		return CY_AS_ERROR_NO_SUCH_DEVICE;

	if (unit > 255)
		return CY_AS_ERROR_NO_SUCH_UNIT;

	if ((cy_as_device_is_storage_async_pending(dev_p)) ||
		(dev_p->storage_wait))
		return CY_AS_ERROR_ASYNC_PENDING;

	/* Also need to check for pending Async MTP writes */
	if (cy_as_device_is_usb_async_pending(dev_p, 6))
		return CY_AS_ERROR_ASYNC_PENDING;

	/* We are supposed to return sucess if the number of
	* blocks is zero
	*/
	if (num_blocks == 0)
		return CY_AS_ERROR_SUCCESS;

	if (dev_p->storage_device_info[bus][device].block_size == 0) {
		/*
		* normally, a given device has been queried via
		* the query device call before a read request is issued.
		* therefore, this normally will not be run.
		*/
		ret = cy_as_get_block_size(dev_p, bus, device, 0);
		if (ret != CY_AS_ERROR_SUCCESS)
			return ret;
	}

	/* Initialise the request to send to the West Bridge. */
	req_p = dev_p->storage_rw_req_p;
	cy_as_ll_init_request(req_p, reqtype,
		CY_RQT_STORAGE_RQT_CONTEXT, 5);

	/* Initialise the space for reply from
	 * the West Bridge. */
	reply_p = dev_p->storage_rw_resp_p;
	cy_as_ll_init_response(reply_p, 5);
	cy_as_device_clear_p2s_dma_start_recvd(dev_p);

	/* Setup the DMA request */
	if (reqtype == CY_RQT_READ_BLOCK) {
		ret = cy_as_dma_queue_request(dev_p, ep, data_p,
			dev_p->storage_device_info[bus][device].block_size *
			num_blocks, cy_false,
			cy_true, cy_as_sync_storage_callback);
		dev_p->storage_oper = cy_as_op_read;
	} else if (reqtype == CY_RQT_WRITE_BLOCK) {
		ret = cy_as_dma_queue_request(dev_p, ep, data_p,
			dev_p->storage_device_info[bus][device].block_size *
			num_blocks, cy_false, cy_false,
			cy_as_sync_storage_callback);
		dev_p->storage_oper = cy_as_op_write;
	}

	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	cy_as_ll_request_response__set_word(req_p, 0,
		create_address(bus, (uint8_t)device, (uint8_t)unit));
	cy_as_ll_request_response__set_word(req_p, 1,
		(uint16_t)((block >> 16) & 0xffff));
	cy_as_ll_request_response__set_word(req_p, 2,
		(uint16_t)(block & 0xffff));
	cy_as_ll_request_response__set_word(req_p, 3,
		(uint16_t)((num_blocks >> 8) & 0x00ff));
	cy_as_ll_request_response__set_word(req_p, 4,
		(uint16_t)((num_blocks << 8) & 0xff00));

	/* Set the burst mode flag. */
	if (dev_p->is_storage_only_mode)
		req_p->data[4] |= 0x0001;

	/* Send the request and wait for
	 * completion of storage request */
	dev_p->storage_wait = cy_true;
	ret = cy_as_ll_send_request(dev_p, req_p, reply_p, cy_true,
		cy_as_sync_storage_reply_callback);
	if (ret != CY_AS_ERROR_SUCCESS) {
		cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_CANCELED);
	} else {
		/* Setup the DMA request */
		ctxt_p = dev_p->context[CY_RQT_STORAGE_RQT_CONTEXT];
		ret = cy_as_dma_drain_queue(dev_p, ep, cy_false);

		while (loopcount-- > 0) {
			if (dev_p->storage_wait == cy_false)
				break;
			cy_as_hal_sleep_on(&ctxt_p->channel, 10);
		}

		if (dev_p->storage_wait == cy_true) {
			dev_p->storage_wait = cy_false;
			cy_as_ll_remove_request(dev_p, ctxt_p, req_p, cy_true);
			ret = CY_AS_ERROR_TIMEOUT;
		}

		if (ret == CY_AS_ERROR_SUCCESS)
			ret = dev_p->storage_error;
	}

	return ret;
}

cy_as_return_status_t
cy_as_storage_read(cy_as_device_handle handle,
	cy_as_bus_number_t bus, uint32_t device,
	uint32_t unit, uint32_t block,
	void *data_p, uint16_t num_blocks)
{
	cy_as_device *dev_p = (cy_as_device *)handle;

	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	return cy_as_storage_sync_oper(dev_p, dev_p->storage_read_endpoint,
		CY_RQT_READ_BLOCK, bus, device,
		unit, block, data_p, num_blocks);
}

cy_as_return_status_t
cy_as_storage_write(cy_as_device_handle handle,
	cy_as_bus_number_t bus, uint32_t device,
	uint32_t unit, uint32_t block, void *data_p,
	uint16_t num_blocks)
{
	cy_as_device *dev_p = (cy_as_device *)handle;

	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	if (dev_p->mtp_turbo_active)
		return CY_AS_ERROR_NOT_VALID_DURING_MTP;

	return cy_as_storage_sync_oper(dev_p,
		dev_p->storage_write_endpoint,
		CY_RQT_WRITE_BLOCK, bus, device,
		unit, block, data_p, num_blocks);
}


cy_as_return_status_t
cy_as_storage_read_async(cy_as_device_handle handle,
	cy_as_bus_number_t bus, uint32_t device, uint32_t unit,
	uint32_t block, void *data_p, uint16_t num_blocks,
	cy_as_storage_callback callback)
{
	cy_as_device *dev_p = (cy_as_device *)handle;

	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	if (callback == 0)
		return CY_AS_ERROR_NULL_CALLBACK;

	return cy_as_storage_async_oper(dev_p,
		dev_p->storage_read_endpoint, CY_RQT_READ_BLOCK,
		CY_AS_REQUEST_RESPONSE_MS, bus, device, unit,
		block, data_p, num_blocks, NULL, callback);
}

cy_as_return_status_t
cy_as_storage_write_async(cy_as_device_handle handle,
	cy_as_bus_number_t bus, uint32_t device, uint32_t unit,
	uint32_t block, void *data_p, uint16_t num_blocks,
	cy_as_storage_callback callback)
{
	cy_as_device *dev_p = (cy_as_device *)handle;

	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	if (callback == 0)
		return CY_AS_ERROR_NULL_CALLBACK;

	if (dev_p->mtp_turbo_active)
		return CY_AS_ERROR_NOT_VALID_DURING_MTP;

	return cy_as_storage_async_oper(dev_p,
		dev_p->storage_write_endpoint, CY_RQT_WRITE_BLOCK,
		CY_AS_REQUEST_RESPONSE_MS, bus, device, unit, block,
		data_p, num_blocks, NULL, callback);
}


static void
my_storage_cancel_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 stat)
{
	(void)context;
	(void)stat;

	/* Nothing to do here, except free up the
	 * request and response structures. */
	cy_as_ll_destroy_response(dev_p, resp);
	cy_as_ll_destroy_request(dev_p, rqt);
}


cy_as_return_status_t
cy_as_storage_cancel_async(cy_as_device_handle handle)
{
	cy_as_return_status_t ret;
	cy_as_ll_request_response *req_p , *reply_p;

	cy_as_device *dev_p = (cy_as_device *)handle;
	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	ret = is_storage_active(dev_p);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	if (!cy_as_device_is_storage_async_pending(dev_p))
		return CY_AS_ERROR_ASYNC_NOT_PENDING;

	/*
	 * create and send a mailbox request to firmware
	 * asking it to abort processing of the current
	 * P2S operation. the rest of the cancel processing will be
	 * driven through the callbacks for the read/write call.
	 */
	req_p = cy_as_ll_create_request(dev_p, CY_RQT_ABORT_P2S_XFER,
		CY_RQT_GENERAL_RQT_CONTEXT, 1);
	if (req_p == 0)
		return CY_AS_ERROR_OUT_OF_MEMORY;

	reply_p = cy_as_ll_create_response(dev_p, 1);
	if (reply_p == 0) {
		cy_as_ll_destroy_request(dev_p, req_p);
		return CY_AS_ERROR_OUT_OF_MEMORY;
	}

	ret = cy_as_ll_send_request(dev_p, req_p,
		reply_p, cy_false, my_storage_cancel_callback);
	if (ret) {
		cy_as_ll_destroy_request(dev_p, req_p);
		cy_as_ll_destroy_response(dev_p, reply_p);
	}

	return CY_AS_ERROR_SUCCESS;
}

/*
 * This function does all the API side clean-up associated with
 * CyAsStorageStop, without any communication with the firmware.
 */
void cy_as_storage_cleanup(cy_as_device *dev_p)
{
	if (dev_p->storage_count) {
		cy_as_ll_destroy_request(dev_p, dev_p->storage_rw_req_p);
		cy_as_ll_destroy_response(dev_p, dev_p->storage_rw_resp_p);
		dev_p->storage_count = 0;
		cy_as_device_clear_scsi_messages(dev_p);
		cy_as_hal_mem_set(dev_p->storage_device_info,
			0, sizeof(dev_p->storage_device_info));

		cy_as_device_clear_storage_async_pending(dev_p);
		dev_p->storage_cb = 0;
		dev_p->storage_cb_ms = 0;
		dev_p->storage_wait = cy_false;
	}
}

static cy_as_return_status_t
my_handle_response_sd_reg_read(
		cy_as_device			   *dev_p,
		cy_as_ll_request_response	*req_p,
		cy_as_ll_request_response	*reply_p,
		cy_as_storage_sd_reg_read_data *info)
{
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	uint8_t  resp_type, i;
	uint16_t resp_len;
	uint8_t  length = info->length;
	uint8_t *data_p = info->buf_p;

	resp_type = cy_as_ll_request_response__get_code(reply_p);
	if (resp_type == CY_RESP_SD_REGISTER_DATA) {
		uint16_t *resp_p = reply_p->data + 1;
		uint16_t temp;

		resp_len = cy_as_ll_request_response__get_word(reply_p, 0);
		cy_as_hal_assert(resp_len >= length);

		/*
		 * copy the values into the output buffer after doing the
		 * necessary bit shifting. the bit shifting is required because
		 * the data comes out of the west bridge with a 6 bit offset.
		 */
		i = 0;
		while (length) {
			temp = ((resp_p[i] << 6) | (resp_p[i + 1] >> 10));
			i++;

			*data_p++ = (uint8_t)(temp >> 8);
			length--;

			if (length) {
				*data_p++ = (uint8_t)(temp & 0xFF);
				length--;
			}
		}
	} else {
		if (resp_type == CY_RESP_SUCCESS_FAILURE)
			ret = cy_as_ll_request_response__get_word(reply_p, 0);
		else
			ret = CY_AS_ERROR_INVALID_RESPONSE;
	}

	cy_as_ll_destroy_response(dev_p, reply_p);
	cy_as_ll_destroy_request(dev_p, req_p);

	return ret;
}

cy_as_return_status_t
cy_as_storage_sd_register_read(
		cy_as_device_handle		  handle,
		cy_as_bus_number_t		   bus,
		uint8_t				   device,
		cy_as_sd_card_reg_type		 reg_type,
		cy_as_storage_sd_reg_read_data *data_p,
		cy_as_function_callback	  cb,
		uint32_t				  client)
{
	cy_as_ll_request_response *req_p , *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	uint8_t  length;

	/*
	 * sanity checks required before sending the request to the
	 * firmware.
	 */
	cy_as_device *dev_p = (cy_as_device *)handle;
	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	ret = is_storage_active(dev_p);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	if (device >= CY_AS_MAX_STORAGE_DEVICES)
		return CY_AS_ERROR_NO_SUCH_DEVICE;

	if (reg_type > cy_as_sd_reg_CSD)
		return CY_AS_ERROR_INVALID_PARAMETER;

	/* If SD/MMC media is not supported on the
	 * addressed bus, return error. */
	if ((dev_p->media_supported[bus] & (1 << cy_as_media_sd_flash)) == 0)
		return CY_AS_ERROR_INVALID_PARAMETER;

	/*
	 * find the amount of data to be returned. this will be the minimum of
	 * the actual data length, and the length requested.
	 */
	switch (reg_type) {
	case cy_as_sd_reg_OCR:
		length = CY_AS_SD_REG_OCR_LENGTH;
		break;
	case cy_as_sd_reg_CID:
		length = CY_AS_SD_REG_CID_LENGTH;
		break;
	case cy_as_sd_reg_CSD:
		length = CY_AS_SD_REG_CSD_LENGTH;
		break;

	default:
		length = 0;
		cy_as_hal_assert(0);
	}

	if (length < data_p->length)
		data_p->length = length;
	length = data_p->length;

	/* Create the request to send to the West Bridge device */
	req_p = cy_as_ll_create_request(dev_p, CY_RQT_SD_REGISTER_READ,
		CY_RQT_STORAGE_RQT_CONTEXT, 1);
	if (req_p == 0)
		return CY_AS_ERROR_OUT_OF_MEMORY;

	cy_as_ll_request_response__set_word(req_p, 0,
		(create_address(bus, device, 0) | (uint16_t)reg_type));

	reply_p = cy_as_ll_create_response(dev_p,
		CY_AS_SD_REG_MAX_RESP_LENGTH);
	if (reply_p == 0) {
		cy_as_ll_destroy_request(dev_p, req_p);
		return CY_AS_ERROR_OUT_OF_MEMORY;
	}

	if (cb == 0) {
		ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		return my_handle_response_sd_reg_read(dev_p,
			req_p, reply_p, data_p);
	} else {
		ret = cy_as_misc_send_request(dev_p, cb, client,
			CY_FUNCT_CB_STOR_SDREGISTERREAD, data_p,
			dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX,
			req_p, reply_p, cy_as_storage_func_callback);

		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		/* The request and response are freed as part of the
		 * MiscFuncCallback */
		return ret;
	}

destroy:
	cy_as_ll_destroy_request(dev_p, req_p);
	cy_as_ll_destroy_response(dev_p, reply_p);

	return ret;
}

cy_as_return_status_t
cy_as_storage_create_p_partition(
		/* Handle to the device of interest */
		cy_as_device_handle		handle,
		cy_as_bus_number_t		 bus,
		uint32_t				device,
		/* of P-port only partition in blocks */
		uint32_t				size,
		cy_as_function_callback	cb,
		uint32_t				client)
{
	cy_as_ll_request_response *req_p, *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	cy_as_device *dev_p = (cy_as_device *)handle;

	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	ret = is_storage_active(dev_p);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	/* Partitions cannot be created or deleted while
	 * the USB stack is active. */
	if (dev_p->usb_count)
		return CY_AS_ERROR_USB_RUNNING;

	/* Create the request to send to the West Bridge device */
	req_p = cy_as_ll_create_request(dev_p, CY_RQT_PARTITION_STORAGE,
		CY_RQT_STORAGE_RQT_CONTEXT, 3);

	if (req_p == 0)
		return CY_AS_ERROR_OUT_OF_MEMORY;

	/* Reserve space for the reply, the reply
	 * data will not exceed one word */
	reply_p = cy_as_ll_create_response(dev_p, 1);
	if (reply_p == 0) {
		cy_as_ll_destroy_request(dev_p, req_p);
		return CY_AS_ERROR_OUT_OF_MEMORY;
	}
	cy_as_ll_request_response__set_word(req_p, 0,
		create_address(bus, (uint8_t)device, 0x00));
	cy_as_ll_request_response__set_word(req_p, 1,
		(uint16_t)((size >> 16) & 0xffff));
	cy_as_ll_request_response__set_word(req_p, 2,
		(uint16_t)(size & 0xffff));

	if (cb == 0) {
		ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		return my_handle_response_no_data(dev_p, req_p, reply_p);
	} else {
		ret = cy_as_misc_send_request(dev_p, cb, client,
			CY_FUNCT_CB_STOR_PARTITION, 0, dev_p->func_cbs_stor,
			CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
			cy_as_storage_func_callback);

		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		/* The request and response are freed as part of the
		 * FuncCallback */
		return ret;

	}

destroy:
	cy_as_ll_destroy_request(dev_p, req_p);
	cy_as_ll_destroy_response(dev_p, reply_p);

	return ret;
}

cy_as_return_status_t
cy_as_storage_remove_p_partition(
		cy_as_device_handle		handle,
		cy_as_bus_number_t		 bus,
		uint32_t				device,
		cy_as_function_callback	cb,
		uint32_t				client)
{
	cy_as_ll_request_response *req_p, *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	cy_as_device *dev_p = (cy_as_device *)handle;

	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	ret = is_storage_active(dev_p);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	/* Partitions cannot be created or deleted while
	 * the USB stack is active. */
	if (dev_p->usb_count)
		return CY_AS_ERROR_USB_RUNNING;

	/* Create the request to send to the West Bridge device */
	req_p = cy_as_ll_create_request(dev_p, CY_RQT_PARTITION_ERASE,
		CY_RQT_STORAGE_RQT_CONTEXT, 1);
	if (req_p == 0)
		return CY_AS_ERROR_OUT_OF_MEMORY;

	/* Reserve space for the reply, the reply
	 * data will not exceed one word */
	reply_p = cy_as_ll_create_response(dev_p, 1);
	if (reply_p == 0) {
		cy_as_ll_destroy_request(dev_p, req_p);
		return CY_AS_ERROR_OUT_OF_MEMORY;
	}

	cy_as_ll_request_response__set_word(req_p,
		0, create_address(bus, (uint8_t)device, 0x00));

	if (cb == 0) {
		ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		return my_handle_response_no_data(dev_p, req_p, reply_p);
	} else {
		ret = cy_as_misc_send_request(dev_p, cb, client,
			CY_FUNCT_CB_NODATA, 0, dev_p->func_cbs_stor,
			CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
			cy_as_storage_func_callback);

		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		/* The request and response are freed
		 * as part of the FuncCallback */
		return ret;

	}

destroy:
	cy_as_ll_destroy_request(dev_p, req_p);
	cy_as_ll_destroy_response(dev_p, reply_p);

	return ret;
}

static cy_as_return_status_t
my_handle_response_get_transfer_amount(cy_as_device *dev_p,
				cy_as_ll_request_response *req_p,
				cy_as_ll_request_response *reply_p,
				cy_as_m_s_c_progress_data *data)
{
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	uint8_t code = cy_as_ll_request_response__get_code(reply_p);
	uint16_t v1, v2;

	if (code != CY_RESP_TRANSFER_COUNT) {
		ret = CY_AS_ERROR_INVALID_RESPONSE;
		goto destroy;
	}

	v1 = cy_as_ll_request_response__get_word(reply_p, 0);
	v2 = cy_as_ll_request_response__get_word(reply_p, 1);
	data->wr_count = (uint32_t)((v1 << 16) | v2);

	v1 = cy_as_ll_request_response__get_word(reply_p, 2);
	v2 = cy_as_ll_request_response__get_word(reply_p, 3);
	data->rd_count = (uint32_t)((v1 << 16) | v2);

destroy:
	cy_as_ll_destroy_request(dev_p, req_p);
	cy_as_ll_destroy_response(dev_p, reply_p);

	return ret;
}

cy_as_return_status_t
cy_as_storage_get_transfer_amount(
		cy_as_device_handle handle,
		cy_as_bus_number_t  bus,
		uint32_t device,
		cy_as_m_s_c_progress_data *data_p,
		cy_as_function_callback cb,
		uint32_t client
	)
{
	cy_as_ll_request_response *req_p, *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	cy_as_device *dev_p = (cy_as_device *)handle;

	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	ret = is_storage_active(dev_p);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	/* Check if the firmware image supports this feature. */
	if ((dev_p->media_supported[0]) && (dev_p->media_supported[0]
	== (1 << cy_as_media_nand)))
		return CY_AS_ERROR_NOT_SUPPORTED;

	/* Create the request to send to the West Bridge device */
	req_p = cy_as_ll_create_request(dev_p, CY_RQT_GET_TRANSFER_AMOUNT,
		CY_RQT_STORAGE_RQT_CONTEXT, 1);
	if (req_p == 0)
		return CY_AS_ERROR_OUT_OF_MEMORY;

	/* Reserve space for the reply, the reply data
	 * will not exceed four words. */
	reply_p = cy_as_ll_create_response(dev_p, 4);
	if (reply_p == 0) {
		cy_as_ll_destroy_request(dev_p, req_p);
		return CY_AS_ERROR_OUT_OF_MEMORY;
	}

	cy_as_ll_request_response__set_word(req_p, 0,
		create_address(bus, (uint8_t)device, 0x00));

	if (cb == 0) {
		ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		return my_handle_response_get_transfer_amount(dev_p,
			req_p, reply_p, data_p);
	} else {
		ret = cy_as_misc_send_request(dev_p, cb, client,
		CY_FUNCT_CB_STOR_GETTRANSFERAMOUNT, (void *)data_p,
		dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX,
		req_p, reply_p, cy_as_storage_func_callback);

		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		/* The request and response are freed as part of the
		 * FuncCallback */
		return ret;
	}

destroy:
	cy_as_ll_destroy_request(dev_p, req_p);
	cy_as_ll_destroy_response(dev_p, reply_p);

	return ret;

}

cy_as_return_status_t
cy_as_storage_erase(
		cy_as_device_handle		handle,
		cy_as_bus_number_t		 bus,
		uint32_t				device,
		uint32_t				erase_unit,
		uint16_t				num_erase_units,
		cy_as_function_callback	cb,
		uint32_t				client
		)
{
	cy_as_ll_request_response *req_p, *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	cy_as_device *dev_p = (cy_as_device *)handle;

	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	ret = is_storage_active(dev_p);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	if (bus < 0 || bus >= CY_AS_MAX_BUSES)
		return CY_AS_ERROR_NO_SUCH_BUS;

	if (device >= CY_AS_MAX_STORAGE_DEVICES)
		return CY_AS_ERROR_NO_SUCH_DEVICE;

	if (dev_p->storage_device_info[bus][device].block_size == 0)
		return CY_AS_ERROR_QUERY_DEVICE_NEEDED;

	/* If SD is not supported on the specified bus, then return ERROR */
	if (dev_p->storage_device_info[bus][device].type !=
		cy_as_media_sd_flash)
		return CY_AS_ERROR_NOT_SUPPORTED;

	if (num_erase_units == 0)
		return CY_AS_ERROR_SUCCESS;

	/* Create the request to send to the West Bridge device */
	req_p = cy_as_ll_create_request(dev_p, CY_RQT_ERASE,
		CY_RQT_STORAGE_RQT_CONTEXT, 5);

	if (req_p == 0)
		return CY_AS_ERROR_OUT_OF_MEMORY;

	/* Reserve space for the reply, the reply
	 * data will not exceed four words. */
	reply_p = cy_as_ll_create_response(dev_p, 4);
	if (reply_p == 0) {
		cy_as_ll_destroy_request(dev_p, req_p);
		return CY_AS_ERROR_OUT_OF_MEMORY;
	}

	cy_as_ll_request_response__set_word(req_p, 0,
		create_address(bus, (uint8_t)device, 0x00));
	cy_as_ll_request_response__set_word(req_p, 1,
		(uint16_t)((erase_unit >> 16) & 0xffff));
	cy_as_ll_request_response__set_word(req_p, 2,
		(uint16_t)(erase_unit & 0xffff));
	cy_as_ll_request_response__set_word(req_p, 3,
		(uint16_t)((num_erase_units >> 8) & 0x00ff));
	cy_as_ll_request_response__set_word(req_p, 4,
		(uint16_t)((num_erase_units << 8) & 0xff00));

	if (cb == 0) {
		ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		ret = my_handle_response_no_data(dev_p, req_p, reply_p);

		/* If error = "invalid response", this (very likely) means
		 * that we are not using the SD-only firmware module which
		 * is the only one supporting storage_erase. in this case
		 * force a "non supported" error code */
		if (ret == CY_AS_ERROR_INVALID_RESPONSE)
			ret = CY_AS_ERROR_NOT_SUPPORTED;

		return ret;
	} else {
		ret = cy_as_misc_send_request(dev_p, cb, client,
			CY_FUNCT_CB_STOR_ERASE, 0, dev_p->func_cbs_stor,
			CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
			cy_as_storage_func_callback);

		if (ret != CY_AS_ERROR_SUCCESS)
			goto destroy;

		/* The request and response are freed
		 * as part of the FuncCallback */
		return ret;
	}

destroy:
	cy_as_ll_destroy_request(dev_p, req_p);
	cy_as_ll_destroy_response(dev_p, reply_p);

	return ret;
}

static void
cy_as_storage_func_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 stat)
{
	cy_as_func_c_b_node *node = (cy_as_func_c_b_node *)
		dev_p->func_cbs_stor->head_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;

	cy_bool	ex_request = (rqt->flags & CY_AS_REQUEST_RESPONSE_EX)
			== CY_AS_REQUEST_RESPONSE_EX;
	cy_bool	ms_request = (rqt->flags & CY_AS_REQUEST_RESPONSE_MS)
			== CY_AS_REQUEST_RESPONSE_MS;
	uint8_t	code;
	uint8_t	cntxt;

	cy_as_hal_assert(ex_request || ms_request);
	cy_as_hal_assert(dev_p->func_cbs_stor->count != 0);
	cy_as_hal_assert(dev_p->func_cbs_stor->type == CYAS_FUNC_CB);
	(void) ex_request;
	(void) ms_request;

	(void)context;

	cntxt = cy_as_ll_request_response__get_context(rqt);
	cy_as_hal_assert(cntxt == CY_RQT_STORAGE_RQT_CONTEXT);

	code = cy_as_ll_request_response__get_code(rqt);
	switch (code) {
	case CY_RQT_START_STORAGE:
		ret = my_handle_response_storage_start(dev_p, rqt, resp, stat);
		break;
	case CY_RQT_STOP_STORAGE:
		ret = my_handle_response_storage_stop(dev_p, rqt, resp, stat);
		break;
	case CY_RQT_CLAIM_STORAGE:
		ret = my_handle_response_storage_claim(dev_p, rqt, resp);
		break;
	case CY_RQT_RELEASE_STORAGE:
		ret = my_handle_response_storage_release(dev_p, rqt, resp);
		break;
	case CY_RQT_QUERY_MEDIA:
		cy_as_hal_assert(cy_false);/* Not used any more. */
		break;
	case CY_RQT_QUERY_BUS:
		cy_as_hal_assert(node->data != 0);
		ret = my_handle_response_storage_query_bus(dev_p,
			rqt, resp, (uint32_t *)node->data);
		break;
	case CY_RQT_QUERY_DEVICE:
		cy_as_hal_assert(node->data != 0);
		ret = my_handle_response_storage_query_device(dev_p,
			rqt, resp, node->data);
		break;
	case CY_RQT_QUERY_UNIT:
		cy_as_hal_assert(node->data != 0);
		ret = my_handle_response_storage_query_unit(dev_p,
			rqt, resp, node->data);
		break;
	case CY_RQT_SD_INTERFACE_CONTROL:
		ret = my_handle_response_no_data(dev_p, rqt, resp);
		break;
	case CY_RQT_SD_REGISTER_READ:
		cy_as_hal_assert(node->data != 0);
		ret = my_handle_response_sd_reg_read(dev_p, rqt, resp,
			(cy_as_storage_sd_reg_read_data *)node->data);
		break;
	case CY_RQT_PARTITION_STORAGE:
		ret = my_handle_response_no_data(dev_p, rqt, resp);
		break;
	case CY_RQT_PARTITION_ERASE:
		ret = my_handle_response_no_data(dev_p, rqt, resp);
		break;
	case CY_RQT_GET_TRANSFER_AMOUNT:
		cy_as_hal_assert(node->data != 0);
		ret = my_handle_response_get_transfer_amount(dev_p,
			rqt, resp, (cy_as_m_s_c_progress_data *)node->data);
		break;
	case CY_RQT_ERASE:
		ret = my_handle_response_no_data(dev_p, rqt, resp);

		/* If error = "invalid response", this (very likely)
		 * means that we are not using the SD-only firmware
		 * module which is the only one supporting storage_erase.
		 * in this case force a "non supported" error code */
		if (ret == CY_AS_ERROR_INVALID_RESPONSE)
			ret = CY_AS_ERROR_NOT_SUPPORTED;

		break;

	default:
		ret = CY_AS_ERROR_INVALID_RESPONSE;
		cy_as_hal_assert(cy_false);
		break;
	}

	/*
	 * if the low level layer returns a direct error, use the
	 * corresponding error code. if not, use the error code
	 * based on the response from firmware.
	 */
	if (stat == CY_AS_ERROR_SUCCESS)
		stat = ret;

	/* Call the user callback, if there is one */
	if (node->cb_p)
		node->cb_p((cy_as_device_handle)dev_p, stat,
			node->client_data, node->data_type, node->data);
	cy_as_remove_c_b_node(dev_p->func_cbs_stor);
}


static void
cy_as_sdio_sync_reply_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;

	if ((cy_as_ll_request_response__get_code(resp) ==
	CY_RESP_SDIO_GET_TUPLE) ||
	(cy_as_ll_request_response__get_code(resp) ==
	CY_RESP_SDIO_EXT)) {
		ret = cy_as_ll_request_response__get_word(resp, 0);
		if ((ret & 0x00FF) != CY_AS_ERROR_SUCCESS) {
			if (cy_as_ll_request_response__get_code(rqt) ==
			CY_RQT_SDIO_READ_EXTENDED)
				cy_as_dma_cancel(dev_p,
					dev_p->storage_read_endpoint, ret);
			else
				cy_as_dma_cancel(dev_p,
					dev_p->storage_write_endpoint, ret);
		}
	} else {
		ret = CY_AS_ERROR_INVALID_RESPONSE;
	}

	dev_p->storage_rw_resp_p = resp;
	dev_p->storage_wait = cy_false;
	if (((ret & 0x00FF) == CY_AS_ERROR_IO_ABORTED) || ((ret & 0x00FF)
	== CY_AS_ERROR_IO_SUSPENDED))
		dev_p->storage_error =  (ret & 0x00FF);
	else
		dev_p->storage_error = (ret & 0x00FF) ?
		CY_AS_ERROR_INVALID_RESPONSE : CY_AS_ERROR_SUCCESS;

	/* Wake any threads/processes that are waiting on
	 * the read/write completion. */
	cy_as_hal_wake(&dev_p->context[context]->channel);
}

cy_as_return_status_t
cy_as_sdio_device_check(
		cy_as_device *dev_p,
		cy_as_bus_number_t	 bus,
		uint32_t			device)
{
	if (!dev_p || (dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
		return CY_AS_ERROR_INVALID_HANDLE;

	if (bus < 0 || bus >= CY_AS_MAX_BUSES)
		return CY_AS_ERROR_NO_SUCH_BUS;

	if (device >= CY_AS_MAX_STORAGE_DEVICES)
		return CY_AS_ERROR_NO_SUCH_DEVICE;

	if (!cy_as_device_is_astoria_dev(dev_p))
		return CY_AS_ERROR_NOT_SUPPORTED;

	return  (is_storage_active(dev_p));
}

cy_as_return_status_t
cy_as_sdio_direct_io(
		cy_as_device_handle	handle,
		cy_as_bus_number_t	 bus,
		uint32_t			device,
		uint8_t			 n_function_no,
		uint32_t			address,
		uint8_t			 misc_buf,
		uint16_t			argument,
		uint8_t			 is_write,
		uint8_t *data_p)
{
	cy_as_ll_request_response *req_p , *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	uint16_t resp_data;

	/*
	 * sanity checks required before sending the request to the
	 * firmware.
	 */
	cy_as_device *dev_p = (cy_as_device *)handle;
	ret = cy_as_sdio_device_check(dev_p, bus, device);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;


	if (!(cy_as_sdio_check_function_initialized(handle,
		bus, n_function_no)))
		return CY_AS_ERROR_INVALID_FUNCTION;
	if (cy_as_sdio_check_function_suspended(handle, bus, n_function_no))
		return CY_AS_ERROR_FUNCTION_SUSPENDED;

	req_p = cy_as_ll_create_request(dev_p, (is_write == cy_true) ?
		CY_RQT_SDIO_WRITE_DIRECT : CY_RQT_SDIO_READ_DIRECT,
			CY_RQT_STORAGE_RQT_CONTEXT, 3);
	if (req_p == 0)
		return CY_AS_ERROR_OUT_OF_MEMORY;

	/*Setting up request*/

	cy_as_ll_request_response__set_word(req_p, 0,
		create_address(bus, (uint8_t)device, n_function_no));
	/* D1 */
	if (is_write == cy_true) {
		cy_as_ll_request_response__set_word(req_p, 1,
			((argument<<8) | 0x0080 | (n_function_no<<4) |
			((misc_buf&CY_SDIO_RAW)<<3) |
			((misc_buf&CY_SDIO_REARM_INT)>>5) |
			(uint16_t)(address>>15)));
	} else {
		cy_as_ll_request_response__set_word(req_p, 1,
			(n_function_no<<4) | ((misc_buf&CY_SDIO_REARM_INT)>>5) |
			(uint16_t)(address>>15));
	}
	/* D2 */
	cy_as_ll_request_response__set_word(req_p, 2,
		((uint16_t)((address&0x00007fff)<<1)));

	/*Create response*/
	reply_p = cy_as_ll_create_response(dev_p, 2);

	if (reply_p == 0) {
		cy_as_ll_destroy_request(dev_p, req_p);
		return CY_AS_ERROR_OUT_OF_MEMORY;
	}

	/*Sending the request*/
	ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
	if (ret != CY_AS_ERROR_SUCCESS)
		goto destroy;

	/*Check reply type*/
	if (cy_as_ll_request_response__get_code(reply_p) ==
	CY_RESP_SDIO_DIRECT) {
		resp_data = cy_as_ll_request_response__get_word(reply_p, 0);
		if (resp_data >> 8)
			ret = CY_AS_ERROR_INVALID_RESPONSE;
		else if (data_p != 0)
			*(uint8_t *)(data_p) = (uint8_t)(resp_data&0x00ff);
	} else {
		ret = CY_AS_ERROR_INVALID_RESPONSE;
	}

destroy:
	if (req_p != 0)
		cy_as_ll_destroy_request(dev_p, req_p);
	if (reply_p != 0)
		cy_as_ll_destroy_response(dev_p, reply_p);
	return ret;
}


cy_as_return_status_t
cy_as_sdio_direct_read(
		cy_as_device_handle handle,
		cy_as_bus_number_t bus,
		uint32_t device,
		uint8_t	n_function_no,
		uint32_t address,
		uint8_t	misc_buf,
		uint8_t *data_p)
{
	return cy_as_sdio_direct_io(handle, bus, device, n_function_no,
		address, misc_buf, 0x00, cy_false, data_p);
}

cy_as_return_status_t
cy_as_sdio_direct_write(
		cy_as_device_handle		handle,
		cy_as_bus_number_t		 bus,
		uint32_t				device,
		uint8_t				 n_function_no,
		uint32_t				address,
		uint8_t				 misc_buf,
		uint16_t				argument,
		uint8_t *data_p)
{
	return cy_as_sdio_direct_io(handle, bus, device, n_function_no,
		address, misc_buf, argument, cy_true, data_p);
}

/*Cmd53 IO*/
cy_as_return_status_t
cy_as_sdio_extended_i_o(
		cy_as_device_handle		handle,
		cy_as_bus_number_t		 bus,
		uint32_t				device,
		uint8_t				 n_function_no,
		uint32_t				address,
		uint8_t				 misc_buf,
		uint16_t				argument,
		uint8_t				 is_write,
		uint8_t *data_p ,
		uint8_t				 is_resume)
{
	cy_as_ll_request_response *req_p , *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	uint8_t resp_type;
	uint8_t reqtype;
	uint16_t resp_data;
	cy_as_context *ctxt_p;
	uint32_t  dmasize, loopcount = 200;
	cy_as_end_point_number_t ep;

	cy_as_device *dev_p = (cy_as_device *)handle;
	ret = cy_as_sdio_device_check(dev_p, bus, device);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	if (!(cy_as_sdio_check_function_initialized(handle,
		bus, n_function_no)))
		return CY_AS_ERROR_INVALID_FUNCTION;
	if (cy_as_sdio_check_function_suspended(handle, bus, n_function_no))
		return CY_AS_ERROR_FUNCTION_SUSPENDED;


	if ((cy_as_device_is_storage_async_pending(dev_p)) ||
	(dev_p->storage_wait))
		return CY_AS_ERROR_ASYNC_PENDING;

	/* Request for 0 bytes of blocks is returned as a success*/
	if (argument == 0)
		return CY_AS_ERROR_SUCCESS;

	/* Initialise the request to send to the West Bridge device. */
	if (is_write == cy_true) {
		reqtype = CY_RQT_SDIO_WRITE_EXTENDED;
		ep = dev_p->storage_write_endpoint;
	} else {
		reqtype = CY_RQT_SDIO_READ_EXTENDED;
		ep = dev_p->storage_read_endpoint;
	}

	req_p = dev_p->storage_rw_req_p;
	cy_as_ll_init_request(req_p, reqtype, CY_RQT_STORAGE_RQT_CONTEXT, 3);

	/* Initialise the space for reply from the Antioch. */
	reply_p = dev_p->storage_rw_resp_p;
	cy_as_ll_init_response(reply_p, 2);

	/* Setup the DMA request */
	if (!(misc_buf&CY_SDIO_BLOCKMODE)) {
		if (argument >
			dev_p->sdiocard[bus].
			function[n_function_no-1].blocksize)
			return CY_AS_ERROR_INVALID_BLOCKSIZE;

	} else {
		if (argument > 511)
			return CY_AS_ERROR_INVALID_BLOCKSIZE;
	}

	if (argument == 512)
		argument = 0;

	dmasize = ((misc_buf&CY_SDIO_BLOCKMODE) != 0) ?
		dev_p->sdiocard[bus].function[n_function_no-1].blocksize
		* argument : argument;

	ret = cy_as_dma_queue_request(dev_p, ep, (void *)(data_p),
		dmasize, cy_false, (is_write & cy_true) ? cy_false :
		cy_true, cy_as_sync_storage_callback);

	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	cy_as_ll_request_response__set_word(req_p, 0,
		create_address(bus, (uint8_t)device,
		n_function_no | ((is_resume) ? 0x80 : 0x00)));
	cy_as_ll_request_response__set_word(req_p, 1,
		((uint16_t)n_function_no)<<12|
		((uint16_t)(misc_buf & (CY_SDIO_BLOCKMODE|CY_SDIO_OP_INCR)))
		<< 9 | (uint16_t)(address >> 7) |
		((is_write == cy_true) ? 0x8000 : 0x0000));
	cy_as_ll_request_response__set_word(req_p, 2,
		((uint16_t)(address&0x0000ffff) << 9) |  argument);


	/* Send the request and wait for completion of storage request */
	dev_p->storage_wait = cy_true;
	ret = cy_as_ll_send_request(dev_p, req_p, reply_p,
		cy_true, cy_as_sdio_sync_reply_callback);

	if (ret != CY_AS_ERROR_SUCCESS) {
		cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_CANCELED);
	} else {
		/* Setup the DMA request */
		ctxt_p = dev_p->context[CY_RQT_STORAGE_RQT_CONTEXT];
		ret = cy_as_dma_drain_queue(dev_p, ep, cy_true);

		while (loopcount-- > 0) {
			if (dev_p->storage_wait == cy_false)
				break;
			cy_as_hal_sleep_on(&ctxt_p->channel, 10);
		}
		if (dev_p->storage_wait == cy_true) {
			dev_p->storage_wait = cy_false;
			cy_as_ll_remove_request(dev_p, ctxt_p, req_p, cy_true);
			dev_p->storage_error = CY_AS_ERROR_TIMEOUT;
		}

		ret = dev_p->storage_error;

		if (ret != CY_AS_ERROR_SUCCESS)
			return ret;

		resp_type = cy_as_ll_request_response__get_code(
			dev_p->storage_rw_resp_p);
		if (resp_type == CY_RESP_SDIO_EXT) {
			resp_data = cy_as_ll_request_response__get_word
				(reply_p, 0)&0x00ff;
			if (resp_data)
				ret = CY_AS_ERROR_INVALID_REQUEST;

		} else {
			ret = CY_AS_ERROR_INVALID_RESPONSE;
		}
	}
	return ret;

}

static void
cy_as_sdio_async_reply_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)
{
	cy_as_storage_callback cb_ms;
	uint8_t reqtype;
	uint32_t pendingblocks;
	(void)rqt;
	(void)context;

	pendingblocks = 0;
	reqtype = cy_as_ll_request_response__get_code(rqt);
	if (ret == CY_AS_ERROR_SUCCESS) {
		if ((cy_as_ll_request_response__get_code(resp) ==
		CY_RESP_SUCCESS_FAILURE) ||
		(cy_as_ll_request_response__get_code(resp) ==
		CY_RESP_SDIO_EXT)) {
			ret = cy_as_ll_request_response__get_word(resp, 0);
			ret &= 0x00FF;
		} else {
			ret = CY_AS_ERROR_INVALID_RESPONSE;
		}
	}

	if (ret != CY_AS_ERROR_SUCCESS) {
		if (reqtype == CY_RQT_SDIO_READ_EXTENDED)
			cy_as_dma_cancel(dev_p,
				dev_p->storage_read_endpoint, ret);
		else
			cy_as_dma_cancel(dev_p,
				dev_p->storage_write_endpoint, ret);

		dev_p->storage_error = ret;
	}

	dev_p->storage_wait = cy_false;

	/*
	 * if the DMA callback has already been called,
	 * the user callback has to be called from here.
	 */
	if (!cy_as_device_is_storage_async_pending(dev_p)) {
		cy_as_hal_assert(dev_p->storage_cb_ms != NULL);
		cb_ms = dev_p->storage_cb_ms;

		dev_p->storage_cb = 0;
		dev_p->storage_cb_ms = 0;

		if ((ret == CY_AS_ERROR_SUCCESS) ||
		(ret == CY_AS_ERROR_IO_ABORTED) ||
		(ret == CY_AS_ERROR_IO_SUSPENDED)) {
			ret = dev_p->storage_error;
			pendingblocks = ((uint32_t)
				cy_as_ll_request_response__get_word
				(resp, 1)) << 16;
		} else
			ret = CY_AS_ERROR_INVALID_RESPONSE;

		cb_ms((cy_as_device_handle)dev_p, dev_p->storage_bus_index,
			dev_p->storage_device_index,
			(dev_p->storage_unit | pendingblocks),
			dev_p->storage_block_addr, dev_p->storage_oper, ret);
	} else
		dev_p->storage_error = ret;
}


cy_as_return_status_t
cy_as_sdio_extended_i_o_async(
		cy_as_device_handle			handle,
		cy_as_bus_number_t			 bus,
		uint32_t					device,
		uint8_t					 n_function_no,
		uint32_t					address,
		uint8_t					 misc_buf,
		uint16_t					argument,
		uint8_t					 is_write,
		uint8_t					*data_p,
		cy_as_storage_callback	   callback)
{

	uint32_t mask;
	uint32_t dmasize;
	cy_as_ll_request_response *req_p , *reply_p;
	uint8_t reqtype;
	cy_as_end_point_number_t ep;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	cy_as_device *dev_p = (cy_as_device *)handle;

	ret = cy_as_sdio_device_check(dev_p, bus, device);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	if (!(cy_as_sdio_check_function_initialized(handle,
		bus, n_function_no)))
		return CY_AS_ERROR_INVALID_FUNCTION;
	if (cy_as_sdio_check_function_suspended(handle, bus, n_function_no))
		return CY_AS_ERROR_FUNCTION_SUSPENDED;

	if (callback == 0)
		return CY_AS_ERROR_NULL_CALLBACK;

	/* We are supposed to return sucess if the number of
	 * blocks is zero
	 */
	if (((misc_buf&CY_SDIO_BLOCKMODE) != 0) && (argument == 0)) {
		callback(handle, bus, device, n_function_no, address,
			((is_write) ? cy_as_op_write : cy_as_op_read),
			CY_AS_ERROR_SUCCESS);
		return CY_AS_ERROR_SUCCESS;
	}


	/*
	 * since async operations can be triggered by interrupt
	 * code, we must insure that we do not get multiple async
	 * operations going at one time and protect this test and
	 * set operation from interrupts.
	 */
	mask = cy_as_hal_disable_interrupts();
	if ((cy_as_device_is_storage_async_pending(dev_p)) ||
	(dev_p->storage_wait)) {
		cy_as_hal_enable_interrupts(mask);
		return CY_AS_ERROR_ASYNC_PENDING;
	}
	cy_as_device_set_storage_async_pending(dev_p);
	cy_as_hal_enable_interrupts(mask);


	/*
	 * storage information about the currently
	 * outstanding request
	 */
	dev_p->storage_cb_ms = callback;
	dev_p->storage_bus_index = bus;
	dev_p->storage_device_index = device;
	dev_p->storage_unit = n_function_no;
	dev_p->storage_block_addr = address;

	if (is_write == cy_true) {
		reqtype = CY_RQT_SDIO_WRITE_EXTENDED;
		ep = dev_p->storage_write_endpoint;
	} else {
		reqtype = CY_RQT_SDIO_READ_EXTENDED;
		ep = dev_p->storage_read_endpoint;
	}

	/* Initialise the request to send to the West Bridge. */
	req_p = dev_p->storage_rw_req_p;
	cy_as_ll_init_request(req_p, reqtype,
		CY_RQT_STORAGE_RQT_CONTEXT, 3);

	/* Initialise the space for reply from the West Bridge. */
	reply_p = dev_p->storage_rw_resp_p;
	cy_as_ll_init_response(reply_p, 2);

	if (!(misc_buf&CY_SDIO_BLOCKMODE)) {
		if (argument >
		dev_p->sdiocard[bus].function[n_function_no-1].blocksize)
			return CY_AS_ERROR_INVALID_BLOCKSIZE;

	} else {
		if (argument > 511)
			return CY_AS_ERROR_INVALID_BLOCKSIZE;
	}

	if (argument == 512)
		argument = 0;
	dmasize = ((misc_buf&CY_SDIO_BLOCKMODE) != 0) ?
		dev_p->sdiocard[bus].function[n_function_no-1].blocksize *
		argument : argument;

	/* Setup the DMA request and adjust the storage
	 * operation if we are reading */
	if (reqtype == CY_RQT_SDIO_READ_EXTENDED) {
		ret = cy_as_dma_queue_request(dev_p, ep,
			(void *)data_p, dmasize , cy_false, cy_true,
			cy_as_async_storage_callback);
		dev_p->storage_oper = cy_as_op_read;
	} else if (reqtype == CY_RQT_SDIO_WRITE_EXTENDED) {
		ret = cy_as_dma_queue_request(dev_p, ep, (void *)data_p,
		dmasize, cy_false, cy_false, cy_as_async_storage_callback);
		dev_p->storage_oper = cy_as_op_write;
	}

	if (ret != CY_AS_ERROR_SUCCESS) {
		cy_as_device_clear_storage_async_pending(dev_p);
		return ret;
	}

	cy_as_ll_request_response__set_word(req_p, 0,
		create_address(bus, (uint8_t)device, n_function_no));
	cy_as_ll_request_response__set_word(req_p, 1,
		((uint16_t)n_function_no) << 12 |
		((uint16_t)(misc_buf & (CY_SDIO_BLOCKMODE | CY_SDIO_OP_INCR)))
		<< 9 | (uint16_t)(address>>7) |
		((is_write == cy_true) ? 0x8000 : 0x0000));
	cy_as_ll_request_response__set_word(req_p, 2,
		((uint16_t)(address&0x0000ffff) << 9) |  argument);


	/* Send the request and wait for completion of storage request */
	dev_p->storage_wait = cy_true;
	ret = cy_as_ll_send_request(dev_p, req_p, reply_p, cy_true,
		cy_as_sdio_async_reply_callback);
	if (ret != CY_AS_ERROR_SUCCESS) {
		cy_as_dma_cancel(dev_p, ep, CY_AS_ERROR_CANCELED);
		cy_as_device_clear_storage_async_pending(dev_p);
	} else {
		cy_as_dma_kick_start(dev_p, ep);
	}

	return ret;
}

/* CMD53 Extended Read*/
cy_as_return_status_t
cy_as_sdio_extended_read(
		cy_as_device_handle			handle,
		cy_as_bus_number_t			 bus,
		uint32_t					device,
		uint8_t					 n_function_no,
		uint32_t					address,
		uint8_t					 misc_buf,
		uint16_t					argument,
		uint8_t					*data_p,
		cy_as_sdio_callback			callback)
{
	if (callback == 0)
		return cy_as_sdio_extended_i_o(handle, bus, device,
			n_function_no, address, misc_buf, argument,
			cy_false, data_p, 0);

	return cy_as_sdio_extended_i_o_async(handle, bus, device,
		n_function_no, address, misc_buf, argument, cy_false,
		data_p, callback);
}

/* CMD53 Extended Write*/
cy_as_return_status_t
cy_as_sdio_extended_write(
		cy_as_device_handle			handle,
		cy_as_bus_number_t			 bus,
		uint32_t					device,
		uint8_t					 n_function_no,
		uint32_t					address,
		uint8_t					 misc_buf,
		uint16_t					argument,
		uint8_t					*data_p,
		cy_as_sdio_callback			callback)
{
	if (callback == 0)
		return cy_as_sdio_extended_i_o(handle, bus, device,
			n_function_no, address, misc_buf, argument, cy_true,
			data_p, 0);

	return cy_as_sdio_extended_i_o_async(handle, bus, device,
		n_function_no, address, misc_buf, argument, cy_true,
		data_p, callback);
}


/* Read the CIS info tuples for the given function and Tuple ID*/
cy_as_return_status_t
cy_as_sdio_get_c_i_s_info(
		cy_as_device_handle			handle,
		cy_as_bus_number_t			 bus,
		uint32_t					device,
		uint8_t					 n_function_no,
		uint16_t					tuple_id,
		uint8_t					*data_p)
{

	cy_as_ll_request_response *req_p , *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	uint16_t resp_data;
	cy_as_context *ctxt_p;
	uint32_t loopcount = 200;

	cy_as_device *dev_p = (cy_as_device *)handle;

	ret = cy_as_sdio_device_check(dev_p, bus, device);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	if (!(cy_as_sdio_check_function_initialized(handle, bus, 0)))
		return CY_AS_ERROR_INVALID_FUNCTION;

	if ((cy_as_device_is_storage_async_pending(dev_p)) ||
	(dev_p->storage_wait))
		return CY_AS_ERROR_ASYNC_PENDING;


	/* Initialise the request to send to the Antioch. */
	req_p = dev_p->storage_rw_req_p;
	cy_as_ll_init_request(req_p, CY_RQT_SDIO_GET_TUPLE,
		CY_RQT_STORAGE_RQT_CONTEXT, 2);

	/* Initialise the space for reply from the Antioch. */
	reply_p = dev_p->storage_rw_resp_p;
	cy_as_ll_init_response(reply_p, 3);

	/* Setup the DMA request */
	ret = cy_as_dma_queue_request(dev_p, dev_p->storage_read_endpoint,
		data_p+1, 255, cy_false, cy_true, cy_as_sync_storage_callback);

	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	cy_as_ll_request_response__set_word(req_p, 0,
		create_address(bus, (uint8_t)device, n_function_no));

	/* Set tuple id to fetch. */
	cy_as_ll_request_response__set_word(req_p, 1, tuple_id<<8);

	/* Send the request and wait for completion of storage request */
	dev_p->storage_wait = cy_true;
	ret = cy_as_ll_send_request(dev_p, req_p, reply_p, cy_true,
		cy_as_sdio_sync_reply_callback);

	if (ret != CY_AS_ERROR_SUCCESS) {
		cy_as_dma_cancel(dev_p,
			dev_p->storage_read_endpoint, CY_AS_ERROR_CANCELED);
	} else {
		/* Setup the DMA request */
		ctxt_p = dev_p->context[CY_RQT_STORAGE_RQT_CONTEXT];
		ret = cy_as_dma_drain_queue(dev_p,
			dev_p->storage_read_endpoint, cy_true);

		while (loopcount-- > 0) {
			if (dev_p->storage_wait == cy_false)
				break;
			cy_as_hal_sleep_on(&ctxt_p->channel, 10);
		}

		if (dev_p->storage_wait == cy_true) {
			dev_p->storage_wait = cy_false;
			cy_as_ll_remove_request(dev_p, ctxt_p, req_p, cy_true);
			return CY_AS_ERROR_TIMEOUT;
		}
		ret = dev_p->storage_error;

		if (ret != CY_AS_ERROR_SUCCESS)
			return ret;

		if (cy_as_ll_request_response__get_code
		(dev_p->storage_rw_resp_p) == CY_RESP_SDIO_GET_TUPLE) {
			resp_data = cy_as_ll_request_response__get_word
				(reply_p, 0);
			if (resp_data) {
				ret = CY_AS_ERROR_INVALID_REQUEST;
			} else if (data_p != 0)
				*(uint8_t *)data_p = (uint8_t)
					(cy_as_ll_request_response__get_word
						(reply_p, 0)&0x00ff);
		} else {
			ret = CY_AS_ERROR_INVALID_RESPONSE;
		}
	}
	return ret;
}

/*Query Device*/
cy_as_return_status_t
cy_as_sdio_query_card(
		cy_as_device_handle handle,
		cy_as_bus_number_t bus,
		uint32_t device,
		cy_as_sdio_card *data_p)
{
	cy_as_ll_request_response *req_p , *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;

	uint8_t resp_type;
	cy_as_device *dev_p = (cy_as_device *)handle;

	ret = cy_as_sdio_device_check(dev_p, bus, device);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	/* Allocating memory to the SDIO device structure in dev_p */

	cy_as_hal_mem_set(&dev_p->sdiocard[bus], 0, sizeof(cy_as_sdio_device));

	req_p = cy_as_ll_create_request(dev_p, CY_RQT_SDIO_QUERY_CARD,
		CY_RQT_STORAGE_RQT_CONTEXT, 1);
	if (req_p == 0)
		return CY_AS_ERROR_OUT_OF_MEMORY;

	cy_as_ll_request_response__set_word(req_p, 0,
		create_address(bus, (uint8_t)device, 0));

	reply_p = cy_as_ll_create_response(dev_p, 5);
	if (reply_p == 0) {
		cy_as_ll_destroy_request(dev_p, req_p);
		return CY_AS_ERROR_OUT_OF_MEMORY;
	}

	ret = cy_as_ll_send_request_wait_reply(dev_p,
		req_p, reply_p);

	if (ret != CY_AS_ERROR_SUCCESS)
		goto destroy;

	resp_type = cy_as_ll_request_response__get_code(reply_p);
	if (resp_type == CY_RESP_SDIO_QUERY_CARD) {
		dev_p->sdiocard[bus].card.num_functions	=
			(uint8_t)((reply_p->data[0]&0xff00)>>8);
		dev_p->sdiocard[bus].card.memory_present =
			(uint8_t)reply_p->data[0]&0x0001;
		dev_p->sdiocard[bus].card.manufacturer__id =
			reply_p->data[1];
		dev_p->sdiocard[bus].card.manufacturer_info =
			reply_p->data[2];
		dev_p->sdiocard[bus].card.blocksize =
			reply_p->data[3];
		dev_p->sdiocard[bus].card.maxblocksize =
			reply_p->data[3];
		dev_p->sdiocard[bus].card.card_capability =
			(uint8_t)((reply_p->data[4]&0xff00)>>8);
		dev_p->sdiocard[bus].card.sdio_version =
			(uint8_t)(reply_p->data[4]&0x00ff);
		dev_p->sdiocard[bus].function_init_map = 0x01;
		data_p->num_functions =
			dev_p->sdiocard[bus].card.num_functions;
		data_p->memory_present =
			dev_p->sdiocard[bus].card.memory_present;
		data_p->manufacturer__id =
			dev_p->sdiocard[bus].card.manufacturer__id;
		data_p->manufacturer_info =
			dev_p->sdiocard[bus].card.manufacturer_info;
		data_p->blocksize = dev_p->sdiocard[bus].card.blocksize;
		data_p->maxblocksize =
			dev_p->sdiocard[bus].card.maxblocksize;
		data_p->card_capability	=
			dev_p->sdiocard[bus].card.card_capability;
		data_p->sdio_version =
			dev_p->sdiocard[bus].card.sdio_version;
	} else {
		if (resp_type == CY_RESP_SUCCESS_FAILURE)
			ret = cy_as_ll_request_response__get_word(reply_p, 0);
		else
			ret = CY_AS_ERROR_INVALID_RESPONSE;
	}
destroy:
	if (req_p != 0)
		cy_as_ll_destroy_request(dev_p, req_p);
	if (reply_p != 0)
		cy_as_ll_destroy_response(dev_p, reply_p);
	return ret;
}

/*Reset SDIO card. */
cy_as_return_status_t
cy_as_sdio_reset_card(
		cy_as_device_handle			handle,
		cy_as_bus_number_t		 bus,
		uint32_t				device)
{

	cy_as_ll_request_response *req_p , *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	uint8_t resp_type;
	cy_as_device *dev_p = (cy_as_device *)handle;

	ret = cy_as_sdio_device_check(dev_p, bus, device);

	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	if (dev_p->sdiocard != 0) {
		dev_p->sdiocard[bus].function_init_map = 0;
		dev_p->sdiocard[bus].function_suspended_map = 0;
	}

	req_p = cy_as_ll_create_request(dev_p, CY_RQT_SDIO_RESET_DEV,
		CY_RQT_STORAGE_RQT_CONTEXT, 1);

	if (req_p == 0)
		return CY_AS_ERROR_OUT_OF_MEMORY;

	/*Setup mailbox */
	cy_as_ll_request_response__set_word(req_p, 0,
		create_address(bus, (uint8_t)device, 0));

	reply_p = cy_as_ll_create_response(dev_p, 2);
	if (reply_p == 0) {
		cy_as_ll_destroy_request(dev_p, req_p);
		return CY_AS_ERROR_OUT_OF_MEMORY;
	}

	ret = cy_as_ll_send_request_wait_reply(dev_p,
		req_p, reply_p);

	if (ret != CY_AS_ERROR_SUCCESS)
		goto destroy;

	resp_type = cy_as_ll_request_response__get_code(reply_p);

	if (resp_type == CY_RESP_SUCCESS_FAILURE) {
		ret = cy_as_ll_request_response__get_word(reply_p, 0);
		if (ret == CY_AS_ERROR_SUCCESS)
			ret = cy_as_sdio_query_card(handle, bus, device, 0);
	} else
		ret = CY_AS_ERROR_INVALID_RESPONSE;

destroy:
	if (req_p != 0)
		cy_as_ll_destroy_request(dev_p, req_p);
	if (reply_p != 0)
		cy_as_ll_destroy_response(dev_p, reply_p);
	return ret;
}

/* Initialise an IO function*/
cy_as_return_status_t
cy_as_sdio_init_function(
		cy_as_device_handle			handle,
		cy_as_bus_number_t			 bus,
		uint32_t					device,
		uint8_t					 n_function_no,
		uint8_t					 misc_buf)
{
	cy_as_ll_request_response *req_p , *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	uint8_t resp_type;
	cy_as_device *dev_p = (cy_as_device *)handle;

	ret = cy_as_sdio_device_check(dev_p, bus, device);

	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	if (!(cy_as_sdio_check_function_initialized
		(handle, bus, 0)))
		return CY_AS_ERROR_NOT_RUNNING;

	if ((cy_as_sdio_check_function_initialized
	(handle, bus, n_function_no))) {
		if (misc_buf&CY_SDIO_FORCE_INIT)
			dev_p->sdiocard[bus].function_init_map &=
				(~(1 << n_function_no));
		else
			return CY_AS_ERROR_ALREADY_RUNNING;
	}

	req_p = cy_as_ll_create_request(dev_p,
		CY_RQT_SDIO_INIT_FUNCTION, CY_RQT_STORAGE_RQT_CONTEXT, 1);
	if (req_p == 0)
		return CY_AS_ERROR_OUT_OF_MEMORY;

	cy_as_ll_request_response__set_word(req_p, 0,
		create_address(bus, (uint8_t)device, n_function_no));

	reply_p = cy_as_ll_create_response(dev_p, 5);
	if (reply_p == 0) {
		cy_as_ll_destroy_request(dev_p, req_p);
		return CY_AS_ERROR_OUT_OF_MEMORY;
	}

	ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);

	if (ret != CY_AS_ERROR_SUCCESS)
		goto destroy;

	resp_type = cy_as_ll_request_response__get_code(reply_p);

	if (resp_type == CY_RESP_SDIO_INIT_FUNCTION) {
		dev_p->sdiocard[bus].function[n_function_no-1].function_code =
			(uint8_t)((reply_p->data[0]&0xff00)>>8);
		dev_p->sdiocard[bus].function[n_function_no-1].
			extended_func_code = (uint8_t)reply_p->data[0]&0x00ff;
		dev_p->sdiocard[bus].function[n_function_no-1].blocksize =
			reply_p->data[1];
		dev_p->sdiocard[bus].function[n_function_no-1].
			maxblocksize = reply_p->data[1];
		dev_p->sdiocard[bus].function[n_function_no-1].card_psn	=
			(uint32_t)(reply_p->data[2])<<16;
		dev_p->sdiocard[bus].function[n_function_no-1].card_psn |=
			(uint32_t)(reply_p->data[3]);
		dev_p->sdiocard[bus].function[n_function_no-1].csa_bits =
			(uint8_t)((reply_p->data[4]&0xff00)>>8);
		dev_p->sdiocard[bus].function[n_function_no-1].wakeup_support =
			(uint8_t)(reply_p->data[4]&0x0001);
		dev_p->sdiocard[bus].function_init_map |= (1 << n_function_no);
		cy_as_sdio_clear_function_suspended(handle, bus, n_function_no);

	} else {
		if (resp_type == CY_RESP_SUCCESS_FAILURE)
			ret = cy_as_ll_request_response__get_word(reply_p, 0);
		else
			ret = CY_AS_ERROR_INVALID_FUNCTION;
	}

destroy:
	if (req_p != 0)
		cy_as_ll_destroy_request(dev_p, req_p);
	if (reply_p != 0)
		cy_as_ll_destroy_response(dev_p, reply_p);
	return ret;
}

/*Query individual functions. */
cy_as_return_status_t
cy_as_sdio_query_function(
		cy_as_device_handle			handle,
		cy_as_bus_number_t			 bus,
		uint32_t					device,
		uint8_t					 n_function_no,
		cy_as_sdio_func			*data_p)
{
	cy_as_device *dev_p = (cy_as_device *)handle;
	cy_as_return_status_t ret;

	ret = cy_as_sdio_device_check(dev_p, bus, device);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	if (!(cy_as_sdio_check_function_initialized(handle,
		bus, n_function_no)))
		return CY_AS_ERROR_INVALID_FUNCTION;

	data_p->blocksize =
		dev_p->sdiocard[bus].function[n_function_no-1].blocksize;
	data_p->card_psn =
		dev_p->sdiocard[bus].function[n_function_no-1].card_psn;
	data_p->csa_bits =
		dev_p->sdiocard[bus].function[n_function_no-1].csa_bits;
	data_p->extended_func_code =
		dev_p->sdiocard[bus].function[n_function_no-1].
		extended_func_code;
	data_p->function_code =
		dev_p->sdiocard[bus].function[n_function_no-1].function_code;
	data_p->maxblocksize =
		dev_p->sdiocard[bus].function[n_function_no-1].maxblocksize;
	data_p->wakeup_support =
		dev_p->sdiocard[bus].function[n_function_no-1].wakeup_support;

	return CY_AS_ERROR_SUCCESS;
}

/* Abort the Current Extended IO Operation*/
cy_as_return_status_t
cy_as_sdio_abort_function(
		cy_as_device_handle			handle,
		cy_as_bus_number_t			 bus,
		uint32_t					device,
		uint8_t					 n_function_no)
{
	cy_as_ll_request_response *req_p , *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	uint8_t resp_type;
	cy_as_device *dev_p = (cy_as_device *)handle;

	ret = cy_as_sdio_device_check(dev_p, bus, device);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	if (!(cy_as_sdio_check_function_initialized(handle,
		bus, n_function_no)))
		return CY_AS_ERROR_INVALID_FUNCTION;

	if ((cy_as_device_is_storage_async_pending(dev_p)) ||
	(dev_p->storage_wait)) {
		if (!(cy_as_sdio_get_card_capability(handle, bus) &
		CY_SDIO_SDC))
			return CY_AS_ERROR_INVALID_COMMAND;
	}

	req_p = cy_as_ll_create_request(dev_p, CY_RQT_SDIO_ABORT_IO,
		CY_RQT_GENERAL_RQT_CONTEXT, 1);

	if (req_p == 0)
		return CY_AS_ERROR_OUT_OF_MEMORY;

	/*Setup mailbox */
	cy_as_ll_request_response__set_word(req_p, 0,
		create_address(bus, (uint8_t)device, n_function_no));

	reply_p = cy_as_ll_create_response(dev_p, 2);
	if (reply_p == 0) {
		cy_as_ll_destroy_request(dev_p, req_p);
		return CY_AS_ERROR_OUT_OF_MEMORY;
	}

	ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);
	if (ret != CY_AS_ERROR_SUCCESS)
		goto destroy;

	resp_type = cy_as_ll_request_response__get_code(reply_p);

	if (resp_type == CY_RESP_SUCCESS_FAILURE)
		ret = cy_as_ll_request_response__get_word(reply_p, 0);
	else
		ret = CY_AS_ERROR_INVALID_RESPONSE;


destroy:
	if (req_p != 0)
		cy_as_ll_destroy_request(dev_p, req_p);
	if (reply_p != 0)
		cy_as_ll_destroy_response(dev_p, reply_p);
	return ret;
}

/* Suspend IO to current function*/
cy_as_return_status_t
cy_as_sdio_suspend(
		cy_as_device_handle		handle,
		cy_as_bus_number_t		 bus,
		uint32_t				device,
		uint8_t				 n_function_no)
{
	cy_as_ll_request_response *req_p , *reply_p;
	cy_as_return_status_t ret = CY_AS_ERROR_SUCCESS;
	cy_as_device *dev_p = (cy_as_device *)handle;

	ret = cy_as_sdio_device_check(dev_p, bus, device);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	if (!(cy_as_sdio_check_function_initialized(handle, bus,
		n_function_no)))
		return CY_AS_ERROR_INVALID_FUNCTION;
	if (!(cy_as_sdio_check_support_bus_suspend(handle, bus)))
		return CY_AS_ERROR_INVALID_FUNCTION;
	if (!(cy_as_sdio_get_card_capability(handle, bus) & CY_SDIO_SDC))
		return CY_AS_ERROR_INVALID_FUNCTION;
	if (cy_as_sdio_check_function_suspended(handle, bus, n_function_no))
		return CY_AS_ERROR_FUNCTION_SUSPENDED;

	req_p = cy_as_ll_create_request(dev_p,
		CY_RQT_SDIO_SUSPEND, CY_RQT_GENERAL_RQT_CONTEXT, 1);
	if (req_p == 0)
		return CY_AS_ERROR_OUT_OF_MEMORY;

	/*Setup mailbox */
	cy_as_ll_request_response__set_word(req_p, 0,
		create_address(bus, (uint8_t)device, n_function_no));

	reply_p = cy_as_ll_create_response(dev_p, 2);
	if (reply_p == 0) {
		cy_as_ll_destroy_request(dev_p, req_p);
		return CY_AS_ERROR_OUT_OF_MEMORY;
	}
	ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);

	if (ret == CY_AS_ERROR_SUCCESS) {
		ret = cy_as_ll_request_response__get_code(reply_p);
		cy_as_sdio_set_function_suspended(handle, bus, n_function_no);
	}

	if (req_p != 0)
		cy_as_ll_destroy_request(dev_p, req_p);
	if (reply_p != 0)
		cy_as_ll_destroy_response(dev_p, reply_p);

	return ret;
}

/*Resume suspended function*/
cy_as_return_status_t
cy_as_sdio_resume(
		cy_as_device_handle		handle,
		cy_as_bus_number_t		 bus,
		uint32_t				device,
		uint8_t				 n_function_no,
		cy_as_oper_type			op,
		uint8_t				 misc_buf,
		uint16_t				pendingblockcount,
		uint8_t				 *data_p
		)
{
	cy_as_ll_request_response *req_p , *reply_p;
	cy_as_return_status_t resp_data, ret = CY_AS_ERROR_SUCCESS;
	cy_as_device *dev_p = (cy_as_device *)handle;

	ret = cy_as_sdio_device_check(dev_p, bus, device);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	if (!(cy_as_sdio_check_function_initialized
	(handle, bus, n_function_no)))
		return CY_AS_ERROR_INVALID_FUNCTION;

	/* If suspend resume is not supported return */
	if (!(cy_as_sdio_check_support_bus_suspend(handle, bus)))
		return CY_AS_ERROR_INVALID_FUNCTION;

	/* if the function is not suspended return. */
	if (!(cy_as_sdio_check_function_suspended
	(handle, bus, n_function_no)))
		return CY_AS_ERROR_INVALID_FUNCTION;

	req_p = cy_as_ll_create_request(dev_p,
		CY_RQT_SDIO_RESUME, CY_RQT_STORAGE_RQT_CONTEXT, 1);
	if (req_p == 0)
		return CY_AS_ERROR_OUT_OF_MEMORY;

	/*Setup mailbox */
	cy_as_ll_request_response__set_word(req_p, 0,
		create_address(bus, (uint8_t)device, n_function_no));

	reply_p = cy_as_ll_create_response(dev_p, 2);
	if (reply_p == 0) {
		cy_as_ll_destroy_request(dev_p, req_p);
		return CY_AS_ERROR_OUT_OF_MEMORY;
	}
	ret = cy_as_ll_send_request_wait_reply(dev_p, req_p, reply_p);

	if (ret != CY_AS_ERROR_SUCCESS)
		goto destroy;

	if (cy_as_ll_request_response__get_code(reply_p) ==
	CY_RESP_SDIO_RESUME) {
		resp_data = cy_as_ll_request_response__get_word(reply_p, 0);
		if (resp_data & 0x00ff) {
			/* Send extended read request to resume the read. */
			if (op == cy_as_op_read) {
				ret = cy_as_sdio_extended_i_o(handle, bus,
					device, n_function_no, 0, misc_buf,
					pendingblockcount, cy_false, data_p, 1);
			} else {
				ret = cy_as_sdio_extended_i_o(handle, bus,
					device, n_function_no, 0, misc_buf,
					pendingblockcount, cy_true, data_p, 1);
			}
		} else {
			ret = CY_AS_ERROR_SUCCESS;
		}
	} else {
		ret = CY_AS_ERROR_INVALID_RESPONSE;
	}

destroy:
	cy_as_sdio_clear_function_suspended(handle, bus, n_function_no);
	if (req_p != 0)
		cy_as_ll_destroy_request(dev_p, req_p);
	if (reply_p != 0)
		cy_as_ll_destroy_response(dev_p, reply_p);
	return ret;

}

/*Set function blocksize. Size cannot exceed max
 * block size for the function*/
cy_as_return_status_t
cy_as_sdio_set_blocksize(
		cy_as_device_handle			handle,
		cy_as_bus_number_t			 bus,
		uint32_t					device,
		uint8_t					 n_function_no,
		uint16_t					blocksize)
{
	cy_as_return_status_t ret;
	cy_as_device *dev_p = (cy_as_device *)handle;
	ret = cy_as_sdio_device_check(dev_p, bus, device);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	if (!(cy_as_sdio_check_function_initialized
	(handle, bus, n_function_no)))
		return CY_AS_ERROR_INVALID_FUNCTION;
	if (n_function_no == 0) {
		if (blocksize > cy_as_sdio_get_card_max_blocksize(handle, bus))
			return CY_AS_ERROR_INVALID_BLOCKSIZE;
		else if (blocksize == cy_as_sdio_get_card_blocksize
			(handle, bus))
			return CY_AS_ERROR_SUCCESS;
	} else {
		if (blocksize >
			cy_as_sdio_get_function_max_blocksize(handle,
				bus, n_function_no))
			return CY_AS_ERROR_INVALID_BLOCKSIZE;
		else if (blocksize ==
			cy_as_sdio_get_function_blocksize(handle,
				bus, n_function_no))
			return CY_AS_ERROR_SUCCESS;
	}

	ret = cy_as_sdio_direct_write(handle, bus, device, 0,
		(uint16_t)(n_function_no << 8) |
		0x10, 0, blocksize & 0x00ff, 0);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	ret = cy_as_sdio_direct_write(handle, bus, device, 0,
		(uint16_t)(n_function_no << 8) |
		0x11, 0, (blocksize & 0xff00) >> 8, 0);

	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	if (n_function_no == 0)
		cy_as_sdio_set_card_block_size(handle, bus, blocksize);
	else
		cy_as_sdio_set_function_block_size(handle,
			bus, n_function_no, blocksize);
	return ret;
}

/* Deinitialize an SDIO function*/
cy_as_return_status_t
cy_as_sdio_de_init_function(
		cy_as_device_handle			handle,
		cy_as_bus_number_t			 bus,
		uint32_t					device,
		uint8_t					 n_function_no)
{
	cy_as_return_status_t ret;
	uint8_t temp;

	if (n_function_no == 0)
		return CY_AS_ERROR_INVALID_FUNCTION;

	ret = cy_as_sdio_device_check((cy_as_device *)handle, bus, device);
	if (ret != CY_AS_ERROR_SUCCESS)
		return ret;

	if (!(cy_as_sdio_check_function_initialized
		(handle, bus, n_function_no)))
		return CY_AS_ERROR_SUCCESS;

	temp = (uint8_t)(((cy_as_device *)handle)->sdiocard[bus].
		function_init_map & (~(1 << n_function_no)));

	cy_as_sdio_direct_write(handle, bus, device, 0, 0x02, 0, temp, 0);

	((cy_as_device *)handle)->sdiocard[bus].function_init_map &=
		(~(1 << n_function_no));

	return CY_AS_ERROR_SUCCESS;
}


/*[]*/
