The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/pms/RefTisa/sallsdk/spc/saioctlcmd.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*******************************************************************************
    2 *Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved. 
    3 *
    4 *Redistribution and use in source and binary forms, with or without modification, are permitted provided 
    5 *that the following conditions are met: 
    6 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
    7 *following disclaimer. 
    8 *2. Redistributions in binary form must reproduce the above copyright notice, 
    9 *this list of conditions and the following disclaimer in the documentation and/or other materials provided
   10 *with the distribution. 
   11 *
   12 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 
   13 *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   14 *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   15 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
   16 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
   17 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
   18 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
   19 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
   20 
   21 ********************************************************************************/
   22 /*******************************************************************************/
   23 /*! \file saioctlcmd.c
   24  *  \brief The file implements the functions of IOCTL MPI Command/Response to/from SPC
   25  *
   26  */
   27 /******************************************************************************/
   28 #include <sys/cdefs.h>
   29 __FBSDID("$FreeBSD$");
   30 #include <dev/pms/config.h>
   31 
   32 #include <dev/pms/RefTisa/sallsdk/spc/saglobal.h>
   33 #ifdef SA_ENABLE_TRACE_FUNCTIONS
   34 #ifdef siTraceFileID
   35 #undef siTraceFileID
   36 #endif
   37 #define siTraceFileID 'H'
   38 #endif
   39 
   40 extern bit32 gFPGA_TEST;
   41 
   42 extern bit32 gWait_3;
   43 extern bit32 gWait_2;
   44 
   45 
   46 
   47 LOCAL bit32 siGSMDump(
   48                       agsaRoot_t     *agRoot,
   49                       bit32          gsmDumpOffset,
   50                       bit32          length,
   51                       void           *directData);
   52 
   53 #ifdef SPC_ENABLE_PROFILE
   54 /******************************************************************************/
   55 /*! \brief SPC FW Profile Command
   56  *
   57  *  This command sends FW Flash Update Command to SPC.
   58  *
   59  *  \param agRoot          Handles for this instance of SAS/SATA LL
   60  *  \param agContext       Context of SPC FW Flash Update Command
   61  *  \param queueNum        Inbound/outbound queue number
   62  *  \param flashUpdateInfo Pointer of flash update information
   63  *
   64  *  \return If the MPI command is sent to SPC successfully
   65  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
   66  *          - \e AGSA_RC_FAILURE the MPI command is failure
   67  *
   68  */
   69 /*******************************************************************************/
   70 GLOBAL bit32 saFwProfile(
   71   agsaRoot_t                *agRoot,
   72   agsaContext_t             *agContext,
   73   bit32                     queueNum,
   74   agsaFwProfile_t         *fwProfileInfo
   75   )
   76 {
   77   bit32 ret           = AGSA_RC_SUCCESS, retVal;
   78   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
   79   agsaIORequestDesc_t *pRequest;
   80   mpiICQueue_t        *circularQ;
   81   void                *pMessage;
   82   agsaFwProfileIOMB_t *pPayload;
   83   bit8                inq, outq;
   84   bit32               i, tcid_processor_cmd = 0;
   85 
   86 
   87   /* sanity check */
   88   SA_ASSERT((agNULL != agRoot), "");
   89 
   90   /* Get request from free IORequests */
   91   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
   92   pRequest = (agsaIORequestDesc_t *)saLlistGetHead(&(saRoot->freeIORequests));
   93 
   94   /* If no LL Control request entry avaliable */
   95   if ( agNULL == pRequest )
   96   {
   97     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
   98     SA_DBG1(("saFwProfile, No request from free list\n" ));
   99      return AGSA_RC_BUSY;
  100   }
  101   /* If LL Control request entry avaliable */
  102   else
  103   {
  104     /* Assign inbound and outbound Ring Buffer */
  105     inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
  106     outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
  107     SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
  108 
  109     /* Remove the request from free list */
  110     saLlistRemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
  111     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
  112     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
  113     saRoot->IOMap[pRequest->HTag].agContext = agContext;
  114     pRequest->valid = agTRUE;
  115     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  116 
  117 #ifdef SA_LL_IBQ_PROTECT
  118     ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
  119 #endif /* SA_LL_IBQ_PROTECT */
  120     /* Get a free inbound queue entry */
  121     circularQ = &saRoot->inboundQueue[inq];
  122     retVal    = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage);
  123 
  124     /* if message size is too large return failure */
  125     if (AGSA_RC_FAILURE == retVal)
  126     {
  127 #ifdef SA_LL_IBQ_PROTECT
  128       ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
  129 #endif  /* SA_LL_IBQ_PROTECT */
  130       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  131       /* remove the request from IOMap */
  132       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
  133       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
  134       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
  135       pRequest->valid = agFALSE;
  136       /* return the request to free pool */
  137       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
  138       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  139 
  140       SA_DBG1(("saFwProfile, error when get free IOMB\n"));
  141       return AGSA_RC_FAILURE;
  142     }
  143 
  144     /* return busy if inbound queue is full */
  145     if (AGSA_RC_BUSY == retVal)
  146     {
  147 #ifdef SA_LL_IBQ_PROTECT
  148       ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
  149 #endif /* SA_LL_IBQ_PROTECT */
  150 
  151       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  152       /* remove the request from IOMap */
  153       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
  154       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
  155       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
  156       pRequest->valid = agFALSE;
  157       /* return the request to free pool */
  158       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
  159       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  160       SA_DBG1(("saFwProfile, no more IOMB\n"));
  161       return AGSA_RC_BUSY;
  162     }
  163 
  164     pPayload = (agsaFwProfileIOMB_t *)pMessage;
  165     tcid_processor_cmd = (((fwProfileInfo->tcid)<< 16) | ((fwProfileInfo->processor)<< 8) | fwProfileInfo->cmd);
  166   /* Prepare the FW_FLASH_UPDATE IOMB payload */
  167     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwProfileIOMB_t, tag), pRequest->HTag);
  168     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwProfileIOMB_t, tcid_processor_cmd), tcid_processor_cmd);
  169     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwProfileIOMB_t, codeStartAdd), fwProfileInfo->codeStartAdd);
  170     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwProfileIOMB_t, codeEndAdd), fwProfileInfo->codeEndAdd);
  171 
  172     pPayload->SGLAL = fwProfileInfo->agSgl.sgLower;
  173     pPayload->SGLAH = fwProfileInfo->agSgl.sgUpper;
  174     pPayload->Len = fwProfileInfo->agSgl.len;
  175     pPayload->extReserved = fwProfileInfo->agSgl.extReserved;
  176 
  177     /* fill up the reserved bytes with zero */
  178     for (i = 0; i < FWPROFILE_IOMB_RESERVED_LEN; i ++)
  179     {
  180       pPayload->reserved0[i] = 0;
  181     }
  182 
  183     /* post the IOMB to SPC */
  184     ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_FW_PROFILE, outq, (bit8)circularQ->priority);
  185 
  186 #ifdef SA_LL_IBQ_PROTECT
  187     ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
  188 #endif /* SA_LL_IBQ_PROTECT */
  189 
  190     if (AGSA_RC_FAILURE == ret)
  191     {
  192       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  193       /* remove the request from IOMap */
  194       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
  195       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
  196       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
  197       pRequest->valid = agFALSE;
  198       /* return the request to free pool */
  199       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
  200       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  201       SA_DBG1(("saFwProfile, error when post FW_PROFILE IOMB\n"));
  202     }
  203   }
  204   return ret;
  205 }
  206 #endif
  207 /******************************************************************************/
  208 /*! \brief SPC FW Flash Update Command
  209  *
  210  *  This command sends FW Flash Update Command to SPC.
  211  *
  212  *  \param agRoot          Handles for this instance of SAS/SATA LL
  213  *  \param agContext       Context of SPC FW Flash Update Command
  214  *  \param queueNum        Inbound/outbound queue number
  215  *  \param flashUpdateInfo Pointer of flash update information
  216  *
  217  *  \return If the MPI command is sent to SPC successfully
  218  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
  219  *          - \e AGSA_RC_FAILURE the MPI command is failure
  220  *
  221  */
  222 /*******************************************************************************/
  223 GLOBAL bit32 saFwFlashUpdate(
  224   agsaRoot_t                *agRoot,
  225   agsaContext_t             *agContext,
  226   bit32                     queueNum,
  227   agsaUpdateFwFlash_t       *flashUpdateInfo
  228   )
  229 {
  230   bit32 ret = AGSA_RC_SUCCESS, retVal;
  231   agsaLLRoot_t        *saRoot;
  232   agsaIORequestDesc_t *pRequest;
  233   mpiICQueue_t        *circularQ;
  234   void                *pMessage;
  235   agsaFwFlashUpdate_t *pPayload;
  236   bit8                inq, outq;
  237   bit32               i;
  238 
  239   SA_ASSERT((agNULL != agRoot), "");
  240   if (agRoot == agNULL)
  241   {
  242     SA_DBG1(("saFwFlashUpdate: agRoot == agNULL\n"));
  243     return AGSA_RC_FAILURE;
  244   }
  245   saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
  246   SA_ASSERT((agNULL != saRoot), "");
  247   if (saRoot == agNULL)
  248   {
  249     SA_DBG1(("saFwFlashUpdate: saRoot == agNULL\n"));
  250     return AGSA_RC_FAILURE;
  251   }
  252 
  253 
  254   smTraceFuncEnter(hpDBG_VERY_LOUD, "6a");
  255   /* sanity check */
  256   SA_ASSERT((agNULL != agRoot), "");
  257   /* Get request from free IORequests */
  258   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  259   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
  260   /* If no LL Control request entry available */
  261   if ( agNULL == pRequest ) {
  262     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  263     SA_DBG1(("saFwFlashUpdate, No request from free list\n" ));
  264     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6a");
  265     return AGSA_RC_BUSY;
  266   }
  267   /* If LL Control request entry avaliable */
  268   else
  269   {
  270     /* Assign inbound and outbound Ring Buffer */
  271     inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
  272     outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
  273     SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
  274     /* Remove the request from free list */
  275     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
  276     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
  277     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
  278     saRoot->IOMap[pRequest->HTag].agContext = agContext;
  279     pRequest->valid = agTRUE;
  280     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  281 #ifdef SA_LL_IBQ_PROTECT
  282     ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
  283 #endif /* SA_LL_IBQ_PROTECT */
  284     /* Get a free inbound queue entry */
  285     circularQ = &saRoot->inboundQueue[inq];
  286     retVal    = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage);
  287     /* if message size is too large return failure */
  288     if (AGSA_RC_FAILURE == retVal)
  289     {
  290 #ifdef SA_LL_IBQ_PROTECT
  291       ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
  292 #endif /* SA_LL_IBQ_PROTECT */
  293       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  294       /* remove the request from IOMap */
  295       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
  296       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
  297       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
  298       pRequest->valid = agFALSE;
  299       /* return the request to free pool */
  300       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
  301       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  302       SA_DBG1(("saFwFlashUpdate, error when get free IOMB\n"));
  303       smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6a");
  304       return AGSA_RC_FAILURE;
  305     }
  306     /* return busy if inbound queue is full */
  307     if (AGSA_RC_BUSY == retVal)
  308     {
  309 #ifdef SA_LL_IBQ_PROTECT
  310       ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
  311 #endif /* SA_LL_IBQ_PROTECT */
  312       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  313       /* remove the request from IOMap */
  314       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
  315       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
  316       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
  317       pRequest->valid = agFALSE;
  318       /* return the request to free pool */
  319       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
  320       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  321       SA_DBG1(("saFwFlashUpdate, no more IOMB\n"));
  322       smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "6a");
  323       return AGSA_RC_BUSY;
  324     }
  325     pPayload = (agsaFwFlashUpdate_t *)pMessage;
  326     /* Prepare the FW_FLASH_UPDATE IOMB payload */
  327     OSSA_WRITE_LE_32( agRoot, pPayload,
  328                       OSSA_OFFSET_OF(agsaFwFlashUpdate_t, tag), pRequest->HTag);
  329     OSSA_WRITE_LE_32( agRoot, pPayload,
  330                       OSSA_OFFSET_OF(agsaFwFlashUpdate_t, curImageOffset),
  331                       flashUpdateInfo->currentImageOffset);
  332     OSSA_WRITE_LE_32( agRoot, pPayload,
  333                       OSSA_OFFSET_OF(agsaFwFlashUpdate_t, curImageLen),
  334                       flashUpdateInfo->currentImageLen);
  335     OSSA_WRITE_LE_32( agRoot, pPayload,
  336                       OSSA_OFFSET_OF(agsaFwFlashUpdate_t, totalImageLen),
  337                       flashUpdateInfo->totalImageLen);
  338     pPayload->SGLAL = flashUpdateInfo->agSgl.sgLower;
  339     pPayload->SGLAH = flashUpdateInfo->agSgl.sgUpper;
  340     pPayload->Len   = flashUpdateInfo->agSgl.len;
  341     pPayload->extReserved = flashUpdateInfo->agSgl.extReserved;
  342     /* fill up the reserved bytes with zero */
  343     for (i = 0; i < FWFLASH_IOMB_RESERVED_LEN; i ++) {
  344       pPayload->reserved0[i] = 0;
  345     }
  346     /* post the IOMB to SPC */
  347     ret = mpiMsgProduce( circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA,
  348                          OPC_INB_FW_FLASH_UPDATE, outq, (bit8)circularQ->priority);
  349 #ifdef SA_LL_IBQ_PROTECT
  350     ossaSingleThreadedLeave( agRoot, LL_IOREQ_IBQ0_LOCK + inq );
  351 #endif /* SA_LL_IBQ_PROTECT */
  352     if (AGSA_RC_FAILURE == ret) {
  353       ossaSingleThreadedEnter( agRoot, LL_IOREQ_LOCKEQ_LOCK );
  354       /* remove the request from IOMap */
  355       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
  356       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
  357       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
  358       pRequest->valid = agFALSE;
  359       /* return the request to free pool */
  360       saLlistIOAdd( &(saRoot->freeIORequests), &(pRequest->linkNode) );
  361       ossaSingleThreadedLeave( agRoot, LL_IOREQ_LOCKEQ_LOCK );
  362       SA_DBG1( ("saFwFlashUpdate, error when post FW_FLASH_UPDATE IOMB\n") );
  363     }
  364   }
  365   smTraceFuncExit( hpDBG_VERY_LOUD, 'd', "6a" );
  366   return ret;
  367 }
  368 
  369 
  370 GLOBAL bit32 saFlashExtExecute (
  371                   agsaRoot_t            *agRoot,
  372                   agsaContext_t         *agContext,
  373                   bit32                 queueNum,
  374                   agsaFlashExtExecute_t *agFlashExtExe)
  375 {
  376 
  377   bit32 ret           = AGSA_RC_SUCCESS, retVal;
  378   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
  379   agsaIORequestDesc_t *pRequest;
  380   mpiICQueue_t        *circularQ;
  381   void                *pMessage;
  382   agsaFwFlashOpExt_t *pPayload;
  383   bit8                inq, outq;
  384 
  385   smTraceFuncEnter(hpDBG_VERY_LOUD,"2R");
  386 
  387   /* sanity check */
  388   SA_ASSERT((agNULL != agRoot), "");
  389 
  390   /* Get request from free IORequests */
  391   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  392   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
  393 
  394   /* If no LL Control request entry available */
  395   if ( agNULL == pRequest )
  396   {
  397     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  398     SA_DBG1(("saFlashExtExecute, No request from free list\n" ));
  399     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2R");
  400     return AGSA_RC_BUSY;
  401   }
  402   /* If LL Control request entry avaliable */
  403   else
  404   {
  405     /* Assign inbound and outbound Ring Buffer */
  406     inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
  407     outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
  408     SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
  409 
  410     /* Remove the request from free list */
  411     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
  412     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
  413     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
  414     saRoot->IOMap[pRequest->HTag].agContext = agContext;
  415     pRequest->valid = agTRUE;
  416     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  417 
  418 #ifdef SA_LL_IBQ_PROTECT
  419     ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
  420 #endif /* SA_LL_IBQ_PROTECT */
  421     /* Get a free inbound queue entry */
  422     circularQ = &saRoot->inboundQueue[inq];
  423     retVal    = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage);
  424 
  425     /* if message size is too large return failure */
  426     if (AGSA_RC_FAILURE == retVal)
  427     {
  428 #ifdef SA_LL_IBQ_PROTECT
  429       ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
  430 #endif   /* SA_LL_IBQ_PROTECT */
  431       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  432       /* remove the request from IOMap */
  433       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
  434       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
  435       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
  436       pRequest->valid = agFALSE;
  437       /* return the request to free pool */
  438       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
  439       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  440 
  441       SA_DBG1(("saFlashExtExecute, error when get free IOMB\n"));
  442       smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2R");
  443       return AGSA_RC_FAILURE;
  444     }
  445 
  446     /* return busy if inbound queue is full */
  447     if (AGSA_RC_BUSY == retVal)
  448     {
  449 #ifdef SA_LL_IBQ_PROTECT
  450       ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
  451 #endif /* SA_LL_IBQ_PROTECT */
  452       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  453       /* remove the request from IOMap */
  454       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
  455       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
  456       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
  457 
  458       pRequest->valid = agFALSE;
  459       /* return the request to free pool */
  460       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
  461       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  462 
  463       SA_DBG3(("saFlashExtExecute, no more IOMB\n"));
  464       smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2R");
  465       return AGSA_RC_BUSY;
  466     }
  467 
  468     pPayload = (agsaFwFlashOpExt_t *)pMessage;
  469 
  470     si_memset(pPayload, 0, sizeof(agsaFwFlashOpExt_t));
  471 
  472 
  473     /* Prepare the FW_FLASH_UPDATE IOMB payload */
  474     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t, tag), pRequest->HTag);
  475     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t,Command ), agFlashExtExe->command);
  476     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t,PartOffset ), agFlashExtExe->partOffset);
  477     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t,DataLength ), agFlashExtExe->dataLen);
  478     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t,SGLAL ), agFlashExtExe->agSgl->sgLower);
  479     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t,SGLAH ), agFlashExtExe->agSgl->sgUpper);
  480     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t,Len ), agFlashExtExe->agSgl->len);
  481     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t,E_sgl ), agFlashExtExe->agSgl->extReserved);
  482 
  483     /* post the IOMB to SPC */
  484     ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_FLASH_OP_EXT, outq, (bit8)circularQ->priority);
  485 
  486 #ifdef SA_LL_IBQ_PROTECT
  487     ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
  488 #endif /* SA_LL_IBQ_PROTECT */
  489 
  490 
  491     if (AGSA_RC_FAILURE == ret)
  492     {
  493       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  494       /* remove the request from IOMap */
  495       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
  496       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
  497       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
  498       pRequest->valid = agFALSE;
  499       /* return the request to free pool */
  500       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
  501       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  502       SA_DBG1(("saFlashExtExecute, error when post FW_FLASH_UPDATE IOMB\n"));
  503     }
  504   }
  505   smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "2R");
  506 
  507   return ret;
  508 
  509 }
  510 
  511 
  512 #ifdef SPC_ENABLE_PROFILE
  513 /******************************************************************************/
  514 /*! \brief SPC FW_PROFILE Respond
  515  *
  516  *  This command sends FW Profile Status to TD layer.
  517  *
  518  *  \param agRoot       Handles for this instance of SAS/SATA LL
  519  *  \param payload      FW download response payload
  520  *
  521  *  \return If the MPI command is sent to SPC successfully
  522  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
  523  *          - \e AGSA_RC_FAILURE the MPI command is failure
  524  *
  525  */
  526 /*******************************************************************************/
  527 GLOBAL bit32 mpiFwProfileRsp(
  528   agsaRoot_t             *agRoot,
  529   agsaFwProfileRsp_t *payload
  530   )
  531 {
  532   bit32               ret = AGSA_RC_SUCCESS;
  533   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
  534   agsaIORequestDesc_t *pRequest;
  535   agsaContext_t       *agContext;
  536 
  537   bit32     status, tag, len;
  538 
  539   /* get request from IOMap */
  540   OSSA_READ_LE_32(AGROOT, &tag, payload, OSSA_OFFSET_OF(agsaFwProfileRsp_t, tag));
  541   OSSA_READ_LE_32(AGROOT, &status, payload, OSSA_OFFSET_OF(agsaFwProfileRsp_t, status));
  542   OSSA_READ_LE_32(AGROOT, &len, payload, OSSA_OFFSET_OF(agsaFwProfileRsp_t, len));
  543   pRequest = saRoot->IOMap[tag].IORequest;
  544   if (agNULL == pRequest)
  545   {
  546     /* remove the request from IOMap */
  547     saRoot->IOMap[tag].Tag = MARK_OFF;
  548     saRoot->IOMap[tag].IORequest = agNULL;
  549     SA_DBG1(("mpiFwProfileRsp: the request is NULL. Tag=%x\n", tag));
  550     return AGSA_RC_FAILURE;
  551   }
  552   agContext = saRoot->IOMap[tag].agContext;
  553   /* remove the request from IOMap */
  554   saRoot->IOMap[tag].Tag = MARK_OFF;
  555   saRoot->IOMap[tag].IORequest = agNULL;
  556   saRoot->IOMap[tag].agContext = agNULL;
  557   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  558 
  559 
  560   if(!pRequest->valid)
  561   {
  562     SA_DBG1(("mpiPortControlRsp: pRequest->valid %d not set\n", pRequest->valid));
  563   }
  564 
  565   SA_ASSERT((pRequest->valid), "pRequest->valid");
  566 
  567   pRequest->valid = agFALSE;
  568   /* return the request to free pool */
  569   saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
  570   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  571 
  572   ossaFwProfileCB(agRoot, agContext, status, len);
  573 
  574  return ret;
  575 }
  576 #endif
  577 /******************************************************************************/
  578 /*! \brief SPC FW_FLASH_UPDATE Respond
  579  *
  580  *  This command sends FW Flash Update Status to TD layer.
  581  *
  582  *  \param agRoot       Handles for this instance of SAS/SATA LL
  583  *  \param payload      FW download response payload
  584  *
  585  *  \return If the MPI command is sent to SPC successfully
  586  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
  587  *          - \e AGSA_RC_FAILURE the MPI command is failure
  588  *
  589  */
  590 /*******************************************************************************/
  591 GLOBAL bit32 mpiFwFlashUpdateRsp(
  592   agsaRoot_t             *agRoot,
  593   agsaFwFlashUpdateRsp_t *payload
  594   )
  595 {
  596   bit32               ret = AGSA_RC_SUCCESS;
  597   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
  598   agsaIORequestDesc_t *pRequest;
  599   agsaContext_t       *agContext;
  600 
  601   bit32     status, tag;
  602   smTraceFuncEnter(hpDBG_VERY_LOUD,"6b");
  603 
  604   /* get request from IOMap */
  605   OSSA_READ_LE_32(AGROOT, &tag, payload, OSSA_OFFSET_OF(agsaFwFlashUpdateRsp_t, tag));
  606   OSSA_READ_LE_32(AGROOT, &status, payload, OSSA_OFFSET_OF(agsaFwFlashUpdateRsp_t, status));
  607   pRequest = saRoot->IOMap[tag].IORequest;
  608   agContext = saRoot->IOMap[tag].agContext;
  609   /* remove the request from IOMap */
  610   saRoot->IOMap[tag].Tag = MARK_OFF;
  611   saRoot->IOMap[tag].IORequest = agNULL;
  612   saRoot->IOMap[tag].agContext = agNULL;
  613   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  614   SA_ASSERT((pRequest->valid), "pRequest->valid");
  615   pRequest->valid = agFALSE;
  616   /* return the request to free pool */
  617   if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
  618   {
  619     SA_DBG1(("mpiFwFlashUpdateRsp: saving pRequest (%p) for later use\n", pRequest));
  620     saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
  621   }
  622   else
  623   {
  624     /* return the request to free pool */
  625     saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
  626   }
  627   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  628 
  629   if(status > 1)
  630   {
  631     SA_DBG1(("mpiFwFlashUpdateRsp: status = 0x%x\n",status));
  632   }
  633 
  634   ossaFwFlashUpdateCB(agRoot, agContext, status);
  635 
  636   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6b");
  637 
  638   return ret;
  639 }
  640 
  641 GLOBAL bit32 mpiFwExtFlashUpdateRsp(
  642   agsaRoot_t             *agRoot,
  643   agsaFwFlashOpExtRsp_t *payload
  644   )
  645 {
  646   bit32               ret = AGSA_RC_SUCCESS;
  647   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
  648   agsaIORequestDesc_t *pRequest;
  649   agsaContext_t       *agContext;
  650 
  651   agsaFlashExtResponse_t FlashExtRsp;
  652 
  653   bit32     Command,Status, tag;
  654   smTraceFuncEnter(hpDBG_VERY_LOUD,"2T");
  655 
  656   /* get request from IOMap */
  657   OSSA_READ_LE_32(AGROOT, &tag, payload, OSSA_OFFSET_OF(agsaFwFlashOpExtRsp_t, tag));
  658   OSSA_READ_LE_32(AGROOT, &Command, payload, OSSA_OFFSET_OF(agsaFwFlashOpExtRsp_t,Command ));
  659   OSSA_READ_LE_32(AGROOT, &Status, payload, OSSA_OFFSET_OF(agsaFwFlashOpExtRsp_t,Status ));
  660   OSSA_READ_LE_32(AGROOT, &FlashExtRsp.epart_sect_size, payload, OSSA_OFFSET_OF(agsaFwFlashOpExtRsp_t,Epart_Size ));
  661   OSSA_READ_LE_32(AGROOT, &FlashExtRsp.epart_size, payload, OSSA_OFFSET_OF(agsaFwFlashOpExtRsp_t,EpartSectSize ));
  662 
  663   pRequest = saRoot->IOMap[tag].IORequest;
  664   agContext = saRoot->IOMap[tag].agContext;
  665   /* remove the request from IOMap */
  666   saRoot->IOMap[tag].Tag = MARK_OFF;
  667   saRoot->IOMap[tag].IORequest = agNULL;
  668   saRoot->IOMap[tag].agContext = agNULL;
  669   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  670   SA_ASSERT((pRequest->valid), "pRequest->valid");
  671   pRequest->valid = agFALSE;
  672   /* return the request to free pool */
  673   if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
  674   {
  675     SA_DBG1(("mpiFwExtFlashUpdateRsp: saving pRequest (%p) for later use\n", pRequest));
  676     saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
  677   }
  678   else
  679   {
  680     /* return the request to free pool */
  681     saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
  682   }
  683   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  684 
  685   if(Status > 1)
  686   {
  687     SA_DBG1(("mpiFwExtFlashUpdateRsp: status = 0x%x\n",Status));
  688   }
  689 
  690   ossaFlashExtExecuteCB(agRoot, agContext, Status,Command,&FlashExtRsp);
  691 
  692   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2T");
  693 
  694   return ret;
  695 
  696 }
  697 
  698 
  699 /******************************************************************************/
  700 /*! \brief SPC Get Controller Information Command
  701  *
  702  *  This command sends Get Controller Information Command to SPC.
  703  *
  704  *  \param agRoot         Handles for this instance of SAS/SATA LL
  705  *  \param controllerInfo Controller Information
  706  *
  707  *  \return If the MPI command is sent to SPC successfully
  708  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
  709  *          - \e AGSA_RC_FAILURE the MPI command is failure
  710  *
  711  */
  712 /*******************************************************************************/
  713 
  714 GLOBAL bit32 saGetControllerInfo(
  715                         agsaRoot_t                *agRoot,
  716                         agsaControllerInfo_t      *controllerInfo
  717                         )
  718 {
  719 
  720   bit32     ret = AGSA_RC_SUCCESS;
  721   bit32     max_wait_time;
  722   bit32     max_wait_count;
  723   bit32     ContrlCapFlag, MSGUCfgTblBase, CfgTblDWIdx;
  724   bit32     value = 0, value1 = 0;
  725   bit8      pcibar;
  726 
  727   if (agNULL != agRoot->sdkData)
  728   {
  729     smTraceFuncEnter(hpDBG_VERY_LOUD,"6e");
  730   }
  731   /* clean the structure */
  732   si_memset(controllerInfo, 0, sizeof(agsaControllerInfo_t));
  733 
  734   if(smIS_SPC6V(agRoot))
  735   {
  736     controllerInfo->sdkInterfaceRev = STSDK_LL_INTERFACE_VERSION;
  737     controllerInfo->sdkRevision     = STSDK_LL_VERSION;
  738     controllerInfo->hwRevision = (ossaHwRegReadConfig32(agRoot,8) & 0xFF);
  739   }else  if(smIS_SPC12V(agRoot))
  740   {
  741     controllerInfo->sdkInterfaceRev = STSDK_LL_12G_INTERFACE_VERSION;
  742     controllerInfo->sdkRevision     = STSDK_LL_12G_VERSION;
  743     controllerInfo->hwRevision = (ossaHwRegReadConfig32(agRoot,8) & 0xFF);
  744   } else if(smIS_SPC(agRoot))
  745   {
  746     controllerInfo->hwRevision = SPC_READ_DEV_REV;
  747     controllerInfo->sdkInterfaceRev = MATCHING_SPC_FW_VERSION;
  748     controllerInfo->sdkRevision     = STSDK_LL_SPC_VERSION;
  749   }
  750   else
  751   {
  752     controllerInfo->hwRevision = (ossaHwRegReadConfig32(agRoot,8) & 0xFF);
  753   }
  754 
  755   SA_DBG1(("saGetControllerInfo: SCRATCH_PAD0 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0)));
  756   SA_DBG1(("saGetControllerInfo: SCRATCH_PAD1 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1)));
  757   SA_DBG1(("saGetControllerInfo: SCRATCH_PAD2 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_2,  MSGU_SCRATCH_PAD_2)));
  758   SA_DBG1(("saGetControllerInfo: SCRATCH_PAD3 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_3,  MSGU_SCRATCH_PAD_3)));
  759   SA_DBG1(("saGetControllerInfo: SCRATCH_PAD3 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_3,  MSGU_SCRATCH_PAD_3)));
  760 
  761   if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0) == 0xFFFFFFFF)
  762   {
  763     SA_DBG1(("saGetControllerInfo:AGSA_RC_FAILURE SCRATCH_PAD0 value = 0x%x\n",
  764             siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0) ) );
  765     return AGSA_RC_FAILURE;
  766   }
  767 
  768   if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0) == 0xFFFFFFFF)
  769   {
  770     SA_DBG1(("saGetControllerInfo:AGSA_RC_FAILURE SCRATCH_PAD0 value = 0x%x\n",
  771             siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0) ) );
  772     return AGSA_RC_FAILURE;
  773   }
  774 
  775   if( SCRATCH_PAD1_V_ERROR_STATE(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1)) )
  776   {
  777     SA_DBG1(("saGetControllerInfo: SCRATCH_PAD1 (0x%x) in error state ila %d raae %d Iop0 %d Iop1 %d\n",
  778       siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1),
  779     ( SCRATCH_PAD1_V_ILA_ERROR_STATE(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1)) ? 1 : 0),
  780     ( SCRATCH_PAD1_V_RAAE_ERROR_STATE(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,MSGU_SCRATCH_PAD_1)) ? 1 : 0),
  781     ( SCRATCH_PAD1_V_IOP0_ERROR_STATE(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,MSGU_SCRATCH_PAD_1)) ? 1 : 0),
  782     ( SCRATCH_PAD1_V_IOP1_ERROR_STATE(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,MSGU_SCRATCH_PAD_1)) ? 1 : 0) ));
  783 
  784   }
  785 
  786   if(smIS_SPC(agRoot))
  787   {
  788     /* check HDA mode */
  789     value = ossaHwRegReadExt(agRoot, PCIBAR3, HDA_RSP_OFFSET1MB+HDA_CMD_CODE_OFFSET) & HDA_STATUS_BITS;
  790 
  791     if (value == BOOTTLOADERHDA_IDLE)
  792     {
  793       /* HDA mode */
  794       SA_DBG1(("saGetControllerInfo: HDA mode, value = 0x%x\n", value));
  795       return AGSA_RC_HDA_NO_FW_RUNNING;
  796     }
  797   }
  798   else
  799   {
  800     if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1) &   SCRATCH_PAD1_V_RESERVED )
  801     {
  802       SA_DBG1(("saGetControllerInfo: Warning SCRATCH_PAD1 reserved bits set value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1)));
  803     }
  804     if( si_check_V_HDA(agRoot))
  805     {
  806       /*  Check HDA */
  807       SA_DBG1(("saGetControllerInfo: HDA mode AGSA_RC_HDA_NO_FW_RUNNING\n" ));
  808       return AGSA_RC_HDA_NO_FW_RUNNING;
  809     }
  810 
  811 
  812   }
  813 
  814   /* checking the fw AAP and IOP in ready state */
  815   max_wait_time = WAIT_SECONDS(gWait_2);  /* 2 sec timeout */
  816   max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT);
  817   /* wait until scratch pad 1 and 2 registers in ready state  */
  818   if(smIS_SPCV(agRoot))
  819   {
  820     do
  821     {
  822       ossaStallThread(agRoot, WAIT_INCREMENT);
  823       value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1);
  824       value1 =siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_2, MSGU_SCRATCH_PAD_2);
  825       if(smIS_SPCV(agRoot))
  826       {
  827         if((value & SCRATCH_PAD1_V_RESERVED) )
  828         {
  829           SA_DBG1(("saGetControllerInfo: V reserved SCRATCH_PAD1 value = 0x%x (0x%x)\n", value, SCRATCH_PAD1_V_RESERVED));
  830           ret = AGSA_RC_FW_NOT_IN_READY_STATE;
  831           break;
  832         }
  833       }
  834 
  835       if ((max_wait_count -= WAIT_INCREMENT) == 0)
  836       {
  837         SA_DBG1(("saGetControllerInfo:  timeout SCRATCH_PAD1_V_READY !! SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1));
  838         break;
  839       }
  840 
  841     } while (((value & SCRATCH_PAD1_V_READY) != SCRATCH_PAD1_V_READY) || (value == 0xffffffff));
  842 
  843   }
  844   else
  845   {
  846     do
  847     {
  848       ossaStallThread(agRoot, WAIT_INCREMENT);
  849       value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1);
  850       /* checking bit 4 to 7 for reserved in case we get 0xFFFFFFFF */
  851       if (value & SCRATCH_PAD1_RESERVED)
  852       {
  853         SA_DBG1(("saGetControllerInfo: SCRATCH_PAD1 value = 0x%x\n", value));
  854         ret = AGSA_RC_FW_NOT_IN_READY_STATE;
  855         break;
  856       }
  857       value1 =siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_2,MSGU_SCRATCH_PAD_2);
  858       /* checking bit 4 to 7 for reserved in case we get 0xFFFFFFFF */
  859       if (value1 & SCRATCH_PAD2_RESERVED)
  860       {
  861         SA_DBG1(("saGetControllerInfo: SCRATCH_PAD2 value = 0x%x\n", value1));
  862         ret = AGSA_RC_FW_NOT_IN_READY_STATE;
  863         break;
  864       }
  865       if ((max_wait_count -= WAIT_INCREMENT) == 0)
  866       {
  867         SA_DBG1(("saGetControllerInfo: Timeout!! SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1));
  868         break;
  869       }
  870     } while (((value & SCRATCH_PAD_STATE_MASK) != SCRATCH_PAD1_RDY) || ((value1 & SCRATCH_PAD_STATE_MASK) != SCRATCH_PAD2_RDY));
  871   }
  872 
  873   if (!max_wait_count)
  874   {
  875     SA_DBG1(("saGetControllerInfo: timeout failure\n"));
  876     ret = AGSA_RC_FW_NOT_IN_READY_STATE;
  877   }
  878 
  879   if (ret == AGSA_RC_SUCCESS)
  880   {
  881     SA_DBG1(("saGetControllerInfo: FW Ready, SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1));
  882 
  883     /* read scratch pad0 to get PCI BAR and offset of configuration table */
  884      MSGUCfgTblBase = siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0);
  885     /* get offset */
  886     CfgTblDWIdx = MSGUCfgTblBase & SCRATCH_PAD0_OFFSET_MASK;
  887     /* get PCI BAR */
  888     MSGUCfgTblBase = (MSGUCfgTblBase & SCRATCH_PAD0_BAR_MASK) >> SHIFT26;
  889 
  890     /* convert the PCI BAR to logical bar number */
  891     pcibar = (bit8)mpiGetPCIBarIndex(agRoot, MSGUCfgTblBase);
  892 
  893     /* get controller information */
  894     controllerInfo->signature =         ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx);
  895     controllerInfo->fwInterfaceRev =    ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_INTERFACE_REVISION);
  896     controllerInfo->fwRevision =        ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_FW_REVISION);
  897     controllerInfo->ilaRevision =       ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_ILAT_ILAV_ILASMRN_ILAMRN_ILAMJN);
  898     controllerInfo->maxPendingIO =      ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_MAX_OUTSTANDING_IO_OFFSET);
  899     controllerInfo->maxDevices =       (ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_MAX_SGL_OFFSET) & MAIN_MAX_DEV_BITS);
  900     controllerInfo->maxDevices =        controllerInfo->maxDevices >> SHIFT16;
  901     controllerInfo->maxSgElements =    (ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_MAX_SGL_OFFSET) & MAIN_MAX_SGL_BITS);
  902 
  903     if( smIS_SPC(agRoot))
  904     {
  905       SA_DBG2(("saGetControllerInfo: LINK_CTRL 0x%08x Speed 0x%X Lanes 0x%X \n", ossaHwRegReadConfig32(agRoot,128),
  906         ((ossaHwRegReadConfig32(agRoot,128) & 0x000F0000) >> 16),
  907         ((ossaHwRegReadConfig32(agRoot,128) & 0x0FF00000) >> 20) ));
  908       controllerInfo->PCILinkRate =  ((ossaHwRegReadConfig32(agRoot,128) & 0x000F0000) >> 16);
  909       controllerInfo->PCIWidth =   ((ossaHwRegReadConfig32(agRoot,128) & 0x0FF00000) >> 20);
  910     }
  911     else
  912     {
  913       SA_DBG2(("saGetControllerInfo: LINK_CTRL 0x%08x Speed 0x%X Lanes 0x%X \n", ossaHwRegReadConfig32(agRoot,208),
  914         ((ossaHwRegReadConfig32(agRoot,208) & 0x000F0000) >> 16),
  915         ((ossaHwRegReadConfig32(agRoot,208) & 0x0FF00000) >> 20) ));
  916       controllerInfo->PCILinkRate =  ((ossaHwRegReadConfig32(agRoot,208) & 0x000F0000) >> 16);
  917       controllerInfo->PCIWidth =   ((ossaHwRegReadConfig32(agRoot,208) & 0x0FF00000) >> 20);
  918     }
  919 
  920 
  921     ContrlCapFlag =                     ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_CNTRL_CAP_OFFSET);
  922     controllerInfo->queueSupport =      ContrlCapFlag & MAIN_QSUPPORT_BITS;
  923     controllerInfo->phyCount =         (bit8)((ContrlCapFlag & MAIN_PHY_COUNT_MASK) >> SHIFT19);
  924 
  925 
  926     if(smIS_SPCV(agRoot))
  927     {
  928       controllerInfo->controllerSetting = (bit8)((siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1) & SCRATCH_PAD1_V_BOOTSTATE_MASK ) >> SHIFT4);
  929     }
  930     else
  931     {
  932       controllerInfo->controllerSetting = (bit8)(ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_HDA_FLAGS_OFFSET) & MAIN_HDA_FLAG_BITS);
  933     }
  934     controllerInfo->sasSpecsSupport =   (ContrlCapFlag & MAIN_SAS_SUPPORT_BITS) >> SHIFT25;
  935   }
  936 
  937   SA_DBG1(("saGetControllerInfo: signature         0x%X\n", controllerInfo->signature));
  938   SA_DBG1(("saGetControllerInfo: fwInterfaceRev    0x%X\n", controllerInfo->fwInterfaceRev));
  939   SA_DBG1(("saGetControllerInfo: hwRevision        0x%X\n", controllerInfo->hwRevision));
  940   SA_DBG1(("saGetControllerInfo: fwRevision        0x%X\n", controllerInfo->fwRevision));
  941   SA_DBG1(("saGetControllerInfo: ilaRevision       0x%X\n", controllerInfo->ilaRevision));
  942   SA_DBG1(("saGetControllerInfo: maxPendingIO      0x%X\n", controllerInfo->maxPendingIO));
  943   SA_DBG1(("saGetControllerInfo: maxDevices        0x%X\n", controllerInfo->maxDevices));
  944   SA_DBG1(("saGetControllerInfo: maxSgElements     0x%X\n", controllerInfo->maxSgElements));
  945   SA_DBG1(("saGetControllerInfo: queueSupport      0x%X\n", controllerInfo->queueSupport));
  946   SA_DBG1(("saGetControllerInfo: phyCount          0x%X\n", controllerInfo->phyCount));
  947   SA_DBG1(("saGetControllerInfo: controllerSetting 0x%X\n", controllerInfo->controllerSetting));
  948   SA_DBG1(("saGetControllerInfo: PCILinkRate       0x%X\n", controllerInfo->PCILinkRate));
  949   SA_DBG1(("saGetControllerInfo: PCIWidth          0x%X\n", controllerInfo->PCIWidth));
  950   SA_DBG1(("saGetControllerInfo: sasSpecsSupport   0x%X\n", controllerInfo->sasSpecsSupport));
  951   SA_DBG1(("saGetControllerInfo: sdkInterfaceRev   0x%X\n", controllerInfo->sdkInterfaceRev));
  952   SA_DBG1(("saGetControllerInfo: sdkRevision       0x%X\n", controllerInfo->sdkRevision));
  953   if (agNULL != agRoot->sdkData)
  954   {
  955     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6e");
  956   }
  957   return ret;
  958 }
  959 
  960 /******************************************************************************/
  961 /*! \brief SPC Get Controller Status Command
  962  *
  963  *  This command sends Get Controller Status Command to SPC.
  964  *
  965  *  \param agRoot           Handles for this instance of SAS/SATA LL
  966  *  \param controllerStatus controller status
  967  *
  968  *  \return If the MPI command is sent to SPC successfully
  969  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
  970  *          - \e AGSA_RC_FAILURE the MPI command is failure
  971  *
  972  */
  973 /*******************************************************************************/
  974 GLOBAL bit32 saGetControllerStatus(
  975                         agsaRoot_t                *agRoot,
  976                         agsaControllerStatus_t    *controllerStatus
  977                         )
  978 {
  979   bit32 ret = AGSA_RC_SUCCESS;
  980   agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
  981   spc_GSTableDescriptor_t GSTable;
  982   bit32 max_wait_time;
  983   bit32 max_wait_count;
  984   bit32 i, value, value1;
  985 
  986   if (agNULL != saRoot)
  987   {
  988     smTraceFuncEnter(hpDBG_VERY_LOUD,"6f");
  989   }
  990   /* clean the structure */
  991   si_memset(controllerStatus, 0, sizeof(agsaControllerStatus_t));
  992   si_memset(&GSTable, 0, sizeof(spc_GSTableDescriptor_t));
  993   if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0) == 0xFFFFFFFF)
  994   {
  995     SA_DBG1(("saGetControllerStatus:AGSA_RC_FAILURE SCRATCH_PAD0 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0)));
  996     return AGSA_RC_FAILURE;
  997   }
  998 
  999   if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_3)  & (OSSA_ENCRYPT_ENGINE_FAILURE_MASK | OSSA_DIF_ENGINE_FAILURE_MASK))
 1000   {
 1001     SA_DBG1(("saGetControllerStatus: BIST error in SCRATCHPAD 3 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_3,  MSGU_SCRATCH_PAD_3)));
 1002   }
 1003 
 1004   if(smIS_SPC(agRoot))
 1005   {
 1006 
 1007     /* read detail fatal errors */
 1008     controllerStatus->fatalErrorInfo.errorInfo0 = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_0);
 1009     controllerStatus->fatalErrorInfo.errorInfo1 = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_1);
 1010     controllerStatus->fatalErrorInfo.errorInfo2 = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_2);
 1011     controllerStatus->fatalErrorInfo.errorInfo3 = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_3);
 1012 
 1013 #if defined(SALLSDK_DEBUG)
 1014     SA_DBG1(("saGetControllerStatus: SCRATCH_PAD0 value = 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo0));
 1015     SA_DBG1(("saGetControllerStatus: SCRATCH_PAD1 value = 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo1));
 1016     SA_DBG1(("saGetControllerStatus: SCRATCH_PAD2 value = 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo2));
 1017     SA_DBG1(("saGetControllerStatus: SCRATCH_PAD3 value = 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo3));
 1018 #endif
 1019 
 1020     /* check HDA mode */
 1021     value = ossaHwRegReadExt(agRoot, PCIBAR3, HDA_RSP_OFFSET1MB+HDA_CMD_CODE_OFFSET) & HDA_STATUS_BITS;
 1022 
 1023     if (value == BOOTTLOADERHDA_IDLE)
 1024     {
 1025       /* HDA mode */
 1026       SA_DBG1(("saGetControllerStatus: HDA mode, value = 0x%x\n", value));
 1027       return AGSA_RC_HDA_NO_FW_RUNNING;
 1028     }
 1029 
 1030     /* check error state */
 1031     value = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_1);
 1032     value1 = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_2);
 1033 
 1034     /* check AAP or IOP error */
 1035     if ((SCRATCH_PAD1_ERR == (value & SCRATCH_PAD_STATE_MASK)) || (SCRATCH_PAD2_ERR == (value1 & SCRATCH_PAD_STATE_MASK)))
 1036     {
 1037       if (agNULL != saRoot)
 1038       {
 1039         controllerStatus->fatalErrorInfo.regDumpBusBaseNum0 = saRoot->mainConfigTable.regDumpPCIBAR;
 1040         controllerStatus->fatalErrorInfo.regDumpOffset0 = saRoot->mainConfigTable.FatalErrorDumpOffset0;
 1041         controllerStatus->fatalErrorInfo.regDumpLen0 = saRoot->mainConfigTable.FatalErrorDumpLength0;
 1042         controllerStatus->fatalErrorInfo.regDumpBusBaseNum1 = saRoot->mainConfigTable.regDumpPCIBAR;
 1043         controllerStatus->fatalErrorInfo.regDumpOffset1 = saRoot->mainConfigTable.FatalErrorDumpOffset1;
 1044         controllerStatus->fatalErrorInfo.regDumpLen1 = saRoot->mainConfigTable.FatalErrorDumpLength1;
 1045       }
 1046       else
 1047       {
 1048         controllerStatus->fatalErrorInfo.regDumpBusBaseNum0 = 0;
 1049         controllerStatus->fatalErrorInfo.regDumpOffset0 = 0;
 1050         controllerStatus->fatalErrorInfo.regDumpLen0 = 0;
 1051         controllerStatus->fatalErrorInfo.regDumpBusBaseNum1 = 0;
 1052         controllerStatus->fatalErrorInfo.regDumpOffset1 = 0;
 1053         controllerStatus->fatalErrorInfo.regDumpLen1 = 0;
 1054       }
 1055 
 1056       if (agNULL != saRoot)
 1057       {
 1058         smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6f");
 1059       }
 1060       return AGSA_RC_FW_NOT_IN_READY_STATE;
 1061     }
 1062 
 1063     /* checking the fw AAP and IOP in ready state */
 1064     max_wait_time = WAIT_SECONDS(2);  /* 2 sec timeout */
 1065     max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT);
 1066     /* wait until scratch pad 1 and 2 registers in ready state  */
 1067     do
 1068     {
 1069       ossaStallThread(agRoot, WAIT_INCREMENT);
 1070       value = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_1);
 1071       /* checking bit 4 to 7 for reserved in case we get 0xFFFFFFFF */
 1072       if (value & SCRATCH_PAD1_RESERVED)
 1073       {
 1074         SA_DBG1(("saGetControllerStatus: (Reserved bit not 0) SCRATCH_PAD1 value = 0x%x\n", value));
 1075         ret = AGSA_RC_FAILURE;
 1076         break;
 1077       }
 1078 
 1079       value1 = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_2);
 1080       /* checking bit 4 to 7 for reserved in case we get 0xFFFFFFFF */
 1081       if (value1 & SCRATCH_PAD2_RESERVED)
 1082       {
 1083         SA_DBG1(("saGetControllerStatus: (Reserved bit not 0) SCRATCH_PAD2 value = 0x%x\n", value1));
 1084         ret = AGSA_RC_FAILURE;
 1085         break;
 1086       }
 1087 
 1088       if ((max_wait_count -=WAIT_INCREMENT) == 0)
 1089       {
 1090         SA_DBG1(("saGetControllerStatus: Timeout!! SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1));
 1091         break;
 1092       }
 1093     } while (((value & SCRATCH_PAD_STATE_MASK) != SCRATCH_PAD1_RDY) || ((value1 & SCRATCH_PAD_STATE_MASK) != SCRATCH_PAD2_RDY));
 1094 
 1095     if (!max_wait_count)
 1096     {
 1097       SA_DBG1(("saGetControllerStatus: timeout failure\n"));
 1098       ret = AGSA_RC_FAILURE;
 1099     }
 1100 
 1101     if (ret == AGSA_RC_SUCCESS)
 1102     {
 1103       SA_DBG1(("saGetControllerStatus: FW Ready, SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1));
 1104 
 1105       /* read scratch pad0 to get PCI BAR and offset of configuration table */
 1106       value = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_0);
 1107       /* get offset */
 1108       value1 = value & SCRATCH_PAD0_OFFSET_MASK;
 1109       /* get PCI BAR */
 1110       value = (value & SCRATCH_PAD0_BAR_MASK) >> SHIFT26;
 1111 
 1112       /* read GST Table state */
 1113       mpiReadGSTable(agRoot, &GSTable);
 1114 
 1115       /* read register dump information */
 1116       controllerStatus->fatalErrorInfo.regDumpBusBaseNum0 = value;
 1117       controllerStatus->fatalErrorInfo.regDumpBusBaseNum1 = value;
 1118       /* convert the PCI BAR to logical bar number */
 1119       value = (bit8)mpiGetPCIBarIndex(agRoot, value);
 1120       controllerStatus->fatalErrorInfo.regDumpOffset0 = ossaHwRegReadExt(agRoot, value, value1 + MAIN_FATAL_ERROR_RDUMP0_OFFSET);
 1121       controllerStatus->fatalErrorInfo.regDumpLen0    = ossaHwRegReadExt(agRoot, value, value1 + MAIN_FATAL_ERROR_RDUMP0_LENGTH);
 1122       controllerStatus->fatalErrorInfo.regDumpOffset1 = ossaHwRegReadExt(agRoot, value, value1 + MAIN_FATAL_ERROR_RDUMP1_OFFSET);
 1123       controllerStatus->fatalErrorInfo.regDumpLen1    = ossaHwRegReadExt(agRoot, value, value1 + MAIN_FATAL_ERROR_RDUMP1_LENGTH);
 1124 
 1125       /* AAP/IOP error state */
 1126       SA_DBG2(("saGetControllerStatus: SCRATCH PAD0 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo0));
 1127       SA_DBG2(("saGetControllerStatus: SCRATCH PAD1 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo1));
 1128       SA_DBG2(("saGetControllerStatus: SCRATCH PAD2 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo2));
 1129       SA_DBG2(("saGetControllerStatus: SCRATCH PAD3 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo3));
 1130       /* Register Dump information */
 1131       SA_DBG2(("saGetControllerStatus: RegDumpOffset0 0x%x\n", controllerStatus->fatalErrorInfo.regDumpOffset0));
 1132       SA_DBG2(("saGetControllerStatus: RegDumpLen0    0x%x\n", controllerStatus->fatalErrorInfo.regDumpLen0));
 1133       SA_DBG2(("saGetControllerStatus: RegDumpOffset1 0x%x\n", controllerStatus->fatalErrorInfo.regDumpOffset1));
 1134       SA_DBG2(("saGetControllerStatus: RegDumpLen1    0x%x\n", controllerStatus->fatalErrorInfo.regDumpLen1));
 1135 
 1136       controllerStatus->interfaceState = GSTable.GSTLenMPIS & GST_INF_STATE_BITS;
 1137       controllerStatus->iqFreezeState0 = GSTable.IQFreezeState0;
 1138       controllerStatus->iqFreezeState1 = GSTable.IQFreezeState1;
 1139       for (i = 0; i < 8; i++)
 1140       {
 1141         controllerStatus->phyStatus[i] = GSTable.PhyState[i];
 1142         controllerStatus->recoverableErrorInfo[i] = GSTable.recoverErrInfo[i];
 1143       }
 1144       controllerStatus->tickCount0 = GSTable.MsguTcnt;
 1145       controllerStatus->tickCount1 = GSTable.IopTcnt;
 1146       controllerStatus->tickCount2 = GSTable.Iop1Tcnt;
 1147     }
 1148   }
 1149   else
 1150   {
 1151 
 1152     SA_DBG1(("saGetControllerStatus: SPCv\n" ));
 1153 
 1154 
 1155     if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1) &   SCRATCH_PAD1_V_RESERVED )
 1156     {
 1157       SA_DBG1(("saGetControllerStatus: Warning SCRATCH_PAD1 reserved bits set value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1)));
 1158     }
 1159     if( si_check_V_HDA(agRoot))
 1160     {
 1161       /*  Check HDA */
 1162 
 1163       controllerStatus->fatalErrorInfo.errorInfo0 = ossaHwRegRead(agRoot,V_Scratchpad_0_Register );
 1164       controllerStatus->fatalErrorInfo.errorInfo1 = ossaHwRegRead(agRoot,V_Scratchpad_1_Register );
 1165       controllerStatus->fatalErrorInfo.errorInfo2 = ossaHwRegRead(agRoot,V_Scratchpad_2_Register );
 1166       controllerStatus->fatalErrorInfo.errorInfo3 = ossaHwRegRead(agRoot,V_Scratchpad_3_Register );
 1167       SA_DBG1(("saGetControllerStatus: HDA mode, AGSA_RC_HDA_NO_FW_RUNNING errorInfo1  = 0x%x\n",controllerStatus->fatalErrorInfo.errorInfo1 ));
 1168       return AGSA_RC_HDA_NO_FW_RUNNING;
 1169     }
 1170 
 1171     ret = si_check_V_Ready(agRoot);
 1172     /* Check ready */
 1173     if (ret == AGSA_RC_SUCCESS)
 1174     {
 1175       /* read GST Table state */
 1176       mpiReadGSTable(agRoot, &GSTable);
 1177       controllerStatus->interfaceState = GSTable.GSTLenMPIS & GST_INF_STATE_BITS;
 1178       controllerStatus->iqFreezeState0 = GSTable.IQFreezeState0;
 1179       controllerStatus->iqFreezeState1 = GSTable.IQFreezeState1;
 1180       for (i = 0; i < 8; i++)
 1181       {
 1182         controllerStatus->phyStatus[i] = GSTable.PhyState[i];
 1183         controllerStatus->recoverableErrorInfo[i] = GSTable.recoverErrInfo[i];
 1184       }
 1185       controllerStatus->tickCount0 = GSTable.MsguTcnt;
 1186       controllerStatus->tickCount1 = GSTable.IopTcnt;
 1187       controllerStatus->tickCount2 = GSTable.Iop1Tcnt;
 1188 
 1189       controllerStatus->interfaceState = GSTable.GSTLenMPIS & GST_INF_STATE_BITS;
 1190       controllerStatus->iqFreezeState0 = GSTable.IQFreezeState0;
 1191       controllerStatus->iqFreezeState1 = GSTable.IQFreezeState1;
 1192       for (i = 0; i < 8; i++)
 1193       {
 1194         if( IS_SDKDATA(agRoot))
 1195         {
 1196           if (agNULL != saRoot)
 1197           {
 1198             controllerStatus->phyStatus[i] = ((saRoot->phys[i+8].linkstatus << SHIFT8) | saRoot->phys[i].linkstatus);
 1199           }
 1200         }
 1201         else
 1202         {
 1203           controllerStatus->phyStatus[i] = 0;
 1204         }
 1205         controllerStatus->recoverableErrorInfo[i] = GSTable.recoverErrInfo[i];
 1206       }
 1207       controllerStatus->tickCount0 = GSTable.MsguTcnt;
 1208       controllerStatus->tickCount1 = GSTable.IopTcnt;
 1209       controllerStatus->tickCount2 = GSTable.Iop1Tcnt;
 1210 
 1211     }
 1212 
 1213     SA_DBG1(("saGetControllerStatus: SCRATCH_PAD0 value = 0x%x\n", ossaHwRegRead(agRoot, V_Scratchpad_0_Register)));
 1214     SA_DBG1(("saGetControllerStatus: SCRATCH_PAD1 value = 0x%x\n", ossaHwRegRead(agRoot, V_Scratchpad_1_Register)));
 1215     SA_DBG1(("saGetControllerStatus: SCRATCH_PAD2 value = 0x%x\n", ossaHwRegRead(agRoot, V_Scratchpad_2_Register)));
 1216     SA_DBG1(("saGetControllerStatus: SCRATCH_PAD3 value = 0x%x\n", ossaHwRegRead(agRoot, V_Scratchpad_3_Register)));
 1217 
 1218     controllerStatus->fatalErrorInfo.errorInfo0 = ossaHwRegRead(agRoot,V_Scratchpad_0_Register );
 1219     controllerStatus->fatalErrorInfo.errorInfo1 = ossaHwRegRead(agRoot,V_Scratchpad_1_Register );
 1220     controllerStatus->fatalErrorInfo.errorInfo2 = ossaHwRegRead(agRoot,V_Scratchpad_2_Register );
 1221     controllerStatus->fatalErrorInfo.errorInfo3 = ossaHwRegRead(agRoot,V_Scratchpad_3_Register );
 1222 
 1223     controllerStatus->bootStatus = ( (( controllerStatus->fatalErrorInfo.errorInfo1 >>  SHIFT9) & 1 )                | /* bit 1  */
 1224                                      (( controllerStatus->fatalErrorInfo.errorInfo3 & 0x3)               << SHIFT16) | /* bit 16 17 */
 1225                                     ((( controllerStatus->fatalErrorInfo.errorInfo3 >>  SHIFT14) & 0x7)  << SHIFT18) | /* bit 18 19 20 */
 1226                                     ((( controllerStatus->fatalErrorInfo.errorInfo3 >>  SHIFT4 ) & 0x1)  << SHIFT23) | /* bit 23 */
 1227                                     ((( controllerStatus->fatalErrorInfo.errorInfo3 >>  SHIFT16) & 0xFF) << SHIFT24) );/* bit 24 31 */
 1228 
 1229     controllerStatus->bootComponentState[0] = (bit16) (( controllerStatus->fatalErrorInfo.errorInfo1               & 3 ) | 0x8000); /* RAAE_STATE */
 1230     controllerStatus->bootComponentState[1] = (bit16) ((( controllerStatus->fatalErrorInfo.errorInfo1 >>  SHIFT10) & 3 ) | 0x8000); /* IOP0_STATE */
 1231     controllerStatus->bootComponentState[2] = (bit16) ((( controllerStatus->fatalErrorInfo.errorInfo1 >>  SHIFT12) & 3 ) | 0x8000); /* IOP1_STATE */
 1232     controllerStatus->bootComponentState[3] = (bit16) ((( controllerStatus->fatalErrorInfo.errorInfo1 >>  SHIFT4)  & 7 ) | 0x8000); /* BOOTLDR_STATE  */
 1233     controllerStatus->bootComponentState[4] = (bit16) ((( controllerStatus->fatalErrorInfo.errorInfo1 >>  SHIFT2)  & 3 ) | 0x8000); /* ILA State */
 1234     controllerStatus->bootComponentState[5] = 0;
 1235     controllerStatus->bootComponentState[6] = 0;
 1236     controllerStatus->bootComponentState[7] = 0;
 1237 
 1238 
 1239 
 1240     if(controllerStatus->fatalErrorInfo.errorInfo0 == 0xFFFFFFFF)
 1241     {
 1242       ret = AGSA_RC_FAILURE;
 1243     }
 1244 
 1245   }
 1246 
 1247   SA_DBG1(("saGetControllerStatus: fatalErrorInfo.errorInfo0          0x%x\n", controllerStatus->fatalErrorInfo.errorInfo0));
 1248   SA_DBG1(("saGetControllerStatus: fatalErrorInfo.errorInfo1          0x%x\n", controllerStatus->fatalErrorInfo.errorInfo1));
 1249   SA_DBG1(("saGetControllerStatus: fatalErrorInfo.errorInfo2          0x%x\n", controllerStatus->fatalErrorInfo.errorInfo2));
 1250   SA_DBG1(("saGetControllerStatus: fatalErrorInfo.errorInfo3          0x%x\n", controllerStatus->fatalErrorInfo.errorInfo3));
 1251   SA_DBG1(("saGetControllerStatus: fatalErrorInfo.regDumpBusBaseNum0  0x%x\n", controllerStatus->fatalErrorInfo.regDumpBusBaseNum0));
 1252   SA_DBG1(("saGetControllerStatus: fatalErrorInfo.regDumpOffset0      0x%x\n", controllerStatus->fatalErrorInfo.regDumpOffset0));
 1253   SA_DBG1(("saGetControllerStatus: fatalErrorInfo.regDumpLen0         0x%x\n", controllerStatus->fatalErrorInfo.regDumpLen0));
 1254   SA_DBG1(("saGetControllerStatus: fatalErrorInfo.regDumpBusBaseNum1  0x%x\n", controllerStatus->fatalErrorInfo.regDumpBusBaseNum1));
 1255   SA_DBG1(("saGetControllerStatus: fatalErrorInfo.regDumpOffset1      0x%x\n", controllerStatus->fatalErrorInfo.regDumpOffset1));
 1256   SA_DBG1(("saGetControllerStatus: fatalErrorInfo.regDumpLen1         0x%x\n", controllerStatus->fatalErrorInfo.regDumpLen1));
 1257 
 1258   SA_DBG1(("saGetControllerStatus: interfaceState                     0x%x\n", controllerStatus->interfaceState));
 1259   SA_DBG1(("saGetControllerStatus: iqFreezeState0                     0x%x\n", controllerStatus->iqFreezeState0));
 1260   SA_DBG1(("saGetControllerStatus: iqFreezeState1                     0x%x\n", controllerStatus->iqFreezeState1));
 1261   SA_DBG1(("saGetControllerStatus: tickCount0                         0x%x\n", controllerStatus->tickCount0));
 1262   SA_DBG1(("saGetControllerStatus: tickCount1                         0x%x\n", controllerStatus->tickCount1));
 1263   SA_DBG1(("saGetControllerStatus: tickCount2                         0x%x\n", controllerStatus->tickCount2));
 1264 
 1265   SA_DBG1(("saGetControllerStatus: phyStatus[0]                       0x%08x\n", controllerStatus->phyStatus[0]));
 1266   SA_DBG1(("saGetControllerStatus: phyStatus[1]                       0x%08x\n", controllerStatus->phyStatus[1]));
 1267   SA_DBG1(("saGetControllerStatus: phyStatus[2]                       0x%08x\n", controllerStatus->phyStatus[2]));
 1268   SA_DBG1(("saGetControllerStatus: phyStatus[3]                       0x%08x\n", controllerStatus->phyStatus[3]));
 1269   SA_DBG1(("saGetControllerStatus: phyStatus[4]                       0x%08x\n", controllerStatus->phyStatus[4]));
 1270   SA_DBG1(("saGetControllerStatus: phyStatus[5]                       0x%08x\n", controllerStatus->phyStatus[5]));
 1271   SA_DBG1(("saGetControllerStatus: phyStatus[6]                       0x%08x\n", controllerStatus->phyStatus[6]));
 1272   SA_DBG1(("saGetControllerStatus: phyStatus[7]                       0x%08x\n", controllerStatus->phyStatus[7]));
 1273 
 1274   SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[0]            0x%08x\n", controllerStatus->recoverableErrorInfo[0]));
 1275   SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[1]            0x%08x\n", controllerStatus->recoverableErrorInfo[1]));
 1276   SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[2]            0x%08x\n", controllerStatus->recoverableErrorInfo[2]));
 1277   SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[3]            0x%08x\n", controllerStatus->recoverableErrorInfo[3]));
 1278   SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[4]            0x%08x\n", controllerStatus->recoverableErrorInfo[4]));
 1279   SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[5]            0x%08x\n", controllerStatus->recoverableErrorInfo[5]));
 1280   SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[6]            0x%08x\n", controllerStatus->recoverableErrorInfo[6]));
 1281   SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[7]            0x%08x\n", controllerStatus->recoverableErrorInfo[7]));
 1282 
 1283   SA_DBG1(("saGetControllerStatus: bootStatus                         0x%08x\n", controllerStatus->bootStatus));
 1284   SA_DBG1(("saGetControllerStatus: bootStatus  Active FW Image        %x\n", (controllerStatus->bootStatus & 1 ) ? 1 : 0 ));
 1285   SA_DBG1(("saGetControllerStatus: bootStatus  Encryption Cap         %x\n", ((controllerStatus->bootStatus & 0x30000 ) >> SHIFT16) ));
 1286   SA_DBG1(("saGetControllerStatus: bootStatus  Encryption Sec Mode    %x\n", ((controllerStatus->bootStatus & 0xC0000 ) >> SHIFT18) ));
 1287   SA_DBG1(("saGetControllerStatus: bootStatus  Encryption AES XTS     %x\n", (controllerStatus->bootStatus & 0x800000 ) ? 1 : 0 ));
 1288   SA_DBG1(("saGetControllerStatus: bootStatus  Encryption Engine Stat 0x%x\n", ((controllerStatus->bootStatus & 0xFF000000 ) >> SHIFT24)  ));
 1289 
 1290 /*
 1291 
 1292 Bit 0 : Active FW Image
 1293 0b: Primary Image
 1294 1b: Secondary Image
 1295 
 1296 Bit 16-17 :  Encryption Capability
 1297 00: Not supported. Controller firmware version doesn't support encryption functionality.
 1298 01: Disabled due to error. Controller firmware supports encryption however, the functionality is currently disabled due to an error. The actual cause of the error is indicated in the error code field (bits [23:16]).
 1299 10: Enabled with Error. Encryption is currently enabled however, firmware encountered encryption-related error during initialization which might have caused the controller to enter SMF Security mode and/or disabled access to non-volatile memory for encryption-related information. The actual cause of the error is indicated in the error code field (bits [23:16]).
 1300 11: Enabled. Encryption functionality is enabled and fully functional.
 1301 Bit 18-21 : Encryption Current Security Mode
 1302 0000: Security Mode Factory
 1303 0001: Security Mode A
 1304 0010: Security Mode B
 1305 All other values are reserved.
 1306 Bit22: Reserved
 1307 Bit 23 : Encryption AES XTS Enabled
 1308 0: AES XTS is disabled.
 1309 1: AES XTS is enabled
 1310 Bit 24-31 : Encryption Engine Status
 1311 */
 1312 
 1313 
 1314   SA_DBG1(("saGetControllerStatus: bootComponentState[0] RAAE_STATE   0x%x\n", controllerStatus->bootComponentState[0]));
 1315   SA_DBG1(("saGetControllerStatus: bootComponentState[1] IOP0_STATE   0x%x\n", controllerStatus->bootComponentState[1]));
 1316   SA_DBG1(("saGetControllerStatus: bootComponentState[2] IOP1_STATE   0x%x\n", controllerStatus->bootComponentState[2]));
 1317   SA_DBG1(("saGetControllerStatus: bootComponentState[3] BOOTLDR_     0x%x\n", controllerStatus->bootComponentState[3]));
 1318   SA_DBG1(("saGetControllerStatus: bootComponentState[4] ILA State    0x%x\n", controllerStatus->bootComponentState[4]));
 1319   SA_DBG1(("saGetControllerStatus: bootComponentState[5]              0x%x\n", controllerStatus->bootComponentState[5]));
 1320   SA_DBG1(("saGetControllerStatus: bootComponentState[6]              0x%x\n", controllerStatus->bootComponentState[6]));
 1321   SA_DBG1(("saGetControllerStatus: bootComponentState[7]              0x%x\n", controllerStatus->bootComponentState[7]));
 1322 
 1323   if (agNULL != saRoot)
 1324   {
 1325     smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6f");
 1326   }
 1327 
 1328   return ret;
 1329 }
 1330 
 1331 /******************************************************************************/
 1332 /*! \brief SPC Get Controller Event Log Information Command
 1333  *
 1334  *  This command sends Get Controller Event Log Information Command to SPC.
 1335  *
 1336  *  \param agRoot       Handles for this instance of SAS/SATA LL
 1337  *  \param eventLogInfo event log information
 1338  *
 1339  *  \return If the MPI command is sent to SPC successfully
 1340  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
 1341  *          - \e AGSA_RC_FAILURE the MPI command is failure
 1342  *
 1343  */
 1344 /*******************************************************************************/
 1345 GLOBAL bit32 saGetControllerEventLogInfo(
 1346                         agsaRoot_t                *agRoot,
 1347                         agsaControllerEventLog_t  *eventLogInfo
 1348                         )
 1349 {
 1350   bit32 ret           = AGSA_RC_SUCCESS;
 1351   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
 1352 
 1353   smTraceFuncEnter(hpDBG_VERY_LOUD,"6g");
 1354 
 1355   /* sanity check */
 1356   SA_ASSERT((agNULL != agRoot), "");
 1357 
 1358   eventLogInfo->eventLog1 = saRoot->memoryAllocated.agMemory[MPI_MEM_INDEX + MPI_EVENTLOG_INDEX];
 1359   eventLogInfo->eventLog1Option = saRoot->mainConfigTable.eventLogOption;
 1360   eventLogInfo->eventLog2 = saRoot->memoryAllocated.agMemory[MPI_MEM_INDEX + MPI_IOP_EVENTLOG_INDEX];
 1361   eventLogInfo->eventLog2Option = saRoot->mainConfigTable.IOPeventLogOption;
 1362 
 1363   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6g");
 1364 
 1365   return ret;
 1366 }
 1367 
 1368 /******************************************************************************/
 1369 /*! \brief SPC Set GPIO Event Setup Command
 1370  *
 1371  *  This command sends GPIO Event Setup Command to SPC.
 1372  *
 1373  *  \param agRoot             Handles for this instance of SAS/SATA LL
 1374  *  \param agsaContext        Context of this command
 1375  *  \param queueNum           Queue number of inbound/outbound queue
 1376  *  \param gpioEventSetupInfo Pointer of Event Setup Information structure
 1377  *
 1378  *  \return If the MPI command is sent to SPC successfully
 1379  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
 1380  *          - \e AGSA_RC_FAILURE the MPI command is failure
 1381  *
 1382  */
 1383 /*******************************************************************************/
 1384 GLOBAL bit32 saGpioEventSetup(
 1385                         agsaRoot_t                *agRoot,
 1386                         agsaContext_t             *agContext,
 1387                         bit32                     queueNum,
 1388                         agsaGpioEventSetupInfo_t  *gpioEventSetupInfo
 1389                         )
 1390 {
 1391   bit32 ret           = AGSA_RC_SUCCESS;
 1392   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
 1393   agsaIORequestDesc_t *pRequest;
 1394   agsaGPIOCmd_t       payload;
 1395 
 1396   smTraceFuncEnter(hpDBG_VERY_LOUD,"6h");
 1397 
 1398   /* sanity check */
 1399   SA_ASSERT((agNULL != agRoot), "");
 1400 
 1401   /* Get request from free IORequests */
 1402   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1403   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
 1404 
 1405   /* If no LL Control request entry available */
 1406   if ( agNULL == pRequest )
 1407   {
 1408     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1409     SA_DBG1(("saGpioEventSetup, No request from free list\n" ));
 1410     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6h");
 1411     return AGSA_RC_BUSY;
 1412   }
 1413   /* If LL Control request entry avaliable */
 1414   else
 1415   {
 1416     /* Remove the request from free list */
 1417     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
 1418     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
 1419     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
 1420     saRoot->IOMap[pRequest->HTag].agContext = agContext;
 1421     pRequest->valid = agTRUE;
 1422 
 1423     /* set payload to zeros */
 1424     si_memset(&payload, 0, sizeof(agsaGPIOCmd_t));
 1425     /* build IOMB command and send to SPC */
 1426     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, tag), pRequest->HTag);
 1427     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, eOBIDGeGsGrGw), GPIO_GE_BIT);
 1428     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, GPIEVChange), gpioEventSetupInfo->gpioEventLevel);
 1429     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, GPIEVFall), gpioEventSetupInfo->gpioEventFallingEdge);
 1430     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, GPIEVRise), gpioEventSetupInfo->gpioEventRisingEdge);
 1431     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GPIO, IOMB_SIZE64, queueNum);
 1432     if (AGSA_RC_SUCCESS != ret)
 1433     {
 1434       /* remove the request from IOMap */
 1435       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
 1436       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
 1437       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
 1438       pRequest->valid = agFALSE;
 1439 
 1440       /* return the request to free pool */
 1441       if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
 1442       {
 1443         SA_DBG1(("saGpioEventSetup: saving pRequest (%p) for later use\n", pRequest));
 1444         saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
 1445       }
 1446       else
 1447       {
 1448         /* return the request to free pool */
 1449         saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
 1450       }
 1451       SA_DBG1(("saGpioEventSetup, sending IOMB failed\n" ));
 1452     }
 1453   }
 1454 
 1455   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1456   smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6h");
 1457 
 1458   return ret;
 1459 }
 1460 
 1461 /******************************************************************************/
 1462 /*! \brief SPC Set GPIO Pin Setup Command
 1463  *
 1464  *  This command sends GPIO Pin Setup Command to SPC.
 1465  *
 1466  *  \param agRoot             Handles for this instance of SAS/SATA LL
 1467  *  \param agsaContext        Context of this command
 1468  *  \param queueNum           Queue number of inbound/outbound queue
 1469  *  \param gpioPinSetupInfo   Pointer of Event Setup Information structure
 1470  *
 1471  *  \return If the MPI command is sent to SPC successfully
 1472  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
 1473  *          - \e AGSA_RC_FAILURE the MPI command is failure
 1474  *
 1475  */
 1476 /*******************************************************************************/
 1477 GLOBAL bit32 saGpioPinSetup(
 1478                         agsaRoot_t                *agRoot,
 1479                         agsaContext_t             *agContext,
 1480                         bit32                     queueNum,
 1481                         agsaGpioPinSetupInfo_t    *gpioPinSetupInfo
 1482                         )
 1483 {
 1484   bit32 ret           = AGSA_RC_SUCCESS;
 1485   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
 1486   agsaIORequestDesc_t *pRequest;
 1487   agsaGPIOCmd_t       payload;
 1488 
 1489   smTraceFuncEnter(hpDBG_VERY_LOUD,"6i");
 1490 
 1491   /* sanity check */
 1492   SA_ASSERT((agNULL != agRoot), "");
 1493 
 1494   /* Get request from free IORequests */
 1495   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1496   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
 1497 
 1498   /* If no LL Control request entry available */
 1499   if ( agNULL == pRequest )
 1500   {
 1501     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1502     SA_DBG1(("saGpioPinSetup, No request from free list\n" ));
 1503     return AGSA_RC_BUSY;
 1504   }
 1505   /* If LL Control request entry avaliable */
 1506   else
 1507   {
 1508     /* Remove the request from free list */
 1509     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
 1510     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
 1511     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
 1512     saRoot->IOMap[pRequest->HTag].agContext = agContext;
 1513     pRequest->valid = agTRUE;
 1514 
 1515     /* set payload to zeros */
 1516     si_memset(&payload, 0, sizeof(agsaGPIOCmd_t));
 1517     /* build IOMB command and send to SPC */
 1518     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, tag), pRequest->HTag);
 1519     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, eOBIDGeGsGrGw), GPIO_GS_BIT);
 1520     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, GpioIe), gpioPinSetupInfo->gpioInputEnabled);
 1521     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, OT11_0), gpioPinSetupInfo->gpioTypePart1);
 1522     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, OT19_12), gpioPinSetupInfo->gpioTypePart2);
 1523     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GPIO, IOMB_SIZE64, queueNum);
 1524     if (AGSA_RC_SUCCESS != ret)
 1525     {
 1526       /* remove the request from IOMap */
 1527       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
 1528       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
 1529       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
 1530       pRequest->valid = agFALSE;
 1531       /* return the request to free pool */
 1532       if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
 1533       {
 1534         SA_DBG1(("saGpioPinSetup: saving pRequest (%p) for later use\n", pRequest));
 1535         saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
 1536       }
 1537       else
 1538       {
 1539         /* return the request to free pool */
 1540         saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
 1541       }
 1542       SA_DBG1(("saGpioPinSetup, sending IOMB failed\n" ));
 1543     }
 1544   }
 1545 
 1546   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1547   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6i");
 1548 
 1549   return ret;
 1550 }
 1551 
 1552 /******************************************************************************/
 1553 /*! \brief SPC GPIO Read Command
 1554  *
 1555  *  This command sends GPIO Read Command to SPC.
 1556  *
 1557  *  \param agRoot       Handles for this instance of SAS/SATA LL
 1558  *  \param agsaContext  Context of this command
 1559  *  \param queueNum     Queue number of inbound/outbound queue
 1560  *
 1561  *  \return If the MPI command is sent to SPC successfully
 1562  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
 1563  *          - \e AGSA_RC_FAILURE the MPI command is failure
 1564  *
 1565  */
 1566 /*******************************************************************************/
 1567 GLOBAL bit32 saGpioRead(
 1568                         agsaRoot_t                *agRoot,
 1569                         agsaContext_t             *agContext,
 1570                         bit32                     queueNum
 1571                         )
 1572 {
 1573   bit32 ret           = AGSA_RC_SUCCESS;
 1574   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
 1575   agsaIORequestDesc_t *pRequest;
 1576   agsaGPIOCmd_t       payload;
 1577 
 1578   smTraceFuncEnter(hpDBG_VERY_LOUD,"6j");
 1579 
 1580   /* sanity check */
 1581   SA_ASSERT((agNULL != agRoot), "");
 1582 
 1583   /* Get request from free IORequests */
 1584   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1585   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
 1586 
 1587   /* If no LL Control request entry available */
 1588   if ( agNULL == pRequest )
 1589   {
 1590     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1591     SA_DBG1(("saGpioRead, No request from free list\n" ));
 1592     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6j");
 1593     return AGSA_RC_BUSY;
 1594   }
 1595   /* If LL Control request entry avaliable */
 1596   else
 1597   {
 1598     /* Remove the request from free list */
 1599     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
 1600     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
 1601     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
 1602     saRoot->IOMap[pRequest->HTag].agContext = agContext;
 1603     pRequest->valid = agTRUE;
 1604 
 1605     /* set payload to zeros */
 1606     si_memset(&payload, 0, sizeof(agsaGPIOCmd_t));
 1607     /* build IOMB command and send to SPC */
 1608     /* set GR bit */
 1609     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, tag), pRequest->HTag);
 1610     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, eOBIDGeGsGrGw), GPIO_GR_BIT);
 1611     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GPIO, IOMB_SIZE64, queueNum);
 1612     if (AGSA_RC_SUCCESS != ret)
 1613     {
 1614       /* remove the request from IOMap */
 1615       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
 1616       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
 1617       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
 1618       pRequest->valid = agFALSE;
 1619       /* return the request to free pool */
 1620       if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
 1621       {
 1622         SA_DBG1(("saGpioRead: saving pRequest (%p) for later use\n", pRequest));
 1623         saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
 1624       }
 1625       else
 1626       {
 1627         /* return the request to free pool */
 1628         saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
 1629       }
 1630       SA_DBG1(("saGpioRead, sending IOMB failed\n" ));
 1631     }
 1632   }
 1633   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1634 
 1635   smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6j");
 1636 
 1637   return ret;
 1638 }
 1639 
 1640 /******************************************************************************/
 1641 /*! \brief SPC GPIO Write Command
 1642  *
 1643  *  This command sends GPIO Write Command to SPC.
 1644  *
 1645  *  \param agRoot         Handles for this instance of SAS/SATA LL
 1646  *  \param agsaContext    Context of this command
 1647  *  \param queueNum       Queue number of inbound/outbound queue
 1648  *  \param gpioWriteMask  GPIO Write Mask
 1649  *  \param gpioWriteValue GPIO Write Value
 1650  *
 1651  *  \return If the MPI command is sent to SPC successfully
 1652  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
 1653  *          - \e AGSA_RC_FAILURE the MPI command is failure
 1654  *
 1655  */
 1656 /*******************************************************************************/
 1657 GLOBAL bit32 saGpioWrite(
 1658                         agsaRoot_t                *agRoot,
 1659                         agsaContext_t             *agContext,
 1660                         bit32                     queueNum,
 1661                         bit32                     gpioWriteMask,
 1662                         bit32                     gpioWriteValue
 1663                         )
 1664 {
 1665   bit32 ret           = AGSA_RC_SUCCESS;
 1666   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
 1667   agsaIORequestDesc_t *pRequest;
 1668   agsaGPIOCmd_t       payload;
 1669 
 1670   smTraceFuncEnter(hpDBG_VERY_LOUD,"6k");
 1671 
 1672   /* sanity check */
 1673   SA_ASSERT((agNULL != agRoot), "");
 1674 
 1675   /* Get request from free IORequests */
 1676   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1677   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
 1678 
 1679   /* If no LL Control request entry available */
 1680   if ( agNULL == pRequest )
 1681   {
 1682     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1683     SA_DBG1(("saGpioWrite, No request from free list\n" ));
 1684     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6k");
 1685     return AGSA_RC_BUSY;
 1686   }
 1687   /* If LL Control request entry avaliable */
 1688   else
 1689   {
 1690     /* Remove the request from free list */
 1691     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
 1692     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
 1693     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
 1694     saRoot->IOMap[pRequest->HTag].agContext = agContext;
 1695     pRequest->valid = agTRUE;
 1696 
 1697     /* set payload to zeros */
 1698     si_memset(&payload, 0, sizeof(agsaGPIOCmd_t));
 1699     /* build IOMB command and send to SPC */
 1700     /* set GW bit */
 1701     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, tag), pRequest->HTag);
 1702     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, eOBIDGeGsGrGw), GPIO_GW_BIT);
 1703     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, GpioWrMsk), gpioWriteMask);
 1704     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, GpioWrVal), gpioWriteValue);
 1705     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GPIO, IOMB_SIZE64, queueNum);
 1706     if (AGSA_RC_SUCCESS != ret)
 1707     {
 1708       /* remove the request from IOMap */
 1709       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
 1710       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
 1711       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
 1712       pRequest->valid = agFALSE;
 1713 
 1714       /* return the request to free pool */
 1715       if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
 1716       {
 1717         SA_DBG1(("saGpioWrite: saving pRequest (%p) for later use\n", pRequest));
 1718         saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
 1719       }
 1720       else
 1721       {
 1722         /* return the request to free pool */
 1723         saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
 1724       }
 1725       SA_DBG1(("saGpioWrite, sending IOMB failed\n" ));
 1726     }
 1727   }
 1728 
 1729   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1730   smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6k");
 1731 
 1732   return ret;
 1733 }
 1734 
 1735 /******************************************************************************/
 1736 /*! \brief SPC SAS Diagnostic Execute Command
 1737  *
 1738  *  This command sends SAS Diagnostic Execute Command to SPC.
 1739  *
 1740  *  \param agRoot         Handles for this instance of SAS/SATA LL
 1741  *  \param agsaContext    Context of this command
 1742  *  \param queueNum       Queue number of inbound/outbound queue
 1743  *  \param diag           Pointer of SAS Diag Execute Structure
 1744  *
 1745  *  \return If the MPI command is sent to SPC successfully
 1746  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
 1747  *          - \e AGSA_RC_FAILURE the MPI command is failure
 1748  *
 1749  */
 1750 /*******************************************************************************/
 1751 GLOBAL bit32 saSASDiagExecute(
 1752                         agsaRoot_t              *agRoot,
 1753                         agsaContext_t           *agContext,
 1754                         bit32                    queueNum,
 1755                         agsaSASDiagExecute_t    *diag
 1756                         )
 1757 {
 1758   bit32                     ret = AGSA_RC_SUCCESS;
 1759   agsaLLRoot_t             *saRoot = agNULL;
 1760   agsaIORequestDesc_t      *pRequest = agNULL;
 1761   bit32  payload[32];
 1762   /* sanity check */
 1763   SA_ASSERT((agNULL != agRoot), "");
 1764 
 1765   saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
 1766   /* sanity check */
 1767   SA_ASSERT((agNULL != saRoot), "");
 1768 
 1769   smTraceFuncEnter(hpDBG_VERY_LOUD,"6m");
 1770 
 1771   SA_DBG2(("saSASDiagExecute,command 0x%X\n", diag->command ));
 1772   SA_DBG2(("saSASDiagExecute,param0 0x%X\n", diag->param0 ));
 1773   SA_DBG2(("saSASDiagExecute,param2 0x%X\n", diag->param2 ));
 1774   SA_DBG2(("saSASDiagExecute,param3 0x%X\n", diag->param3 ));
 1775   SA_DBG2(("saSASDiagExecute,param4 0x%X\n", diag->param4 ));
 1776   SA_DBG2(("saSASDiagExecute,param5 0x%X\n", diag->param5 ));
 1777 
 1778   /* Get request from free IORequests */
 1779   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1780   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
 1781 
 1782   /* If no LL Control request entry available */
 1783   if ( agNULL == pRequest )
 1784   {
 1785     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1786     SA_DBG1(("saSASDiagExecute, No request from free list\n" ));
 1787     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6m");
 1788     return AGSA_RC_BUSY;
 1789   }
 1790   /* If LL Control request entry avaliable */
 1791   else
 1792   {
 1793     /* Remove the request from free list */
 1794     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
 1795     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
 1796     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
 1797     saRoot->IOMap[pRequest->HTag].agContext = agContext;
 1798     pRequest->valid = agTRUE;
 1799     if(smIS_SPC(agRoot))
 1800     {
 1801       diag->param5 = 0; /* Reserved for SPC */
 1802     }
 1803 
 1804     /* set payload to zeros */
 1805     si_memset(&payload, 0, sizeof(payload));
 1806     /* set payload to zeros */
 1807     if(smIS_SPCV(agRoot))
 1808     {
 1809       /* build IOMB command and send to SPC */
 1810       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, tag),             pRequest->HTag);
 1811       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, CmdTypeDescPhyId),diag->command );
 1812       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, Pat1Pat2),        diag->param0 );
 1813       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, Threshold),       diag->param1 );
 1814       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, CodePatErrMsk),   diag->param2 );
 1815       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, Pmon),            diag->param3 );
 1816       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, PERF1CTL),        diag->param4 );
 1817       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, THRSHLD1),        diag->param5 );
 1818       ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SAS_DIAG_EXECUTE, IOMB_SIZE128, queueNum);
 1819     }
 1820     else
 1821     {
 1822       /* build IOMB command and send to SPC */
 1823       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_SASDiagExecuteCmd_t, tag),             pRequest->HTag);
 1824       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_SASDiagExecuteCmd_t, CmdTypeDescPhyId),diag->command );
 1825       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_SASDiagExecuteCmd_t, Pat1Pat2),        diag->param0 );
 1826       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_SASDiagExecuteCmd_t, Threshold),       diag->param1 );
 1827       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_SASDiagExecuteCmd_t, CodePatErrMsk),   diag->param2 );
 1828       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_SASDiagExecuteCmd_t, Pmon),            diag->param3 );
 1829       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_SASDiagExecuteCmd_t, PERF1CTL),        diag->param4 );
 1830       ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SAS_DIAG_EXECUTE, IOMB_SIZE64, queueNum);
 1831     }
 1832     if (AGSA_RC_SUCCESS != ret)
 1833     {
 1834       /* remove the request from IOMap */
 1835       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
 1836       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
 1837       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
 1838       pRequest->valid = agFALSE;
 1839 
 1840       /* return the request to free pool */
 1841       if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
 1842       {
 1843         SA_DBG1(("saSASDiagExecute: saving pRequest (%p) for later use\n", pRequest));
 1844         saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
 1845       }
 1846       else
 1847       {
 1848         /* return the request to free pool */
 1849         saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
 1850       }
 1851       SA_DBG1(("saSASDiagExecute, sending IOMB failed\n" ));
 1852       smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6m");
 1853       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1854       return ret;
 1855     }
 1856   }
 1857 
 1858   smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "6m");
 1859   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1860   return ret;
 1861 }
 1862 
 1863 /******************************************************************************/
 1864 /*! \brief SPC SAS Diagnostic Start/End Command
 1865  *
 1866  *  This command sends SAS Diagnostic Start/End Command to SPC.
 1867  *
 1868  *  \param agRoot         Handles for this instance of SAS/SATA LL
 1869  *  \param agsaContext    Context of this command
 1870  *  \param queueNum       Queue number of inbound/outbound queue
 1871  *  \param phyId          Phy ID
 1872  *  \param operation      Operation of SAS Diagnostic
 1873  *
 1874  *  \return If the MPI command is sent to SPC successfully
 1875  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
 1876  *          - \e AGSA_RC_FAILURE the MPI command is failure
 1877  *
 1878  */
 1879 /*******************************************************************************/
 1880 GLOBAL bit32 saSASDiagStartEnd(
 1881                         agsaRoot_t                *agRoot,
 1882                         agsaContext_t             *agContext,
 1883                         bit32                     queueNum,
 1884                         bit32                     phyId,
 1885                         bit32                     operation
 1886                         )
 1887 {
 1888   bit32 ret                = AGSA_RC_SUCCESS;
 1889   agsaLLRoot_t             *saRoot;
 1890   agsaIORequestDesc_t      *pRequest;
 1891   agsaSASDiagStartEndCmd_t payload;
 1892 
 1893   /* sanity check */
 1894   SA_ASSERT((agNULL != agRoot), "");
 1895   if (agRoot == agNULL)
 1896   {
 1897     SA_DBG1(("saSASDiagStartEnd: agRoot == agNULL\n"));
 1898     return AGSA_RC_FAILURE;
 1899   }
 1900   saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
 1901   SA_ASSERT((agNULL != saRoot), "");
 1902   if (saRoot == agNULL)
 1903   {
 1904     SA_DBG1(("saSASDiagStartEnd: saRoot == agNULL\n"));
 1905     return AGSA_RC_FAILURE;
 1906   }
 1907 
 1908   smTraceFuncEnter(hpDBG_VERY_LOUD,"6n");
 1909 
 1910   SA_DBG3(("saSASDiagStartEnd, phyId 0x%x operation 0x%x\n",phyId,operation ));
 1911 
 1912   /* Get request from free IORequests */
 1913   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1914   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
 1915 
 1916   /* If no LL Control request entry available */
 1917   if ( agNULL == pRequest )
 1918   {
 1919     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1920     SA_DBG1(("saSASDiagStartEnd, No request from free list\n" ));
 1921     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6n");
 1922     return AGSA_RC_BUSY;
 1923   }
 1924   /* If LL Control request entry avaliable */
 1925   else
 1926   {
 1927     /* Remove the request from free list */
 1928     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
 1929     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
 1930     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
 1931     saRoot->IOMap[pRequest->HTag].agContext = agContext;
 1932     pRequest->valid = agTRUE;
 1933 
 1934     /* set payload to zeros */
 1935     si_memset(&payload, 0, sizeof(agsaSASDiagStartEndCmd_t));
 1936     /* build IOMB command and send to SPC */
 1937     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagStartEndCmd_t, tag), pRequest->HTag);
 1938     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagStartEndCmd_t, OperationPhyId), ((phyId & SM_PHYID_MASK) | (operation << SHIFT8)));
 1939     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SAS_DIAG_MODE_START_END, IOMB_SIZE64, queueNum);
 1940     if (AGSA_RC_SUCCESS != ret)
 1941     {
 1942       /* remove the request from IOMap */
 1943       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
 1944       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
 1945       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
 1946       pRequest->valid = agFALSE;
 1947 
 1948       /* return the request to free pool */
 1949       if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
 1950       {
 1951         SA_DBG1(("saSASDiagStartEnd: saving pRequest (%p) for later use\n", pRequest));
 1952         saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
 1953       }
 1954       else
 1955       {
 1956         /* return the request to free pool */
 1957         saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
 1958       }
 1959       SA_DBG1(("saSASDiagStartEnd, sending IOMB failed\n" ));
 1960     }
 1961   }
 1962 
 1963   smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6n");
 1964   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1965   return ret;
 1966 }
 1967 
 1968 /******************************************************************************/
 1969 /*! \brief Initiate a GET TIME STAMP command
 1970  *
 1971  *  This function is called to initiate a Get Time Stamp command to the SPC.
 1972  *  The completion of this function is reported in ossaGetTimeStampCB().
 1973  *
 1974  *  \param agRoot      handles for this instance of SAS/SATA hardware
 1975  *  \param agContext   the context of this API
 1976  *  \param queueNum    queue number
 1977  *
 1978  *  \return
 1979  *          - SUCCESS or FAILURE
 1980  */
 1981 /*******************************************************************************/
 1982 GLOBAL bit32 saGetTimeStamp(
 1983                       agsaRoot_t        *agRoot,
 1984                       agsaContext_t     *agContext,
 1985                       bit32             queueNum
 1986                       )
 1987 {
 1988   agsaIORequestDesc_t   *pRequest;
 1989   agsaGetTimeStampCmd_t payload;
 1990   bit32                 ret = AGSA_RC_SUCCESS;
 1991   agsaLLRoot_t          *saRoot;
 1992   SA_ASSERT((agNULL != agRoot), "");
 1993   if (agRoot == agNULL)
 1994   {
 1995     SA_DBG1(("saGetTimeStamp: agRoot == agNULL\n"));
 1996     return AGSA_RC_FAILURE;
 1997   }
 1998   saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
 1999   SA_ASSERT((agNULL != saRoot), "");
 2000   if (saRoot == agNULL)
 2001   {
 2002     SA_DBG1(("saGetTimeStamp: saRoot == agNULL\n"));
 2003     return AGSA_RC_FAILURE;
 2004   }
 2005 
 2006   smTraceFuncEnter(hpDBG_VERY_LOUD,"6o");
 2007 
 2008   /* sanity check */
 2009   SA_ASSERT((agNULL != agRoot), "");
 2010 
 2011   SA_DBG3(("saGetTimeStamp: agContext %p\n", agContext));
 2012 
 2013   /* Get request from free IORequests */
 2014   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 2015   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
 2016 
 2017   /* If no LL Control request entry available */
 2018   if ( agNULL == pRequest )
 2019   {
 2020     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 2021     SA_DBG1(("saGetTimeStamp, No request from free list\n" ));
 2022     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6o");
 2023     return AGSA_RC_BUSY;
 2024   }
 2025   /* If LL Control request entry avaliable */
 2026   else
 2027   {
 2028     /* Remove the request from free list */
 2029     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
 2030     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
 2031     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
 2032     saRoot->IOMap[pRequest->HTag].agContext = agContext;
 2033     pRequest->valid = agTRUE;
 2034 
 2035     /* build IOMB command and send to SPC */
 2036     /* set payload to zeros */
 2037     si_memset(&payload, 0, sizeof(agsaGetTimeStampCmd_t));
 2038 
 2039     /* set tag */
 2040     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetTimeStampCmd_t, tag), pRequest->HTag);
 2041 
 2042     /* build IOMB command and send to SPC */
 2043     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_TIME_STAMP, IOMB_SIZE64, queueNum);
 2044     if (AGSA_RC_SUCCESS != ret)
 2045     {
 2046       /* remove the request from IOMap */
 2047       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
 2048       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
 2049       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
 2050       pRequest->valid = agFALSE;
 2051 
 2052       /* return the request to free pool */
 2053       if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
 2054       {
 2055         SA_DBG1(("saGetTimeStamp: saving pRequest (%p) for later use\n", pRequest));
 2056         saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
 2057       }
 2058       else
 2059       {
 2060         /* return the request to free pool */
 2061         saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
 2062       }
 2063       SA_DBG1(("saGetTimeStamp, sending IOMB failed\n" ));
 2064     }
 2065   }
 2066 
 2067   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 2068   smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6o");
 2069 
 2070   return ret;
 2071 }
 2072 
 2073 /******************************************************************************/
 2074 /*! \brief Update IOMap Entry  
 2075  *
 2076  *  This function is called to update certain fields of IOMap Entry
 2077  * 
 2078  *  \param pIOMap       IOMap Entry
 2079  *  \param HTag         Host Tag
 2080  *  \param pRequest     Request
 2081  *  \parma agContext    Context of this API
 2082  *
 2083  *  \return             NA
 2084  */         
 2085 /*******************************************************************************/
 2086 static void saUpdateIOMap(
 2087                         agsaIOMap_t         *pIOMap,
 2088                         bit32               HTag,
 2089                         agsaIORequestDesc_t *pRequest,
 2090                         agsaContext_t       *agContext
 2091                         )
 2092 {
 2093   pIOMap->Tag = HTag;
 2094   pIOMap->IORequest = (void *)pRequest;
 2095   pIOMap->agContext = agContext;
 2096 }
 2097 
 2098 /******************************************************************************/
 2099 /*! \brief Get a request from free pool
 2100  *
 2101  *  This function gets a request from free pool
 2102  * 
 2103  *  \param agRoot       Handles for this instance of SAS/SATA LL
 2104  *  \param agsaContext  Context of this command
 2105  *
 2106  *  \return
 2107  *          - \e Pointer to request, in case of success
 2108  *          - \e NULL, in case of failure 
 2109  *
 2110  */
 2111 /*******************************************************************************/
 2112 agsaIORequestDesc_t* saGetRequestFromFreePool(
 2113                                             agsaRoot_t      *agRoot,
 2114                                             agsaContext_t   *agContext
 2115                                             )
 2116 {
 2117   agsaLLRoot_t          *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
 2118   agsaIORequestDesc_t   *pRequest = agNULL;
 2119   
 2120   /* Acquire LL_IOREQ_LOCKEQ_LOCK */
 2121   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 2122   
 2123   /* Get request from free IORequests */
 2124   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
 2125   if (pRequest != agNULL)
 2126   {
 2127     /* Remove the request from free list */
 2128     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
 2129 
 2130     /* Release LL_IOREQ_LOCKEQ_LOCK */
 2131     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 2132 
 2133     /* Add the request to IOMap */
 2134     saUpdateIOMap(&saRoot->IOMap[pRequest->HTag], pRequest->HTag, pRequest, agContext);
 2135     pRequest->valid = agTRUE;
 2136   }
 2137   else
 2138   {
 2139     /* Release LL_IOREQ_LOCKEQ_LOCK */
 2140     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 2141   }
 2142   
 2143   return pRequest;
 2144 }
 2145 
 2146 /******************************************************************************/
 2147 /*! \brief Return request to free pool
 2148  *
 2149  *  This function returns the request to free pool
 2150  * 
 2151  *  \param agRoot       Handles for this instance of SAS/SATA LL
 2152  *  \param pRequest     Request to be returned
 2153  *
 2154  *  \return             NA             
 2155  *
 2156  */
 2157 /*******************************************************************************/
 2158 void saReturnRequestToFreePool(
 2159                             agsaRoot_t          *agRoot,
 2160                             agsaIORequestDesc_t *pRequest
 2161                             )
 2162 {
 2163   agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
 2164 
 2165   SA_ASSERT((pRequest->valid), "pRequest->valid");
 2166 
 2167   /* Remove the request from IOMap */
 2168   saUpdateIOMap(&saRoot->IOMap[pRequest->HTag], MARK_OFF, agNULL, agNULL);
 2169   pRequest->valid = agFALSE;
 2170   
 2171   /* Acquire LL_IOREQ_LOCKEQ_LOCK */
 2172   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 2173 
 2174   if (saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
 2175   {
 2176     SA_DBG1(("saReturnRequestToFreePool: saving pRequest (%p) for later use\n", pRequest));     
 2177     saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
 2178   }
 2179   else
 2180   {
 2181     /* Return the request to free pool */      
 2182     saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
 2183   }
 2184   
 2185   /* Release LL_IOREQ_LOCKEQ_LOCK */
 2186   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 2187 }
 2188 /******************************************************************************/
 2189 /*! \brief Initiate a serial GPIO command
 2190  *
 2191  *  This function is called to initiate a serial GPIO command to the SPC.
 2192  *  The completion of this function is reported in ossaSgpioCB().
 2193  *
 2194  *  \param agRoot      handles for this instance of SAS/SATA hardware
 2195  *  \param agContext   the context of this API
 2196  *  \param queueNum    queue number
 2197  *  \param pSGpioReq   Pointer to the serial GPIO fields
 2198  *
 2199  *  \return 
 2200  *          - SUCCESS or FAILURE
 2201  */         
 2202 /*******************************************************************************/
 2203 GLOBAL bit32 saSgpio(
 2204                 agsaRoot_t              *agRoot,
 2205                 agsaContext_t           *agContext,
 2206                 bit32                   queueNum,
 2207                 agsaSGpioReqResponse_t  *pSGpioReq
 2208                 )
 2209 {
 2210   bit32                 i;
 2211   agsaIORequestDesc_t   *pRequest = agNULL;
 2212   agsaSGpioCmd_t        payload = {0};
 2213   bit32                 ret = AGSA_RC_BUSY;
 2214 
 2215   smTraceFuncEnter(hpDBG_VERY_LOUD,"6t");
 2216 
 2217   /* Sanity check */
 2218   SA_ASSERT((agNULL != agRoot), "");
 2219 
 2220   SA_DBG3(("saSgpio: agContext %p\n", agContext));
 2221 
 2222   /* Get request from free pool */
 2223   pRequest = saGetRequestFromFreePool(agRoot, agContext);
 2224   if (agNULL == pRequest)
 2225   {
 2226     SA_DBG1(("saSgpio, No request from free list\n" ));
 2227     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6t");
 2228   }
 2229   else
 2230   {
 2231     /* Set payload to zeros */
 2232     si_memset(&payload, 0, sizeof(agsaSGpioCmd_t));
 2233         
 2234     /* set tag */
 2235     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSGpioCmd_t, tag), pRequest->HTag);
 2236     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSGpioCmd_t, regIndexRegTypeFunctionFrameType),
 2237                         (pSGpioReq->smpFrameType | 
 2238                         ((bit32)pSGpioReq->function << 8)  |
 2239                         ((bit32)pSGpioReq->registerType << 16) |
 2240                         ((bit32)pSGpioReq->registerIndex << 24)));
 2241     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSGpioCmd_t, regCount), pSGpioReq->registerCount);
 2242         
 2243     if (SA_SAS_SMP_WRITE_GPIO_REGISTER == pSGpioReq->function)
 2244     {
 2245       for (i = 0; i < pSGpioReq->registerCount; i++)
 2246       {
 2247         OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSGpioCmd_t, writeData) + (i * 4), pSGpioReq->readWriteData[i]);
 2248       }
 2249     }
 2250 
 2251     /* Build IOMB command and send to SPC */
 2252     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SGPIO, IOMB_SIZE64, queueNum);
 2253     if (AGSA_RC_SUCCESS != ret)
 2254     {
 2255       /* Return the request to free pool */
 2256       saReturnRequestToFreePool(agRoot, pRequest);
 2257       SA_DBG1(("saSgpio, sending IOMB failed\n" ));
 2258     }
 2259 
 2260     smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6t");
 2261   }
 2262 
 2263   return ret;
 2264 }
 2265 
 2266 /******************************************************************************/
 2267 /*! \brief for spc card read Error Registers to memory if error occur
 2268  *
 2269  *  This function is called to get erorr registers content to memory if error occur.
 2270  *
 2271  *  \param agRoot      handles for this instance of SAS/SATA hardware
 2272  *
 2273  *  \return
 2274  */
 2275 /*******************************************************************************/
 2276 LOCAL void siSpcGetErrorContent(
 2277                                 agsaRoot_t *agRoot
 2278                                )
 2279 {
 2280 
 2281   agsaLLRoot_t          *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
 2282   bit32       value, value1;
 2283 
 2284   value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1) & SCRATCH_PAD_STATE_MASK;
 2285   value1 = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_2, MSGU_SCRATCH_PAD_2) & SCRATCH_PAD_STATE_MASK;
 2286       /* check AAP error */
 2287   if ((SCRATCH_PAD1_ERR == value) || (SCRATCH_PAD2_ERR == value1))
 2288   {
 2289         /* fatal error */
 2290         /* get register dump from GSM and save it to LL local memory */
 2291       siGetRegisterDumpGSM(agRoot, (void *)&saRoot->registerDump0[0],
 2292            REG_DUMP_NUM0, 0, saRoot->mainConfigTable.FatalErrorDumpLength0);
 2293       siGetRegisterDumpGSM(agRoot, (void *)&saRoot->registerDump1[0],
 2294            REG_DUMP_NUM1, 0, saRoot->mainConfigTable.FatalErrorDumpLength1);
 2295   }
 2296 }
 2297 
 2298 
 2299 /******************************************************************************/
 2300 /*! \brief for spcv card read Error Registers to memory if error occur
 2301  *
 2302  *  This function is called to get erorr registers content to memory if error occur.
 2303  *
 2304  *  \param agRoot      handles for this instance of SAS/SATA hardware
 2305  *
 2306  *  \return
 2307  */
 2308 /*******************************************************************************/
 2309 LOCAL void siSpcvGetErrorContent(
 2310                                  agsaRoot_t *agRoot
 2311                                  )
 2312 {
 2313 
 2314   agsaLLRoot_t          *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
 2315   bit32                 value;
 2316 
 2317   smTraceFuncEnter(hpDBG_VERY_LOUD,"2d");
 2318   value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1);
 2319 
 2320   if(((value & SPCV_RAAE_STATE_MASK) == SPCV_ERROR_VALUE) ||
 2321      ((value & SPCV_IOP0_STATE_MASK) == SPCV_ERROR_VALUE) ||
 2322      ((value & SPCV_IOP1_STATE_MASK) == SPCV_ERROR_VALUE)
 2323     )
 2324   {
 2325         /* fatal error */
 2326         /* get register dump from GSM and save it to LL local memory */
 2327     siGetRegisterDumpGSM(agRoot, (void *)&saRoot->registerDump0[0],
 2328        REG_DUMP_NUM0, 0, saRoot->mainConfigTable.FatalErrorDumpLength0);
 2329     siGetRegisterDumpGSM(agRoot, (void *)&saRoot->registerDump1[0],
 2330        REG_DUMP_NUM1, 0, saRoot->mainConfigTable.FatalErrorDumpLength1);
 2331   }
 2332   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2d");
 2333 }
 2334 
 2335 #define LEFT_BYTE_FAIL(x, v)   \
 2336      do {if( (x) < (v) ) return AGSA_RC_FAILURE; } while(0);
 2337 
 2338 LOCAL bit32 siDumpInboundQueue(
 2339           void *  buffer,
 2340           bit32   length,
 2341           mpiICQueue_t  *q
 2342           )
 2343 {
 2344   bit8  * _buf = buffer;
 2345   si_memcpy( _buf, (bit8*)(q->memoryRegion.virtPtr) + length, 128*256);
 2346   return AGSA_RC_SUCCESS;
 2347 }
 2348 
 2349 LOCAL bit32 siDumpOutboundQueue(
 2350           void *  buffer,
 2351           bit32   length,
 2352           mpiOCQueue_t  *q)
 2353 {
 2354   bit8  * _buf   = buffer;
 2355   si_memcpy( _buf, (bit8*)(q->memoryRegion.virtPtr) + length, 128*256);
 2356   return AGSA_RC_SUCCESS;
 2357 }
 2358 
 2359 
 2360 LOCAL bit32 siWaitForNonFatalTransfer( agsaRoot_t *agRoot,bit32 pcibar)
 2361 {
 2362   bit32 status = AGSA_RC_SUCCESS;
 2363   bit32 ready;
 2364   bit32 max_wait_time;
 2365   bit32 max_wait_count;
 2366   smTraceFuncEnter(hpDBG_VERY_LOUD,"2c");
 2367 
 2368   SA_DBG4(("siWaitForNonFatalTransfer:0 IBDBS 0x%x\n",ossaHwRegReadExt(agRoot,0 ,V_Inbound_Doorbell_Set_Register ) ));
 2369   /* Write FDDHSHK  */
 2370 
 2371 
 2372   /* Write bit7 of inbound doorbell set register  step 3 */
 2373   ossaHwRegWriteExt(agRoot, 0,V_Inbound_Doorbell_Set_Register, SPCV_MSGU_CFG_TABLE_TRANSFER_DEBUG_INFO );
 2374   SA_DBG4(("siWaitForNonFatalTransfer:1 IBDBS 0x%x\n",ossaHwRegReadExt(agRoot,0 ,V_Inbound_Doorbell_Set_Register ) ));
 2375 
 2376   /* Poll bit7 of inbound doorbell set register until clear step 4 */
 2377   max_wait_time = (2000 * 1000); /* wait 2 seconds */
 2378   max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT) - WAIT_INCREMENT;
 2379   do
 2380   {
 2381     ossaStallThread(agRoot, WAIT_INCREMENT);
 2382     ready = ossaHwRegReadExt(agRoot,0 ,V_Inbound_Doorbell_Set_Register );
 2383   } while ( (ready & SPCV_MSGU_CFG_TABLE_TRANSFER_DEBUG_INFO)  && (max_wait_count -= WAIT_INCREMENT));
 2384   if(max_wait_count == 0)
 2385   {
 2386     SA_DBG1(("siWaitForNonFatalTransfer:Timeout IBDBS 0x%x\n",ossaHwRegReadExt(agRoot,0 ,V_Inbound_Doorbell_Set_Register ) ));
 2387     status = AGSA_RC_FAILURE;
 2388   }
 2389 
 2390   SA_DBG4(("siWaitForNonFatalTransfer:3 IBDBS 0x%x\n",ossaHwRegReadExt(agRoot,0 ,V_Inbound_Doorbell_Set_Register ) ));
 2391 
 2392   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2c");
 2393   return(status);
 2394 }
 2395 
 2396 LOCAL bit32 siWaitForFatalTransfer( agsaRoot_t *agRoot,bit32 pcibar)
 2397 {
 2398   bit32 status = AGSA_RC_SUCCESS;
 2399   bit32 ready;
 2400   bit32 ErrorTableOffset;
 2401   bit32 max_wait_time;
 2402   bit32 max_wait_count;
 2403 
 2404   smTraceFuncEnter(hpDBG_VERY_LOUD,"2o");
 2405 
 2406   ErrorTableOffset = siGetTableOffset( agRoot, MAIN_MERRDCTO_MERRDCES );
 2407 
 2408   SA_DBG4(("siWaitForFatalTransfer: MPI_FATAL_EDUMP_TABLE_STATUS    Offset 0x%x 0x%x\n",ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_STATUS, ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_STATUS )));
 2409   SA_DBG4(("siWaitForFatalTransfer: MPI_FATAL_EDUMP_TABLE_ACCUM_LEN Offset 0x%x 0x%x\n",ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_ACCUM_LEN, ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN)));
 2410   /*
 2411   2. Write 0x1 to the Fatal Error Debug Dump Handshake control [FDDHSHK] field in Table 73 and
 2412   read back the same field (by polling) until it is 0. This prompts the debug agent to copy the next
 2413   part of the debug data into GSM shared memory. To check the completion of the copy process, the
 2414   host must poll the Fatal/Non Fatal Debug Data Transfer Status [FDDTSTAT] field in the Table
 2415   Table 73.
 2416   */
 2417 
 2418   /* Write FDDHSHK  */
 2419   ossaHwRegWriteExt(agRoot,pcibar ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_HANDSHAKE, MPI_FATAL_EDUMP_HANDSHAKE_RDY );
 2420   SA_DBG4(("siWaitForFatalTransfer:1 MPI_FATAL_EDUMP_TABLE_HANDSHAKE 0x%x\n",ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_HANDSHAKE ) ));
 2421 
 2422   /* Poll FDDHSHK  until clear  */
 2423   max_wait_time = (2000 * 1000); /* wait 2 seconds */
 2424   max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT) - WAIT_INCREMENT;
 2425   do
 2426   {
 2427     ossaStallThread(agRoot, WAIT_INCREMENT);
 2428     ready = ossaHwRegReadExt(agRoot,0 ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_HANDSHAKE );
 2429   } while (ready   && (max_wait_count -= WAIT_INCREMENT));
 2430   if(max_wait_count == 0)
 2431   {
 2432     SA_DBG1(("siWaitForFatalTransfer : 1 Timeout\n"));
 2433     status = AGSA_RC_FAILURE;
 2434   }
 2435 
 2436   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2o");
 2437   return(status);
 2438 }
 2439 
 2440 
 2441 
 2442 LOCAL bit32 siFatalErrorBuffer(
 2443                   agsaRoot_t *agRoot,
 2444                   agsaForensicData_t *forensicData
 2445                   )
 2446 {
 2447   bit32 status = AGSA_RC_FAILURE;
 2448   bit32 pcibar;
 2449   bit32 ErrorTableOffset;
 2450   bit32 Accum_len = 0;
 2451 
 2452   agsaLLRoot_t      *saRoot;
 2453   /* sanity check */
 2454   SA_ASSERT( (agNULL != agRoot), "");
 2455   saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
 2456   SA_ASSERT( (agNULL != saRoot), "saRoot");
 2457   if(agNULL == saRoot )
 2458   {
 2459     SA_DBG1(("siFatalErrorBuffer: agNULL  saRoot\n"));
 2460     return(status);
 2461   }
 2462 
 2463   if(saRoot->ResetFailed )
 2464   {
 2465     SA_DBG1(("siFatalErrorBuffer: saRoot->ResetFailed\n"));
 2466     return(status);
 2467   }
 2468   smTraceFuncEnter(hpDBG_VERY_LOUD,"2a");
 2469   SA_DBG2(("siFatalErrorBuffer:In %p Offset 0x%08x Len 0x%08x Totel len 0x%x\n",
 2470                         forensicData->BufferType.dataBuf.directData,
 2471                         forensicData->BufferType.dataBuf.directOffset,
 2472                         forensicData->BufferType.dataBuf.directLen,
 2473                         forensicData->BufferType.dataBuf.readLen ));
 2474 
 2475   pcibar = siGetPciBar(agRoot);
 2476   ErrorTableOffset = siGetTableOffset( agRoot, MAIN_MERRDCTO_MERRDCES );
 2477 
 2478   SA_DBG3(("siFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_STATUS  0x%x LEN 0x%x\n",
 2479       ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_STATUS),
 2480       ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN) ));
 2481 
 2482   /*
 2483   This section describes sequence for the host to capture debug data under fatal error conditions.
 2484   A fatal error is an error condition that stops the SPCv controller from normal operation and causes it
 2485   to be unresponsive to host requests. Since the firmware is non-operational, the host needs to pull the
 2486   debug dump information using PCIe MEMBASE II with the assistance of the debug agent which becomes
 2487   active when the main controller firmware fails.
 2488   */
 2489   /*
 2490   To capture the fatal error debug data, the host must:
 2491   1. Upon detecting the fatal error condition through a fatal error interrupt or by the MSGU scratchpad
 2492   registers, capture the first part of the fatal error debug data. Upon fatal error, the first part of the
 2493   debug data is located GSM shared memory and its length is updated in the Accumulative Debug
 2494   Data Length Transferred [ACCDDLEN] field in Table Table 82. To capture the first part:
 2495   */
 2496   if(forensicData->BufferType.dataBuf.directOffset == 0)
 2497   {
 2498     /* start to get data */
 2499     /*
 2500     a. Program the MEMBASE II Shifting Register with 0x00.
 2501     */
 2502     ossaHwRegWriteExt(agRoot, pcibar,V_MEMBASE_II_ShiftRegister, saRoot->FatalForensicShiftOffset); // set base to zero
 2503 
 2504     saRoot->ForensicLastOffset =0;
 2505     saRoot->FatalForensicStep = 0;
 2506     saRoot->FatalBarLoc = 0;
 2507     saRoot->FatalForensicShiftOffset = 0;
 2508 
 2509     SA_DBG1(("siFatalErrorBuffer: directOffset zero SCRATCH_PAD1 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1) ));
 2510   }
 2511 
 2512   /* Read until Accum_len is retrived */
 2513   Accum_len = ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN);
 2514 
 2515   SA_DBG2(("siFatalErrorBuffer: Accum_len 0x%x\n", Accum_len));
 2516   if(Accum_len == 0xFFFFFFFF)
 2517   {
 2518     SA_DBG1(("siFatalErrorBuffer: Possible PCI issue 0x%x not expected\n", Accum_len));
 2519     return(status);
 2520   }
 2521 
 2522   if( Accum_len == 0 || Accum_len >=0x100000 )
 2523   {
 2524     SA_DBG1(("siFatalErrorBuffer: Accum_len == saRoot->FatalCurrentLength 0x%x\n", Accum_len));
 2525     return(IOCTL_ERROR_NO_FATAL_ERROR);
 2526   }
 2527 
 2528   if(saRoot->FatalForensicStep == 0) /* PM Step 1a and 1b */
 2529   {
 2530     moreData:
 2531           if(forensicData->BufferType.dataBuf.directData)
 2532           {
 2533                   siPciCpyMem(agRoot,saRoot->FatalBarLoc ,forensicData->BufferType.dataBuf.directData,forensicData->BufferType.dataBuf.directLen ,1 );
 2534           }
 2535           saRoot->FatalBarLoc += forensicData->BufferType.dataBuf.directLen;
 2536           forensicData->BufferType.dataBuf.directOffset += forensicData->BufferType.dataBuf.directLen;
 2537           saRoot->ForensicLastOffset  += forensicData->BufferType.dataBuf.directLen;
 2538           forensicData->BufferType.dataBuf.readLen = forensicData->BufferType.dataBuf.directLen;
 2539 
 2540           if(saRoot->ForensicLastOffset  >= Accum_len)
 2541     {
 2542       /*
 2543       e. Repeat the above 2 steps until all debug data is retrieved as specified in the Accumulative Debug
 2544       Data Length Transferred [ACCDDLEN] field.
 2545       NOTE: The ACCDDLEN field is cumulative so the host needs to take the difference from the
 2546       previous step.
 2547       */
 2548       /* This section data ends get next section */
 2549       SA_DBG1(("siFatalErrorBuffer: Accum_len reached 0x%x directOffset 0x%x\n",Accum_len,forensicData->BufferType.dataBuf.directOffset ));
 2550       saRoot->FatalBarLoc = 0;
 2551       saRoot->FatalForensicStep = 1;
 2552       saRoot->FatalForensicShiftOffset = 0;
 2553                   status = AGSA_RC_COMPLETE;
 2554                   return status;
 2555     }
 2556     if(saRoot->FatalBarLoc < (64*1024))
 2557     {
 2558       SA_DBG2(("siFatalErrorBuffer: In same 64k FatalBarLoc 0x%x\n",saRoot->FatalBarLoc ));
 2559       status = AGSA_RC_SUCCESS;
 2560                   return status;
 2561     }
 2562     /*
 2563     c. Increment the MEMBASE II Shifting Register value by 0x100.
 2564     */
 2565     saRoot->FatalForensicShiftOffset+= 0x100;
 2566           ossaHwRegWriteExt(agRoot, pcibar,V_MEMBASE_II_ShiftRegister, saRoot->FatalForensicShiftOffset);
 2567     saRoot->FatalBarLoc = 0;
 2568 
 2569           SA_DBG1(("siFatalErrorBuffer: Get next bar data 0x%x\n",saRoot->FatalForensicShiftOffset));
 2570 
 2571     status = AGSA_RC_SUCCESS;
 2572 
 2573           SA_DBG1(("siFatalErrorBuffer:Offset 0x%x BarLoc 0x%x\n",saRoot->FatalForensicShiftOffset,saRoot->FatalBarLoc  )); 
 2574           SA_DBG1(("siFatalErrorBuffer: step 0 status %d %p Offset 0x%x Len 0x%x total_len 0x%x\n",
 2575                         status,
 2576                         forensicData->BufferType.dataBuf.directData,
 2577                                   forensicData->BufferType.dataBuf.directOffset, 
 2578                         forensicData->BufferType.dataBuf.directLen,
 2579                                   forensicData->BufferType.dataBuf.readLen )); 
 2580           return(status);
 2581   }
 2582 
 2583   if(saRoot->FatalForensicStep == 1)
 2584   {
 2585 
 2586     /*
 2587     3. If Fatal/Non Fatal Debug Data Transfer Status [FDDTSTAT] field indicates status value of
 2588     0x00000002 or 0x00000003, read the next part of the fatal debug data by taking the difference
 2589     between the preserved ACCDDLEN value from step 2 and the new ACCDDLEN value.To capture
 2590     the second part:
 2591     a. Program the MEMBASE II Shifting Register with 0x00.
 2592     */
 2593     SA_DBG1(("siFatalErrorBuffer: FatalForensicStep 1 Accum_len 0x%X MPI_FATAL_EDUMP_TABLE_ACCUM_LEN 0x%x\n",
 2594                 Accum_len,
 2595                 ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN)));
 2596 
 2597     saRoot->FatalForensicShiftOffset = 0; /* location in 64k region */
 2598     /*
 2599     b. Read 64K of the debug data.
 2600     */
 2601     ossaHwRegWriteExt(agRoot, pcibar,V_MEMBASE_II_ShiftRegister  ,saRoot->FatalForensicShiftOffset);
 2602     SA_DBG1(("siFatalErrorBuffer: FatalForensicStep 1\n" ));
 2603     /*
 2604     2.Write 0x1 to the Fatal Error Debug Dump Handshake control [FDDHSHK]
 2605     field inTable 82 and read back the same field (by polling for 2 seconds) until it is 0. This prompts
 2606     the debug agent to copy the next part of the debug data into GSM shared memory. To check the
 2607     completion of the copy process, the host must poll the Fatal/Non Fatal Debug Data Transfer Status
 2608     [FDDTSTAT] field for 2 secondsin the MPI Fatal and Non-Fatal Error Dump Capture Table Table 82.
 2609     */
 2610     siWaitForFatalTransfer( agRoot,pcibar);
 2611 
 2612     /*
 2613     d. Read the next 64K of the debug data.
 2614     */
 2615     saRoot->FatalForensicStep = 0;
 2616 
 2617     if( ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_STATUS) != MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE )
 2618     {
 2619 
 2620       SA_DBG3(("siFatalErrorBuffer:Step 3\n" ));
 2621       SA_DBG3(("siFatalErrorBuffer:Step 3 MPI_FATAL_EDUMP_TABLE_STATUS 0x%x\n", ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_STATUS )));
 2622       /*
 2623       2. Write FDDSTAT to 0x00000000 but preserve the Accumulative Debug Data Length Transferred
 2624       [ACCDDLEN] field.
 2625       */
 2626       ossaHwRegWriteExt(agRoot,pcibar ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_STATUS, 0 );
 2627       /*
 2628       4. If FDDSTAT is 0x00000002, repeat steps 2 and 3 until you reach this step with FDDSTAT being
 2629       equal to 0x00000003.
 2630       */
 2631       goto moreData;
 2632     }
 2633     else
 2634     {
 2635       /*
 2636          When FDDSTAT equals 0x00000003 and ACCDDLEN is unchanged, then
 2637       */
 2638       /*
 2639       the fatal error dump is complete. If ACCDDLEN increases, one more read step is required.
 2640       The content and format of the debug data is opaque to the host and must be forwarded to PMC-Sierra
 2641       Applications support for failure analysis. Debug data is retrieved in several iterations which enables
 2642       the host to use a smaller buffer and store the captured debug data in secondary storage during the process.
 2643       */
 2644 
 2645       SA_DBG3(("siFatalErrorBuffer:Step 4\n" ));
 2646       SA_DBG1(("siFatalErrorBuffer:  Done  Read 0x%x accum 0x%x\n",
 2647                 forensicData->BufferType.dataBuf.directOffset,
 2648                 ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN)));
 2649 
 2650 #if defined(SALLSDK_DEBUG)
 2651       SA_DBG1(("siFatalErrorBuffer: SCRATCH_PAD1_V_ERROR_STATE 0x%x\n",SCRATCH_PAD1_V_ERROR_STATE( siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1) )));
 2652       SA_DBG1(("siFatalErrorBuffer: SCRATCH_PAD0 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0)));
 2653       SA_DBG1(("siFatalErrorBuffer: SCRATCH_PAD1 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1)));
 2654       SA_DBG1(("siFatalErrorBuffer: SCRATCH_PAD2 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_2,  MSGU_SCRATCH_PAD_2)));
 2655       SA_DBG1(("siFatalErrorBuffer: SCRATCH_PAD3 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_3,  MSGU_SCRATCH_PAD_3)));
 2656 #endif
 2657       forensicData->BufferType.dataBuf.readLen = 0xFFFFFFFF;
 2658       status = AGSA_RC_SUCCESS;
 2659 
 2660     }
 2661   }
 2662 
 2663 
 2664   SA_DBG3(("siFatalErrorBuffer:status 0x%x %p directOffset 0x%x directLen 0x%x readLen 0x%x\n",
 2665                         status,
 2666                         forensicData->BufferType.dataBuf.directData,
 2667                         forensicData->BufferType.dataBuf.directOffset,
 2668                         forensicData->BufferType.dataBuf.directLen,
 2669                         forensicData->BufferType.dataBuf.readLen )); 
 2670 
 2671       smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2a");
 2672   return(status);
 2673 }
 2674 
 2675 LOCAL bit32 siNonFatalErrorBuffer(
 2676               agsaRoot_t *agRoot,
 2677               agsaForensicData_t *forensicData
 2678               )
 2679 {
 2680   bit32 status = AGSA_RC_FAILURE;
 2681   bit32 pcibar;
 2682   bit32 ErrorTableOffset;
 2683 
 2684   //bit32 i;
 2685   bit32 ready;
 2686   bit32 biggest;
 2687   bit32 max_wait_time;
 2688   bit32 max_wait_count;
 2689   agsaLLRoot_t      *saRoot;
 2690   /* sanity check */
 2691   SA_ASSERT( (agNULL != agRoot), "agRoot");
 2692   saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
 2693   SA_ASSERT( (agNULL != saRoot), "saRoot");
 2694   if(agNULL == saRoot )
 2695   {
 2696     SA_DBG1(("siNonFatalErrorBuffer: agNULL  saRoot\n"));
 2697     return(status);
 2698   }
 2699 
 2700   smTraceFuncEnter(hpDBG_VERY_LOUD,"2b");
 2701   pcibar = siGetPciBar(agRoot);
 2702   ErrorTableOffset = siGetTableOffset( agRoot, MAIN_MERRDCTO_MERRDCES );
 2703 
 2704   SA_DBG4(("siNonFatalErrorBuffer: ErrorTableOffset 0x%x\n",ErrorTableOffset ));
 2705 
 2706   SA_DBG4(("siNonFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_STATUS Offset 0x%x   0x%x\n",
 2707             ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS,
 2708             ossaHwRegReadExt(agRoot,pcibar,ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS)));
 2709   SA_DBG4(("siNonFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_ACCUM_LEN Offset 0x%x   0x%x\n",
 2710             ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN,
 2711             ossaHwRegReadExt(agRoot,pcibar,ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN)));
 2712 
 2713   biggest = saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].totalLength;
 2714 
 2715   if(biggest >= forensicData->BufferType.dataBuf.directLen )
 2716   {
 2717     biggest = forensicData->BufferType.dataBuf.directLen;
 2718   }
 2719   else
 2720   {
 2721     SA_DBG1(("siNonFatalErrorBuffer: directLen larger than DMA Buffer 0x%x < 0x%x\n",
 2722               biggest, forensicData->BufferType.dataBuf.directLen));
 2723     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2b");
 2724     return(AGSA_RC_FAILURE);
 2725   }
 2726 
 2727   if(saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].virtPtr)
 2728   {
 2729     si_memset(saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].virtPtr, 0, biggest);
 2730   }
 2731   else
 2732   {
 2733     SA_DBG1(("siNonFatalErrorBuffer: Error\n" ));
 2734     return(AGSA_RC_FAILURE);
 2735   }
 2736 
 2737 
 2738   if(forensicData->BufferType.dataBuf.directOffset)
 2739   {
 2740     /* Write FDDSTAT and ACCDDLEN to zero step 2 */
 2741     ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS, 0);
 2742     goto skip_setup;
 2743   }
 2744 
 2745   SA_DBG1(("siNonFatalErrorBuffer: %p Offset 0x%x Len 0x%x total_len 0x%x\n",
 2746                         forensicData->BufferType.dataBuf.directData,
 2747                         forensicData->BufferType.dataBuf.directOffset,
 2748                         forensicData->BufferType.dataBuf.directLen,
 2749                         forensicData->BufferType.dataBuf.readLen ));
 2750 
 2751   SA_DBG1(("siNonFatalErrorBuffer: directOffset zero setup\n" ));
 2752   SA_DBG1(("siNonFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_STATUS  0x%x LEN 0x%x\n",
 2753       ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_STATUS),
 2754       ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN) ));
 2755 
 2756   SA_DBG1(("siNonFatalErrorBuffer: Clear V_Scratchpad_Rsvd_0_Register 0x%x\n",
 2757           ossaHwRegReadExt(agRoot, 0,V_Scratchpad_Rsvd_0_Register) ));
 2758   ossaHwRegWriteExt(agRoot, 0,V_Scratchpad_Rsvd_0_Register ,0);
 2759 
 2760   saRoot->ForensicLastOffset = 0;
 2761 
 2762   /* WriteACCDDLEN  for error interface Step 0 */
 2763   /*ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN ,0);*/
 2764 
 2765   /* Write DMA get Offset for error interface Step 1 */
 2766   ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_LO_OFFSET, saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].phyAddrLower);
 2767   ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_HI_OFFSET, saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].phyAddrUpper);
 2768   ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_LENGTH, biggest);
 2769 
 2770   /* Write FDDSTAT and ACCDDLEN to zero step 2 */
 2771   ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS, 0);
 2772   ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN, 0);
 2773 
 2774   SA_DBG4(("siNonFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_STATUS Offset 0x%x   0x%x\n",
 2775            ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS,
 2776            ossaHwRegReadExt(agRoot,pcibar,ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS )));
 2777   SA_DBG4(("siNonFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_ACCUM_LEN Offset 0x%x   0x%x\n",
 2778            ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN,
 2779            ossaHwRegReadExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN)));
 2780 
 2781   if( 0 != ossaHwRegReadExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN))
 2782   {
 2783     SA_DBG1(("siNonFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_ACCUM_LEN  0x%x   0x%x\n",
 2784              forensicData->BufferType.dataBuf.directOffset,
 2785              ossaHwRegReadExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN)));
 2786   }
 2787   skip_setup:
 2788 
 2789   if( saRoot->ForensicLastOffset == 0xFFFFFFFF)
 2790   {
 2791     forensicData->BufferType.dataBuf.readLen = 0xFFFFFFFF;
 2792     smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2b");
 2793     return(AGSA_RC_SUCCESS);
 2794   }
 2795 
 2796 
 2797   /* Write bit7 of inbound doorbell set register and wait for complete step 3 and 4*/
 2798   siWaitForNonFatalTransfer(agRoot,pcibar);
 2799 
 2800   SA_DBG3(("siNonFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_STATUS  0x%x LEN 0x%x\n",
 2801       ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_STATUS),
 2802       ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN) ));
 2803 
 2804 
 2805 
 2806   max_wait_time = (2000 * 1000); /* wait 2 seconds */
 2807   max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT) - WAIT_INCREMENT;
 2808   ready = ossaHwRegReadExt(agRoot,pcibar,ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS );
 2809   do
 2810   {
 2811     ossaStallThread(agRoot, WAIT_INCREMENT);
 2812     ready =  ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS );
 2813     forensicData->BufferType.dataBuf.directOffset = ossaHwRegReadExt(agRoot,pcibar,ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN);
 2814     if( ready == MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_MORE_DATA )
 2815     {
 2816       SA_DBG2(("siNonFatalErrorBuffer: More data available MPI_FATAL_EDUMP_TABLE_ACCUM_LEN 0x%x\n", ossaHwRegReadExt(agRoot,pcibar,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN) )); 
 2817       break;
 2818     }
 2819   } while ( ready != MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE && (max_wait_count -= WAIT_INCREMENT));
 2820 
 2821 
 2822   if(max_wait_count == 0 || ready == MPI_FATAL_EDUMP_TABLE_STAT_DMA_FAILED)
 2823   {
 2824     status = AGSA_RC_FAILURE;
 2825     SA_DBG1(("siNonFatalErrorBuffer: timeout waiting ready\n"));
 2826   }
 2827   else
 2828   {
 2829     forensicData->BufferType.dataBuf.readLen = forensicData->BufferType.dataBuf.directOffset - saRoot->ForensicLastOffset;
 2830     if( ready == MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE && forensicData->BufferType.dataBuf.readLen == 0)
 2831     {
 2832       SA_DBG1(("siNonFatalErrorBuffer:ready 0x%x readLen 0x%x\n",ready ,forensicData->BufferType.dataBuf.readLen));
 2833       saRoot->ForensicLastOffset = 0xFFFFFFFF;
 2834     }
 2835     else
 2836     {
 2837       saRoot->ForensicLastOffset = forensicData->BufferType.dataBuf.directOffset;
 2838     }
 2839 
 2840     if(forensicData->BufferType.dataBuf.directData )
 2841     {
 2842       si_memcpy(forensicData->BufferType.dataBuf.directData, saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].virtPtr,biggest);
 2843     }
 2844     status = AGSA_RC_SUCCESS;
 2845   }
 2846   /* step 5 */
 2847   SA_DBG3(("siNonFatalErrorBuffer: %p directOffset 0x%x directLen 0x%x readLen 0x%x\n",
 2848                         forensicData->BufferType.dataBuf.directData,
 2849                         forensicData->BufferType.dataBuf.directOffset,
 2850                         forensicData->BufferType.dataBuf.directLen,
 2851                         forensicData->BufferType.dataBuf.readLen ));
 2852   smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2b");
 2853   return(status);
 2854 }
 2855 
 2856 
 2857 LOCAL bit32 siGetForensicData(
 2858     agsaRoot_t         *agRoot,
 2859     agsaContext_t      *agContext,
 2860     agsaForensicData_t *forensicData
 2861     )
 2862 {
 2863   bit32 status = AGSA_RC_FAILURE;
 2864         agsaLLRoot_t        *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
 2865 
 2866   smTraceFuncEnter(hpDBG_VERY_LOUD,"2Z");
 2867 
 2868   if(forensicData->DataType == TYPE_GSM_SPACE)
 2869         {
 2870 #define _1M 0x100000
 2871                 if( forensicData->BufferType.gsmBuf.directLen >= _1M )
 2872   {
 2873                         return AGSA_RC_FAILURE;
 2874                 }
 2875 
 2876                 if(forensicData->BufferType.dataBuf.readLen)
 2877     {
 2878                         SA_DBG1(("siGetForensicData: Incorrect readLen 0x%08X\n", forensicData->BufferType.dataBuf.readLen));
 2879                         forensicData->BufferType.dataBuf.readLen = forensicData->BufferType.dataBuf.directLen;
 2880                 }
 2881                 if( forensicData->BufferType.dataBuf.directOffset >= ONE_MEGABYTE )
 2882                 {
 2883                         SA_DBG1(("siGSMDump:    total length > ONE_MEGABYTE  0x%x\n",forensicData->BufferType.dataBuf.directOffset));
 2884                         forensicData->BufferType.dataBuf.readLen = 0xFFFFFFFF;
 2885                         return(AGSA_RC_SUCCESS);
 2886     }
 2887                 if(smIS_SPC(agRoot))
 2888                 {
 2889     if( forensicData->BufferType.dataBuf.directLen >= SIXTYFOURKBYTE )
 2890     {
 2891       SA_DBG1(("siGetForensicData directLen too large !\n"));
 2892       return AGSA_RC_FAILURE;
 2893     }
 2894     SA_DBG1(("siGetForensicData: TYPE_GSM_SPACE directLen 0x%X directOffset 0x%08X %p\n",
 2895                   forensicData->BufferType.dataBuf.directLen,
 2896                   forensicData->BufferType.dataBuf.directOffset,
 2897                   forensicData->BufferType.dataBuf.directData ));
 2898 
 2899 
 2900     /* Shift BAR4 original address */
 2901     if (AGSA_RC_FAILURE == siBar4Shift(agRoot, BAR_SHIFT_GSM_OFFSET + forensicData->BufferType.dataBuf.directOffset))
 2902     {
 2903       SA_DBG1(("siGSMDump:Shift Bar4 to 0x%x failed\n", 0x0));
 2904       return AGSA_RC_FAILURE;
 2905     }
 2906 
 2907   
 2908                         //if( forensicData->BufferType.dataBuf.directOffset >= ONE_MEGABYTE )
 2909                         //{
 2910                         //SA_DBG1(("siGSMDump:  total length > ONE_MEGABYTE  0x%x\n",forensicData->BufferType.dataBuf.directOffset));
 2911                         //forensicData->BufferType.dataBuf.readLen = 0xFFFFFFFF;
 2912                         //return(AGSA_RC_SUCCESS); 
 2913                         //}
 2914                         forensicData->BufferType.gsmBuf.directOffset = 0;
 2915     }
 2916     status = siGSMDump( agRoot,
 2917                                 forensicData->BufferType.gsmBuf.directOffset, 
 2918                                 forensicData->BufferType.gsmBuf.directLen, 
 2919                                 forensicData->BufferType.gsmBuf.directData );
 2920 
 2921     if(status == AGSA_RC_SUCCESS)
 2922     {
 2923       forensicData->BufferType.dataBuf.readLen = forensicData->BufferType.dataBuf.directLen;
 2924     }
 2925 
 2926     if( forensicData->BufferType.dataBuf.directOffset == 0 )
 2927     {
 2928       SA_DBG1(("siGetForensicData: TYPE_GSM_SPACE readLen 0x%08X\n", forensicData->BufferType.dataBuf.readLen));
 2929     }
 2930     smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2Z");
 2931 
 2932     return status;
 2933   }
 2934         else if(forensicData->DataType == TYPE_INBOUND_QUEUE )
 2935   {
 2936       mpiICQueue_t        *circularQ = NULL;
 2937                 SA_DBG2(("siGetForensicData: TYPE_INBOUND \n")); 
 2938 
 2939       if(forensicData->BufferType.queueBuf.queueIndex >=AGSA_MAX_INBOUND_Q )
 2940       {
 2941         smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2Z");
 2942         return AGSA_RC_FAILURE;
 2943       }
 2944       circularQ = &saRoot->inboundQueue[forensicData->BufferType.queueBuf.queueIndex];
 2945       status = siDumpInboundQueue( forensicData->BufferType.queueBuf.directData,
 2946                                  forensicData->BufferType.queueBuf.directLen,
 2947                                  circularQ );
 2948                 smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "2Z");
 2949                 return status;
 2950     }
 2951         else if(forensicData->DataType == TYPE_OUTBOUND_QUEUE )
 2952         //else if( forensicData->BufferType.queueBuf.queueType == TYPE_OUTBOUND_QUEUE )
 2953     {
 2954       mpiOCQueue_t        *circularQ = NULL;
 2955                 SA_DBG2(("siGetForensicData: TYPE_OUTBOUND\n")); 
 2956 
 2957       if(forensicData->BufferType.queueBuf.queueIndex >= AGSA_MAX_OUTBOUND_Q )
 2958       {
 2959         smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "2Z");
 2960         return AGSA_RC_FAILURE;
 2961       }
 2962 
 2963       circularQ = &saRoot->outboundQueue[forensicData->BufferType.queueBuf.queueIndex];
 2964       status = siDumpOutboundQueue(forensicData->BufferType.queueBuf.directData,
 2965                                  forensicData->BufferType.queueBuf.directLen,
 2966                                  circularQ );
 2967     smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "2Z");
 2968 
 2969     return status;
 2970   }
 2971   else if(forensicData->DataType == TYPE_NON_FATAL  )
 2972   {
 2973                 // if(smIS_SPCV(agRoot))
 2974                 // {
 2975                 SA_DBG2(("siGetForensicData:TYPE_NON_FATAL \n")); 
 2976       status = siNonFatalErrorBuffer(agRoot,forensicData);
 2977                 // }
 2978     smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "2Z");
 2979     return status;
 2980   }
 2981   else if(forensicData->DataType == TYPE_FATAL  )
 2982   {
 2983                 // if(smIS_SPCV(agRoot))
 2984                 //{
 2985                 SA_DBG2(("siGetForensicData:TYPE_NON_FATAL \n")); 
 2986       status = siFatalErrorBuffer(agRoot,forensicData );
 2987                 // }
 2988                 smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "2Z");
 2989                 return status;
 2990         }
 2991         else
 2992         {
 2993                 SA_DBG1(("siGetForensicData receive error parameter!\n"));
 2994                 smTraceFuncExit(hpDBG_VERY_LOUD, 'h', "2Z");
 2995                 return AGSA_RC_FAILURE;
 2996         }
 2997         smTraceFuncExit(hpDBG_VERY_LOUD, 'i', "2Z");
 2998 
 2999         return status;
 3000 }
 3001 
 3002 
 3003 //GLOBAL bit32 saGetForensicData(
 3004 bit32 saGetForensicData(
 3005     agsaRoot_t         *agRoot,
 3006     agsaContext_t      *agContext,
 3007     agsaForensicData_t *forensicData
 3008     )
 3009 {
 3010   bit32 status;
 3011   status = siGetForensicData(agRoot, agContext, forensicData);
 3012   ossaGetForensicDataCB(agRoot, agContext, status, forensicData);
 3013   return status;
 3014 }
 3015 
 3016 bit32 saGetIOErrorStats(
 3017                          agsaRoot_t        *agRoot,
 3018                          agsaContext_t     *agContext,
 3019                          bit32              flag
 3020                          )
 3021 {
 3022   agsaLLRoot_t  *saRoot = (agsaLLRoot_t*)agRoot->sdkData;
 3023   bit32          status = AGSA_RC_SUCCESS;
 3024 
 3025   ossaGetIOErrorStatsCB(agRoot, agContext, status, &saRoot->IoErrorCount);
 3026 
 3027   if (flag)
 3028   {
 3029     /* clear IO error counter */
 3030     si_memset(&saRoot->IoErrorCount, 0, sizeof(agsaIOErrorEventStats_t));
 3031   }
 3032 
 3033   return status;
 3034 }
 3035 
 3036 bit32 saGetIOEventStats(
 3037                          agsaRoot_t        *agRoot,
 3038                          agsaContext_t     *agContext,
 3039                          bit32              flag
 3040                          )
 3041 {
 3042   agsaLLRoot_t  *saRoot = (agsaLLRoot_t*)agRoot->sdkData;
 3043   bit32          status = AGSA_RC_SUCCESS;
 3044 
 3045   ossaGetIOEventStatsCB(agRoot, agContext, status, &saRoot->IoEventCount);
 3046 
 3047   if (flag)
 3048   {
 3049     /* clear IO event counter */
 3050     si_memset(&saRoot->IoEventCount, 0, sizeof(agsaIOErrorEventStats_t));
 3051   }
 3052 
 3053   return status;
 3054 }
 3055 
 3056 /******************************************************************************/
 3057 /*! \brief Initiate a GET REGISTER DUMP command
 3058  *
 3059  *  This function is called to Get Register Dump from the SPC.
 3060  *
 3061  *  \param agRoot      handles for this instance of SAS/SATA hardware
 3062  *  \param agContext   the context of this API
 3063  *  \param queueNum    queue number
 3064  *  \param regDumpInfo register dump information
 3065  *
 3066  *  \return
 3067  *          - SUCCESS or FAILURE
 3068  */
 3069 /*******************************************************************************/
 3070 //GLOBAL bit32 saGetRegisterDump(
 3071 bit32 saGetRegisterDump(
 3072               agsaRoot_t        *agRoot,
 3073               agsaContext_t     *agContext,
 3074               bit32             queueNum,
 3075               agsaRegDumpInfo_t *regDumpInfo
 3076               )
 3077 {
 3078   agsaLLRoot_t          *saRoot = agNULL;
 3079   bit32                 ret = AGSA_RC_SUCCESS;
 3080 //  bit32                 value, value1;
 3081 
 3082   smTraceFuncEnter(hpDBG_VERY_LOUD,"6p");
 3083 
 3084   /* sanity check */
 3085   SA_ASSERT((agNULL != agRoot), "");
 3086 
 3087   saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
 3088   /* sanity check */
 3089   SA_ASSERT((agNULL != saRoot), "");
 3090 
 3091   /* sanity check */
 3092   SA_ASSERT((agNULL != regDumpInfo), "");
 3093 
 3094   SA_DBG3(("saGetRegisterDump: agContext %p\n", agContext));
 3095 
 3096   if (regDumpInfo->regDumpSrc > 3)
 3097   {
 3098     SA_DBG1(("saGetRegisterDump, regDumpSrc %d or regDumpNum %d invalid\n",
 3099             regDumpInfo->regDumpNum, regDumpInfo->regDumpNum));
 3100     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6p");
 3101     /* CB error for Register Dump */
 3102     ossaGetRegisterDumpCB(agRoot, agContext, OSSA_FAILURE);
 3103     return AGSA_RC_FAILURE;
 3104   }
 3105 
 3106   switch(regDumpInfo->regDumpSrc)
 3107   {
 3108   case REG_DUMP_NONFLASH:
 3109     /*First 6 64k data from GSMDUMP, contains IOST and RB info*/
 3110     if (regDumpInfo->regDumpNum == GET_IOST_RB_INFO)
 3111     {
 3112       regDumpInfo->regDumpOffset = regDumpInfo->regDumpOffset + 0;
 3113       ret = siGSMDump(agRoot, regDumpInfo->regDumpOffset, regDumpInfo->directLen, regDumpInfo->directData);
 3114       /* CB error for Register Dump */
 3115       ossaGetRegisterDumpCB(agRoot, agContext, ret);
 3116       return ret;
 3117     }
 3118     /* Last 1MB data from GSMDUMP, contains GSM_SM info*/
 3119 
 3120     if (regDumpInfo->regDumpNum == GET_GSM_SM_INFO)
 3121     {
 3122       /* GSM_SM - total 1 Mbytes */
 3123       bit32    offset;
 3124       if(smIS_SPC(agRoot))
 3125       {
 3126         offset = regDumpInfo->regDumpOffset + SPC_GSM_SM_OFFSET;
 3127       }else if(smIS_SPCV(agRoot))
 3128       {
 3129         offset = regDumpInfo->regDumpOffset + SPCV_GSM_SM_OFFSET;
 3130       } else
 3131       {
 3132         SA_DBG1(("saGetRegisterDump: the device type is not support\n"));
 3133         return AGSA_RC_FAILURE;
 3134       }
 3135 
 3136       ret = siGSMDump(agRoot, offset, regDumpInfo->directLen, regDumpInfo->directData);
 3137       /* CB error for Register Dump */
 3138       ossaGetRegisterDumpCB(agRoot, agContext, ret);
 3139       return ret;
 3140     }
 3141 
 3142     /* check fatal errors */
 3143     if(smIS_SPC(agRoot)) {
 3144       siSpcGetErrorContent(agRoot);
 3145     }
 3146     else if(smIS_SPCV(agRoot)) {
 3147       siSpcvGetErrorContent(agRoot);
 3148     }
 3149     /* Then read from local copy */
 3150     if (regDumpInfo->directLen > REGISTER_DUMP_BUFF_SIZE)
 3151     {
 3152       SA_DBG1(("saGetRegisterDump, Request too many bytes %d\n",
 3153               regDumpInfo->directLen));
 3154       regDumpInfo->directLen = REGISTER_DUMP_BUFF_SIZE;
 3155     }
 3156 
 3157     if (regDumpInfo->regDumpNum == 0)
 3158     {
 3159       /* Copy the LL Local register dump0 data to the destination */
 3160       si_memcpy(regDumpInfo->directData, (bit8 *)&saRoot->registerDump0[0] +
 3161                 regDumpInfo->regDumpOffset, regDumpInfo->directLen);
 3162     }
 3163     else if( regDumpInfo->regDumpNum == 1)
 3164     {
 3165       /* Copy the LL Local register dump1 data to the destination */
 3166       si_memcpy(regDumpInfo->directData, (bit8 *)&saRoot->registerDump1[0] +
 3167                 regDumpInfo->regDumpOffset, regDumpInfo->directLen);
 3168     } else {
 3169       SA_DBG1(("saGetRegisterDump, the regDumpNum value is wrong %x\n",
 3170               regDumpInfo->regDumpNum));
 3171     }
 3172 
 3173     /* CB for Register Dump */
 3174     ossaGetRegisterDumpCB(agRoot, agContext, OSSA_SUCCESS);
 3175     break;
 3176 
 3177   case REG_DUMP_FLASH:
 3178     /* build IOMB command and send to SPC */
 3179     ret = mpiNVMReadRegDumpCmd(agRoot, agContext, queueNum,
 3180                             regDumpInfo->regDumpNum,
 3181                             regDumpInfo->regDumpOffset,
 3182                             regDumpInfo->indirectAddrUpper32,
 3183                             regDumpInfo->indirectAddrLower32,
 3184                             regDumpInfo->indirectLen);
 3185 
 3186     break;
 3187 
 3188   default:
 3189     break;
 3190   }
 3191 
 3192   smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6p");
 3193 
 3194   return ret;
 3195 }
 3196 
 3197 /******************************************************************************/
 3198 /*! \brief Initiate a GET REGISTER DUMP from GSM command
 3199  *
 3200  *  This function is called to Get Register Dump from the GSM of SPC.
 3201  *
 3202  *  \param agRoot      handles for this instance of SAS/SATA hardware
 3203  *  \param destinationAddress address of the register dump data copied to
 3204  *  \param regDumpNum  Register Dump # 0 or 1
 3205  *  \param regDumpOffset Offset within the register dump area
 3206  *  \param len         Length in bytes of the register dump data to copy
 3207  *
 3208  *  \return
 3209  *          - SUCCESS or FAILURE
 3210  */
 3211 /*******************************************************************************/
 3212 //GLOBAL bit32 siGetRegisterDumpGSM(
 3213 bit32 siGetRegisterDumpGSM(
 3214                         agsaRoot_t        *agRoot,
 3215                         void              *destinationAddress,
 3216                         bit32             regDumpNum,
 3217                         bit32             regDumpOffset,
 3218                         bit32             len
 3219                         )
 3220 {
 3221   agsaLLRoot_t          *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
 3222   bit32                 ret = AGSA_RC_SUCCESS;
 3223   bit32                 rDumpOffset, rDumpLen; //, rDumpValue;
 3224   bit8                  *dst;
 3225 
 3226   smTraceFuncEnter(hpDBG_VERY_LOUD,"2V");
 3227 
 3228   /* sanity check */
 3229   SA_ASSERT((agNULL != agRoot), "");
 3230 
 3231   dst = (bit8 *)destinationAddress;
 3232 
 3233   if (regDumpNum > 1)
 3234   {
 3235     SA_DBG1(("siGetRegisterDump, regDumpNum %d is invalid\n", regDumpNum));
 3236     return AGSA_RC_FAILURE;
 3237   }
 3238 
 3239   if (!regDumpNum)
 3240   {
 3241     rDumpOffset = saRoot->mainConfigTable.FatalErrorDumpOffset0;
 3242     rDumpLen = saRoot->mainConfigTable.FatalErrorDumpLength0;
 3243   }
 3244   else
 3245   {
 3246     rDumpOffset = saRoot->mainConfigTable.FatalErrorDumpOffset1;
 3247     rDumpLen = saRoot->mainConfigTable.FatalErrorDumpLength1;
 3248   }
 3249 
 3250   if (len > rDumpLen)
 3251   {
 3252     SA_DBG1(("siGetRegisterDump, Request too many bytes %d, rDumpLen %d\n", len, rDumpLen));
 3253     len = rDumpLen;
 3254   }
 3255 
 3256   if (regDumpOffset >= len)
 3257   {
 3258     SA_DBG1(("siGetRegisterDump, Offset is not within the area %d, regDumpOffset%d\n", rDumpLen, regDumpOffset));
 3259     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2V");
 3260     return AGSA_RC_FAILURE;
 3261   }
 3262 
 3263   /* adjust length to dword boundary */
 3264   if ((len % 4) > 0)
 3265   {
 3266     len = (len/4 + 1) * 4;
 3267   }
 3268 
 3269   ret = siGSMDump(agRoot, rDumpOffset, len, dst);
 3270   smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2V");
 3271 
 3272   return ret;
 3273 }
 3274 
 3275 /******************************************************************************/
 3276 /*! \brief SPC Get NVMD Command
 3277  *
 3278  *  This command sends GET_NVMD_DATA Command to SPC.
 3279  *
 3280  *  \param agRoot       Handles for this instance of SAS/SATA LL
 3281  *  \param agContext    Context of SPC FW Flash Update Command
 3282  *  \param queueNum     Inbound/outbound queue number
 3283  *  \param NVMDInfo     Pointer of NVM Device information
 3284  *
 3285  *  \return If the MPI command is sent to SPC successfully
 3286  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
 3287  *          - \e AGSA_RC_FAILURE the MPI command is failure
 3288  *
 3289  */
 3290 /*******************************************************************************/
 3291 //GLOBAL bit32 saGetNVMDCommand(
 3292 bit32 saGetNVMDCommand(
 3293   agsaRoot_t                *agRoot,
 3294   agsaContext_t             *agContext,
 3295   bit32                     queueNum,
 3296   agsaNVMDData_t            *NVMDInfo
 3297   )
 3298 {
 3299   bit32 ret           = AGSA_RC_SUCCESS;
 3300 
 3301   /* sanity check */
 3302   SA_ASSERT((agNULL != agRoot), "");
 3303 
 3304   /* build IOMB command and send to SPC */
 3305   ret = mpiGetNVMDCmd(agRoot, agContext, NVMDInfo, queueNum);
 3306 
 3307   return ret;
 3308 }
 3309 
 3310 /******************************************************************************/
 3311 /*! \brief SPC Set NVMD Command
 3312  *
 3313  *  This command sends SET_NVMD_DATA Command to SPC.
 3314  *
 3315  *  \param agRoot       Handles for this instance of SAS/SATA LL
 3316  *  \param agContext    Context of SPC FW Flash Update Command
 3317  *  \param queueNum     Inbound/outbound queue number
 3318  *  \param NVMDInfo     Pointer of NVM Device information
 3319  *
 3320  *  \return If the MPI command is sent to SPC successfully
 3321  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
 3322  *          - \e AGSA_RC_FAILURE the MPI command is failure
 3323  *
 3324  */
 3325 /*******************************************************************************/
 3326 //GLOBAL bit32 saSetNVMDCommand(
 3327 bit32 saSetNVMDCommand(
 3328   agsaRoot_t                *agRoot,
 3329   agsaContext_t             *agContext,
 3330   bit32                     queueNum,
 3331   agsaNVMDData_t            *NVMDInfo
 3332   )
 3333 {
 3334   bit32 ret           = AGSA_RC_SUCCESS;
 3335 
 3336   /* sanity check */
 3337   SA_ASSERT((agNULL != agRoot), "");
 3338 
 3339   /* build IOMB command and send to SPC */
 3340   ret = mpiSetNVMDCmd(agRoot, agContext, NVMDInfo, queueNum);
 3341 
 3342   return ret;
 3343 }
 3344 
 3345 
 3346 GLOBAL bit32 saSendSMPIoctl(
 3347   agsaRoot_t                *agRoot,
 3348   agsaDevHandle_t           *agDevHandle,
 3349   bit32                      queueNum,
 3350   agsaSMPFrame_t            *pSMPFrame,  
 3351   ossaSMPCompletedCB_t       agCB
 3352   )
 3353 {
 3354   bit32 ret           = AGSA_RC_SUCCESS;
 3355   //bit32 IR_IP_OV_res_phyId_DPdLen_res = 0;
 3356   bit32 retVal;
 3357   bit8                      inq, outq;
 3358   agsaIORequestDesc_t       *pRequest;
 3359   void                      *pMessage;
 3360   bit8                      *payload_ptr;
 3361   agsaDeviceDesc_t          *pDevice;
 3362   bit8                      using_reserved = agFALSE;  
 3363   agsaPort_t                *pPort;  
 3364   mpiICQueue_t              *circularQ;
 3365   agsaLLRoot_t              *saRoot = agNULL;
 3366 //  agsaDevHandle_t             *agDevHandle;
 3367 
 3368   saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
 3369   SA_ASSERT((agNULL != saRoot), "");
 3370 
 3371   /* sanity check */
 3372   SA_ASSERT((agNULL != agRoot), "");
 3373 
 3374 
 3375   
 3376   /* Get request from free IO Requests */
 3377   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);      
 3378   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/
 3379 
 3380   /* If no LL IO request entry available */
 3381   if ( agNULL == pRequest )
 3382   {
 3383     pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests));
 3384 
 3385     if(agNULL != pRequest)
 3386     {
 3387       using_reserved = agTRUE;
 3388       SA_DBG1(("saSMPStart, using saRoot->freeReservedRequests\n"));  
 3389     }
 3390     else
 3391     {
 3392       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 3393       SA_DBG1(("saSMPStart, No request from free list Not using saRoot->freeReservedRequests\n"));  
 3394       smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "9a");
 3395       return AGSA_RC_BUSY;     
 3396     }
 3397   }
 3398 
 3399   inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
 3400   outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
 3401 
 3402 
 3403 
 3404   
 3405   SA_ASSERT((agNULL != agDevHandle), "");
 3406   /* Find the outgoing port for the device */
 3407   if (agNULL == agDevHandle->sdkData)
 3408   {
 3409         /* Device has been removed */
 3410       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 3411         SA_DBG1(("saSMPStart, Device has been removed. agDevHandle=%p\n", agDevHandle));
 3412         smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "9a");
 3413         return AGSA_RC_FAILURE;
 3414   }
 3415           
 3416   pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
 3417          
 3418   pPort = pDevice->pPort;
 3419         
 3420 
 3421         
 3422           /* If free IOMB avaliable */
 3423           /* Remove the request from free list */
 3424           if( using_reserved )
 3425           {
 3426                 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
 3427           }
 3428           else
 3429           {
 3430                 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
 3431           }
 3432         
 3433           /* Add the request to the pendingSMPRequests list of the device */
 3434           saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode));
 3435           SA_ASSERT((!pRequest->valid), "The pRequest is in use");
 3436           pRequest->valid                         = agTRUE;
 3437           ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 3438         
 3439           /* set up pRequest */
 3440           pRequest->pIORequestContext = (agsaIORequest_t *)pRequest;
 3441           pRequest->pDevice               = pDevice;
 3442           pRequest->pPort                         = pPort;              
 3443           pRequest->startTick             = saRoot->timeTick;
 3444           pRequest->completionCB          = (ossaSSPCompletedCB_t)agCB;
 3445           pRequest->requestType           = AGSA_SMP_IOCTL_REQUEST;
 3446         
 3447           /* Set request to the sdkData of agIORequest */
 3448          // agIORequest->sdkData                  = pRequest;
 3449         
 3450           /* save tag to IOMap */
 3451           saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
 3452           saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
 3453         
 3454 #ifdef SA_LL_IBQ_PROTECT
 3455           ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
 3456 #endif /* SA_LL_IBQ_PROTECT */
 3457         
 3458           /* If LL IO request entry avaliable */
 3459           /* Get a free inbound queue entry */
 3460           circularQ = &saRoot->inboundQueue[inq];
 3461           retVal        = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage);
 3462          
 3463           if (AGSA_RC_FAILURE == retVal)
 3464           {
 3465 #ifdef SA_LL_IBQ_PROTECT
 3466                 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
 3467 #endif /* SA_LL_IBQ_PROTECT */
 3468                 /* if not sending return to free list rare */
 3469                 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 3470                 saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
 3471                 pRequest->valid = agFALSE;
 3472                 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
 3473                 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 3474         
 3475                 SA_DBG1(("saSMPStart, error when get free IOMB\n")); 
 3476                 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "9a");
 3477                 return AGSA_RC_FAILURE;
 3478           }
 3479          
 3480           /* return busy if inbound queue is full */
 3481           if (AGSA_RC_BUSY == retVal)
 3482           {
 3483 #ifdef SA_LL_IBQ_PROTECT
 3484                 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
 3485 #endif /* SA_LL_IBQ_PROTECT */
 3486                 /* if not sending return to free list rare */
 3487                 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 3488                 saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
 3489                 pRequest->valid = agFALSE;
 3490                 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
 3491                 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 3492         
 3493                 SA_DBG1(("saSMPStart, no more IOMB\n"));  
 3494                 smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "9a");
 3495                 return AGSA_RC_BUSY;
 3496           }
 3497 #ifdef SA_LL_IBQ_PROTECT
 3498                           ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
 3499 #endif /* SA_LL_IBQ_PROTECT */
 3500 
 3501 
 3502         if(smIS_SPC(agRoot))
 3503         {
 3504          agsaSMPCmd_t payload;
 3505   
 3506 
 3507                   bit32 IR_IP_OV_res_phyId_DPdLen_res = 0;
 3508                   /* Prepare the payload of IOMB */
 3509                   si_memset(&payload, 0, sizeof(agsaSMPCmd_V_t));
 3510                   OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, tag), pRequest->HTag);
 3511                   OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, deviceId), pDevice->DeviceMapIndex);
 3512 
 3513 
 3514 
 3515                   /*Indirect request and response*/
 3516                   if (smpFrameFlagIndirectResponse & pSMPFrame->flag && smpFrameFlagIndirectPayload & pSMPFrame->flag) /* */
 3517                   {
 3518   
 3519                         SA_DBG2(("saSMPStart:V Indirect payload and indirect response\n"));
 3520   
 3521                         /* Indirect Response mode */
 3522                         pRequest->IRmode = INDIRECT_MODE;
 3523                         IR_IP_OV_res_phyId_DPdLen_res = 3;
 3524   
 3525   
 3526                         /* payload */
 3527                         OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[4]), (pSMPFrame->outFrameAddrLower32));
 3528                         OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[5]), (pSMPFrame->outFrameAddrUpper32));
 3529                         OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[6]), (pSMPFrame->outFrameLen));
 3530                         
 3531                         OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[8]), (pSMPFrame->inFrameAddrLower32));
 3532                         OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[9]), (pSMPFrame->inFrameAddrUpper32));
 3533                         OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[10]), (pSMPFrame->inFrameLen));
 3534                         
 3535                   }
 3536                   
 3537 
 3538                   IR_IP_OV_res_phyId_DPdLen_res |= (pSMPFrame->flag & 3);
 3539                   /* fatal error if missing */
 3540                   OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, IR_IP_OV_res_phyId_DPdLen_res), IR_IP_OV_res_phyId_DPdLen_res);
 3541                   /* fatal error if missing */
 3542   
 3543                           
 3544                 /* check IR bit */
 3545   
 3546                 /* Build IOMB command and send it to SPC */
 3547                 payload_ptr = (bit8 *)&payload;
 3548 #ifdef SA_LL_IBQ_PROTECT
 3549                                 ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
 3550 #endif /* SA_LL_IBQ_PROTECT */
 3551 
 3552                 ret = mpiSMPCmd(agRoot, pMessage, OPC_INB_SMP_REQUEST, (agsaSMPCmd_t *)payload_ptr, inq, outq);
 3553 
 3554 #ifdef SA_LL_IBQ_PROTECT
 3555                           ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
 3556 #endif /* SA_LL_IBQ_PROTECT */
 3557 
 3558                 
 3559   }
 3560         else /* IOMB is different for SPCV SMP */
 3561         {
 3562          agsaSMPCmd_V_t vpayload;
 3563   
 3564 
 3565                   bit32 IR_IP_OV_res_phyId_DPdLen_res = 0;
 3566                   /* Prepare the payload of IOMB */
 3567                   si_memset(&vpayload, 0, sizeof(agsaSMPCmd_V_t));
 3568                   OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, tag), pRequest->HTag);
 3569                   OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, deviceId), pDevice->DeviceMapIndex);
 3570                   OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMPHDR ), *((bit32*)pSMPFrame->outFrameBuf+0) );
 3571 
 3572                   /*Indirect request and response*/
 3573                   if (smpFrameFlagIndirectResponse & pSMPFrame->flag && smpFrameFlagIndirectPayload & pSMPFrame->flag) /* */
 3574                   {
 3575   
 3576                         SA_DBG2(("saSMPStart:V Indirect payload and indirect response\n"));
 3577   
 3578                         /* Indirect Response mode */
 3579                         pRequest->IRmode = INDIRECT_MODE;
 3580                         IR_IP_OV_res_phyId_DPdLen_res = 3;
 3581   
 3582   
 3583                         /* payload */
 3584                         OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirL_SMPRF15_12 ), (pSMPFrame->outFrameAddrLower32));
 3585                         OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirH_or_SMPRF19_16 ), (pSMPFrame->outFrameAddrUpper32));
 3586                         OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirLen_or_SMPRF23_20 ), (pSMPFrame->outFrameLen));
 3587                         
 3588                         OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,ISRAL_or_SMPRF31_28), (pSMPFrame->inFrameAddrLower32));
 3589                         OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,ISRAH_or_SMPRF35_32), (pSMPFrame->inFrameAddrUpper32));
 3590                         OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,ISRL_or_SMPRF39_36), (pSMPFrame->inFrameLen));
 3591                         
 3592                   }
 3593                   
 3594                   /*Direct request and indirect response*/
 3595                   else if (smpFrameFlagIndirectResponse & pSMPFrame->flag ) /* */
 3596                   {
 3597   
 3598                         SA_DBG2(("saSMPStart:V Direct payload and indirect response\n"));
 3599                         IR_IP_OV_res_phyId_DPdLen_res = (pSMPFrame->outFrameLen << SHIFT16) | pSMPFrame->flag;
 3600   
 3601                         
 3602                           /* Write IR_IP_OV_res_phyId_DPdLen_res field in the payload*/  
 3603                           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, IR_IP_OV_res_phyId_DPdLen_res), IR_IP_OV_res_phyId_DPdLen_res);
 3604                           /* setup indirect response frame address */
 3605                           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRAL_or_SMPRF31_28 ), (pSMPFrame->inFrameAddrLower32));
 3606                           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRAH_or_SMPRF35_32 ), (pSMPFrame->inFrameAddrUpper32));
 3607                           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRL_or_SMPRF39_36 ), (pSMPFrame->inFrameLen));             
 3608                         
 3609                   }
 3610                   IR_IP_OV_res_phyId_DPdLen_res |= (pSMPFrame->flag & 3);
 3611                   /* fatal error if missing */
 3612                   OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, IR_IP_OV_res_phyId_DPdLen_res), IR_IP_OV_res_phyId_DPdLen_res);
 3613                   /* fatal error if missing */
 3614   
 3615                           
 3616                 /* check IR bit */
 3617   
 3618 #ifdef SA_LL_IBQ_PROTECT
 3619                                 ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
 3620 #endif /* SA_LL_IBQ_PROTECT */
 3621                 /* Build IOMB command and send it to SPCv */
 3622                 payload_ptr = (bit8 *)&vpayload;
 3623                 ret = mpiSMPCmd(agRoot, pMessage, OPC_INB_SMP_REQUEST, (agsaSMPCmd_t *)payload_ptr, inq, outq);
 3624 
 3625 #ifdef SA_LL_IBQ_PROTECT
 3626                           ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
 3627 #endif /* SA_LL_IBQ_PROTECT */
 3628 
 3629                 
 3630   }
 3631   
 3632 
 3633   return ret;
 3634 }
 3635 
 3636 
 3637 /******************************************************************************/
 3638 /*! \brief Reconfiguration of SAS Parameters Command
 3639  *
 3640  *  This command Reconfigure the SAS parameters to SPC.
 3641  *
 3642  *  \param agRoot       Handles for this instance of SAS/SATA LL
 3643  *  \param agContext    Context of SPC FW Flash Update Command
 3644  *  \param queueNum     Inbound/outbound queue number
 3645  *  \param agSASConfig  Pointer of SAS Configuration Parameters
 3646  *
 3647  *  \return If the MPI command is sent to SPC successfully
 3648  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
 3649  *          - \e AGSA_RC_FAILURE the MPI command is failure
 3650  *
 3651  */
 3652 /*******************************************************************************/
 3653 //GLOBAL bit32 saReconfigSASParams(
 3654 bit32 saReconfigSASParams(
 3655   agsaRoot_t        *agRoot,
 3656   agsaContext_t     *agContext,
 3657   bit32             queueNum ,
 3658   agsaSASReconfig_t *agSASConfig
 3659   )
 3660 {
 3661   bit32 ret           = AGSA_RC_SUCCESS;
 3662 
 3663   /* sanity check */
 3664   SA_ASSERT((agNULL != agRoot), "");
 3665 
 3666   if(smIS_SPCV(agRoot))
 3667   {
 3668     SA_DBG1(("saReconfigSASParams: AGSA_RC_FAILURE for SPCv\n" ));
 3669     return(AGSA_RC_FAILURE);
 3670   }
 3671 
 3672   /* build IOMB command and send to SPC */
 3673   ret = mpiSasReinitializeCmd(agRoot, agContext, agSASConfig, queueNum);
 3674 
 3675   return ret;
 3676 }
 3677 
 3678 /******************************************************************************/
 3679 /*! \brief Dump GSM registers from the controller
 3680  *
 3681  *  \param agRoot         Handles for this instance of SAS/SATA hardware
 3682  *  \param gsmDumpOffset  Offset of GSM
 3683  *  \param length         Max is 1 MB
 3684  *  \param directData     address of GSM data dump to
 3685  *
 3686  *  \return
 3687  *          - \e AGSA_RC_SUCCESS saGSMDump is successfully
 3688  *          - \e AGSA_RC_FAILURE saGSMDump is not successfully
 3689  *
 3690  */
 3691 /*******************************************************************************/
 3692 //LOCAL bit32 siGSMDump(
 3693 bit32 siGSMDump(
 3694   agsaRoot_t     *agRoot,
 3695   bit32          gsmDumpOffset,
 3696   bit32          length,
 3697   void           *directData)
 3698 {
 3699   bit8  *dst;
 3700   bit32 value, rem, offset = 0;
 3701   bit32 i, workOffset, dwLength;
 3702   bit32 bar = 0;
 3703 
 3704   SA_DBG1(("siGSMDump: gsmDumpOffset 0x%x length 0x%x\n", gsmDumpOffset, length));
 3705 
 3706   /* check max is 64k chunks */
 3707   if (length > (64 * 1024))  
 3708   {
 3709     SA_DBG1(("siGSMDump: Max length is greater than 64K  bytes 0x%x\n", length));
 3710     return AGSA_RC_FAILURE;
 3711   }
 3712 
 3713   if (gsmDumpOffset & 3)
 3714   {
 3715     SA_DBG1(("siGSMDump: Not allow NON_DW Boundary 0x%x\n", gsmDumpOffset));
 3716     return AGSA_RC_FAILURE;
 3717   }
 3718 
 3719   if ((gsmDumpOffset + length) > ONE_MEGABYTE)
 3720   {
 3721     SA_DBG1(("siGSMDump: Out of GSM end address boundary 0x%x\n", (gsmDumpOffset+length)));
 3722     return AGSA_RC_FAILURE;
 3723   }
 3724 
 3725   if( smIS_SPCV(agRoot))
 3726   {
 3727     bar = PCIBAR1;
 3728   }
 3729   else if( smIS_SPC(agRoot))
 3730   {
 3731     bar = PCIBAR2;
 3732   }
 3733   else
 3734   {
 3735     SA_DBG1(("siGSMDump: device type is not supported"));
 3736     return AGSA_RC_FAILURE;
 3737   }
 3738 
 3739   workOffset = gsmDumpOffset & 0xFFFF0000;
 3740   offset = gsmDumpOffset & 0x0000FFFF;
 3741   gsmDumpOffset = workOffset;
 3742 
 3743   dst = (bit8 *)directData;
 3744 
 3745   /* adjust length to dword boundary */
 3746   rem = length & 3;
 3747   dwLength = length >> 2;
 3748 
 3749   for (i =0; i < dwLength; i++)
 3750   {
 3751     if((workOffset + offset) > length )
 3752     {
 3753       break;
 3754     }
 3755     value = ossaHwRegReadExt(agRoot, bar, (workOffset + offset) & 0x0000FFFF);
 3756     /* xfr for dw */
 3757     si_memcpy(dst, &value, 4);
 3758     dst += 4;
 3759     offset += 4;
 3760   }
 3761 
 3762   if (rem != 0)
 3763   {
 3764     value = ossaHwRegReadExt(agRoot, bar, (workOffset + offset) & 0x0000FFFF);
 3765     /* xfr for non_dw */
 3766     if(dst)
 3767     {
 3768       si_memcpy(dst, &value, rem);
 3769     }
 3770   }
 3771 
 3772   /* Shift back to BAR4 original address */
 3773   if (AGSA_RC_FAILURE == siBar4Shift(agRoot, 0x0))
 3774   {
 3775     SA_DBG1(("siGSMDump:Shift Bar4 to 0x%x failed\n", 0x0));
 3776     return AGSA_RC_FAILURE;
 3777   }
 3778 
 3779   return AGSA_RC_SUCCESS;
 3780 }
 3781 
 3782 //GLOBAL bit32 saPCIeDiagExecute(
 3783 bit32 saPCIeDiagExecute(
 3784             agsaRoot_t            *agRoot,
 3785             agsaContext_t         *agContext,
 3786             bit32                 queueNum,
 3787             agsaPCIeDiagExecute_t *diag)
 3788 {
 3789   bit32                    ret    = AGSA_RC_SUCCESS;
 3790   agsaLLRoot_t            *saRoot = agNULL;
 3791   agsaIORequestDesc_t     *pRequest;
 3792   bit32  payload[32];
 3793 
 3794   smTraceFuncEnter(hpDBG_VERY_LOUD,"6r");
 3795 
 3796   /* sanity check */
 3797   SA_ASSERT((agNULL != agRoot), "");
 3798 
 3799   saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
 3800   /* sanity check */
 3801   SA_ASSERT((agNULL != saRoot), "");
 3802   SA_ASSERT((agNULL != diag), "");
 3803 
 3804   if(diag->len == 0)
 3805   {
 3806     SA_DBG1(("saPCIeDiagExecute,  diag->len Zero\n"));
 3807   }
 3808   SA_DBG1(("saPCIeDiagExecute, diag->command  0x%X\n", diag->command ));
 3809   SA_DBG1(("saPCIeDiagExecute, diag->flags  0x%X\n",diag->flags ));
 3810   SA_DBG1(("saPCIeDiagExecute,  diag->initialIOSeed  0x%X\n", diag->initialIOSeed));
 3811   SA_DBG1(("saPCIeDiagExecute, diag->reserved   0x%X\n",diag->reserved ));
 3812   SA_DBG1(("saPCIeDiagExecute, diag->rdAddrLower   0x%X\n", diag->rdAddrLower));
 3813   SA_DBG1(("saPCIeDiagExecute, diag->rdAddrUpper   0x%X\n", diag->rdAddrUpper ));
 3814   SA_DBG1(("saPCIeDiagExecute, diag->wrAddrLower   0x%X\n", diag->wrAddrLower));
 3815   SA_DBG1(("saPCIeDiagExecute, diag->wrAddrUpper   0x%X\n",diag->wrAddrUpper ));
 3816   SA_DBG1(("saPCIeDiagExecute,  diag->len   0x%X\n",diag->len  ));
 3817   SA_DBG1(("saPCIeDiagExecute, diag->pattern  0x%X\n",diag->pattern ));
 3818   SA_DBG1(("saPCIeDiagExecute, %02X %02X %02X %02X %02X %02X\n",
 3819                   diag->udtArray[0],
 3820                   diag->udtArray[1],
 3821                   diag->udtArray[2],
 3822                   diag->udtArray[3],
 3823                   diag->udtArray[4],
 3824                   diag->udtArray[5] ));
 3825 
 3826    SA_DBG1(("saPCIeDiagExecute, %02X %02X %02X %02X %02X %02X\n",
 3827                   diag->udrtArray[0],
 3828                   diag->udrtArray[1],
 3829                   diag->udrtArray[2],
 3830                   diag->udrtArray[3],
 3831                   diag->udrtArray[4],
 3832                   diag->udrtArray[5]));
 3833 
 3834 
 3835   /* Get request from free IORequests */
 3836   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 3837   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
 3838 
 3839   /* If no LL Control request entry available */
 3840   if ( agNULL == pRequest )
 3841   {
 3842     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 3843     SA_DBG1(("saPCIeDiagExecute, No request from free list\n" ));
 3844     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6r");
 3845     return AGSA_RC_BUSY;
 3846   }
 3847   /* If LL Control request entry avaliable */
 3848   /* Remove the request from free list */
 3849   saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
 3850   saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
 3851   saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
 3852   saRoot->IOMap[pRequest->HTag].agContext = agContext;
 3853   pRequest->valid = agTRUE;
 3854 
 3855   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 3856 
 3857   /* set payload to zeros */
 3858   si_memset(&payload, 0, sizeof(payload));
 3859 
 3860   if(smIS_SPCV(agRoot))
 3861   {
 3862     bit32      UDTR1_UDT0 ,UDT5_UDT2,UDTR5_UDTR2;
 3863 
 3864     UDTR5_UDTR2 = (( diag->udrtArray[5] << SHIFT24) | (diag->udrtArray[4] << SHIFT16) | (diag->udrtArray[3] << SHIFT8) | diag->udrtArray[2]);
 3865     UDT5_UDT2 =   ((  diag->udtArray[5] << SHIFT24) |  (diag->udtArray[4] << SHIFT16) |  (diag->udtArray[3] << SHIFT8) |  diag->udtArray[2]);
 3866     UDTR1_UDT0 =  (( diag->udrtArray[1] << SHIFT24) | (diag->udrtArray[0] << SHIFT16) |  (diag->udtArray[1] << SHIFT8) |  diag->udtArray[0]);
 3867 
 3868     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, tag)        , pRequest->HTag);
 3869     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, CmdTypeDesc), diag->command );
 3870     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, UUM_EDA)    , diag->flags);
 3871     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, UDTR1_UDT0) , UDTR1_UDT0);
 3872     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, UDT5_UDT2)  , UDT5_UDT2);
 3873     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, UDTR5_UDTR2), UDTR5_UDTR2);
 3874     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, Res_IOS)    , diag->initialIOSeed);
 3875     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, rdAddrLower), diag->rdAddrLower);
 3876     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, rdAddrUpper), diag->rdAddrUpper);
 3877     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, wrAddrLower), diag->wrAddrLower);
 3878     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, wrAddrUpper), diag->wrAddrUpper);
 3879     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, len),         diag->len);
 3880     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, pattern),     diag->pattern);
 3881     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_PCIE_DIAG_EXECUTE, IOMB_SIZE128, queueNum);
 3882   }
 3883   else
 3884   {
 3885     /* build IOMB command and send to SPC */
 3886     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, tag),         pRequest->HTag);
 3887     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, CmdTypeDesc), diag->command );
 3888     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, rdAddrLower), diag->rdAddrLower);
 3889     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, rdAddrUpper), diag->rdAddrUpper);
 3890     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, wrAddrLower), diag->wrAddrLower);
 3891     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, wrAddrUpper), diag->wrAddrUpper);
 3892     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, len),         diag->len);
 3893     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, pattern),     diag->pattern);
 3894     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_PCIE_DIAG_EXECUTE, IOMB_SIZE64, queueNum);
 3895   }
 3896 
 3897   if (AGSA_RC_SUCCESS != ret)
 3898   {
 3899     /* remove the request from IOMap */
 3900     saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
 3901     saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
 3902     saRoot->IOMap[pRequest->HTag].agContext = agNULL;
 3903 
 3904     ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 3905     pRequest->valid = agFALSE;
 3906 
 3907     /* return the request to free pool */
 3908     saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
 3909 
 3910     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 3911 
 3912     SA_DBG1(("saPCIeDiagExecute, sending IOMB failed\n" ));
 3913     smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6r");
 3914 
 3915     return ret;
 3916   }
 3917 
 3918   smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "6r");
 3919   return ret;
 3920 }
 3921 
 3922 //GLOBAL bit32 saGetDFEData(
 3923 bit32 saGetDFEData(
 3924                           agsaRoot_t     *agRoot,
 3925                           agsaContext_t  *agContext,
 3926                           bit32           queueNum,
 3927                           bit32           interface,
 3928                           bit32           laneNumber,
 3929                           bit32           interations,
 3930                           agsaSgl_t      *agSgl)
 3931 {
 3932   bit32                    ret    = AGSA_RC_SUCCESS;
 3933   agsaLLRoot_t            *saRoot = agNULL;
 3934   agsaIORequestDesc_t     *pRequest = agNULL;
 3935   bit32  payload[32];
 3936   bit32 reserved_In_Ln;
 3937 
 3938   smTraceFuncEnter(hpDBG_VERY_LOUD,"2X");
 3939   /* sanity check */
 3940   SA_ASSERT((agNULL != agRoot), "");
 3941   saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
 3942   SA_ASSERT((agNULL != saRoot), "");
 3943   SA_ASSERT((agNULL != agSgl), "");
 3944 
 3945   /* Get request from free IORequests */
 3946   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 3947   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
 3948 
 3949   /* If no LL Control request entry available */
 3950   if ( agNULL == pRequest )
 3951   {
 3952     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 3953     SA_DBG1(("saGetDFEData, No request from free list\n" ));
 3954     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2X");
 3955     return AGSA_RC_BUSY;
 3956   }
 3957   /* If LL Control request entry avaliable */
 3958   /* Remove the request from free list */
 3959   saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
 3960   saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
 3961   saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
 3962   saRoot->IOMap[pRequest->HTag].agContext = agContext;
 3963   pRequest->valid = agTRUE;
 3964 
 3965   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 3966 
 3967   /* set payload to zeros */
 3968   si_memset(&payload, 0, sizeof(payload));
 3969 
 3970   if(smIS_SPCV(agRoot))
 3971   {
 3972     reserved_In_Ln = ((interface & 0x1) << SHIFT7) | (laneNumber & 0x7F);
 3973     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDDEFDataCmd_t, tag)        , pRequest->HTag);
 3974     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDDEFDataCmd_t, reserved_In_Ln)        , reserved_In_Ln);
 3975     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDDEFDataCmd_t, MCNT)        , interations);
 3976     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDDEFDataCmd_t, Buf_AddrL)        , agSgl->sgLower);
 3977     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDDEFDataCmd_t, Buf_AddrH)        , agSgl->sgUpper);
 3978     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDDEFDataCmd_t, Buf_Len)        , agSgl->len);
 3979     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDDEFDataCmd_t, E_reserved)        , agSgl->extReserved);
 3980     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_DFE_DATA, IOMB_SIZE128, queueNum);
 3981 
 3982   }
 3983   else
 3984   {
 3985     /* SPC does not support this command */
 3986     ret = AGSA_RC_FAILURE;
 3987   }
 3988 
 3989   if (AGSA_RC_SUCCESS != ret)
 3990   {
 3991     /* remove the request from IOMap */
 3992     saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
 3993     saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
 3994     saRoot->IOMap[pRequest->HTag].agContext = agNULL;
 3995 
 3996     ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 3997     pRequest->valid = agFALSE;
 3998     /* return the request to free pool */
 3999     saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
 4000     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 4001 
 4002     SA_DBG1(("saPCIeDiagExecute, sending IOMB failed\n" ));
 4003     smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2X");
 4004     return ret;
 4005   }
 4006 
 4007   smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2X");
 4008   return ret;
 4009 }
 4010 

Cache object: 19f16795f138b1c8ef6a746a12571114


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.