omap3530/beagle_drivers/wb/api/src/cyasstorage.c
changeset 27 117faf51deac
child 52 254b9435d75e
equal deleted inserted replaced
26:b7e488c49d0d 27:117faf51deac
       
     1 /* Cypress West Bridge API source file (cyasstorage.c)
       
     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 /*
       
    23 * Storage Design
       
    24 *
       
    25 * The storage module is fairly straight forward once the DMA and LOWLEVEL modules
       
    26 * have been designed.  The storage module simple takes requests from the user, queues the
       
    27 * associated DMA requests for action, and then sends the low level requests to the
       
    28 * West Bridge firmware.
       
    29 *
       
    30 */
       
    31 
       
    32 #include "cyashal.h"
       
    33 #include "cyasstorage.h"
       
    34 #include "cyaserr.h"
       
    35 #include "cyasdevice.h"
       
    36 #include "cyaslowlevel.h"
       
    37 #include "cyasdma.h"
       
    38 #include "cyasregs.h"
       
    39 
       
    40 /* Map a pre-V1.2 media type to the V1.2+ bus number */
       
    41 CyAsReturnStatus_t
       
    42 CyAnMapBusFromMediaType(CyAsDevice *dev_p, CyAsMediaType type, CyAsBusNumber_t *bus)
       
    43 {
       
    44     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
    45     uint8_t code = (uint8_t)(1 << type) ;
       
    46     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
    47         return CY_AS_ERROR_INVALID_HANDLE ;
       
    48 
       
    49     if (!CyAsDeviceIsConfigured(dev_p))
       
    50         return CY_AS_ERROR_NOT_CONFIGURED ;
       
    51 
       
    52     if (!CyAsDeviceIsFirmwareLoaded(dev_p))
       
    53         return CY_AS_ERROR_NO_FIRMWARE ;
       
    54 
       
    55 
       
    56     if (dev_p->media_supported[0] & code)
       
    57     {
       
    58         if (dev_p->media_supported[1] & code)
       
    59         {
       
    60             /*
       
    61              * This media type could be supported on multiple buses. So, report
       
    62              * an address resolution error.
       
    63              */
       
    64             ret = CY_AS_ERROR_ADDRESS_RESOLUTION_ERROR ;
       
    65         }
       
    66         else
       
    67             *bus = 0 ;
       
    68     }
       
    69     else
       
    70     {
       
    71         if (dev_p->media_supported[1] & code)
       
    72             *bus = 1 ;
       
    73         else
       
    74             ret = CY_AS_ERROR_NO_SUCH_MEDIA ;
       
    75     }
       
    76 
       
    77     return ret ;
       
    78 }
       
    79 
       
    80 static uint16_t
       
    81 CreateAddress(CyAsBusNumber_t bus, uint32_t device, uint8_t unit)
       
    82 {
       
    83     CyAsHalAssert(bus >= 0  && bus < CY_AS_MAX_BUSES) ;
       
    84     CyAsHalAssert(device < 16) ;
       
    85 
       
    86     return (uint16_t)(((uint8_t)bus << 12) | (device << 8) | unit) ;
       
    87 }
       
    88 
       
    89 CyAsMediaType
       
    90 CyAsStorageGetMediaFromAddress(uint16_t v)
       
    91 {
       
    92     CyAsMediaType media = CyAsMediaMaxMediaValue ;
       
    93 
       
    94     switch(v & 0xFF)
       
    95     {
       
    96         case 0x00:
       
    97             break;
       
    98         case 0x01:
       
    99             media = CyAsMediaNand ;
       
   100             break ;
       
   101         case 0x02:
       
   102             media = CyAsMediaSDFlash ;
       
   103             break ;
       
   104         case 0x04:
       
   105             media = CyAsMediaMMCFlash ;
       
   106             break ;
       
   107         case 0x08:
       
   108             media = CyAsMediaCEATA ;
       
   109             break ;
       
   110         case 0x10:
       
   111             media = CyAsMediaSDIO ;
       
   112             break ;
       
   113         default:
       
   114             CyAsHalAssert(0) ;
       
   115             break ;
       
   116     }
       
   117 
       
   118     return media ;
       
   119 }
       
   120 
       
   121 CyAsBusNumber_t
       
   122 CyAsStorageGetBusFromAddress(uint16_t v)
       
   123 {
       
   124     CyAsBusNumber_t bus = (CyAsBusNumber_t)((v >> 12) & 0x0f) ;
       
   125     CyAsHalAssert(bus >= 0 && bus < CY_AS_MAX_BUSES) ;
       
   126     return bus ;
       
   127 }
       
   128 
       
   129 uint32_t
       
   130 CyAsStorageGetDeviceFromAddress(uint16_t v)
       
   131 {
       
   132     return (uint32_t)((v >> 8) & 0x0f) ;
       
   133 }
       
   134 
       
   135 static uint8_t
       
   136 GetUnitFromAddress(uint16_t v)
       
   137 {
       
   138     return (uint8_t)(v & 0xff) ;
       
   139 }
       
   140 
       
   141 static CyAsReturnStatus_t
       
   142 CyAsMapBadAddr(uint16_t val)
       
   143 {
       
   144     CyAsReturnStatus_t ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
   145 
       
   146     switch(val)
       
   147     {
       
   148     case 0:
       
   149         ret = CY_AS_ERROR_NO_SUCH_BUS ;
       
   150         break ;
       
   151     case 1:
       
   152         ret = CY_AS_ERROR_NO_SUCH_DEVICE ;
       
   153         break ;
       
   154     case 2:
       
   155         ret = CY_AS_ERROR_NO_SUCH_UNIT ;
       
   156         break ;
       
   157     case 3:
       
   158         ret = CY_AS_ERROR_INVALID_BLOCK ;
       
   159         break ;
       
   160     }
       
   161 
       
   162     return ret ;
       
   163 }
       
   164 
       
   165 static void
       
   166 MyStorageRequestCallback(CyAsDevice *dev_p, uint8_t context, CyAsLLRequestResponse *req_p,
       
   167                          CyAsLLRequestResponse *resp_p, CyAsReturnStatus_t ret)
       
   168 {
       
   169     uint16_t val ;
       
   170     uint16_t addr ;
       
   171     CyAsBusNumber_t bus;
       
   172     uint32_t device;
       
   173     CyAsDeviceHandle h = (CyAsDeviceHandle)dev_p ;
       
   174     CyAsDmaEndPoint *ep_p = NULL ;
       
   175 
       
   176     (void)resp_p ;
       
   177     (void)context ;
       
   178     (void)ret ;
       
   179 
       
   180     switch(CyAsLLRequestResponse_GetCode(req_p))
       
   181     {
       
   182     case CY_RQT_MEDIA_CHANGED:
       
   183         CyAsLLSendStatusResponse(dev_p, CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
       
   184 
       
   185         /* Media has either been inserted or removed */
       
   186         addr = CyAsLLRequestResponse_GetWord(req_p, 0) ;
       
   187 
       
   188         bus = CyAsStorageGetBusFromAddress(addr);
       
   189         device = CyAsStorageGetDeviceFromAddress(addr);
       
   190 
       
   191         /* Clear the entry for this device to force re-query later */
       
   192         CyAsHalMemSet(&(dev_p->storage_device_info[bus][device]), 0,
       
   193             sizeof(dev_p->storage_device_info[bus][device])) ;
       
   194 
       
   195         val = CyAsLLRequestResponse_GetWord(req_p, 1) ;
       
   196         if (dev_p->storage_event_cb_ms)
       
   197         {
       
   198             if (val == 1)
       
   199                 dev_p->storage_event_cb_ms(h, bus, device, CyAsStorageRemoved, 0) ;
       
   200             else
       
   201                 dev_p->storage_event_cb_ms(h, bus, device, CyAsStorageInserted, 0) ;
       
   202         }
       
   203         else if (dev_p->storage_event_cb)
       
   204         {
       
   205             if (val == 1)
       
   206                 dev_p->storage_event_cb(h, (CyAsMediaType)bus, CyAsStorageRemoved, 0) ; /*nxz*/
       
   207             else
       
   208                 dev_p->storage_event_cb(h, (CyAsMediaType)bus, CyAsStorageInserted, 0) ; /*nxz*/
       
   209         }
       
   210 
       
   211         break ;
       
   212 
       
   213     case CY_RQT_ANTIOCH_CLAIM:
       
   214         CyAsLLSendStatusResponse(dev_p, CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
       
   215         if (dev_p->storage_event_cb || dev_p->storage_event_cb_ms)
       
   216         {
       
   217             val = CyAsLLRequestResponse_GetWord(req_p, 0) ;
       
   218             if (dev_p->storage_event_cb_ms)
       
   219             {
       
   220                 if (val & 0x0100)
       
   221                     dev_p->storage_event_cb_ms(h, 0, 0, CyAsStorageAntioch, 0) ;
       
   222                 if (val & 0x0200)
       
   223                     dev_p->storage_event_cb_ms(h, 1, 0, CyAsStorageAntioch, 0) ;
       
   224             }
       
   225             else
       
   226             {
       
   227                 if (val & 0x01)
       
   228                     dev_p->storage_event_cb(h, CyAsMediaNand, CyAsStorageAntioch, 0) ;
       
   229                 if (val & 0x02)
       
   230                     dev_p->storage_event_cb(h, CyAsMediaSDFlash, CyAsStorageAntioch, 0) ;
       
   231                 if (val & 0x04)
       
   232                     dev_p->storage_event_cb(h, CyAsMediaMMCFlash, CyAsStorageAntioch, 0) ;
       
   233                 if (val & 0x08)
       
   234                     dev_p->storage_event_cb(h, CyAsMediaCEATA, CyAsStorageAntioch, 0) ;
       
   235             }
       
   236         }
       
   237         break ;
       
   238 
       
   239     case CY_RQT_ANTIOCH_RELEASE:
       
   240         CyAsLLSendStatusResponse(dev_p, CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
       
   241         val = CyAsLLRequestResponse_GetWord(req_p, 0) ;
       
   242         if (dev_p->storage_event_cb_ms)
       
   243         {
       
   244             if (val & 0x0100)
       
   245                 dev_p->storage_event_cb_ms(h, 0, 0, CyAsStorageProcessor, 0) ;
       
   246             if (val & 0x0200)
       
   247                 dev_p->storage_event_cb_ms(h, 1, 0, CyAsStorageProcessor, 0) ;
       
   248         }
       
   249         else if (dev_p->storage_event_cb)
       
   250         {
       
   251             if (val & 0x01)
       
   252                 dev_p->storage_event_cb(h, CyAsMediaNand, CyAsStorageProcessor, 0) ;
       
   253             if (val & 0x02)
       
   254                 dev_p->storage_event_cb(h, CyAsMediaSDFlash, CyAsStorageProcessor, 0) ;
       
   255             if (val & 0x04)
       
   256                 dev_p->storage_event_cb(h, CyAsMediaMMCFlash, CyAsStorageProcessor, 0) ;
       
   257             if (val & 0x08)
       
   258                 dev_p->storage_event_cb(h, CyAsMediaCEATA, CyAsStorageProcessor, 0) ;
       
   259         }
       
   260         break ;
       
   261 
       
   262 
       
   263     case CY_RQT_SDIO_INTR:
       
   264         CyAsLLSendStatusResponse(dev_p, CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
       
   265         val = CyAsLLRequestResponse_GetWord(req_p, 0) ;
       
   266         if (dev_p->storage_event_cb_ms)
       
   267         {
       
   268             if (val & 0x0100)
       
   269                 dev_p->storage_event_cb_ms(h, 1, 0, CyAsSdioInterrupt, 0) ;
       
   270             else
       
   271                 dev_p->storage_event_cb_ms(h, 0, 0, CyAsSdioInterrupt, 0) ;
       
   272 
       
   273         }
       
   274         else if (dev_p->storage_event_cb)
       
   275         {
       
   276             dev_p->storage_event_cb(h, CyAsMediaSDIO, CyAsSdioInterrupt, 0) ;
       
   277         }
       
   278         break;
       
   279 
       
   280     case CY_RQT_P2S_DMA_START:
       
   281         /* Do the DMA setup for the waiting operation. This event is used only in
       
   282          * the MTP mode firmware. */
       
   283         CyAsLLSendStatusResponse(dev_p, CY_RQT_STORAGE_RQT_CONTEXT, CY_AS_ERROR_SUCCESS, 0) ;
       
   284         if (dev_p->storage_oper == CyAsOpRead)
       
   285         {
       
   286             ep_p = CY_AS_NUM_EP(dev_p, CY_AS_P2S_READ_ENDPOINT) ;
       
   287             CyAsDmaEndPointSetStopped(ep_p) ;
       
   288             CyAsDmaKickStart(dev_p, CY_AS_P2S_READ_ENDPOINT) ;
       
   289         }
       
   290         else
       
   291         {
       
   292             ep_p = CY_AS_NUM_EP(dev_p, CY_AS_P2S_WRITE_ENDPOINT) ;
       
   293             CyAsDmaEndPointSetStopped(ep_p) ;
       
   294             CyAsDmaKickStart(dev_p, CY_AS_P2S_WRITE_ENDPOINT) ;
       
   295         }
       
   296         break ;
       
   297 
       
   298     default:
       
   299         CyAsHalPrintMessage("Invalid request received on storage context\n") ;
       
   300         val = req_p->box0 ;
       
   301         CyAsLLSendDataResponse(dev_p, CY_RQT_STORAGE_RQT_CONTEXT, CY_RESP_INVALID_REQUEST, sizeof(val), &val) ;
       
   302         break ;
       
   303     }
       
   304 }
       
   305 
       
   306 static CyAsReturnStatus_t
       
   307 IsStorageActive(CyAsDevice *dev_p)
       
   308 {
       
   309     if (!CyAsDeviceIsConfigured(dev_p))
       
   310         return CY_AS_ERROR_NOT_CONFIGURED ;
       
   311 
       
   312     if (!CyAsDeviceIsFirmwareLoaded(dev_p))
       
   313         return CY_AS_ERROR_NO_FIRMWARE ;
       
   314 
       
   315     if (dev_p->storage_count == 0)
       
   316         return CY_AS_ERROR_NOT_RUNNING ;
       
   317 
       
   318     if (CyAsDeviceIsInSuspendMode(dev_p))
       
   319         return CY_AS_ERROR_IN_SUSPEND ;
       
   320 
       
   321     return CY_AS_ERROR_SUCCESS ;
       
   322 }
       
   323 
       
   324 static void
       
   325 CyAsStorageFuncCallback(CyAsDevice *dev_p,
       
   326                         uint8_t context,
       
   327                         CyAsLLRequestResponse *rqt,
       
   328                         CyAsLLRequestResponse *resp,
       
   329                         CyAsReturnStatus_t ret) ;
       
   330 
       
   331 static CyAsReturnStatus_t
       
   332 MyHandleResponseNoData(CyAsDevice* dev_p,
       
   333                          CyAsLLRequestResponse *req_p,
       
   334                          CyAsLLRequestResponse *reply_p)
       
   335 {
       
   336     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   337 
       
   338     if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
       
   339     {
       
   340         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
   341         goto destroy ;
       
   342     }
       
   343 
       
   344     ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
   345 
       
   346 destroy :
       
   347     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   348     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   349 
       
   350     return ret ;
       
   351 }
       
   352 
       
   353 static CyAsReturnStatus_t
       
   354 MyHandleResponseStorageStart(CyAsDevice* dev_p,
       
   355                          CyAsLLRequestResponse *req_p,
       
   356                          CyAsLLRequestResponse *reply_p,
       
   357                          CyAsReturnStatus_t ret)
       
   358 {
       
   359     if (ret != CY_AS_ERROR_SUCCESS)
       
   360         goto destroy ;
       
   361 
       
   362     if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
       
   363     {
       
   364         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
   365         goto destroy ;
       
   366     }
       
   367 
       
   368     ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
   369     if (dev_p->storage_count > 0 && ret == CY_AS_ERROR_ALREADY_RUNNING)
       
   370         ret = CY_AS_ERROR_SUCCESS ;
       
   371 
       
   372     ret = CyAsDmaEnableEndPoint(dev_p, CY_AS_P2S_WRITE_ENDPOINT, CyTrue, CyAsDirectionIn) ;
       
   373     if (ret != CY_AS_ERROR_SUCCESS)
       
   374         goto destroy ;
       
   375 
       
   376     ret = CyAsDmaSetMaxDmaSize(dev_p, CY_AS_P2S_WRITE_ENDPOINT, CY_AS_STORAGE_EP_SIZE) ;
       
   377     if (ret != CY_AS_ERROR_SUCCESS)
       
   378         goto destroy ;
       
   379 
       
   380     ret = CyAsDmaEnableEndPoint(dev_p, CY_AS_P2S_READ_ENDPOINT, CyTrue, CyAsDirectionOut) ;
       
   381     if (ret != CY_AS_ERROR_SUCCESS)
       
   382         goto destroy ;
       
   383 
       
   384     ret = CyAsDmaSetMaxDmaSize(dev_p, CY_AS_P2S_READ_ENDPOINT, CY_AS_STORAGE_EP_SIZE) ;
       
   385     if (ret != CY_AS_ERROR_SUCCESS)
       
   386         goto destroy ;
       
   387 
       
   388     CyAsLLRegisterRequestCallback(dev_p, CY_RQT_STORAGE_RQT_CONTEXT, MyStorageRequestCallback) ;
       
   389 
       
   390     /* Create the request/response used for storage reads and writes. */
       
   391     dev_p->storage_rw_req_p  = CyAsLLCreateRequest(dev_p, 0, CY_RQT_STORAGE_RQT_CONTEXT, 5) ;
       
   392     if (dev_p->storage_rw_req_p == 0)
       
   393     {
       
   394         ret = CY_AS_ERROR_OUT_OF_MEMORY;
       
   395         goto destroy;
       
   396     }
       
   397 
       
   398     dev_p->storage_rw_resp_p = CyAsLLCreateResponse(dev_p, 5) ;
       
   399     if (dev_p->storage_rw_resp_p == 0)
       
   400     {
       
   401         CyAsLLDestroyRequest(dev_p, dev_p->storage_rw_req_p) ;
       
   402         ret = CY_AS_ERROR_OUT_OF_MEMORY ;
       
   403     }
       
   404 
       
   405 destroy :
       
   406     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   407     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   408 
       
   409     /* Increment the storage count only if the above functionality succeeds.*/
       
   410     if (ret == CY_AS_ERROR_SUCCESS)
       
   411     {
       
   412         if (dev_p->storage_count == 0)
       
   413         {
       
   414             CyAsHalMemSet(dev_p->storage_device_info, 0, sizeof(dev_p->storage_device_info)) ;
       
   415             dev_p->is_storage_only_mode = CyFalse ;
       
   416         }
       
   417 
       
   418         dev_p->storage_count++ ;
       
   419     }
       
   420 
       
   421     CyAsDeviceClearSSSPending(dev_p) ;
       
   422 
       
   423     return ret ;
       
   424 }
       
   425 
       
   426 CyAsReturnStatus_t
       
   427 CyAsStorageStart(CyAsDeviceHandle handle,
       
   428                    CyAsFunctionCallback cb,
       
   429                    uint32_t client)
       
   430 {
       
   431     CyAsLLRequestResponse *req_p, *reply_p ;
       
   432     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   433     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
   434 
       
   435     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
   436         return CY_AS_ERROR_INVALID_HANDLE ;
       
   437 
       
   438     if (!CyAsDeviceIsConfigured(dev_p))
       
   439         return CY_AS_ERROR_NOT_CONFIGURED ;
       
   440 
       
   441     if (!CyAsDeviceIsFirmwareLoaded(dev_p))
       
   442         return CY_AS_ERROR_NO_FIRMWARE ;
       
   443 
       
   444     if (CyAsDeviceIsInSuspendMode(dev_p))
       
   445         return CY_AS_ERROR_IN_SUSPEND ;
       
   446 
       
   447     if(CyAsDeviceIsSSSPending(dev_p))
       
   448         return CY_AS_ERROR_STARTSTOP_PENDING ;
       
   449 
       
   450     CyAsDeviceSetSSSPending(dev_p) ;
       
   451 
       
   452     if (dev_p->storage_count == 0)
       
   453     {
       
   454         /* Create the request to send to the West Bridge device */
       
   455         req_p = CyAsLLCreateRequest(dev_p, CY_RQT_START_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
       
   456         if (req_p == 0)
       
   457         {
       
   458             CyAsDeviceClearSSSPending(dev_p) ;
       
   459             return CY_AS_ERROR_OUT_OF_MEMORY ;
       
   460         }
       
   461 
       
   462         /* Reserve space for the reply, the reply data will not exceed one word */
       
   463         reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
   464         if (reply_p == 0)
       
   465         {
       
   466             CyAsDeviceClearSSSPending(dev_p) ;
       
   467             CyAsLLDestroyRequest(dev_p, req_p) ;
       
   468             return CY_AS_ERROR_OUT_OF_MEMORY ;
       
   469         }
       
   470 
       
   471         if(cb == 0)
       
   472         {
       
   473             ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
   474             if (ret != CY_AS_ERROR_SUCCESS)
       
   475                 goto destroy ;
       
   476 
       
   477             return MyHandleResponseStorageStart(dev_p, req_p, reply_p, ret) ;
       
   478         }
       
   479         else
       
   480         {
       
   481             ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_START,
       
   482                 0, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX,
       
   483                 req_p, reply_p, CyAsStorageFuncCallback) ;
       
   484 
       
   485             if (ret != CY_AS_ERROR_SUCCESS)
       
   486                 goto destroy ;
       
   487 
       
   488             /* The request and response are freed as part of the FuncCallback */
       
   489             return ret ;
       
   490         }
       
   491 
       
   492 destroy:
       
   493         CyAsLLDestroyRequest(dev_p, req_p) ;
       
   494         CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   495     }
       
   496     else
       
   497     {
       
   498         dev_p->storage_count++ ;
       
   499         if (cb)
       
   500             cb(handle, ret, client, CY_FUNCT_CB_STOR_START, 0) ;
       
   501     }
       
   502 
       
   503     CyAsDeviceClearSSSPending(dev_p) ;
       
   504 
       
   505     return ret ;
       
   506 }
       
   507 
       
   508 
       
   509 static CyAsReturnStatus_t
       
   510 MyHandleResponseStorageStop(CyAsDevice* dev_p,
       
   511                          CyAsLLRequestResponse *req_p,
       
   512                          CyAsLLRequestResponse *reply_p,
       
   513                          CyAsReturnStatus_t ret)
       
   514 {
       
   515     if (ret != CY_AS_ERROR_SUCCESS)
       
   516         goto destroy ;
       
   517 
       
   518     if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
       
   519     {
       
   520         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
   521         goto destroy ;
       
   522     }
       
   523 
       
   524 destroy :
       
   525     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   526     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   527 
       
   528     if (ret == CY_AS_ERROR_SUCCESS)
       
   529     {
       
   530         CyAsLLDestroyRequest(dev_p, dev_p->storage_rw_req_p) ;
       
   531         CyAsLLDestroyResponse(dev_p, dev_p->storage_rw_resp_p) ;
       
   532         dev_p->storage_count-- ;
       
   533     }
       
   534 
       
   535     CyAsDeviceClearSSSPending(dev_p) ;
       
   536 
       
   537     return ret ;
       
   538 }
       
   539 CyAsReturnStatus_t
       
   540 CyAsStorageStop(CyAsDeviceHandle handle,
       
   541                   CyAsFunctionCallback cb,
       
   542                   uint32_t client)
       
   543 {
       
   544     CyAsLLRequestResponse *req_p , *reply_p ;
       
   545     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   546 
       
   547     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
   548 
       
   549     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
   550         return CY_AS_ERROR_INVALID_HANDLE ;
       
   551 
       
   552     ret = IsStorageActive(dev_p) ;
       
   553     if (ret != CY_AS_ERROR_SUCCESS)
       
   554         return ret ;
       
   555 
       
   556     if (CyAsDeviceIsStorageAsyncPending(dev_p))
       
   557         return CY_AS_ERROR_ASYNC_PENDING ;
       
   558 
       
   559     if(CyAsDeviceIsSSSPending(dev_p))
       
   560         return CY_AS_ERROR_STARTSTOP_PENDING ;
       
   561 
       
   562     CyAsDeviceSetSSSPending(dev_p) ;
       
   563 
       
   564     if (dev_p->storage_count == 1)
       
   565     {
       
   566 
       
   567         /* Create the request to send to the West Bridge device */
       
   568         req_p = CyAsLLCreateRequest(dev_p, CY_RQT_STOP_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 0) ;
       
   569         if (req_p == 0)
       
   570         {
       
   571             CyAsDeviceClearSSSPending(dev_p) ;
       
   572             return CY_AS_ERROR_OUT_OF_MEMORY ;
       
   573         }
       
   574 
       
   575         /* Reserve space for the reply, the reply data will not exceed one word */
       
   576         reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
   577         if (reply_p == 0)
       
   578         {
       
   579             CyAsDeviceClearSSSPending(dev_p) ;
       
   580             CyAsLLDestroyRequest(dev_p, req_p) ;
       
   581             return CY_AS_ERROR_OUT_OF_MEMORY ;
       
   582         }
       
   583 
       
   584         if(cb == 0)
       
   585         {
       
   586             ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
   587             if (ret != CY_AS_ERROR_SUCCESS)
       
   588                 goto destroy ;
       
   589 
       
   590             return MyHandleResponseStorageStop(dev_p, req_p, reply_p, ret) ;
       
   591         }
       
   592         else
       
   593         {
       
   594             ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_STOP,
       
   595                 0, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX,
       
   596                 req_p, reply_p, CyAsStorageFuncCallback) ;
       
   597 
       
   598             if (ret != CY_AS_ERROR_SUCCESS)
       
   599                 goto destroy ;
       
   600 
       
   601             /* The request and response are freed as part of the MiscFuncCallback */
       
   602             return ret ;
       
   603         }
       
   604 
       
   605 destroy:
       
   606         CyAsLLDestroyRequest(dev_p, req_p) ;
       
   607         CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   608     }
       
   609     else if(dev_p->storage_count > 1)
       
   610     {
       
   611         dev_p->storage_count-- ;
       
   612         if (cb)
       
   613             cb(handle, ret, client, CY_FUNCT_CB_STOR_STOP, 0) ;
       
   614     }
       
   615 
       
   616     CyAsDeviceClearSSSPending(dev_p) ;
       
   617 
       
   618     return ret ;
       
   619 }
       
   620 
       
   621 CyAsReturnStatus_t
       
   622 CyAsStorageRegisterCallback(CyAsDeviceHandle handle, CyAsStorageEventCallback callback)
       
   623 {
       
   624     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
   625     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
   626         return CY_AS_ERROR_INVALID_HANDLE ;
       
   627 
       
   628     if (!CyAsDeviceIsConfigured(dev_p))
       
   629         return CY_AS_ERROR_NOT_CONFIGURED ;
       
   630 
       
   631     if (!CyAsDeviceIsFirmwareLoaded(dev_p))
       
   632         return CY_AS_ERROR_NO_FIRMWARE ;
       
   633 
       
   634     if (dev_p->storage_count == 0)
       
   635         return CY_AS_ERROR_NOT_RUNNING ;
       
   636 
       
   637     dev_p->storage_event_cb = NULL ;
       
   638     dev_p->storage_event_cb_ms = callback ;
       
   639 
       
   640     return CY_AS_ERROR_SUCCESS ;
       
   641 }
       
   642 
       
   643 
       
   644 
       
   645 static CyAsReturnStatus_t
       
   646 MyHandleResponseStorageClaim(CyAsDevice* dev_p,
       
   647                          CyAsLLRequestResponse *req_p,
       
   648                          CyAsLLRequestResponse *reply_p)
       
   649 {
       
   650     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   651 
       
   652     if (CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_NO_SUCH_ADDRESS)
       
   653     {
       
   654         ret = CyAsMapBadAddr(CyAsLLRequestResponse_GetWord(reply_p, 3)) ;
       
   655         goto destroy ;
       
   656     }
       
   657 
       
   658     if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_MEDIA_CLAIMED_RELEASED)
       
   659     {
       
   660         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
   661         goto destroy ;
       
   662     }
       
   663 
       
   664     /* The response must be about the address I am trying to claim or the firmware is broken */
       
   665     if ((CyAsStorageGetBusFromAddress(CyAsLLRequestResponse_GetWord(req_p, 0)) !=
       
   666         CyAsStorageGetBusFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 0))) ||
       
   667         (CyAsStorageGetDeviceFromAddress(CyAsLLRequestResponse_GetWord(req_p, 0)) !=
       
   668         CyAsStorageGetDeviceFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 0))))
       
   669     {
       
   670         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
   671         goto destroy ;
       
   672     }
       
   673 
       
   674     if (CyAsLLRequestResponse_GetWord(reply_p, 1) != 1)
       
   675         ret = CY_AS_ERROR_NOT_ACQUIRED ;
       
   676 
       
   677 destroy :
       
   678     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   679     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   680 
       
   681     return ret ;
       
   682 }
       
   683 
       
   684 static CyAsReturnStatus_t
       
   685 MyStorageClaim(CyAsDevice *dev_p,
       
   686                 void* data,
       
   687                 CyAsBusNumber_t bus,
       
   688                 uint32_t device,
       
   689                 uint16_t req_flags,
       
   690                 CyAsFunctionCallback cb,
       
   691                 uint32_t client)
       
   692 {
       
   693     CyAsLLRequestResponse *req_p , *reply_p ;
       
   694     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   695 
       
   696     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
   697         return CY_AS_ERROR_INVALID_HANDLE ;
       
   698 
       
   699     ret = IsStorageActive(dev_p) ;
       
   700     if (ret != CY_AS_ERROR_SUCCESS)
       
   701         return ret ;
       
   702 
       
   703     if(dev_p->mtp_count > 0)
       
   704         return CY_AS_ERROR_NOT_VALID_IN_MTP ;
       
   705 
       
   706     /* Create the request to send to the West Bridge device */
       
   707     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_CLAIM_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
       
   708     if (req_p == 0)
       
   709         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
   710 
       
   711     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, device, 0)) ;
       
   712 
       
   713     /* Reserve space for the reply, the reply data will not exceed one word */
       
   714     reply_p = CyAsLLCreateResponse(dev_p, 4) ;
       
   715     if (reply_p == 0)
       
   716     {
       
   717         CyAsLLDestroyRequest(dev_p, req_p) ;
       
   718         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
   719     }
       
   720 
       
   721     if(cb == 0)
       
   722     {
       
   723         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
   724         if (ret != CY_AS_ERROR_SUCCESS)
       
   725             goto destroy ;
       
   726 
       
   727         return MyHandleResponseStorageClaim(dev_p, req_p, reply_p) ;
       
   728     }
       
   729     else
       
   730     {
       
   731         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_CLAIM,
       
   732             data, dev_p->func_cbs_stor, req_flags,
       
   733             req_p, reply_p, CyAsStorageFuncCallback) ;
       
   734 
       
   735         if (ret != CY_AS_ERROR_SUCCESS)
       
   736             goto destroy ;
       
   737 
       
   738         /* The request and response are freed as part of the MiscFuncCallback */
       
   739         return ret ;
       
   740     }
       
   741 
       
   742 destroy:
       
   743     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   744     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   745 
       
   746     return ret ;
       
   747 }
       
   748 
       
   749 CyAsReturnStatus_t
       
   750 CyAsStorageClaim(CyAsDeviceHandle handle,
       
   751                    CyAsBusNumber_t bus,
       
   752                    uint32_t device,
       
   753                    CyAsFunctionCallback cb,
       
   754                    uint32_t client)
       
   755 {
       
   756     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
   757 
       
   758     if (bus < 0 || bus >= CY_AS_MAX_BUSES)
       
   759         return CY_AS_ERROR_NO_SUCH_BUS ;
       
   760 
       
   761     return MyStorageClaim(dev_p, NULL, bus, device, CY_AS_REQUEST_RESPONSE_MS, cb, client) ;
       
   762 }
       
   763 
       
   764 static CyAsReturnStatus_t
       
   765 MyHandleResponseStorageRelease(CyAsDevice* dev_p,
       
   766                          CyAsLLRequestResponse *req_p,
       
   767                          CyAsLLRequestResponse *reply_p)
       
   768 {
       
   769     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   770 
       
   771     if (CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_NO_SUCH_ADDRESS)
       
   772     {
       
   773         ret = CyAsMapBadAddr(CyAsLLRequestResponse_GetWord(reply_p, 3)) ;
       
   774         goto destroy ;
       
   775     }
       
   776 
       
   777     if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_MEDIA_CLAIMED_RELEASED)
       
   778     {
       
   779         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
   780         goto destroy ;
       
   781     }
       
   782 
       
   783     /* The response must be about the address I am trying to release or the firmware is broken */
       
   784     if ((CyAsStorageGetBusFromAddress(CyAsLLRequestResponse_GetWord(req_p, 0)) !=
       
   785         CyAsStorageGetBusFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 0))) ||
       
   786         (CyAsStorageGetDeviceFromAddress(CyAsLLRequestResponse_GetWord(req_p, 0)) !=
       
   787         CyAsStorageGetDeviceFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 0))))
       
   788     {
       
   789         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
   790         goto destroy ;
       
   791     }
       
   792 
       
   793 
       
   794     if (CyAsLLRequestResponse_GetWord(reply_p, 1) != 0)
       
   795         ret = CY_AS_ERROR_NOT_RELEASED ;
       
   796 
       
   797 destroy :
       
   798     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   799     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   800 
       
   801     return ret ;
       
   802 }
       
   803 
       
   804 static CyAsReturnStatus_t
       
   805 MyStorageRelease(CyAsDevice* dev_p,
       
   806                     void* data,
       
   807                     CyAsBusNumber_t bus,
       
   808                     uint32_t device,
       
   809                     uint16_t req_flags,
       
   810                     CyAsFunctionCallback cb,
       
   811                     uint32_t client)
       
   812 {
       
   813     CyAsLLRequestResponse *req_p , *reply_p ;
       
   814     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   815 
       
   816     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
   817         return CY_AS_ERROR_INVALID_HANDLE ;
       
   818 
       
   819     ret = IsStorageActive(dev_p) ;
       
   820     if (ret != CY_AS_ERROR_SUCCESS)
       
   821         return ret ;
       
   822 
       
   823     if(dev_p->mtp_count > 0)
       
   824         return CY_AS_ERROR_NOT_VALID_IN_MTP ;
       
   825 
       
   826     /* Create the request to send to the West Bridge device */
       
   827     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_RELEASE_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
       
   828     if (req_p == 0)
       
   829         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
   830 
       
   831     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, device, 0)) ;
       
   832 
       
   833     /* Reserve space for the reply, the reply data will not exceed one word */
       
   834     reply_p = CyAsLLCreateResponse(dev_p, 4) ;
       
   835     if (reply_p == 0)
       
   836     {
       
   837         CyAsLLDestroyRequest(dev_p, req_p) ;
       
   838         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
   839     }
       
   840 
       
   841     if(cb == 0)
       
   842     {
       
   843         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
   844         if (ret != CY_AS_ERROR_SUCCESS)
       
   845             goto destroy ;
       
   846 
       
   847         return MyHandleResponseStorageRelease(dev_p, req_p, reply_p) ;
       
   848     }
       
   849     else
       
   850     {
       
   851         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_RELEASE,
       
   852             data, dev_p->func_cbs_stor, req_flags,
       
   853             req_p, reply_p, CyAsStorageFuncCallback) ;
       
   854 
       
   855         if (ret != CY_AS_ERROR_SUCCESS)
       
   856             goto destroy ;
       
   857 
       
   858         /* The request and response are freed as part of the MiscFuncCallback */
       
   859         return ret ;
       
   860     }
       
   861 
       
   862 destroy:
       
   863     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   864     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   865 
       
   866     return ret ;
       
   867 }
       
   868 
       
   869 CyAsReturnStatus_t
       
   870 CyAsStorageRelease(CyAsDeviceHandle handle,
       
   871                    CyAsBusNumber_t bus,
       
   872                    uint32_t device,
       
   873                    CyAsFunctionCallback cb,
       
   874                    uint32_t client)
       
   875 {
       
   876     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
   877 
       
   878     if (bus < 0 || bus >= CY_AS_MAX_BUSES)
       
   879         return CY_AS_ERROR_NO_SUCH_BUS ;
       
   880 
       
   881     return MyStorageRelease(dev_p, NULL, bus, device, CY_AS_REQUEST_RESPONSE_MS, cb, client) ;
       
   882 }
       
   883 
       
   884 static CyAsReturnStatus_t
       
   885 MyHandleResponseStorageQueryBus(CyAsDevice* dev_p,
       
   886                          CyAsLLRequestResponse *req_p,
       
   887                          CyAsLLRequestResponse *reply_p,
       
   888                          uint32_t* count)
       
   889 {
       
   890     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
   891     uint8_t code = CyAsLLRequestResponse_GetCode(reply_p) ;
       
   892     uint16_t v ;
       
   893 
       
   894     if (code == CY_RESP_NO_SUCH_ADDRESS)
       
   895     {
       
   896         ret = CY_AS_ERROR_NO_SUCH_BUS ;
       
   897         goto destroy ;
       
   898     }
       
   899 
       
   900     if (code != CY_RESP_BUS_DESCRIPTOR)
       
   901     {
       
   902         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
   903         goto destroy ;
       
   904     }
       
   905 
       
   906     /*
       
   907      * Verify that the response corresponds to the bus that was queried.
       
   908      */
       
   909     if (CyAsStorageGetBusFromAddress(CyAsLLRequestResponse_GetWord(req_p, 0)) !=
       
   910                 CyAsStorageGetBusFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 0)))
       
   911     {
       
   912         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
   913         goto destroy ;
       
   914     }
       
   915 
       
   916     v = CyAsLLRequestResponse_GetWord(reply_p, 1) ;
       
   917     if (req_p->flags & CY_AS_REQUEST_RESPONSE_MS)
       
   918     {
       
   919         /*
       
   920          * This request is only for the count of devices on the bus. There
       
   921          * is no need to check the media type.
       
   922          */
       
   923         if (v)
       
   924             *count = 1 ;
       
   925         else
       
   926             *count = 0 ;
       
   927     }
       
   928     else
       
   929     {
       
   930         /*
       
   931          * This request is for the count of devices of a particular type. We need
       
   932          * to check whether the media type found matches the queried type.
       
   933          */
       
   934         CyAsMediaType queried = (CyAsMediaType)CyAsLLRequestResponse_GetWord(req_p, 1) ;
       
   935         CyAsMediaType found   = CyAsStorageGetMediaFromAddress(v) ;
       
   936 
       
   937         if (queried == found)
       
   938             *count = 1 ;
       
   939         else
       
   940             *count = 0 ;
       
   941     }
       
   942 
       
   943 destroy :
       
   944     CyAsLLDestroyRequest(dev_p, req_p) ;
       
   945     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
   946 
       
   947     return ret ;
       
   948 }
       
   949 
       
   950 CyAsReturnStatus_t
       
   951 MyStorageQueryBus(CyAsDevice *dev_p,
       
   952                         CyAsBusNumber_t bus,
       
   953                         CyAsMediaType   type,
       
   954                         uint16_t req_flags,
       
   955                         uint32_t *count,
       
   956                         CyAsFunctionCallback cb,
       
   957                         uint32_t client)
       
   958 {
       
   959     CyAsReturnStatus_t ret ;
       
   960     CyAsLLRequestResponse *req_p, *reply_p ;
       
   961     CyAsFunctCBType cbType = CY_FUNCT_CB_STOR_QUERYBUS ;
       
   962 
       
   963     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
   964         return CY_AS_ERROR_INVALID_HANDLE ;
       
   965 
       
   966     ret = IsStorageActive(dev_p) ;
       
   967     if (ret != CY_AS_ERROR_SUCCESS)
       
   968         return ret ;
       
   969 
       
   970     /* Create the request to send to the Antioch device */
       
   971     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_QUERY_BUS, CY_RQT_STORAGE_RQT_CONTEXT, 2) ;
       
   972     if (req_p == 0)
       
   973         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
   974 
       
   975     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, 0, 0)) ;
       
   976     CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)type) ;
       
   977 
       
   978     /* Reserve space for the reply, the reply data will not exceed two words. */
       
   979     reply_p = CyAsLLCreateResponse(dev_p, 2) ;
       
   980     if (reply_p == 0)
       
   981     {
       
   982         CyAsLLDestroyRequest(dev_p, req_p) ;
       
   983         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
   984     }
       
   985 
       
   986     if(cb == 0)
       
   987     {
       
   988         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
   989         if (ret != CY_AS_ERROR_SUCCESS)
       
   990             goto destroy ;
       
   991 
       
   992         req_p->flags |= req_flags;
       
   993         return MyHandleResponseStorageQueryBus(dev_p, req_p, reply_p, count) ;
       
   994     }
       
   995     else
       
   996     {
       
   997         if (req_flags == CY_AS_REQUEST_RESPONSE_EX)
       
   998             cbType = CY_FUNCT_CB_STOR_QUERYMEDIA ;
       
   999 
       
  1000         ret = CyAsMiscSendRequest(dev_p, cb, client, cbType,
       
  1001             count, dev_p->func_cbs_stor, req_flags,
       
  1002             req_p, reply_p, CyAsStorageFuncCallback) ;
       
  1003 
       
  1004         if (ret != CY_AS_ERROR_SUCCESS)
       
  1005             goto destroy ;
       
  1006 
       
  1007         /* The request and response are freed as part of the MiscFuncCallback */
       
  1008         return ret ;
       
  1009     }
       
  1010 
       
  1011 destroy:
       
  1012     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1013     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  1014 
       
  1015     return ret ;
       
  1016 }
       
  1017 
       
  1018 CyAsReturnStatus_t
       
  1019 CyAsStorageQueryBus(CyAsDeviceHandle handle,
       
  1020                         CyAsBusNumber_t bus,
       
  1021                         uint32_t *count,
       
  1022                         CyAsFunctionCallback cb,
       
  1023                         uint32_t client)
       
  1024 {
       
  1025     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  1026 
       
  1027     return MyStorageQueryBus(dev_p, bus, CyAsMediaMaxMediaValue, CY_AS_REQUEST_RESPONSE_MS,
       
  1028             count, cb, client) ;
       
  1029 }
       
  1030 
       
  1031 CyAsReturnStatus_t
       
  1032 CyAsStorageQueryMedia(CyAsDeviceHandle handle,
       
  1033                         CyAsMediaType type,
       
  1034                         uint32_t *count,
       
  1035                         CyAsFunctionCallback cb,
       
  1036                         uint32_t client)
       
  1037 {
       
  1038     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  1039     CyAsBusNumber_t bus ;
       
  1040 
       
  1041     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  1042 
       
  1043     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
  1044         return CY_AS_ERROR_INVALID_HANDLE ;
       
  1045 
       
  1046     ret = IsStorageActive(dev_p) ;
       
  1047     if (ret != CY_AS_ERROR_SUCCESS)
       
  1048         return ret ;
       
  1049 
       
  1050     ret = CyAnMapBusFromMediaType(dev_p, type, &bus) ;
       
  1051     if (ret != CY_AS_ERROR_SUCCESS)
       
  1052         return ret ;
       
  1053 
       
  1054     return MyStorageQueryBus(dev_p, bus, type, CY_AS_REQUEST_RESPONSE_EX,
       
  1055             count, cb, client) ;
       
  1056 }
       
  1057 
       
  1058 static CyAsReturnStatus_t
       
  1059 MyHandleResponseStorageQueryDevice(CyAsDevice* dev_p,
       
  1060                          CyAsLLRequestResponse *req_p,
       
  1061                          CyAsLLRequestResponse *reply_p,
       
  1062                          void* data_p)
       
  1063 {
       
  1064     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  1065     uint16_t v ;
       
  1066     CyAsBusNumber_t bus ;
       
  1067     CyAsMediaType type ;
       
  1068     uint32_t device ;
       
  1069     CyBool removable ;
       
  1070     CyBool writeable ;
       
  1071     CyBool locked ;
       
  1072     uint16_t block_size ;
       
  1073     uint32_t number_units ;
       
  1074     uint32_t number_eus ;
       
  1075 
       
  1076     if (CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_NO_SUCH_ADDRESS)
       
  1077     {
       
  1078         ret = CyAsMapBadAddr(CyAsLLRequestResponse_GetWord(reply_p, 3)) ;
       
  1079         goto destroy ;
       
  1080     }
       
  1081 
       
  1082     if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_DEVICE_DESCRIPTOR)
       
  1083     {
       
  1084         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  1085         goto destroy ;
       
  1086     }
       
  1087 
       
  1088     /* Unpack the response */
       
  1089     v = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  1090     type = CyAsStorageGetMediaFromAddress(v) ;
       
  1091     bus  = CyAsStorageGetBusFromAddress(v) ;
       
  1092     device = CyAsStorageGetDeviceFromAddress(v) ;
       
  1093 
       
  1094     block_size = CyAsLLRequestResponse_GetWord(reply_p, 1) ;
       
  1095 
       
  1096     v = CyAsLLRequestResponse_GetWord(reply_p, 2) ;
       
  1097     removable = (v & 0x8000) ? CyTrue : CyFalse ;
       
  1098     writeable = (v & 0x0100) ? CyTrue : CyFalse ;
       
  1099     locked = (v & 0x0200) ? CyTrue : CyFalse ;
       
  1100     number_units = (v & 0xff) ;
       
  1101 
       
  1102     number_eus  = (CyAsLLRequestResponse_GetWord(reply_p, 3) << 16) | CyAsLLRequestResponse_GetWord(reply_p, 4) ;
       
  1103 
       
  1104     /* Store the results based on the version of originating function */
       
  1105     if (req_p->flags & CY_AS_REQUEST_RESPONSE_MS)
       
  1106     {
       
  1107         CyAsStorageQueryDeviceData  *store_p = (CyAsStorageQueryDeviceData*)data_p ;
       
  1108 
       
  1109         /* Make sure the response is about the address we asked about - if not, firmware error */
       
  1110         if ((bus != store_p->bus) || (device != store_p->device))
       
  1111         {
       
  1112             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  1113             goto destroy ;
       
  1114         }
       
  1115 
       
  1116         store_p->desc_p.type = type ;
       
  1117         store_p->desc_p.removable = removable ;
       
  1118         store_p->desc_p.writeable = writeable ;
       
  1119         store_p->desc_p.block_size = block_size ;
       
  1120         store_p->desc_p.number_units = number_units ;
       
  1121         store_p->desc_p.locked = locked ;
       
  1122         store_p->desc_p.erase_unit_size = number_eus ;
       
  1123         dev_p->storage_device_info[bus][device] = store_p->desc_p ;
       
  1124     }
       
  1125     else
       
  1126     {
       
  1127         CyAsStorageQueryDeviceData_dep    *store_p = (CyAsStorageQueryDeviceData_dep*)data_p ;
       
  1128 
       
  1129         /* Make sure the response is about the address we asked about - if not, firmware error */
       
  1130         if ((type != store_p->type) || (device != store_p->device))
       
  1131         {
       
  1132             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  1133             goto destroy ;
       
  1134         }
       
  1135 
       
  1136         store_p->desc_p.type = type ;
       
  1137         store_p->desc_p.removable = removable ;
       
  1138         store_p->desc_p.writeable = writeable ;
       
  1139         store_p->desc_p.block_size = block_size ;
       
  1140         store_p->desc_p.number_units = number_units ;
       
  1141         store_p->desc_p.locked = locked ;
       
  1142         store_p->desc_p.erase_unit_size = number_eus ;
       
  1143         dev_p->storage_device_info[bus][device] = store_p->desc_p ;
       
  1144     }
       
  1145 
       
  1146 destroy :
       
  1147     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1148     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  1149 
       
  1150     return ret ;
       
  1151 }
       
  1152 
       
  1153 static CyAsReturnStatus_t
       
  1154 MyStorageQueryDevice(CyAsDevice *dev_p,
       
  1155                         void* data_p,
       
  1156                         uint16_t req_flags,
       
  1157                         CyAsBusNumber_t bus,
       
  1158                         uint32_t device,
       
  1159                         CyAsFunctionCallback cb,
       
  1160                         uint32_t client)
       
  1161 {
       
  1162     CyAsLLRequestResponse *req_p , *reply_p ;
       
  1163     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  1164 
       
  1165     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
  1166         return CY_AS_ERROR_INVALID_HANDLE ;
       
  1167 
       
  1168     ret = IsStorageActive(dev_p) ;
       
  1169     if (ret != CY_AS_ERROR_SUCCESS)
       
  1170         return ret ;
       
  1171 
       
  1172     /* Create the request to send to the Antioch device */
       
  1173     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_QUERY_DEVICE, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
       
  1174     if (req_p == 0)
       
  1175         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1176 
       
  1177     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, device, 0)) ;
       
  1178 
       
  1179     /* Reserve space for the reply, the reply data will not exceed five words. */
       
  1180     reply_p = CyAsLLCreateResponse(dev_p, 5) ;
       
  1181     if (reply_p == 0)
       
  1182     {
       
  1183         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1184         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1185     }
       
  1186 
       
  1187     if(cb == 0)
       
  1188     {
       
  1189         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  1190         if (ret != CY_AS_ERROR_SUCCESS)
       
  1191             goto destroy ;
       
  1192 
       
  1193         req_p->flags |= req_flags;
       
  1194         return MyHandleResponseStorageQueryDevice(dev_p, req_p, reply_p, data_p) ;
       
  1195     }
       
  1196     else
       
  1197     {
       
  1198 
       
  1199         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_QUERYDEVICE,
       
  1200             data_p, dev_p->func_cbs_stor, req_flags,
       
  1201             req_p, reply_p, CyAsStorageFuncCallback) ;
       
  1202 
       
  1203         if (ret != CY_AS_ERROR_SUCCESS)
       
  1204             goto destroy ;
       
  1205 
       
  1206         /* The request and response are freed as part of the MiscFuncCallback */
       
  1207         return ret ;
       
  1208     }
       
  1209 
       
  1210 destroy:
       
  1211     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1212     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  1213 
       
  1214     return ret ;
       
  1215 }
       
  1216 
       
  1217 CyAsReturnStatus_t
       
  1218 CyAsStorageQueryDevice(CyAsDeviceHandle handle,
       
  1219                          CyAsStorageQueryDeviceData* data_p,
       
  1220                          CyAsFunctionCallback cb,
       
  1221                          uint32_t client)
       
  1222 {
       
  1223     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  1224     return MyStorageQueryDevice(dev_p, data_p, CY_AS_REQUEST_RESPONSE_MS, data_p->bus,
       
  1225             data_p->device, cb, client) ;
       
  1226 }
       
  1227 
       
  1228 static CyAsReturnStatus_t
       
  1229 MyHandleResponseStorageQueryUnit(CyAsDevice* dev_p,
       
  1230                          CyAsLLRequestResponse *req_p,
       
  1231                          CyAsLLRequestResponse *reply_p,
       
  1232                          void* data_p)
       
  1233 {
       
  1234     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  1235     CyAsBusNumber_t bus ;
       
  1236     uint32_t device ;
       
  1237     uint32_t unit ;
       
  1238     CyAsMediaType type ;
       
  1239     uint16_t block_size ;
       
  1240     uint32_t start_block ;
       
  1241     uint32_t unit_size ;
       
  1242     uint16_t v ;
       
  1243 
       
  1244     if (CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_NO_SUCH_ADDRESS)
       
  1245     {
       
  1246         ret = CyAsMapBadAddr(CyAsLLRequestResponse_GetWord(reply_p, 3)) ;
       
  1247         goto destroy ;
       
  1248     }
       
  1249 
       
  1250     if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_UNIT_DESCRIPTOR)
       
  1251     {
       
  1252         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  1253         goto destroy ;
       
  1254     }
       
  1255 
       
  1256     /* Unpack the response */
       
  1257     v      = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  1258     bus    = CyAsStorageGetBusFromAddress(v) ;
       
  1259     device = CyAsStorageGetDeviceFromAddress(v) ;
       
  1260     unit   = GetUnitFromAddress(v) ;
       
  1261 
       
  1262     type   = CyAsStorageGetMediaFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 1));
       
  1263 
       
  1264     block_size = CyAsLLRequestResponse_GetWord(reply_p, 2) ;
       
  1265     start_block = CyAsLLRequestResponse_GetWord(reply_p, 3) | (CyAsLLRequestResponse_GetWord(reply_p, 4) << 16) ;
       
  1266     unit_size = CyAsLLRequestResponse_GetWord(reply_p, 5) | (CyAsLLRequestResponse_GetWord(reply_p, 6) << 16) ;
       
  1267 
       
  1268     /* Store the results based on the version of originating function */
       
  1269     if (req_p->flags & CY_AS_REQUEST_RESPONSE_MS)
       
  1270     {
       
  1271         CyAsStorageQueryUnitData  *store_p = (CyAsStorageQueryUnitData*)data_p ;
       
  1272 
       
  1273         /* Make sure the response is about the address we asked about - if not, firmware error */
       
  1274         if (bus != store_p->bus || device != store_p->device || unit != store_p->unit)
       
  1275         {
       
  1276             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  1277             goto destroy ;
       
  1278         }
       
  1279 
       
  1280         store_p->desc_p.type = type ;
       
  1281         store_p->desc_p.block_size = block_size ;
       
  1282         store_p->desc_p.start_block = start_block ;
       
  1283         store_p->desc_p.unit_size = unit_size ;
       
  1284     }
       
  1285     else
       
  1286     {
       
  1287         CyAsStorageQueryUnitData_dep    *store_p = (CyAsStorageQueryUnitData_dep*)data_p ;
       
  1288 
       
  1289         /* Make sure the response is about the media type we asked about - if not, firmware error */
       
  1290         if ((type != store_p->type) || (device != store_p->device) || (unit != store_p->unit) ) {
       
  1291             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  1292             goto destroy ;
       
  1293         }
       
  1294 
       
  1295         store_p->desc_p.type = type ;
       
  1296         store_p->desc_p.block_size = block_size ;
       
  1297         store_p->desc_p.start_block = start_block ;
       
  1298         store_p->desc_p.unit_size = unit_size ;
       
  1299     }
       
  1300 
       
  1301     dev_p->storage_device_info[bus][device].type = type ;
       
  1302     dev_p->storage_device_info[bus][device].block_size = block_size ;
       
  1303 
       
  1304 destroy :
       
  1305     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1306     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  1307 
       
  1308     return ret ;
       
  1309 }
       
  1310 
       
  1311 static CyAsReturnStatus_t
       
  1312 MyStorageQueryUnit(CyAsDevice *dev_p,
       
  1313                     void* data_p,
       
  1314                     uint16_t req_flags,
       
  1315                     CyAsBusNumber_t bus,
       
  1316                     uint32_t device,
       
  1317                     uint32_t unit,
       
  1318                     CyAsFunctionCallback cb,
       
  1319                     uint32_t client)
       
  1320 {
       
  1321     CyAsLLRequestResponse *req_p , *reply_p ;
       
  1322     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  1323 
       
  1324     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
  1325         return CY_AS_ERROR_INVALID_HANDLE ;
       
  1326 
       
  1327     ret = IsStorageActive(dev_p) ;
       
  1328     if (ret != CY_AS_ERROR_SUCCESS)
       
  1329         return ret ;
       
  1330 
       
  1331     /* Create the request to send to the West Bridge device */
       
  1332     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_QUERY_UNIT, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
       
  1333     if (req_p == 0)
       
  1334         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1335 
       
  1336     if (device > 255)
       
  1337         return CY_AS_ERROR_NO_SUCH_DEVICE ;
       
  1338 
       
  1339     if (unit > 255)
       
  1340         return CY_AS_ERROR_NO_SUCH_UNIT ;
       
  1341 
       
  1342     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, device, (uint8_t)unit)) ;
       
  1343 
       
  1344     /* Reserve space for the reply, the reply data will be of seven words. */
       
  1345     reply_p = CyAsLLCreateResponse(dev_p, 7) ;
       
  1346     if (reply_p == 0)
       
  1347     {
       
  1348         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1349         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1350     }
       
  1351 
       
  1352     if(cb == 0)
       
  1353     {
       
  1354         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  1355         if (ret != CY_AS_ERROR_SUCCESS)
       
  1356             goto destroy ;
       
  1357 
       
  1358         req_p->flags |= req_flags ;
       
  1359         return MyHandleResponseStorageQueryUnit(dev_p, req_p, reply_p, data_p) ;
       
  1360     }
       
  1361     else
       
  1362     {
       
  1363 
       
  1364         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_QUERYUNIT,
       
  1365             data_p, dev_p->func_cbs_stor, req_flags,
       
  1366             req_p, reply_p, CyAsStorageFuncCallback) ;
       
  1367 
       
  1368         if (ret != CY_AS_ERROR_SUCCESS)
       
  1369             goto destroy ;
       
  1370 
       
  1371         /* The request and response are freed as part of the MiscFuncCallback */
       
  1372         return ret ;
       
  1373     }
       
  1374 
       
  1375 destroy:
       
  1376     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1377     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  1378 
       
  1379     return ret ;
       
  1380 }
       
  1381 
       
  1382 CyAsReturnStatus_t
       
  1383 CyAsStorageQueryUnit(CyAsDeviceHandle handle,
       
  1384                        CyAsStorageQueryUnitData* data_p,
       
  1385                        CyAsFunctionCallback cb,
       
  1386                        uint32_t client)
       
  1387 {
       
  1388     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  1389     return MyStorageQueryUnit(dev_p, data_p, CY_AS_REQUEST_RESPONSE_MS, data_p->bus,
       
  1390             data_p->device, data_p->unit, cb, client) ;
       
  1391 }
       
  1392 
       
  1393 
       
  1394 static CyAsReturnStatus_t
       
  1395 CyAsGetBlockSize(CyAsDevice *dev_p,
       
  1396                     CyAsBusNumber_t bus,
       
  1397                     uint32_t device,
       
  1398                     CyAsFunctionCallback cb)
       
  1399 {
       
  1400     CyAsLLRequestResponse *req_p , *reply_p ;
       
  1401     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  1402 
       
  1403     /* Create the request to send to the West Bridge device */
       
  1404     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_QUERY_DEVICE, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
       
  1405     if (req_p == 0)
       
  1406         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1407 
       
  1408     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, device, 0)) ;
       
  1409 
       
  1410     reply_p = CyAsLLCreateResponse(dev_p, 4) ;
       
  1411     if (reply_p == 0)
       
  1412     {
       
  1413         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1414         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1415     }
       
  1416 
       
  1417     if(cb == 0)
       
  1418     {
       
  1419         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  1420         if (ret != CY_AS_ERROR_SUCCESS)
       
  1421             goto destroy ;
       
  1422 
       
  1423         if (CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_NO_SUCH_ADDRESS)
       
  1424         {
       
  1425             ret = CY_AS_ERROR_NO_SUCH_BUS ;
       
  1426             goto destroy ;
       
  1427         }
       
  1428 
       
  1429         if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_DEVICE_DESCRIPTOR)
       
  1430         {
       
  1431             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  1432             goto destroy ;
       
  1433         }
       
  1434 
       
  1435         /* Make sure the response is about the media type we asked about - if not, firmware error */
       
  1436         if ((CyAsStorageGetBusFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 0)) != bus) ||
       
  1437             (CyAsStorageGetDeviceFromAddress(CyAsLLRequestResponse_GetWord(reply_p, 0)) != device) )
       
  1438         {
       
  1439             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  1440             goto destroy ;
       
  1441         }
       
  1442 
       
  1443 
       
  1444         dev_p->storage_device_info[bus][device].block_size = CyAsLLRequestResponse_GetWord(reply_p, 1) ;
       
  1445     }
       
  1446     else
       
  1447         ret = CY_AS_ERROR_INVALID_REQUEST ;
       
  1448 
       
  1449 destroy:
       
  1450     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1451     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  1452 
       
  1453     return ret ;
       
  1454 }
       
  1455 
       
  1456 CyAsReturnStatus_t
       
  1457 MyStorageDeviceControl(
       
  1458         CyAsDevice          *dev_p,
       
  1459         CyAsBusNumber_t      bus,
       
  1460         uint32_t             device,
       
  1461         CyBool               card_detect_en,
       
  1462         CyBool               write_prot_en,
       
  1463                 CyAsStorageCardDetect config_detect,
       
  1464         CyAsFunctionCallback cb,
       
  1465         uint32_t             client)
       
  1466 {
       
  1467     CyAsLLRequestResponse *req_p , *reply_p ;
       
  1468     CyAsReturnStatus_t ret ;
       
  1469     CyBool use_gpio = CyFalse ;
       
  1470 
       
  1471     (void)device ;
       
  1472 
       
  1473     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
  1474         return CY_AS_ERROR_INVALID_HANDLE ;
       
  1475 
       
  1476     if (!CyAsDeviceIsConfigured(dev_p))
       
  1477         return CY_AS_ERROR_NOT_CONFIGURED ;
       
  1478 
       
  1479     if (!CyAsDeviceIsFirmwareLoaded(dev_p))
       
  1480         return CY_AS_ERROR_NO_FIRMWARE ;
       
  1481 
       
  1482     if (CyAsDeviceIsInSuspendMode(dev_p))
       
  1483         return CY_AS_ERROR_IN_SUSPEND ;
       
  1484 
       
  1485     if (bus < 0 || bus >= CY_AS_MAX_BUSES)
       
  1486         return CY_AS_ERROR_NO_SUCH_BUS ;
       
  1487 
       
  1488     if (device >= CY_AS_MAX_STORAGE_DEVICES)
       
  1489         return CY_AS_ERROR_NO_SUCH_DEVICE ;
       
  1490 
       
  1491     /* If SD is not supported on the specified bus, then return ERROR */
       
  1492     if((dev_p->media_supported[bus] ==0 ) || (dev_p->media_supported[bus] &(1<<CyAsMediaNand)))
       
  1493         return CY_AS_ERROR_NOT_SUPPORTED;
       
  1494 
       
  1495     if(config_detect == CyAsStorageDetect_GPIO)
       
  1496         use_gpio = CyTrue ;
       
  1497     else if(config_detect == CyAsStorageDetect_SDAT_3)
       
  1498         use_gpio = CyFalse ;
       
  1499     else
       
  1500         return CY_AS_ERROR_INVALID_PARAMETER ;
       
  1501 
       
  1502     /* Create the request to send to the West Bridge device */
       
  1503     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SD_INTERFACE_CONTROL, CY_RQT_STORAGE_RQT_CONTEXT, 2) ;
       
  1504     if (req_p == 0)
       
  1505         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1506 
       
  1507     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, device, 0)) ;
       
  1508     CyAsLLRequestResponse_SetWord(req_p, 1, (((uint16_t)card_detect_en << 8) | ((uint16_t)use_gpio << 1) | (uint16_t)write_prot_en)) ;
       
  1509 
       
  1510     reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
  1511     if (reply_p == 0)
       
  1512     {
       
  1513         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1514         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  1515     }
       
  1516 
       
  1517     if(cb == 0)
       
  1518     {
       
  1519         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  1520         if (ret != CY_AS_ERROR_SUCCESS)
       
  1521             goto destroy ;
       
  1522 
       
  1523         if (CyAsLLRequestResponse_GetCode(reply_p) != CY_RESP_SUCCESS_FAILURE)
       
  1524         {
       
  1525             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  1526             goto destroy ;
       
  1527         }
       
  1528 
       
  1529         ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  1530     }
       
  1531     else
       
  1532     {
       
  1533 
       
  1534         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_DEVICECONTROL,
       
  1535             0, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX,
       
  1536             req_p, reply_p, CyAsStorageFuncCallback) ;
       
  1537 
       
  1538         if (ret != CY_AS_ERROR_SUCCESS)
       
  1539             goto destroy ;
       
  1540 
       
  1541         /* The request and response are freed as part of the MiscFuncCallback */
       
  1542         return ret ;
       
  1543     }
       
  1544 destroy:
       
  1545     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  1546     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  1547 
       
  1548     return ret ;
       
  1549 }
       
  1550 
       
  1551 CyAsReturnStatus_t
       
  1552 CyAsStorageDeviceControl(CyAsDeviceHandle handle,
       
  1553                             CyAsBusNumber_t bus,
       
  1554                             uint32_t device,
       
  1555                             CyBool card_detect_en,
       
  1556                             CyBool write_prot_en,
       
  1557                             CyAsStorageCardDetect config_detect,
       
  1558                             CyAsFunctionCallback cb,
       
  1559                             uint32_t client)
       
  1560 {
       
  1561     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  1562 
       
  1563     return MyStorageDeviceControl(dev_p, bus, device, card_detect_en, write_prot_en, config_detect, cb, client);
       
  1564 }
       
  1565 
       
  1566 static void
       
  1567 CyAsAsyncStorageCallback(CyAsDevice *dev_p, CyAsEndPointNumber_t ep, void *buf_p, uint32_t size, CyAsReturnStatus_t ret)
       
  1568 {
       
  1569     CyAsStorageCallback_dep cb ;
       
  1570     CyAsStorageCallback cb_ms ;
       
  1571 
       
  1572     (void)size ;
       
  1573     (void)buf_p ;
       
  1574     (void)ep ;
       
  1575 
       
  1576     CyAsDeviceClearStorageAsyncPending(dev_p) ;
       
  1577 
       
  1578     /*
       
  1579     * If the LL request callback has already been called, the user
       
  1580     * callback has to be called from here.
       
  1581     */
       
  1582     if (!dev_p->storage_wait)
       
  1583     {
       
  1584             CyAsHalAssert(dev_p->storage_cb != NULL || dev_p->storage_cb_ms != NULL) ;
       
  1585             cb = dev_p->storage_cb ;
       
  1586             cb_ms = dev_p->storage_cb_ms ;
       
  1587 
       
  1588             dev_p->storage_cb = 0 ;
       
  1589             dev_p->storage_cb_ms = 0 ;
       
  1590 
       
  1591             if (ret == CY_AS_ERROR_SUCCESS)
       
  1592                 ret = dev_p->storage_error ;
       
  1593 
       
  1594         if (cb_ms)
       
  1595         {
       
  1596             cb_ms((CyAsDeviceHandle)dev_p, dev_p->storage_bus_index, dev_p->storage_device_index,
       
  1597                 dev_p->storage_unit, dev_p->storage_block_addr, dev_p->storage_oper, ret) ;
       
  1598         }
       
  1599         else
       
  1600         {
       
  1601             cb((CyAsDeviceHandle)dev_p,
       
  1602                 dev_p->storage_device_info[dev_p->storage_bus_index][dev_p->storage_device_index].type,
       
  1603                 dev_p->storage_device_index, dev_p->storage_unit, dev_p->storage_block_addr, dev_p->storage_oper, ret) ;
       
  1604         }
       
  1605     }
       
  1606     else
       
  1607         dev_p->storage_error = ret ;
       
  1608 }
       
  1609 
       
  1610 static void
       
  1611 CyAsAsyncStorageReplyCallback(
       
  1612                               CyAsDevice *dev_p,
       
  1613                               uint8_t context,
       
  1614                               CyAsLLRequestResponse *rqt,
       
  1615                               CyAsLLRequestResponse *resp,
       
  1616                               CyAsReturnStatus_t ret)
       
  1617 {
       
  1618     CyAsStorageCallback_dep cb ;
       
  1619     CyAsStorageCallback cb_ms ;
       
  1620     uint8_t reqtype ;
       
  1621     (void)rqt ;
       
  1622     (void)context ;
       
  1623 
       
  1624     reqtype = CyAsLLRequestResponse_GetCode(rqt) ;
       
  1625 
       
  1626     if (ret == CY_AS_ERROR_SUCCESS)
       
  1627     {
       
  1628         if (CyAsLLRequestResponse_GetCode(resp) == CY_RESP_ANTIOCH_DEFERRED_ERROR)
       
  1629         {
       
  1630             ret = CyAsLLRequestResponse_GetWord(resp, 0) & 0x00FF ;
       
  1631         }
       
  1632         else if (CyAsLLRequestResponse_GetCode(resp) != CY_RESP_SUCCESS_FAILURE)
       
  1633         {
       
  1634             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  1635         }
       
  1636     }
       
  1637 
       
  1638     if (ret != CY_AS_ERROR_SUCCESS)
       
  1639     {
       
  1640         if(reqtype == CY_RQT_READ_BLOCK)
       
  1641             CyAsDmaCancel(dev_p, dev_p->storage_read_endpoint, ret) ;
       
  1642         else
       
  1643             CyAsDmaCancel(dev_p, dev_p->storage_write_endpoint, ret) ;
       
  1644     }
       
  1645 
       
  1646     dev_p->storage_wait = CyFalse ;
       
  1647 
       
  1648     /*
       
  1649     * If the DMA callback has already been called, the user callback
       
  1650     * has to be called from here.
       
  1651     */
       
  1652     if (!CyAsDeviceIsStorageAsyncPending(dev_p))
       
  1653     {
       
  1654             CyAsHalAssert(dev_p->storage_cb != NULL || dev_p->storage_cb_ms != NULL) ;
       
  1655         cb = dev_p->storage_cb ;
       
  1656         cb_ms = dev_p->storage_cb_ms ;
       
  1657 
       
  1658             dev_p->storage_cb = 0 ;
       
  1659             dev_p->storage_cb_ms = 0 ;
       
  1660 
       
  1661             if (ret == CY_AS_ERROR_SUCCESS)
       
  1662                 ret = dev_p->storage_error ;
       
  1663 
       
  1664         if (cb_ms)
       
  1665         {
       
  1666             cb_ms((CyAsDeviceHandle)dev_p, dev_p->storage_bus_index, dev_p->storage_device_index,
       
  1667                 dev_p->storage_unit, dev_p->storage_block_addr, dev_p->storage_oper, ret) ;
       
  1668         }
       
  1669         else
       
  1670         {
       
  1671             cb((CyAsDeviceHandle)dev_p,
       
  1672                 dev_p->storage_device_info[dev_p->storage_bus_index][dev_p->storage_device_index].type,
       
  1673                 dev_p->storage_device_index, dev_p->storage_unit, dev_p->storage_block_addr, dev_p->storage_oper, ret) ;
       
  1674         }
       
  1675     }
       
  1676     else
       
  1677         dev_p->storage_error = ret ;
       
  1678 }
       
  1679 
       
  1680 static CyAsReturnStatus_t
       
  1681 CyAsStorageAsyncOper(CyAsDevice *dev_p, CyAsEndPointNumber_t ep, uint8_t reqtype, uint16_t req_flags,
       
  1682                      CyAsBusNumber_t bus, uint32_t device, uint32_t unit,
       
  1683                      uint32_t block, void *data_p, uint16_t num_blocks,
       
  1684                      CyAsStorageCallback_dep callback, CyAsStorageCallback callback_ms)
       
  1685 {
       
  1686     uint32_t mask ;
       
  1687     CyAsLLRequestResponse *req_p , *reply_p ;
       
  1688     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  1689 
       
  1690     ret = IsStorageActive(dev_p) ;
       
  1691     if (ret != CY_AS_ERROR_SUCCESS)
       
  1692         return ret ;
       
  1693 
       
  1694     if (bus < 0 || bus >= CY_AS_MAX_BUSES)
       
  1695         return CY_AS_ERROR_NO_SUCH_BUS ;
       
  1696 
       
  1697     if (device >= CY_AS_MAX_STORAGE_DEVICES)
       
  1698         return CY_AS_ERROR_NO_SUCH_DEVICE ;
       
  1699 
       
  1700     if (unit > 255)
       
  1701         return CY_AS_ERROR_NO_SUCH_UNIT ;
       
  1702 
       
  1703     /* We are supposed to return sucess if the number of
       
  1704     * blocks is zero
       
  1705     */
       
  1706     if (num_blocks == 0)
       
  1707     {
       
  1708         if (callback_ms)
       
  1709             callback_ms((CyAsDeviceHandle)dev_p, bus, device, unit, block,
       
  1710                 ((reqtype == CY_RQT_WRITE_BLOCK) ? CyAsOpWrite : CyAsOpRead),
       
  1711                 CY_AS_ERROR_SUCCESS) ;
       
  1712         else
       
  1713             callback((CyAsDeviceHandle)dev_p, dev_p->storage_device_info[bus][device].type,
       
  1714                 device, unit, block, ((reqtype == CY_RQT_WRITE_BLOCK) ? CyAsOpWrite : CyAsOpRead),
       
  1715                 CY_AS_ERROR_SUCCESS) ;
       
  1716 
       
  1717         return CY_AS_ERROR_SUCCESS ;
       
  1718     }
       
  1719 
       
  1720     if (dev_p->storage_device_info[bus][device].block_size == 0)
       
  1721             return CY_AS_ERROR_QUERY_DEVICE_NEEDED ;
       
  1722 
       
  1723     /*
       
  1724     * Since async operations can be triggered by interrupt code, we must
       
  1725     * insure that we do not get multiple async operations going at one time and
       
  1726     * protect this test and set operation from interrupts.
       
  1727     * Also need to check for pending Async MTP writes
       
  1728     */
       
  1729     mask = CyAsHalDisableInterrupts() ;
       
  1730     if ((CyAsDeviceIsStorageAsyncPending(dev_p)) || (dev_p->storage_wait) || (CyAsDeviceIsUsbAsyncPending(dev_p, 6)))
       
  1731     {
       
  1732         CyAsHalEnableInterrupts(mask) ;
       
  1733         return CY_AS_ERROR_ASYNC_PENDING ;
       
  1734     }
       
  1735 
       
  1736     CyAsDeviceSetStorageAsyncPending(dev_p) ;
       
  1737     CyAsHalEnableInterrupts(mask) ;
       
  1738 
       
  1739     /*
       
  1740     * Storage information about the currently outstanding request
       
  1741     */
       
  1742     dev_p->storage_cb = callback ;
       
  1743     dev_p->storage_cb_ms = callback_ms ;
       
  1744     dev_p->storage_bus_index = bus ;
       
  1745     dev_p->storage_device_index = device ;
       
  1746     dev_p->storage_unit = unit ;
       
  1747     dev_p->storage_block_addr = block ;
       
  1748 
       
  1749     /* Initialise the request to send to the West Bridge. */
       
  1750     req_p = dev_p->storage_rw_req_p ;
       
  1751     CyAsLLInitRequest(req_p, reqtype, CY_RQT_STORAGE_RQT_CONTEXT, 5) ;
       
  1752 
       
  1753     /* Initialise the space for reply from the West Bridge. */
       
  1754     reply_p = dev_p->storage_rw_resp_p ;
       
  1755     CyAsLLInitResponse(reply_p, 5) ;
       
  1756 
       
  1757     /* Remember which version of the API originated the request */
       
  1758     req_p->flags |= req_flags ;
       
  1759 
       
  1760     /* Setup the DMA request and adjust the storage operation if we are reading */
       
  1761     if (reqtype == CY_RQT_READ_BLOCK)
       
  1762     {
       
  1763         ret = CyAsDmaQueueRequest(dev_p, ep, data_p, dev_p->storage_device_info[bus][device].block_size * num_blocks,
       
  1764             CyFalse, CyTrue, CyAsAsyncStorageCallback) ;
       
  1765         dev_p->storage_oper = CyAsOpRead ;
       
  1766     }
       
  1767     else if (reqtype == CY_RQT_WRITE_BLOCK)
       
  1768     {
       
  1769         ret = CyAsDmaQueueRequest(dev_p, ep, data_p, dev_p->storage_device_info[bus][device].block_size * num_blocks,
       
  1770             CyFalse, CyFalse, CyAsAsyncStorageCallback) ;
       
  1771         dev_p->storage_oper = CyAsOpWrite ;
       
  1772     }
       
  1773     if (ret != CY_AS_ERROR_SUCCESS)
       
  1774     {
       
  1775         CyAsDeviceClearStorageAsyncPending(dev_p) ;
       
  1776         return ret ;
       
  1777     }
       
  1778 
       
  1779     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, (uint8_t)unit)) ;
       
  1780     CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)((block >> 16) & 0xffff)) ;
       
  1781     CyAsLLRequestResponse_SetWord(req_p, 2, (uint16_t)(block & 0xffff)) ;
       
  1782     CyAsLLRequestResponse_SetWord(req_p, 3, (uint16_t)((num_blocks >> 8) & 0x00ff)) ;
       
  1783     CyAsLLRequestResponse_SetWord(req_p, 4, (uint16_t)((num_blocks << 8) & 0xff00)) ;
       
  1784 
       
  1785     /* Set the burst mode flag. */
       
  1786     if (dev_p->is_storage_only_mode)
       
  1787         req_p->data[4] |= 0x0001;
       
  1788 
       
  1789     /* Send the request and wait for completion of storage request */
       
  1790     dev_p->storage_wait = CyTrue ;
       
  1791     ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyTrue, CyAsAsyncStorageReplyCallback) ;
       
  1792     if (ret != CY_AS_ERROR_SUCCESS)
       
  1793     {
       
  1794         CyAsDmaCancel(dev_p, ep, CY_AS_ERROR_CANCELED) ;
       
  1795         CyAsDeviceClearStorageAsyncPending(dev_p) ;
       
  1796     }
       
  1797 
       
  1798     return ret ;
       
  1799 }
       
  1800 
       
  1801 static void
       
  1802 CyAsSyncStorageCallback(CyAsDevice *dev_p, CyAsEndPointNumber_t ep, void *buf_p, uint32_t size, CyAsReturnStatus_t err)
       
  1803 {
       
  1804     (void)ep ;
       
  1805     (void)buf_p ;
       
  1806     (void)size ;
       
  1807 
       
  1808     dev_p->storage_error = err ;
       
  1809 }
       
  1810 
       
  1811 static void
       
  1812 CyAsSyncStorageReplyCallback(
       
  1813                              CyAsDevice *dev_p,
       
  1814                              uint8_t context,
       
  1815                              CyAsLLRequestResponse *rqt,
       
  1816                              CyAsLLRequestResponse *resp,
       
  1817                              CyAsReturnStatus_t ret)
       
  1818 {
       
  1819     uint8_t reqtype ;
       
  1820     (void)rqt ;
       
  1821 
       
  1822     reqtype = CyAsLLRequestResponse_GetCode(rqt) ;
       
  1823 
       
  1824     if (CyAsLLRequestResponse_GetCode(resp) == CY_RESP_ANTIOCH_DEFERRED_ERROR)
       
  1825     {
       
  1826         ret = CyAsLLRequestResponse_GetWord(resp, 0) & 0x00FF ;
       
  1827 
       
  1828         if (ret != CY_AS_ERROR_SUCCESS)
       
  1829         {
       
  1830             if(reqtype == CY_RQT_READ_BLOCK)
       
  1831                 CyAsDmaCancel(dev_p, dev_p->storage_read_endpoint, ret) ;
       
  1832             else
       
  1833                 CyAsDmaCancel(dev_p, dev_p->storage_write_endpoint, ret) ;
       
  1834         }
       
  1835     }
       
  1836     else if (CyAsLLRequestResponse_GetCode(resp) != CY_RESP_SUCCESS_FAILURE)
       
  1837     {
       
  1838         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  1839     }
       
  1840 
       
  1841     dev_p->storage_wait = CyFalse ;
       
  1842     dev_p->storage_error = ret ;
       
  1843 
       
  1844     /* Wake any threads/processes that are waiting on the read/write completion. */
       
  1845     CyAsHalWake (&dev_p->context[context]->channel) ;
       
  1846 }
       
  1847 
       
  1848 static CyAsReturnStatus_t
       
  1849 CyAsStorageSyncOper(CyAsDevice *dev_p, CyAsEndPointNumber_t ep, uint8_t reqtype, CyAsBusNumber_t bus, uint32_t device,
       
  1850                     uint32_t unit, uint32_t block, void *data_p, uint16_t num_blocks)
       
  1851 {
       
  1852     CyAsLLRequestResponse *req_p , *reply_p ;
       
  1853     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  1854     CyAsContext *ctxt_p ;
       
  1855     uint32_t loopcount = 200 ;
       
  1856 
       
  1857     ret = IsStorageActive(dev_p) ;
       
  1858     if (ret != CY_AS_ERROR_SUCCESS)
       
  1859         return ret ;
       
  1860 
       
  1861     if (bus < 0 || bus >= CY_AS_MAX_BUSES)
       
  1862         return CY_AS_ERROR_NO_SUCH_BUS ;
       
  1863 
       
  1864     if (device >= CY_AS_MAX_STORAGE_DEVICES)
       
  1865         return CY_AS_ERROR_NO_SUCH_DEVICE ;
       
  1866 
       
  1867     if (unit > 255)
       
  1868         return CY_AS_ERROR_NO_SUCH_UNIT ;
       
  1869 
       
  1870     if ((CyAsDeviceIsStorageAsyncPending(dev_p)) || (dev_p->storage_wait))
       
  1871         return CY_AS_ERROR_ASYNC_PENDING ;
       
  1872 
       
  1873     /* Also need to check for pending Async MTP writes */
       
  1874     if(CyAsDeviceIsUsbAsyncPending(dev_p, 6))
       
  1875         return CY_AS_ERROR_ASYNC_PENDING ;
       
  1876 
       
  1877     /* We are supposed to return sucess if the number of
       
  1878     * blocks is zero
       
  1879     */
       
  1880     if (num_blocks == 0)
       
  1881         return CY_AS_ERROR_SUCCESS ;
       
  1882 
       
  1883     if (dev_p->storage_device_info[bus][device].block_size == 0)
       
  1884     {
       
  1885         /*
       
  1886         * Normally, a given device has been queried via the query device call before a
       
  1887         * read request is issued.  Therefore, this normally will not be run.
       
  1888         */
       
  1889         ret = CyAsGetBlockSize(dev_p, bus, device, 0) ;
       
  1890         if (ret != CY_AS_ERROR_SUCCESS)
       
  1891             return ret ;
       
  1892     }
       
  1893 
       
  1894     /* Initialise the request to send to the West Bridge. */
       
  1895     req_p = dev_p->storage_rw_req_p ;
       
  1896     CyAsLLInitRequest(req_p, reqtype, CY_RQT_STORAGE_RQT_CONTEXT, 5) ;
       
  1897 
       
  1898     /* Initialise the space for reply from the West Bridge. */
       
  1899     reply_p = dev_p->storage_rw_resp_p ;
       
  1900     CyAsLLInitResponse(reply_p, 5) ;
       
  1901 
       
  1902     /* Setup the DMA request */
       
  1903     if (reqtype == CY_RQT_READ_BLOCK)
       
  1904     {
       
  1905         ret = CyAsDmaQueueRequest(dev_p, ep, data_p, dev_p->storage_device_info[bus][device].block_size * num_blocks, CyFalse,
       
  1906             CyTrue, CyAsSyncStorageCallback) ;
       
  1907         dev_p->storage_oper = CyAsOpRead ;
       
  1908     }
       
  1909     else if (reqtype == CY_RQT_WRITE_BLOCK)
       
  1910     {
       
  1911         ret = CyAsDmaQueueRequest(dev_p, ep, data_p, dev_p->storage_device_info[bus][device].block_size * num_blocks, CyFalse,
       
  1912             CyFalse, CyAsSyncStorageCallback) ;
       
  1913         dev_p->storage_oper = CyAsOpWrite ;
       
  1914     }
       
  1915     if (ret != CY_AS_ERROR_SUCCESS)
       
  1916     {
       
  1917         return ret ;
       
  1918     }
       
  1919 
       
  1920     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, (uint8_t)unit)) ;
       
  1921     CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)((block >> 16) & 0xffff)) ;
       
  1922     CyAsLLRequestResponse_SetWord(req_p, 2, (uint16_t)(block & 0xffff)) ;
       
  1923     CyAsLLRequestResponse_SetWord(req_p, 3, (uint16_t)((num_blocks >> 8) & 0x00ff)) ;
       
  1924     CyAsLLRequestResponse_SetWord(req_p, 4, (uint16_t)((num_blocks << 8) & 0xff00)) ;
       
  1925 
       
  1926     /* Set the burst mode flag. */
       
  1927     if (dev_p->is_storage_only_mode)
       
  1928         req_p->data[4] |= 0x0001;
       
  1929 
       
  1930     /* Send the request and wait for completion of storage request */
       
  1931     dev_p->storage_wait = CyTrue ;
       
  1932     ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyTrue, CyAsSyncStorageReplyCallback) ;
       
  1933     if (ret != CY_AS_ERROR_SUCCESS)
       
  1934     {
       
  1935         CyAsDmaCancel(dev_p, ep, CY_AS_ERROR_CANCELED) ;
       
  1936     }
       
  1937     else
       
  1938     {
       
  1939         /* Setup the DMA request */
       
  1940         ctxt_p = dev_p->context[CY_RQT_STORAGE_RQT_CONTEXT] ;
       
  1941         ret = CyAsDmaDrainQueue(dev_p, ep, CyFalse) ;
       
  1942 
       
  1943         while (loopcount-- > 0)
       
  1944         {
       
  1945             if (dev_p->storage_wait == CyFalse)
       
  1946                 break ;
       
  1947             CyAsHalSleepOn(&ctxt_p->channel, 10) ;
       
  1948         }
       
  1949 
       
  1950         if (dev_p->storage_wait == CyTrue)
       
  1951         {
       
  1952             dev_p->storage_wait = CyFalse ;
       
  1953             CyAsLLRemoveRequest(dev_p, ctxt_p, req_p, CyTrue) ;
       
  1954             ret = CY_AS_ERROR_TIMEOUT ;
       
  1955         }
       
  1956 
       
  1957         if (ret == CY_AS_ERROR_SUCCESS)
       
  1958             ret = dev_p->storage_error ;
       
  1959     }
       
  1960 
       
  1961     return ret ;
       
  1962 }
       
  1963 
       
  1964 CyAsReturnStatus_t
       
  1965 CyAsStorageRead(CyAsDeviceHandle handle, CyAsBusNumber_t bus, uint32_t device, uint32_t unit, uint32_t block,
       
  1966                 void *data_p, uint16_t num_blocks)
       
  1967 {
       
  1968     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  1969 
       
  1970     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
  1971         return CY_AS_ERROR_INVALID_HANDLE ;
       
  1972 
       
  1973     return CyAsStorageSyncOper(dev_p, dev_p->storage_read_endpoint, CY_RQT_READ_BLOCK, bus, device,
       
  1974         unit, block, data_p, num_blocks) ;
       
  1975 }
       
  1976 
       
  1977 CyAsReturnStatus_t
       
  1978 CyAsStorageWrite(CyAsDeviceHandle handle, CyAsBusNumber_t bus, uint32_t device, uint32_t unit, uint32_t block,
       
  1979                  void *data_p, uint16_t num_blocks)
       
  1980 {
       
  1981     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  1982 
       
  1983     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
  1984         return CY_AS_ERROR_INVALID_HANDLE ;
       
  1985 
       
  1986     if(dev_p->mtp_turbo_active)
       
  1987         return CY_AS_ERROR_NOT_VALID_DURING_MTP ;
       
  1988 
       
  1989     return CyAsStorageSyncOper(dev_p, dev_p->storage_write_endpoint, CY_RQT_WRITE_BLOCK, bus, device,
       
  1990         unit, block, data_p, num_blocks) ;
       
  1991 }
       
  1992 
       
  1993 
       
  1994 CyAsReturnStatus_t
       
  1995 CyAsStorageReadAsync(CyAsDeviceHandle handle, CyAsBusNumber_t bus, uint32_t device, uint32_t unit,
       
  1996                      uint32_t block, void *data_p, uint16_t num_blocks, CyAsStorageCallback callback)
       
  1997 {
       
  1998     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  1999 
       
  2000     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
  2001         return CY_AS_ERROR_INVALID_HANDLE ;
       
  2002 
       
  2003     if (callback == 0)
       
  2004         return CY_AS_ERROR_NULL_CALLBACK ;
       
  2005 
       
  2006     return CyAsStorageAsyncOper(dev_p, dev_p->storage_read_endpoint, CY_RQT_READ_BLOCK,
       
  2007         CY_AS_REQUEST_RESPONSE_MS, bus, device, unit, block, data_p, num_blocks, NULL, callback);
       
  2008 }
       
  2009 
       
  2010 CyAsReturnStatus_t
       
  2011 CyAsStorageWriteAsync(CyAsDeviceHandle handle, CyAsBusNumber_t bus, uint32_t device, uint32_t unit,
       
  2012                       uint32_t block, void *data_p, uint16_t num_blocks, CyAsStorageCallback callback)
       
  2013 {
       
  2014     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  2015 
       
  2016     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
  2017         return CY_AS_ERROR_INVALID_HANDLE ;
       
  2018 
       
  2019     if (callback == 0)
       
  2020         return CY_AS_ERROR_NULL_CALLBACK ;
       
  2021 
       
  2022     if(dev_p->mtp_turbo_active)
       
  2023         return CY_AS_ERROR_NOT_VALID_DURING_MTP ;
       
  2024 
       
  2025     return CyAsStorageAsyncOper(dev_p, dev_p->storage_write_endpoint, CY_RQT_WRITE_BLOCK,
       
  2026         CY_AS_REQUEST_RESPONSE_MS, bus, device, unit, block, data_p, num_blocks, NULL, callback);
       
  2027 }
       
  2028 
       
  2029 
       
  2030 static void
       
  2031 MyStorageCancelCallback (
       
  2032         CyAsDevice *dev_p,
       
  2033         uint8_t context,
       
  2034         CyAsLLRequestResponse *rqt,
       
  2035         CyAsLLRequestResponse *resp,
       
  2036         CyAsReturnStatus_t stat)
       
  2037 {
       
  2038     (void)context ;
       
  2039     (void)stat ;
       
  2040 
       
  2041     /* Nothing to do here, except free up the request and response structures. */
       
  2042     CyAsLLDestroyResponse(dev_p, resp) ;
       
  2043     CyAsLLDestroyRequest(dev_p, rqt) ;
       
  2044 }
       
  2045 
       
  2046 
       
  2047 CyAsReturnStatus_t
       
  2048 CyAsStorageCancelAsync(CyAsDeviceHandle handle)
       
  2049 {
       
  2050     CyAsReturnStatus_t ret ;
       
  2051     CyAsLLRequestResponse *req_p , *reply_p ;
       
  2052 
       
  2053     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  2054     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
  2055         return CY_AS_ERROR_INVALID_HANDLE ;
       
  2056 
       
  2057     ret = IsStorageActive(dev_p) ;
       
  2058     if (ret != CY_AS_ERROR_SUCCESS)
       
  2059         return ret ;
       
  2060 
       
  2061     if (!CyAsDeviceIsStorageAsyncPending(dev_p))
       
  2062         return CY_AS_ERROR_ASYNC_NOT_PENDING ;
       
  2063 
       
  2064     /*
       
  2065      * Create and send a mailbox request to firmware asking it to abort processing
       
  2066      * of the current P2S operation. The rest of the cancel processing will be
       
  2067      * driven through the callbacks for the read/write call.
       
  2068      */
       
  2069     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_ABORT_P2S_XFER, CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
       
  2070     if (req_p == 0)
       
  2071         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2072 
       
  2073     reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
  2074     if (reply_p == 0)
       
  2075     {
       
  2076         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2077         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2078     }
       
  2079 
       
  2080     ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyFalse, MyStorageCancelCallback) ;
       
  2081     if (ret)
       
  2082     {
       
  2083         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2084         CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  2085     }
       
  2086 
       
  2087     return CY_AS_ERROR_SUCCESS ;
       
  2088 }
       
  2089 
       
  2090 /*
       
  2091  * This function does all the API side clean-up associated with
       
  2092  * CyAsStorageStop, without any communication with the firmware.
       
  2093  */
       
  2094 void CyAsStorageCleanup(CyAsDevice *dev_p)
       
  2095 {
       
  2096     if (dev_p->storage_count)
       
  2097     {
       
  2098         CyAsLLDestroyRequest(dev_p, dev_p->storage_rw_req_p) ;
       
  2099         CyAsLLDestroyResponse(dev_p, dev_p->storage_rw_resp_p) ;
       
  2100         dev_p->storage_count = 0 ;
       
  2101         CyAsDeviceClearScsiMessages(dev_p) ;
       
  2102         CyAsHalMemSet(dev_p->storage_device_info, 0, sizeof(dev_p->storage_device_info)) ;
       
  2103 
       
  2104         CyAsDeviceClearStorageAsyncPending(dev_p) ;
       
  2105         dev_p->storage_cb = 0 ;
       
  2106         dev_p->storage_cb_ms = 0 ;
       
  2107         dev_p->storage_wait = CyFalse ;
       
  2108     }
       
  2109 }
       
  2110 
       
  2111 static CyAsReturnStatus_t
       
  2112 MyHandleResponseSDRegRead(
       
  2113         CyAsDevice               *dev_p,
       
  2114         CyAsLLRequestResponse    *req_p,
       
  2115         CyAsLLRequestResponse    *reply_p,
       
  2116         CyAsStorageSDRegReadData *info)
       
  2117 {
       
  2118     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  2119     uint8_t  resp_type, i ;
       
  2120     uint16_t resp_len ;
       
  2121     uint8_t  length = info->length ;
       
  2122     uint8_t *data_p = info->buf_p ;
       
  2123 
       
  2124     resp_type = CyAsLLRequestResponse_GetCode(reply_p) ;
       
  2125     if (resp_type == CY_RESP_SD_REGISTER_DATA)
       
  2126     {
       
  2127         uint16_t *resp_p = reply_p->data + 1 ;
       
  2128         uint16_t temp ;
       
  2129 
       
  2130         resp_len = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  2131         CyAsHalAssert(resp_len >= length) ;
       
  2132 
       
  2133         /*
       
  2134          * Copy the values into the output buffer after doing the
       
  2135          * necessary bit shifting. The bit shifting is required because
       
  2136          * the data comes out of the West Bridge with a 6 bit offset.
       
  2137          */
       
  2138         i = 0 ;
       
  2139         while (length)
       
  2140         {
       
  2141             temp = ((resp_p[i] << 6) | (resp_p[i + 1] >> 10)) ;
       
  2142             i++ ;
       
  2143 
       
  2144             *data_p++ = (uint8_t)(temp >> 8) ;
       
  2145             length-- ;
       
  2146 
       
  2147             if (length)
       
  2148             {
       
  2149                 *data_p++ = (uint8_t)(temp & 0xFF) ;
       
  2150                 length-- ;
       
  2151             }
       
  2152         }
       
  2153     }
       
  2154     else
       
  2155     {
       
  2156         if (resp_type == CY_RESP_SUCCESS_FAILURE)
       
  2157             ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  2158         else
       
  2159             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  2160     }
       
  2161 
       
  2162     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  2163     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2164 
       
  2165     return ret ;
       
  2166 }
       
  2167 
       
  2168 CyAsReturnStatus_t
       
  2169 CyAsStorageSDRegisterRead(
       
  2170         CyAsDeviceHandle          handle,
       
  2171         CyAsBusNumber_t           bus,
       
  2172         uint8_t                   device,
       
  2173         CyAsSDCardRegType         regType,
       
  2174         CyAsStorageSDRegReadData *data_p,
       
  2175         CyAsFunctionCallback      cb,
       
  2176         uint32_t                  client)
       
  2177 {
       
  2178     CyAsLLRequestResponse *req_p , *reply_p ;
       
  2179     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  2180     uint8_t  length ;
       
  2181 
       
  2182     /*
       
  2183      * Sanity checks required before sending the request to the
       
  2184      * firmware.
       
  2185      */
       
  2186     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  2187     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
  2188         return CY_AS_ERROR_INVALID_HANDLE ;
       
  2189 
       
  2190     ret = IsStorageActive(dev_p) ;
       
  2191     if (ret != CY_AS_ERROR_SUCCESS)
       
  2192         return ret ;
       
  2193 
       
  2194     if (device >= CY_AS_MAX_STORAGE_DEVICES)
       
  2195         return CY_AS_ERROR_NO_SUCH_DEVICE ;
       
  2196 
       
  2197     if (regType > CyAsSDReg_CSD)
       
  2198         return CY_AS_ERROR_INVALID_PARAMETER ;
       
  2199 
       
  2200     /* If SD/MMC media is not supported on the addressed bus, return error. */
       
  2201     if ((dev_p->media_supported[bus] & (1 << CyAsMediaSDFlash)) == 0)
       
  2202         return CY_AS_ERROR_INVALID_PARAMETER ;
       
  2203 
       
  2204     /*
       
  2205      * Find the amount of data to be returned. This will be the minimum of
       
  2206      * the actual data length, and the length requested.
       
  2207      */
       
  2208     switch (regType)
       
  2209     {
       
  2210         case CyAsSDReg_OCR:
       
  2211             length = CY_AS_SD_REG_OCR_LENGTH ;
       
  2212             break ;
       
  2213 
       
  2214         case CyAsSDReg_CID:
       
  2215             length = CY_AS_SD_REG_CID_LENGTH ;
       
  2216             break ;
       
  2217 
       
  2218         case CyAsSDReg_CSD:
       
  2219             length = CY_AS_SD_REG_CSD_LENGTH ;
       
  2220             break ;
       
  2221 
       
  2222         default:
       
  2223             length = 0 ;
       
  2224             CyAsHalAssert(0) ;
       
  2225     }
       
  2226 
       
  2227     if (length < data_p->length)
       
  2228         data_p->length = length ;
       
  2229     length = data_p->length ;
       
  2230 
       
  2231     /* Create the request to send to the West Bridge device */
       
  2232     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SD_REGISTER_READ, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
       
  2233     if (req_p == 0)
       
  2234         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2235 
       
  2236     CyAsLLRequestResponse_SetWord(req_p, 0, (CreateAddress(bus, device, 0) | (uint16_t)regType)) ;
       
  2237 
       
  2238     reply_p = CyAsLLCreateResponse(dev_p, CY_AS_SD_REG_MAX_RESP_LENGTH) ;
       
  2239     if (reply_p == 0)
       
  2240     {
       
  2241         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2242         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2243     }
       
  2244 
       
  2245     if (cb == 0)
       
  2246     {
       
  2247         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  2248         if (ret != CY_AS_ERROR_SUCCESS)
       
  2249             goto destroy ;
       
  2250 
       
  2251         return MyHandleResponseSDRegRead(dev_p, req_p, reply_p, data_p) ;
       
  2252     }
       
  2253     else
       
  2254     {
       
  2255         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_SDREGISTERREAD,
       
  2256             data_p, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX,
       
  2257             req_p, reply_p, CyAsStorageFuncCallback) ;
       
  2258 
       
  2259         if (ret != CY_AS_ERROR_SUCCESS)
       
  2260             goto destroy ;
       
  2261 
       
  2262         /* The request and response are freed as part of the MiscFuncCallback */
       
  2263         return ret ;
       
  2264     }
       
  2265 
       
  2266 destroy:
       
  2267     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2268     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  2269 
       
  2270     return ret ;
       
  2271 }
       
  2272 
       
  2273 CyAsReturnStatus_t
       
  2274 CyAsStorageCreatePPartition(
       
  2275         CyAsDeviceHandle        handle,                 /* Handle to the device of interest */
       
  2276         CyAsBusNumber_t         bus,
       
  2277         uint32_t                device,
       
  2278         uint32_t                size, /* of P-port only partition in blocks */
       
  2279         CyAsFunctionCallback    cb,
       
  2280         uint32_t                client)
       
  2281 {
       
  2282     CyAsLLRequestResponse *req_p, *reply_p ;
       
  2283     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  2284     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  2285 
       
  2286     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
  2287         return CY_AS_ERROR_INVALID_HANDLE ;
       
  2288 
       
  2289     ret = IsStorageActive(dev_p) ;
       
  2290     if (ret != CY_AS_ERROR_SUCCESS)
       
  2291         return ret ;
       
  2292 
       
  2293     /* Partitions cannot be created or deleted while the USB stack is active. */
       
  2294     if (dev_p->usb_count)
       
  2295         return CY_AS_ERROR_USB_RUNNING ;
       
  2296 
       
  2297     /* Create the request to send to the West Bridge device */
       
  2298     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_PARTITION_STORAGE, CY_RQT_STORAGE_RQT_CONTEXT, 3) ;
       
  2299     if (req_p == 0)
       
  2300     {
       
  2301         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2302     }
       
  2303 
       
  2304     /* Reserve space for the reply, the reply data will not exceed one word */
       
  2305     reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
  2306     if (reply_p == 0)
       
  2307     {
       
  2308         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2309         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2310     }
       
  2311     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, 0x00) );
       
  2312     CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)((size >> 16) & 0xffff)) ;
       
  2313     CyAsLLRequestResponse_SetWord(req_p, 2, (uint16_t)(size & 0xffff)) ;
       
  2314 
       
  2315     if(cb == 0)
       
  2316     {
       
  2317         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  2318         if (ret != CY_AS_ERROR_SUCCESS)
       
  2319             goto destroy ;
       
  2320 
       
  2321         return MyHandleResponseNoData(dev_p, req_p, reply_p) ;
       
  2322     }
       
  2323     else
       
  2324     {
       
  2325         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_PARTITION,
       
  2326             0, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX,
       
  2327                 req_p, reply_p, CyAsStorageFuncCallback) ;
       
  2328 
       
  2329         if (ret != CY_AS_ERROR_SUCCESS)
       
  2330             goto destroy ;
       
  2331 
       
  2332         /* The request and response are freed as part of the FuncCallback */
       
  2333         return ret ;
       
  2334 
       
  2335     }
       
  2336 
       
  2337 destroy:
       
  2338     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2339     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  2340 
       
  2341     return ret ;
       
  2342 }
       
  2343 
       
  2344 CyAsReturnStatus_t
       
  2345 CyAsStorageRemovePPartition(
       
  2346         CyAsDeviceHandle        handle,
       
  2347         CyAsBusNumber_t         bus,
       
  2348         uint32_t                device,
       
  2349         CyAsFunctionCallback    cb,
       
  2350         uint32_t                client)
       
  2351 {
       
  2352     CyAsLLRequestResponse *req_p, *reply_p ;
       
  2353     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  2354     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  2355 
       
  2356     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
  2357         return CY_AS_ERROR_INVALID_HANDLE ;
       
  2358 
       
  2359     ret = IsStorageActive(dev_p) ;
       
  2360     if (ret != CY_AS_ERROR_SUCCESS)
       
  2361         return ret ;
       
  2362 
       
  2363     /* Partitions cannot be created or deleted while the USB stack is active. */
       
  2364     if (dev_p->usb_count)
       
  2365         return CY_AS_ERROR_USB_RUNNING ;
       
  2366 
       
  2367     /* Create the request to send to the West Bridge device */
       
  2368     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_PARTITION_ERASE, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
       
  2369     if (req_p == 0)
       
  2370     {
       
  2371         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2372     }
       
  2373 
       
  2374     /* Reserve space for the reply, the reply data will not exceed one word */
       
  2375     reply_p = CyAsLLCreateResponse(dev_p, 1) ;
       
  2376     if (reply_p == 0)
       
  2377     {
       
  2378         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2379         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2380     }
       
  2381 
       
  2382     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, 0x00) );
       
  2383 
       
  2384     if(cb == 0)
       
  2385     {
       
  2386         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  2387         if (ret != CY_AS_ERROR_SUCCESS)
       
  2388             goto destroy ;
       
  2389 
       
  2390         return MyHandleResponseNoData(dev_p, req_p, reply_p) ;
       
  2391     }
       
  2392     else
       
  2393     {
       
  2394         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_NODATA,
       
  2395             0, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX,
       
  2396                 req_p, reply_p, CyAsStorageFuncCallback) ;
       
  2397 
       
  2398         if (ret != CY_AS_ERROR_SUCCESS)
       
  2399             goto destroy ;
       
  2400 
       
  2401         /* The request and response are freed as part of the FuncCallback */
       
  2402         return ret ;
       
  2403 
       
  2404     }
       
  2405 
       
  2406 destroy:
       
  2407     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2408     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  2409 
       
  2410     return ret ;
       
  2411 }
       
  2412 
       
  2413 static CyAsReturnStatus_t
       
  2414 MyHandleResponseGetTransferAmount(CyAsDevice* dev_p,
       
  2415                          CyAsLLRequestResponse *req_p,
       
  2416                          CyAsLLRequestResponse *reply_p,
       
  2417                          CyAsMSCProgressData *data)
       
  2418 {
       
  2419     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  2420     uint8_t code = CyAsLLRequestResponse_GetCode(reply_p) ;
       
  2421     uint16_t v1, v2 ;
       
  2422 
       
  2423     if (code != CY_RESP_TRANSFER_COUNT)
       
  2424     {
       
  2425         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  2426         goto destroy ;
       
  2427     }
       
  2428 
       
  2429     v1 = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  2430     v2 = CyAsLLRequestResponse_GetWord(reply_p, 1) ;
       
  2431     data->wr_count = (uint32_t)((v1 << 16) | v2) ;
       
  2432 
       
  2433     v1 = CyAsLLRequestResponse_GetWord(reply_p, 2) ;
       
  2434     v2 = CyAsLLRequestResponse_GetWord(reply_p, 3) ;
       
  2435     data->rd_count = (uint32_t)((v1 << 16) | v2) ;
       
  2436 
       
  2437 destroy :
       
  2438     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2439     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  2440 
       
  2441     return ret ;
       
  2442 }
       
  2443 
       
  2444 CyAsReturnStatus_t
       
  2445 CyAsStorageGetTransferAmount(
       
  2446         CyAsDeviceHandle handle,
       
  2447         CyAsBusNumber_t  bus,
       
  2448         uint32_t device,
       
  2449         CyAsMSCProgressData *data_p,
       
  2450         CyAsFunctionCallback cb,
       
  2451         uint32_t client
       
  2452     )
       
  2453 {
       
  2454     CyAsLLRequestResponse *req_p, *reply_p ;
       
  2455     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  2456     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  2457 
       
  2458     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
  2459         return CY_AS_ERROR_INVALID_HANDLE ;
       
  2460 
       
  2461     ret = IsStorageActive(dev_p) ;
       
  2462     if (ret != CY_AS_ERROR_SUCCESS)
       
  2463         return ret ;
       
  2464 
       
  2465     /* Check if the firmware image supports this feature. */
       
  2466     if ((dev_p->media_supported[0]) && (dev_p->media_supported[0] == (1 << CyAsMediaNand)))
       
  2467         return CY_AS_ERROR_NOT_SUPPORTED ;
       
  2468 
       
  2469     /* Create the request to send to the West Bridge device */
       
  2470     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_GET_TRANSFER_AMOUNT, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
       
  2471     if (req_p == 0)
       
  2472     {
       
  2473         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2474     }
       
  2475 
       
  2476     /* Reserve space for the reply, the reply data will not exceed four words. */
       
  2477     reply_p = CyAsLLCreateResponse(dev_p, 4) ;
       
  2478     if (reply_p == 0)
       
  2479     {
       
  2480         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2481         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2482     }
       
  2483 
       
  2484     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, 0x00));
       
  2485 
       
  2486     if(cb == 0)
       
  2487     {
       
  2488         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  2489         if (ret != CY_AS_ERROR_SUCCESS)
       
  2490             goto destroy ;
       
  2491 
       
  2492         return MyHandleResponseGetTransferAmount(dev_p, req_p, reply_p, data_p) ;
       
  2493     }
       
  2494     else
       
  2495     {
       
  2496         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_GETTRANSFERAMOUNT,
       
  2497             (void *)data_p, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX,
       
  2498                 req_p, reply_p, CyAsStorageFuncCallback) ;
       
  2499 
       
  2500         if (ret != CY_AS_ERROR_SUCCESS)
       
  2501             goto destroy ;
       
  2502 
       
  2503         /* The request and response are freed as part of the FuncCallback */
       
  2504         return ret ;
       
  2505     }
       
  2506 
       
  2507 destroy:
       
  2508     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2509     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  2510 
       
  2511     return ret ;
       
  2512 
       
  2513 }
       
  2514 
       
  2515 CyAsReturnStatus_t
       
  2516 CyAsStorageErase(
       
  2517         CyAsDeviceHandle        handle,
       
  2518         CyAsBusNumber_t         bus,
       
  2519         uint32_t                device,
       
  2520         uint32_t                erase_unit,
       
  2521         uint16_t                num_erase_units,
       
  2522         CyAsFunctionCallback    cb,
       
  2523         uint32_t                client
       
  2524         )
       
  2525 {
       
  2526     CyAsLLRequestResponse *req_p, *reply_p ;
       
  2527     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  2528     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  2529 
       
  2530     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
  2531         return CY_AS_ERROR_INVALID_HANDLE ;
       
  2532 
       
  2533     ret = IsStorageActive(dev_p) ;
       
  2534     if (ret != CY_AS_ERROR_SUCCESS)
       
  2535         return ret ;
       
  2536 
       
  2537     if (bus < 0 || bus >= CY_AS_MAX_BUSES)
       
  2538         return CY_AS_ERROR_NO_SUCH_BUS ;
       
  2539 
       
  2540     if (device >= CY_AS_MAX_STORAGE_DEVICES)
       
  2541         return CY_AS_ERROR_NO_SUCH_DEVICE ;
       
  2542 
       
  2543     if (dev_p->storage_device_info[bus][device].block_size == 0)
       
  2544         return CY_AS_ERROR_QUERY_DEVICE_NEEDED ;
       
  2545 
       
  2546     /* If SD is not supported on the specified bus, then return ERROR */
       
  2547     if(dev_p->storage_device_info[bus][device].type != CyAsMediaSDFlash)
       
  2548         return CY_AS_ERROR_NOT_SUPPORTED;
       
  2549 
       
  2550     if (num_erase_units == 0)
       
  2551         return CY_AS_ERROR_SUCCESS ;
       
  2552 
       
  2553     /* Create the request to send to the West Bridge device */
       
  2554     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_ERASE, CY_RQT_STORAGE_RQT_CONTEXT, 5) ;
       
  2555     if (req_p == 0)
       
  2556     {
       
  2557         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2558     }
       
  2559 
       
  2560     /* Reserve space for the reply, the reply data will not exceed four words. */
       
  2561     reply_p = CyAsLLCreateResponse(dev_p, 4) ;
       
  2562     if (reply_p == 0)
       
  2563     {
       
  2564         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2565         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2566     }
       
  2567 
       
  2568     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, 0x00));
       
  2569     CyAsLLRequestResponse_SetWord(req_p, 1, (uint16_t)((erase_unit >> 16) & 0xffff)) ;
       
  2570     CyAsLLRequestResponse_SetWord(req_p, 2, (uint16_t)(erase_unit & 0xffff)) ;
       
  2571     CyAsLLRequestResponse_SetWord(req_p, 3, (uint16_t)((num_erase_units >> 8) & 0x00ff)) ;
       
  2572     CyAsLLRequestResponse_SetWord(req_p, 4, (uint16_t)((num_erase_units << 8) & 0xff00)) ;
       
  2573 
       
  2574     if(cb == 0)
       
  2575     {
       
  2576         ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  2577         if (ret != CY_AS_ERROR_SUCCESS)
       
  2578             goto destroy ;
       
  2579 
       
  2580         ret = MyHandleResponseNoData(dev_p, req_p, reply_p) ;
       
  2581 
       
  2582         /* If error = "invalid response", this (very likely) means that we are not using the SD-only firmware module
       
  2583         which is the only one supporting StorageErase. In this case force a "non supported" error code */
       
  2584         if (ret == CY_AS_ERROR_INVALID_RESPONSE)
       
  2585             ret = CY_AS_ERROR_NOT_SUPPORTED;
       
  2586 
       
  2587         return ret ;
       
  2588     }
       
  2589     else
       
  2590     {
       
  2591         ret = CyAsMiscSendRequest(dev_p, cb, client, CY_FUNCT_CB_STOR_ERASE,
       
  2592             0, dev_p->func_cbs_stor, CY_AS_REQUEST_RESPONSE_EX,
       
  2593                 req_p, reply_p, CyAsStorageFuncCallback) ;
       
  2594 
       
  2595         if (ret != CY_AS_ERROR_SUCCESS)
       
  2596             goto destroy ;
       
  2597 
       
  2598         /* The request and response are freed as part of the FuncCallback */
       
  2599         return ret ;
       
  2600     }
       
  2601 
       
  2602 destroy:
       
  2603     CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2604     CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  2605 
       
  2606     return ret ;
       
  2607 }
       
  2608 
       
  2609 static void
       
  2610 CyAsStorageFuncCallback(CyAsDevice *dev_p,
       
  2611                         uint8_t context,
       
  2612                         CyAsLLRequestResponse *rqt,
       
  2613                         CyAsLLRequestResponse *resp,
       
  2614                         CyAsReturnStatus_t stat)
       
  2615 {
       
  2616     CyAsFuncCBNode* node = (CyAsFuncCBNode*)dev_p->func_cbs_stor->head_p ;
       
  2617     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  2618 
       
  2619     CyBool              exRequest = (rqt->flags & CY_AS_REQUEST_RESPONSE_EX) == CY_AS_REQUEST_RESPONSE_EX ;
       
  2620     CyBool              msRequest = (rqt->flags & CY_AS_REQUEST_RESPONSE_MS) == CY_AS_REQUEST_RESPONSE_MS ;
       
  2621     uint8_t             code ;
       
  2622     uint8_t             cntxt ;
       
  2623 
       
  2624     CyAsHalAssert(exRequest || msRequest) ;
       
  2625     CyAsHalAssert(dev_p->func_cbs_stor->count != 0) ;
       
  2626     CyAsHalAssert(dev_p->func_cbs_stor->type == CYAS_FUNC_CB) ;
       
  2627     (void) exRequest;
       
  2628     (void) msRequest;
       
  2629 
       
  2630     (void)context ;
       
  2631 
       
  2632     cntxt = CyAsLLRequestResponse_GetContext(rqt) ;
       
  2633     CyAsHalAssert(cntxt == CY_RQT_STORAGE_RQT_CONTEXT) ;
       
  2634 
       
  2635     code = CyAsLLRequestResponse_GetCode(rqt) ;
       
  2636     switch(code)
       
  2637     {
       
  2638     case CY_RQT_START_STORAGE:
       
  2639         ret = MyHandleResponseStorageStart(dev_p, rqt, resp, stat) ;
       
  2640         break ;
       
  2641     case CY_RQT_STOP_STORAGE:
       
  2642         ret = MyHandleResponseStorageStop(dev_p, rqt, resp, stat) ;
       
  2643         break ;
       
  2644     case CY_RQT_CLAIM_STORAGE:
       
  2645         ret = MyHandleResponseStorageClaim(dev_p, rqt, resp) ;
       
  2646         break ;
       
  2647     case CY_RQT_RELEASE_STORAGE:
       
  2648         ret = MyHandleResponseStorageRelease(dev_p, rqt, resp) ;
       
  2649         break ;
       
  2650     case CY_RQT_QUERY_MEDIA:
       
  2651         CyAsHalAssert(CyFalse) ;        /* Not used any more. */
       
  2652         break ;
       
  2653     case CY_RQT_QUERY_BUS:
       
  2654         CyAsHalAssert(node->data != 0) ;
       
  2655         ret = MyHandleResponseStorageQueryBus(dev_p, rqt, resp, (uint32_t*)node->data) ;
       
  2656         break ;
       
  2657     case CY_RQT_QUERY_DEVICE:
       
  2658         CyAsHalAssert(node->data != 0) ;
       
  2659         ret = MyHandleResponseStorageQueryDevice(dev_p, rqt, resp, node->data) ;
       
  2660         break ;
       
  2661     case CY_RQT_QUERY_UNIT:
       
  2662         CyAsHalAssert(node->data != 0) ;
       
  2663         ret = MyHandleResponseStorageQueryUnit(dev_p, rqt, resp, node->data) ;
       
  2664         break ;
       
  2665     case CY_RQT_SD_INTERFACE_CONTROL:
       
  2666         ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
       
  2667         break ;
       
  2668     case CY_RQT_SD_REGISTER_READ:
       
  2669         CyAsHalAssert(node->data != 0) ;
       
  2670         ret = MyHandleResponseSDRegRead(dev_p, rqt, resp, (CyAsStorageSDRegReadData *)node->data) ;
       
  2671         break ;
       
  2672     case CY_RQT_PARTITION_STORAGE:
       
  2673         ret = MyHandleResponseNoData(dev_p, rqt, resp);
       
  2674         break ;
       
  2675     case CY_RQT_PARTITION_ERASE:
       
  2676         ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
       
  2677         break ;
       
  2678     case CY_RQT_GET_TRANSFER_AMOUNT:
       
  2679         CyAsHalAssert(node->data != 0) ;
       
  2680         ret = MyHandleResponseGetTransferAmount(dev_p, rqt, resp, (CyAsMSCProgressData *)node->data) ;
       
  2681         break ;
       
  2682     case CY_RQT_ERASE:
       
  2683         ret = MyHandleResponseNoData(dev_p, rqt, resp) ;
       
  2684 
       
  2685         /* If error = "invalid response", this (very likely) means that we are not using the SD-only firmware module
       
  2686         which is the only one supporting StorageErase. In this case force a "non supported" error code */
       
  2687         if (ret == CY_AS_ERROR_INVALID_RESPONSE)
       
  2688             ret = CY_AS_ERROR_NOT_SUPPORTED;
       
  2689 
       
  2690         break ;
       
  2691 
       
  2692     default:
       
  2693         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  2694         CyAsHalAssert(CyFalse) ;
       
  2695         break ;
       
  2696     }
       
  2697 
       
  2698     /*
       
  2699      * If the low level layer returns a direct error, use the corresponding error code.
       
  2700      * If not, use the error code based on the response from firmware.
       
  2701      */
       
  2702     if (stat == CY_AS_ERROR_SUCCESS)
       
  2703         stat = ret ;
       
  2704 
       
  2705     /* Call the user callback, if there is one */
       
  2706     if (node->cb_p)
       
  2707         node->cb_p((CyAsDeviceHandle)dev_p, stat, node->client_data, (CyAsFunctCBType)node->dataType, node->data) ;
       
  2708     CyAsRemoveCBNode(dev_p->func_cbs_stor) ;
       
  2709 }
       
  2710 
       
  2711 
       
  2712 static void
       
  2713 CyAsSdioSyncReplyCallback(
       
  2714         CyAsDevice *dev_p,
       
  2715         uint8_t context,
       
  2716         CyAsLLRequestResponse *rqt,
       
  2717         CyAsLLRequestResponse *resp,
       
  2718         CyAsReturnStatus_t ret)
       
  2719 {
       
  2720     (void)rqt ;
       
  2721 
       
  2722     if ((CyAsLLRequestResponse_GetCode(resp) == CY_RESP_SDIO_GET_TUPLE )||
       
  2723             (CyAsLLRequestResponse_GetCode(resp) == CY_RESP_SDIO_EXT))
       
  2724     {
       
  2725         ret = CyAsLLRequestResponse_GetWord(resp, 0) ;
       
  2726         if ((ret & 0x00FF) != CY_AS_ERROR_SUCCESS)
       
  2727         {
       
  2728             if(CyAsLLRequestResponse_GetCode(rqt) == CY_RQT_SDIO_READ_EXTENDED)
       
  2729                 CyAsDmaCancel(dev_p, dev_p->storage_read_endpoint, ret) ;
       
  2730             else
       
  2731                 CyAsDmaCancel(dev_p, dev_p->storage_write_endpoint, ret) ;
       
  2732         }
       
  2733     }
       
  2734     else
       
  2735     {
       
  2736         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  2737     }
       
  2738 
       
  2739     dev_p->storage_rw_resp_p=resp;
       
  2740     dev_p->storage_wait = CyFalse ;
       
  2741     if(((ret & 0x00FF) == CY_AS_ERROR_IO_ABORTED) || ((ret & 0x00FF) == CY_AS_ERROR_IO_SUSPENDED))
       
  2742         dev_p->storage_error =  (ret & 0x00FF);
       
  2743     else
       
  2744         dev_p->storage_error = (ret & 0x00FF)? CY_AS_ERROR_INVALID_RESPONSE : CY_AS_ERROR_SUCCESS ;
       
  2745 
       
  2746     /* Wake any threads/processes that are waiting on the read/write completion. */
       
  2747     CyAsHalWake (&dev_p->context[context]->channel);
       
  2748 }
       
  2749 
       
  2750 CyAsReturnStatus_t
       
  2751 CyAsSdioDeviceCheck(
       
  2752         CyAsDevice*         dev_p,
       
  2753         CyAsBusNumber_t     bus,
       
  2754         uint32_t            device)
       
  2755 {
       
  2756     if (!dev_p ||(dev_p->sig != CY_AS_DEVICE_HANDLE_SIGNATURE))
       
  2757         return CY_AS_ERROR_INVALID_HANDLE ;
       
  2758 
       
  2759     if (bus < 0 || bus >= CY_AS_MAX_BUSES)
       
  2760         return CY_AS_ERROR_NO_SUCH_BUS ;
       
  2761 
       
  2762     if (device >= CY_AS_MAX_STORAGE_DEVICES)
       
  2763         return CY_AS_ERROR_NO_SUCH_DEVICE ;
       
  2764 
       
  2765     if (!CyAsDeviceIsAstoriaDev(dev_p))
       
  2766         return CY_AS_ERROR_NOT_SUPPORTED ;
       
  2767 
       
  2768     return  (IsStorageActive(dev_p)) ;
       
  2769 }
       
  2770 
       
  2771 CyAsReturnStatus_t
       
  2772 CyAsSdioDirectIo(
       
  2773         CyAsDeviceHandle    handle,
       
  2774         CyAsBusNumber_t     bus,
       
  2775         uint32_t            device,
       
  2776         uint8_t             nFunctionNo,
       
  2777         uint32_t            address,
       
  2778         uint8_t             miscBuf,
       
  2779         uint16_t            argument,
       
  2780         uint8_t             isWrite,
       
  2781         uint8_t *           data_p )
       
  2782 {
       
  2783     CyAsLLRequestResponse *req_p , *reply_p ;
       
  2784     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  2785     uint16_t resp_data;
       
  2786 
       
  2787     /*
       
  2788      * Sanity checks required before sending the request to the
       
  2789      * firmware.
       
  2790      */
       
  2791     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  2792     ret = CyAsSdioDeviceCheck(dev_p,bus,device);
       
  2793     if( ret != CY_AS_ERROR_SUCCESS )
       
  2794         return ret;
       
  2795 
       
  2796 
       
  2797     if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo)))
       
  2798         return CY_AS_ERROR_INVALID_FUNCTION;
       
  2799     if(CyAsSdioCheckFunctionSuspended(handle,bus,nFunctionNo))
       
  2800         return CY_AS_ERROR_FUNCTION_SUSPENDED;
       
  2801 
       
  2802     req_p = CyAsLLCreateRequest(dev_p, (isWrite==CyTrue)?CY_RQT_SDIO_WRITE_DIRECT:CY_RQT_SDIO_READ_DIRECT,
       
  2803             CY_RQT_STORAGE_RQT_CONTEXT, 3) ;
       
  2804     if (req_p == 0)
       
  2805         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2806 
       
  2807     /*Setting up request*/
       
  2808 
       
  2809     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo) ) ;
       
  2810     /* D1 */
       
  2811     if(isWrite==CyTrue)
       
  2812     {
       
  2813         CyAsLLRequestResponse_SetWord(req_p, 1,  ((argument<<8)|0x0080|(nFunctionNo<<4)|
       
  2814                     ((miscBuf&CY_SDIO_RAW)<<3)|((miscBuf&CY_SDIO_REARM_INT)>>5)|(uint16_t)(address>>15)));
       
  2815     }
       
  2816     else
       
  2817     {
       
  2818         CyAsLLRequestResponse_SetWord(req_p, 1,  (nFunctionNo<<4)|((miscBuf&CY_SDIO_REARM_INT)>>5)|
       
  2819                 (uint16_t)(address>>15));
       
  2820     }
       
  2821     /* D2 */
       
  2822     CyAsLLRequestResponse_SetWord(req_p, 2,  ((uint16_t)((address&0x00007fff)<<1))) ;
       
  2823 
       
  2824     /*Create response*/
       
  2825     reply_p = CyAsLLCreateResponse(dev_p, 2) ;
       
  2826 
       
  2827     if (reply_p == 0)
       
  2828     {
       
  2829         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2830         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  2831     }
       
  2832 
       
  2833     /*Sending the request*/
       
  2834     ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  2835     if (ret != CY_AS_ERROR_SUCCESS)
       
  2836         goto destroy ;
       
  2837 
       
  2838     /*Check reply type*/
       
  2839     if ( CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_SDIO_DIRECT)
       
  2840     {
       
  2841         resp_data = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  2842         if(resp_data>>8)
       
  2843         {
       
  2844             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  2845         }
       
  2846         else if (data_p!=0)
       
  2847             *(uint8_t*)(data_p)=(uint8_t)(resp_data&0x00ff);
       
  2848     }
       
  2849     else
       
  2850     {
       
  2851         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  2852     }
       
  2853 
       
  2854 destroy:
       
  2855     if(req_p!=0)
       
  2856         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  2857     if(reply_p!=0)
       
  2858         CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  2859     return ret ;
       
  2860 }
       
  2861 
       
  2862 
       
  2863 CyAsReturnStatus_t
       
  2864 CyAsSdioDirectRead(
       
  2865         CyAsDeviceHandle        handle,
       
  2866         CyAsBusNumber_t         bus,
       
  2867         uint32_t                device,
       
  2868         uint8_t                 nFunctionNo,
       
  2869         uint32_t                address,
       
  2870         uint8_t                 miscBuf,
       
  2871         uint8_t *               data_p)
       
  2872 {
       
  2873     return (CyAsSdioDirectIo(handle,bus,device, nFunctionNo, address, miscBuf, 0x00, CyFalse, data_p));
       
  2874 }
       
  2875 
       
  2876 CyAsReturnStatus_t
       
  2877 CyAsSdioDirectWrite(
       
  2878         CyAsDeviceHandle        handle,
       
  2879         CyAsBusNumber_t         bus,
       
  2880         uint32_t                device,
       
  2881         uint8_t                 nFunctionNo,
       
  2882         uint32_t                address,
       
  2883         uint8_t                 miscBuf,
       
  2884         uint16_t                argument,
       
  2885         uint8_t *               data_p)
       
  2886 {
       
  2887     return (CyAsSdioDirectIo(handle,bus,device, nFunctionNo, address, miscBuf, argument, CyTrue, data_p));
       
  2888 }
       
  2889 
       
  2890 /*Cmd53 IO*/
       
  2891 CyAsReturnStatus_t
       
  2892 CyAsSdioExtendedIO(
       
  2893         CyAsDeviceHandle        handle,
       
  2894         CyAsBusNumber_t         bus,
       
  2895         uint32_t                device,
       
  2896         uint8_t                 nFunctionNo,
       
  2897         uint32_t                address,
       
  2898         uint8_t                 miscBuf,
       
  2899         uint16_t                argument,
       
  2900         uint8_t                 isWrite,
       
  2901         uint8_t *               data_p ,
       
  2902         uint8_t                 isResume)
       
  2903 {
       
  2904     CyAsLLRequestResponse *req_p , *reply_p ;
       
  2905     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  2906     uint8_t resp_type;
       
  2907     uint8_t reqtype;
       
  2908     uint16_t resp_data;
       
  2909     CyAsContext *ctxt_p ;
       
  2910     uint32_t  dmasize,loopcount = 200;
       
  2911     CyAsEndPointNumber_t ep;
       
  2912 
       
  2913     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  2914     ret = CyAsSdioDeviceCheck(dev_p,bus,device);
       
  2915     if( ret != CY_AS_ERROR_SUCCESS )
       
  2916         return ret;
       
  2917 
       
  2918 
       
  2919     if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo)))
       
  2920         return CY_AS_ERROR_INVALID_FUNCTION;
       
  2921     if(CyAsSdioCheckFunctionSuspended(handle,bus,nFunctionNo))
       
  2922         return CY_AS_ERROR_FUNCTION_SUSPENDED;
       
  2923 
       
  2924 
       
  2925     if ((CyAsDeviceIsStorageAsyncPending(dev_p)) || (dev_p->storage_wait))
       
  2926         return CY_AS_ERROR_ASYNC_PENDING ;
       
  2927 
       
  2928     /* Request for 0 bytes of blocks is returned as a success*/
       
  2929     if(argument == 0)
       
  2930         return CY_AS_ERROR_SUCCESS;
       
  2931 
       
  2932     /* Initialise the request to send to the West Bridge device. */
       
  2933     if(isWrite == CyTrue)
       
  2934     {
       
  2935         reqtype =CY_RQT_SDIO_WRITE_EXTENDED;
       
  2936         ep=dev_p->storage_write_endpoint;
       
  2937     }
       
  2938     else
       
  2939     {
       
  2940         reqtype=CY_RQT_SDIO_READ_EXTENDED;
       
  2941         ep=dev_p->storage_read_endpoint;
       
  2942     }
       
  2943 
       
  2944     req_p = dev_p->storage_rw_req_p ;
       
  2945     CyAsLLInitRequest(req_p, reqtype, CY_RQT_STORAGE_RQT_CONTEXT, 3) ;
       
  2946 
       
  2947     /* Initialise the space for reply from the Antioch. */
       
  2948     reply_p = dev_p->storage_rw_resp_p ;
       
  2949     CyAsLLInitResponse(reply_p, 2) ;
       
  2950 
       
  2951     /* Setup the DMA request */
       
  2952     if(!(miscBuf&CY_SDIO_BLOCKMODE))
       
  2953     {
       
  2954         if(argument > dev_p->sdiocard[bus].function[nFunctionNo-1].blocksize)
       
  2955             return CY_AS_ERROR_INVALID_BLOCKSIZE;
       
  2956 
       
  2957     }
       
  2958     else
       
  2959     {
       
  2960         if( argument > 511)
       
  2961         {
       
  2962             return CY_AS_ERROR_INVALID_BLOCKSIZE;
       
  2963         }
       
  2964     }
       
  2965 
       
  2966     if(argument == 512)
       
  2967         argument =0;
       
  2968 
       
  2969     dmasize=((miscBuf&CY_SDIO_BLOCKMODE) !=0)? dev_p->sdiocard[bus].function[nFunctionNo-1].blocksize*argument:argument;
       
  2970 
       
  2971     ret = CyAsDmaQueueRequest(dev_p, ep, (void*)(data_p), dmasize, CyFalse,
       
  2972             (isWrite & CyTrue)?CyFalse:CyTrue, CyAsSyncStorageCallback) ;
       
  2973 
       
  2974     if (ret != CY_AS_ERROR_SUCCESS)
       
  2975     {
       
  2976         return ret ;
       
  2977     }
       
  2978 
       
  2979     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo|((isResume)?0x80:0x00) )) ;
       
  2980     CyAsLLRequestResponse_SetWord(req_p, 1, ((uint16_t)nFunctionNo)<<12|
       
  2981             ((uint16_t)(miscBuf&(CY_SDIO_BLOCKMODE|CY_SDIO_OP_INCR)))<<9|
       
  2982             (uint16_t)(address>>7)|((isWrite==CyTrue)?0x8000:0x0000 )) ;
       
  2983     CyAsLLRequestResponse_SetWord(req_p, 2, ((uint16_t)(address&0x0000ffff)<<9) |  argument) ;
       
  2984 
       
  2985 
       
  2986     /* Send the request and wait for completion of storage request */
       
  2987     dev_p->storage_wait = CyTrue ;
       
  2988     ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyTrue, CyAsSdioSyncReplyCallback) ;
       
  2989 
       
  2990     if (ret != CY_AS_ERROR_SUCCESS)
       
  2991     {
       
  2992         CyAsDmaCancel(dev_p, ep, CY_AS_ERROR_CANCELED) ;
       
  2993     }
       
  2994     else
       
  2995     {
       
  2996         /* Setup the DMA request */
       
  2997         ctxt_p = dev_p->context[CY_RQT_STORAGE_RQT_CONTEXT] ;
       
  2998         ret = CyAsDmaDrainQueue(dev_p, ep, CyTrue) ;
       
  2999 
       
  3000         while (loopcount-- > 0)
       
  3001         {
       
  3002             if (dev_p->storage_wait == CyFalse)
       
  3003                 break;
       
  3004             CyAsHalSleepOn(&ctxt_p->channel, 10) ;
       
  3005         }
       
  3006         if (dev_p->storage_wait == CyTrue)
       
  3007         {
       
  3008             dev_p->storage_wait = CyFalse ;
       
  3009             CyAsLLRemoveRequest(dev_p, ctxt_p, req_p, CyTrue) ;
       
  3010             dev_p->storage_error = CY_AS_ERROR_TIMEOUT ;
       
  3011         }
       
  3012 
       
  3013         ret=dev_p->storage_error;
       
  3014 
       
  3015         if (ret != CY_AS_ERROR_SUCCESS)
       
  3016         {
       
  3017             return ret ;
       
  3018         }
       
  3019 
       
  3020 
       
  3021         resp_type = CyAsLLRequestResponse_GetCode(dev_p->storage_rw_resp_p) ;
       
  3022         if (resp_type == CY_RESP_SDIO_EXT)
       
  3023         {
       
  3024             resp_data = CyAsLLRequestResponse_GetWord(reply_p, 0)&0x00ff ;
       
  3025             if(resp_data)
       
  3026             {
       
  3027                 ret = CY_AS_ERROR_INVALID_REQUEST ;
       
  3028             }
       
  3029 
       
  3030         }
       
  3031         else
       
  3032         {
       
  3033             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  3034         }
       
  3035     }
       
  3036     return ret;
       
  3037 
       
  3038 }
       
  3039 
       
  3040 static void
       
  3041 CyAsSdioAsyncReplyCallback(
       
  3042         CyAsDevice*             dev_p,
       
  3043         uint8_t                 context,
       
  3044         CyAsLLRequestResponse*  rqt,
       
  3045         CyAsLLRequestResponse*  resp,
       
  3046         CyAsReturnStatus_t      ret )
       
  3047 {
       
  3048     CyAsStorageCallback cb_ms ;
       
  3049     uint8_t reqtype ;
       
  3050     uint32_t pendingblocks;
       
  3051     (void)rqt ;
       
  3052     (void)context ;
       
  3053 
       
  3054     pendingblocks = 0;
       
  3055     reqtype = CyAsLLRequestResponse_GetCode(rqt) ;
       
  3056     if (ret == CY_AS_ERROR_SUCCESS)
       
  3057     {
       
  3058         if ((CyAsLLRequestResponse_GetCode(resp) == CY_RESP_SUCCESS_FAILURE) ||
       
  3059                 (CyAsLLRequestResponse_GetCode(resp) == CY_RESP_SDIO_EXT))
       
  3060         {
       
  3061             ret = CyAsLLRequestResponse_GetWord(resp, 0) ;
       
  3062             ret &= 0x00FF ;
       
  3063         }
       
  3064         else
       
  3065         {
       
  3066             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  3067         }
       
  3068     }
       
  3069 
       
  3070     if (ret != CY_AS_ERROR_SUCCESS)
       
  3071     {
       
  3072         if(reqtype == CY_RQT_SDIO_READ_EXTENDED)
       
  3073             CyAsDmaCancel(dev_p, dev_p->storage_read_endpoint, ret) ;
       
  3074         else
       
  3075             CyAsDmaCancel(dev_p, dev_p->storage_write_endpoint, ret) ;
       
  3076 
       
  3077         dev_p->storage_error = ret;
       
  3078     }
       
  3079 
       
  3080 
       
  3081 
       
  3082     dev_p->storage_wait = CyFalse ;
       
  3083 
       
  3084     /*
       
  3085      * If the DMA callback has already been called, the user callback
       
  3086      * has to be called from here.
       
  3087      */
       
  3088     if (!CyAsDeviceIsStorageAsyncPending(dev_p))
       
  3089     {
       
  3090         CyAsHalAssert(dev_p->storage_cb_ms != NULL) ;
       
  3091         cb_ms = dev_p->storage_cb_ms ;
       
  3092 
       
  3093         dev_p->storage_cb = 0 ;
       
  3094         dev_p->storage_cb_ms = 0 ;
       
  3095 
       
  3096         if ((ret == CY_AS_ERROR_SUCCESS) || (ret == CY_AS_ERROR_IO_ABORTED) || (ret == CY_AS_ERROR_IO_SUSPENDED))
       
  3097         {
       
  3098             ret = dev_p->storage_error ;
       
  3099             pendingblocks = ((uint32_t)CyAsLLRequestResponse_GetWord(resp, 1))<<16;
       
  3100         }
       
  3101         else
       
  3102             ret = CY_AS_ERROR_INVALID_RESPONSE;
       
  3103 
       
  3104         cb_ms((CyAsDeviceHandle)dev_p, dev_p->storage_bus_index, dev_p->storage_device_index,
       
  3105                 (dev_p->storage_unit | pendingblocks), dev_p->storage_block_addr, dev_p->storage_oper, ret) ;
       
  3106     }
       
  3107     else
       
  3108         dev_p->storage_error = ret ;
       
  3109 }
       
  3110 
       
  3111 
       
  3112 CyAsReturnStatus_t
       
  3113 CyAsSdioExtendedIOAsync(
       
  3114         CyAsDeviceHandle            handle,
       
  3115         CyAsBusNumber_t             bus,
       
  3116         uint32_t                    device,
       
  3117         uint8_t                     nFunctionNo,
       
  3118         uint32_t                    address,
       
  3119         uint8_t                     miscBuf,
       
  3120         uint16_t                    argument,
       
  3121         uint8_t                     isWrite,
       
  3122         uint8_t *                   data_p,
       
  3123         CyAsStorageCallback       callback )
       
  3124 {
       
  3125 
       
  3126     uint32_t mask ;
       
  3127     uint32_t dmasize;
       
  3128     CyAsLLRequestResponse *req_p , *reply_p ;
       
  3129     uint8_t reqtype;
       
  3130     CyAsEndPointNumber_t ep;
       
  3131     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  3132     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  3133 
       
  3134     ret = CyAsSdioDeviceCheck(dev_p,bus,device);
       
  3135     if( ret != CY_AS_ERROR_SUCCESS )
       
  3136         return ret;
       
  3137 
       
  3138     if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo)))
       
  3139         return CY_AS_ERROR_INVALID_FUNCTION;
       
  3140     if(CyAsSdioCheckFunctionSuspended(handle,bus,nFunctionNo))
       
  3141         return CY_AS_ERROR_FUNCTION_SUSPENDED;
       
  3142 
       
  3143     if (callback == 0)
       
  3144         return CY_AS_ERROR_NULL_CALLBACK ;
       
  3145 
       
  3146     /* We are supposed to return sucess if the number of
       
  3147      * blocks is zero
       
  3148      */
       
  3149     if(((miscBuf&CY_SDIO_BLOCKMODE)!=0)&&(argument==0))
       
  3150     {
       
  3151         callback(handle, bus, device,nFunctionNo,address,((isWrite) ? CyAsOpWrite : CyAsOpRead), CY_AS_ERROR_SUCCESS) ;
       
  3152         return CY_AS_ERROR_SUCCESS ;
       
  3153     }
       
  3154 
       
  3155 
       
  3156     /*
       
  3157      * Since async operations can be triggered by interrupt code, we must
       
  3158      * insure that we do not get multiple async operations going at one time and
       
  3159      * protect this test and set operation from interrupts.
       
  3160      */
       
  3161     mask = CyAsHalDisableInterrupts() ;
       
  3162     if ((CyAsDeviceIsStorageAsyncPending(dev_p)) || (dev_p->storage_wait))
       
  3163     {
       
  3164         CyAsHalEnableInterrupts(mask) ;
       
  3165         return CY_AS_ERROR_ASYNC_PENDING ;
       
  3166     }
       
  3167     CyAsDeviceSetStorageAsyncPending(dev_p) ;
       
  3168     CyAsHalEnableInterrupts(mask) ;
       
  3169 
       
  3170 
       
  3171     /*
       
  3172      * Storage information about the currently outstanding request
       
  3173      */
       
  3174     dev_p->storage_cb_ms = callback ;
       
  3175     dev_p->storage_bus_index = bus ;
       
  3176     dev_p->storage_device_index = device ;
       
  3177     dev_p->storage_unit = nFunctionNo ;
       
  3178     dev_p->storage_block_addr = address ;
       
  3179 
       
  3180     if(isWrite == CyTrue)
       
  3181     {
       
  3182         reqtype =CY_RQT_SDIO_WRITE_EXTENDED;
       
  3183         ep=dev_p->storage_write_endpoint;
       
  3184     }
       
  3185     else
       
  3186     {
       
  3187         reqtype=CY_RQT_SDIO_READ_EXTENDED;
       
  3188         ep=dev_p->storage_read_endpoint;
       
  3189     }
       
  3190 
       
  3191     /* Initialise the request to send to the West Bridge. */
       
  3192     req_p = dev_p->storage_rw_req_p ;
       
  3193     CyAsLLInitRequest(req_p, reqtype, CY_RQT_STORAGE_RQT_CONTEXT, 3) ;
       
  3194 
       
  3195     /* Initialise the space for reply from the West Bridge. */
       
  3196     reply_p = dev_p->storage_rw_resp_p ;
       
  3197     CyAsLLInitResponse(reply_p, 2) ;
       
  3198 
       
  3199     if(!(miscBuf&CY_SDIO_BLOCKMODE))
       
  3200     {
       
  3201         if(argument > dev_p->sdiocard[bus].function[nFunctionNo-1].blocksize)
       
  3202             return CY_AS_ERROR_INVALID_BLOCKSIZE;
       
  3203 
       
  3204     }
       
  3205     else
       
  3206     {
       
  3207         if( argument > 511)
       
  3208         {
       
  3209             return CY_AS_ERROR_INVALID_BLOCKSIZE;
       
  3210         }
       
  3211     }
       
  3212 
       
  3213     if(argument == 512)
       
  3214         argument =0;
       
  3215     dmasize=((miscBuf&CY_SDIO_BLOCKMODE) !=0)? dev_p->sdiocard[bus].function[nFunctionNo-1].blocksize*argument:argument;
       
  3216 
       
  3217     /* Setup the DMA request and adjust the storage operation if we are reading */
       
  3218     if (reqtype == CY_RQT_SDIO_READ_EXTENDED)
       
  3219     {
       
  3220         ret = CyAsDmaQueueRequest(dev_p, ep, (void*)data_p,dmasize , CyFalse, CyTrue,CyAsAsyncStorageCallback) ;
       
  3221         dev_p->storage_oper = CyAsOpRead ;
       
  3222     }
       
  3223     else if (reqtype == CY_RQT_SDIO_WRITE_EXTENDED)
       
  3224     {
       
  3225         ret = CyAsDmaQueueRequest(dev_p, ep, (void*)data_p, dmasize, CyFalse, CyFalse,CyAsAsyncStorageCallback) ;
       
  3226         dev_p->storage_oper = CyAsOpWrite ;
       
  3227     }
       
  3228     if (ret != CY_AS_ERROR_SUCCESS)
       
  3229     {
       
  3230         CyAsDeviceClearStorageAsyncPending(dev_p) ;
       
  3231         return ret ;
       
  3232     }
       
  3233 
       
  3234     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo )) ;
       
  3235     CyAsLLRequestResponse_SetWord(req_p, 1, ((uint16_t)nFunctionNo)<<12|
       
  3236             ((uint16_t)(miscBuf&(CY_SDIO_BLOCKMODE|CY_SDIO_OP_INCR)))<<9|
       
  3237             (uint16_t)(address>>7)|((isWrite==CyTrue)?0x8000:0x0000 )) ;
       
  3238     CyAsLLRequestResponse_SetWord(req_p, 2, ((uint16_t)(address&0x0000ffff)<<9) |  argument) ;
       
  3239 
       
  3240 
       
  3241     /* Send the request and wait for completion of storage request */
       
  3242     dev_p->storage_wait = CyTrue ;
       
  3243     ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyTrue, CyAsSdioAsyncReplyCallback) ;
       
  3244     if (ret != CY_AS_ERROR_SUCCESS)
       
  3245     {
       
  3246         CyAsDmaCancel(dev_p, ep, CY_AS_ERROR_CANCELED) ;
       
  3247         CyAsDeviceClearStorageAsyncPending(dev_p) ;
       
  3248     }
       
  3249     else
       
  3250     {
       
  3251         CyAsDmaKickStart(dev_p, ep) ;
       
  3252     }
       
  3253 
       
  3254     return ret ;
       
  3255 }
       
  3256 
       
  3257 /* CMD53 Extended Read*/
       
  3258 CyAsReturnStatus_t
       
  3259 CyAsSdioExtendedRead(
       
  3260         CyAsDeviceHandle            handle,
       
  3261         CyAsBusNumber_t             bus,
       
  3262         uint32_t                    device,
       
  3263         uint8_t                     nFunctionNo,
       
  3264         uint32_t                    address,
       
  3265         uint8_t                     miscBuf,
       
  3266         uint16_t                    argument,
       
  3267         uint8_t *                   data_p,
       
  3268         CyAsSdioCallback            callback )
       
  3269 {
       
  3270     if (callback==0)
       
  3271         return CyAsSdioExtendedIO(handle,bus,device,nFunctionNo,address,miscBuf,argument,CyFalse,data_p,0);
       
  3272 
       
  3273     return CyAsSdioExtendedIOAsync(handle,bus,device,nFunctionNo,address,miscBuf,argument,CyFalse,data_p,callback);
       
  3274 }
       
  3275 
       
  3276 /* CMD53 Extended Write*/
       
  3277 CyAsReturnStatus_t
       
  3278 CyAsSdioExtendedWrite(
       
  3279         CyAsDeviceHandle            handle,
       
  3280         CyAsBusNumber_t             bus,
       
  3281         uint32_t                    device,
       
  3282         uint8_t                     nFunctionNo,
       
  3283         uint32_t                    address,
       
  3284         uint8_t                     miscBuf,
       
  3285         uint16_t                    argument,
       
  3286         uint8_t *                   data_p,
       
  3287         CyAsSdioCallback            callback )
       
  3288 {
       
  3289     if (callback==0)
       
  3290         return CyAsSdioExtendedIO(handle,bus,device,nFunctionNo,address,miscBuf,argument,CyTrue,data_p,0);
       
  3291 
       
  3292     return CyAsSdioExtendedIOAsync(handle,bus,device,nFunctionNo,address,miscBuf,argument,CyTrue,data_p,callback);
       
  3293 }
       
  3294 
       
  3295 
       
  3296 /* Read the CIS info tuples for the given function and Tuple ID*/
       
  3297 CyAsReturnStatus_t
       
  3298 CyAsSdioGetCISInfo(
       
  3299         CyAsDeviceHandle            handle,
       
  3300         CyAsBusNumber_t             bus,
       
  3301         uint32_t                    device,
       
  3302         uint8_t                     nFunctionNo,
       
  3303         uint16_t                    tupleId,
       
  3304         uint8_t *                   data_p )
       
  3305 {
       
  3306 
       
  3307     CyAsLLRequestResponse *req_p , *reply_p ;
       
  3308     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  3309     uint16_t resp_data;
       
  3310     CyAsContext *ctxt_p ;
       
  3311     uint32_t loopcount = 200;
       
  3312 
       
  3313     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  3314 
       
  3315     ret = CyAsSdioDeviceCheck(dev_p,bus,device);
       
  3316     if( ret != CY_AS_ERROR_SUCCESS )
       
  3317         return ret;
       
  3318 
       
  3319     if(!( CyAsSdioCheckFunctionInitialized(handle,bus,0) ))
       
  3320         return CY_AS_ERROR_INVALID_FUNCTION;
       
  3321 
       
  3322     if ((CyAsDeviceIsStorageAsyncPending(dev_p)) || (dev_p->storage_wait))
       
  3323         return CY_AS_ERROR_ASYNC_PENDING ;
       
  3324 
       
  3325 
       
  3326     /* Initialise the request to send to the Antioch. */
       
  3327     req_p = dev_p->storage_rw_req_p ;
       
  3328     CyAsLLInitRequest(req_p, CY_RQT_SDIO_GET_TUPLE, CY_RQT_STORAGE_RQT_CONTEXT, 2) ;
       
  3329 
       
  3330     /* Initialise the space for reply from the Antioch. */
       
  3331     reply_p = dev_p->storage_rw_resp_p ;
       
  3332     CyAsLLInitResponse(reply_p, 3) ;
       
  3333 
       
  3334     /* Setup the DMA request */
       
  3335     ret = CyAsDmaQueueRequest(dev_p, dev_p->storage_read_endpoint, data_p+1, 255, CyFalse, CyTrue,
       
  3336             CyAsSyncStorageCallback) ;
       
  3337 
       
  3338     if (ret != CY_AS_ERROR_SUCCESS)
       
  3339     {
       
  3340         return ret ;
       
  3341     }
       
  3342 
       
  3343     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo )) ;
       
  3344 
       
  3345     /* Set tuple id to fetch. */
       
  3346     CyAsLLRequestResponse_SetWord(req_p, 1, tupleId<<8) ;
       
  3347 
       
  3348     /* Send the request and wait for completion of storage request */
       
  3349     dev_p->storage_wait = CyTrue ;
       
  3350     ret = CyAsLLSendRequest(dev_p, req_p, reply_p, CyTrue, CyAsSdioSyncReplyCallback) ;
       
  3351 
       
  3352 
       
  3353     if (ret != CY_AS_ERROR_SUCCESS)
       
  3354     {
       
  3355         CyAsDmaCancel(dev_p, dev_p->storage_read_endpoint, CY_AS_ERROR_CANCELED) ;
       
  3356     }
       
  3357     else
       
  3358     {
       
  3359         /* Setup the DMA request */
       
  3360         ctxt_p = dev_p->context[CY_RQT_STORAGE_RQT_CONTEXT] ;
       
  3361         ret = CyAsDmaDrainQueue(dev_p, dev_p->storage_read_endpoint, CyTrue) ;
       
  3362 
       
  3363         while (loopcount-- > 0)
       
  3364         {
       
  3365             if (dev_p->storage_wait == CyFalse)
       
  3366                 break;
       
  3367             CyAsHalSleepOn(&ctxt_p->channel, 10) ;
       
  3368         }
       
  3369 
       
  3370         if (dev_p->storage_wait == CyTrue)
       
  3371         {
       
  3372             dev_p->storage_wait = CyFalse ;
       
  3373             CyAsLLRemoveRequest(dev_p, ctxt_p, req_p, CyTrue) ;
       
  3374             return CY_AS_ERROR_TIMEOUT ;
       
  3375         }
       
  3376         ret = dev_p->storage_error ;
       
  3377 
       
  3378         if (ret != CY_AS_ERROR_SUCCESS)
       
  3379         {
       
  3380             return ret ;
       
  3381         }
       
  3382 
       
  3383         if ( CyAsLLRequestResponse_GetCode(dev_p->storage_rw_resp_p) == CY_RESP_SDIO_GET_TUPLE)
       
  3384         {
       
  3385             resp_data = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  3386             if(resp_data)
       
  3387             {
       
  3388                 ret = CY_AS_ERROR_INVALID_REQUEST ;
       
  3389             }
       
  3390             else if (data_p!=0)
       
  3391                 *(uint8_t*)data_p=(uint8_t)(CyAsLLRequestResponse_GetWord(reply_p, 0)&0x00ff);
       
  3392         }
       
  3393         else
       
  3394         {
       
  3395             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  3396         }
       
  3397     }
       
  3398     return ret;
       
  3399 }
       
  3400 
       
  3401 /*Query Device*/
       
  3402 CyAsReturnStatus_t
       
  3403 CyAsSdioQueryCard(
       
  3404         CyAsDeviceHandle            handle,
       
  3405         CyAsBusNumber_t             bus,
       
  3406         uint32_t                    device,
       
  3407         CyAsSDIOCard*               data_p )
       
  3408 {
       
  3409     CyAsLLRequestResponse *req_p , *reply_p ;
       
  3410     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  3411 
       
  3412     uint8_t resp_type;
       
  3413     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  3414 
       
  3415     ret = CyAsSdioDeviceCheck(dev_p,bus,device);
       
  3416     if( ret != CY_AS_ERROR_SUCCESS )
       
  3417         return ret;
       
  3418 
       
  3419     /* Allocating memory to the SDIO device structure in dev_p */
       
  3420 
       
  3421     CyAsHalMemSet(& dev_p->sdiocard[bus],0,sizeof(CyAsSDIODevice));
       
  3422 
       
  3423     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SDIO_QUERY_CARD, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
       
  3424     if (req_p == 0)
       
  3425         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  3426 
       
  3427     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, 0 )) ;
       
  3428 
       
  3429     reply_p = CyAsLLCreateResponse(dev_p, 5) ;
       
  3430     if (reply_p == 0)
       
  3431     {
       
  3432         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  3433         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  3434     }
       
  3435 
       
  3436     ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  3437 
       
  3438     if (ret != CY_AS_ERROR_SUCCESS)
       
  3439         goto destroy ;
       
  3440 
       
  3441     resp_type = CyAsLLRequestResponse_GetCode(reply_p);
       
  3442     if ( resp_type == CY_RESP_SDIO_QUERY_CARD)
       
  3443     {
       
  3444         dev_p->sdiocard[bus].card.num_functions     = (uint8_t)((reply_p->data[0]&0xff00)>>8);
       
  3445         dev_p->sdiocard[bus].card.memory_present    = (uint8_t)reply_p->data[0]&0x0001;
       
  3446         dev_p->sdiocard[bus].card.manufacturer_Id   = reply_p->data[1];
       
  3447         dev_p->sdiocard[bus].card.manufacturer_info = reply_p->data[2];
       
  3448         dev_p->sdiocard[bus].card.blocksize         = reply_p->data[3];
       
  3449         dev_p->sdiocard[bus].card.maxblocksize      = reply_p->data[3];
       
  3450         dev_p->sdiocard[bus].card.card_capability   = (uint8_t)((reply_p->data[4]&0xff00)>>8);
       
  3451         dev_p->sdiocard[bus].card.sdio_version      = (uint8_t)(reply_p->data[4]&0x00ff);
       
  3452         dev_p->sdiocard[bus].function_init_map      = 0x01;
       
  3453         data_p->num_functions       = dev_p->sdiocard[bus].card.num_functions;
       
  3454         data_p->memory_present      = dev_p->sdiocard[bus].card.memory_present;
       
  3455         data_p->manufacturer_Id     = dev_p->sdiocard[bus].card.manufacturer_Id;
       
  3456         data_p->manufacturer_info   = dev_p->sdiocard[bus].card.manufacturer_info;
       
  3457         data_p->blocksize           = dev_p->sdiocard[bus].card.blocksize;
       
  3458         data_p->maxblocksize        = dev_p->sdiocard[bus].card.maxblocksize;
       
  3459         data_p->card_capability     = dev_p->sdiocard[bus].card.card_capability;
       
  3460         data_p->sdio_version        = dev_p->sdiocard[bus].card.sdio_version;
       
  3461     }
       
  3462     else
       
  3463     {
       
  3464         if (resp_type == CY_RESP_SUCCESS_FAILURE)
       
  3465             ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  3466         else
       
  3467             ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  3468     }
       
  3469 destroy:
       
  3470     if(req_p!=0)
       
  3471         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  3472     if(reply_p!=0)
       
  3473         CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  3474     return ret ;
       
  3475 }
       
  3476 
       
  3477 /*Reset SDIO card. */
       
  3478 CyAsReturnStatus_t
       
  3479 CyAsSdioResetCard(
       
  3480         CyAsDeviceHandle            handle,
       
  3481         CyAsBusNumber_t         bus,
       
  3482         uint32_t                device )
       
  3483 {
       
  3484 
       
  3485     CyAsLLRequestResponse *req_p , *reply_p ;
       
  3486     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  3487     uint8_t resp_type;
       
  3488     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  3489 
       
  3490     ret = CyAsSdioDeviceCheck(dev_p,bus,device);
       
  3491 
       
  3492     if( ret != CY_AS_ERROR_SUCCESS )
       
  3493         return ret;
       
  3494 
       
  3495     if(dev_p->sdiocard != 0)
       
  3496     {
       
  3497         dev_p->sdiocard[bus].function_init_map=0;
       
  3498         dev_p->sdiocard[bus].function_suspended_map = 0;
       
  3499     }
       
  3500 
       
  3501 
       
  3502     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SDIO_RESET_DEV, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
       
  3503 
       
  3504     if (req_p == 0)
       
  3505         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  3506 
       
  3507     /*Setup mailbox */
       
  3508     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, 0) ) ;
       
  3509 
       
  3510     reply_p = CyAsLLCreateResponse(dev_p, 2) ;
       
  3511     if (reply_p == 0)
       
  3512     {
       
  3513         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  3514         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  3515     }
       
  3516 
       
  3517     ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  3518 
       
  3519 
       
  3520     if (ret != CY_AS_ERROR_SUCCESS)
       
  3521         goto destroy ;
       
  3522 
       
  3523 
       
  3524     resp_type = CyAsLLRequestResponse_GetCode(reply_p) ;
       
  3525 
       
  3526 
       
  3527     if (resp_type == CY_RESP_SUCCESS_FAILURE)
       
  3528     {
       
  3529         ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  3530         if(ret == CY_AS_ERROR_SUCCESS)
       
  3531         {
       
  3532             ret = CyAsSdioQueryCard(handle,bus,device,0);
       
  3533         }
       
  3534     }
       
  3535     else
       
  3536         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  3537 
       
  3538 destroy:
       
  3539     if(req_p!=0)
       
  3540         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  3541     if(reply_p!=0)
       
  3542         CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  3543     return ret ;
       
  3544 }
       
  3545 
       
  3546 /* Initialise an IO function*/
       
  3547 CyAsReturnStatus_t
       
  3548 CyAsSdioInitFunction(
       
  3549         CyAsDeviceHandle            handle,
       
  3550         CyAsBusNumber_t             bus,
       
  3551         uint32_t                    device,
       
  3552         uint8_t                     nFunctionNo,
       
  3553         uint8_t                     miscBuf     )
       
  3554 {
       
  3555     CyAsLLRequestResponse *req_p , *reply_p ;
       
  3556     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  3557     uint8_t resp_type;
       
  3558     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  3559 
       
  3560     ret = CyAsSdioDeviceCheck(dev_p,bus,device);
       
  3561 
       
  3562     if( ret != CY_AS_ERROR_SUCCESS )
       
  3563         return ret;
       
  3564 
       
  3565     if(!(CyAsSdioCheckFunctionInitialized(handle,bus,0)))
       
  3566         return CY_AS_ERROR_NOT_RUNNING;
       
  3567 
       
  3568     if((CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo)))
       
  3569     {
       
  3570         if(miscBuf&CY_SDIO_FORCE_INIT)
       
  3571             dev_p->sdiocard[bus].function_init_map&=(~(1<<nFunctionNo));
       
  3572         else
       
  3573             return CY_AS_ERROR_ALREADY_RUNNING;
       
  3574     }
       
  3575 
       
  3576     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SDIO_INIT_FUNCTION, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
       
  3577     if (req_p == 0)
       
  3578         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  3579 
       
  3580     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo )) ;
       
  3581 
       
  3582     reply_p = CyAsLLCreateResponse(dev_p, 5) ;
       
  3583     if (reply_p == 0)
       
  3584     {
       
  3585         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  3586         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  3587     }
       
  3588 
       
  3589     ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  3590 
       
  3591     if (ret != CY_AS_ERROR_SUCCESS)
       
  3592         goto destroy ;
       
  3593 
       
  3594     resp_type = CyAsLLRequestResponse_GetCode(reply_p) ;
       
  3595 
       
  3596     if (resp_type == CY_RESP_SDIO_INIT_FUNCTION)
       
  3597     {
       
  3598 
       
  3599         dev_p->sdiocard[bus].function[nFunctionNo-1].function_code      = (uint8_t)((reply_p->data[0]&0xff00)>>8);
       
  3600         dev_p->sdiocard[bus].function[nFunctionNo-1].extended_func_code = (uint8_t)reply_p->data[0]&0x00ff;
       
  3601         dev_p->sdiocard[bus].function[nFunctionNo-1].blocksize          =  reply_p->data[1];
       
  3602         dev_p->sdiocard[bus].function[nFunctionNo-1].maxblocksize       =  reply_p->data[1];
       
  3603         dev_p->sdiocard[bus].function[nFunctionNo-1].card_psn           = (uint32_t)(reply_p->data[2])<<16;
       
  3604         dev_p->sdiocard[bus].function[nFunctionNo-1].card_psn           |=(uint32_t)(reply_p->data[3]);
       
  3605         dev_p->sdiocard[bus].function[nFunctionNo-1].csa_bits           = (uint8_t)((reply_p->data[4]&0xff00)>>8);
       
  3606         dev_p->sdiocard[bus].function[nFunctionNo-1].wakeup_support     = (uint8_t)(reply_p->data[4]&0x0001);
       
  3607         dev_p->sdiocard[bus].function_init_map                          |= (1<<nFunctionNo);
       
  3608         CyAsSdioClearFunctionSuspended(handle,bus,nFunctionNo);
       
  3609 
       
  3610     }
       
  3611     else
       
  3612     {
       
  3613         if (resp_type == CY_RESP_SUCCESS_FAILURE)
       
  3614             ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  3615         else
       
  3616             ret = CY_AS_ERROR_INVALID_FUNCTION ;
       
  3617     }
       
  3618 
       
  3619 destroy:
       
  3620     if(req_p!=0)
       
  3621         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  3622     if(reply_p!=0)
       
  3623         CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  3624     return ret ;
       
  3625 }
       
  3626 
       
  3627 /*Query individual functions. */
       
  3628 CyAsReturnStatus_t
       
  3629 CyAsSdioQueryFunction(
       
  3630         CyAsDeviceHandle            handle,
       
  3631         CyAsBusNumber_t             bus,
       
  3632         uint32_t                    device,
       
  3633         uint8_t                     nFunctionNo,
       
  3634         CyAsSDIOFunc*               data_p )
       
  3635 {
       
  3636     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  3637     CyAsReturnStatus_t ret;
       
  3638 
       
  3639     ret = CyAsSdioDeviceCheck(dev_p,bus,device);
       
  3640     if( ret != CY_AS_ERROR_SUCCESS )
       
  3641         return ret;
       
  3642 
       
  3643     if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo)))
       
  3644         return CY_AS_ERROR_INVALID_FUNCTION;
       
  3645 
       
  3646     data_p->blocksize           =   dev_p->sdiocard[bus].function[nFunctionNo-1].blocksize;
       
  3647     data_p->card_psn            =   dev_p->sdiocard[bus].function[nFunctionNo-1].card_psn;
       
  3648     data_p->csa_bits            =   dev_p->sdiocard[bus].function[nFunctionNo-1].csa_bits;
       
  3649     data_p->extended_func_code  =   dev_p->sdiocard[bus].function[nFunctionNo-1].extended_func_code;
       
  3650     data_p->function_code       =   dev_p->sdiocard[bus].function[nFunctionNo-1].function_code;
       
  3651     data_p->maxblocksize        =   dev_p->sdiocard[bus].function[nFunctionNo-1].maxblocksize;
       
  3652     data_p->wakeup_support      =   dev_p->sdiocard[bus].function[nFunctionNo-1].wakeup_support;
       
  3653 
       
  3654 
       
  3655     return CY_AS_ERROR_SUCCESS;
       
  3656 }
       
  3657 
       
  3658 /* Abort the Current Extended IO Operation*/
       
  3659 CyAsReturnStatus_t
       
  3660 CyAsSdioAbortFunction(
       
  3661         CyAsDeviceHandle            handle,
       
  3662         CyAsBusNumber_t             bus,
       
  3663         uint32_t                    device,
       
  3664         uint8_t                     nFunctionNo)
       
  3665 {
       
  3666     CyAsLLRequestResponse *req_p , *reply_p ;
       
  3667     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  3668     uint8_t resp_type;
       
  3669     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  3670 
       
  3671     ret = CyAsSdioDeviceCheck(dev_p,bus,device);
       
  3672     if( ret != CY_AS_ERROR_SUCCESS )
       
  3673         return ret;
       
  3674 
       
  3675     if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo)))
       
  3676         return CY_AS_ERROR_INVALID_FUNCTION;
       
  3677 
       
  3678     if ((CyAsDeviceIsStorageAsyncPending(dev_p)) || (dev_p->storage_wait))
       
  3679     {
       
  3680         if(!(CyAsSdioGetCardCapability(handle,bus) & CY_SDIO_SDC ))
       
  3681         {
       
  3682             return CY_AS_ERROR_INVALID_COMMAND;
       
  3683         }
       
  3684     }
       
  3685 
       
  3686     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SDIO_ABORT_IO, CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
       
  3687 
       
  3688     if (req_p == 0)
       
  3689         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  3690 
       
  3691     /*Setup mailbox */
       
  3692     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo) ) ;
       
  3693 
       
  3694     reply_p = CyAsLLCreateResponse(dev_p, 2) ;
       
  3695     if (reply_p == 0)
       
  3696     {
       
  3697         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  3698         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  3699     }
       
  3700 
       
  3701     ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  3702     if (ret != CY_AS_ERROR_SUCCESS)
       
  3703         goto destroy ;
       
  3704 
       
  3705     resp_type = CyAsLLRequestResponse_GetCode(reply_p) ;
       
  3706 
       
  3707     if (resp_type == CY_RESP_SUCCESS_FAILURE)
       
  3708         ret = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  3709     else
       
  3710         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  3711 
       
  3712 
       
  3713 destroy:
       
  3714     if(req_p!=0)
       
  3715         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  3716     if(reply_p!=0)
       
  3717         CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  3718     return ret ;
       
  3719 }
       
  3720 
       
  3721 /* Suspend IO to current function*/
       
  3722 CyAsReturnStatus_t
       
  3723 CyAsSdioSuspend(
       
  3724         CyAsDeviceHandle        handle,
       
  3725         CyAsBusNumber_t         bus,
       
  3726         uint32_t                device,
       
  3727         uint8_t                 nFunctionNo)
       
  3728 {
       
  3729     CyAsLLRequestResponse *req_p , *reply_p ;
       
  3730     CyAsReturnStatus_t ret = CY_AS_ERROR_SUCCESS ;
       
  3731     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  3732 
       
  3733     ret = CyAsSdioDeviceCheck(dev_p,bus,device);
       
  3734     if( ret != CY_AS_ERROR_SUCCESS )
       
  3735         return ret;
       
  3736 
       
  3737     if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo)))
       
  3738         return CY_AS_ERROR_INVALID_FUNCTION;
       
  3739     if(!(CyAsSdioCheckSupportBusSuspend(handle,bus)))
       
  3740         return CY_AS_ERROR_INVALID_FUNCTION;
       
  3741     if(!(CyAsSdioGetCardCapability(handle,bus) & CY_SDIO_SDC))
       
  3742         return CY_AS_ERROR_INVALID_FUNCTION;
       
  3743     if(CyAsSdioCheckFunctionSuspended(handle,bus,nFunctionNo))
       
  3744         return CY_AS_ERROR_FUNCTION_SUSPENDED;
       
  3745 
       
  3746     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SDIO_SUSPEND, CY_RQT_GENERAL_RQT_CONTEXT, 1) ;
       
  3747     if (req_p == 0)
       
  3748         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  3749 
       
  3750     /*Setup mailbox */
       
  3751     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo) ) ;
       
  3752 
       
  3753     reply_p = CyAsLLCreateResponse(dev_p, 2) ;
       
  3754     if (reply_p == 0)
       
  3755     {
       
  3756         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  3757         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  3758     }
       
  3759     ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  3760 
       
  3761     if (ret == CY_AS_ERROR_SUCCESS)
       
  3762     {
       
  3763         ret = CyAsLLRequestResponse_GetCode(reply_p) ;
       
  3764         CyAsSdioSetFunctionSuspended(handle,bus,nFunctionNo);
       
  3765     }
       
  3766 
       
  3767     if(req_p!=0)
       
  3768         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  3769     if(reply_p!=0)
       
  3770         CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  3771 
       
  3772     return ret ;
       
  3773 }
       
  3774 
       
  3775 /*Resume suspended function*/
       
  3776 CyAsReturnStatus_t
       
  3777 CyAsSdioResume(
       
  3778         CyAsDeviceHandle        handle,
       
  3779         CyAsBusNumber_t         bus,
       
  3780         uint32_t                device,
       
  3781         uint8_t                 nFunctionNo,
       
  3782         CyAsOperType            op,
       
  3783         uint8_t                 miscBuf,
       
  3784         uint16_t                pendingblockcount,
       
  3785         uint8_t                 *data_p
       
  3786         )
       
  3787 {
       
  3788     CyAsLLRequestResponse *req_p , *reply_p ;
       
  3789     CyAsReturnStatus_t resp_data, ret = CY_AS_ERROR_SUCCESS ;
       
  3790     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  3791 
       
  3792     ret = CyAsSdioDeviceCheck(dev_p,bus,device);
       
  3793     if( ret != CY_AS_ERROR_SUCCESS )
       
  3794         return ret;
       
  3795 
       
  3796     if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo)))
       
  3797         return CY_AS_ERROR_INVALID_FUNCTION;
       
  3798 
       
  3799     /* If suspend resume is not supported return */
       
  3800     if(!(CyAsSdioCheckSupportBusSuspend(handle,bus)))
       
  3801         return CY_AS_ERROR_INVALID_FUNCTION;
       
  3802 
       
  3803     /* if the function is not suspended return. */
       
  3804     if(!(CyAsSdioCheckFunctionSuspended(handle,bus,nFunctionNo)))
       
  3805         return CY_AS_ERROR_INVALID_FUNCTION;
       
  3806 
       
  3807     req_p = CyAsLLCreateRequest(dev_p, CY_RQT_SDIO_RESUME, CY_RQT_STORAGE_RQT_CONTEXT, 1) ;
       
  3808     if (req_p == 0)
       
  3809         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  3810 
       
  3811     /*Setup mailbox */
       
  3812     CyAsLLRequestResponse_SetWord(req_p, 0, CreateAddress(bus, (uint8_t)device, nFunctionNo) ) ;
       
  3813 
       
  3814     reply_p = CyAsLLCreateResponse(dev_p, 2) ;
       
  3815     if (reply_p == 0)
       
  3816     {
       
  3817         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  3818         return CY_AS_ERROR_OUT_OF_MEMORY ;
       
  3819     }
       
  3820     ret = CyAsLLSendRequestWaitReply(dev_p, req_p, reply_p) ;
       
  3821 
       
  3822     if (ret != CY_AS_ERROR_SUCCESS)
       
  3823         goto destroy ;
       
  3824 
       
  3825 
       
  3826     if ( CyAsLLRequestResponse_GetCode(reply_p) == CY_RESP_SDIO_RESUME)
       
  3827     {
       
  3828         resp_data = CyAsLLRequestResponse_GetWord(reply_p, 0) ;
       
  3829         if(resp_data & 0x00ff)
       
  3830         {
       
  3831             /* Send extended read request to resume the read. */
       
  3832             if(op == CyAsOpRead)
       
  3833             {
       
  3834                 ret = CyAsSdioExtendedIO(handle,bus,device,nFunctionNo,0,miscBuf,pendingblockcount,CyFalse,data_p,1);
       
  3835             }
       
  3836             else
       
  3837             {
       
  3838                 ret = CyAsSdioExtendedIO(handle,bus,device,nFunctionNo,0,miscBuf,pendingblockcount,CyTrue,data_p,1);
       
  3839             }
       
  3840         }
       
  3841         else
       
  3842         {
       
  3843             ret= CY_AS_ERROR_SUCCESS;
       
  3844         }
       
  3845 
       
  3846     }
       
  3847     else
       
  3848     {
       
  3849         ret = CY_AS_ERROR_INVALID_RESPONSE ;
       
  3850     }
       
  3851 
       
  3852 destroy:
       
  3853     CyAsSdioClearFunctionSuspended(handle,bus,nFunctionNo);
       
  3854     if(req_p!=0)
       
  3855         CyAsLLDestroyRequest(dev_p, req_p) ;
       
  3856     if(reply_p!=0)
       
  3857         CyAsLLDestroyResponse(dev_p, reply_p) ;
       
  3858     return ret ;
       
  3859 
       
  3860 }
       
  3861 
       
  3862 /*Set function blocksize. Size cannot exceed max block size for the function*/
       
  3863 CyAsReturnStatus_t
       
  3864 CyAsSdioSetBlocksize(
       
  3865         CyAsDeviceHandle            handle,
       
  3866         CyAsBusNumber_t             bus,
       
  3867         uint32_t                    device,
       
  3868         uint8_t                     nFunctionNo,
       
  3869         uint16_t                    blocksize)
       
  3870 {
       
  3871     CyAsReturnStatus_t ret;
       
  3872     CyAsDevice *dev_p = (CyAsDevice *)handle ;
       
  3873     ret = CyAsSdioDeviceCheck(dev_p,bus,device);
       
  3874     if( ret != CY_AS_ERROR_SUCCESS )
       
  3875         return ret;
       
  3876 
       
  3877     if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo)))
       
  3878         return CY_AS_ERROR_INVALID_FUNCTION;
       
  3879     if( nFunctionNo == 0)
       
  3880     {
       
  3881         if ( blocksize > CyAsSdioGetCardMaxBlocksize(handle,bus))
       
  3882             return CY_AS_ERROR_INVALID_BLOCKSIZE;
       
  3883         else if (blocksize == CyAsSdioGetCardBlocksize(handle,bus))
       
  3884             return CY_AS_ERROR_SUCCESS;
       
  3885     }
       
  3886     else
       
  3887     {
       
  3888         if ( blocksize > CyAsSdioGetFunctionMaxBlocksize(handle,bus,nFunctionNo))
       
  3889             return CY_AS_ERROR_INVALID_BLOCKSIZE;
       
  3890         else if (blocksize == CyAsSdioGetFunctionBlocksize(handle,bus,nFunctionNo))
       
  3891             return CY_AS_ERROR_SUCCESS;
       
  3892     }
       
  3893 
       
  3894     ret = CyAsSdioDirectWrite(handle,bus,device,0,(uint16_t)(nFunctionNo<<8)|0x10,0,blocksize&0x00ff,0);
       
  3895     if(ret != CY_AS_ERROR_SUCCESS )
       
  3896         return ret;
       
  3897     ret = CyAsSdioDirectWrite(handle,bus,device,0,(uint16_t)(nFunctionNo<<8)|0x11,0,(blocksize&0xff00)>>8,0);
       
  3898     if (ret != CY_AS_ERROR_SUCCESS )
       
  3899         return ret;
       
  3900 
       
  3901     if(nFunctionNo ==0)
       
  3902         CyAsSdioSetCardBlockSize(handle,bus,blocksize);
       
  3903     else
       
  3904         CyAsSdioSetFunctionBlockSize(handle,bus,nFunctionNo,blocksize);
       
  3905     return ret;
       
  3906 }
       
  3907 
       
  3908 /* Deinitialize an SDIO function*/
       
  3909 CyAsReturnStatus_t
       
  3910 CyAsSdioDeInitFunction(
       
  3911         CyAsDeviceHandle            handle,
       
  3912         CyAsBusNumber_t             bus,
       
  3913         uint32_t                    device,
       
  3914         uint8_t                     nFunctionNo)
       
  3915 {
       
  3916     CyAsReturnStatus_t ret;
       
  3917     uint8_t temp;
       
  3918 
       
  3919     if(nFunctionNo == 0)
       
  3920         return CY_AS_ERROR_INVALID_FUNCTION;
       
  3921 
       
  3922     ret = CyAsSdioDeviceCheck((CyAsDevice*)handle,bus,device);
       
  3923     if( ret != CY_AS_ERROR_SUCCESS )
       
  3924         return ret;
       
  3925 
       
  3926     if(!(CyAsSdioCheckFunctionInitialized(handle,bus,nFunctionNo)))
       
  3927         return CY_AS_ERROR_SUCCESS;
       
  3928 
       
  3929     temp =(uint8_t)(((CyAsDevice*)handle)->sdiocard[bus].function_init_map & (~(1<<nFunctionNo)));
       
  3930     CyAsSdioDirectWrite(handle,bus,device,0,0x02,0,temp,0);
       
  3931     ((CyAsDevice*)handle)->sdiocard[bus].function_init_map &= (~(1<<nFunctionNo));
       
  3932 
       
  3933     return CY_AS_ERROR_SUCCESS;
       
  3934 }
       
  3935 
       
  3936 /* This includes the implementation of the deprecated functions for backward
       
  3937  * compatibility
       
  3938  */
       
  3939 #include "cyasstorage_dep_impl.h"
       
  3940 
       
  3941 /*[]*/