omap3530/beagle_drivers/wb/api/src/cyasmtp.c
changeset 27 117faf51deac
equal deleted inserted replaced
26:b7e488c49d0d 27:117faf51deac
       
     1 /* Cypress West Bridge API header file (cyasmtp.h)
       
     2 ## ===========================
       
     3 ##
       
     4 ##  Copyright Cypress Semiconductor Corporation, 2006-2009,
       
     5 ##  All Rights Reserved
       
     6 ##  UNPUBLISHED, LICENSED SOFTWARE.
       
     7 ##
       
     8 ##  CONFIDENTIAL AND PROPRIETARY INFORMATION
       
     9 ##  WHICH IS THE PROPERTY OF CYPRESS.
       
    10 ##
       
    11 ##  Use of this file is governed
       
    12 ##  by the license agreement included in the file
       
    13 ##
       
    14 ##     <install>/license/license.txt
       
    15 ##
       
    16 ##  where <install> is the Cypress software
       
    17 ##  installation root directory path.
       
    18 ##
       
    19 ## ===========================
       
    20 */
       
    21 
       
    22 #include "cyashal.h"
       
    23 #include "cyasmtp.h"
       
    24 #include "cyaserr.h"
       
    25 #include "cyasdma.h"
       
    26 #include "cyaslowlevel.h"
       
    27 
       
    28 static void
       
    29 CyAsMTPFuncCallback(CyAsDevice *dev_p,
       
    30                     uint8_t context,
       
    31                     CyAsLLRequestResponse *rqt,
       
    32                     CyAsLLRequestResponse *resp,
       
    33                     CyAsReturnStatus_t stat) ;
       
    34 
       
    35 static CyAsReturnStatus_t
       
    36 IsMTPActive(CyAsDevice *dev_p)
       
    37 {
       
    38     if (!CyAsDeviceIsConfigured(dev_p))
       
    39         return CY_AS_ERROR_NOT_CONFIGURED ;
       
    40 
       
    41     if (!CyAsDeviceIsFirmwareLoaded(dev_p))
       
    42         return CY_AS_ERROR_NO_FIRMWARE ;
       
    43 
       
    44     if (dev_p->mtp_count == 0)
       
    45         return CY_AS_ERROR_NOT_RUNNING ;
       
    46 
       
    47     if (CyAsDeviceIsInSuspendMode(dev_p))
       
    48         return CY_AS_ERROR_IN_SUSPEND ;
       
    49 
       
    50     return CY_AS_ERROR_SUCCESS ;
       
    51 }
       
    52 
       
    53 static void
       
    54 MyMtpRequestCallback(CyAsDevice *dev_p,
       
    55                      uint8_t context,
       
    56                      CyAsLLRequestResponse *req_p,
       
    57                      CyAsLLRequestResponse *resp_p,
       
    58                      CyAsReturnStatus_t ret)
       
    59 {
       
    60     uint16_t val, ev, status ;
       
    61     uint16_t mtp_datalen = 0 ;
       
    62     uint32_t bytecount_l, bytecount_h ;
       
    63     CyAsMTPSendObjectCompleteData sendObjData ;
       
    64     CyAsMTPGetObjectCompleteData  getObjData ;
       
    65     CyAsDmaEndPoint *ep_p ;
       
    66 
       
    67     uint8_t code = CyAsLLRequestResponse_GetCode(req_p) ;
       
    68 
       
    69     (void)resp_p ;
       
    70     (void)context ;
       
    71     (void)ret ;
       
    72 
       
    73     switch(code)
       
    74     {
       
    75     case CY_RQT_MTP_EVENT:
       
    76         val = CyAsLLRequestResponse_GetWord(req_p, 0) ;
       
    77         status = (val >> 8) & 0xFF ; /* MSB indicates status of read/write */
       
    78         ev =   val & 0xFF ; /* event type */
       
    79         switch(ev)
       
    80         {
       
    81         case 0: /* SendObject Complete */
       
    82             {
       
    83                 bytecount_l = CyAsLLRequestResponse_GetWord(req_p, 1) ;
       
    84                 bytecount_h = CyAsLLRequestResponse_GetWord(req_p, 2) ;
       
    85                 sendObjData.byte_count = (bytecount_h << 16) | bytecount_l ;
       
    86 
       
    87                 sendObjData.status = status ;
       
    88 
       
    89                 /* use the byte count again */
       
    90                 bytecount_l = CyAsLLRequestResponse_GetWord(req_p, 3) ;
       
    91                 bytecount_h = CyAsLLRequestResponse_GetWord(req_p, 4) ;
       
    92                 sendObjData.transaction_id = (bytecount_h << 16) | bytecount_l ;
       
    93 
       
    94                 dev_p->mtp_turbo_active = CyFalse ;
       
    95 
       
    96                 if (dev_p->mtp_event_cb)
       
    97                     dev_p->mtp_event_cb((CyAsDeviceHandle)dev_p,  CyAsMTPSendObjectComplete,
       
    98                                         &sendObjData) ;
       
    99             }
       
   100             break ;
       
   101 
       
   102         case 1: /* GetObject Complete */
       
   103             {
       
   104                 bytecount_l = CyAsLLRequestResponse_GetWord(req_p, 1) ;
       
   105                 bytecount_h = CyAsLLRequestResponse_GetWord(req_p, 2) ;
       
   106 
       
   107                 getObjData.byte_count = (bytecount_h << 16) | bytecount_l ;
       
   108                 getObjData.status = status ;
       
   109 
       
   110                 dev_p->mtp_turbo_active = CyFalse ;
       
   111 
       
   112                 if (dev_p->mtp_event_cb)
       
   113                     dev_p->mtp_event_cb((CyAsDeviceHandle)dev_p,  CyAsMTPGetObjectComplete,
       
   114                                         &getObjData);
       
   115             }
       
   116             break ;
       
   117 
       
   118         case 2: /* BlockTable Needed */
       
   119             {
       
   120                 if (dev_p->mtp_event_cb)
       
   121                     dev_p->mtp_event_cb((CyAsDeviceHandle)dev_p,  CyAsMTPBlockTableNeeded, 0);
       
   122             }
       
   123             break ;
       
   124         default:
       
   125             CyAsHalPrintMessage("Invalid event type\n") ;
       
   126             CyAsLLSendDataResponse(dev_p, CY_RQT_TUR_RQT_CONTEXT, CY_RESP_MTP_INVALID_EVENT, sizeof(ev), &ev) ;
       
   127             break ;
       
   128         }
       
   129         break ;
       
   130 
       
   131     case CY_RQT_TURBO_CMD_FROM_HOST:
       
   132         {
       
   133             mtp_datalen = CyAsLLRequestResponse_GetWord(req_p, 1) ;
       
   134 
       
   135             /* Get the endpoint pointer based on the endpoint number */
       
   136             ep_p = CY_AS_NUM_EP(dev_p, CY_AS_MTP_READ_ENDPOINT) ;
       
   137 
       
   138             /* The event should arrive only after the DMA operation has been queued. */
       
   139             CyAsHalAssert(ep_p->queue_p != 0) ;
       
   140 
       
   141             /* Put the len in ep data information in dmaqueue and kick start the queue */
       
   142             CyAsHalAssert(ep_p->queue_p->size >= mtp_datalen) ;
       
   143 
       
   144             if (mtp_datalen == 0)
       
   145             {
       
   146                 CyAsDmaCompletedCallback(dev_p->tag, CY_AS_MTP_READ_ENDPOINT, 0, CY_AS_ERROR_SUCCESS) ;
       
   147             }
       
   148             else
       
   149             {
       
   150                 ep_p->maxhwdata = mtp_datalen ;
       
   151 
       
   152                 /*
       
   153                  * Make sure that the DMA status for this EP is not running, so that
       
   154                  * the call to CyAsDmaKickStart gets this transfer going.
       
   155                  * Note: In MTP mode, we never leave a DMA transfer of greater than one
       
   156                  * packet running. So, it is okay to override the status here and start
       
   157                  * the next packet transfer.
       
   158                  */
       
   159                 CyAsDmaEndPointSetStopped(ep_p) ;
       
   160 
       
   161                 /* Kick start the queue if it is not running */
       
   162                 CyAsDmaKickStart(dev_p, CY_AS_MTP_READ_ENDPOINT) ;
       
   163             }
       
   164         }
       
   165         break ;
       
   166 
       
   167     case CY_RQT_TURBO_START_WRITE_DMA:
       
   168         {
       
   169             /*
       
   170              * Now that the firmware is ready to receive the next packet of data, start
       
   171              * the corresponding DMA transfer.  First, ensure that a DMA operation is still
       
   172              * pending in the queue for the write endpoint.
       
   173              */
       
   174             CyAsLLSendStatusResponse(dev_p, CY_RQT_TUR_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
       
   175 
       
   176             ep_p = CY_AS_NUM_EP(dev_p, CY_AS_MTP_WRITE_ENDPOINT) ;
       
   177             CyAsHalAssert (ep_p->queue_p != 0) ;
       
   178 
       
   179             CyAsDmaEndPointSetStopped(ep_p) ;
       
   180             CyAsDmaKickStart(dev_p, CY_AS_MTP_WRITE_ENDPOINT) ;
       
   181         }
       
   182         break ;
       
   183 
       
   184     default:
       
   185         CyAsHalPrintMessage("Invalid request received on TUR context\n") ;
       
   186         val = req_p->box0 ;
       
   187         CyAsLLSendDataResponse(dev_p, CY_RQT_TUR_RQT_CONTEXT, CY_RESP_INVALID_REQUEST, sizeof(val), &val) ;
       
   188         break ;
       
   189     }
       
   190 }
       
   191 
       
   192 static CyAsReturnStatus_t
       
   193 MyHandleResponseNoData(CyAsDevice* dev_p,
       
   194                          CyAsLLRequestResponse *req_p,
       
   195                          CyAsLLRequestResponse *reply_p)
       
   196 {
       
   197     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   198 
       
   199     if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
       
   200     {
       
   201         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
   202         goto destroy ;
       
   203     }
       
   204 
       
   205     ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
   206 
       
   207 destroy :
       
   208     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   209     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   210 
       
   211     return ret ;
       
   212 }
       
   213 
       
   214 static CyAsReturnStatus_t
       
   215 MyHandleResponseMTPStart(CyAsDevice* dev_p,
       
   216                          CyAsLLRequestResponse *req_p,
       
   217                          CyAsLLRequestResponse *reply_p,
       
   218                          CyAsReturnStatus_t ret)
       
   219 {
       
   220     if (ret != CY_AS_ERROR_SUCCESS)
       
   221         goto destroy ;
       
   222 
       
   223     if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
       
   224     {
       
   225         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
   226         goto destroy ;
       
   227     }
       
   228 
       
   229     ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
   230     if (ret != CY_AS_ERROR_SUCCESS)
       
   231         goto destroy ;
       
   232 
       
   233     dev_p->mtp_count++ ;
       
   234 
       
   235     CyAsDmaEnableEndPoint(dev_p, CY_AS_MTP_READ_ENDPOINT, CyTrue, CyAsDirectionOut) ;
       
   236     dev_p->usb_config[CY_AS_MTP_READ_ENDPOINT].enabled = CyTrue ;
       
   237     dev_p->usb_config[CY_AS_MTP_READ_ENDPOINT].dir = CyAsUsbOut ;
       
   238     dev_p->usb_config[CY_AS_MTP_READ_ENDPOINT].type = CyAsUsbBulk ;
       
   239 
       
   240     CyAsDmaEnableEndPoint(dev_p, CY_AS_MTP_WRITE_ENDPOINT, CyTrue, CyAsDirectionIn) ;
       
   241     dev_p->usb_config[CY_AS_MTP_WRITE_ENDPOINT].enabled = CyTrue ;
       
   242     dev_p->usb_config[CY_AS_MTP_WRITE_ENDPOINT].dir = CyAsUsbIn ;
       
   243     dev_p->usb_config[CY_AS_MTP_WRITE_ENDPOINT].type = CyAsUsbBulk ;
       
   244 
       
   245     CyAsDmaSetMaxDmaSize(dev_p, 0x02, 0x0200) ; /* Packet size is 512 bytes */
       
   246     CyAsDmaSetMaxDmaSize(dev_p, 0x06, 0x40) ;   /* Packet size is 64 bytes until a switch to high speed happens. */
       
   247 
       
   248 destroy :
       
   249     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   250     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   251 
       
   252     if (ret != CY_AS_ERROR_SUCCESS)
       
   253         CyAsLLRegisterRequestCallback(dev_p, CY_RQT_TUR_RQT_CONTEXT, 0) ;
       
   254 
       
   255     CyAsDeviceClearMSSPending(dev_p) ;
       
   256 
       
   257     return ret ;
       
   258 }
       
   259 
       
   260 
       
   261 CyAsReturnStatus_t
       
   262 CyAsMTPStart(CyAsDeviceHandle handle,
       
   263              CyAsMTPEventCallback eventCB,
       
   264              CyAsFunctionCallback cb,
       
   265              uint32_t client
       
   266              )
       
   267 {
       
   268     CyAsLLRequestResponse *req_p, *reply_p ;
       
   269     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   270     CyAsDevice* dev_p ;
       
   271 
       
   272     dev_p = (CyAsDevice *)handle ;
       
   273     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
   274         return CY_AS_ERROR_INVALID_HANDLE ;
       
   275 
       
   276     if (!CyAsDeviceIsConfigured(dev_p))
       
   277         return CY_AS_ERROR_NOT_CONFIGURED ;
       
   278 
       
   279     if (!CyAsDeviceIsFirmwareLoaded(dev_p))
       
   280         return CY_AS_ERROR_NO_FIRMWARE ;
       
   281 
       
   282     if (CyAsDeviceIsInSuspendMode(dev_p))
       
   283         return CY_AS_ERROR_IN_SUSPEND ;
       
   284 
       
   285     if (CyAsDeviceIsInCallback(dev_p))
       
   286         return CY_AS_ERROR_INVALID_IN_CALLBACK ;
       
   287 
       
   288     if(CyAsDeviceIsMSSPending(dev_p))
       
   289         return CY_AS_ERROR_STARTSTOP_PENDING ;
       
   290 
       
   291     if (dev_p->storage_count == 0)
       
   292         return CY_AS_ERROR_NOT_RUNNING ;
       
   293 
       
   294     if (dev_p->usb_count == 0)
       
   295         return CY_AS_ERROR_NOT_RUNNING ;
       
   296 
       
   297     if (dev_p->is_mtp_firmware == 0)
       
   298         return CY_AS_ERROR_NOT_SUPPORTED ;
       
   299 
       
   300     CyAsDeviceSetMSSPending(dev_p) ;
       
   301 
       
   302     if (dev_p->mtp_count == 0)
       
   303     {
       
   304 
       
   305         dev_p->mtp_event_cb = eventCB ;
       
   306         /*
       
   307         * We register here becuase the start request may cause events to occur before the
       
   308         * response to the start request.
       
   309         */
       
   310         CyAsLLRegisterRequestCallback(dev_p, CY_RQT_TUR_RQT_CONTEXT, MyMtpRequestCallback) ;
       
   311 
       
   312         /* Create the request to send to the West Bridge device */
       
   313         req_p = CyAsLLCreateRequest(dev_p, CY_RQT_START_MTP, CY_RQT_TUR_RQT_CONTEXT, 0) ;
       
   314         if (req_p == 0)
       
   315         {
       
   316             CyAsDeviceClearMSSPending(dev_p) ;
       
   317             return CY_AS_ERROR_OUT_OF_MEMORY ;
       
   318         }
       
   319 
       
   320         /* Reserve space for the reply, the reply data will not exceed one word */
       
   321         reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
   322         if (reply_p == 0)
       
   323         {
       
   324             CyAsLLDestroyRequest(dev_p, req_p) ;
       
   325             CyAsDeviceClearMSSPending(dev_p) ;
       
   326             return CY_AS_ERROR_OUT_OF_MEMORY ;
       
   327         }
       
   328 
       
   329         if(cb == 0)
       
   330         {
       
   331             ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
   332             if (ret != CY_AS_ERROR_SUCCESS)
       
   333                 goto destroy ;
       
   334 
       
   335             return MyHandleResponseMTPStart(dev_p, req_p, reply_p, ret) ;
       
   336         }
       
   337         else
       
   338         {
       
   339             ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MTP_START,
       
   340                 0, dev_p->func_cbs_mtp, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
       
   341                 CyAsMTPFuncCallback) ;
       
   342 
       
   343             if (ret != CY_AS_ERROR_SUCCESS)
       
   344                 goto destroy ;
       
   345 
       
   346             return ret ;
       
   347         }
       
   348 
       
   349 destroy:
       
   350         CyAsLLDestroyRequest(dev_p, req_p) ;
       
   351         CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   352     }
       
   353     else
       
   354     {
       
   355         dev_p->mtp_count++ ;
       
   356         if (cb)
       
   357             cb(handle, ret, client, CY_FUNCT_CB_MTP_START, 0) ;
       
   358     }
       
   359 
       
   360     CyAsDeviceClearMSSPending(dev_p) ;
       
   361 
       
   362     return ret ;
       
   363 }
       
   364 
       
   365 static CyAsReturnStatus_t
       
   366 MyHandleResponseMTPStop(CyAsDevice* dev_p,
       
   367                         CyAsLLRequestResponse *req_p,
       
   368                         CyAsLLRequestResponse *reply_p,
       
   369                         CyAsReturnStatus_t ret)
       
   370 {
       
   371     if (ret != CY_AS_ERROR_SUCCESS)
       
   372         goto destroy ;
       
   373 
       
   374     if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
       
   375     {
       
   376         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
   377         goto destroy ;
       
   378     }
       
   379 
       
   380     ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
   381     if (ret != CY_AS_ERROR_SUCCESS)
       
   382         goto destroy ;
       
   383 
       
   384     /*
       
   385     * We sucessfully shutdown the stack, so decrement to make the count
       
   386     * zero.
       
   387     */
       
   388     dev_p->mtp_count-- ;
       
   389 
       
   390 destroy :
       
   391     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   392     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   393 
       
   394     if (ret != CY_AS_ERROR_SUCCESS)
       
   395         CyAsLLRegisterRequestCallback(dev_p, CY_RQT_TUR_RQT_CONTEXT, 0) ;
       
   396 
       
   397     CyAsDeviceClearMSSPending(dev_p) ;
       
   398 
       
   399     return ret ;
       
   400 }
       
   401 
       
   402 CyAsReturnStatus_t
       
   403 CyAsMTPStop(CyAsDeviceHandle handle,
       
   404             CyAsFunctionCallback cb,
       
   405             uint32_t client
       
   406             )
       
   407 {
       
   408     CyAsLLRequestResponse *req_p = 0, *reply_p = 0 ;
       
   409     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   410 
       
   411     CyAsDevice*dev_p ;
       
   412 
       
   413     CyAsLogDebugMessage(6, "CyAsMTPStop called") ;
       
   414 
       
   415     dev_p = (CyAsDevice *)handle ;
       
   416     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
   417         return CY_AS_ERROR_INVALID_HANDLE ;
       
   418 
       
   419     ret = IsMTPActive(dev_p) ;
       
   420     if (ret != CY_AS_ERROR_SUCCESS)
       
   421         return ret ;
       
   422 
       
   423     if (CyAsDeviceIsInCallback(dev_p))
       
   424         return CY_AS_ERROR_INVALID_IN_CALLBACK ;
       
   425 
       
   426     if(CyAsDeviceIsMSSPending(dev_p))
       
   427         return CY_AS_ERROR_STARTSTOP_PENDING ;
       
   428 
       
   429     CyAsDeviceSetMSSPending(dev_p) ;
       
   430 
       
   431     if (dev_p->mtp_count == 1)
       
   432     {
       
   433         /* Create the request to send to the West Bridge device */
       
   434         req_p = CyAsLLCreateRequest(dev_p, CY_RQT_STOP_MTP, CY_RQT_TUR_RQT_CONTEXT, 0) ;
       
   435         if (req_p == 0)
       
   436         {
       
   437             ret = CY_AS_ERROR_OUT_OF_MEMORY ;
       
   438             goto destroy ;
       
   439         }
       
   440 
       
   441         /* Reserve space for the reply, the reply data will not exceed one word */
       
   442         reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
   443         if (reply_p == 0)
       
   444         {
       
   445             ret = CY_AS_ERROR_OUT_OF_MEMORY ;
       
   446             goto destroy ;
       
   447         }
       
   448 
       
   449         if(cb == 0)
       
   450         {
       
   451             ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
   452             if (ret != CY_AS_ERROR_SUCCESS)
       
   453                 goto destroy ;
       
   454 
       
   455             return MyHandleResponseMTPStop(dev_p, req_p, reply_p, ret) ;
       
   456         }
       
   457         else
       
   458         {
       
   459             ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MTP_STOP,
       
   460                 0, dev_p->func_cbs_mtp, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
       
   461                 CyAsMTPFuncCallback) ;
       
   462 
       
   463             if (ret != CY_AS_ERROR_SUCCESS)
       
   464                 goto destroy ;
       
   465 
       
   466             return ret ;
       
   467         }
       
   468 
       
   469 destroy:
       
   470         CyAsLLDestroyRequest(dev_p, req_p) ;
       
   471         CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   472     }
       
   473     else if (dev_p->mtp_count > 1)
       
   474     {
       
   475 
       
   476         dev_p->mtp_count-- ;
       
   477 
       
   478         if (cb)
       
   479             cb(handle, ret, client, CY_FUNCT_CB_MTP_STOP, 0) ;
       
   480     }
       
   481 
       
   482     CyAsDeviceClearMSSPending(dev_p) ;
       
   483 
       
   484     return ret ;
       
   485 }
       
   486 
       
   487 static void
       
   488 MtpWriteCallback(
       
   489         CyAsDevice *dev_p,
       
   490         uint8_t context,
       
   491         CyAsLLRequestResponse *rqt,
       
   492         CyAsLLRequestResponse *resp,
       
   493         CyAsReturnStatus_t ret)
       
   494 {
       
   495     CyAsHalAssert(context == CY_RQT_TUR_RQT_CONTEXT) ;
       
   496 
       
   497     if (ret == CY_AS_ERROR_SUCCESS)
       
   498     {
       
   499         if (CyAsLLRequestResponse_GetCode(resp) != CY_RESP_SUCCESS_FAILURE)
       
   500             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
   501         else
       
   502             ret = CyAsLLRequestResponse_GetWord(resp, 0) ;
       
   503     }
       
   504 
       
   505     if (ret != CY_AS_ERROR_SUCCESS)
       
   506     {
       
   507         /* Firmware failed the request. Cancel the DMA transfer. */
       
   508         CyAsDmaCancel(dev_p, 0x04, CY_AS_ERROR_CANCELED) ;
       
   509         CyAsDeviceClearStorageAsyncPending(dev_p) ;
       
   510     }
       
   511 
       
   512     CyAsLLDestroyResponse(dev_p, resp) ;
       
   513     CyAsLLDestroyRequest(dev_p, rqt) ;
       
   514 }
       
   515 
       
   516 static void
       
   517 AsyncWriteRequestCallback(CyAsDevice *dev_p, CyAsEndPointNumber_t ep, void *buf_p, uint32_t size, CyAsReturnStatus_t err)
       
   518 {
       
   519     CyAsDeviceHandle h ;
       
   520     CyAsFunctionCallback cb ;
       
   521 
       
   522     (void)size ;
       
   523     (void)buf_p ;
       
   524     (void)ep ;
       
   525 
       
   526 
       
   527     CyAsLogDebugMessage(6, "AsyncWriteRequestCallback called") ;
       
   528 
       
   529     h = (CyAsDeviceHandle)dev_p ;
       
   530 
       
   531     cb = dev_p->mtp_cb ;
       
   532     dev_p->mtp_cb = 0 ;
       
   533 
       
   534     CyAsDeviceClearStorageAsyncPending(dev_p) ;
       
   535 
       
   536     if (cb)
       
   537         cb(h, err, dev_p->mtp_client, dev_p->mtp_op, 0) ;
       
   538 
       
   539 }
       
   540 
       
   541 static void
       
   542 SyncMTPCallback(CyAsDevice *dev_p, CyAsEndPointNumber_t ep, void *buf_p, uint32_t size, CyAsReturnStatus_t err)
       
   543 {
       
   544     (void)ep ;
       
   545     (void)buf_p ;
       
   546     (void)size ;
       
   547 
       
   548     dev_p->mtp_error = err ;
       
   549 }
       
   550 
       
   551 static CyAsReturnStatus_t
       
   552 CyAsMTPOperation(CyAsDevice *dev_p,
       
   553                  CyAsMTPBlockTable* blk_table,
       
   554                  uint32_t num_bytes,
       
   555                  uint32_t transaction_id,
       
   556                  CyAsFunctionCallback cb,
       
   557                  uint32_t client,
       
   558                  uint8_t rqttype
       
   559                  )
       
   560 {
       
   561     CyAsLLRequestResponse *req_p = 0, *reply_p = 0 ;
       
   562     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   563     uint32_t mask = 0 ;
       
   564     CyAsFunctCBType mtp_cb_op = (CyAsFunctCBType)0 ;
       
   565     uint16_t size = 2 ;
       
   566 
       
   567         if(dev_p->mtp_count == 0)
       
   568                 return CY_AS_ERROR_NOT_RUNNING ;
       
   569 
       
   570     if (rqttype == CY_RQT_INIT_SEND_OBJECT)
       
   571     {
       
   572         mtp_cb_op = CY_FUNCT_CB_MTP_INIT_SEND_OBJECT ;
       
   573         dev_p->mtp_turbo_active = CyTrue ;
       
   574     }
       
   575     else if (rqttype == CY_RQT_INIT_GET_OBJECT)
       
   576     {
       
   577         mtp_cb_op = CY_FUNCT_CB_MTP_INIT_GET_OBJECT ;
       
   578         dev_p->mtp_turbo_active = CyTrue ;
       
   579     }
       
   580     else
       
   581         mtp_cb_op = CY_FUNCT_CB_MTP_SEND_BLOCK_TABLE ;
       
   582 
       
   583     ret = IsMTPActive(dev_p) ;
       
   584     if (ret != CY_AS_ERROR_SUCCESS)
       
   585         return ret ;
       
   586 
       
   587     if (CY_RQT_INIT_GET_OBJECT == rqttype)
       
   588     {
       
   589         size = 4 ;
       
   590     }
       
   591     /* Create the request to send to the West Bridge device */
       
   592     req_p = CyAsLLCreateRequest(dev_p, rqttype, CY_RQT_TUR_RQT_CONTEXT, size) ;
       
   593     if (req_p == 0)
       
   594     {
       
   595         ret = CY_AS_ERROR_OUT_OF_MEMORY ;
       
   596         goto destroy ;
       
   597     }
       
   598 
       
   599     /* Reserve space for the reply, the reply data will not exceed one word */
       
   600     reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
   601     if (reply_p == 0)
       
   602     {
       
   603         ret = CY_AS_ERROR_OUT_OF_MEMORY ;
       
   604         goto destroy ;
       
   605     }
       
   606 
       
   607     CyAsLLRequestResponse_SetWord(req_p, 0, (uint16_t)(num_bytes & 0xFFFF)) ;
       
   608     CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)((num_bytes >> 16) & 0xFFFF)) ;
       
   609 
       
   610     /* If it is GET_OBJECT, send transaction id as well */
       
   611     if (CY_RQT_INIT_GET_OBJECT == rqttype)
       
   612     {
       
   613         CyAsLLRequestResponse_SetWord(req_p, 2, (uint16_t)(transaction_id & 0xFFFF)) ;
       
   614         CyAsLLRequestResponse_SetWord(req_p, 3, (uint16_t)((transaction_id >> 16) & 0xFFFF)) ;
       
   615     }
       
   616 
       
   617     if(cb == 0)
       
   618     {
       
   619         /* Queue the DMA request for block table write */
       
   620         ret = CyAsDmaQueueRequest(dev_p, 4, blk_table, sizeof(CyAsMTPBlockTable), CyFalse, CyFalse, SyncMTPCallback) ;
       
   621 
       
   622         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
   623         if (ret != CY_AS_ERROR_SUCCESS)
       
   624         {
       
   625             CyAsDmaCancel(dev_p, 4, CY_AS_ERROR_CANCELED) ;
       
   626             CyAsDeviceClearStorageAsyncPending(dev_p) ;
       
   627 
       
   628             goto destroy ;
       
   629         }
       
   630 
       
   631         ret = CyAsDmaDrainQueue(dev_p, 4, CyTrue) ;
       
   632         if (ret != CY_AS_ERROR_SUCCESS)
       
   633             goto destroy ;
       
   634 
       
   635         ret = dev_p->mtp_error ;
       
   636         goto destroy ;
       
   637     }
       
   638     else
       
   639     {
       
   640 #if 0
       
   641         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MTP_INIT_SEND_OBJECT,
       
   642             0, dev_p->func_cbs_mtp, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
       
   643             CyAsMTPFuncCallback) ;
       
   644 
       
   645         if (ret != CY_AS_ERROR_SUCCESS)
       
   646             goto destroy ;
       
   647 #endif
       
   648 
       
   649         /* Protection from interrupt driven code */
       
   650         /* since we are using storage EP4 check if any storage activity is pending */
       
   651         mask = CyAsHalDisableInterrupts() ;
       
   652         if ((CyAsDeviceIsStorageAsyncPending(dev_p)) || (dev_p->storage_wait))
       
   653         {
       
   654             CyAsHalEnableInterrupts(mask) ;
       
   655             return CY_AS_ERROR_ASYNC_PENDING ;
       
   656         }
       
   657         CyAsDeviceSetStorageAsyncPending(dev_p) ;
       
   658         CyAsHalEnableInterrupts(mask) ;
       
   659 
       
   660         dev_p->mtp_cb     = cb ;
       
   661         dev_p->mtp_client = client ;
       
   662         dev_p->mtp_op     = mtp_cb_op ;
       
   663 
       
   664         ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyFalse, MtpWriteCallback) ;
       
   665         if (ret != CY_AS_ERROR_SUCCESS)
       
   666             goto destroy ;
       
   667 
       
   668         ret = CyAsDmaQueueRequest(dev_p, 4, blk_table, sizeof(CyAsMTPBlockTable), CyFalse, CyFalse, AsyncWriteRequestCallback) ;
       
   669         if (ret != CY_AS_ERROR_SUCCESS)
       
   670             return ret ;
       
   671 
       
   672         /* Kick start the queue if it is not running */
       
   673         CyAsDmaKickStart(dev_p, 4) ;
       
   674 
       
   675         return CY_AS_ERROR_SUCCESS ;
       
   676     }
       
   677 
       
   678 destroy:
       
   679     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   680     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   681 
       
   682     return ret ;
       
   683 }
       
   684 
       
   685 CyAsReturnStatus_t
       
   686 CyAsMTPInitSendObject(CyAsDeviceHandle handle,
       
   687                       CyAsMTPBlockTable* blk_table,
       
   688                       uint32_t num_bytes,
       
   689                       CyAsFunctionCallback cb,
       
   690                       uint32_t client
       
   691                       )
       
   692 {
       
   693     CyAsDevice* dev_p ;
       
   694     dev_p = (CyAsDevice *)handle ;
       
   695     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
   696         return CY_AS_ERROR_INVALID_HANDLE ;
       
   697 
       
   698     return CyAsMTPOperation(dev_p, blk_table, num_bytes, 0, cb, client, CY_RQT_INIT_SEND_OBJECT) ;
       
   699 
       
   700 }
       
   701 
       
   702 CyAsReturnStatus_t
       
   703 CyAsMTPInitGetObject(CyAsDeviceHandle handle,
       
   704                      CyAsMTPBlockTable* blk_table,
       
   705                      uint32_t num_bytes,
       
   706                      uint32_t transaction_id,
       
   707                      CyAsFunctionCallback cb,
       
   708                      uint32_t client
       
   709                      )
       
   710 {
       
   711     CyAsDevice* dev_p ;
       
   712     dev_p = (CyAsDevice *)handle ;
       
   713     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
   714         return CY_AS_ERROR_INVALID_HANDLE ;
       
   715 
       
   716     return CyAsMTPOperation(dev_p, blk_table, num_bytes, transaction_id, cb, client, CY_RQT_INIT_GET_OBJECT) ;
       
   717 
       
   718 }
       
   719 
       
   720 static CyAsReturnStatus_t
       
   721 MyHandleResponseCancelSendObject(CyAsDevice* dev_p,
       
   722                                  CyAsLLRequestResponse *req_p,
       
   723                                  CyAsLLRequestResponse *reply_p,
       
   724                                  CyAsReturnStatus_t ret)
       
   725 {
       
   726     if (ret != CY_AS_ERROR_SUCCESS)
       
   727         goto destroy ;
       
   728 
       
   729     if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
       
   730     {
       
   731         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
   732         goto destroy ;
       
   733     }
       
   734 
       
   735     ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
   736     if (ret != CY_AS_ERROR_SUCCESS)
       
   737         goto destroy ;
       
   738 
       
   739 
       
   740 destroy :
       
   741     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   742     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   743 
       
   744     return ret ;
       
   745 }
       
   746 
       
   747 CyAsReturnStatus_t
       
   748 CyAsMTPCancelSendObject(CyAsDeviceHandle handle,
       
   749                         CyAsFunctionCallback cb,
       
   750                         uint32_t client
       
   751                         )
       
   752 {
       
   753     CyAsLLRequestResponse *req_p = 0, *reply_p = 0 ;
       
   754     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   755     CyAsDevice*dev_p ;
       
   756 
       
   757     dev_p = (CyAsDevice *)handle ;
       
   758     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
   759         return CY_AS_ERROR_INVALID_HANDLE ;
       
   760 
       
   761         if(dev_p->mtp_count == 0)
       
   762                 return CY_AS_ERROR_NOT_RUNNING ;
       
   763 
       
   764     /* Create the request to send to the West Bridge device */
       
   765     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_CANCEL_SEND_OBJECT, CY_RQT_TUR_RQT_CONTEXT, 0) ;
       
   766     if (req_p == 0)
       
   767     {
       
   768         ret = CY_AS_ERROR_OUT_OF_MEMORY ;
       
   769         goto destroy ;
       
   770     }
       
   771 
       
   772     /* Reserve space for the reply, the reply data will not exceed one word */
       
   773     reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
   774     if (reply_p == 0)
       
   775     {
       
   776         ret = CY_AS_ERROR_OUT_OF_MEMORY ;
       
   777         goto destroy ;
       
   778     }
       
   779 
       
   780     if(cb == 0)
       
   781     {
       
   782         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
   783         if (ret != CY_AS_ERROR_SUCCESS)
       
   784             goto destroy ;
       
   785 
       
   786         return MyHandleResponseCancelSendObject(dev_p, req_p, reply_p, ret) ;
       
   787     }
       
   788     else
       
   789     {
       
   790         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MTP_CANCEL_SEND_OBJECT,
       
   791             0, dev_p->func_cbs_mtp, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
       
   792             CyAsMTPFuncCallback) ;
       
   793 
       
   794         if (ret != CY_AS_ERROR_SUCCESS)
       
   795             goto destroy ;
       
   796 
       
   797         return ret ;
       
   798     }
       
   799 
       
   800 destroy :
       
   801     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   802     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   803 
       
   804     return ret ;
       
   805 }
       
   806 
       
   807 static CyAsReturnStatus_t
       
   808 MyHandleResponseCancelGetObject(CyAsDevice* dev_p,
       
   809                                 CyAsLLRequestResponse *req_p,
       
   810                                 CyAsLLRequestResponse *reply_p,
       
   811                                 CyAsReturnStatus_t ret)
       
   812 {
       
   813     if (ret != CY_AS_ERROR_SUCCESS)
       
   814         goto destroy ;
       
   815 
       
   816     if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
       
   817     {
       
   818         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
   819         goto destroy ;
       
   820     }
       
   821 
       
   822     ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
   823     if (ret != CY_AS_ERROR_SUCCESS)
       
   824         goto destroy ;
       
   825 
       
   826 
       
   827 destroy :
       
   828     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   829     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   830 
       
   831     return ret ;
       
   832 }
       
   833 
       
   834 CyAsReturnStatus_t
       
   835 CyAsMTPCancelGetObject(CyAsDeviceHandle handle,
       
   836                        CyAsFunctionCallback cb,
       
   837                        uint32_t client
       
   838                        )
       
   839 {
       
   840     CyAsLLRequestResponse *req_p = 0, *reply_p = 0 ;
       
   841     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   842     CyAsDevice*dev_p ;
       
   843 
       
   844     dev_p = (CyAsDevice *)handle ;
       
   845     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
   846         return CY_AS_ERROR_INVALID_HANDLE ;
       
   847 
       
   848         if(dev_p->mtp_count == 0)
       
   849                 return CY_AS_ERROR_NOT_RUNNING ;
       
   850 
       
   851     /* Create the request to send to the West Bridge device */
       
   852     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_CANCEL_GET_OBJECT, CY_RQT_TUR_RQT_CONTEXT, 0) ;
       
   853     if (req_p == 0)
       
   854     {
       
   855         ret = CY_AS_ERROR_OUT_OF_MEMORY ;
       
   856         goto destroy ;
       
   857     }
       
   858 
       
   859     /* Reserve space for the reply, the reply data will not exceed one word */
       
   860     reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
   861     if (reply_p == 0)
       
   862     {
       
   863         ret = CY_AS_ERROR_OUT_OF_MEMORY ;
       
   864         goto destroy ;
       
   865     }
       
   866 
       
   867     if(cb == 0)
       
   868     {
       
   869         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
   870         if (ret != CY_AS_ERROR_SUCCESS)
       
   871             goto destroy ;
       
   872 
       
   873         return MyHandleResponseCancelGetObject(dev_p, req_p, reply_p, ret) ;
       
   874     }
       
   875     else
       
   876     {
       
   877         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MTP_CANCEL_GET_OBJECT,
       
   878             0, dev_p->func_cbs_mtp, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
       
   879             CyAsMTPFuncCallback) ;
       
   880 
       
   881         if (ret != CY_AS_ERROR_SUCCESS)
       
   882             goto destroy ;
       
   883 
       
   884         return ret ;
       
   885     }
       
   886 
       
   887 destroy:
       
   888     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   889     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   890 
       
   891     return ret ;
       
   892 }
       
   893 
       
   894 CyAsReturnStatus_t
       
   895 CyAsMTPSendBlockTable(CyAsDeviceHandle handle,
       
   896                       CyAsMTPBlockTable* blk_table,
       
   897                       CyAsFunctionCallback cb,
       
   898                       uint32_t client
       
   899                       )
       
   900 {
       
   901     CyAsDevice* dev_p ;
       
   902     dev_p = (CyAsDevice *)handle ;
       
   903     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
   904         return CY_AS_ERROR_INVALID_HANDLE ;
       
   905 
       
   906     return CyAsMTPOperation(dev_p, blk_table, 0, 0, cb, client, CY_RQT_SEND_BLOCK_TABLE) ;
       
   907 }
       
   908 
       
   909 static void
       
   910 CyAsMTPFuncCallback(CyAsDevice *dev_p,
       
   911                     uint8_t context,
       
   912                     CyAsLLRequestResponse *rqt,
       
   913                     CyAsLLRequestResponse *resp,
       
   914                     CyAsReturnStatus_t stat)
       
   915 {
       
   916     CyAsFuncCBNode*     node = (CyAsFuncCBNode*)dev_p->func_cbs_mtp->head_p ;
       
   917     CyAsReturnStatus_t  ret = CY_AS_ERROR_SUCCESS ;
       
   918     uint8_t             code ;
       
   919     CyBool delay_callback = CyFalse ;
       
   920 
       
   921     CyAsHalAssert(dev_p->func_cbs_mtp->count != 0) ;
       
   922     CyAsHalAssert(dev_p->func_cbs_mtp->type == CYAS_FUNC_CB) ;
       
   923 
       
   924     (void)context ;
       
   925 
       
   926     /* The Handlers are responsible for Deleting the rqt and resp when
       
   927     * they are finished
       
   928     */
       
   929     code = CyAsLLRequestResponse_GetCode(rqt) ;
       
   930     switch(code)
       
   931     {
       
   932     case CY_RQT_START_MTP:
       
   933         ret = MyHandleResponseMTPStart(dev_p, rqt, resp, stat) ;
       
   934         break ;
       
   935     case CY_RQT_STOP_MTP:
       
   936         ret = MyHandleResponseMTPStop(dev_p, rqt, resp, stat) ;
       
   937         break ;
       
   938 #if 0
       
   939     case CY_RQT_INIT_SEND_OBJECT:
       
   940         ret = MyHandleResponseInitSendObject(dev_p, rqt, resp, stat, CyTrue) ;
       
   941         delay_callback = CyTrue ;
       
   942         break ;
       
   943 #endif
       
   944     case CY_RQT_CANCEL_SEND_OBJECT:
       
   945         ret = MyHandleResponseCancelSendObject(dev_p, rqt, resp, stat) ;
       
   946         break ;
       
   947 #if 0
       
   948     case CY_RQT_INIT_GET_OBJECT:
       
   949         ret = MyHandleResponseInitGetObject(dev_p, rqt, resp, stat, CyTrue) ;
       
   950         delay_callback = CyTrue ;
       
   951         break ;
       
   952 #endif
       
   953     case CY_RQT_CANCEL_GET_OBJECT:
       
   954         ret = MyHandleResponseCancelGetObject(dev_p, rqt, resp, stat) ;
       
   955         break ;
       
   956 #if 0
       
   957     case CY_RQT_SEND_BLOCK_TABLE:
       
   958         ret = MyHandleResponseSendBlockTable(dev_p, rqt, resp, stat, CyTrue) ;
       
   959         delay_callback = CyTrue ;
       
   960         break ;
       
   961 #endif
       
   962     case CY_RQT_ENABLE_USB_PATH:
       
   963         ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
       
   964         if (ret == CY_AS_ERROR_SUCCESS)
       
   965             dev_p->is_storage_only_mode = CyFalse ;
       
   966         break ;
       
   967     default:
       
   968         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
   969         CyAsHalAssert(CyFalse) ;
       
   970         break ;
       
   971     }
       
   972 
       
   973     /*
       
   974     * If the low level layer returns a direct error, use the corresponding error code.
       
   975     * If not, use the error code based on the response from firmware.
       
   976     */
       
   977     if (stat == CY_AS_ERROR_SUCCESS)
       
   978         stat = ret ;
       
   979 
       
   980     if(!delay_callback)
       
   981     {
       
   982         node->cb_p((CyAsDeviceHandle)dev_p, stat, node->client_data, (CyAsFunctCBType)node->dataType, node->data) ;
       
   983         CyAsRemoveCBNode(dev_p->func_cbs_mtp) ;
       
   984     }
       
   985 }
       
   986 
       
   987 CyAsReturnStatus_t
       
   988 CyAsMTPStorageOnlyStart(CyAsDeviceHandle handle)
       
   989 {
       
   990     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
   991     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
   992         return CY_AS_ERROR_INVALID_HANDLE ;
       
   993 
       
   994     if (!CyAsDeviceIsConfigured(dev_p))
       
   995         return CY_AS_ERROR_NOT_CONFIGURED ;
       
   996 
       
   997     if (!CyAsDeviceIsFirmwareLoaded(dev_p))
       
   998         return CY_AS_ERROR_NO_FIRMWARE ;
       
   999 
       
  1000     if (dev_p->storage_count == 0)
       
  1001         return CY_AS_ERROR_NOT_RUNNING ;
       
  1002 
       
  1003     dev_p->is_storage_only_mode = CyTrue ;
       
  1004     return CY_AS_ERROR_SUCCESS ;
       
  1005 }
       
  1006 
       
  1007 CyAsReturnStatus_t
       
  1008 CyAsMTPStorageOnlyStop(CyAsDeviceHandle handle,
       
  1009                         CyAsFunctionCallback cb,
       
  1010                         uint32_t client)
       
  1011 {
       
  1012     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  1013     CyAsLLRequestResponse *req_p, *reply_p ;
       
  1014     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  1015 
       
  1016     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
  1017         return CY_AS_ERROR_INVALID_HANDLE ;
       
  1018 
       
  1019     if (!CyAsDeviceIsConfigured(dev_p))
       
  1020         return CY_AS_ERROR_NOT_CONFIGURED ;
       
  1021 
       
  1022     if (!CyAsDeviceIsFirmwareLoaded(dev_p))
       
  1023         return CY_AS_ERROR_NO_FIRMWARE ;
       
  1024 
       
  1025     if (dev_p->storage_count == 0)
       
  1026         return CY_AS_ERROR_NOT_RUNNING ;
       
  1027 
       
  1028     if (dev_p->is_storage_only_mode == CyFalse)
       
  1029         return CY_AS_ERROR_SUCCESS ;
       
  1030 
       
  1031     if (CyAsDeviceIsInCallback(dev_p))
       
  1032         return CY_AS_ERROR_INVALID_IN_CALLBACK ;
       
  1033 
       
  1034     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_ENABLE_USB_PATH, CY_RQT_TUR_RQT_CONTEXT, 1) ;
       
  1035     if (req_p == 0)
       
  1036         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1037 
       
  1038     reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
  1039     if (reply_p == 0)
       
  1040     {
       
  1041         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1042         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1043     }
       
  1044 
       
  1045     if(cb == 0)
       
  1046     {
       
  1047         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  1048         if (ret != CY_AS_ERROR_SUCCESS)
       
  1049             goto destroy ;
       
  1050 
       
  1051         ret = MyHandleResponseNoData(dev_p, req_p, reply_p) ;
       
  1052         if (ret == CY_AS_ERROR_SUCCESS)
       
  1053             dev_p->is_storage_only_mode = CyFalse ;
       
  1054         return ret ;
       
  1055     }
       
  1056     else
       
  1057     {
       
  1058         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_MTP_STOP_STORAGE_ONLY,
       
  1059             0, dev_p->func_cbs_mtp, CY_AS_REQUEST_RESPONSE_EX, req_p, reply_p,
       
  1060             CyAsMTPFuncCallback) ;
       
  1061 
       
  1062         if (ret != CY_AS_ERROR_SUCCESS)
       
  1063             goto destroy ;
       
  1064 
       
  1065         return ret ;
       
  1066     }
       
  1067 
       
  1068 destroy:
       
  1069     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1070     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  1071 
       
  1072     return ret ;
       
  1073 }