omap3530/beagle_drivers/wb/api/src/cyasstorage.c
changeset 27 117faf51deac
child 52 254b9435d75e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omap3530/beagle_drivers/wb/api/src/cyasstorage.c	Wed Mar 03 13:10:32 2010 +0000
@@ -0,0 +1,3941 @@
+/* Cypress West Bridge API source file (cyasstorage.c)
+## ===========================
+##
+##  Copyright Cypress Semiconductor Corporation, 2006-2009,
+##  All Rights Reserved
+##  UNPUBLISHED, LICENSED SOFTWARE.
+##
+##  CONFIDENTIAL AND PROPRIETARY INFORMATION
+##  WHICH IS THE PROPERTY OF CYPRESS.
+##
+##  Use of this file is governed
+##  by the license agreement included in the file
+##
+##     <install>/license/license.txt
+##
+##  where <install> is the Cypress software
+##  installation root directory path.
+##
+## ===========================
+*/
+
+/*
+* 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 "cyashal.h"
+#include "cyasstorage.h"
+#include "cyaserr.h"
+#include "cyasdevice.h"
+#include "cyaslowlevel.h"
+#include "cyasdma.h"
+#include "cyasregs.h"
+
+/* Map a pre-V1.2 media type to the V1.2+ bus number */
+CyAsReturnStatus_t
+CyAnMapBusFromMediaType(CyAsDevice *dev_p, CyAsMediaType type, CyAsBusNumber_t *bus)
+{
+    CyAsReturnStatus_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 (!CyAsDeviceIsConfigured(dev_p))
+        return CY_AS_ERROR_NOT_CONFIGURED ;
+
+    if (!CyAsDeviceIsFirmwareLoaded(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
+CreateAddress(CyAsBusNumber_t bus, uint32_t device, uint8_t unit)
+{
+    CyAsHalAssert(bus >= 0  && bus < CY_AS_MAX_BUSES) ;
+    CyAsHalAssert(device < 16) ;
+
+    return (uint16_t)(((uint8_t)bus << 12) | (device << 8) | unit) ;
+}
+
+CyAsMediaType
+CyAsStorageGetMediaFromAddress(uint16_t v)
+{
+    CyAsMediaType media = CyAsMediaMaxMediaValue ;
+
+    switch(v & 0xFF)
+    {
+        case 0x00:
+            break;
+        case 0x01:
+            media = CyAsMediaNand ;
+            break ;
+        case 0x02:
+            media = CyAsMediaSDFlash ;
+            break ;
+        case 0x04:
+            media = CyAsMediaMMCFlash ;
+            break ;
+        case 0x08:
+            media = CyAsMediaCEATA ;
+            break ;
+        case 0x10:
+            media = CyAsMediaSDIO ;
+            break ;
+        default:
+            CyAsHalAssert(0) ;
+            break ;
+    }
+
+    return media ;
+}
+
+CyAsBusNumber_t
+CyAsStorageGetBusFromAddress(uint16_t v)
+{
+    CyAsBusNumber_t bus = (CyAsBusNumber_t)((v >> 12) & 0x0f) ;
+    CyAsHalAssert(bus >= 0 && bus < CY_AS_MAX_BUSES) ;
+    return bus ;
+}
+
+uint32_t
+CyAsStorageGetDeviceFromAddress(uint16_t v)
+{
+    return (uint32_t)((v >> 8) & 0x0f) ;
+}
+
+static uint8_t
+GetUnitFromAddress(uint16_t v)
+{
+    return (uint8_t)(v & 0xff) ;
+}
+
+static CyAsReturnStatus_t
+CyAsMapBadAddr(uint16_t val)
+{
+    CyAsReturnStatus_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
+MyStorageRequestCallback(CyAsDevice *dev_p, uint8_t context, CyAsLLRequestResponse *req_p,
+                         CyAsLLRequestResponse *resp_p, CyAsReturnStatus_t ret)
+{
+    uint16_t val ;
+    uint16_t addr ;
+    CyAsBusNumber_t bus;
+    uint32_t device;
+    CyAsDeviceHandle h = (CyAsDeviceHandle)dev_p ;
+    CyAsDmaEndPoint *ep_p = NULL ;
+
+    (void)resp_p ;
+    (void)context ;
+    (void)ret ;
+
+    switch(CyAsLLRequestResponse_GetCode(req_p))
+    {
+    case CY_RQT_MEDIA_CHANGED:
+        CyAsLLSendStatusResponse(dev_p, CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+
+        /* Media has either been inserted or removed */
+        addr = CyAsLLRequestResponse_GetWord(req_p, 0) ;
+
+        bus = CyAsStorageGetBusFromAddress(addr);
+        device = CyAsStorageGetDeviceFromAddress(addr);
+
+        /* Clear the entry for this device to force re-query later */
+        CyAsHalMemSet(&(dev_p->storage_device_info[bus][device]), 0,
+            sizeof(dev_p->storage_device_info[bus][device])) ;
+
+        val = CyAsLLRequestResponse_GetWord(req_p, 1) ;
+        if (dev_p->storage_event_cb_ms)
+        {
+            if (val == 1)
+                dev_p->storage_event_cb_ms(h, bus, device, CyAsStorageRemoved, 0) ;
+            else
+                dev_p->storage_event_cb_ms(h, bus, device, CyAsStorageInserted, 0) ;
+        }
+        else if (dev_p->storage_event_cb)
+        {
+            if (val == 1)
+                dev_p->storage_event_cb(h, (CyAsMediaType)bus, CyAsStorageRemoved, 0) ; /*nxz*/
+            else
+                dev_p->storage_event_cb(h, (CyAsMediaType)bus, CyAsStorageInserted, 0) ; /*nxz*/
+        }
+
+        break ;
+
+    case CY_RQT_ANTIOCH_CLAIM:
+        CyAsLLSendStatusResponse(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 = CyAsLLRequestResponse_GetWord(req_p, 0) ;
+            if (dev_p->storage_event_cb_ms)
+            {
+                if (val & 0x0100)
+                    dev_p->storage_event_cb_ms(h, 0, 0, CyAsStorageAntioch, 0) ;
+                if (val & 0x0200)
+                    dev_p->storage_event_cb_ms(h, 1, 0, CyAsStorageAntioch, 0) ;
+            }
+            else
+            {
+                if (val & 0x01)
+                    dev_p->storage_event_cb(h, CyAsMediaNand, CyAsStorageAntioch, 0) ;
+                if (val & 0x02)
+                    dev_p->storage_event_cb(h, CyAsMediaSDFlash, CyAsStorageAntioch, 0) ;
+                if (val & 0x04)
+                    dev_p->storage_event_cb(h, CyAsMediaMMCFlash, CyAsStorageAntioch, 0) ;
+                if (val & 0x08)
+                    dev_p->storage_event_cb(h, CyAsMediaCEATA, CyAsStorageAntioch, 0) ;
+            }
+        }
+        break ;
+
+    case CY_RQT_ANTIOCH_RELEASE:
+        CyAsLLSendStatusResponse(dev_p, CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+        val = CyAsLLRequestResponse_GetWord(req_p, 0) ;
+        if (dev_p->storage_event_cb_ms)
+        {
+            if (val & 0x0100)
+                dev_p->storage_event_cb_ms(h, 0, 0, CyAsStorageProcessor, 0) ;
+            if (val & 0x0200)
+                dev_p->storage_event_cb_ms(h, 1, 0, CyAsStorageProcessor, 0) ;
+        }
+        else if (dev_p->storage_event_cb)
+        {
+            if (val & 0x01)
+                dev_p->storage_event_cb(h, CyAsMediaNand, CyAsStorageProcessor, 0) ;
+            if (val & 0x02)
+                dev_p->storage_event_cb(h, CyAsMediaSDFlash, CyAsStorageProcessor, 0) ;
+            if (val & 0x04)
+                dev_p->storage_event_cb(h, CyAsMediaMMCFlash, CyAsStorageProcessor, 0) ;
+            if (val & 0x08)
+                dev_p->storage_event_cb(h, CyAsMediaCEATA, CyAsStorageProcessor, 0) ;
+        }
+        break ;
+
+
+    case CY_RQT_SDIO_INTR:
+        CyAsLLSendStatusResponse(dev_p, CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+        val = CyAsLLRequestResponse_GetWord(req_p, 0) ;
+        if (dev_p->storage_event_cb_ms)
+        {
+            if (val & 0x0100)
+                dev_p->storage_event_cb_ms(h, 1, 0, CyAsSdioInterrupt, 0) ;
+            else
+                dev_p->storage_event_cb_ms(h, 0, 0, CyAsSdioInterrupt, 0) ;
+
+        }
+        else if (dev_p->storage_event_cb)
+        {
+            dev_p->storage_event_cb(h, CyAsMediaSDIO, CyAsSdioInterrupt, 0) ;
+        }
+        break;
+
+    case CY_RQT_P2S_DMA_START:
+        /* Do the DMA setup for the waiting operation. This event is used only in
+         * the MTP mode firmware. */
+        CyAsLLSendStatusResponse(dev_p, CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+        if (dev_p->storage_oper == CyAsOpRead)
+        {
+            ep_p = CY_AS_NUM_EP(dev_p, CY_AS_P2S_READ_ENDPOINT) ;
+            CyAsDmaEndPointSetStopped(ep_p) ;
+            CyAsDmaKickStart(dev_p, CY_AS_P2S_READ_ENDPOINT) ;
+        }
+        else
+        {
+            ep_p = CY_AS_NUM_EP(dev_p, CY_AS_P2S_WRITE_ENDPOINT) ;
+            CyAsDmaEndPointSetStopped(ep_p) ;
+            CyAsDmaKickStart(dev_p, CY_AS_P2S_WRITE_ENDPOINT) ;
+        }
+        break ;
+
+    default:
+        CyAsHalPrintMessage("Invalid request received on storage context\n") ;
+        val = req_p->box0 ;
+        CyAsLLSendDataResponse(dev_p, CY_RQT_STORAGE_RQT_CONTEXT, CY_RESP_INVALID_REQUEST, sizeof(val), &val) ;
+        break ;
+    }
+}
+
+static CyAsReturnStatus_t
+IsStorageActive(CyAsDevice *dev_p)
+{
+    if (!CyAsDeviceIsConfigured(dev_p))
+        return CY_AS_ERROR_NOT_CONFIGURED ;
+
+    if (!CyAsDeviceIsFirmwareLoaded(dev_p))
+        return CY_AS_ERROR_NO_FIRMWARE ;
+
+    if (dev_p->storage_count == 0)
+        return CY_AS_ERROR_NOT_RUNNING ;
+
+    if (CyAsDeviceIsInSuspendMode(dev_p))
+        return CY_AS_ERROR_IN_SUSPEND ;
+
+    return CY_AS_ERROR_SUCCESS ;
+}
+
+static void
+CyAsStorageFuncCallback(CyAsDevice *dev_p,
+                        uint8_t context,
+                        CyAsLLRequestResponse *rqt,
+                        CyAsLLRequestResponse *resp,
+                        CyAsReturnStatus_t ret) ;
+
+static CyAsReturnStatus_t
+MyHandleResponseNoData(CyAsDevice* dev_p,
+                         CyAsLLRequestResponse *req_p,
+                         CyAsLLRequestResponse *reply_p)
+{
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+
+    if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
+    {
+        ret = CY_AS_ERROR_INVALID_RESPONSE ;
+        goto destroy ;
+    }
+
+    ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+
+destroy :
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+static CyAsReturnStatus_t
+MyHandleResponseStorageStart(CyAsDevice* dev_p,
+                         CyAsLLRequestResponse *req_p,
+                         CyAsLLRequestResponse *reply_p,
+                         CyAsReturnStatus_t ret)
+{
+    if (ret != CY_AS_ERROR_SUCCESS)
+        goto destroy ;
+
+    if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
+    {
+        ret = CY_AS_ERROR_INVALID_RESPONSE ;
+        goto destroy ;
+    }
+
+    ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+    if (dev_p->storage_count > 0 && ret == CY_AS_ERROR_ALREADY_RUNNING)
+        ret = CY_AS_ERROR_SUCCESS ;
+
+    ret = CyAsDmaEnableEndPoint(dev_p, CY_AS_P2S_WRITE_ENDPOINT, CyTrue, CyAsDirectionIn) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        goto destroy ;
+
+    ret = CyAsDmaSetMaxDmaSize(dev_p, CY_AS_P2S_WRITE_ENDPOINT, CY_AS_STORAGE_EP_SIZE) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        goto destroy ;
+
+    ret = CyAsDmaEnableEndPoint(dev_p, CY_AS_P2S_READ_ENDPOINT, CyTrue, CyAsDirectionOut) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        goto destroy ;
+
+    ret = CyAsDmaSetMaxDmaSize(dev_p, CY_AS_P2S_READ_ENDPOINT, CY_AS_STORAGE_EP_SIZE) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        goto destroy ;
+
+    CyAsLLRegisterRequestCallback(dev_p, CY_RQT_STORAGE_RQT_CONTEXT, MyStorageRequestCallback) ;
+
+    /* Create the request/response used for storage reads and writes. */
+    dev_p->storage_rw_req_p  = CyAsLLCreateRequest(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 = CyAsLLCreateResponse(dev_p, 5) ;
+    if (dev_p->storage_rw_resp_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, dev_p->storage_rw_req_p) ;
+        ret = CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+
+destroy :
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(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)
+        {
+            CyAsHalMemSet(dev_p->storage_device_info, 0, sizeof(dev_p->storage_device_info)) ;
+            dev_p->is_storage_only_mode = CyFalse ;
+        }
+
+        dev_p->storage_count++ ;
+    }
+
+    CyAsDeviceClearSSSPending(dev_p) ;
+
+    return ret ;
+}
+
+CyAsReturnStatus_t
+CyAsStorageStart(CyAsDeviceHandle handle,
+                   CyAsFunctionCallback cb,
+                   uint32_t client)
+{
+    CyAsLLRequestResponse *req_p, *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    if (!CyAsDeviceIsConfigured(dev_p))
+        return CY_AS_ERROR_NOT_CONFIGURED ;
+
+    if (!CyAsDeviceIsFirmwareLoaded(dev_p))
+        return CY_AS_ERROR_NO_FIRMWARE ;
+
+    if (CyAsDeviceIsInSuspendMode(dev_p))
+        return CY_AS_ERROR_IN_SUSPEND ;
+
+    if(CyAsDeviceIsSSSPending(dev_p))
+        return CY_AS_ERROR_STARTSTOP_PENDING ;
+
+    CyAsDeviceSetSSSPending(dev_p) ;
+
+    if (dev_p->storage_count == 0)
+    {
+        /* Create the request to send to the West Bridge device */
+        req_p = CyAsLLCreateRequest(dev_p, CY_RQT_START_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
+        if (req_p == 0)
+        {
+            CyAsDeviceClearSSSPending(dev_p) ;
+            return CY_AS_ERROR_OUT_OF_MEMORY ;
+        }
+
+        /* Reserve space for the reply, the reply data will not exceed one word */
+        reply_p = CyAsLLCreateResponse(dev_p, 1) ;
+        if (reply_p == 0)
+        {
+            CyAsDeviceClearSSSPending(dev_p) ;
+            CyAsLLDestroyRequest(dev_p, req_p) ;
+            return CY_AS_ERROR_OUT_OF_MEMORY ;
+        }
+
+        if(cb == 0)
+        {
+            ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+            if (ret != CY_AS_ERROR_SUCCESS)
+                goto destroy ;
+
+            return MyHandleResponseStorageStart(dev_p, req_p, reply_p, ret) ;
+        }
+        else
+        {
+            ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_START,
+                0, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX,
+                req_p, reply_p, CyAsStorageFuncCallback) ;
+
+            if (ret != CY_AS_ERROR_SUCCESS)
+                goto destroy ;
+
+            /* The request and response are freed as part of the FuncCallback */
+            return ret ;
+        }
+
+destroy:
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        CyAsLLDestroyResponse(dev_p, reply_p) ;
+    }
+    else
+    {
+        dev_p->storage_count++ ;
+        if (cb)
+            cb(handle, ret, client, CY_FUNCT_CB_STOR_START, 0) ;
+    }
+
+    CyAsDeviceClearSSSPending(dev_p) ;
+
+    return ret ;
+}
+
+
+static CyAsReturnStatus_t
+MyHandleResponseStorageStop(CyAsDevice* dev_p,
+                         CyAsLLRequestResponse *req_p,
+                         CyAsLLRequestResponse *reply_p,
+                         CyAsReturnStatus_t ret)
+{
+    if (ret != CY_AS_ERROR_SUCCESS)
+        goto destroy ;
+
+    if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
+    {
+        ret = CY_AS_ERROR_INVALID_RESPONSE ;
+        goto destroy ;
+    }
+
+destroy :
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    if (ret == CY_AS_ERROR_SUCCESS)
+    {
+        CyAsLLDestroyRequest(dev_p, dev_p->storage_rw_req_p) ;
+        CyAsLLDestroyResponse(dev_p, dev_p->storage_rw_resp_p) ;
+        dev_p->storage_count-- ;
+    }
+
+    CyAsDeviceClearSSSPending(dev_p) ;
+
+    return ret ;
+}
+CyAsReturnStatus_t
+CyAsStorageStop(CyAsDeviceHandle handle,
+                  CyAsFunctionCallback cb,
+                  uint32_t client)
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsStorageActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (CyAsDeviceIsStorageAsyncPending(dev_p))
+        return CY_AS_ERROR_ASYNC_PENDING ;
+
+    if(CyAsDeviceIsSSSPending(dev_p))
+        return CY_AS_ERROR_STARTSTOP_PENDING ;
+
+    CyAsDeviceSetSSSPending(dev_p) ;
+
+    if (dev_p->storage_count == 1)
+    {
+
+        /* Create the request to send to the West Bridge device */
+        req_p = CyAsLLCreateRequest(dev_p, CY_RQT_STOP_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 0) ;
+        if (req_p == 0)
+        {
+            CyAsDeviceClearSSSPending(dev_p) ;
+            return CY_AS_ERROR_OUT_OF_MEMORY ;
+        }
+
+        /* Reserve space for the reply, the reply data will not exceed one word */
+        reply_p = CyAsLLCreateResponse(dev_p, 1) ;
+        if (reply_p == 0)
+        {
+            CyAsDeviceClearSSSPending(dev_p) ;
+            CyAsLLDestroyRequest(dev_p, req_p) ;
+            return CY_AS_ERROR_OUT_OF_MEMORY ;
+        }
+
+        if(cb == 0)
+        {
+            ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+            if (ret != CY_AS_ERROR_SUCCESS)
+                goto destroy ;
+
+            return MyHandleResponseStorageStop(dev_p, req_p, reply_p, ret) ;
+        }
+        else
+        {
+            ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_STOP,
+                0, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX,
+                req_p, reply_p, CyAsStorageFuncCallback) ;
+
+            if (ret != CY_AS_ERROR_SUCCESS)
+                goto destroy ;
+
+            /* The request and response are freed as part of the MiscFuncCallback */
+            return ret ;
+        }
+
+destroy:
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        CyAsLLDestroyResponse(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) ;
+    }
+
+    CyAsDeviceClearSSSPending(dev_p) ;
+
+    return ret ;
+}
+
+CyAsReturnStatus_t
+CyAsStorageRegisterCallback(CyAsDeviceHandle handle, CyAsStorageEventCallback callback)
+{
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    if (!CyAsDeviceIsConfigured(dev_p))
+        return CY_AS_ERROR_NOT_CONFIGURED ;
+
+    if (!CyAsDeviceIsFirmwareLoaded(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 CyAsReturnStatus_t
+MyHandleResponseStorageClaim(CyAsDevice* dev_p,
+                         CyAsLLRequestResponse *req_p,
+                         CyAsLLRequestResponse *reply_p)
+{
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+
+    if (CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_NO_SUCH_ADDRESS)
+    {
+        ret = CyAsMapBadAddr(CyAsLLRequestResponse_GetWord(reply_p, 3)) ;
+        goto destroy ;
+    }
+
+    if (CyAsLLRequestResponse_GetCode(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 ((CyAsStorageGetBusFromAddress(CyAsLLRequestResponse_GetWord(req_p, 0)) !=
+        CyAsStorageGetBusFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 0))) ||
+        (CyAsStorageGetDeviceFromAddress(CyAsLLRequestResponse_GetWord(req_p, 0)) !=
+        CyAsStorageGetDeviceFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 0))))
+    {
+        ret = CY_AS_ERROR_INVALID_RESPONSE ;
+        goto destroy ;
+    }
+
+    if (CyAsLLRequestResponse_GetWord(reply_p, 1) != 1)
+        ret = CY_AS_ERROR_NOT_ACQUIRED ;
+
+destroy :
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+static CyAsReturnStatus_t
+MyStorageClaim(CyAsDevice *dev_p,
+                void* data,
+                CyAsBusNumber_t bus,
+                uint32_t device,
+                uint16_t req_flags,
+                CyAsFunctionCallback cb,
+                uint32_t client)
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsStorageActive(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 = CyAsLLCreateRequest(dev_p, CY_RQT_CLAIM_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
+    if (req_p == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, device, 0)) ;
+
+    /* Reserve space for the reply, the reply data will not exceed one word */
+    reply_p = CyAsLLCreateResponse(dev_p, 4) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+
+    if(cb == 0)
+    {
+        ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        return MyHandleResponseStorageClaim(dev_p, req_p, reply_p) ;
+    }
+    else
+    {
+        ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_CLAIM,
+            data, dev_p->func_cbs_stor, req_flags,
+            req_p, reply_p, CyAsStorageFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        /* The request and response are freed as part of the MiscFuncCallback */
+        return ret ;
+    }
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+CyAsReturnStatus_t
+CyAsStorageClaim(CyAsDeviceHandle handle,
+                   CyAsBusNumber_t bus,
+                   uint32_t device,
+                   CyAsFunctionCallback cb,
+                   uint32_t client)
+{
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+
+    if (bus < 0 || bus >= CY_AS_MAX_BUSES)
+        return CY_AS_ERROR_NO_SUCH_BUS ;
+
+    return MyStorageClaim(dev_p, NULL, bus, device, CY_AS_REQUEST_RESPONSE_MS, cb, client) ;
+}
+
+static CyAsReturnStatus_t
+MyHandleResponseStorageRelease(CyAsDevice* dev_p,
+                         CyAsLLRequestResponse *req_p,
+                         CyAsLLRequestResponse *reply_p)
+{
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+
+    if (CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_NO_SUCH_ADDRESS)
+    {
+        ret = CyAsMapBadAddr(CyAsLLRequestResponse_GetWord(reply_p, 3)) ;
+        goto destroy ;
+    }
+
+    if (CyAsLLRequestResponse_GetCode(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 ((CyAsStorageGetBusFromAddress(CyAsLLRequestResponse_GetWord(req_p, 0)) !=
+        CyAsStorageGetBusFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 0))) ||
+        (CyAsStorageGetDeviceFromAddress(CyAsLLRequestResponse_GetWord(req_p, 0)) !=
+        CyAsStorageGetDeviceFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 0))))
+    {
+        ret = CY_AS_ERROR_INVALID_RESPONSE ;
+        goto destroy ;
+    }
+
+
+    if (CyAsLLRequestResponse_GetWord(reply_p, 1) != 0)
+        ret = CY_AS_ERROR_NOT_RELEASED ;
+
+destroy :
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+static CyAsReturnStatus_t
+MyStorageRelease(CyAsDevice* dev_p,
+                    void* data,
+                    CyAsBusNumber_t bus,
+                    uint32_t device,
+                    uint16_t req_flags,
+                    CyAsFunctionCallback cb,
+                    uint32_t client)
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsStorageActive(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 = CyAsLLCreateRequest(dev_p, CY_RQT_RELEASE_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
+    if (req_p == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, device, 0)) ;
+
+    /* Reserve space for the reply, the reply data will not exceed one word */
+    reply_p = CyAsLLCreateResponse(dev_p, 4) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+
+    if(cb == 0)
+    {
+        ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        return MyHandleResponseStorageRelease(dev_p, req_p, reply_p) ;
+    }
+    else
+    {
+        ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_RELEASE,
+            data, dev_p->func_cbs_stor, req_flags,
+            req_p, reply_p, CyAsStorageFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        /* The request and response are freed as part of the MiscFuncCallback */
+        return ret ;
+    }
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+CyAsReturnStatus_t
+CyAsStorageRelease(CyAsDeviceHandle handle,
+                   CyAsBusNumber_t bus,
+                   uint32_t device,
+                   CyAsFunctionCallback cb,
+                   uint32_t client)
+{
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+
+    if (bus < 0 || bus >= CY_AS_MAX_BUSES)
+        return CY_AS_ERROR_NO_SUCH_BUS ;
+
+    return MyStorageRelease(dev_p, NULL, bus, device, CY_AS_REQUEST_RESPONSE_MS, cb, client) ;
+}
+
+static CyAsReturnStatus_t
+MyHandleResponseStorageQueryBus(CyAsDevice* dev_p,
+                         CyAsLLRequestResponse *req_p,
+                         CyAsLLRequestResponse *reply_p,
+                         uint32_t* count)
+{
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    uint8_t code = CyAsLLRequestResponse_GetCode(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 (CyAsStorageGetBusFromAddress(CyAsLLRequestResponse_GetWord(req_p, 0)) !=
+                CyAsStorageGetBusFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 0)))
+    {
+        ret = CY_AS_ERROR_INVALID_RESPONSE ;
+        goto destroy ;
+    }
+
+    v = CyAsLLRequestResponse_GetWord(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.
+         */
+        CyAsMediaType queried = (CyAsMediaType)CyAsLLRequestResponse_GetWord(req_p, 1) ;
+        CyAsMediaType found   = CyAsStorageGetMediaFromAddress(v) ;
+
+        if (queried == found)
+            *count = 1 ;
+        else
+            *count = 0 ;
+    }
+
+destroy :
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+CyAsReturnStatus_t
+MyStorageQueryBus(CyAsDevice *dev_p,
+                        CyAsBusNumber_t bus,
+                        CyAsMediaType   type,
+                        uint16_t req_flags,
+                        uint32_t *count,
+                        CyAsFunctionCallback cb,
+                        uint32_t client)
+{
+    CyAsReturnStatus_t ret ;
+    CyAsLLRequestResponse *req_p, *reply_p ;
+    CyAsFunctCBType cbType = CY_FUNCT_CB_STOR_QUERYBUS ;
+
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsStorageActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    /* Create the request to send to the Antioch device */
+    req_p = CyAsLLCreateRequest(dev_p, CY_RQT_QUERY_BUS, CY_RQT_STORAGE_RQT_CONTEXT, 2) ;
+    if (req_p == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, 0, 0)) ;
+    CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)type) ;
+
+    /* Reserve space for the reply, the reply data will not exceed two words. */
+    reply_p = CyAsLLCreateResponse(dev_p, 2) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+
+    if(cb == 0)
+    {
+        ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        req_p->flags |= req_flags;
+        return MyHandleResponseStorageQueryBus(dev_p, req_p, reply_p, count) ;
+    }
+    else
+    {
+        if (req_flags == CY_AS_REQUEST_RESPONSE_EX)
+            cbType = CY_FUNCT_CB_STOR_QUERYMEDIA ;
+
+        ret = CyAsMiscSendRequest(dev_p, cb, client, cbType,
+            count, dev_p->func_cbs_stor, req_flags,
+            req_p, reply_p, CyAsStorageFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        /* The request and response are freed as part of the MiscFuncCallback */
+        return ret ;
+    }
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+CyAsReturnStatus_t
+CyAsStorageQueryBus(CyAsDeviceHandle handle,
+                        CyAsBusNumber_t bus,
+                        uint32_t *count,
+                        CyAsFunctionCallback cb,
+                        uint32_t client)
+{
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+
+    return MyStorageQueryBus(dev_p, bus, CyAsMediaMaxMediaValue, CY_AS_REQUEST_RESPONSE_MS,
+            count, cb, client) ;
+}
+
+CyAsReturnStatus_t
+CyAsStorageQueryMedia(CyAsDeviceHandle handle,
+                        CyAsMediaType type,
+                        uint32_t *count,
+                        CyAsFunctionCallback cb,
+                        uint32_t client)
+{
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    CyAsBusNumber_t bus ;
+
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsStorageActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    ret = CyAnMapBusFromMediaType(dev_p, type, &bus) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    return MyStorageQueryBus(dev_p, bus, type, CY_AS_REQUEST_RESPONSE_EX,
+            count, cb, client) ;
+}
+
+static CyAsReturnStatus_t
+MyHandleResponseStorageQueryDevice(CyAsDevice* dev_p,
+                         CyAsLLRequestResponse *req_p,
+                         CyAsLLRequestResponse *reply_p,
+                         void* data_p)
+{
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    uint16_t v ;
+    CyAsBusNumber_t bus ;
+    CyAsMediaType type ;
+    uint32_t device ;
+    CyBool removable ;
+    CyBool writeable ;
+    CyBool locked ;
+    uint16_t block_size ;
+    uint32_t number_units ;
+    uint32_t number_eus ;
+
+    if (CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_NO_SUCH_ADDRESS)
+    {
+        ret = CyAsMapBadAddr(CyAsLLRequestResponse_GetWord(reply_p, 3)) ;
+        goto destroy ;
+    }
+
+    if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_DEVICE_DESCRIPTOR)
+    {
+        ret = CY_AS_ERROR_INVALID_RESPONSE ;
+        goto destroy ;
+    }
+
+    /* Unpack the response */
+    v = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+    type = CyAsStorageGetMediaFromAddress(v) ;
+    bus  = CyAsStorageGetBusFromAddress(v) ;
+    device = CyAsStorageGetDeviceFromAddress(v) ;
+
+    block_size = CyAsLLRequestResponse_GetWord(reply_p, 1) ;
+
+    v = CyAsLLRequestResponse_GetWord(reply_p, 2) ;
+    removable = (v & 0x8000) ? CyTrue : CyFalse ;
+    writeable = (v & 0x0100) ? CyTrue : CyFalse ;
+    locked = (v & 0x0200) ? CyTrue : CyFalse ;
+    number_units = (v & 0xff) ;
+
+    number_eus  = (CyAsLLRequestResponse_GetWord(reply_p, 3) << 16) | CyAsLLRequestResponse_GetWord(reply_p, 4) ;
+
+    /* Store the results based on the version of originating function */
+    if (req_p->flags & CY_AS_REQUEST_RESPONSE_MS)
+    {
+        CyAsStorageQueryDeviceData  *store_p = (CyAsStorageQueryDeviceData*)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
+    {
+        CyAsStorageQueryDeviceData_dep    *store_p = (CyAsStorageQueryDeviceData_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 :
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+static CyAsReturnStatus_t
+MyStorageQueryDevice(CyAsDevice *dev_p,
+                        void* data_p,
+                        uint16_t req_flags,
+                        CyAsBusNumber_t bus,
+                        uint32_t device,
+                        CyAsFunctionCallback cb,
+                        uint32_t client)
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsStorageActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    /* Create the request to send to the Antioch device */
+    req_p = CyAsLLCreateRequest(dev_p, CY_RQT_QUERY_DEVICE, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
+    if (req_p == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, device, 0)) ;
+
+    /* Reserve space for the reply, the reply data will not exceed five words. */
+    reply_p = CyAsLLCreateResponse(dev_p, 5) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+
+    if(cb == 0)
+    {
+        ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        req_p->flags |= req_flags;
+        return MyHandleResponseStorageQueryDevice(dev_p, req_p, reply_p, data_p) ;
+    }
+    else
+    {
+
+        ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_QUERYDEVICE,
+            data_p, dev_p->func_cbs_stor, req_flags,
+            req_p, reply_p, CyAsStorageFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        /* The request and response are freed as part of the MiscFuncCallback */
+        return ret ;
+    }
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+CyAsReturnStatus_t
+CyAsStorageQueryDevice(CyAsDeviceHandle handle,
+                         CyAsStorageQueryDeviceData* data_p,
+                         CyAsFunctionCallback cb,
+                         uint32_t client)
+{
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+    return MyStorageQueryDevice(dev_p, data_p, CY_AS_REQUEST_RESPONSE_MS, data_p->bus,
+            data_p->device, cb, client) ;
+}
+
+static CyAsReturnStatus_t
+MyHandleResponseStorageQueryUnit(CyAsDevice* dev_p,
+                         CyAsLLRequestResponse *req_p,
+                         CyAsLLRequestResponse *reply_p,
+                         void* data_p)
+{
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    CyAsBusNumber_t bus ;
+    uint32_t device ;
+    uint32_t unit ;
+    CyAsMediaType type ;
+    uint16_t block_size ;
+    uint32_t start_block ;
+    uint32_t unit_size ;
+    uint16_t v ;
+
+    if (CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_NO_SUCH_ADDRESS)
+    {
+        ret = CyAsMapBadAddr(CyAsLLRequestResponse_GetWord(reply_p, 3)) ;
+        goto destroy ;
+    }
+
+    if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_UNIT_DESCRIPTOR)
+    {
+        ret = CY_AS_ERROR_INVALID_RESPONSE ;
+        goto destroy ;
+    }
+
+    /* Unpack the response */
+    v      = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+    bus    = CyAsStorageGetBusFromAddress(v) ;
+    device = CyAsStorageGetDeviceFromAddress(v) ;
+    unit   = GetUnitFromAddress(v) ;
+
+    type   = CyAsStorageGetMediaFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 1));
+
+    block_size = CyAsLLRequestResponse_GetWord(reply_p, 2) ;
+    start_block = CyAsLLRequestResponse_GetWord(reply_p, 3) | (CyAsLLRequestResponse_GetWord(reply_p, 4) << 16) ;
+    unit_size = CyAsLLRequestResponse_GetWord(reply_p, 5) | (CyAsLLRequestResponse_GetWord(reply_p, 6) << 16) ;
+
+    /* Store the results based on the version of originating function */
+    if (req_p->flags & CY_AS_REQUEST_RESPONSE_MS)
+    {
+        CyAsStorageQueryUnitData  *store_p = (CyAsStorageQueryUnitData*)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
+    {
+        CyAsStorageQueryUnitData_dep    *store_p = (CyAsStorageQueryUnitData_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 :
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+static CyAsReturnStatus_t
+MyStorageQueryUnit(CyAsDevice *dev_p,
+                    void* data_p,
+                    uint16_t req_flags,
+                    CyAsBusNumber_t bus,
+                    uint32_t device,
+                    uint32_t unit,
+                    CyAsFunctionCallback cb,
+                    uint32_t client)
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsStorageActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    /* Create the request to send to the West Bridge device */
+    req_p = CyAsLLCreateRequest(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 ;
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, device, (uint8_t)unit)) ;
+
+    /* Reserve space for the reply, the reply data will be of seven words. */
+    reply_p = CyAsLLCreateResponse(dev_p, 7) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+
+    if(cb == 0)
+    {
+        ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        req_p->flags |= req_flags ;
+        return MyHandleResponseStorageQueryUnit(dev_p, req_p, reply_p, data_p) ;
+    }
+    else
+    {
+
+        ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_QUERYUNIT,
+            data_p, dev_p->func_cbs_stor, req_flags,
+            req_p, reply_p, CyAsStorageFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        /* The request and response are freed as part of the MiscFuncCallback */
+        return ret ;
+    }
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+CyAsReturnStatus_t
+CyAsStorageQueryUnit(CyAsDeviceHandle handle,
+                       CyAsStorageQueryUnitData* data_p,
+                       CyAsFunctionCallback cb,
+                       uint32_t client)
+{
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+    return MyStorageQueryUnit(dev_p, data_p, CY_AS_REQUEST_RESPONSE_MS, data_p->bus,
+            data_p->device, data_p->unit, cb, client) ;
+}
+
+
+static CyAsReturnStatus_t
+CyAsGetBlockSize(CyAsDevice *dev_p,
+                    CyAsBusNumber_t bus,
+                    uint32_t device,
+                    CyAsFunctionCallback cb)
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+
+    /* Create the request to send to the West Bridge device */
+    req_p = CyAsLLCreateRequest(dev_p, CY_RQT_QUERY_DEVICE, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
+    if (req_p == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, device, 0)) ;
+
+    reply_p = CyAsLLCreateResponse(dev_p, 4) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+
+    if(cb == 0)
+    {
+        ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        if (CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_NO_SUCH_ADDRESS)
+        {
+            ret = CY_AS_ERROR_NO_SUCH_BUS ;
+            goto destroy ;
+        }
+
+        if (CyAsLLRequestResponse_GetCode(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 ((CyAsStorageGetBusFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 0)) != bus) ||
+            (CyAsStorageGetDeviceFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 0)) != device) )
+        {
+            ret = CY_AS_ERROR_INVALID_RESPONSE ;
+            goto destroy ;
+        }
+
+
+        dev_p->storage_device_info[bus][device].block_size = CyAsLLRequestResponse_GetWord(reply_p, 1) ;
+    }
+    else
+        ret = CY_AS_ERROR_INVALID_REQUEST ;
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+CyAsReturnStatus_t
+MyStorageDeviceControl(
+        CyAsDevice          *dev_p,
+        CyAsBusNumber_t      bus,
+        uint32_t             device,
+        CyBool               card_detect_en,
+        CyBool               write_prot_en,
+                CyAsStorageCardDetect config_detect,
+        CyAsFunctionCallback cb,
+        uint32_t             client)
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret ;
+    CyBool use_gpio = CyFalse ;
+
+    (void)device ;
+
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    if (!CyAsDeviceIsConfigured(dev_p))
+        return CY_AS_ERROR_NOT_CONFIGURED ;
+
+    if (!CyAsDeviceIsFirmwareLoaded(dev_p))
+        return CY_AS_ERROR_NO_FIRMWARE ;
+
+    if (CyAsDeviceIsInSuspendMode(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<<CyAsMediaNand)))
+        return CY_AS_ERROR_NOT_SUPPORTED;
+
+    if(config_detect == CyAsStorageDetect_GPIO)
+        use_gpio = CyTrue ;
+    else if(config_detect == CyAsStorageDetect_SDAT_3)
+        use_gpio = CyFalse ;
+    else
+        return CY_AS_ERROR_INVALID_PARAMETER ;
+
+    /* Create the request to send to the West Bridge device */
+    req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SD_INTERFACE_CONTROL, CY_RQT_STORAGE_RQT_CONTEXT, 2) ;
+    if (req_p == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, device, 0)) ;
+    CyAsLLRequestResponse_SetWord(req_p, 1, (((uint16_t)card_detect_en << 8) | ((uint16_t)use_gpio << 1) | (uint16_t)write_prot_en)) ;
+
+    reply_p = CyAsLLCreateResponse(dev_p, 1) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+
+    if(cb == 0)
+    {
+        ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
+        {
+            ret = CY_AS_ERROR_INVALID_RESPONSE ;
+            goto destroy ;
+        }
+
+        ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+    }
+    else
+    {
+
+        ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_DEVICECONTROL,
+            0, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX,
+            req_p, reply_p, CyAsStorageFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        /* The request and response are freed as part of the MiscFuncCallback */
+        return ret ;
+    }
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+CyAsReturnStatus_t
+CyAsStorageDeviceControl(CyAsDeviceHandle handle,
+                            CyAsBusNumber_t bus,
+                            uint32_t device,
+                            CyBool card_detect_en,
+                            CyBool write_prot_en,
+                            CyAsStorageCardDetect config_detect,
+                            CyAsFunctionCallback cb,
+                            uint32_t client)
+{
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+
+    return MyStorageDeviceControl(dev_p, bus, device, card_detect_en, write_prot_en, config_detect, cb, client);
+}
+
+static void
+CyAsAsyncStorageCallback(CyAsDevice *dev_p, CyAsEndPointNumber_t ep, void *buf_p, uint32_t size, CyAsReturnStatus_t ret)
+{
+    CyAsStorageCallback_dep cb ;
+    CyAsStorageCallback cb_ms ;
+
+    (void)size ;
+    (void)buf_p ;
+    (void)ep ;
+
+    CyAsDeviceClearStorageAsyncPending(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)
+    {
+            CyAsHalAssert(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((CyAsDeviceHandle)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((CyAsDeviceHandle)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
+CyAsAsyncStorageReplyCallback(
+                              CyAsDevice *dev_p,
+                              uint8_t context,
+                              CyAsLLRequestResponse *rqt,
+                              CyAsLLRequestResponse *resp,
+                              CyAsReturnStatus_t ret)
+{
+    CyAsStorageCallback_dep cb ;
+    CyAsStorageCallback cb_ms ;
+    uint8_t reqtype ;
+    (void)rqt ;
+    (void)context ;
+
+    reqtype = CyAsLLRequestResponse_GetCode(rqt) ;
+
+    if (ret == CY_AS_ERROR_SUCCESS)
+    {
+        if (CyAsLLRequestResponse_GetCode(resp) == CY_RESP_ANTIOCH_DEFERRED_ERROR)
+        {
+            ret = CyAsLLRequestResponse_GetWord(resp, 0) & 0x00FF ;
+        }
+        else if (CyAsLLRequestResponse_GetCode(resp) != CY_RESP_SUCCESS_FAILURE)
+        {
+            ret = CY_AS_ERROR_INVALID_RESPONSE ;
+        }
+    }
+
+    if (ret != CY_AS_ERROR_SUCCESS)
+    {
+        if(reqtype == CY_RQT_READ_BLOCK)
+            CyAsDmaCancel(dev_p, dev_p->storage_read_endpoint, ret) ;
+        else
+            CyAsDmaCancel(dev_p, dev_p->storage_write_endpoint, ret) ;
+    }
+
+    dev_p->storage_wait = CyFalse ;
+
+    /*
+    * If the DMA callback has already been called, the user callback
+    * has to be called from here.
+    */
+    if (!CyAsDeviceIsStorageAsyncPending(dev_p))
+    {
+            CyAsHalAssert(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((CyAsDeviceHandle)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((CyAsDeviceHandle)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 CyAsReturnStatus_t
+CyAsStorageAsyncOper(CyAsDevice *dev_p, CyAsEndPointNumber_t ep, uint8_t reqtype, uint16_t req_flags,
+                     CyAsBusNumber_t bus, uint32_t device, uint32_t unit,
+                     uint32_t block, void *data_p, uint16_t num_blocks,
+                     CyAsStorageCallback_dep callback, CyAsStorageCallback callback_ms)
+{
+    uint32_t mask ;
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+
+    ret = IsStorageActive(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((CyAsDeviceHandle)dev_p, bus, device, unit, block,
+                ((reqtype == CY_RQT_WRITE_BLOCK) ? CyAsOpWrite : CyAsOpRead),
+                CY_AS_ERROR_SUCCESS) ;
+        else
+            callback((CyAsDeviceHandle)dev_p, dev_p->storage_device_info[bus][device].type,
+                device, unit, block, ((reqtype == CY_RQT_WRITE_BLOCK) ? CyAsOpWrite : CyAsOpRead),
+                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 = CyAsHalDisableInterrupts() ;
+    if ((CyAsDeviceIsStorageAsyncPending(dev_p)) || (dev_p->storage_wait) || (CyAsDeviceIsUsbAsyncPending(dev_p, 6)))
+    {
+        CyAsHalEnableInterrupts(mask) ;
+        return CY_AS_ERROR_ASYNC_PENDING ;
+    }
+
+    CyAsDeviceSetStorageAsyncPending(dev_p) ;
+    CyAsHalEnableInterrupts(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 ;
+    CyAsLLInitRequest(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 ;
+    CyAsLLInitResponse(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 = CyAsDmaQueueRequest(dev_p, ep, data_p, dev_p->storage_device_info[bus][device].block_size * num_blocks,
+            CyFalse, CyTrue, CyAsAsyncStorageCallback) ;
+        dev_p->storage_oper = CyAsOpRead ;
+    }
+    else if (reqtype == CY_RQT_WRITE_BLOCK)
+    {
+        ret = CyAsDmaQueueRequest(dev_p, ep, data_p, dev_p->storage_device_info[bus][device].block_size * num_blocks,
+            CyFalse, CyFalse, CyAsAsyncStorageCallback) ;
+        dev_p->storage_oper = CyAsOpWrite ;
+    }
+    if (ret != CY_AS_ERROR_SUCCESS)
+    {
+        CyAsDeviceClearStorageAsyncPending(dev_p) ;
+        return ret ;
+    }
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, (uint8_t)unit)) ;
+    CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)((block >> 16) & 0xffff)) ;
+    CyAsLLRequestResponse_SetWord(req_p, 2, (uint16_t)(block & 0xffff)) ;
+    CyAsLLRequestResponse_SetWord(req_p, 3, (uint16_t)((num_blocks >> 8) & 0x00ff)) ;
+    CyAsLLRequestResponse_SetWord(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 = CyTrue ;
+    ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyTrue, CyAsAsyncStorageReplyCallback) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+    {
+        CyAsDmaCancel(dev_p, ep, CY_AS_ERROR_CANCELED) ;
+        CyAsDeviceClearStorageAsyncPending(dev_p) ;
+    }
+
+    return ret ;
+}
+
+static void
+CyAsSyncStorageCallback(CyAsDevice *dev_p, CyAsEndPointNumber_t ep, void *buf_p, uint32_t size, CyAsReturnStatus_t err)
+{
+    (void)ep ;
+    (void)buf_p ;
+    (void)size ;
+
+    dev_p->storage_error = err ;
+}
+
+static void
+CyAsSyncStorageReplyCallback(
+                             CyAsDevice *dev_p,
+                             uint8_t context,
+                             CyAsLLRequestResponse *rqt,
+                             CyAsLLRequestResponse *resp,
+                             CyAsReturnStatus_t ret)
+{
+    uint8_t reqtype ;
+    (void)rqt ;
+
+    reqtype = CyAsLLRequestResponse_GetCode(rqt) ;
+
+    if (CyAsLLRequestResponse_GetCode(resp) == CY_RESP_ANTIOCH_DEFERRED_ERROR)
+    {
+        ret = CyAsLLRequestResponse_GetWord(resp, 0) & 0x00FF ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+        {
+            if(reqtype == CY_RQT_READ_BLOCK)
+                CyAsDmaCancel(dev_p, dev_p->storage_read_endpoint, ret) ;
+            else
+                CyAsDmaCancel(dev_p, dev_p->storage_write_endpoint, ret) ;
+        }
+    }
+    else if (CyAsLLRequestResponse_GetCode(resp) != CY_RESP_SUCCESS_FAILURE)
+    {
+        ret = CY_AS_ERROR_INVALID_RESPONSE ;
+    }
+
+    dev_p->storage_wait = CyFalse ;
+    dev_p->storage_error = ret ;
+
+    /* Wake any threads/processes that are waiting on the read/write completion. */
+    CyAsHalWake (&dev_p->context[context]->channel) ;
+}
+
+static CyAsReturnStatus_t
+CyAsStorageSyncOper(CyAsDevice *dev_p, CyAsEndPointNumber_t ep, uint8_t reqtype, CyAsBusNumber_t bus, uint32_t device,
+                    uint32_t unit, uint32_t block, void *data_p, uint16_t num_blocks)
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    CyAsContext *ctxt_p ;
+    uint32_t loopcount = 200 ;
+
+    ret = IsStorageActive(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 ((CyAsDeviceIsStorageAsyncPending(dev_p)) || (dev_p->storage_wait))
+        return CY_AS_ERROR_ASYNC_PENDING ;
+
+    /* Also need to check for pending Async MTP writes */
+    if(CyAsDeviceIsUsbAsyncPending(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 = CyAsGetBlockSize(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 ;
+    CyAsLLInitRequest(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 ;
+    CyAsLLInitResponse(reply_p, 5) ;
+
+    /* Setup the DMA request */
+    if (reqtype == CY_RQT_READ_BLOCK)
+    {
+        ret = CyAsDmaQueueRequest(dev_p, ep, data_p, dev_p->storage_device_info[bus][device].block_size * num_blocks, CyFalse,
+            CyTrue, CyAsSyncStorageCallback) ;
+        dev_p->storage_oper = CyAsOpRead ;
+    }
+    else if (reqtype == CY_RQT_WRITE_BLOCK)
+    {
+        ret = CyAsDmaQueueRequest(dev_p, ep, data_p, dev_p->storage_device_info[bus][device].block_size * num_blocks, CyFalse,
+            CyFalse, CyAsSyncStorageCallback) ;
+        dev_p->storage_oper = CyAsOpWrite ;
+    }
+    if (ret != CY_AS_ERROR_SUCCESS)
+    {
+        return ret ;
+    }
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, (uint8_t)unit)) ;
+    CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)((block >> 16) & 0xffff)) ;
+    CyAsLLRequestResponse_SetWord(req_p, 2, (uint16_t)(block & 0xffff)) ;
+    CyAsLLRequestResponse_SetWord(req_p, 3, (uint16_t)((num_blocks >> 8) & 0x00ff)) ;
+    CyAsLLRequestResponse_SetWord(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 = CyTrue ;
+    ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyTrue, CyAsSyncStorageReplyCallback) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+    {
+        CyAsDmaCancel(dev_p, ep, CY_AS_ERROR_CANCELED) ;
+    }
+    else
+    {
+        /* Setup the DMA request */
+        ctxt_p = dev_p->context[CY_RQT_STORAGE_RQT_CONTEXT] ;
+        ret = CyAsDmaDrainQueue(dev_p, ep, CyFalse) ;
+
+        while (loopcount-- > 0)
+        {
+            if (dev_p->storage_wait == CyFalse)
+                break ;
+            CyAsHalSleepOn(&ctxt_p->channel, 10) ;
+        }
+
+        if (dev_p->storage_wait == CyTrue)
+        {
+            dev_p->storage_wait = CyFalse ;
+            CyAsLLRemoveRequest(dev_p, ctxt_p, req_p, CyTrue) ;
+            ret = CY_AS_ERROR_TIMEOUT ;
+        }
+
+        if (ret == CY_AS_ERROR_SUCCESS)
+            ret = dev_p->storage_error ;
+    }
+
+    return ret ;
+}
+
+CyAsReturnStatus_t
+CyAsStorageRead(CyAsDeviceHandle handle, CyAsBusNumber_t bus, uint32_t device, uint32_t unit, uint32_t block,
+                void *data_p, uint16_t num_blocks)
+{
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    return CyAsStorageSyncOper(dev_p, dev_p->storage_read_endpoint, CY_RQT_READ_BLOCK, bus, device,
+        unit, block, data_p, num_blocks) ;
+}
+
+CyAsReturnStatus_t
+CyAsStorageWrite(CyAsDeviceHandle handle, CyAsBusNumber_t bus, uint32_t device, uint32_t unit, uint32_t block,
+                 void *data_p, uint16_t num_blocks)
+{
+    CyAsDevice *dev_p = (CyAsDevice *)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 CyAsStorageSyncOper(dev_p, dev_p->storage_write_endpoint, CY_RQT_WRITE_BLOCK, bus, device,
+        unit, block, data_p, num_blocks) ;
+}
+
+
+CyAsReturnStatus_t
+CyAsStorageReadAsync(CyAsDeviceHandle handle, CyAsBusNumber_t bus, uint32_t device, uint32_t unit,
+                     uint32_t block, void *data_p, uint16_t num_blocks, CyAsStorageCallback callback)
+{
+    CyAsDevice *dev_p = (CyAsDevice *)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 CyAsStorageAsyncOper(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);
+}
+
+CyAsReturnStatus_t
+CyAsStorageWriteAsync(CyAsDeviceHandle handle, CyAsBusNumber_t bus, uint32_t device, uint32_t unit,
+                      uint32_t block, void *data_p, uint16_t num_blocks, CyAsStorageCallback callback)
+{
+    CyAsDevice *dev_p = (CyAsDevice *)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 CyAsStorageAsyncOper(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
+MyStorageCancelCallback (
+        CyAsDevice *dev_p,
+        uint8_t context,
+        CyAsLLRequestResponse *rqt,
+        CyAsLLRequestResponse *resp,
+        CyAsReturnStatus_t stat)
+{
+    (void)context ;
+    (void)stat ;
+
+    /* Nothing to do here, except free up the request and response structures. */
+    CyAsLLDestroyResponse(dev_p, resp) ;
+    CyAsLLDestroyRequest(dev_p, rqt) ;
+}
+
+
+CyAsReturnStatus_t
+CyAsStorageCancelAsync(CyAsDeviceHandle handle)
+{
+    CyAsReturnStatus_t ret ;
+    CyAsLLRequestResponse *req_p , *reply_p ;
+
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsStorageActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (!CyAsDeviceIsStorageAsyncPending(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 = CyAsLLCreateRequest(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 = CyAsLLCreateResponse(dev_p, 1) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+
+    ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyFalse, MyStorageCancelCallback) ;
+    if (ret)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        CyAsLLDestroyResponse(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 CyAsStorageCleanup(CyAsDevice *dev_p)
+{
+    if (dev_p->storage_count)
+    {
+        CyAsLLDestroyRequest(dev_p, dev_p->storage_rw_req_p) ;
+        CyAsLLDestroyResponse(dev_p, dev_p->storage_rw_resp_p) ;
+        dev_p->storage_count = 0 ;
+        CyAsDeviceClearScsiMessages(dev_p) ;
+        CyAsHalMemSet(dev_p->storage_device_info, 0, sizeof(dev_p->storage_device_info)) ;
+
+        CyAsDeviceClearStorageAsyncPending(dev_p) ;
+        dev_p->storage_cb = 0 ;
+        dev_p->storage_cb_ms = 0 ;
+        dev_p->storage_wait = CyFalse ;
+    }
+}
+
+static CyAsReturnStatus_t
+MyHandleResponseSDRegRead(
+        CyAsDevice               *dev_p,
+        CyAsLLRequestResponse    *req_p,
+        CyAsLLRequestResponse    *reply_p,
+        CyAsStorageSDRegReadData *info)
+{
+    CyAsReturnStatus_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 = CyAsLLRequestResponse_GetCode(reply_p) ;
+    if (resp_type == CY_RESP_SD_REGISTER_DATA)
+    {
+        uint16_t *resp_p = reply_p->data + 1 ;
+        uint16_t temp ;
+
+        resp_len = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+        CyAsHalAssert(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 = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+        else
+            ret = CY_AS_ERROR_INVALID_RESPONSE ;
+    }
+
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+
+    return ret ;
+}
+
+CyAsReturnStatus_t
+CyAsStorageSDRegisterRead(
+        CyAsDeviceHandle          handle,
+        CyAsBusNumber_t           bus,
+        uint8_t                   device,
+        CyAsSDCardRegType         regType,
+        CyAsStorageSDRegReadData *data_p,
+        CyAsFunctionCallback      cb,
+        uint32_t                  client)
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    uint8_t  length ;
+
+    /*
+     * Sanity checks required before sending the request to the
+     * firmware.
+     */
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsStorageActive(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 (regType > CyAsSDReg_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 << CyAsMediaSDFlash)) == 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 (regType)
+    {
+        case CyAsSDReg_OCR:
+            length = CY_AS_SD_REG_OCR_LENGTH ;
+            break ;
+
+        case CyAsSDReg_CID:
+            length = CY_AS_SD_REG_CID_LENGTH ;
+            break ;
+
+        case CyAsSDReg_CSD:
+            length = CY_AS_SD_REG_CSD_LENGTH ;
+            break ;
+
+        default:
+            length = 0 ;
+            CyAsHalAssert(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 = CyAsLLCreateRequest(dev_p, CY_RQT_SD_REGISTER_READ, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
+    if (req_p == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, (CreateAddress(bus, device, 0) | (uint16_t)regType)) ;
+
+    reply_p = CyAsLLCreateResponse(dev_p, CY_AS_SD_REG_MAX_RESP_LENGTH) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+
+    if (cb == 0)
+    {
+        ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        return MyHandleResponseSDRegRead(dev_p, req_p, reply_p, data_p) ;
+    }
+    else
+    {
+        ret = CyAsMiscSendRequest(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, CyAsStorageFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        /* The request and response are freed as part of the MiscFuncCallback */
+        return ret ;
+    }
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+CyAsReturnStatus_t
+CyAsStorageCreatePPartition(
+        CyAsDeviceHandle        handle,                 /* Handle to the device of interest */
+        CyAsBusNumber_t         bus,
+        uint32_t                device,
+        uint32_t                size, /* of P-port only partition in blocks */
+        CyAsFunctionCallback    cb,
+        uint32_t                client)
+{
+    CyAsLLRequestResponse *req_p, *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsStorageActive(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 = CyAsLLCreateRequest(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 = CyAsLLCreateResponse(dev_p, 1) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, 0x00) );
+    CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)((size >> 16) & 0xffff)) ;
+    CyAsLLRequestResponse_SetWord(req_p, 2, (uint16_t)(size & 0xffff)) ;
+
+    if(cb == 0)
+    {
+        ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        return MyHandleResponseNoData(dev_p, req_p, reply_p) ;
+    }
+    else
+    {
+        ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_PARTITION,
+            0, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX,
+                req_p, reply_p, CyAsStorageFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        /* The request and response are freed as part of the FuncCallback */
+        return ret ;
+
+    }
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+CyAsReturnStatus_t
+CyAsStorageRemovePPartition(
+        CyAsDeviceHandle        handle,
+        CyAsBusNumber_t         bus,
+        uint32_t                device,
+        CyAsFunctionCallback    cb,
+        uint32_t                client)
+{
+    CyAsLLRequestResponse *req_p, *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsStorageActive(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 = CyAsLLCreateRequest(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 = CyAsLLCreateResponse(dev_p, 1) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, 0x00) );
+
+    if(cb == 0)
+    {
+        ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        return MyHandleResponseNoData(dev_p, req_p, reply_p) ;
+    }
+    else
+    {
+        ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_NODATA,
+            0, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX,
+                req_p, reply_p, CyAsStorageFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        /* The request and response are freed as part of the FuncCallback */
+        return ret ;
+
+    }
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+static CyAsReturnStatus_t
+MyHandleResponseGetTransferAmount(CyAsDevice* dev_p,
+                         CyAsLLRequestResponse *req_p,
+                         CyAsLLRequestResponse *reply_p,
+                         CyAsMSCProgressData *data)
+{
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    uint8_t code = CyAsLLRequestResponse_GetCode(reply_p) ;
+    uint16_t v1, v2 ;
+
+    if (code != CY_RESP_TRANSFER_COUNT)
+    {
+        ret = CY_AS_ERROR_INVALID_RESPONSE ;
+        goto destroy ;
+    }
+
+    v1 = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+    v2 = CyAsLLRequestResponse_GetWord(reply_p, 1) ;
+    data->wr_count = (uint32_t)((v1 << 16) | v2) ;
+
+    v1 = CyAsLLRequestResponse_GetWord(reply_p, 2) ;
+    v2 = CyAsLLRequestResponse_GetWord(reply_p, 3) ;
+    data->rd_count = (uint32_t)((v1 << 16) | v2) ;
+
+destroy :
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+CyAsReturnStatus_t
+CyAsStorageGetTransferAmount(
+        CyAsDeviceHandle handle,
+        CyAsBusNumber_t  bus,
+        uint32_t device,
+        CyAsMSCProgressData *data_p,
+        CyAsFunctionCallback cb,
+        uint32_t client
+    )
+{
+    CyAsLLRequestResponse *req_p, *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsStorageActive(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 << CyAsMediaNand)))
+        return CY_AS_ERROR_NOT_SUPPORTED ;
+
+    /* Create the request to send to the West Bridge device */
+    req_p = CyAsLLCreateRequest(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 = CyAsLLCreateResponse(dev_p, 4) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, 0x00));
+
+    if(cb == 0)
+    {
+        ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        return MyHandleResponseGetTransferAmount(dev_p, req_p, reply_p, data_p) ;
+    }
+    else
+    {
+        ret = CyAsMiscSendRequest(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, CyAsStorageFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        /* The request and response are freed as part of the FuncCallback */
+        return ret ;
+    }
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+
+}
+
+CyAsReturnStatus_t
+CyAsStorageErase(
+        CyAsDeviceHandle        handle,
+        CyAsBusNumber_t         bus,
+        uint32_t                device,
+        uint32_t                erase_unit,
+        uint16_t                num_erase_units,
+        CyAsFunctionCallback    cb,
+        uint32_t                client
+        )
+{
+    CyAsLLRequestResponse *req_p, *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsStorageActive(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 != CyAsMediaSDFlash)
+        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 = CyAsLLCreateRequest(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 = CyAsLLCreateResponse(dev_p, 4) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, 0x00));
+    CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)((erase_unit >> 16) & 0xffff)) ;
+    CyAsLLRequestResponse_SetWord(req_p, 2, (uint16_t)(erase_unit & 0xffff)) ;
+    CyAsLLRequestResponse_SetWord(req_p, 3, (uint16_t)((num_erase_units >> 8) & 0x00ff)) ;
+    CyAsLLRequestResponse_SetWord(req_p, 4, (uint16_t)((num_erase_units << 8) & 0xff00)) ;
+
+    if(cb == 0)
+    {
+        ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        ret = MyHandleResponseNoData(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 StorageErase. 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 = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_ERASE,
+            0, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX,
+                req_p, reply_p, CyAsStorageFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        /* The request and response are freed as part of the FuncCallback */
+        return ret ;
+    }
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+static void
+CyAsStorageFuncCallback(CyAsDevice *dev_p,
+                        uint8_t context,
+                        CyAsLLRequestResponse *rqt,
+                        CyAsLLRequestResponse *resp,
+                        CyAsReturnStatus_t stat)
+{
+    CyAsFuncCBNode* node = (CyAsFuncCBNode*)dev_p->func_cbs_stor->head_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+
+    CyBool              exRequest = (rqt->flags & CY_AS_REQUEST_RESPONSE_EX) == CY_AS_REQUEST_RESPONSE_EX ;
+    CyBool              msRequest = (rqt->flags & CY_AS_REQUEST_RESPONSE_MS) == CY_AS_REQUEST_RESPONSE_MS ;
+    uint8_t             code ;
+    uint8_t             cntxt ;
+
+    CyAsHalAssert(exRequest || msRequest) ;
+    CyAsHalAssert(dev_p->func_cbs_stor->count != 0) ;
+    CyAsHalAssert(dev_p->func_cbs_stor->type == CYAS_FUNC_CB) ;
+    (void) exRequest;
+    (void) msRequest;
+
+    (void)context ;
+
+    cntxt = CyAsLLRequestResponse_GetContext(rqt) ;
+    CyAsHalAssert(cntxt == CY_RQT_STORAGE_RQT_CONTEXT) ;
+
+    code = CyAsLLRequestResponse_GetCode(rqt) ;
+    switch(code)
+    {
+    case CY_RQT_START_STORAGE:
+        ret = MyHandleResponseStorageStart(dev_p, rqt, resp, stat) ;
+        break ;
+    case CY_RQT_STOP_STORAGE:
+        ret = MyHandleResponseStorageStop(dev_p, rqt, resp, stat) ;
+        break ;
+    case CY_RQT_CLAIM_STORAGE:
+        ret = MyHandleResponseStorageClaim(dev_p, rqt, resp) ;
+        break ;
+    case CY_RQT_RELEASE_STORAGE:
+        ret = MyHandleResponseStorageRelease(dev_p, rqt, resp) ;
+        break ;
+    case CY_RQT_QUERY_MEDIA:
+        CyAsHalAssert(CyFalse) ;        /* Not used any more. */
+        break ;
+    case CY_RQT_QUERY_BUS:
+        CyAsHalAssert(node->data != 0) ;
+        ret = MyHandleResponseStorageQueryBus(dev_p, rqt, resp, (uint32_t*)node->data) ;
+        break ;
+    case CY_RQT_QUERY_DEVICE:
+        CyAsHalAssert(node->data != 0) ;
+        ret = MyHandleResponseStorageQueryDevice(dev_p, rqt, resp, node->data) ;
+        break ;
+    case CY_RQT_QUERY_UNIT:
+        CyAsHalAssert(node->data != 0) ;
+        ret = MyHandleResponseStorageQueryUnit(dev_p, rqt, resp, node->data) ;
+        break ;
+    case CY_RQT_SD_INTERFACE_CONTROL:
+        ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
+        break ;
+    case CY_RQT_SD_REGISTER_READ:
+        CyAsHalAssert(node->data != 0) ;
+        ret = MyHandleResponseSDRegRead(dev_p, rqt, resp, (CyAsStorageSDRegReadData *)node->data) ;
+        break ;
+    case CY_RQT_PARTITION_STORAGE:
+        ret = MyHandleResponseNoData(dev_p, rqt, resp);
+        break ;
+    case CY_RQT_PARTITION_ERASE:
+        ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
+        break ;
+    case CY_RQT_GET_TRANSFER_AMOUNT:
+        CyAsHalAssert(node->data != 0) ;
+        ret = MyHandleResponseGetTransferAmount(dev_p, rqt, resp, (CyAsMSCProgressData *)node->data) ;
+        break ;
+    case CY_RQT_ERASE:
+        ret = MyHandleResponseNoData(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 StorageErase. 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 ;
+        CyAsHalAssert(CyFalse) ;
+        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((CyAsDeviceHandle)dev_p, stat, node->client_data, (CyAsFunctCBType)node->dataType, node->data) ;
+    CyAsRemoveCBNode(dev_p->func_cbs_stor) ;
+}
+
+
+static void
+CyAsSdioSyncReplyCallback(
+        CyAsDevice *dev_p,
+        uint8_t context,
+        CyAsLLRequestResponse *rqt,
+        CyAsLLRequestResponse *resp,
+        CyAsReturnStatus_t ret)
+{
+    (void)rqt ;
+
+    if ((CyAsLLRequestResponse_GetCode(resp) == CY_RESP_SDIO_GET_TUPLE )||
+            (CyAsLLRequestResponse_GetCode(resp) == CY_RESP_SDIO_EXT))
+    {
+        ret = CyAsLLRequestResponse_GetWord(resp, 0) ;
+        if ((ret & 0x00FF) != CY_AS_ERROR_SUCCESS)
+        {
+            if(CyAsLLRequestResponse_GetCode(rqt) == CY_RQT_SDIO_READ_EXTENDED)
+                CyAsDmaCancel(dev_p, dev_p->storage_read_endpoint, ret) ;
+            else
+                CyAsDmaCancel(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 = CyFalse ;
+    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. */
+    CyAsHalWake (&dev_p->context[context]->channel);
+}
+
+CyAsReturnStatus_t
+CyAsSdioDeviceCheck(
+        CyAsDevice*         dev_p,
+        CyAsBusNumber_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 (!CyAsDeviceIsAstoriaDev(dev_p))
+        return CY_AS_ERROR_NOT_SUPPORTED ;
+
+    return  (IsStorageActive(dev_p)) ;
+}
+
+CyAsReturnStatus_t
+CyAsSdioDirectIo(
+        CyAsDeviceHandle    handle,
+        CyAsBusNumber_t     bus,
+        uint32_t            device,
+        uint8_t             nFunctionNo,
+        uint32_t            address,
+        uint8_t             miscBuf,
+        uint16_t            argument,
+        uint8_t             isWrite,
+        uint8_t *           data_p )
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    uint16_t resp_data;
+
+    /*
+     * Sanity checks required before sending the request to the
+     * firmware.
+     */
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+    ret = CyAsSdioDeviceCheck(dev_p,bus,device);
+    if( ret != CY_AS_ERROR_SUCCESS )
+        return ret;
+
+
+    if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo)))
+        return CY_AS_ERROR_INVALID_FUNCTION;
+    if(CyAsSdioCheckFunctionSuspended(handle,bus,nFunctionNo))
+        return CY_AS_ERROR_FUNCTION_SUSPENDED;
+
+    req_p = CyAsLLCreateRequest(dev_p, (isWrite==CyTrue)?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*/
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo) ) ;
+    /* D1 */
+    if(isWrite==CyTrue)
+    {
+        CyAsLLRequestResponse_SetWord(req_p, 1,  ((argument<<8)|0x0080|(nFunctionNo<<4)|
+                    ((miscBuf&CY_SDIO_RAW)<<3)|((miscBuf&CY_SDIO_REARM_INT)>>5)|(uint16_t)(address>>15)));
+    }
+    else
+    {
+        CyAsLLRequestResponse_SetWord(req_p, 1,  (nFunctionNo<<4)|((miscBuf&CY_SDIO_REARM_INT)>>5)|
+                (uint16_t)(address>>15));
+    }
+    /* D2 */
+    CyAsLLRequestResponse_SetWord(req_p, 2,  ((uint16_t)((address&0x00007fff)<<1))) ;
+
+    /*Create response*/
+    reply_p = CyAsLLCreateResponse(dev_p, 2) ;
+
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+
+    /*Sending the request*/
+    ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        goto destroy ;
+
+    /*Check reply type*/
+    if ( CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_SDIO_DIRECT)
+    {
+        resp_data = CyAsLLRequestResponse_GetWord(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)
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+    if(reply_p!=0)
+        CyAsLLDestroyResponse(dev_p, reply_p) ;
+    return ret ;
+}
+
+
+CyAsReturnStatus_t
+CyAsSdioDirectRead(
+        CyAsDeviceHandle        handle,
+        CyAsBusNumber_t         bus,
+        uint32_t                device,
+        uint8_t                 nFunctionNo,
+        uint32_t                address,
+        uint8_t                 miscBuf,
+        uint8_t *               data_p)
+{
+    return (CyAsSdioDirectIo(handle,bus,device, nFunctionNo, address, miscBuf, 0x00, CyFalse, data_p));
+}
+
+CyAsReturnStatus_t
+CyAsSdioDirectWrite(
+        CyAsDeviceHandle        handle,
+        CyAsBusNumber_t         bus,
+        uint32_t                device,
+        uint8_t                 nFunctionNo,
+        uint32_t                address,
+        uint8_t                 miscBuf,
+        uint16_t                argument,
+        uint8_t *               data_p)
+{
+    return (CyAsSdioDirectIo(handle,bus,device, nFunctionNo, address, miscBuf, argument, CyTrue, data_p));
+}
+
+/*Cmd53 IO*/
+CyAsReturnStatus_t
+CyAsSdioExtendedIO(
+        CyAsDeviceHandle        handle,
+        CyAsBusNumber_t         bus,
+        uint32_t                device,
+        uint8_t                 nFunctionNo,
+        uint32_t                address,
+        uint8_t                 miscBuf,
+        uint16_t                argument,
+        uint8_t                 isWrite,
+        uint8_t *               data_p ,
+        uint8_t                 isResume)
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    uint8_t resp_type;
+    uint8_t reqtype;
+    uint16_t resp_data;
+    CyAsContext *ctxt_p ;
+    uint32_t  dmasize,loopcount = 200;
+    CyAsEndPointNumber_t ep;
+
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+    ret = CyAsSdioDeviceCheck(dev_p,bus,device);
+    if( ret != CY_AS_ERROR_SUCCESS )
+        return ret;
+
+
+    if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo)))
+        return CY_AS_ERROR_INVALID_FUNCTION;
+    if(CyAsSdioCheckFunctionSuspended(handle,bus,nFunctionNo))
+        return CY_AS_ERROR_FUNCTION_SUSPENDED;
+
+
+    if ((CyAsDeviceIsStorageAsyncPending(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(isWrite == CyTrue)
+    {
+        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 ;
+    CyAsLLInitRequest(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 ;
+    CyAsLLInitResponse(reply_p, 2) ;
+
+    /* Setup the DMA request */
+    if(!(miscBuf&CY_SDIO_BLOCKMODE))
+    {
+        if(argument > dev_p->sdiocard[bus].function[nFunctionNo-1].blocksize)
+            return CY_AS_ERROR_INVALID_BLOCKSIZE;
+
+    }
+    else
+    {
+        if( argument > 511)
+        {
+            return CY_AS_ERROR_INVALID_BLOCKSIZE;
+        }
+    }
+
+    if(argument == 512)
+        argument =0;
+
+    dmasize=((miscBuf&CY_SDIO_BLOCKMODE) !=0)? dev_p->sdiocard[bus].function[nFunctionNo-1].blocksize*argument:argument;
+
+    ret = CyAsDmaQueueRequest(dev_p, ep, (void*)(data_p), dmasize, CyFalse,
+            (isWrite & CyTrue)?CyFalse:CyTrue, CyAsSyncStorageCallback) ;
+
+    if (ret != CY_AS_ERROR_SUCCESS)
+    {
+        return ret ;
+    }
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo|((isResume)?0x80:0x00) )) ;
+    CyAsLLRequestResponse_SetWord(req_p, 1, ((uint16_t)nFunctionNo)<<12|
+            ((uint16_t)(miscBuf&(CY_SDIO_BLOCKMODE|CY_SDIO_OP_INCR)))<<9|
+            (uint16_t)(address>>7)|((isWrite==CyTrue)?0x8000:0x0000 )) ;
+    CyAsLLRequestResponse_SetWord(req_p, 2, ((uint16_t)(address&0x0000ffff)<<9) |  argument) ;
+
+
+    /* Send the request and wait for completion of storage request */
+    dev_p->storage_wait = CyTrue ;
+    ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyTrue, CyAsSdioSyncReplyCallback) ;
+
+    if (ret != CY_AS_ERROR_SUCCESS)
+    {
+        CyAsDmaCancel(dev_p, ep, CY_AS_ERROR_CANCELED) ;
+    }
+    else
+    {
+        /* Setup the DMA request */
+        ctxt_p = dev_p->context[CY_RQT_STORAGE_RQT_CONTEXT] ;
+        ret = CyAsDmaDrainQueue(dev_p, ep, CyTrue) ;
+
+        while (loopcount-- > 0)
+        {
+            if (dev_p->storage_wait == CyFalse)
+                break;
+            CyAsHalSleepOn(&ctxt_p->channel, 10) ;
+        }
+        if (dev_p->storage_wait == CyTrue)
+        {
+            dev_p->storage_wait = CyFalse ;
+            CyAsLLRemoveRequest(dev_p, ctxt_p, req_p, CyTrue) ;
+            dev_p->storage_error = CY_AS_ERROR_TIMEOUT ;
+        }
+
+        ret=dev_p->storage_error;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+        {
+            return ret ;
+        }
+
+
+        resp_type = CyAsLLRequestResponse_GetCode(dev_p->storage_rw_resp_p) ;
+        if (resp_type == CY_RESP_SDIO_EXT)
+        {
+            resp_data = CyAsLLRequestResponse_GetWord(reply_p, 0)&0x00ff ;
+            if(resp_data)
+            {
+                ret = CY_AS_ERROR_INVALID_REQUEST ;
+            }
+
+        }
+        else
+        {
+            ret = CY_AS_ERROR_INVALID_RESPONSE ;
+        }
+    }
+    return ret;
+
+}
+
+static void
+CyAsSdioAsyncReplyCallback(
+        CyAsDevice*             dev_p,
+        uint8_t                 context,
+        CyAsLLRequestResponse*  rqt,
+        CyAsLLRequestResponse*  resp,
+        CyAsReturnStatus_t      ret )
+{
+    CyAsStorageCallback cb_ms ;
+    uint8_t reqtype ;
+    uint32_t pendingblocks;
+    (void)rqt ;
+    (void)context ;
+
+    pendingblocks = 0;
+    reqtype = CyAsLLRequestResponse_GetCode(rqt) ;
+    if (ret == CY_AS_ERROR_SUCCESS)
+    {
+        if ((CyAsLLRequestResponse_GetCode(resp) == CY_RESP_SUCCESS_FAILURE) ||
+                (CyAsLLRequestResponse_GetCode(resp) == CY_RESP_SDIO_EXT))
+        {
+            ret = CyAsLLRequestResponse_GetWord(resp, 0) ;
+            ret &= 0x00FF ;
+        }
+        else
+        {
+            ret = CY_AS_ERROR_INVALID_RESPONSE ;
+        }
+    }
+
+    if (ret != CY_AS_ERROR_SUCCESS)
+    {
+        if(reqtype == CY_RQT_SDIO_READ_EXTENDED)
+            CyAsDmaCancel(dev_p, dev_p->storage_read_endpoint, ret) ;
+        else
+            CyAsDmaCancel(dev_p, dev_p->storage_write_endpoint, ret) ;
+
+        dev_p->storage_error = ret;
+    }
+
+
+
+    dev_p->storage_wait = CyFalse ;
+
+    /*
+     * If the DMA callback has already been called, the user callback
+     * has to be called from here.
+     */
+    if (!CyAsDeviceIsStorageAsyncPending(dev_p))
+    {
+        CyAsHalAssert(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)CyAsLLRequestResponse_GetWord(resp, 1))<<16;
+        }
+        else
+            ret = CY_AS_ERROR_INVALID_RESPONSE;
+
+        cb_ms((CyAsDeviceHandle)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 ;
+}
+
+
+CyAsReturnStatus_t
+CyAsSdioExtendedIOAsync(
+        CyAsDeviceHandle            handle,
+        CyAsBusNumber_t             bus,
+        uint32_t                    device,
+        uint8_t                     nFunctionNo,
+        uint32_t                    address,
+        uint8_t                     miscBuf,
+        uint16_t                    argument,
+        uint8_t                     isWrite,
+        uint8_t *                   data_p,
+        CyAsStorageCallback       callback )
+{
+
+    uint32_t mask ;
+    uint32_t dmasize;
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    uint8_t reqtype;
+    CyAsEndPointNumber_t ep;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+
+    ret = CyAsSdioDeviceCheck(dev_p,bus,device);
+    if( ret != CY_AS_ERROR_SUCCESS )
+        return ret;
+
+    if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo)))
+        return CY_AS_ERROR_INVALID_FUNCTION;
+    if(CyAsSdioCheckFunctionSuspended(handle,bus,nFunctionNo))
+        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(((miscBuf&CY_SDIO_BLOCKMODE)!=0)&&(argument==0))
+    {
+        callback(handle, bus, device,nFunctionNo,address,((isWrite) ? CyAsOpWrite : CyAsOpRead), 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 = CyAsHalDisableInterrupts() ;
+    if ((CyAsDeviceIsStorageAsyncPending(dev_p)) || (dev_p->storage_wait))
+    {
+        CyAsHalEnableInterrupts(mask) ;
+        return CY_AS_ERROR_ASYNC_PENDING ;
+    }
+    CyAsDeviceSetStorageAsyncPending(dev_p) ;
+    CyAsHalEnableInterrupts(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 = nFunctionNo ;
+    dev_p->storage_block_addr = address ;
+
+    if(isWrite == CyTrue)
+    {
+        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 ;
+    CyAsLLInitRequest(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 ;
+    CyAsLLInitResponse(reply_p, 2) ;
+
+    if(!(miscBuf&CY_SDIO_BLOCKMODE))
+    {
+        if(argument > dev_p->sdiocard[bus].function[nFunctionNo-1].blocksize)
+            return CY_AS_ERROR_INVALID_BLOCKSIZE;
+
+    }
+    else
+    {
+        if( argument > 511)
+        {
+            return CY_AS_ERROR_INVALID_BLOCKSIZE;
+        }
+    }
+
+    if(argument == 512)
+        argument =0;
+    dmasize=((miscBuf&CY_SDIO_BLOCKMODE) !=0)? dev_p->sdiocard[bus].function[nFunctionNo-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 = CyAsDmaQueueRequest(dev_p, ep, (void*)data_p,dmasize , CyFalse, CyTrue,CyAsAsyncStorageCallback) ;
+        dev_p->storage_oper = CyAsOpRead ;
+    }
+    else if (reqtype == CY_RQT_SDIO_WRITE_EXTENDED)
+    {
+        ret = CyAsDmaQueueRequest(dev_p, ep, (void*)data_p, dmasize, CyFalse, CyFalse,CyAsAsyncStorageCallback) ;
+        dev_p->storage_oper = CyAsOpWrite ;
+    }
+    if (ret != CY_AS_ERROR_SUCCESS)
+    {
+        CyAsDeviceClearStorageAsyncPending(dev_p) ;
+        return ret ;
+    }
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo )) ;
+    CyAsLLRequestResponse_SetWord(req_p, 1, ((uint16_t)nFunctionNo)<<12|
+            ((uint16_t)(miscBuf&(CY_SDIO_BLOCKMODE|CY_SDIO_OP_INCR)))<<9|
+            (uint16_t)(address>>7)|((isWrite==CyTrue)?0x8000:0x0000 )) ;
+    CyAsLLRequestResponse_SetWord(req_p, 2, ((uint16_t)(address&0x0000ffff)<<9) |  argument) ;
+
+
+    /* Send the request and wait for completion of storage request */
+    dev_p->storage_wait = CyTrue ;
+    ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyTrue, CyAsSdioAsyncReplyCallback) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+    {
+        CyAsDmaCancel(dev_p, ep, CY_AS_ERROR_CANCELED) ;
+        CyAsDeviceClearStorageAsyncPending(dev_p) ;
+    }
+    else
+    {
+        CyAsDmaKickStart(dev_p, ep) ;
+    }
+
+    return ret ;
+}
+
+/* CMD53 Extended Read*/
+CyAsReturnStatus_t
+CyAsSdioExtendedRead(
+        CyAsDeviceHandle            handle,
+        CyAsBusNumber_t             bus,
+        uint32_t                    device,
+        uint8_t                     nFunctionNo,
+        uint32_t                    address,
+        uint8_t                     miscBuf,
+        uint16_t                    argument,
+        uint8_t *                   data_p,
+        CyAsSdioCallback            callback )
+{
+    if (callback==0)
+        return CyAsSdioExtendedIO(handle,bus,device,nFunctionNo,address,miscBuf,argument,CyFalse,data_p,0);
+
+    return CyAsSdioExtendedIOAsync(handle,bus,device,nFunctionNo,address,miscBuf,argument,CyFalse,data_p,callback);
+}
+
+/* CMD53 Extended Write*/
+CyAsReturnStatus_t
+CyAsSdioExtendedWrite(
+        CyAsDeviceHandle            handle,
+        CyAsBusNumber_t             bus,
+        uint32_t                    device,
+        uint8_t                     nFunctionNo,
+        uint32_t                    address,
+        uint8_t                     miscBuf,
+        uint16_t                    argument,
+        uint8_t *                   data_p,
+        CyAsSdioCallback            callback )
+{
+    if (callback==0)
+        return CyAsSdioExtendedIO(handle,bus,device,nFunctionNo,address,miscBuf,argument,CyTrue,data_p,0);
+
+    return CyAsSdioExtendedIOAsync(handle,bus,device,nFunctionNo,address,miscBuf,argument,CyTrue,data_p,callback);
+}
+
+
+/* Read the CIS info tuples for the given function and Tuple ID*/
+CyAsReturnStatus_t
+CyAsSdioGetCISInfo(
+        CyAsDeviceHandle            handle,
+        CyAsBusNumber_t             bus,
+        uint32_t                    device,
+        uint8_t                     nFunctionNo,
+        uint16_t                    tupleId,
+        uint8_t *                   data_p )
+{
+
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    uint16_t resp_data;
+    CyAsContext *ctxt_p ;
+    uint32_t loopcount = 200;
+
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+
+    ret = CyAsSdioDeviceCheck(dev_p,bus,device);
+    if( ret != CY_AS_ERROR_SUCCESS )
+        return ret;
+
+    if(!( CyAsSdioCheckFunctionInitialized(handle,bus,0) ))
+        return CY_AS_ERROR_INVALID_FUNCTION;
+
+    if ((CyAsDeviceIsStorageAsyncPending(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 ;
+    CyAsLLInitRequest(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 ;
+    CyAsLLInitResponse(reply_p, 3) ;
+
+    /* Setup the DMA request */
+    ret = CyAsDmaQueueRequest(dev_p, dev_p->storage_read_endpoint, data_p+1, 255, CyFalse, CyTrue,
+            CyAsSyncStorageCallback) ;
+
+    if (ret != CY_AS_ERROR_SUCCESS)
+    {
+        return ret ;
+    }
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo )) ;
+
+    /* Set tuple id to fetch. */
+    CyAsLLRequestResponse_SetWord(req_p, 1, tupleId<<8) ;
+
+    /* Send the request and wait for completion of storage request */
+    dev_p->storage_wait = CyTrue ;
+    ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyTrue, CyAsSdioSyncReplyCallback) ;
+
+
+    if (ret != CY_AS_ERROR_SUCCESS)
+    {
+        CyAsDmaCancel(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 = CyAsDmaDrainQueue(dev_p, dev_p->storage_read_endpoint, CyTrue) ;
+
+        while (loopcount-- > 0)
+        {
+            if (dev_p->storage_wait == CyFalse)
+                break;
+            CyAsHalSleepOn(&ctxt_p->channel, 10) ;
+        }
+
+        if (dev_p->storage_wait == CyTrue)
+        {
+            dev_p->storage_wait = CyFalse ;
+            CyAsLLRemoveRequest(dev_p, ctxt_p, req_p, CyTrue) ;
+            return CY_AS_ERROR_TIMEOUT ;
+        }
+        ret = dev_p->storage_error ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+        {
+            return ret ;
+        }
+
+        if ( CyAsLLRequestResponse_GetCode(dev_p->storage_rw_resp_p) == CY_RESP_SDIO_GET_TUPLE)
+        {
+            resp_data = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+            if(resp_data)
+            {
+                ret = CY_AS_ERROR_INVALID_REQUEST ;
+            }
+            else if (data_p!=0)
+                *(uint8_t*)data_p=(uint8_t)(CyAsLLRequestResponse_GetWord(reply_p, 0)&0x00ff);
+        }
+        else
+        {
+            ret = CY_AS_ERROR_INVALID_RESPONSE ;
+        }
+    }
+    return ret;
+}
+
+/*Query Device*/
+CyAsReturnStatus_t
+CyAsSdioQueryCard(
+        CyAsDeviceHandle            handle,
+        CyAsBusNumber_t             bus,
+        uint32_t                    device,
+        CyAsSDIOCard*               data_p )
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+
+    uint8_t resp_type;
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+
+    ret = CyAsSdioDeviceCheck(dev_p,bus,device);
+    if( ret != CY_AS_ERROR_SUCCESS )
+        return ret;
+
+    /* Allocating memory to the SDIO device structure in dev_p */
+
+    CyAsHalMemSet(& dev_p->sdiocard[bus],0,sizeof(CyAsSDIODevice));
+
+    req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SDIO_QUERY_CARD, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
+    if (req_p == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, 0 )) ;
+
+    reply_p = CyAsLLCreateResponse(dev_p, 5) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+
+    ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+
+    if (ret != CY_AS_ERROR_SUCCESS)
+        goto destroy ;
+
+    resp_type = CyAsLLRequestResponse_GetCode(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 = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+        else
+            ret = CY_AS_ERROR_INVALID_RESPONSE ;
+    }
+destroy:
+    if(req_p!=0)
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+    if(reply_p!=0)
+        CyAsLLDestroyResponse(dev_p, reply_p) ;
+    return ret ;
+}
+
+/*Reset SDIO card. */
+CyAsReturnStatus_t
+CyAsSdioResetCard(
+        CyAsDeviceHandle            handle,
+        CyAsBusNumber_t         bus,
+        uint32_t                device )
+{
+
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    uint8_t resp_type;
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+
+    ret = CyAsSdioDeviceCheck(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 = CyAsLLCreateRequest(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 */
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, 0) ) ;
+
+    reply_p = CyAsLLCreateResponse(dev_p, 2) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+
+    ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+
+
+    if (ret != CY_AS_ERROR_SUCCESS)
+        goto destroy ;
+
+
+    resp_type = CyAsLLRequestResponse_GetCode(reply_p) ;
+
+
+    if (resp_type == CY_RESP_SUCCESS_FAILURE)
+    {
+        ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+        if(ret == CY_AS_ERROR_SUCCESS)
+        {
+            ret = CyAsSdioQueryCard(handle,bus,device,0);
+        }
+    }
+    else
+        ret = CY_AS_ERROR_INVALID_RESPONSE ;
+
+destroy:
+    if(req_p!=0)
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+    if(reply_p!=0)
+        CyAsLLDestroyResponse(dev_p, reply_p) ;
+    return ret ;
+}
+
+/* Initialise an IO function*/
+CyAsReturnStatus_t
+CyAsSdioInitFunction(
+        CyAsDeviceHandle            handle,
+        CyAsBusNumber_t             bus,
+        uint32_t                    device,
+        uint8_t                     nFunctionNo,
+        uint8_t                     miscBuf     )
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    uint8_t resp_type;
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+
+    ret = CyAsSdioDeviceCheck(dev_p,bus,device);
+
+    if( ret != CY_AS_ERROR_SUCCESS )
+        return ret;
+
+    if(!(CyAsSdioCheckFunctionInitialized(handle,bus,0)))
+        return CY_AS_ERROR_NOT_RUNNING;
+
+    if((CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo)))
+    {
+        if(miscBuf&CY_SDIO_FORCE_INIT)
+            dev_p->sdiocard[bus].function_init_map&=(~(1<<nFunctionNo));
+        else
+            return CY_AS_ERROR_ALREADY_RUNNING;
+    }
+
+    req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SDIO_INIT_FUNCTION, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
+    if (req_p == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo )) ;
+
+    reply_p = CyAsLLCreateResponse(dev_p, 5) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+
+    ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+
+    if (ret != CY_AS_ERROR_SUCCESS)
+        goto destroy ;
+
+    resp_type = CyAsLLRequestResponse_GetCode(reply_p) ;
+
+    if (resp_type == CY_RESP_SDIO_INIT_FUNCTION)
+    {
+
+        dev_p->sdiocard[bus].function[nFunctionNo-1].function_code      = (uint8_t)((reply_p->data[0]&0xff00)>>8);
+        dev_p->sdiocard[bus].function[nFunctionNo-1].extended_func_code = (uint8_t)reply_p->data[0]&0x00ff;
+        dev_p->sdiocard[bus].function[nFunctionNo-1].blocksize          =  reply_p->data[1];
+        dev_p->sdiocard[bus].function[nFunctionNo-1].maxblocksize       =  reply_p->data[1];
+        dev_p->sdiocard[bus].function[nFunctionNo-1].card_psn           = (uint32_t)(reply_p->data[2])<<16;
+        dev_p->sdiocard[bus].function[nFunctionNo-1].card_psn           |=(uint32_t)(reply_p->data[3]);
+        dev_p->sdiocard[bus].function[nFunctionNo-1].csa_bits           = (uint8_t)((reply_p->data[4]&0xff00)>>8);
+        dev_p->sdiocard[bus].function[nFunctionNo-1].wakeup_support     = (uint8_t)(reply_p->data[4]&0x0001);
+        dev_p->sdiocard[bus].function_init_map                          |= (1<<nFunctionNo);
+        CyAsSdioClearFunctionSuspended(handle,bus,nFunctionNo);
+
+    }
+    else
+    {
+        if (resp_type == CY_RESP_SUCCESS_FAILURE)
+            ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+        else
+            ret = CY_AS_ERROR_INVALID_FUNCTION ;
+    }
+
+destroy:
+    if(req_p!=0)
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+    if(reply_p!=0)
+        CyAsLLDestroyResponse(dev_p, reply_p) ;
+    return ret ;
+}
+
+/*Query individual functions. */
+CyAsReturnStatus_t
+CyAsSdioQueryFunction(
+        CyAsDeviceHandle            handle,
+        CyAsBusNumber_t             bus,
+        uint32_t                    device,
+        uint8_t                     nFunctionNo,
+        CyAsSDIOFunc*               data_p )
+{
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+    CyAsReturnStatus_t ret;
+
+    ret = CyAsSdioDeviceCheck(dev_p,bus,device);
+    if( ret != CY_AS_ERROR_SUCCESS )
+        return ret;
+
+    if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo)))
+        return CY_AS_ERROR_INVALID_FUNCTION;
+
+    data_p->blocksize           =   dev_p->sdiocard[bus].function[nFunctionNo-1].blocksize;
+    data_p->card_psn            =   dev_p->sdiocard[bus].function[nFunctionNo-1].card_psn;
+    data_p->csa_bits            =   dev_p->sdiocard[bus].function[nFunctionNo-1].csa_bits;
+    data_p->extended_func_code  =   dev_p->sdiocard[bus].function[nFunctionNo-1].extended_func_code;
+    data_p->function_code       =   dev_p->sdiocard[bus].function[nFunctionNo-1].function_code;
+    data_p->maxblocksize        =   dev_p->sdiocard[bus].function[nFunctionNo-1].maxblocksize;
+    data_p->wakeup_support      =   dev_p->sdiocard[bus].function[nFunctionNo-1].wakeup_support;
+
+
+    return CY_AS_ERROR_SUCCESS;
+}
+
+/* Abort the Current Extended IO Operation*/
+CyAsReturnStatus_t
+CyAsSdioAbortFunction(
+        CyAsDeviceHandle            handle,
+        CyAsBusNumber_t             bus,
+        uint32_t                    device,
+        uint8_t                     nFunctionNo)
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    uint8_t resp_type;
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+
+    ret = CyAsSdioDeviceCheck(dev_p,bus,device);
+    if( ret != CY_AS_ERROR_SUCCESS )
+        return ret;
+
+    if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo)))
+        return CY_AS_ERROR_INVALID_FUNCTION;
+
+    if ((CyAsDeviceIsStorageAsyncPending(dev_p)) || (dev_p->storage_wait))
+    {
+        if(!(CyAsSdioGetCardCapability(handle,bus) & CY_SDIO_SDC ))
+        {
+            return CY_AS_ERROR_INVALID_COMMAND;
+        }
+    }
+
+    req_p = CyAsLLCreateRequest(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 */
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo) ) ;
+
+    reply_p = CyAsLLCreateResponse(dev_p, 2) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+
+    ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        goto destroy ;
+
+    resp_type = CyAsLLRequestResponse_GetCode(reply_p) ;
+
+    if (resp_type == CY_RESP_SUCCESS_FAILURE)
+        ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+    else
+        ret = CY_AS_ERROR_INVALID_RESPONSE ;
+
+
+destroy:
+    if(req_p!=0)
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+    if(reply_p!=0)
+        CyAsLLDestroyResponse(dev_p, reply_p) ;
+    return ret ;
+}
+
+/* Suspend IO to current function*/
+CyAsReturnStatus_t
+CyAsSdioSuspend(
+        CyAsDeviceHandle        handle,
+        CyAsBusNumber_t         bus,
+        uint32_t                device,
+        uint8_t                 nFunctionNo)
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+
+    ret = CyAsSdioDeviceCheck(dev_p,bus,device);
+    if( ret != CY_AS_ERROR_SUCCESS )
+        return ret;
+
+    if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo)))
+        return CY_AS_ERROR_INVALID_FUNCTION;
+    if(!(CyAsSdioCheckSupportBusSuspend(handle,bus)))
+        return CY_AS_ERROR_INVALID_FUNCTION;
+    if(!(CyAsSdioGetCardCapability(handle,bus) & CY_SDIO_SDC))
+        return CY_AS_ERROR_INVALID_FUNCTION;
+    if(CyAsSdioCheckFunctionSuspended(handle,bus,nFunctionNo))
+        return CY_AS_ERROR_FUNCTION_SUSPENDED;
+
+    req_p = CyAsLLCreateRequest(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 */
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo) ) ;
+
+    reply_p = CyAsLLCreateResponse(dev_p, 2) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+    ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+
+    if (ret == CY_AS_ERROR_SUCCESS)
+    {
+        ret = CyAsLLRequestResponse_GetCode(reply_p) ;
+        CyAsSdioSetFunctionSuspended(handle,bus,nFunctionNo);
+    }
+
+    if(req_p!=0)
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+    if(reply_p!=0)
+        CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+/*Resume suspended function*/
+CyAsReturnStatus_t
+CyAsSdioResume(
+        CyAsDeviceHandle        handle,
+        CyAsBusNumber_t         bus,
+        uint32_t                device,
+        uint8_t                 nFunctionNo,
+        CyAsOperType            op,
+        uint8_t                 miscBuf,
+        uint16_t                pendingblockcount,
+        uint8_t                 *data_p
+        )
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t resp_data, ret = CY_AS_ERROR_SUCCESS ;
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+
+    ret = CyAsSdioDeviceCheck(dev_p,bus,device);
+    if( ret != CY_AS_ERROR_SUCCESS )
+        return ret;
+
+    if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo)))
+        return CY_AS_ERROR_INVALID_FUNCTION;
+
+    /* If suspend resume is not supported return */
+    if(!(CyAsSdioCheckSupportBusSuspend(handle,bus)))
+        return CY_AS_ERROR_INVALID_FUNCTION;
+
+    /* if the function is not suspended return. */
+    if(!(CyAsSdioCheckFunctionSuspended(handle,bus,nFunctionNo)))
+        return CY_AS_ERROR_INVALID_FUNCTION;
+
+    req_p = CyAsLLCreateRequest(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 */
+    CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo) ) ;
+
+    reply_p = CyAsLLCreateResponse(dev_p, 2) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+    ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+
+    if (ret != CY_AS_ERROR_SUCCESS)
+        goto destroy ;
+
+
+    if ( CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_SDIO_RESUME)
+    {
+        resp_data = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+        if(resp_data & 0x00ff)
+        {
+            /* Send extended read request to resume the read. */
+            if(op == CyAsOpRead)
+            {
+                ret = CyAsSdioExtendedIO(handle,bus,device,nFunctionNo,0,miscBuf,pendingblockcount,CyFalse,data_p,1);
+            }
+            else
+            {
+                ret = CyAsSdioExtendedIO(handle,bus,device,nFunctionNo,0,miscBuf,pendingblockcount,CyTrue,data_p,1);
+            }
+        }
+        else
+        {
+            ret= CY_AS_ERROR_SUCCESS;
+        }
+
+    }
+    else
+    {
+        ret = CY_AS_ERROR_INVALID_RESPONSE ;
+    }
+
+destroy:
+    CyAsSdioClearFunctionSuspended(handle,bus,nFunctionNo);
+    if(req_p!=0)
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+    if(reply_p!=0)
+        CyAsLLDestroyResponse(dev_p, reply_p) ;
+    return ret ;
+
+}
+
+/*Set function blocksize. Size cannot exceed max block size for the function*/
+CyAsReturnStatus_t
+CyAsSdioSetBlocksize(
+        CyAsDeviceHandle            handle,
+        CyAsBusNumber_t             bus,
+        uint32_t                    device,
+        uint8_t                     nFunctionNo,
+        uint16_t                    blocksize)
+{
+    CyAsReturnStatus_t ret;
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+    ret = CyAsSdioDeviceCheck(dev_p,bus,device);
+    if( ret != CY_AS_ERROR_SUCCESS )
+        return ret;
+
+    if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo)))
+        return CY_AS_ERROR_INVALID_FUNCTION;
+    if( nFunctionNo == 0)
+    {
+        if ( blocksize > CyAsSdioGetCardMaxBlocksize(handle,bus))
+            return CY_AS_ERROR_INVALID_BLOCKSIZE;
+        else if (blocksize == CyAsSdioGetCardBlocksize(handle,bus))
+            return CY_AS_ERROR_SUCCESS;
+    }
+    else
+    {
+        if ( blocksize > CyAsSdioGetFunctionMaxBlocksize(handle,bus,nFunctionNo))
+            return CY_AS_ERROR_INVALID_BLOCKSIZE;
+        else if (blocksize == CyAsSdioGetFunctionBlocksize(handle,bus,nFunctionNo))
+            return CY_AS_ERROR_SUCCESS;
+    }
+
+    ret = CyAsSdioDirectWrite(handle,bus,device,0,(uint16_t)(nFunctionNo<<8)|0x10,0,blocksize&0x00ff,0);
+    if(ret != CY_AS_ERROR_SUCCESS )
+        return ret;
+    ret = CyAsSdioDirectWrite(handle,bus,device,0,(uint16_t)(nFunctionNo<<8)|0x11,0,(blocksize&0xff00)>>8,0);
+    if (ret != CY_AS_ERROR_SUCCESS )
+        return ret;
+
+    if(nFunctionNo ==0)
+        CyAsSdioSetCardBlockSize(handle,bus,blocksize);
+    else
+        CyAsSdioSetFunctionBlockSize(handle,bus,nFunctionNo,blocksize);
+    return ret;
+}
+
+/* Deinitialize an SDIO function*/
+CyAsReturnStatus_t
+CyAsSdioDeInitFunction(
+        CyAsDeviceHandle            handle,
+        CyAsBusNumber_t             bus,
+        uint32_t                    device,
+        uint8_t                     nFunctionNo)
+{
+    CyAsReturnStatus_t ret;
+    uint8_t temp;
+
+    if(nFunctionNo == 0)
+        return CY_AS_ERROR_INVALID_FUNCTION;
+
+    ret = CyAsSdioDeviceCheck((CyAsDevice*)handle,bus,device);
+    if( ret != CY_AS_ERROR_SUCCESS )
+        return ret;
+
+    if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo)))
+        return CY_AS_ERROR_SUCCESS;
+
+    temp =(uint8_t)(((CyAsDevice*)handle)->sdiocard[bus].function_init_map & (~(1<<nFunctionNo)));
+    CyAsSdioDirectWrite(handle,bus,device,0,0x02,0,temp,0);
+    ((CyAsDevice*)handle)->sdiocard[bus].function_init_map &= (~(1<<nFunctionNo));
+
+    return CY_AS_ERROR_SUCCESS;
+}
+
+/* This includes the implementation of the deprecated functions for backward
+ * compatibility
+ */
+#include "cyasstorage_dep_impl.h"
+
+/*[]*/