omap3530/beagle_drivers/wb/api/src/cyasusb.c
changeset 27 117faf51deac
child 52 254b9435d75e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omap3530/beagle_drivers/wb/api/src/cyasusb.c	Wed Mar 03 13:10:32 2010 +0000
@@ -0,0 +1,3613 @@
+/* Cypress West Bridge API source file (cyasusb.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.
+##
+## ===========================
+*/
+
+#include "cyashal.h"
+#include "cyasusb.h"
+#include "cyaserr.h"
+#include "cyasdma.h"
+#include "cyaslowlevel.h"
+#include "cyaslep2pep.h"
+#include "cyasregs.h"
+#include "cyasstorage.h"
+
+extern CyAsMediaType
+CyAsStorageGetMediaFromAddress(uint16_t v) ;
+
+extern CyAsBusNumber_t
+CyAsStorageGetBusFromAddress(uint16_t v) ;
+
+extern uint32_t
+CyAsStorageGetDeviceFromAddress(uint16_t v) ;
+
+static CyAsReturnStatus_t
+CyAsUsbAckSetupPacket(
+                      CyAsDeviceHandle                  handle,         /* Handle to the West Bridge device */
+                      CyAsFunctionCallback              cb,             /* The callback if async call */
+                      uint32_t                          client          /* Client supplied data */
+                      ) ;
+
+static void
+CyAsUsbFuncCallback(
+                    CyAsDevice *dev_p,
+                    uint8_t context,
+                    CyAsLLRequestResponse *rqt,
+                    CyAsLLRequestResponse *resp,
+                    CyAsReturnStatus_t ret) ;
+/*
+* Reset the USB EP0 state
+*/
+static void
+CyAsUsbResetEP0State(CyAsDevice *dev_p)
+{
+    CyAsLogDebugMessage(6, "CyAsUsbResetEP0State called") ;
+
+    CyAsDeviceClearAckDelayed(dev_p) ;
+    CyAsDeviceClearSetupPacket(dev_p) ;
+    if (CyAsDeviceIsUsbAsyncPending(dev_p, 0))
+        CyAsUsbCancelAsync((CyAsDeviceHandle)dev_p, 0) ;
+
+    dev_p->usb_pending_buffer = 0 ;
+}
+
+/*
+* External function to map logical endpoints to physical endpoints
+*/
+static CyAsReturnStatus_t
+IsUsbActive(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->usb_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
+UsbAckCallback(CyAsDeviceHandle h,
+               CyAsReturnStatus_t status,
+               uint32_t client,
+               CyAsFunctCBType  type,
+               void* data)
+{
+    CyAsDevice *dev_p = (CyAsDevice *)h ;
+
+    (void)client ;
+    (void)status ;
+    (void)data ;
+
+    CyAsHalAssert(type == CY_FUNCT_CB_NODATA) ;
+
+    if (dev_p->usb_pending_buffer)
+    {
+        CyAsUsbIoCallback cb ;
+
+        cb = dev_p->usb_cb[0] ;
+        dev_p->usb_cb[0] = 0 ;
+        CyAsDeviceClearUsbAsyncPending(dev_p, 0) ;
+        if (cb)
+            cb(h, 0, dev_p->usb_pending_size, dev_p->usb_pending_buffer, dev_p->usb_error) ;
+
+        dev_p->usb_pending_buffer = 0 ;
+    }
+
+    CyAsDeviceClearSetupPacket(dev_p) ;
+}
+
+static void
+MyUsbRequestCallbackUsbEvent(CyAsDevice *dev_p, CyAsLLRequestResponse *req_p)
+{
+    uint16_t ev ;
+    uint16_t val ;
+    CyAsDeviceHandle h = (CyAsDeviceHandle)dev_p ;
+
+    ev = CyAsLLRequestResponse_GetWord(req_p, 0) ;
+    switch(ev)
+    {
+    case 0:             /* Reserved */
+        CyAsLLSendStatusResponse(dev_p, CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_INVALID_REQUEST, 0) ;
+        break ;
+
+    case 1:             /* Reserved */
+        CyAsLLSendStatusResponse(dev_p, CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_INVALID_REQUEST, 0) ;
+        break ;
+
+    case 2:             /* USB Suspend */
+        dev_p->usb_last_event = CyAsEventUsbSuspend ;
+        if (dev_p->usb_event_cb_ms)
+            dev_p->usb_event_cb_ms(h, CyAsEventUsbSuspend, 0) ;
+        else if (dev_p->usb_event_cb)
+            dev_p->usb_event_cb(h, CyAsEventUsbSuspend, 0) ;
+        CyAsLLSendStatusResponse(dev_p, CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+        break;
+
+    case 3:             /* USB Resume */
+        dev_p->usb_last_event = CyAsEventUsbResume ;
+        if (dev_p->usb_event_cb_ms)
+            dev_p->usb_event_cb_ms(h, CyAsEventUsbResume, 0) ;
+        else if (dev_p->usb_event_cb)
+            dev_p->usb_event_cb(h, CyAsEventUsbResume, 0) ;
+        CyAsLLSendStatusResponse(dev_p, CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+        break ;
+
+    case 4:             /* USB Reset */
+        /*
+        * If we get a USB reset, the USB host did not understand our response
+        * or we timed out for some reason.  Reset our internal state to be ready for
+        * another set of enumeration based requests.
+        */
+        if (CyAsDeviceIsAckDelayed(dev_p))
+        {
+            CyAsUsbResetEP0State(dev_p) ;
+        }
+
+        dev_p->usb_last_event = CyAsEventUsbReset ;
+        if (dev_p->usb_event_cb_ms)
+            dev_p->usb_event_cb_ms(h, CyAsEventUsbReset, 0) ;
+        else if (dev_p->usb_event_cb)
+            dev_p->usb_event_cb(h, CyAsEventUsbReset, 0) ;
+
+        CyAsLLSendStatusResponse(dev_p, CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+        CyAsDeviceClearUsbHighSpeed(dev_p) ;
+        CyAsUsbSetDmaSizes(dev_p) ;
+        dev_p->usb_max_tx_size = 0x40 ;
+        CyAsDmaSetMaxDmaSize(dev_p, 0x06, 0x40) ;
+        break ;
+
+    case 5:             /* USB Set Configuration */
+        val = CyAsLLRequestResponse_GetWord(req_p, 1) ;                 /* The configuration to set */
+        dev_p->usb_last_event = CyAsEventUsbSetConfig ;
+        if (dev_p->usb_event_cb_ms)
+            dev_p->usb_event_cb_ms(h, CyAsEventUsbSetConfig, &val) ;
+        else if (dev_p->usb_event_cb)
+            dev_p->usb_event_cb(h, CyAsEventUsbSetConfig, &val) ;
+        CyAsLLSendStatusResponse(dev_p, CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+        break ;
+
+    case 6:             /* USB Speed change */
+        val = CyAsLLRequestResponse_GetWord(req_p, 1) ;                 /* Connect speed */
+        dev_p->usb_last_event = CyAsEventUsbSpeedChange ;
+        if (dev_p->usb_event_cb_ms)
+            dev_p->usb_event_cb_ms(h, CyAsEventUsbSpeedChange, &val) ;
+        else if (dev_p->usb_event_cb)
+            dev_p->usb_event_cb(h, CyAsEventUsbSpeedChange, &val) ;
+        CyAsLLSendStatusResponse(dev_p, CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+        CyAsDeviceSetUsbHighSpeed(dev_p) ;
+        CyAsUsbSetDmaSizes(dev_p) ;
+        dev_p->usb_max_tx_size = 0x200 ;
+        CyAsDmaSetMaxDmaSize(dev_p, 0x06, 0x200) ;
+        break ;
+
+    case 7:             /* USB Clear Feature */
+        val = CyAsLLRequestResponse_GetWord(req_p, 1) ;                 /* EP Number */
+        if (dev_p->usb_event_cb_ms)
+            dev_p->usb_event_cb_ms(h, CyAsEventUsbClearFeature, &val) ;
+        if (dev_p->usb_event_cb)
+            dev_p->usb_event_cb(h, CyAsEventUsbClearFeature, &val) ;
+        CyAsLLSendStatusResponse(dev_p, CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+        break ;
+
+    default:
+        CyAsHalPrintMessage("Invalid event type\n") ;
+        CyAsLLSendDataResponse(dev_p, CY_RQT_USB_RQT_CONTEXT, CY_RESP_USB_INVALID_EVENT, sizeof(ev), &ev) ;
+        break ;
+    }
+}
+
+static void
+MyUsbRequestCallbackUsbData(CyAsDevice *dev_p, CyAsLLRequestResponse *req_p)
+{
+    CyAsEndPointNumber_t ep ;
+    uint8_t type ;
+    uint16_t len ;
+    uint16_t val ;
+    CyAsDeviceHandle h = (CyAsDeviceHandle)dev_p ;
+
+    val = CyAsLLRequestResponse_GetWord(req_p, 0) ;
+    ep = (CyAsEndPointNumber_t)((val >> 13) & 0x01) ;
+    len = (val & 0x1ff) ;
+
+    CyAsHalAssert(len <= 64) ;
+    CyAsLLRequestResponse_Unpack(req_p, 1, len, dev_p->usb_ep_data) ;
+
+    type = (uint8_t)((val >> 14) & 0x03) ;
+    if (type == 0)
+    {
+        if (CyAsDeviceIsAckDelayed(dev_p))
+        {
+            /*
+            * A setup packet has arrived while we are processing a previous setup packet.
+            * Reset our state with respect to EP0 to be ready to process the new packet.
+            */
+            CyAsUsbResetEP0State(dev_p) ;
+        }
+
+        if (len != 8)
+            CyAsLLSendStatusResponse(dev_p, CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_INVALID_REQUEST, 0) ;
+        else
+        {
+            CyAsDeviceClearEp0Stalled(dev_p) ;
+            CyAsDeviceSetSetupPacket(dev_p) ;
+            CyAsLLSendStatusResponse(dev_p, CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+            if (dev_p->usb_event_cb_ms)
+                dev_p->usb_event_cb_ms(h, CyAsEventUsbSetupPacket, dev_p->usb_ep_data) ;
+            else
+                dev_p->usb_event_cb(h, CyAsEventUsbSetupPacket, dev_p->usb_ep_data) ;
+
+            if ((!CyAsDeviceIsAckDelayed(dev_p)) && (!CyAsDeviceIsEp0Stalled(dev_p)))
+            {
+                CyAsUsbAckSetupPacket(h, UsbAckCallback, 0) ;
+            }
+        }
+    }
+    else if (type == 2)
+    {
+        if (len != 0)
+            CyAsLLSendStatusResponse(dev_p, CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_INVALID_REQUEST, 0) ;
+        else
+        {
+            if (dev_p->usb_event_cb_ms)
+                dev_p->usb_event_cb_ms(h, CyAsEventUsbStatusPacket, 0) ;
+            else
+                dev_p->usb_event_cb(h, CyAsEventUsbStatusPacket, 0) ;
+
+            CyAsLLSendStatusResponse(dev_p, CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+        }
+    }
+    else if (type == 1)
+    {
+        /*
+        * We need to hand the data associated with these endpoints to the DMA
+        * module.
+        */
+        CyAsDmaReceivedData(dev_p, ep, len, dev_p->usb_ep_data) ;
+        CyAsLLSendStatusResponse(dev_p, CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+    }
+}
+
+static void
+MyUsbRequestCallbackInquiry(CyAsDevice *dev_p, CyAsLLRequestResponse *req_p)
+{
+    CyAsUsbInquiryData_dep cbdata ;
+    CyAsUsbInquiryData cbdata_ms ;
+    void *data ;
+    uint16_t val ;
+    CyAsDeviceHandle h = (CyAsDeviceHandle)dev_p ;
+    uint8_t def_inq_data[64] ;
+    uint8_t evpd ;
+    uint8_t codepage ;
+    CyBool updated ;
+    uint16_t length ;
+
+    CyAsBusNumber_t bus ;
+    uint32_t        device ;
+    CyAsMediaType   media ;
+
+    val    = CyAsLLRequestResponse_GetWord(req_p, 0) ;
+    bus    = CyAsStorageGetBusFromAddress(val) ;
+    device = CyAsStorageGetDeviceFromAddress(val) ;
+    media  = CyAsStorageGetMediaFromAddress(val) ;
+
+    val      = CyAsLLRequestResponse_GetWord(req_p, 1) ;
+    evpd     = (uint8_t)((val >> 8) & 0x01) ;
+    codepage = (uint8_t)(val & 0xff) ;
+
+    length = CyAsLLRequestResponse_GetWord(req_p, 2) ;
+    data   = (void *)def_inq_data ;
+
+    updated = CyFalse ;
+
+    if (dev_p->usb_event_cb_ms)
+    {
+        cbdata_ms.bus = bus ;
+        cbdata_ms.device = device ;
+        cbdata_ms.updated = updated ;
+        cbdata_ms.evpd = evpd ;
+        cbdata_ms.codepage = codepage ;
+        cbdata_ms.length = length ;
+        cbdata_ms.data = data ;
+
+        CyAsHalAssert(cbdata_ms.length <= sizeof(def_inq_data)) ;
+        CyAsLLRequestResponse_Unpack(req_p, 3, cbdata_ms.length, cbdata_ms.data) ;
+
+        dev_p->usb_event_cb_ms(h, CyAsEventUsbInquiryBefore, &cbdata_ms) ;
+
+        updated = cbdata_ms.updated;
+        data    = cbdata_ms.data ;
+        length  = cbdata_ms.length ;
+    }
+    else if (dev_p->usb_event_cb)
+    {
+        cbdata.media = media ;
+        cbdata.updated = updated ;
+        cbdata.evpd = evpd ;
+        cbdata.codepage = codepage ;
+        cbdata.length = length ;
+        cbdata.data = data ;
+
+        CyAsHalAssert(cbdata.length <= sizeof(def_inq_data)) ;
+        CyAsLLRequestResponse_Unpack(req_p, 3, cbdata.length, cbdata.data) ;
+
+        dev_p->usb_event_cb(h, CyAsEventUsbInquiryBefore, &cbdata) ;
+
+        updated = cbdata.updated ;
+        data    = cbdata.data ;
+        length  = cbdata.length ;
+    }
+
+    if (updated && length > 192)
+        CyAsHalPrintMessage("An inquiry result from a CyAsEventUsbInquiryBefore event was greater than 192 bytes.") ;
+
+    /* Now send the reply with the data back to the West Bridge device */
+    if (updated && length <= 192)
+    {
+        /*
+        * The callback function modified the inquiry data, ship the data back
+        * to the West Bridge firmware.
+        */
+        CyAsLLSendDataResponse(dev_p, CY_RQT_USB_RQT_CONTEXT, CY_RESP_INQUIRY_DATA, length, data) ;
+    }
+    else
+    {
+        /*
+        * The callback did not modify the data, just acknowledge that we
+        * processed the request
+        */
+        CyAsLLSendStatusResponse(dev_p, CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 1) ;
+    }
+
+    if (dev_p->usb_event_cb_ms)
+        dev_p->usb_event_cb_ms(h, CyAsEventUsbInquiryAfter, &cbdata_ms) ;
+    else if (dev_p->usb_event_cb)
+        dev_p->usb_event_cb(h, CyAsEventUsbInquiryAfter, &cbdata) ;
+}
+
+static void
+MyUsbRequestCallbackStartStop(CyAsDevice *dev_p, CyAsLLRequestResponse *req_p)
+{
+    CyAsBusNumber_t bus ;
+    CyAsMediaType media ;
+    uint32_t device ;
+    uint16_t val ;
+
+    if (dev_p->usb_event_cb_ms || dev_p->usb_event_cb)
+    {
+        CyBool loej ;
+        CyBool start ;
+        CyAsDeviceHandle h = (CyAsDeviceHandle)dev_p ;
+
+        val = CyAsLLRequestResponse_GetWord(req_p, 0) ;
+        bus = CyAsStorageGetBusFromAddress(val) ;
+        device = CyAsStorageGetDeviceFromAddress(val) ;
+        media = CyAsStorageGetMediaFromAddress(val) ;
+
+        val = CyAsLLRequestResponse_GetWord(req_p, 1) ;
+        loej = (val & 0x02) ? CyTrue : CyFalse ;
+        start = (val & 0x01) ? CyTrue: CyFalse ;
+
+        if (dev_p->usb_event_cb_ms)
+        {
+            CyAsUsbStartStopData cbdata_ms ;
+
+            cbdata_ms.bus = bus ;
+            cbdata_ms.device = device ;
+            cbdata_ms.loej = loej ;
+            cbdata_ms.start = start ;
+            dev_p->usb_event_cb_ms(h, CyAsEventUsbStartStop, &cbdata_ms) ;
+        }
+        else if (dev_p->usb_event_cb)
+        {
+            CyAsUsbStartStopData_dep cbdata ;
+
+            cbdata.media = media ;
+            cbdata.loej = loej ;
+            cbdata.start = start ;
+            dev_p->usb_event_cb(h, CyAsEventUsbStartStop, &cbdata) ;
+        }
+    }
+    CyAsLLSendStatusResponse(dev_p, CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 1) ;
+}
+
+static void
+MyUsbRequestCallbackUknownCBW(CyAsDevice *dev_p, CyAsLLRequestResponse *req_p)
+{
+    uint16_t val ;
+    CyAsDeviceHandle h = (CyAsDeviceHandle)dev_p ;
+    uint8_t buf[16] ;
+
+    uint8_t response[4] ;
+    uint16_t reqlen ;
+    void *request ;
+    uint8_t status ;
+    uint8_t key ;
+    uint8_t asc ;
+    uint8_t ascq ;
+
+    val = CyAsLLRequestResponse_GetWord(req_p, 0) ;
+    status = 1 ;                                            /* Failed by default */
+    key = 0x05 ;                                            /* Invalid command */
+    asc = 0x20 ;                                            /* Invalid command */
+    ascq = 0x00 ;                                   /* Invalid command */
+    reqlen = CyAsLLRequestResponse_GetWord(req_p, 1) ;
+    request = buf ;
+
+    CyAsHalAssert(reqlen <= sizeof(buf)) ;
+    CyAsLLRequestResponse_Unpack(req_p, 2, reqlen, request) ;
+
+    if (dev_p->usb_event_cb_ms)
+    {
+        CyAsUsbUnknownCommandData cbdata_ms ;
+        cbdata_ms.bus = CyAsStorageGetBusFromAddress(val) ;
+        cbdata_ms.device = CyAsStorageGetDeviceFromAddress(val) ;
+        cbdata_ms.reqlen = reqlen ;
+        cbdata_ms.request = request ;
+        cbdata_ms.status = status ;
+        cbdata_ms.key = key ;
+        cbdata_ms.asc = asc ;
+        cbdata_ms.ascq = ascq ;
+
+        dev_p->usb_event_cb_ms(h, CyAsEventUsbUnknownStorage, &cbdata_ms) ;
+        status = cbdata_ms.status ;
+        key = cbdata_ms.key ;
+        asc = cbdata_ms.asc ;
+        ascq = cbdata_ms.ascq ;
+    }
+    else if (dev_p->usb_event_cb)
+    {
+        CyAsUsbUnknownCommandData_dep cbdata ;
+        cbdata.media = CyAsStorageGetMediaFromAddress(val) ;
+        cbdata.reqlen = reqlen ;
+        cbdata.request = request ;
+        cbdata.status = status ;
+        cbdata.key = key ;
+        cbdata.asc = asc ;
+        cbdata.ascq = ascq ;
+
+        dev_p->usb_event_cb(h, CyAsEventUsbUnknownStorage, &cbdata) ;
+        status = cbdata.status ;
+        key = cbdata.key ;
+        asc = cbdata.asc ;
+        ascq = cbdata.ascq ;
+    }
+
+    response[0] = status ;
+    response[1] = key ;
+    response[2] = asc ;
+    response[3] = ascq ;
+    CyAsLLSendDataResponse(dev_p, CY_RQT_USB_RQT_CONTEXT, CY_RESP_UNKNOWN_SCSI_COMMAND, sizeof(response), response) ;
+}
+
+static void
+MyUsbRequestCallbackMSCProgress(CyAsDevice *dev_p, CyAsLLRequestResponse *req_p)
+{
+    uint16_t val1, val2 ;
+    CyAsDeviceHandle h = (CyAsDeviceHandle)dev_p ;
+
+    if ((dev_p->usb_event_cb) || (dev_p->usb_event_cb_ms))
+    {
+        CyAsMSCProgressData cbdata ;
+
+        val1 = CyAsLLRequestResponse_GetWord(req_p, 0) ;
+        val2 = CyAsLLRequestResponse_GetWord(req_p, 1) ;
+        cbdata.wr_count = (uint32_t)((val1 << 16) | val2) ;
+
+        val1 = CyAsLLRequestResponse_GetWord(req_p, 2) ;
+        val2 = CyAsLLRequestResponse_GetWord(req_p, 3) ;
+        cbdata.rd_count = (uint32_t)((val1 << 16) | val2) ;
+
+        if (dev_p->usb_event_cb)
+            dev_p->usb_event_cb(h, CyAsEventUsbMSCProgress, &cbdata) ;
+        else
+            dev_p->usb_event_cb_ms(h, CyAsEventUsbMSCProgress, &cbdata) ;
+    }
+
+    CyAsLLSendStatusResponse(dev_p, CY_RQT_USB_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
+}
+
+/*
+* This function processes the requests delivered from the firmware within the West Bridge
+* device that are delivered in the USB context.  These requests generally are EP0 and
+* EP1 related requests or USB events.
+*/
+static void
+MyUsbRequestCallback(CyAsDevice *dev_p, uint8_t context, CyAsLLRequestResponse *req_p, CyAsLLRequestResponse *resp_p,
+                     CyAsReturnStatus_t ret)
+{
+    uint16_t val ;
+    uint8_t code = CyAsLLRequestResponse_GetCode(req_p) ;
+
+    (void)resp_p ;
+    (void)context ;
+    (void)ret ;
+
+    switch(code)
+    {
+    case CY_RQT_USB_EVENT:
+        MyUsbRequestCallbackUsbEvent(dev_p, req_p) ;
+        break ;
+
+    case CY_RQT_USB_EP_DATA:
+        dev_p->usb_last_event = CyAsEventUsbSetupPacket ;
+        MyUsbRequestCallbackUsbData(dev_p, req_p) ;
+        break ;
+
+    case CY_RQT_SCSI_INQUIRY_COMMAND:
+        dev_p->usb_last_event = CyAsEventUsbInquiryAfter ;
+        MyUsbRequestCallbackInquiry(dev_p, req_p) ;
+        break ;
+
+    case CY_RQT_SCSI_START_STOP_COMMAND:
+        dev_p->usb_last_event = CyAsEventUsbStartStop ;
+        MyUsbRequestCallbackStartStop(dev_p, req_p) ;
+        break ;
+
+    case CY_RQT_SCSI_UNKNOWN_COMMAND:
+        dev_p->usb_last_event = CyAsEventUsbUnknownStorage ;
+        MyUsbRequestCallbackUknownCBW(dev_p, req_p) ;
+        break ;
+
+    case CY_RQT_USB_ACTIVITY_UPDATE:
+        dev_p->usb_last_event = CyAsEventUsbMSCProgress ;
+        MyUsbRequestCallbackMSCProgress(dev_p, req_p) ;
+        break ;
+
+    default:
+        CyAsHalPrintMessage("Invalid request received on USB context\n") ;
+        val = req_p->box0 ;
+        CyAsLLSendDataResponse(dev_p, CY_RQT_USB_RQT_CONTEXT, CY_RESP_INVALID_REQUEST, sizeof(val), &val) ;
+        break ;
+    }
+}
+
+static CyAsReturnStatus_t
+MyHandleResponseUsbStart(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 (ret != CY_AS_ERROR_SUCCESS)
+        goto destroy ;
+
+    /*
+    * Mark EP 0 and EP1 as 64 byte endpoints
+    */
+    CyAsDmaSetMaxDmaSize(dev_p, 0, 64) ;
+    CyAsDmaSetMaxDmaSize(dev_p, 1, 64) ;
+
+    dev_p->usb_count++ ;
+
+destroy :
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    if (ret != CY_AS_ERROR_SUCCESS)
+    {
+        CyAsDestroyCBQueue(dev_p->usb_func_cbs) ;
+        CyAsLLRegisterRequestCallback(dev_p, CY_RQT_USB_RQT_CONTEXT, 0) ;
+    }
+
+    CyAsDeviceClearUSSPending(dev_p) ;
+
+    return ret ;
+
+}
+
+/*
+* This function starts the USB stack.  The stack is reference counted so if the stack is already
+* started, this function just increments the count.  If the stack has not been started, a start
+* request is sent to the West Bridge device.
+*
+* Note: Starting the USB stack does not cause the USB signals to be connected to the USB pins.  To do
+*       this and therefore initiate enumeration, CyAsUsbConnect() must be called.
+*/
+CyAsReturnStatus_t
+CyAsUsbStart(CyAsDeviceHandle handle,
+               CyAsFunctionCallback cb,
+               uint32_t client)
+{
+    CyAsLLRequestResponse *req_p, *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+
+    CyAsDevice*dev_p ;
+
+    CyAsLogDebugMessage(6, "CyAsUsbStart called") ;
+
+    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 (CyAsDeviceIsInCallback(dev_p))
+        return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+    if(CyAsDeviceIsUSSPending(dev_p))
+        return CY_AS_ERROR_STARTSTOP_PENDING ;
+
+    CyAsDeviceSetUSSPending(dev_p) ;
+
+    if (dev_p->usb_count == 0)
+    {
+        /*
+        * Since we are just starting the stack, mark USB as not connected to the
+        * remote host
+        */
+        CyAsDeviceClearUsbConnected(dev_p) ;
+        dev_p->usb_phy_config = 0 ;
+
+        /* Queue for 1.0 Async Requests, kept for backwards compatibility */
+        dev_p->usb_func_cbs = CyAsCreateCBQueue(CYAS_USB_FUNC_CB) ;
+        if(dev_p->usb_func_cbs == 0)
+        {
+            CyAsDeviceClearUSSPending(dev_p) ;
+            return CY_AS_ERROR_OUT_OF_MEMORY ;
+        }
+
+        /* Reset the EP0 state */
+        CyAsUsbResetEP0State(dev_p) ;
+
+        /*
+        * We register here becuase the start request may cause events to occur before the
+        * response to the start request.
+        */
+        CyAsLLRegisterRequestCallback(dev_p, CY_RQT_USB_RQT_CONTEXT, MyUsbRequestCallback) ;
+
+        /* Create the request to send to the West Bridge device */
+        req_p = CyAsLLCreateRequest(dev_p, CY_RQT_START_USB, CY_RQT_USB_RQT_CONTEXT, 0) ;
+        if (req_p == 0)
+        {
+            CyAsDestroyCBQueue(dev_p->usb_func_cbs) ;
+            dev_p->usb_func_cbs = 0 ;
+            CyAsDeviceClearUSSPending(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)
+        {
+            CyAsDestroyCBQueue(dev_p->usb_func_cbs) ;
+            dev_p->usb_func_cbs = 0 ;
+            CyAsLLDestroyRequest(dev_p, req_p) ;
+            CyAsDeviceClearUSSPending(dev_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 MyHandleResponseUsbStart(dev_p, req_p, reply_p, ret) ;
+        }
+        else
+        {
+            ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_USB_START,
+                0, dev_p->func_cbs_usb, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+                CyAsUsbFuncCallback) ;
+
+            if (ret != CY_AS_ERROR_SUCCESS)
+                goto destroy ;
+
+            return ret ;
+        }
+
+destroy:
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        CyAsLLDestroyResponse(dev_p, reply_p) ;
+    }
+    else
+    {
+        dev_p->usb_count++ ;
+        if (cb)
+            cb(handle, ret, client, CY_FUNCT_CB_USB_START, 0) ;
+    }
+
+    CyAsDeviceClearUSSPending(dev_p) ;
+
+    return ret ;
+}
+
+void
+CyAsUsbReset(CyAsDevice *dev_p)
+{
+    int i ;
+
+    CyAsDeviceClearUsbConnected(dev_p) ;
+
+    for(i = 0 ; i < sizeof(dev_p->usb_config)/sizeof(dev_p->usb_config[0]) ; i++)
+    {
+        /*
+         * Cancel all pending USB read/write operations, as it is possible
+         * that the USB stack comes up in a different configuration with a
+         * different set of endpoints.
+         */
+        if (CyAsDeviceIsUsbAsyncPending(dev_p, i))
+            CyAsUsbCancelAsync(dev_p, (CyAsEndPointNumber_t)i) ;
+
+        dev_p->usb_cb[i] = 0 ;
+        dev_p->usb_config[i].enabled = CyFalse ;
+    }
+
+    dev_p->usb_phy_config = 0 ;
+}
+
+/*
+ * This function does all the API side clean-up associated with CyAsUsbStop,
+ * without any communication with firmware. This needs to be done when the
+ * device is being reset while the USB stack is active.
+ */
+void
+CyAsUsbCleanup(CyAsDevice *dev_p)
+{
+    if (dev_p->usb_count)
+    {
+        CyAsUsbResetEP0State(dev_p) ;
+        CyAsUsbReset(dev_p) ;
+        CyAsHalMemSet(dev_p->usb_config, 0, sizeof(dev_p->usb_config)) ;
+        CyAsDestroyCBQueue(dev_p->usb_func_cbs) ;
+
+        dev_p->usb_count = 0 ;
+    }
+}
+
+static CyAsReturnStatus_t
+MyHandleResponseUsbStop(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 (ret != CY_AS_ERROR_SUCCESS)
+        goto destroy ;
+
+    /*
+     * We sucessfully shutdown the stack, so decrement to make the count
+     * zero.
+     */
+    CyAsUsbCleanup(dev_p) ;
+
+destroy :
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    if (ret != CY_AS_ERROR_SUCCESS)
+        CyAsLLRegisterRequestCallback(dev_p, CY_RQT_USB_RQT_CONTEXT, 0) ;
+
+    CyAsDeviceClearUSSPending(dev_p) ;
+
+    return ret ;
+}
+
+/*
+* This function stops the USB stack.  The USB stack is reference counted so first is reference count is
+* decremented.  If the reference count is then zero, a request is sent to the West Bridge device to stop the USB
+* stack on the West Bridge device.
+*/
+CyAsReturnStatus_t
+CyAsUsbStop(CyAsDeviceHandle handle,
+              CyAsFunctionCallback cb,
+              uint32_t client)
+{
+    CyAsLLRequestResponse *req_p = 0, *reply_p = 0 ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+
+    CyAsDevice*dev_p ;
+
+    CyAsLogDebugMessage(6, "CyAsUsbStop called") ;
+
+    dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (CyAsDeviceIsUsbConnected(dev_p))
+        return CY_AS_ERROR_USB_CONNECTED ;
+
+    if (CyAsDeviceIsInCallback(dev_p))
+        return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+    if(CyAsDeviceIsUSSPending(dev_p))
+        return CY_AS_ERROR_STARTSTOP_PENDING ;
+
+    CyAsDeviceSetUSSPending(dev_p) ;
+
+    if (dev_p->usb_count == 1)
+    {
+        /* Create the request to send to the West Bridge device */
+        req_p = CyAsLLCreateRequest(dev_p, CY_RQT_STOP_USB, CY_RQT_USB_RQT_CONTEXT, 0) ;
+        if (req_p == 0)
+        {
+            ret = CY_AS_ERROR_OUT_OF_MEMORY ;
+            goto destroy ;
+        }
+
+        /* Reserve space for the reply, the reply data will not exceed one word */
+        reply_p = CyAsLLCreateResponse(dev_p, 1) ;
+        if (reply_p == 0)
+        {
+            ret = CY_AS_ERROR_OUT_OF_MEMORY ;
+            goto destroy ;
+        }
+
+        if(cb == 0)
+        {
+            ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+            if (ret != CY_AS_ERROR_SUCCESS)
+                goto destroy ;
+
+            return MyHandleResponseUsbStop(dev_p, req_p, reply_p, ret) ;
+        }
+        else
+        {
+            ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_USB_STOP,
+                0, dev_p->func_cbs_usb, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+                CyAsUsbFuncCallback) ;
+
+            if (ret != CY_AS_ERROR_SUCCESS)
+                goto destroy ;
+
+            return ret ;
+        }
+
+destroy:
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        CyAsLLDestroyResponse(dev_p, reply_p) ;
+    }
+    else if (dev_p->usb_count > 1)
+    {
+        /*
+         * Reset all LEPs to inactive state, after cleaning up any
+         * pending async read/write calls.
+         */
+        CyAsUsbReset(dev_p) ;
+        dev_p->usb_count-- ;
+
+        if (cb)
+            cb(handle, ret, client, CY_FUNCT_CB_USB_STOP, 0) ;
+    }
+
+    CyAsDeviceClearUSSPending(dev_p) ;
+
+    return ret ;
+}
+
+/*
+* This function registers a callback to be called when USB events are processed
+*/
+CyAsReturnStatus_t
+CyAsUsbRegisterCallback(CyAsDeviceHandle handle, CyAsUsbEventCallback callback)
+{
+    CyAsDevice*dev_p ;
+
+    CyAsLogDebugMessage(6, "CyAsUsbRegisterCallback called") ;
+
+    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 ;
+
+    dev_p->usb_event_cb = NULL ;
+    dev_p->usb_event_cb_ms = callback ;
+    return CY_AS_ERROR_SUCCESS ;
+}
+
+
+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 ;
+    else
+        ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+static CyAsReturnStatus_t
+MyHandleResponseConnect(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 (ret == CY_AS_ERROR_SUCCESS)
+        CyAsDeviceSetUsbConnected(dev_p) ;
+
+destroy :
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+
+/*
+* This method asks the West Bridge device to connect the internal USB D+ and D- signals to the USB
+* pins, thus starting the enumeration processes if the external pins are connnected to a USB host.
+* If the external pins are not connect to a USB host, enumeration will begin as soon as the USB
+* pins are connected to a host.
+*/
+CyAsReturnStatus_t
+CyAsUsbConnect(CyAsDeviceHandle handle,
+                 CyAsFunctionCallback cb,
+                 uint32_t client)
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+
+    CyAsDevice*dev_p ;
+
+    CyAsLogDebugMessage(6, "CyAsUsbConnect called") ;
+
+    dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (CyAsDeviceIsInCallback(dev_p))
+        return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+    /* Create the request to send to the West Bridge device */
+    req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SET_CONNECT_STATE, CY_RQT_USB_RQT_CONTEXT, 1) ;
+    if (req_p == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    /* 1 = Connect request */
+    CyAsLLRequestResponse_SetWord(req_p, 0, 1) ;
+
+    /* 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 ;
+    }
+
+    if(cb == 0)
+    {
+        ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        return MyHandleResponseConnect(dev_p, req_p, reply_p, ret) ;
+    }
+    else
+    {
+        ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_USB_CONNECT,
+            0, dev_p->func_cbs_usb, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+            CyAsUsbFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        return ret ;
+    }
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+static CyAsReturnStatus_t
+MyHandleResponseDisconnect(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 (ret == CY_AS_ERROR_SUCCESS)
+        CyAsDeviceClearUsbConnected(dev_p) ;
+
+destroy :
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+/*
+* This method forces a disconnect of the D+ and D- pins external to the West Bridge device from the
+* D+ and D- signals internally, effectively disconnecting the West Bridge device from any connectec
+* USB host.
+*/
+CyAsReturnStatus_t
+CyAsUsbDisconnect(CyAsDeviceHandle handle,
+                    CyAsFunctionCallback cb,
+                    uint32_t client)
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+
+    CyAsDevice*dev_p ;
+
+    CyAsLogDebugMessage(6, "CyAsUsbDisconnect called") ;
+
+    dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (CyAsDeviceIsInCallback(dev_p))
+        return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+    if (!CyAsDeviceIsUsbConnected(dev_p))
+        return CY_AS_ERROR_USB_NOT_CONNECTED ;
+
+    /* Create the request to send to the West Bridge device */
+    req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SET_CONNECT_STATE, CY_RQT_USB_RQT_CONTEXT, 1) ;
+    if (req_p == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, 0) ;
+
+    /* Reserve space for the reply, the reply data will not exceed two bytes */
+    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 ;
+
+        return MyHandleResponseDisconnect(dev_p, req_p, reply_p, ret) ;
+    }
+    else
+    {
+        ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_USB_DISCONNECT,
+            0, dev_p->func_cbs_usb, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+            CyAsUsbFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        return ret ;
+    }
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+static CyAsReturnStatus_t
+MyHandleResponseSetEnumConfig(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) ;
+
+    if (ret == CY_AS_ERROR_SUCCESS)
+    {
+        /*
+        * We configured the West Bridge device and enumeration is going to happen
+        * on the P port processor.  Now we must enable endpoint zero
+        */
+        CyAsUsbEndPointConfig config ;
+
+        config.dir = CyAsUsbInOut ;
+        config.type = CyAsUsbControl ;
+        config.enabled = CyTrue ;
+
+        ret = CyAsUsbSetEndPointConfig((CyAsDeviceHandle*)dev_p, 0, &config) ;
+    }
+
+destroy :
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+        return ret ;
+}
+
+/*
+* This method sets how the USB is enumerated and should be called before the
+* CyAsUsbConnect() is called.
+*/
+static CyAsReturnStatus_t
+MyUsbSetEnumConfig(CyAsDevice *dev_p,
+                    uint8_t bus_mask,
+                    uint8_t media_mask,
+                    CyBool use_antioch_enumeration,
+                    uint8_t mass_storage_interface,
+                    uint8_t mtp_interface,
+                    CyBool mass_storage_callbacks,
+                    CyAsFunctionCallback cb,
+                    uint32_t client)
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+
+    CyAsLogDebugMessage(6, "CyAsUsbSetEnumConfig called") ;
+
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (CyAsDeviceIsUsbConnected(dev_p))
+        return CY_AS_ERROR_USB_CONNECTED ;
+
+    if (CyAsDeviceIsInCallback(dev_p))
+        return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+    /* if we are using MTP firmware:  */
+    if (dev_p->is_mtp_firmware == 1)
+    {
+        if (mass_storage_interface != 0) /* we can not enemurate MSC */
+            return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+        if (bus_mask == 0)
+        {
+            if (mtp_interface != 0)
+                return CY_AS_ERROR_INVALID_CONFIGURATION ;
+        }
+        else if (bus_mask == 2)
+        {
+            /* enable EP 1 as it will be used */
+            CyAsDmaEnableEndPoint(dev_p, 1, CyTrue, CyAsDirectionIn) ;
+            dev_p->usb_config[1].enabled = CyTrue ;
+            dev_p->usb_config[1].dir = CyAsUsbIn ;
+            dev_p->usb_config[1].type = CyAsUsbInt ;
+        }
+        else
+        {
+            return CY_AS_ERROR_INVALID_CONFIGURATION ;
+        }
+    }
+    else if (mtp_interface != 0) /* if we are not using MTP firmware, we can not enumerate MTP */
+        return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+    /*
+    * If we are not enumerating mass storage, we should not be providing an interface
+    * number.
+    */
+    if (bus_mask == 0 && mass_storage_interface != 0)
+        return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+    /*
+    * If we are going to use mtp_interface, bus mask must be 2.
+    */
+    if (mtp_interface != 0 && bus_mask != 2)
+        return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+
+    /* Create the request to send to the West Bridge device */
+    req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SET_USB_CONFIG, CY_RQT_USB_RQT_CONTEXT, 4) ;
+    if (req_p == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    /* Marshal the structure */
+    CyAsLLRequestResponse_SetWord(req_p, 0, (uint16_t)((media_mask << 8) | bus_mask)) ;
+    CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)use_antioch_enumeration) ;
+    CyAsLLRequestResponse_SetWord(req_p, 2, dev_p->is_mtp_firmware ? mtp_interface : mass_storage_interface) ;
+    CyAsLLRequestResponse_SetWord(req_p, 3, (uint16_t)mass_storage_callbacks) ;
+
+    /* 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 ;
+    }
+
+    if(cb == 0)
+    {
+
+        ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        return MyHandleResponseSetEnumConfig(dev_p, req_p, reply_p) ;
+    }
+    else
+    {
+        ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_USB_SETENUMCONFIG,
+            0, dev_p->func_cbs_usb, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+            CyAsUsbFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        return ret ;
+    }
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+/*
+ * This method sets how the USB is enumerated and should be called before the
+ * CyAsUsbConnect() is called.
+ */
+CyAsReturnStatus_t
+CyAsUsbSetEnumConfig(CyAsDeviceHandle handle,
+                       CyAsUsbEnumControl *config_p,
+                       CyAsFunctionCallback cb,
+                       uint32_t client)
+{
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+    uint8_t bus_mask, media_mask ;
+    uint32_t bus, device ;
+    CyAsReturnStatus_t ret ;
+
+    dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if ((CyAsDeviceIsInCallback(dev_p))  && (cb != 0))
+        return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+    /* Since we are mapping the media types to bus with NAND to 0 and the rest
+     * to 1, and we are only allowing for enumerating all the devices on a bus
+     * we just scan the array for any positions where there a device is enabled
+     * and mark the bus to be enumerated.
+     */
+    bus_mask   = 0 ;
+    media_mask = 0 ;
+    media_mask = 0 ;
+    for( bus = 0; bus < CY_AS_MAX_BUSES; bus++)
+    {
+        for( device = 0; device < CY_AS_MAX_STORAGE_DEVICES; device++)
+        {
+            if (config_p->devices_to_enumerate[bus][device] == CyTrue)
+            {
+                bus_mask   |= (0x01 << bus) ;
+                media_mask |= dev_p->media_supported[bus] ;
+                media_mask |= dev_p->media_supported[bus] ;
+            }
+        }
+    }
+
+    return MyUsbSetEnumConfig(dev_p, bus_mask,media_mask,
+            config_p->antioch_enumeration,
+            config_p->mass_storage_interface,
+            config_p->mtp_interface,
+            config_p->mass_storage_callbacks,
+            cb,
+            client
+        ) ;
+}
+
+
+static CyAsReturnStatus_t
+MyHandleResponseGetEnumConfig(CyAsDevice* dev_p,
+                         CyAsLLRequestResponse *req_p,
+                         CyAsLLRequestResponse *reply_p,
+                         void* config_p)
+{
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    uint16_t val ;
+    uint8_t bus_mask ;
+    uint32_t bus ;
+
+    if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_USB_CONFIG)
+    {
+        ret = CY_AS_ERROR_INVALID_RESPONSE ;
+        goto destroy ;
+    }
+
+    /* Marshal the reply */
+    if (req_p->flags & CY_AS_REQUEST_RESPONSE_MS)
+    {
+        uint32_t device ;
+        CyBool state;
+        CyAsUsbEnumControl *ms_config_p = (CyAsUsbEnumControl*)config_p;
+
+        bus_mask = (uint8_t)(CyAsLLRequestResponse_GetWord(reply_p, 0) & 0xFF) ;
+        for( bus = 0; bus < CY_AS_MAX_BUSES; bus++)
+        {
+            if (bus_mask & (1 << bus))
+                state = CyTrue ;
+            else
+                state = CyFalse ;
+
+            for( device = 0; device < CY_AS_MAX_STORAGE_DEVICES; device++)
+            {
+                ms_config_p->devices_to_enumerate[bus][device] = state ;
+            }
+        }
+
+        ms_config_p->antioch_enumeration = (CyBool)CyAsLLRequestResponse_GetWord(reply_p, 1) ;
+
+        val = CyAsLLRequestResponse_GetWord(reply_p, 2) ;
+        if (dev_p->is_mtp_firmware)
+        {
+            ms_config_p->mass_storage_interface = 0 ;
+            ms_config_p->mtp_interface          = (uint8_t)(val & 0xFF) ;
+        }
+        else
+        {
+            ms_config_p->mass_storage_interface = (uint8_t)(val & 0xFF) ;
+            ms_config_p->mtp_interface          = 0 ;
+        }
+        ms_config_p->mass_storage_callbacks = (CyBool)(val >> 8) ;
+
+        /*
+        * Firmware returns an invalid interface number for mass storage,
+        * if mass storage is not enabled. This needs to be converted to zero
+        * to match the input configuration.
+        */
+        if (bus_mask == 0)
+        {
+            if (dev_p->is_mtp_firmware)
+                ms_config_p->mtp_interface = 0 ;
+            else
+                ms_config_p->mass_storage_interface = 0 ;
+        }
+    }
+    else
+    {
+        CyAsUsbEnumControl_dep *ex_config_p = (CyAsUsbEnumControl_dep*)config_p;
+
+        ex_config_p->enum_mass_storage = (uint8_t)((CyAsLLRequestResponse_GetWord(reply_p, 0) >> 8) & 0xFF) ;
+        ex_config_p->antioch_enumeration = (CyBool)CyAsLLRequestResponse_GetWord(reply_p, 1) ;
+
+        val = CyAsLLRequestResponse_GetWord(reply_p, 2) ;
+        ex_config_p->mass_storage_interface = (uint8_t)(val & 0xFF) ;
+        ex_config_p->mass_storage_callbacks = (CyBool)(val >> 8) ;
+
+        /*
+        * Firmware returns an invalid interface number for mass storage,
+        * if mass storage is not enabled. This needs to be converted to zero
+        * to match the input configuration.
+        */
+        if (ex_config_p->enum_mass_storage == 0)
+            ex_config_p->mass_storage_interface = 0 ;
+    }
+
+destroy :
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+/*
+* This sets up the request for the enumerateion configuration information, based on if the request is from
+* the old pre-1.2 functions.
+*/
+static CyAsReturnStatus_t
+MyUsbGetEnumConfig(CyAsDeviceHandle handle,
+                    uint16_t req_flags,
+                    void* config_p,
+                    CyAsFunctionCallback cb,
+                    uint32_t client)
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+
+    CyAsDevice*dev_p ;
+
+    CyAsLogDebugMessage(6, "CyAsUsbGetEnumConfig called") ;
+
+    dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (CyAsDeviceIsInCallback(dev_p))
+        return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+    /* Create the request to send to the West Bridge device */
+    req_p = CyAsLLCreateRequest(dev_p, CY_RQT_GET_USB_CONFIG, CY_RQT_USB_RQT_CONTEXT, 0) ;
+    if (req_p == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    /* Reserve space for the reply, the reply data will not exceed two bytes */
+    reply_p = CyAsLLCreateResponse(dev_p, 3) ;
+    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 ;
+
+        /* we need to know the type of request to know how to manage the data */
+        req_p->flags |= req_flags;
+        return MyHandleResponseGetEnumConfig(dev_p, req_p, reply_p, config_p) ;
+    }
+    else
+    {
+        ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_USB_GETENUMCONFIG,
+            config_p, dev_p->func_cbs_usb, req_flags, req_p, reply_p,
+            CyAsUsbFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        return ret ;
+    }
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+/*
+ * This method returns the enumerateion configuration information from the West Bridge device.
+ * Generally this is not used by client software but is provided mostly for debug information.
+ * We want a method to read all state information from the device.
+ */
+CyAsReturnStatus_t
+CyAsUsbGetEnumConfig(CyAsDeviceHandle handle,
+                       CyAsUsbEnumControl *config_p,
+                       CyAsFunctionCallback cb,
+                       uint32_t client)
+{
+    return MyUsbGetEnumConfig(handle, CY_AS_REQUEST_RESPONSE_MS, config_p, cb, client);
+}
+
+
+/*
+* This method sets the USB descriptor for a given entity.
+*/
+CyAsReturnStatus_t
+CyAsUsbSetDescriptor(CyAsDeviceHandle handle,
+                       CyAsUsbDescType type,
+                       uint8_t index,
+                       void *desc_p,
+                       uint16_t length,
+                       CyAsFunctionCallback cb,
+                       uint32_t client)
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    uint16_t pktlen ;
+
+    CyAsDevice*dev_p ;
+
+    CyAsLogDebugMessage(6, "CyAsUsbSetDescriptor called") ;
+
+    dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (CyAsDeviceIsInCallback(dev_p))
+        return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+    if (length > CY_AS_MAX_USB_DESCRIPTOR_SIZE)
+        return CY_AS_ERROR_INVALID_DESCRIPTOR ;
+
+    pktlen = (uint16_t)length / 2 ;
+    if (length % 2)
+        pktlen++ ;
+    pktlen += 2 ;                       /* 1 for type, 1 for length */
+
+    /* Create the request to send to the West Bridge device */
+    req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SET_DESCRIPTOR, CY_RQT_USB_RQT_CONTEXT, (uint16_t)pktlen) ;
+    if (req_p == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, (uint16_t)((uint8_t)type | (index << 8))) ;
+    CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)length) ;
+    CyAsLLRequestResponse_Pack(req_p, 2, length, desc_p) ;
+
+    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 ;
+
+        return MyHandleResponseNoData(dev_p, req_p, reply_p) ;
+    }
+    else
+    {
+        ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_USB_SETDESCRIPTOR,
+            0, dev_p->func_cbs_usb, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+            CyAsUsbFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        return ret ;
+    }
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+/*
+ * This method clears all descriptors that were previously stored on the West Bridge
+ * through CyAsUsbSetDescriptor calls.
+ */
+CyAsReturnStatus_t
+CyAsUsbClearDescriptors(CyAsDeviceHandle handle,
+                       CyAsFunctionCallback cb,
+                       uint32_t client)
+{
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+
+    CyAsDevice*dev_p ;
+
+    CyAsLogDebugMessage(6, "CyAsUsbClearDescriptors called") ;
+
+    dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if ((CyAsDeviceIsInCallback(dev_p)) && (cb == 0))
+        return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+    /* Create the request to send to the West Bridge device */
+    req_p = CyAsLLCreateRequest(dev_p, CY_RQT_CLEAR_DESCRIPTORS, CY_RQT_USB_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 ;
+    }
+
+    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_USB_CLEARDESCRIPTORS,
+            0, dev_p->func_cbs_usb, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+            CyAsUsbFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        return ret ;
+    }
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+static CyAsReturnStatus_t
+MyHandleResponseGetDescriptor(CyAsDevice* dev_p,
+                         CyAsLLRequestResponse *req_p,
+                         CyAsLLRequestResponse *reply_p,
+                         CyAsGetDescriptorData* data)
+{
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+     uint32_t retlen ;
+
+    if (CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_SUCCESS_FAILURE)
+    {
+        ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+        goto destroy ;
+    }
+    else if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_USB_DESCRIPTOR)
+    {
+        ret = CY_AS_ERROR_INVALID_RESPONSE ;
+        goto destroy ;
+    }
+
+    retlen = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+    if (retlen > data->length)
+    {
+        ret = CY_AS_ERROR_INVALID_SIZE ;
+        goto destroy ;
+    }
+
+    ret = CY_AS_ERROR_SUCCESS ;
+    CyAsLLRequestResponse_Unpack(reply_p, 1, retlen, data->desc_p) ;
+
+
+destroy :
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+        return ret ;
+}
+
+/*
+* This method retreives the USB descriptor for a given type.
+*/
+CyAsReturnStatus_t
+CyAsUsbGetDescriptor(CyAsDeviceHandle handle,
+                       CyAsUsbDescType type,
+                       uint8_t index,
+                       CyAsGetDescriptorData* data,
+                       CyAsFunctionCallback cb,
+                       uint32_t client)
+{
+    CyAsReturnStatus_t ret ;
+    CyAsLLRequestResponse *req_p , *reply_p ;
+
+    CyAsDevice*dev_p ;
+
+    CyAsLogDebugMessage(6, "CyAsUsbGetDescriptor called") ;
+
+    dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (CyAsDeviceIsInCallback(dev_p))
+        return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+    /* Create the request to send to the West Bridge device */
+    req_p = CyAsLLCreateRequest(dev_p, CY_RQT_GET_DESCRIPTOR, CY_RQT_USB_RQT_CONTEXT, 1) ;
+    if (req_p == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    CyAsLLRequestResponse_SetWord(req_p, 0, (uint16_t)((uint8_t)type | (index << 8))) ;
+
+    /* Add one for the length field */
+    reply_p = CyAsLLCreateResponse(dev_p, CY_AS_MAX_USB_DESCRIPTOR_SIZE + 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 ;
+
+        return MyHandleResponseGetDescriptor(dev_p, req_p, reply_p, data) ;
+    }
+    else
+    {
+        ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_USB_GETDESCRIPTOR,
+            data, dev_p->func_cbs_usb, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+            CyAsUsbFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        return ret ;
+    }
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+CyAsReturnStatus_t
+CyAsUsbSetPhysicalConfiguration(CyAsDeviceHandle handle, uint8_t config)
+{
+    CyAsReturnStatus_t ret ;
+    CyAsDevice*dev_p ;
+
+    CyAsLogDebugMessage(6, "CyAsUsbSetPhysicalConfiguration called") ;
+
+    dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (CyAsDeviceIsUsbConnected(dev_p))
+        return CY_AS_ERROR_USB_CONNECTED ;
+
+    if (config < 1 || config > 12)
+        return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+    dev_p->usb_phy_config = config ;
+
+    return CY_AS_ERROR_SUCCESS ;
+}
+
+static CyBool
+IsPhysicalValid(uint8_t config, CyAsEndPointNumber_t ep)
+{
+    static uint8_t validmask[12] =
+    {
+        0x0f,       /* Config  1 - 1, 2, 3, 4 */
+        0x07,       /* Config  2 - 1, 2, 3 */
+        0x07,       /* Config  3 - 1, 2, 3 */
+        0x0d,       /* Config  4 - 1, 3, 4 */
+        0x05,       /* Config  5 - 1, 3 */
+        0x05,       /* Config  6 - 1, 3 */
+        0x0d,       /* Config  7 - 1, 3, 4 */
+        0x05,       /* Config  8 - 1, 3 */
+        0x05,       /* Config  9 - 1, 3 */
+        0x0d,       /* Config 10 - 1, 3, 4 */
+        0x09,       /* Config 11 - 1, 4 */
+        0x01        /* Config 12 - 1 */
+    } ;
+
+    return (validmask[config - 1] & (1 << (ep - 1))) ? CyTrue : CyFalse ;
+}
+
+/*
+* This method sets the configuration for an endpoint
+*/
+CyAsReturnStatus_t
+CyAsUsbSetEndPointConfig(CyAsDeviceHandle handle, CyAsEndPointNumber_t ep, CyAsUsbEndPointConfig *config_p)
+{
+    CyAsReturnStatus_t ret ;
+    CyAsDevice*dev_p ;
+
+    CyAsLogDebugMessage(6, "CyAsUsbSetEndPointConfig called") ;
+
+    dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (CyAsDeviceIsUsbConnected(dev_p))
+        return CY_AS_ERROR_USB_CONNECTED ;
+
+    if (ep >= 16 || ep == 2 || ep == 4 || ep == 6 || ep == 8)
+        return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+    if (ep == 0)
+    {
+        /* Endpoint 0 must be 64 byte, dir IN/OUT, and control type */
+        if (config_p->dir != CyAsUsbInOut || config_p->type != CyAsUsbControl)
+            return CY_AS_ERROR_INVALID_CONFIGURATION ;
+    }
+    else if (ep == 1)
+    {
+        if ((dev_p->is_mtp_firmware == 1) && (dev_p->usb_config[1].enabled == CyTrue))
+        {
+            return CY_AS_ERROR_INVALID_ENDPOINT ;
+        }
+
+        /*
+         * EP1 can only be used either as an OUT ep, or as an IN ep.
+         */
+        if ((config_p->type == CyAsUsbControl) || (config_p->type == CyAsUsbIso) || (config_p->dir == CyAsUsbInOut))
+            return CY_AS_ERROR_INVALID_CONFIGURATION ;
+    }
+    else
+    {
+        if (config_p->dir == CyAsUsbInOut || config_p->type == CyAsUsbControl)
+            return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+        if (!IsPhysicalValid(dev_p->usb_phy_config, config_p->physical))
+            return CY_AS_ERROR_INVALID_PHYSICAL_ENDPOINT ;
+
+        /*
+        * ISO endpoints must be on EPs 3, 5, 7 or 9 as they need to align directly
+        * with the underlying physical endpoint.
+        */
+        if (config_p->type == CyAsUsbIso)
+        {
+            if (ep != 3 && ep != 5 && ep != 7 && ep != 9)
+                return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+            if (ep == 3 && config_p->physical != 1)
+                return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+            if (ep == 5 && config_p->physical != 2)
+                return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+            if (ep == 7 && config_p->physical != 3)
+                return CY_AS_ERROR_INVALID_CONFIGURATION ;
+
+            if (ep == 9 && config_p->physical != 4)
+                return CY_AS_ERROR_INVALID_CONFIGURATION ;
+        }
+    }
+
+    /* Store the configuration information until a CyAsUsbCommitConfig is done */
+    dev_p->usb_config[ep] = *config_p ;
+
+    /* If the endpoint is enabled, enable DMA associated with the endpoint */
+    /*
+    * We make some assumptions that we check here.  We assume that the direction fields for the
+    * DMA module are the same values as the direction values for the USB module.  At some point these should
+    * be consolidated into a single enumerated type. - BWG
+    */
+    CyAsHalAssert((int)CyAsUsbIn == (int)CyAsDirectionIn);
+    CyAsHalAssert((int)CyAsUsbOut == (int)CyAsDirectionOut);
+    CyAsHalAssert((int)CyAsUsbInOut == (int)CyAsDirectionInOut) ;
+
+    return CyAsDmaEnableEndPoint(dev_p, ep, config_p->enabled, (CyAsDmaDirection)config_p->dir) ;
+}
+
+CyAsReturnStatus_t
+CyAsUsbGetEndPointConfig(CyAsDeviceHandle handle, CyAsEndPointNumber_t ep, CyAsUsbEndPointConfig *config_p)
+{
+    CyAsReturnStatus_t ret ;
+
+    CyAsDevice*dev_p ;
+
+    CyAsLogDebugMessage(6, "CyAsUsbGetEndPointConfig called") ;
+
+    dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (ep >= 16 || ep == 2 || ep == 4 || ep == 6 || ep == 8)
+        return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+    *config_p = dev_p->usb_config[ep] ;
+
+    return CY_AS_ERROR_SUCCESS ;
+}
+
+/*
+* Commit the configuration of the various endpoints to the hardware.
+*/
+CyAsReturnStatus_t
+CyAsUsbCommitConfig(CyAsDeviceHandle handle,
+                      CyAsFunctionCallback cb,
+                      uint32_t client)
+{
+    uint32_t i ;
+    CyAsReturnStatus_t ret ;
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    CyAsDevice*dev_p ;
+    uint16_t data ;
+
+    CyAsLogDebugMessage(6, "CyAsUsbCommitConfig called") ;
+
+    dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (CyAsDeviceIsUsbConnected(dev_p))
+        return CY_AS_ERROR_USB_CONNECTED ;
+
+    if (CyAsDeviceIsInCallback(dev_p))
+        return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+    /*
+    * This performs the mapping based on informatation that was previously
+    * stored on the device about the various endpoints and how they are configured.  The
+    * output of this mapping is setting the the 14 register values contained in usb_lepcfg
+    * and usb_pepcfg
+    */
+    ret = CyAsUsbMapLogical2Physical(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    /*
+    * Now, package the information about the various logical and physical
+    * endpoint configuration registers and send it across to the West Bridge
+    * device.
+    */
+    req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SET_USB_CONFIG_REGISTERS, CY_RQT_USB_RQT_CONTEXT, 8) ;
+    if (req_p == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    CyAsHalPrintMessage("USB Configuration: %d\n", dev_p->usb_phy_config) ;
+    CyAsHalPrintMessage("EP1OUT: 0x%02x EP1IN: 0x%02x\n", dev_p->usb_ep1cfg[0], dev_p->usb_ep1cfg[1]) ;
+    CyAsHalPrintMessage("PEP Registers: 0x%02x 0x%02x 0x%02x 0x%02x\n", dev_p->usb_pepcfg[0],
+        dev_p->usb_pepcfg[1], dev_p->usb_pepcfg[2], dev_p->usb_pepcfg[3]) ;
+
+    CyAsHalPrintMessage("LEP Registers: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
+        dev_p->usb_lepcfg[0],dev_p->usb_lepcfg[1], dev_p->usb_lepcfg[2], dev_p->usb_lepcfg[3],
+        dev_p->usb_lepcfg[4],dev_p->usb_lepcfg[5], dev_p->usb_lepcfg[6], dev_p->usb_lepcfg[7],
+        dev_p->usb_lepcfg[8],dev_p->usb_lepcfg[9]) ;
+
+    /* Write the EP1OUTCFG and EP1INCFG data in the first word. */
+    data = (uint16_t)((dev_p->usb_ep1cfg[0] << 8) | dev_p->usb_ep1cfg[1]) ;
+    CyAsLLRequestResponse_SetWord(req_p, 0, data) ;
+
+    /* Write the PEP CFG data in the next 2 words */
+    for(i = 0 ; i < 4 ; i += 2)
+    {
+        data = (uint16_t)((dev_p->usb_pepcfg[i] << 8) | dev_p->usb_pepcfg[i + 1]) ;
+        CyAsLLRequestResponse_SetWord(req_p, 1 + i / 2, data) ;
+    }
+
+    /* Write the LEP CFG data in the next 5 words */
+    for(i = 0 ; i < 10 ; i += 2)
+    {
+        data = (uint16_t)((dev_p->usb_lepcfg[i] << 8) | dev_p->usb_lepcfg[i + 1]) ;
+        CyAsLLRequestResponse_SetWord(req_p, 3 + i / 2, data) ;
+    }
+
+    /* A single status word response type */
+    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 ;
+
+        ret = MyHandleResponseNoData(dev_p, req_p, reply_p) ;
+
+        if (ret == CY_AS_ERROR_SUCCESS)
+            ret = CyAsUsbSetupDma(dev_p) ;
+
+        return ret ;
+    }
+    else
+    {
+        ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_USB_COMMITCONFIG,
+            0, dev_p->func_cbs_usb, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+            CyAsUsbFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        return ret ;
+    }
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+static void
+SyncRequestCallback(CyAsDevice *dev_p, CyAsEndPointNumber_t ep, void *buf_p, uint32_t size, CyAsReturnStatus_t err)
+{
+    (void)ep ;
+    (void)buf_p ;
+
+    dev_p->usb_error = err ;
+    dev_p->usb_actual_cnt = size ;
+}
+
+static void
+AsyncReadRequestCallback(CyAsDevice *dev_p, CyAsEndPointNumber_t ep, void *buf_p, uint32_t size, CyAsReturnStatus_t err)
+{
+    CyAsDeviceHandle h ;
+
+    CyAsLogDebugMessage(6, "AsyncReadRequestCallback called") ;
+
+    h = (CyAsDeviceHandle)dev_p ;
+
+    if (ep == 0 && CyAsDeviceIsAckDelayed(dev_p))
+    {
+        dev_p->usb_pending_buffer = buf_p ;
+        dev_p->usb_pending_size = size ;
+        dev_p->usb_error = err ;
+        CyAsUsbAckSetupPacket(h, UsbAckCallback, 0) ;
+    }
+    else
+    {
+        CyAsUsbIoCallback cb ;
+
+        cb = dev_p->usb_cb[ep] ;
+        dev_p->usb_cb[ep] = 0 ;
+        CyAsDeviceClearUsbAsyncPending(dev_p, ep) ;
+        if (cb)
+            cb(h, ep, size, buf_p, err) ;
+    }
+}
+
+static void
+AsyncWriteRequestCallback(CyAsDevice *dev_p, CyAsEndPointNumber_t ep, void *buf_p, uint32_t size, CyAsReturnStatus_t err)
+{
+    CyAsDeviceHandle h ;
+
+    CyAsLogDebugMessage(6, "AsyncWriteRequestCallback called") ;
+
+    h = (CyAsDeviceHandle)dev_p ;
+
+    if (ep == 0 && CyAsDeviceIsAckDelayed(dev_p))
+    {
+        dev_p->usb_pending_buffer = buf_p ;
+        dev_p->usb_pending_size = size ;
+        dev_p->usb_error = err ;
+
+        /* The west bridge protocol generates ZLPs as required. */
+        CyAsUsbAckSetupPacket(h, UsbAckCallback, 0) ;
+    }
+    else
+    {
+        CyAsUsbIoCallback cb ;
+
+        cb = dev_p->usb_cb[ep] ;
+        dev_p->usb_cb[ep] = 0 ;
+
+        CyAsDeviceClearUsbAsyncPending(dev_p, ep) ;
+        if (cb)
+            cb(h, ep, size, buf_p, err) ;
+    }
+}
+
+static void
+MyTurboRqtCallback(CyAsDevice *dev_p,
+                    uint8_t context,
+                    CyAsLLRequestResponse *rqt,
+                    CyAsLLRequestResponse *resp,
+                    CyAsReturnStatus_t stat)
+{
+    uint8_t code ;
+
+    (void)context ;
+    (void)stat ;
+
+    /* The Handlers are responsible for Deleting the rqt and resp when
+     * they are finished
+     */
+    code = CyAsLLRequestResponse_GetCode(rqt) ;
+    switch(code)
+    {
+    case CY_RQT_TURBO_SWITCH_ENDPOINT:
+        CyAsHalAssert(stat == CY_AS_ERROR_SUCCESS) ;
+        CyAsLLDestroyRequest(dev_p, rqt) ;
+        CyAsLLDestroyResponse(dev_p, resp) ;
+        break;
+    default:
+        CyAsHalAssert(CyFalse) ;
+        break ;
+    }
+}
+
+/* Send a mailbox request to prepare the endpoint for switching */
+static CyAsReturnStatus_t
+MySendTurboSwitch(CyAsDevice* dev_p, uint32_t size, CyBool pktread)
+{
+    CyAsReturnStatus_t ret ;
+    CyAsLLRequestResponse *req_p , *reply_p ;
+
+    /* Create the request to send to the West Bridge device */
+    req_p = CyAsLLCreateRequest(dev_p, CY_RQT_TURBO_SWITCH_ENDPOINT, CY_RQT_TUR_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, (uint16_t)pktread) ;
+    CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)((size >> 16) & 0xFFFF)) ;
+    CyAsLLRequestResponse_SetWord(req_p, 2, (uint16_t)(size & 0xFFFF)) ;
+
+    ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyFalse, MyTurboRqtCallback) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        CyAsLLDestroyRequest(dev_p, reply_p) ;
+        return ret ;
+    }
+
+    return CY_AS_ERROR_SUCCESS ;
+}
+
+CyAsReturnStatus_t
+CyAsUsbReadData(CyAsDeviceHandle handle, CyAsEndPointNumber_t ep, CyBool pktread, uint32_t dsize, uint32_t *dataread, void *data)
+{
+    CyAsReturnStatus_t ret ;
+    CyAsDevice *dev_p ;
+
+    CyAsLogDebugMessage(6, "CyAsUsbReadData called") ;
+
+    dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (CyAsDeviceIsInCallback(dev_p))
+        return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+    if (ep >= 16 || ep == 4 || ep == 6 || ep == 8)
+        return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+    /* EP2 is available for reading when MTP is active */
+    if(dev_p->mtp_count == 0 && ep == CY_AS_MTP_READ_ENDPOINT)
+        return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+    /* If the endpoint is disabled, we cannot write data to the endpoint */
+    if (!dev_p->usb_config[ep].enabled)
+        return CY_AS_ERROR_ENDPOINT_DISABLED ;
+
+    if (dev_p->usb_config[ep].dir != CyAsUsbOut)
+        return CY_AS_ERROR_USB_BAD_DIRECTION ;
+
+    ret = CyAsDmaQueueRequest(dev_p, ep, data, dsize, pktread, CyTrue, SyncRequestCallback) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (ep == CY_AS_MTP_READ_ENDPOINT )
+    {
+        ret = MySendTurboSwitch(dev_p, dsize, pktread) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+        {
+            CyAsDmaCancel(dev_p, ep, ret) ;
+            return ret ;
+        }
+
+        ret = CyAsDmaDrainQueue(dev_p, ep, CyFalse) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+            return ret ;
+    }
+    else
+    {
+        ret = CyAsDmaDrainQueue(dev_p, ep, CyTrue) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+            return ret ;
+    }
+
+    ret = dev_p->usb_error ;
+    *dataread = dev_p->usb_actual_cnt ;
+
+    return ret ;
+}
+
+CyAsReturnStatus_t
+CyAsUsbReadDataAsync(CyAsDeviceHandle handle, CyAsEndPointNumber_t ep, CyBool pktread, uint32_t dsize, void *data, CyAsUsbIoCallback cb)
+{
+    CyAsReturnStatus_t ret ;
+    uint32_t mask ;
+    CyAsDevice *dev_p ;
+
+    CyAsLogDebugMessage(6, "CyAsUsbReadDataAsync called") ;
+
+    dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (ep >= 16 || ep == 4 || ep == 6 || ep == 8)
+        return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+    /* EP2 is available for reading when MTP is active */
+    if(dev_p->mtp_count == 0 && ep == CY_AS_MTP_READ_ENDPOINT)
+        return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+    /* If the endpoint is disabled, we cannot write data to the endpoint */
+    if (!dev_p->usb_config[ep].enabled)
+        return CY_AS_ERROR_ENDPOINT_DISABLED ;
+
+    if (dev_p->usb_config[ep].dir != CyAsUsbOut && dev_p->usb_config[ep].dir != CyAsUsbInOut)
+        return CY_AS_ERROR_USB_BAD_DIRECTION ;
+
+    /*
+    * 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 (CyAsDeviceIsUsbAsyncPending(dev_p, ep))
+    {
+        CyAsHalEnableInterrupts(mask) ;
+        return CY_AS_ERROR_ASYNC_PENDING ;
+    }
+    CyAsDeviceSetUsbAsyncPending(dev_p, ep) ;
+
+    /*
+    * If this is for EP0, we set this bit to delay the ACK response
+    * until after this read has completed.
+    */
+    if (ep == 0)
+        CyAsDeviceSetAckDelayed(dev_p) ;
+
+    CyAsHalEnableInterrupts(mask) ;
+
+    CyAsHalAssert(dev_p->usb_cb[ep] == 0) ;
+    dev_p->usb_cb[ep] = cb ;
+
+    ret = CyAsDmaQueueRequest(dev_p, ep, data, dsize, pktread, CyTrue, AsyncReadRequestCallback) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (ep == CY_AS_MTP_READ_ENDPOINT)
+    {
+        ret = MySendTurboSwitch(dev_p, dsize, pktread) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+        {
+            CyAsDmaCancel(dev_p, ep, ret) ;
+            return ret ;
+        }
+    }
+    else
+    {
+        /* Kick start the queue if it is not running */
+        CyAsDmaKickStart(dev_p, ep) ;
+    }
+    return ret ;
+}
+
+CyAsReturnStatus_t
+CyAsUsbWriteData(CyAsDeviceHandle handle, CyAsEndPointNumber_t ep, uint32_t dsize, void *data)
+{
+    CyAsReturnStatus_t ret ;
+    CyAsDevice *dev_p ;
+
+    CyAsLogDebugMessage(6, "CyAsUsbWriteData called") ;
+
+    dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (CyAsDeviceIsInCallback(dev_p))
+        return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+    if (ep >= 16 || ep == 2 || ep == 4 || ep == 8)
+        return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+    /* EP6 is available for writing when MTP is active */
+    if(dev_p->mtp_count == 0 && ep == CY_AS_MTP_WRITE_ENDPOINT)
+        return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+    /* If the endpoint is disabled, we cannot write data to the endpoint */
+    if (!dev_p->usb_config[ep].enabled)
+        return CY_AS_ERROR_ENDPOINT_DISABLED ;
+
+    if (dev_p->usb_config[ep].dir != CyAsUsbIn && dev_p->usb_config[ep].dir != CyAsUsbInOut)
+        return CY_AS_ERROR_USB_BAD_DIRECTION ;
+
+    /* Write on Turbo endpoint */
+    if (ep == CY_AS_MTP_WRITE_ENDPOINT)
+    {
+        CyAsLLRequestResponse *req_p, *reply_p ;
+
+        req_p = CyAsLLCreateRequest(dev_p, CY_RQT_TURBO_SEND_RESP_DATA_TO_HOST, CY_RQT_TUR_RQT_CONTEXT, 3) ;
+        if (req_p == 0)
+            return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+        CyAsLLRequestResponse_SetWord(req_p, 0, 0x0006) ; /* EP number to use. */
+        CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)((dsize >> 16) & 0xFFFF)) ;
+        CyAsLLRequestResponse_SetWord(req_p, 2, (uint16_t)(dsize & 0xFFFF)) ;
+
+        /* 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 ;
+        }
+
+        if (dsize)
+        {
+            ret = CyAsDmaQueueRequest(dev_p, ep, data, dsize, CyFalse, CyFalse, SyncRequestCallback) ;
+            if (ret != CY_AS_ERROR_SUCCESS)
+                return ret ;
+        }
+
+        ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
+        if (ret == CY_AS_ERROR_SUCCESS)
+        {
+            if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
+                ret = CY_AS_ERROR_INVALID_RESPONSE ;
+            else
+                ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+        }
+
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+        {
+            if (dsize)
+                CyAsDmaCancel(dev_p, ep, ret) ;
+            return ret ;
+        }
+
+        /* If this is a zero-byte write, firmware will handle it.
+         * There is no need to do any work here.
+         */
+        if (!dsize)
+            return CY_AS_ERROR_SUCCESS ;
+    }
+    else
+    {
+        ret = CyAsDmaQueueRequest(dev_p, ep, data, dsize, CyFalse, CyFalse, SyncRequestCallback) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+            return ret ;
+    }
+
+    if (ep != CY_AS_MTP_WRITE_ENDPOINT)
+        ret = CyAsDmaDrainQueue(dev_p, ep, CyTrue) ;
+    else
+        ret = CyAsDmaDrainQueue(dev_p, ep, CyFalse) ;
+
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    ret = dev_p->usb_error ;
+    return ret ;
+}
+
+static void
+MtpWriteCallback(
+        CyAsDevice *dev_p,
+        uint8_t context,
+        CyAsLLRequestResponse *rqt,
+        CyAsLLRequestResponse *resp,
+        CyAsReturnStatus_t ret)
+{
+    CyAsUsbIoCallback cb ;
+    CyAsDeviceHandle h = (CyAsDeviceHandle)dev_p ;
+
+    CyAsHalAssert(context == CY_RQT_TUR_RQT_CONTEXT) ;
+
+    if (ret == CY_AS_ERROR_SUCCESS)
+    {
+        if (CyAsLLRequestResponse_GetCode(resp) != CY_RESP_SUCCESS_FAILURE)
+            ret = CY_AS_ERROR_INVALID_RESPONSE ;
+        else
+            ret = CyAsLLRequestResponse_GetWord(resp, 0) ;
+    }
+
+    /* If this was a zero byte transfer request, we can call the callback from
+     * here. */
+    if ((CyAsLLRequestResponse_GetWord(rqt, 1) == 0) &&
+            (CyAsLLRequestResponse_GetWord(rqt, 2) == 0))
+    {
+        cb = dev_p->usb_cb[CY_AS_MTP_WRITE_ENDPOINT] ;
+        dev_p->usb_cb[CY_AS_MTP_WRITE_ENDPOINT] = 0 ;
+        CyAsDeviceClearUsbAsyncPending(dev_p, CY_AS_MTP_WRITE_ENDPOINT) ;
+        if (cb)
+            cb(h, CY_AS_MTP_WRITE_ENDPOINT, 0, 0, ret) ;
+
+        goto destroy ;
+    }
+
+    if (ret != CY_AS_ERROR_SUCCESS)
+    {
+        /* Firmware failed the request. Cancel the DMA transfer. */
+        CyAsDmaCancel(dev_p, 0x06, CY_AS_ERROR_CANCELED) ;
+        dev_p->usb_cb[0x06] = 0 ;
+        CyAsDeviceClearUsbAsyncPending(dev_p, 0x06) ;
+    }
+
+destroy:
+    CyAsLLDestroyResponse(dev_p, resp) ;
+    CyAsLLDestroyRequest(dev_p, rqt) ;
+}
+
+CyAsReturnStatus_t
+CyAsUsbWriteDataAsync(CyAsDeviceHandle handle, CyAsEndPointNumber_t ep, uint32_t dsize, void *data, CyBool spacket, CyAsUsbIoCallback cb)
+{
+    uint32_t mask ;
+    CyAsReturnStatus_t ret ;
+    CyAsDevice *dev_p ;
+
+    CyAsLogDebugMessage(6, "CyAsUsbWriteDataAsync called") ;
+
+    dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (ep >= 16 || ep == 2 || ep == 4 || ep == 8)
+        return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+     /* EP6 is available for writing when MTP is active */
+    if(dev_p->mtp_count == 0 && ep == CY_AS_MTP_WRITE_ENDPOINT)
+        return CY_AS_ERROR_INVALID_ENDPOINT ;
+
+    /* If the endpoint is disabled, we cannot write data to the endpoint */
+    if (!dev_p->usb_config[ep].enabled)
+        return CY_AS_ERROR_ENDPOINT_DISABLED ;
+
+    if (dev_p->usb_config[ep].dir != CyAsUsbIn && dev_p->usb_config[ep].dir != CyAsUsbInOut)
+        return CY_AS_ERROR_USB_BAD_DIRECTION ;
+
+    /*
+    * 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 (CyAsDeviceIsUsbAsyncPending(dev_p, ep))
+    {
+        CyAsHalEnableInterrupts(mask) ;
+        return CY_AS_ERROR_ASYNC_PENDING ;
+    }
+
+    CyAsDeviceSetUsbAsyncPending(dev_p, ep) ;
+
+    if (ep == 0)
+        CyAsDeviceSetAckDelayed(dev_p) ;
+
+    CyAsHalEnableInterrupts(mask) ;
+
+    CyAsHalAssert(dev_p->usb_cb[ep] == 0) ;
+    dev_p->usb_cb[ep] = cb ;
+    dev_p->usb_spacket[ep] = spacket ;
+
+    /* Write on Turbo endpoint */
+    if (ep == CY_AS_MTP_WRITE_ENDPOINT)
+    {
+        CyAsLLRequestResponse *req_p, *reply_p ;
+
+        req_p = CyAsLLCreateRequest(dev_p, CY_RQT_TURBO_SEND_RESP_DATA_TO_HOST, CY_RQT_TUR_RQT_CONTEXT, 3) ;
+        if (req_p == 0)
+            return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+        CyAsLLRequestResponse_SetWord(req_p, 0, 0x0006) ; /* EP number to use. */
+        CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)((dsize >> 16) & 0xFFFF)) ;
+        CyAsLLRequestResponse_SetWord(req_p, 2, (uint16_t)(dsize & 0xFFFF)) ;
+
+        /* 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 ;
+        }
+
+        if (dsize)
+        {
+            ret = CyAsDmaQueueRequest(dev_p, ep, data, dsize, CyFalse, CyFalse, AsyncWriteRequestCallback) ;
+            if (ret != CY_AS_ERROR_SUCCESS)
+                return ret ;
+        }
+
+        ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyFalse, MtpWriteCallback) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+        {
+            if (dsize)
+                CyAsDmaCancel(dev_p, ep, ret) ;
+            return ret ;
+        }
+
+        /* Firmware will handle a zero byte transfer without any DMA transfers. */
+        if (!dsize)
+            return CY_AS_ERROR_SUCCESS ;
+    }
+    else
+    {
+        ret = CyAsDmaQueueRequest(dev_p, ep, data, dsize, CyFalse, CyFalse, AsyncWriteRequestCallback) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+            return ret ;
+    }
+
+    /* Kick start the queue if it is not running */
+    if (ep != CY_AS_MTP_WRITE_ENDPOINT)
+    {
+        CyAsDmaKickStart(dev_p, ep) ;
+    }
+
+    return CY_AS_ERROR_SUCCESS ;
+}
+
+static void
+MyUsbCancelAsyncCallback(
+                   CyAsDevice *dev_p,
+                   uint8_t context,
+                   CyAsLLRequestResponse *rqt,
+                   CyAsLLRequestResponse *resp,
+                   CyAsReturnStatus_t ret)
+{
+    uint8_t ep ;
+    (void)context ;
+
+    ep = (uint8_t)CyAsLLRequestResponse_GetWord(rqt, 0) ;
+    if (ret == CY_AS_ERROR_SUCCESS)
+    {
+        if (CyAsLLRequestResponse_GetCode(resp) != CY_RESP_SUCCESS_FAILURE)
+            ret = CY_AS_ERROR_INVALID_RESPONSE ;
+        else
+            ret = CyAsLLRequestResponse_GetWord(resp, 0) ;
+    }
+
+    CyAsLLDestroyRequest(dev_p, rqt) ;
+    CyAsLLDestroyResponse(dev_p, resp) ;
+
+    if (ret == CY_AS_ERROR_SUCCESS)
+    {
+        CyAsDmaCancel(dev_p, ep, CY_AS_ERROR_CANCELED) ;
+        dev_p->usb_cb[ep] = 0 ;
+        CyAsDeviceClearUsbAsyncPending(dev_p, ep) ;
+    }
+}
+
+CyAsReturnStatus_t
+CyAsUsbCancelAsync(CyAsDeviceHandle handle, CyAsEndPointNumber_t ep)
+{
+    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 ;
+
+    ep &= 0x7F;         /* Remove the direction bit. */
+    if (!CyAsDeviceIsUsbAsyncPending(dev_p, ep))
+        return CY_AS_ERROR_ASYNC_NOT_PENDING;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (CyAsDeviceIsInSuspendMode(dev_p))
+        return CY_AS_ERROR_IN_SUSPEND ;
+
+    if ((ep == CY_AS_MTP_WRITE_ENDPOINT) || (ep == CY_AS_MTP_READ_ENDPOINT))
+    {
+        /* Need firmware support for the cancel operation. */
+        req_p = CyAsLLCreateRequest(dev_p, CY_RQT_CANCEL_ASYNC_TRANSFER, CY_RQT_TUR_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 ;
+        }
+
+        CyAsLLRequestResponse_SetWord(req_p, 0, (uint16_t)ep) ;
+        ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyFalse, MyUsbCancelAsyncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+        {
+            CyAsLLDestroyRequest(dev_p, req_p) ;
+            CyAsLLDestroyResponse(dev_p, reply_p) ;
+            return ret ;
+        }
+    }
+    else
+    {
+        ret = CyAsDmaCancel(dev_p, ep, CY_AS_ERROR_CANCELED) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+            return ret ;
+
+        dev_p->usb_cb[ep] = 0 ;
+        CyAsDeviceClearUsbAsyncPending(dev_p, ep) ;
+    }
+
+    return CY_AS_ERROR_SUCCESS ;
+}
+
+static void
+CyAsUsbAckCallback(
+                   CyAsDevice *dev_p,
+                   uint8_t context,
+                   CyAsLLRequestResponse *rqt,
+                   CyAsLLRequestResponse *resp,
+                   CyAsReturnStatus_t ret)
+{
+    CyAsFuncCBNode* node  = (CyAsFuncCBNode*)dev_p->func_cbs_usb->head_p ;
+
+    (void)context ;
+
+    if (ret == CY_AS_ERROR_SUCCESS)
+    {
+        if (CyAsLLRequestResponse_GetCode(resp) != CY_RESP_SUCCESS_FAILURE)
+            ret = CY_AS_ERROR_INVALID_RESPONSE ;
+        else
+            ret = CyAsLLRequestResponse_GetWord(resp, 0) ;
+    }
+
+    node->cb_p((CyAsDeviceHandle)dev_p, ret, node->client_data, (CyAsFunctCBType)node->dataType, node->data) ;
+    CyAsRemoveCBNode(dev_p->func_cbs_usb) ;
+
+    CyAsLLDestroyRequest(dev_p, rqt) ;
+    CyAsLLDestroyResponse(dev_p, resp) ;
+    CyAsDeviceClearAckDelayed(dev_p) ;
+}
+
+static CyAsReturnStatus_t
+CyAsUsbAckSetupPacket(CyAsDeviceHandle handle,
+                      CyAsFunctionCallback      cb,
+                      uint32_t client)
+{
+    CyAsReturnStatus_t ret ;
+    CyAsLLRequestResponse *req_p ;
+    CyAsLLRequestResponse *reply_p ;
+    CyAsFuncCBNode* cbnode ;
+
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (CyAsDeviceIsInCallback(dev_p) && cb == 0)
+        return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+    CyAsHalAssert(cb != 0) ;
+
+    cbnode = CyAsCreateFuncCBNode(cb, client);
+    if( cbnode == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    req_p = CyAsLLCreateRequest(dev_p, 0, CY_RQT_USB_RQT_CONTEXT, 2) ;
+    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 ;
+    }
+
+    CyAsLLInitRequest(req_p, CY_RQT_ACK_SETUP_PACKET, CY_RQT_USB_RQT_CONTEXT, 1) ;
+    CyAsLLInitResponse(reply_p, 1) ;
+
+    req_p->flags |= CY_AS_REQUEST_RESPONSE_EX ;
+
+    CyAsInsertCBNode(dev_p->func_cbs_usb, cbnode) ;
+
+    ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyFalse, CyAsUsbAckCallback) ;
+
+    return ret ;
+}
+
+/*
+ * Flush all data in logical EP that is being NAK-ed or Stall-ed,
+ * so that this does not continue to block data on other LEPs that
+ * use the same physical EP.
+ */
+static void
+CyAsUsbFlushLogicalEP(
+        CyAsDevice *dev_p,
+        uint16_t    ep)
+{
+    uint16_t addr, val, count ;
+
+    addr = CY_AS_MEM_P0_EP2_DMA_REG + ep - 2 ;
+    val  = CyAsHalReadRegister(dev_p->tag, addr) ;
+
+    while (val)
+    {
+        count = ((val & 0xFFF) + 1) / 2 ;
+        while (count--)
+        {
+            val = CyAsHalReadRegister(dev_p->tag, ep) ;
+        }
+
+        CyAsHalWriteRegister(dev_p->tag, addr, 0) ;
+        val = CyAsHalReadRegister(dev_p->tag, addr) ;
+    }
+}
+
+static CyAsReturnStatus_t
+CyAsUsbNakStallRequest(CyAsDeviceHandle handle,
+                       CyAsEndPointNumber_t ep,
+                       uint16_t request,
+                       CyBool state,
+                       CyAsUsbFunctionCallback cb,
+                       CyAsFunctionCallback fcb,
+                       uint32_t client)
+{
+    CyAsReturnStatus_t ret ;
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    uint16_t data ;
+
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    if(cb)
+        CyAsHalAssert(fcb == 0) ;
+    if(fcb)
+        CyAsHalAssert(cb == 0) ;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (CyAsDeviceIsInCallback(dev_p) && cb == 0 && fcb == 0)
+        return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+    req_p = CyAsLLCreateRequest(dev_p, request, CY_RQT_USB_RQT_CONTEXT, 2) ;
+    if (req_p == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    /* A single status word response type */
+    reply_p = CyAsLLCreateResponse(dev_p, 1) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+
+    /* Set the endpoint */
+    data = (uint8_t)ep ;
+    CyAsLLRequestResponse_SetWord(req_p, 0, data) ;
+
+    /* Set stall state to stalled */
+    CyAsLLRequestResponse_SetWord(req_p, 1, (uint8_t)state) ;
+
+    if (cb || fcb)
+    {
+        void * cbnode ;
+        CyAsCBQueue* queue ;
+        if(cb)
+        {
+            cbnode = CyAsCreateUsbFuncCBNode(cb, client) ;
+            queue = dev_p->usb_func_cbs ;
+        }
+        else
+        {
+            cbnode = CyAsCreateFuncCBNode(fcb, client) ;
+            queue = dev_p->func_cbs_usb ;
+            req_p->flags |= CY_AS_REQUEST_RESPONSE_EX ;
+        }
+
+        if(cbnode == 0)
+        {
+            ret = CY_AS_ERROR_OUT_OF_MEMORY ;
+            goto destroy ;
+        }
+        else
+            CyAsInsertCBNode(queue, cbnode) ;
+
+
+        if (CyAsDeviceIsSetupPacket(dev_p))
+        {
+            /* No Ack is needed on a stall request on EP0 */
+            if ((state == CyTrue) && (ep == 0))
+            {
+                CyAsDeviceSetEp0Stalled(dev_p) ;
+            }
+            else
+            {
+                CyAsDeviceSetAckDelayed(dev_p) ;
+                req_p->flags |= CY_AS_REQUEST_RESPONSE_DELAY_ACK ;
+            }
+        }
+
+        ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyFalse, CyAsUsbFuncCallback) ;
+        if (ret != CY_AS_ERROR_SUCCESS)
+        {
+            if (req_p->flags & CY_AS_REQUEST_RESPONSE_DELAY_ACK)
+                CyAsDeviceRemAckDelayed(dev_p) ;
+            CyAsRemoveCBTailNode(queue) ;
+
+            goto destroy ;
+        }
+    }
+    else
+    {
+        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) ;
+
+        if ((ret == CY_AS_ERROR_SUCCESS) && (request == CY_RQT_STALL_ENDPOINT))
+        {
+            if ((ep > 1) && (state != 0) && (dev_p->usb_config[ep].dir == CyAsUsbOut))
+                CyAsUsbFlushLogicalEP(dev_p, ep) ;
+        }
+
+destroy:
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        CyAsLLDestroyResponse(dev_p, reply_p) ;
+    }
+
+    return ret ;
+}
+
+static CyAsReturnStatus_t
+MyHandleResponseGetStall(CyAsDevice* dev_p,
+                         CyAsLLRequestResponse *req_p,
+                         CyAsLLRequestResponse *reply_p,
+                         CyBool *state_p)
+{
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    uint8_t code = CyAsLLRequestResponse_GetCode(reply_p) ;
+
+    if (code == CY_RESP_SUCCESS_FAILURE)
+    {
+        ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+        goto destroy ;
+    }
+    else if (code != CY_RESP_ENDPOINT_STALL)
+    {
+        ret = CY_AS_ERROR_INVALID_RESPONSE ;
+        goto destroy ;
+    }
+
+    *state_p = (CyBool)CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+    ret = CY_AS_ERROR_SUCCESS ;
+
+
+destroy :
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+        return ret ;
+}
+
+static CyAsReturnStatus_t
+MyHandleResponseGetNak(CyAsDevice* dev_p,
+                       CyAsLLRequestResponse *req_p,
+                       CyAsLLRequestResponse *reply_p,
+                       CyBool *state_p)
+{
+    CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
+    uint8_t code = CyAsLLRequestResponse_GetCode(reply_p) ;
+
+    if (code == CY_RESP_SUCCESS_FAILURE)
+    {
+        ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+        goto destroy ;
+    }
+    else if (code != CY_RESP_ENDPOINT_NAK)
+    {
+        ret = CY_AS_ERROR_INVALID_RESPONSE ;
+        goto destroy ;
+    }
+
+    *state_p = (CyBool)CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+    ret = CY_AS_ERROR_SUCCESS ;
+
+
+destroy :
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+        return ret ;
+}
+
+static CyAsReturnStatus_t
+CyAsUsbGetNakStall(CyAsDeviceHandle handle,
+                   CyAsEndPointNumber_t ep,
+                   uint16_t request,
+                   uint16_t response,
+                   CyBool *state_p,
+                   CyAsFunctionCallback cb,
+                   uint32_t client)
+{
+    CyAsReturnStatus_t ret ;
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    uint16_t data ;
+
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+
+    (void)response ;
+
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (CyAsDeviceIsInCallback(dev_p) && !cb)
+        return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+    req_p = CyAsLLCreateRequest(dev_p, request, CY_RQT_USB_RQT_CONTEXT, 1) ;
+    if (req_p == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    /* Set the endpoint */
+    data = (uint8_t)ep ;
+    CyAsLLRequestResponse_SetWord(req_p, 0, (uint16_t)ep) ;
+
+    /* A single status word response type */
+    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(request == CY_RQT_GET_STALL)
+            return MyHandleResponseGetStall(dev_p, req_p, reply_p, state_p) ;
+        else
+            return MyHandleResponseGetNak(dev_p, req_p, reply_p, state_p) ;
+
+    }
+    else
+    {
+        CyAsFunctCBType type ;
+
+        if(request == CY_RQT_GET_STALL)
+            type = CY_FUNCT_CB_USB_GETSTALL ;
+        else
+            type = CY_FUNCT_CB_USB_GETNAK ;
+
+        ret = CyAsMiscSendRequest(dev_p, cb, client, type,
+            state_p, dev_p->func_cbs_usb, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+            CyAsUsbFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+
+        return ret ;
+    }
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+CyAsReturnStatus_t
+CyAsUsbSetNak(CyAsDeviceHandle handle,
+                CyAsEndPointNumber_t ep,
+                CyAsFunctionCallback cb,
+                uint32_t client)
+{
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    /*
+    * We send the firmware the EP# with the appropriate direction bit, regardless
+    * of what the user gave us.
+    */
+    ep &= 0x0f ;
+    if (dev_p->usb_config[ep].dir == CyAsUsbIn)
+        ep |= 0x80 ;
+
+        if(dev_p->mtp_count > 0)
+                return CY_AS_ERROR_NOT_VALID_IN_MTP ;
+
+    return CyAsUsbNakStallRequest(handle, ep, CY_RQT_ENDPOINT_SET_NAK, CyTrue, 0, cb, client) ;
+}
+
+
+CyAsReturnStatus_t
+CyAsUsbClearNak(CyAsDeviceHandle handle,
+                  CyAsEndPointNumber_t ep,
+                  CyAsFunctionCallback cb,
+                  uint32_t client)
+{
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    /*
+    * We send the firmware the EP# with the appropriate direction bit, regardless
+    * of what the user gave us.
+    */
+    ep &= 0x0f ;
+    if (dev_p->usb_config[ep].dir == CyAsUsbIn)
+        ep |= 0x80 ;
+
+        if(dev_p->mtp_count > 0)
+                return CY_AS_ERROR_NOT_VALID_IN_MTP ;
+
+    return CyAsUsbNakStallRequest(handle, ep, CY_RQT_ENDPOINT_SET_NAK, CyFalse, 0, cb, client) ;
+}
+
+CyAsReturnStatus_t
+CyAsUsbGetNak(CyAsDeviceHandle handle,
+                CyAsEndPointNumber_t ep,
+                CyBool *nak_p,
+                CyAsFunctionCallback cb,
+                uint32_t client)
+{
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    /*
+    * We send the firmware the EP# with the appropriate direction bit, regardless
+    * of what the user gave us.
+    */
+    ep &= 0x0f ;
+    if (dev_p->usb_config[ep].dir == CyAsUsbIn)
+        ep |= 0x80 ;
+
+        if(dev_p->mtp_count > 0)
+                return CY_AS_ERROR_NOT_VALID_IN_MTP ;
+
+    return CyAsUsbGetNakStall(handle, ep, CY_RQT_GET_ENDPOINT_NAK, CY_RESP_ENDPOINT_NAK, nak_p, cb, client ) ;
+}
+
+
+CyAsReturnStatus_t
+CyAsUsbSetStall(CyAsDeviceHandle handle,
+                  CyAsEndPointNumber_t ep,
+                  CyAsFunctionCallback cb,
+                  uint32_t client)
+{
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    /*
+    * We send the firmware the EP# with the appropriate direction bit, regardless
+    * of what the user gave us.
+    */
+    ep &= 0x0f ;
+    if (dev_p->usb_config[ep].dir == CyAsUsbIn)
+        ep |= 0x80 ;
+
+    if(dev_p->mtp_turbo_active)
+        return CY_AS_ERROR_NOT_VALID_DURING_MTP ;
+
+    return CyAsUsbNakStallRequest(handle, ep, CY_RQT_STALL_ENDPOINT, CyTrue, 0, cb, client) ;
+}
+
+CyAsReturnStatus_t
+CyAsUsbClearStall(CyAsDeviceHandle handle,
+                    CyAsEndPointNumber_t ep,
+                    CyAsFunctionCallback cb,
+                    uint32_t client)
+{
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    /*
+    * We send the firmware the EP# with the appropriate direction bit, regardless
+    * of what the user gave us.
+    */
+    ep &= 0x0f ;
+    if (dev_p->usb_config[ep].dir == CyAsUsbIn)
+        ep |= 0x80 ;
+
+    if(dev_p->mtp_turbo_active)
+        return CY_AS_ERROR_NOT_VALID_DURING_MTP ;
+
+    return CyAsUsbNakStallRequest(handle, ep, CY_RQT_STALL_ENDPOINT, CyFalse, 0, cb, client) ;
+}
+
+CyAsReturnStatus_t
+CyAsUsbGetStall(CyAsDeviceHandle handle,
+                  CyAsEndPointNumber_t ep,
+                  CyBool *stall_p,
+                  CyAsFunctionCallback cb,
+                  uint32_t client)
+{
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    /*
+    * We send the firmware the EP# with the appropriate direction bit, regardless
+    * of what the user gave us.
+    */
+    ep &= 0x0f ;
+    if (dev_p->usb_config[ep].dir == CyAsUsbIn)
+        ep |= 0x80 ;
+
+    if(dev_p->mtp_turbo_active)
+        return CY_AS_ERROR_NOT_VALID_DURING_MTP ;
+
+    return CyAsUsbGetNakStall(handle, ep, CY_RQT_GET_STALL, CY_RESP_ENDPOINT_STALL, stall_p, cb, client) ;
+}
+
+CyAsReturnStatus_t
+CyAsUsbSignalRemoteWakeup(CyAsDeviceHandle handle,
+        CyAsFunctionCallback cb,
+        uint32_t client)
+{
+    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 = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if (CyAsDeviceIsInCallback(dev_p))
+        return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+    if (dev_p->usb_last_event != CyAsEventUsbSuspend)
+        return CY_AS_ERROR_NOT_IN_SUSPEND ;
+
+    req_p = CyAsLLCreateRequest(dev_p, CY_RQT_USB_REMOTE_WAKEUP, CY_RQT_USB_RQT_CONTEXT, 0) ;
+    if (req_p == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    /* A single status word response type */
+    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 = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+        else
+            ret = CY_AS_ERROR_INVALID_RESPONSE ;
+    }
+    else
+    {
+        ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_USB_SIGNALREMOTEWAKEUP,
+            0, dev_p->func_cbs_usb, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+            CyAsUsbFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+        return ret ;
+    }
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+CyAsReturnStatus_t
+CyAsUsbSetMSReportThreshold(CyAsDeviceHandle handle,
+        uint32_t wr_sectors,
+        uint32_t rd_sectors,
+        CyAsFunctionCallback cb,
+        uint32_t client)
+{
+    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 = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    if ((cb == 0) && (CyAsDeviceIsInCallback(dev_p)))
+        return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+    /* Check if the firmware version supports this feature. */
+    if ((dev_p->media_supported[0]) && (dev_p->media_supported[0] == (1 << CyAsMediaNand)))
+        return CY_AS_ERROR_NOT_SUPPORTED ;
+
+    req_p = CyAsLLCreateRequest(dev_p, CY_RQT_USB_STORAGE_MONITOR, CY_RQT_USB_RQT_CONTEXT, 4) ;
+    if (req_p == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    /* A single status word response type */
+    reply_p = CyAsLLCreateResponse(dev_p, 1) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+
+    /* Set the read and write count parameters into the request structure. */
+    CyAsLLRequestResponse_SetWord(req_p, 0, (uint16_t)((wr_sectors >> 16) & 0xFFFF)) ;
+    CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)(wr_sectors & 0xFFFF)) ;
+    CyAsLLRequestResponse_SetWord(req_p, 2, (uint16_t)((rd_sectors >> 16) & 0xFFFF)) ;
+    CyAsLLRequestResponse_SetWord(req_p, 3, (uint16_t)(rd_sectors & 0xFFFF)) ;
+
+    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 = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+        else
+            ret = CY_AS_ERROR_INVALID_RESPONSE ;
+    }
+    else
+    {
+        ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_USB_SET_MSREPORT_THRESHOLD,
+            0, dev_p->func_cbs_usb, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+            CyAsUsbFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+        return ret ;
+    }
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+CyAsReturnStatus_t
+CyAsUsbSelectMSPartitions (
+        CyAsDeviceHandle        handle,
+        CyAsBusNumber_t         bus,
+        uint32_t                device,
+        CyAsUsbMSType_t         type,
+        CyAsFunctionCallback    cb,
+        uint32_t                client)
+{
+    CyAsReturnStatus_t ret ;
+    CyAsLLRequestResponse *req_p , *reply_p ;
+    uint16_t val ;
+
+    CyAsDevice *dev_p = (CyAsDevice *)handle ;
+    if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
+        return CY_AS_ERROR_INVALID_HANDLE ;
+
+    ret = IsUsbActive(dev_p) ;
+    if (ret != CY_AS_ERROR_SUCCESS)
+        return ret ;
+
+    /* This API has to be made before SetEnumConfig is called. */
+    if (dev_p->usb_config[0].enabled)
+        return CY_AS_ERROR_INVALID_CALL_SEQUENCE ;
+
+    if ((cb == 0) && (CyAsDeviceIsInCallback(dev_p)))
+        return CY_AS_ERROR_INVALID_IN_CALLBACK ;
+
+    req_p = CyAsLLCreateRequest(dev_p, CY_RQT_MS_PARTITION_SELECT, CY_RQT_USB_RQT_CONTEXT, 2) ;
+    if (req_p == 0)
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+
+    /* A single status word response type */
+    reply_p = CyAsLLCreateResponse(dev_p, 1) ;
+    if (reply_p == 0)
+    {
+        CyAsLLDestroyRequest(dev_p, req_p) ;
+        return CY_AS_ERROR_OUT_OF_MEMORY ;
+    }
+
+    /* Set the read and write count parameters into the request structure. */
+    CyAsLLRequestResponse_SetWord(req_p, 0, (uint16_t)((bus << 8) | device)) ;
+
+    val = 0 ;
+    if ((type == CyAsUsbMSUnit0) || (type == CyAsUsbMSBoth))
+        val |= 1 ;
+    if ((type == CyAsUsbMSUnit1) || (type == CyAsUsbMSBoth))
+        val |= (1 << 8) ;
+
+    CyAsLLRequestResponse_SetWord(req_p, 1, val) ;
+
+    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 = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
+        else
+            ret = CY_AS_ERROR_INVALID_RESPONSE ;
+    }
+    else
+    {
+        ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_NODATA,
+            0, dev_p->func_cbs_usb, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
+            CyAsUsbFuncCallback) ;
+
+        if (ret != CY_AS_ERROR_SUCCESS)
+            goto destroy ;
+        return ret ;
+    }
+
+destroy:
+    CyAsLLDestroyRequest(dev_p, req_p) ;
+    CyAsLLDestroyResponse(dev_p, reply_p) ;
+
+    return ret ;
+}
+
+static void
+CyAsUsbFuncCallback(
+                    CyAsDevice *dev_p,
+                    uint8_t context,
+                    CyAsLLRequestResponse *rqt,
+                    CyAsLLRequestResponse *resp,
+                    CyAsReturnStatus_t stat)
+{
+    CyAsUsbFuncCBNode*  node = (CyAsUsbFuncCBNode*)dev_p->usb_func_cbs->head_p ;
+    CyAsFuncCBNode*     fnode = (CyAsFuncCBNode*)dev_p->func_cbs_usb->head_p ;
+    CyAsReturnStatus_t  ret = CY_AS_ERROR_SUCCESS ;
+
+    CyAsDeviceHandle    h = (CyAsDeviceHandle)dev_p ;
+    CyBool              delayed_ack = (rqt->flags & CY_AS_REQUEST_RESPONSE_DELAY_ACK) == CY_AS_REQUEST_RESPONSE_DELAY_ACK;
+    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             ep, state ;
+
+    if(!exRequest && !msRequest)
+    {
+        CyAsHalAssert(dev_p->usb_func_cbs->count != 0) ;
+        CyAsHalAssert(dev_p->usb_func_cbs->type == CYAS_USB_FUNC_CB) ;
+    }
+    else
+    {
+        CyAsHalAssert(dev_p->func_cbs_usb->count != 0) ;
+        CyAsHalAssert(dev_p->func_cbs_usb->type == CYAS_FUNC_CB) ;
+    }
+
+    (void)context ;
+
+    /* The Handlers are responsible for Deleting the rqt and resp when
+     * they are finished
+     */
+    code = CyAsLLRequestResponse_GetCode(rqt) ;
+    switch(code)
+    {
+    case CY_RQT_START_USB:
+        ret = MyHandleResponseUsbStart(dev_p, rqt, resp, stat) ;
+        break ;
+    case CY_RQT_STOP_USB:
+        ret = MyHandleResponseUsbStop(dev_p, rqt, resp, stat) ;
+        break ;
+    case CY_RQT_SET_CONNECT_STATE:
+        if(!CyAsLLRequestResponse_GetWord(rqt, 0))
+            ret = MyHandleResponseDisconnect(dev_p, rqt, resp, stat) ;
+        else
+            ret = MyHandleResponseConnect(dev_p, rqt, resp, stat) ;
+        break ;
+    case CY_RQT_GET_CONNECT_STATE:
+        break ;
+    case CY_RQT_SET_USB_CONFIG:
+        ret = MyHandleResponseSetEnumConfig(dev_p, rqt, resp) ;
+        break ;
+    case CY_RQT_GET_USB_CONFIG:
+        CyAsHalAssert(fnode->data != 0) ;
+        ret = MyHandleResponseGetEnumConfig(dev_p, rqt, resp, fnode->data) ;
+        break ;
+    case CY_RQT_STALL_ENDPOINT:
+        ep    = (uint8_t)CyAsLLRequestResponse_GetWord(rqt, 0) ;
+        state = (uint8_t)CyAsLLRequestResponse_GetWord(rqt, 1) ;
+        ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
+        if ((ret == CY_AS_ERROR_SUCCESS) && (ep > 1) && (state != 0) && (dev_p->usb_config[ep].dir == CyAsUsbOut))
+            CyAsUsbFlushLogicalEP(dev_p, ep) ;
+        break ;
+    case CY_RQT_GET_STALL:
+        CyAsHalAssert(fnode->data != 0) ;
+        ret = MyHandleResponseGetStall(dev_p, rqt, resp, (CyBool*)fnode->data) ;
+        break ;
+    case CY_RQT_SET_DESCRIPTOR:
+        ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
+        break ;
+    case CY_RQT_GET_DESCRIPTOR:
+        CyAsHalAssert(fnode->data != 0) ;
+        ret = MyHandleResponseGetDescriptor(dev_p, rqt, resp, (CyAsGetDescriptorData*)fnode->data) ;
+        break;
+    case CY_RQT_SET_USB_CONFIG_REGISTERS:
+        ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
+        if (ret == CY_AS_ERROR_SUCCESS)
+            ret = CyAsUsbSetupDma(dev_p) ;
+        break ;
+    case CY_RQT_ENDPOINT_SET_NAK:
+        ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
+        break ;
+    case CY_RQT_GET_ENDPOINT_NAK:
+        CyAsHalAssert(fnode->data != 0) ;
+        ret = MyHandleResponseGetNak(dev_p, rqt, resp, (CyBool*)fnode->data) ;
+        break ;
+    case CY_RQT_ACK_SETUP_PACKET:
+        break ;
+    case CY_RQT_USB_REMOTE_WAKEUP:
+        ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
+        break ;
+    case CY_RQT_CLEAR_DESCRIPTORS:
+        ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
+        break ;
+    case CY_RQT_USB_STORAGE_MONITOR:
+        ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
+        break ;
+    case CY_RQT_MS_PARTITION_SELECT:
+        ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
+        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 ;
+
+    if(exRequest || msRequest)
+    {
+        fnode->cb_p((CyAsDeviceHandle)dev_p, stat, fnode->client_data, (CyAsFunctCBType)fnode->dataType, fnode->data) ;
+        CyAsRemoveCBNode(dev_p->func_cbs_usb) ;
+    }
+    else
+    {
+        node->cb_p((CyAsDeviceHandle)dev_p, stat, node->client_data) ;
+        CyAsRemoveCBNode(dev_p->usb_func_cbs) ;
+    }
+
+    if(delayed_ack)
+    {
+        CyAsHalAssert(CyAsDeviceIsAckDelayed(dev_p)) ;
+        CyAsDeviceRemAckDelayed(dev_p) ;
+
+        /*
+         * Send the ACK if required.
+         */
+        if (!CyAsDeviceIsAckDelayed(dev_p))
+            CyAsUsbAckSetupPacket(h, UsbAckCallback, 0) ;
+    }
+}
+
+/* This includes the implementation of the deprecated functions for backward
+ * compatibility
+ */
+#include "cyasusb_dep_impl.h"
+
+/*[]*/