14e1bc9a0SAchim Leubner /*******************************************************************************
24e1bc9a0SAchim Leubner *Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved.
34e1bc9a0SAchim Leubner *
44e1bc9a0SAchim Leubner *Redistribution and use in source and binary forms, with or without modification, are permitted provided
54e1bc9a0SAchim Leubner *that the following conditions are met:
64e1bc9a0SAchim Leubner *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
74e1bc9a0SAchim Leubner *following disclaimer.
84e1bc9a0SAchim Leubner *2. Redistributions in binary form must reproduce the above copyright notice,
94e1bc9a0SAchim Leubner *this list of conditions and the following disclaimer in the documentation and/or other materials provided
104e1bc9a0SAchim Leubner *with the distribution.
114e1bc9a0SAchim Leubner *
124e1bc9a0SAchim Leubner *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
134e1bc9a0SAchim Leubner *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
144e1bc9a0SAchim Leubner *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
154e1bc9a0SAchim Leubner *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
164e1bc9a0SAchim Leubner *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
174e1bc9a0SAchim Leubner *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
184e1bc9a0SAchim Leubner *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
194e1bc9a0SAchim Leubner *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
204e1bc9a0SAchim Leubner 
214e1bc9a0SAchim Leubner ********************************************************************************/
224e1bc9a0SAchim Leubner /*******************************************************************************/
234e1bc9a0SAchim Leubner /*! \file saioctlcmd.c
244e1bc9a0SAchim Leubner  *  \brief The file implements the functions of IOCTL MPI Command/Response to/from SPC
254e1bc9a0SAchim Leubner  *
264e1bc9a0SAchim Leubner  */
274e1bc9a0SAchim Leubner /******************************************************************************/
284e1bc9a0SAchim Leubner #include <sys/cdefs.h>
294e1bc9a0SAchim Leubner #include <dev/pms/config.h>
304e1bc9a0SAchim Leubner 
314e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/sallsdk/spc/saglobal.h>
324e1bc9a0SAchim Leubner #ifdef SA_ENABLE_TRACE_FUNCTIONS
334e1bc9a0SAchim Leubner #ifdef siTraceFileID
344e1bc9a0SAchim Leubner #undef siTraceFileID
354e1bc9a0SAchim Leubner #endif
364e1bc9a0SAchim Leubner #define siTraceFileID 'H'
374e1bc9a0SAchim Leubner #endif
384e1bc9a0SAchim Leubner 
394e1bc9a0SAchim Leubner extern bit32 gFPGA_TEST;
404e1bc9a0SAchim Leubner 
414e1bc9a0SAchim Leubner extern bit32 gWait_3;
424e1bc9a0SAchim Leubner extern bit32 gWait_2;
434e1bc9a0SAchim Leubner 
444e1bc9a0SAchim Leubner 
454e1bc9a0SAchim Leubner 
464e1bc9a0SAchim Leubner LOCAL bit32 siGSMDump(
474e1bc9a0SAchim Leubner                       agsaRoot_t     *agRoot,
484e1bc9a0SAchim Leubner                       bit32          gsmDumpOffset,
494e1bc9a0SAchim Leubner                       bit32          length,
504e1bc9a0SAchim Leubner                       void           *directData);
514e1bc9a0SAchim Leubner 
524e1bc9a0SAchim Leubner #ifdef SPC_ENABLE_PROFILE
534e1bc9a0SAchim Leubner /******************************************************************************/
544e1bc9a0SAchim Leubner /*! \brief SPC FW Profile Command
554e1bc9a0SAchim Leubner  *
564e1bc9a0SAchim Leubner  *  This command sends FW Flash Update Command to SPC.
574e1bc9a0SAchim Leubner  *
584e1bc9a0SAchim Leubner  *  \param agRoot          Handles for this instance of SAS/SATA LL
594e1bc9a0SAchim Leubner  *  \param agContext       Context of SPC FW Flash Update Command
604e1bc9a0SAchim Leubner  *  \param queueNum        Inbound/outbound queue number
614e1bc9a0SAchim Leubner  *  \param flashUpdateInfo Pointer of flash update information
624e1bc9a0SAchim Leubner  *
634e1bc9a0SAchim Leubner  *  \return If the MPI command is sent to SPC successfully
644e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
654e1bc9a0SAchim Leubner  *          - \e AGSA_RC_FAILURE the MPI command is failure
664e1bc9a0SAchim Leubner  *
674e1bc9a0SAchim Leubner  */
684e1bc9a0SAchim Leubner /*******************************************************************************/
saFwProfile(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,agsaFwProfile_t * fwProfileInfo)694e1bc9a0SAchim Leubner GLOBAL bit32 saFwProfile(
704e1bc9a0SAchim Leubner   agsaRoot_t                *agRoot,
714e1bc9a0SAchim Leubner   agsaContext_t             *agContext,
724e1bc9a0SAchim Leubner   bit32                     queueNum,
734e1bc9a0SAchim Leubner   agsaFwProfile_t         *fwProfileInfo
744e1bc9a0SAchim Leubner   )
754e1bc9a0SAchim Leubner {
764e1bc9a0SAchim Leubner   bit32 ret           = AGSA_RC_SUCCESS, retVal;
774e1bc9a0SAchim Leubner   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
784e1bc9a0SAchim Leubner   agsaIORequestDesc_t *pRequest;
794e1bc9a0SAchim Leubner   mpiICQueue_t        *circularQ;
804e1bc9a0SAchim Leubner   void                *pMessage;
814e1bc9a0SAchim Leubner   agsaFwProfileIOMB_t *pPayload;
824e1bc9a0SAchim Leubner   bit8                inq, outq;
834e1bc9a0SAchim Leubner   bit32               i, tcid_processor_cmd = 0;
844e1bc9a0SAchim Leubner 
854e1bc9a0SAchim Leubner 
864e1bc9a0SAchim Leubner   /* sanity check */
874e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
884e1bc9a0SAchim Leubner 
894e1bc9a0SAchim Leubner   /* Get request from free IORequests */
904e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
914e1bc9a0SAchim Leubner   pRequest = (agsaIORequestDesc_t *)saLlistGetHead(&(saRoot->freeIORequests));
924e1bc9a0SAchim Leubner 
934e1bc9a0SAchim Leubner   /* If no LL Control request entry avaliable */
944e1bc9a0SAchim Leubner   if ( agNULL == pRequest )
954e1bc9a0SAchim Leubner   {
964e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
974e1bc9a0SAchim Leubner     SA_DBG1(("saFwProfile, No request from free list\n" ));
984e1bc9a0SAchim Leubner      return AGSA_RC_BUSY;
994e1bc9a0SAchim Leubner   }
1004e1bc9a0SAchim Leubner   /* If LL Control request entry avaliable */
1014e1bc9a0SAchim Leubner   else
1024e1bc9a0SAchim Leubner   {
1034e1bc9a0SAchim Leubner     /* Assign inbound and outbound Ring Buffer */
1044e1bc9a0SAchim Leubner     inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
1054e1bc9a0SAchim Leubner     outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
1064e1bc9a0SAchim Leubner     SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
1074e1bc9a0SAchim Leubner 
1084e1bc9a0SAchim Leubner     /* Remove the request from free list */
1094e1bc9a0SAchim Leubner     saLlistRemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
1104e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
1114e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
1124e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].agContext = agContext;
1134e1bc9a0SAchim Leubner     pRequest->valid = agTRUE;
1144e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1154e1bc9a0SAchim Leubner 
1164e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
1174e1bc9a0SAchim Leubner     ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
1184e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
1194e1bc9a0SAchim Leubner     /* Get a free inbound queue entry */
1204e1bc9a0SAchim Leubner     circularQ = &saRoot->inboundQueue[inq];
1214e1bc9a0SAchim Leubner     retVal    = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage);
1224e1bc9a0SAchim Leubner 
1234e1bc9a0SAchim Leubner     /* if message size is too large return failure */
1244e1bc9a0SAchim Leubner     if (AGSA_RC_FAILURE == retVal)
1254e1bc9a0SAchim Leubner     {
1264e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
1274e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
1284e1bc9a0SAchim Leubner #endif  /* SA_LL_IBQ_PROTECT */
1294e1bc9a0SAchim Leubner       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1304e1bc9a0SAchim Leubner       /* remove the request from IOMap */
1314e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
1324e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
1334e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
1344e1bc9a0SAchim Leubner       pRequest->valid = agFALSE;
1354e1bc9a0SAchim Leubner       /* return the request to free pool */
1364e1bc9a0SAchim Leubner       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1374e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1384e1bc9a0SAchim Leubner 
1394e1bc9a0SAchim Leubner       SA_DBG1(("saFwProfile, error when get free IOMB\n"));
1404e1bc9a0SAchim Leubner       return AGSA_RC_FAILURE;
1414e1bc9a0SAchim Leubner     }
1424e1bc9a0SAchim Leubner 
1434e1bc9a0SAchim Leubner     /* return busy if inbound queue is full */
1444e1bc9a0SAchim Leubner     if (AGSA_RC_BUSY == retVal)
1454e1bc9a0SAchim Leubner     {
1464e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
1474e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
1484e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
1494e1bc9a0SAchim Leubner 
1504e1bc9a0SAchim Leubner       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1514e1bc9a0SAchim Leubner       /* remove the request from IOMap */
1524e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
1534e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
1544e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
1554e1bc9a0SAchim Leubner       pRequest->valid = agFALSE;
1564e1bc9a0SAchim Leubner       /* return the request to free pool */
1574e1bc9a0SAchim Leubner       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1584e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1594e1bc9a0SAchim Leubner       SA_DBG1(("saFwProfile, no more IOMB\n"));
1604e1bc9a0SAchim Leubner       return AGSA_RC_BUSY;
1614e1bc9a0SAchim Leubner     }
1624e1bc9a0SAchim Leubner 
1634e1bc9a0SAchim Leubner     pPayload = (agsaFwProfileIOMB_t *)pMessage;
1644e1bc9a0SAchim Leubner     tcid_processor_cmd = (((fwProfileInfo->tcid)<< 16) | ((fwProfileInfo->processor)<< 8) | fwProfileInfo->cmd);
1654e1bc9a0SAchim Leubner   /* Prepare the FW_FLASH_UPDATE IOMB payload */
1664e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwProfileIOMB_t, tag), pRequest->HTag);
1674e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwProfileIOMB_t, tcid_processor_cmd), tcid_processor_cmd);
1684e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwProfileIOMB_t, codeStartAdd), fwProfileInfo->codeStartAdd);
1694e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwProfileIOMB_t, codeEndAdd), fwProfileInfo->codeEndAdd);
1704e1bc9a0SAchim Leubner 
1714e1bc9a0SAchim Leubner     pPayload->SGLAL = fwProfileInfo->agSgl.sgLower;
1724e1bc9a0SAchim Leubner     pPayload->SGLAH = fwProfileInfo->agSgl.sgUpper;
1734e1bc9a0SAchim Leubner     pPayload->Len = fwProfileInfo->agSgl.len;
1744e1bc9a0SAchim Leubner     pPayload->extReserved = fwProfileInfo->agSgl.extReserved;
1754e1bc9a0SAchim Leubner 
1764e1bc9a0SAchim Leubner     /* fill up the reserved bytes with zero */
1774e1bc9a0SAchim Leubner     for (i = 0; i < FWPROFILE_IOMB_RESERVED_LEN; i ++)
1784e1bc9a0SAchim Leubner     {
1794e1bc9a0SAchim Leubner       pPayload->reserved0[i] = 0;
1804e1bc9a0SAchim Leubner     }
1814e1bc9a0SAchim Leubner 
1824e1bc9a0SAchim Leubner     /* post the IOMB to SPC */
1834e1bc9a0SAchim Leubner     ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_FW_PROFILE, outq, (bit8)circularQ->priority);
1844e1bc9a0SAchim Leubner 
1854e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
1864e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
1874e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
1884e1bc9a0SAchim Leubner 
1894e1bc9a0SAchim Leubner     if (AGSA_RC_FAILURE == ret)
1904e1bc9a0SAchim Leubner     {
1914e1bc9a0SAchim Leubner       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1924e1bc9a0SAchim Leubner       /* remove the request from IOMap */
1934e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
1944e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
1954e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
1964e1bc9a0SAchim Leubner       pRequest->valid = agFALSE;
1974e1bc9a0SAchim Leubner       /* return the request to free pool */
1984e1bc9a0SAchim Leubner       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1994e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2004e1bc9a0SAchim Leubner       SA_DBG1(("saFwProfile, error when post FW_PROFILE IOMB\n"));
2014e1bc9a0SAchim Leubner     }
2024e1bc9a0SAchim Leubner   }
2034e1bc9a0SAchim Leubner   return ret;
2044e1bc9a0SAchim Leubner }
2054e1bc9a0SAchim Leubner #endif
2064e1bc9a0SAchim Leubner /******************************************************************************/
2074e1bc9a0SAchim Leubner /*! \brief SPC FW Flash Update Command
2084e1bc9a0SAchim Leubner  *
2094e1bc9a0SAchim Leubner  *  This command sends FW Flash Update Command to SPC.
2104e1bc9a0SAchim Leubner  *
2114e1bc9a0SAchim Leubner  *  \param agRoot          Handles for this instance of SAS/SATA LL
2124e1bc9a0SAchim Leubner  *  \param agContext       Context of SPC FW Flash Update Command
2134e1bc9a0SAchim Leubner  *  \param queueNum        Inbound/outbound queue number
2144e1bc9a0SAchim Leubner  *  \param flashUpdateInfo Pointer of flash update information
2154e1bc9a0SAchim Leubner  *
2164e1bc9a0SAchim Leubner  *  \return If the MPI command is sent to SPC successfully
2174e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
2184e1bc9a0SAchim Leubner  *          - \e AGSA_RC_FAILURE the MPI command is failure
2194e1bc9a0SAchim Leubner  *
2204e1bc9a0SAchim Leubner  */
2214e1bc9a0SAchim Leubner /*******************************************************************************/
saFwFlashUpdate(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,agsaUpdateFwFlash_t * flashUpdateInfo)2224e1bc9a0SAchim Leubner GLOBAL bit32 saFwFlashUpdate(
2234e1bc9a0SAchim Leubner   agsaRoot_t                *agRoot,
2244e1bc9a0SAchim Leubner   agsaContext_t             *agContext,
2254e1bc9a0SAchim Leubner   bit32                     queueNum,
2264e1bc9a0SAchim Leubner   agsaUpdateFwFlash_t       *flashUpdateInfo
2274e1bc9a0SAchim Leubner   )
2284e1bc9a0SAchim Leubner {
2294e1bc9a0SAchim Leubner   bit32 ret = AGSA_RC_SUCCESS, retVal;
2304e1bc9a0SAchim Leubner   agsaLLRoot_t        *saRoot;
2314e1bc9a0SAchim Leubner   agsaIORequestDesc_t *pRequest;
2324e1bc9a0SAchim Leubner   mpiICQueue_t        *circularQ;
2334e1bc9a0SAchim Leubner   void                *pMessage;
2344e1bc9a0SAchim Leubner   agsaFwFlashUpdate_t *pPayload;
2354e1bc9a0SAchim Leubner   bit8                inq, outq;
2364e1bc9a0SAchim Leubner   bit32               i;
2374e1bc9a0SAchim Leubner 
2384e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
2394e1bc9a0SAchim Leubner   if (agRoot == agNULL)
2404e1bc9a0SAchim Leubner   {
2414e1bc9a0SAchim Leubner     SA_DBG1(("saFwFlashUpdate: agRoot == agNULL\n"));
2424e1bc9a0SAchim Leubner     return AGSA_RC_FAILURE;
2434e1bc9a0SAchim Leubner   }
2444e1bc9a0SAchim Leubner   saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
2454e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != saRoot), "");
2464e1bc9a0SAchim Leubner   if (saRoot == agNULL)
2474e1bc9a0SAchim Leubner   {
2484e1bc9a0SAchim Leubner     SA_DBG1(("saFwFlashUpdate: saRoot == agNULL\n"));
2494e1bc9a0SAchim Leubner     return AGSA_RC_FAILURE;
2504e1bc9a0SAchim Leubner   }
2514e1bc9a0SAchim Leubner 
2524e1bc9a0SAchim Leubner 
2534e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD, "6a");
2544e1bc9a0SAchim Leubner   /* sanity check */
2554e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
2564e1bc9a0SAchim Leubner   /* Get request from free IORequests */
2574e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2584e1bc9a0SAchim Leubner   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2594e1bc9a0SAchim Leubner   /* If no LL Control request entry available */
2604e1bc9a0SAchim Leubner   if ( agNULL == pRequest ) {
2614e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2624e1bc9a0SAchim Leubner     SA_DBG1(("saFwFlashUpdate, No request from free list\n" ));
2634e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6a");
2644e1bc9a0SAchim Leubner     return AGSA_RC_BUSY;
2654e1bc9a0SAchim Leubner   }
2664e1bc9a0SAchim Leubner   /* If LL Control request entry avaliable */
2674e1bc9a0SAchim Leubner   else
2684e1bc9a0SAchim Leubner   {
2694e1bc9a0SAchim Leubner     /* Assign inbound and outbound Ring Buffer */
2704e1bc9a0SAchim Leubner     inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
2714e1bc9a0SAchim Leubner     outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
2724e1bc9a0SAchim Leubner     SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
2734e1bc9a0SAchim Leubner     /* Remove the request from free list */
2744e1bc9a0SAchim Leubner     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
2754e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
2764e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
2774e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].agContext = agContext;
2784e1bc9a0SAchim Leubner     pRequest->valid = agTRUE;
2794e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2804e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
2814e1bc9a0SAchim Leubner     ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
2824e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
2834e1bc9a0SAchim Leubner     /* Get a free inbound queue entry */
2844e1bc9a0SAchim Leubner     circularQ = &saRoot->inboundQueue[inq];
2854e1bc9a0SAchim Leubner     retVal    = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage);
2864e1bc9a0SAchim Leubner     /* if message size is too large return failure */
2874e1bc9a0SAchim Leubner     if (AGSA_RC_FAILURE == retVal)
2884e1bc9a0SAchim Leubner     {
2894e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
2904e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
2914e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
2924e1bc9a0SAchim Leubner       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2934e1bc9a0SAchim Leubner       /* remove the request from IOMap */
2944e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
2954e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
2964e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
2974e1bc9a0SAchim Leubner       pRequest->valid = agFALSE;
2984e1bc9a0SAchim Leubner       /* return the request to free pool */
2994e1bc9a0SAchim Leubner       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
3004e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3014e1bc9a0SAchim Leubner       SA_DBG1(("saFwFlashUpdate, error when get free IOMB\n"));
3024e1bc9a0SAchim Leubner       smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6a");
3034e1bc9a0SAchim Leubner       return AGSA_RC_FAILURE;
3044e1bc9a0SAchim Leubner     }
3054e1bc9a0SAchim Leubner     /* return busy if inbound queue is full */
3064e1bc9a0SAchim Leubner     if (AGSA_RC_BUSY == retVal)
3074e1bc9a0SAchim Leubner     {
3084e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
3094e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
3104e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
3114e1bc9a0SAchim Leubner       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3124e1bc9a0SAchim Leubner       /* remove the request from IOMap */
3134e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
3144e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
3154e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
3164e1bc9a0SAchim Leubner       pRequest->valid = agFALSE;
3174e1bc9a0SAchim Leubner       /* return the request to free pool */
3184e1bc9a0SAchim Leubner       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
3194e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3204e1bc9a0SAchim Leubner       SA_DBG1(("saFwFlashUpdate, no more IOMB\n"));
3214e1bc9a0SAchim Leubner       smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "6a");
3224e1bc9a0SAchim Leubner       return AGSA_RC_BUSY;
3234e1bc9a0SAchim Leubner     }
3244e1bc9a0SAchim Leubner     pPayload = (agsaFwFlashUpdate_t *)pMessage;
3254e1bc9a0SAchim Leubner     /* Prepare the FW_FLASH_UPDATE IOMB payload */
3264e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32( agRoot, pPayload,
3274e1bc9a0SAchim Leubner                       OSSA_OFFSET_OF(agsaFwFlashUpdate_t, tag), pRequest->HTag);
3284e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32( agRoot, pPayload,
3294e1bc9a0SAchim Leubner                       OSSA_OFFSET_OF(agsaFwFlashUpdate_t, curImageOffset),
3304e1bc9a0SAchim Leubner                       flashUpdateInfo->currentImageOffset);
3314e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32( agRoot, pPayload,
3324e1bc9a0SAchim Leubner                       OSSA_OFFSET_OF(agsaFwFlashUpdate_t, curImageLen),
3334e1bc9a0SAchim Leubner                       flashUpdateInfo->currentImageLen);
3344e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32( agRoot, pPayload,
3354e1bc9a0SAchim Leubner                       OSSA_OFFSET_OF(agsaFwFlashUpdate_t, totalImageLen),
3364e1bc9a0SAchim Leubner                       flashUpdateInfo->totalImageLen);
3374e1bc9a0SAchim Leubner     pPayload->SGLAL = flashUpdateInfo->agSgl.sgLower;
3384e1bc9a0SAchim Leubner     pPayload->SGLAH = flashUpdateInfo->agSgl.sgUpper;
3394e1bc9a0SAchim Leubner     pPayload->Len   = flashUpdateInfo->agSgl.len;
3404e1bc9a0SAchim Leubner     pPayload->extReserved = flashUpdateInfo->agSgl.extReserved;
3414e1bc9a0SAchim Leubner     /* fill up the reserved bytes with zero */
3424e1bc9a0SAchim Leubner     for (i = 0; i < FWFLASH_IOMB_RESERVED_LEN; i ++) {
3434e1bc9a0SAchim Leubner       pPayload->reserved0[i] = 0;
3444e1bc9a0SAchim Leubner     }
3454e1bc9a0SAchim Leubner     /* post the IOMB to SPC */
3464e1bc9a0SAchim Leubner     ret = mpiMsgProduce( circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA,
3474e1bc9a0SAchim Leubner                          OPC_INB_FW_FLASH_UPDATE, outq, (bit8)circularQ->priority);
3484e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
3494e1bc9a0SAchim Leubner     ossaSingleThreadedLeave( agRoot, LL_IOREQ_IBQ0_LOCK + inq );
3504e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
3514e1bc9a0SAchim Leubner     if (AGSA_RC_FAILURE == ret) {
3524e1bc9a0SAchim Leubner       ossaSingleThreadedEnter( agRoot, LL_IOREQ_LOCKEQ_LOCK );
3534e1bc9a0SAchim Leubner       /* remove the request from IOMap */
3544e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
3554e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
3564e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
3574e1bc9a0SAchim Leubner       pRequest->valid = agFALSE;
3584e1bc9a0SAchim Leubner       /* return the request to free pool */
3594e1bc9a0SAchim Leubner       saLlistIOAdd( &(saRoot->freeIORequests), &(pRequest->linkNode) );
3604e1bc9a0SAchim Leubner       ossaSingleThreadedLeave( agRoot, LL_IOREQ_LOCKEQ_LOCK );
3614e1bc9a0SAchim Leubner       SA_DBG1( ("saFwFlashUpdate, error when post FW_FLASH_UPDATE IOMB\n") );
3624e1bc9a0SAchim Leubner     }
3634e1bc9a0SAchim Leubner   }
3644e1bc9a0SAchim Leubner   smTraceFuncExit( hpDBG_VERY_LOUD, 'd', "6a" );
3654e1bc9a0SAchim Leubner   return ret;
3664e1bc9a0SAchim Leubner }
3674e1bc9a0SAchim Leubner 
3684e1bc9a0SAchim Leubner 
saFlashExtExecute(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,agsaFlashExtExecute_t * agFlashExtExe)3694e1bc9a0SAchim Leubner GLOBAL bit32 saFlashExtExecute (
3704e1bc9a0SAchim Leubner                   agsaRoot_t            *agRoot,
3714e1bc9a0SAchim Leubner                   agsaContext_t         *agContext,
3724e1bc9a0SAchim Leubner                   bit32                 queueNum,
3734e1bc9a0SAchim Leubner                   agsaFlashExtExecute_t *agFlashExtExe)
3744e1bc9a0SAchim Leubner {
3754e1bc9a0SAchim Leubner 
3764e1bc9a0SAchim Leubner   bit32 ret           = AGSA_RC_SUCCESS, retVal;
3774e1bc9a0SAchim Leubner   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
3784e1bc9a0SAchim Leubner   agsaIORequestDesc_t *pRequest;
3794e1bc9a0SAchim Leubner   mpiICQueue_t        *circularQ;
3804e1bc9a0SAchim Leubner   void                *pMessage;
3814e1bc9a0SAchim Leubner   agsaFwFlashOpExt_t *pPayload;
3824e1bc9a0SAchim Leubner   bit8                inq, outq;
3834e1bc9a0SAchim Leubner 
3844e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"2R");
3854e1bc9a0SAchim Leubner 
3864e1bc9a0SAchim Leubner   /* sanity check */
3874e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
3884e1bc9a0SAchim Leubner 
3894e1bc9a0SAchim Leubner   /* Get request from free IORequests */
3904e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3914e1bc9a0SAchim Leubner   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
3924e1bc9a0SAchim Leubner 
3934e1bc9a0SAchim Leubner   /* If no LL Control request entry available */
3944e1bc9a0SAchim Leubner   if ( agNULL == pRequest )
3954e1bc9a0SAchim Leubner   {
3964e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3974e1bc9a0SAchim Leubner     SA_DBG1(("saFlashExtExecute, No request from free list\n" ));
3984e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2R");
3994e1bc9a0SAchim Leubner     return AGSA_RC_BUSY;
4004e1bc9a0SAchim Leubner   }
4014e1bc9a0SAchim Leubner   /* If LL Control request entry avaliable */
4024e1bc9a0SAchim Leubner   else
4034e1bc9a0SAchim Leubner   {
4044e1bc9a0SAchim Leubner     /* Assign inbound and outbound Ring Buffer */
4054e1bc9a0SAchim Leubner     inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
4064e1bc9a0SAchim Leubner     outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
4074e1bc9a0SAchim Leubner     SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
4084e1bc9a0SAchim Leubner 
4094e1bc9a0SAchim Leubner     /* Remove the request from free list */
4104e1bc9a0SAchim Leubner     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
4114e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
4124e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
4134e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].agContext = agContext;
4144e1bc9a0SAchim Leubner     pRequest->valid = agTRUE;
4154e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
4164e1bc9a0SAchim Leubner 
4174e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
4184e1bc9a0SAchim Leubner     ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
4194e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
4204e1bc9a0SAchim Leubner     /* Get a free inbound queue entry */
4214e1bc9a0SAchim Leubner     circularQ = &saRoot->inboundQueue[inq];
4224e1bc9a0SAchim Leubner     retVal    = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage);
4234e1bc9a0SAchim Leubner 
4244e1bc9a0SAchim Leubner     /* if message size is too large return failure */
4254e1bc9a0SAchim Leubner     if (AGSA_RC_FAILURE == retVal)
4264e1bc9a0SAchim Leubner     {
4274e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
4284e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
4294e1bc9a0SAchim Leubner #endif   /* SA_LL_IBQ_PROTECT */
4304e1bc9a0SAchim Leubner       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
4314e1bc9a0SAchim Leubner       /* remove the request from IOMap */
4324e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
4334e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
4344e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
4354e1bc9a0SAchim Leubner       pRequest->valid = agFALSE;
4364e1bc9a0SAchim Leubner       /* return the request to free pool */
4374e1bc9a0SAchim Leubner       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
4384e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
4394e1bc9a0SAchim Leubner 
4404e1bc9a0SAchim Leubner       SA_DBG1(("saFlashExtExecute, error when get free IOMB\n"));
4414e1bc9a0SAchim Leubner       smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2R");
4424e1bc9a0SAchim Leubner       return AGSA_RC_FAILURE;
4434e1bc9a0SAchim Leubner     }
4444e1bc9a0SAchim Leubner 
4454e1bc9a0SAchim Leubner     /* return busy if inbound queue is full */
4464e1bc9a0SAchim Leubner     if (AGSA_RC_BUSY == retVal)
4474e1bc9a0SAchim Leubner     {
4484e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
4494e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
4504e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
4514e1bc9a0SAchim Leubner       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
4524e1bc9a0SAchim Leubner       /* remove the request from IOMap */
4534e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
4544e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
4554e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
4564e1bc9a0SAchim Leubner 
4574e1bc9a0SAchim Leubner       pRequest->valid = agFALSE;
4584e1bc9a0SAchim Leubner       /* return the request to free pool */
4594e1bc9a0SAchim Leubner       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
4604e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
4614e1bc9a0SAchim Leubner 
4624e1bc9a0SAchim Leubner       SA_DBG3(("saFlashExtExecute, no more IOMB\n"));
4634e1bc9a0SAchim Leubner       smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2R");
4644e1bc9a0SAchim Leubner       return AGSA_RC_BUSY;
4654e1bc9a0SAchim Leubner     }
4664e1bc9a0SAchim Leubner 
4674e1bc9a0SAchim Leubner     pPayload = (agsaFwFlashOpExt_t *)pMessage;
4684e1bc9a0SAchim Leubner 
4694e1bc9a0SAchim Leubner     si_memset(pPayload, 0, sizeof(agsaFwFlashOpExt_t));
4704e1bc9a0SAchim Leubner 
4714e1bc9a0SAchim Leubner 
4724e1bc9a0SAchim Leubner     /* Prepare the FW_FLASH_UPDATE IOMB payload */
4734e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t, tag), pRequest->HTag);
4744e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t,Command ), agFlashExtExe->command);
4754e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t,PartOffset ), agFlashExtExe->partOffset);
4764e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t,DataLength ), agFlashExtExe->dataLen);
4774e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t,SGLAL ), agFlashExtExe->agSgl->sgLower);
4784e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t,SGLAH ), agFlashExtExe->agSgl->sgUpper);
4794e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t,Len ), agFlashExtExe->agSgl->len);
4804e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t,E_sgl ), agFlashExtExe->agSgl->extReserved);
4814e1bc9a0SAchim Leubner 
4824e1bc9a0SAchim Leubner     /* post the IOMB to SPC */
4834e1bc9a0SAchim Leubner     ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_FLASH_OP_EXT, outq, (bit8)circularQ->priority);
4844e1bc9a0SAchim Leubner 
4854e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
4864e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
4874e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
4884e1bc9a0SAchim Leubner 
4894e1bc9a0SAchim Leubner 
4904e1bc9a0SAchim Leubner     if (AGSA_RC_FAILURE == ret)
4914e1bc9a0SAchim Leubner     {
4924e1bc9a0SAchim Leubner       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
4934e1bc9a0SAchim Leubner       /* remove the request from IOMap */
4944e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
4954e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
4964e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
4974e1bc9a0SAchim Leubner       pRequest->valid = agFALSE;
4984e1bc9a0SAchim Leubner       /* return the request to free pool */
4994e1bc9a0SAchim Leubner       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
5004e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
5014e1bc9a0SAchim Leubner       SA_DBG1(("saFlashExtExecute, error when post FW_FLASH_UPDATE IOMB\n"));
5024e1bc9a0SAchim Leubner     }
5034e1bc9a0SAchim Leubner   }
5044e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "2R");
5054e1bc9a0SAchim Leubner 
5064e1bc9a0SAchim Leubner   return ret;
5074e1bc9a0SAchim Leubner 
5084e1bc9a0SAchim Leubner }
5094e1bc9a0SAchim Leubner 
5104e1bc9a0SAchim Leubner 
5114e1bc9a0SAchim Leubner #ifdef SPC_ENABLE_PROFILE
5124e1bc9a0SAchim Leubner /******************************************************************************/
5134e1bc9a0SAchim Leubner /*! \brief SPC FW_PROFILE Respond
5144e1bc9a0SAchim Leubner  *
5154e1bc9a0SAchim Leubner  *  This command sends FW Profile Status to TD layer.
5164e1bc9a0SAchim Leubner  *
5174e1bc9a0SAchim Leubner  *  \param agRoot       Handles for this instance of SAS/SATA LL
5184e1bc9a0SAchim Leubner  *  \param payload      FW download response payload
5194e1bc9a0SAchim Leubner  *
5204e1bc9a0SAchim Leubner  *  \return If the MPI command is sent to SPC successfully
5214e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
5224e1bc9a0SAchim Leubner  *          - \e AGSA_RC_FAILURE the MPI command is failure
5234e1bc9a0SAchim Leubner  *
5244e1bc9a0SAchim Leubner  */
5254e1bc9a0SAchim Leubner /*******************************************************************************/
mpiFwProfileRsp(agsaRoot_t * agRoot,agsaFwProfileRsp_t * payload)5264e1bc9a0SAchim Leubner GLOBAL bit32 mpiFwProfileRsp(
5274e1bc9a0SAchim Leubner   agsaRoot_t             *agRoot,
5284e1bc9a0SAchim Leubner   agsaFwProfileRsp_t *payload
5294e1bc9a0SAchim Leubner   )
5304e1bc9a0SAchim Leubner {
5314e1bc9a0SAchim Leubner   bit32               ret = AGSA_RC_SUCCESS;
5324e1bc9a0SAchim Leubner   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
5334e1bc9a0SAchim Leubner   agsaIORequestDesc_t *pRequest;
5344e1bc9a0SAchim Leubner   agsaContext_t       *agContext;
5354e1bc9a0SAchim Leubner 
5364e1bc9a0SAchim Leubner   bit32     status, tag, len;
5374e1bc9a0SAchim Leubner 
5384e1bc9a0SAchim Leubner   /* get request from IOMap */
5394e1bc9a0SAchim Leubner   OSSA_READ_LE_32(AGROOT, &tag, payload, OSSA_OFFSET_OF(agsaFwProfileRsp_t, tag));
5404e1bc9a0SAchim Leubner   OSSA_READ_LE_32(AGROOT, &status, payload, OSSA_OFFSET_OF(agsaFwProfileRsp_t, status));
5414e1bc9a0SAchim Leubner   OSSA_READ_LE_32(AGROOT, &len, payload, OSSA_OFFSET_OF(agsaFwProfileRsp_t, len));
5424e1bc9a0SAchim Leubner   pRequest = saRoot->IOMap[tag].IORequest;
5434e1bc9a0SAchim Leubner   if (agNULL == pRequest)
5444e1bc9a0SAchim Leubner   {
5454e1bc9a0SAchim Leubner     /* remove the request from IOMap */
5464e1bc9a0SAchim Leubner     saRoot->IOMap[tag].Tag = MARK_OFF;
5474e1bc9a0SAchim Leubner     saRoot->IOMap[tag].IORequest = agNULL;
5484e1bc9a0SAchim Leubner     SA_DBG1(("mpiFwProfileRsp: the request is NULL. Tag=%x\n", tag));
5494e1bc9a0SAchim Leubner     return AGSA_RC_FAILURE;
5504e1bc9a0SAchim Leubner   }
5514e1bc9a0SAchim Leubner   agContext = saRoot->IOMap[tag].agContext;
5524e1bc9a0SAchim Leubner   /* remove the request from IOMap */
5534e1bc9a0SAchim Leubner   saRoot->IOMap[tag].Tag = MARK_OFF;
5544e1bc9a0SAchim Leubner   saRoot->IOMap[tag].IORequest = agNULL;
5554e1bc9a0SAchim Leubner   saRoot->IOMap[tag].agContext = agNULL;
5564e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
5574e1bc9a0SAchim Leubner 
5584e1bc9a0SAchim Leubner 
5594e1bc9a0SAchim Leubner   if(!pRequest->valid)
5604e1bc9a0SAchim Leubner   {
5614e1bc9a0SAchim Leubner     SA_DBG1(("mpiPortControlRsp: pRequest->valid %d not set\n", pRequest->valid));
5624e1bc9a0SAchim Leubner   }
5634e1bc9a0SAchim Leubner 
5644e1bc9a0SAchim Leubner   SA_ASSERT((pRequest->valid), "pRequest->valid");
5654e1bc9a0SAchim Leubner 
5664e1bc9a0SAchim Leubner   pRequest->valid = agFALSE;
5674e1bc9a0SAchim Leubner   /* return the request to free pool */
5684e1bc9a0SAchim Leubner   saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
5694e1bc9a0SAchim Leubner   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
5704e1bc9a0SAchim Leubner 
5714e1bc9a0SAchim Leubner   ossaFwProfileCB(agRoot, agContext, status, len);
5724e1bc9a0SAchim Leubner 
5734e1bc9a0SAchim Leubner  return ret;
5744e1bc9a0SAchim Leubner }
5754e1bc9a0SAchim Leubner #endif
5764e1bc9a0SAchim Leubner /******************************************************************************/
5774e1bc9a0SAchim Leubner /*! \brief SPC FW_FLASH_UPDATE Respond
5784e1bc9a0SAchim Leubner  *
5794e1bc9a0SAchim Leubner  *  This command sends FW Flash Update Status to TD layer.
5804e1bc9a0SAchim Leubner  *
5814e1bc9a0SAchim Leubner  *  \param agRoot       Handles for this instance of SAS/SATA LL
5824e1bc9a0SAchim Leubner  *  \param payload      FW download response payload
5834e1bc9a0SAchim Leubner  *
5844e1bc9a0SAchim Leubner  *  \return If the MPI command is sent to SPC successfully
5854e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
5864e1bc9a0SAchim Leubner  *          - \e AGSA_RC_FAILURE the MPI command is failure
5874e1bc9a0SAchim Leubner  *
5884e1bc9a0SAchim Leubner  */
5894e1bc9a0SAchim Leubner /*******************************************************************************/
mpiFwFlashUpdateRsp(agsaRoot_t * agRoot,agsaFwFlashUpdateRsp_t * payload)5904e1bc9a0SAchim Leubner GLOBAL bit32 mpiFwFlashUpdateRsp(
5914e1bc9a0SAchim Leubner   agsaRoot_t             *agRoot,
5924e1bc9a0SAchim Leubner   agsaFwFlashUpdateRsp_t *payload
5934e1bc9a0SAchim Leubner   )
5944e1bc9a0SAchim Leubner {
5954e1bc9a0SAchim Leubner   bit32               ret = AGSA_RC_SUCCESS;
5964e1bc9a0SAchim Leubner   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
5974e1bc9a0SAchim Leubner   agsaIORequestDesc_t *pRequest;
5984e1bc9a0SAchim Leubner   agsaContext_t       *agContext;
5994e1bc9a0SAchim Leubner 
6004e1bc9a0SAchim Leubner   bit32     status, tag;
6014e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"6b");
6024e1bc9a0SAchim Leubner 
6034e1bc9a0SAchim Leubner   /* get request from IOMap */
6044e1bc9a0SAchim Leubner   OSSA_READ_LE_32(AGROOT, &tag, payload, OSSA_OFFSET_OF(agsaFwFlashUpdateRsp_t, tag));
6054e1bc9a0SAchim Leubner   OSSA_READ_LE_32(AGROOT, &status, payload, OSSA_OFFSET_OF(agsaFwFlashUpdateRsp_t, status));
6064e1bc9a0SAchim Leubner   pRequest = saRoot->IOMap[tag].IORequest;
6074e1bc9a0SAchim Leubner   agContext = saRoot->IOMap[tag].agContext;
6084e1bc9a0SAchim Leubner   /* remove the request from IOMap */
6094e1bc9a0SAchim Leubner   saRoot->IOMap[tag].Tag = MARK_OFF;
6104e1bc9a0SAchim Leubner   saRoot->IOMap[tag].IORequest = agNULL;
6114e1bc9a0SAchim Leubner   saRoot->IOMap[tag].agContext = agNULL;
6124e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
6134e1bc9a0SAchim Leubner   SA_ASSERT((pRequest->valid), "pRequest->valid");
6144e1bc9a0SAchim Leubner   pRequest->valid = agFALSE;
6154e1bc9a0SAchim Leubner   /* return the request to free pool */
6164e1bc9a0SAchim Leubner   if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
6174e1bc9a0SAchim Leubner   {
6184e1bc9a0SAchim Leubner     SA_DBG1(("mpiFwFlashUpdateRsp: saving pRequest (%p) for later use\n", pRequest));
6194e1bc9a0SAchim Leubner     saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
6204e1bc9a0SAchim Leubner   }
6214e1bc9a0SAchim Leubner   else
6224e1bc9a0SAchim Leubner   {
6234e1bc9a0SAchim Leubner     /* return the request to free pool */
6244e1bc9a0SAchim Leubner     saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
6254e1bc9a0SAchim Leubner   }
6264e1bc9a0SAchim Leubner   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
6274e1bc9a0SAchim Leubner 
6284e1bc9a0SAchim Leubner   if(status > 1)
6294e1bc9a0SAchim Leubner   {
6304e1bc9a0SAchim Leubner     SA_DBG1(("mpiFwFlashUpdateRsp: status = 0x%x\n",status));
6314e1bc9a0SAchim Leubner   }
6324e1bc9a0SAchim Leubner 
6334e1bc9a0SAchim Leubner   ossaFwFlashUpdateCB(agRoot, agContext, status);
6344e1bc9a0SAchim Leubner 
6354e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6b");
6364e1bc9a0SAchim Leubner 
6374e1bc9a0SAchim Leubner   return ret;
6384e1bc9a0SAchim Leubner }
6394e1bc9a0SAchim Leubner 
mpiFwExtFlashUpdateRsp(agsaRoot_t * agRoot,agsaFwFlashOpExtRsp_t * payload)6404e1bc9a0SAchim Leubner GLOBAL bit32 mpiFwExtFlashUpdateRsp(
6414e1bc9a0SAchim Leubner   agsaRoot_t             *agRoot,
6424e1bc9a0SAchim Leubner   agsaFwFlashOpExtRsp_t *payload
6434e1bc9a0SAchim Leubner   )
6444e1bc9a0SAchim Leubner {
6454e1bc9a0SAchim Leubner   bit32               ret = AGSA_RC_SUCCESS;
6464e1bc9a0SAchim Leubner   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
6474e1bc9a0SAchim Leubner   agsaIORequestDesc_t *pRequest;
6484e1bc9a0SAchim Leubner   agsaContext_t       *agContext;
6494e1bc9a0SAchim Leubner 
6504e1bc9a0SAchim Leubner   agsaFlashExtResponse_t FlashExtRsp;
6514e1bc9a0SAchim Leubner 
6524e1bc9a0SAchim Leubner   bit32     Command,Status, tag;
6534e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"2T");
6544e1bc9a0SAchim Leubner 
6554e1bc9a0SAchim Leubner   /* get request from IOMap */
6564e1bc9a0SAchim Leubner   OSSA_READ_LE_32(AGROOT, &tag, payload, OSSA_OFFSET_OF(agsaFwFlashOpExtRsp_t, tag));
6574e1bc9a0SAchim Leubner   OSSA_READ_LE_32(AGROOT, &Command, payload, OSSA_OFFSET_OF(agsaFwFlashOpExtRsp_t,Command ));
6584e1bc9a0SAchim Leubner   OSSA_READ_LE_32(AGROOT, &Status, payload, OSSA_OFFSET_OF(agsaFwFlashOpExtRsp_t,Status ));
6594e1bc9a0SAchim Leubner   OSSA_READ_LE_32(AGROOT, &FlashExtRsp.epart_sect_size, payload, OSSA_OFFSET_OF(agsaFwFlashOpExtRsp_t,Epart_Size ));
6604e1bc9a0SAchim Leubner   OSSA_READ_LE_32(AGROOT, &FlashExtRsp.epart_size, payload, OSSA_OFFSET_OF(agsaFwFlashOpExtRsp_t,EpartSectSize ));
6614e1bc9a0SAchim Leubner 
6624e1bc9a0SAchim Leubner   pRequest = saRoot->IOMap[tag].IORequest;
6634e1bc9a0SAchim Leubner   agContext = saRoot->IOMap[tag].agContext;
6644e1bc9a0SAchim Leubner   /* remove the request from IOMap */
6654e1bc9a0SAchim Leubner   saRoot->IOMap[tag].Tag = MARK_OFF;
6664e1bc9a0SAchim Leubner   saRoot->IOMap[tag].IORequest = agNULL;
6674e1bc9a0SAchim Leubner   saRoot->IOMap[tag].agContext = agNULL;
6684e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
6694e1bc9a0SAchim Leubner   SA_ASSERT((pRequest->valid), "pRequest->valid");
6704e1bc9a0SAchim Leubner   pRequest->valid = agFALSE;
6714e1bc9a0SAchim Leubner   /* return the request to free pool */
6724e1bc9a0SAchim Leubner   if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
6734e1bc9a0SAchim Leubner   {
6744e1bc9a0SAchim Leubner     SA_DBG1(("mpiFwExtFlashUpdateRsp: saving pRequest (%p) for later use\n", pRequest));
6754e1bc9a0SAchim Leubner     saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
6764e1bc9a0SAchim Leubner   }
6774e1bc9a0SAchim Leubner   else
6784e1bc9a0SAchim Leubner   {
6794e1bc9a0SAchim Leubner     /* return the request to free pool */
6804e1bc9a0SAchim Leubner     saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
6814e1bc9a0SAchim Leubner   }
6824e1bc9a0SAchim Leubner   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
6834e1bc9a0SAchim Leubner 
6844e1bc9a0SAchim Leubner   if(Status > 1)
6854e1bc9a0SAchim Leubner   {
6864e1bc9a0SAchim Leubner     SA_DBG1(("mpiFwExtFlashUpdateRsp: status = 0x%x\n",Status));
6874e1bc9a0SAchim Leubner   }
6884e1bc9a0SAchim Leubner 
6894e1bc9a0SAchim Leubner   ossaFlashExtExecuteCB(agRoot, agContext, Status,Command,&FlashExtRsp);
6904e1bc9a0SAchim Leubner 
6914e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2T");
6924e1bc9a0SAchim Leubner 
6934e1bc9a0SAchim Leubner   return ret;
6944e1bc9a0SAchim Leubner 
6954e1bc9a0SAchim Leubner }
6964e1bc9a0SAchim Leubner 
6974e1bc9a0SAchim Leubner 
6984e1bc9a0SAchim Leubner /******************************************************************************/
6994e1bc9a0SAchim Leubner /*! \brief SPC Get Controller Information Command
7004e1bc9a0SAchim Leubner  *
7014e1bc9a0SAchim Leubner  *  This command sends Get Controller Information Command to SPC.
7024e1bc9a0SAchim Leubner  *
7034e1bc9a0SAchim Leubner  *  \param agRoot         Handles for this instance of SAS/SATA LL
7044e1bc9a0SAchim Leubner  *  \param controllerInfo Controller Information
7054e1bc9a0SAchim Leubner  *
7064e1bc9a0SAchim Leubner  *  \return If the MPI command is sent to SPC successfully
7074e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
7084e1bc9a0SAchim Leubner  *          - \e AGSA_RC_FAILURE the MPI command is failure
7094e1bc9a0SAchim Leubner  *
7104e1bc9a0SAchim Leubner  */
7114e1bc9a0SAchim Leubner /*******************************************************************************/
7124e1bc9a0SAchim Leubner 
saGetControllerInfo(agsaRoot_t * agRoot,agsaControllerInfo_t * controllerInfo)7134e1bc9a0SAchim Leubner GLOBAL bit32 saGetControllerInfo(
7144e1bc9a0SAchim Leubner                         agsaRoot_t                *agRoot,
7154e1bc9a0SAchim Leubner                         agsaControllerInfo_t      *controllerInfo
7164e1bc9a0SAchim Leubner                         )
7174e1bc9a0SAchim Leubner {
7184e1bc9a0SAchim Leubner 
7194e1bc9a0SAchim Leubner   bit32     ret = AGSA_RC_SUCCESS;
7204e1bc9a0SAchim Leubner   bit32     max_wait_time;
7214e1bc9a0SAchim Leubner   bit32     max_wait_count;
7224e1bc9a0SAchim Leubner   bit32     ContrlCapFlag, MSGUCfgTblBase, CfgTblDWIdx;
7234e1bc9a0SAchim Leubner   bit32     value = 0, value1 = 0;
7244e1bc9a0SAchim Leubner   bit8      pcibar;
7254e1bc9a0SAchim Leubner 
7264e1bc9a0SAchim Leubner   if (agNULL != agRoot->sdkData)
7274e1bc9a0SAchim Leubner   {
7284e1bc9a0SAchim Leubner     smTraceFuncEnter(hpDBG_VERY_LOUD,"6e");
7294e1bc9a0SAchim Leubner   }
7304e1bc9a0SAchim Leubner   /* clean the structure */
7314e1bc9a0SAchim Leubner   si_memset(controllerInfo, 0, sizeof(agsaControllerInfo_t));
7324e1bc9a0SAchim Leubner 
7334e1bc9a0SAchim Leubner   if(smIS_SPC6V(agRoot))
7344e1bc9a0SAchim Leubner   {
7354e1bc9a0SAchim Leubner     controllerInfo->sdkInterfaceRev = STSDK_LL_INTERFACE_VERSION;
7364e1bc9a0SAchim Leubner     controllerInfo->sdkRevision     = STSDK_LL_VERSION;
7374e1bc9a0SAchim Leubner     controllerInfo->hwRevision = (ossaHwRegReadConfig32(agRoot,8) & 0xFF);
7384e1bc9a0SAchim Leubner   }else  if(smIS_SPC12V(agRoot))
7394e1bc9a0SAchim Leubner   {
7404e1bc9a0SAchim Leubner     controllerInfo->sdkInterfaceRev = STSDK_LL_12G_INTERFACE_VERSION;
7414e1bc9a0SAchim Leubner     controllerInfo->sdkRevision     = STSDK_LL_12G_VERSION;
7424e1bc9a0SAchim Leubner     controllerInfo->hwRevision = (ossaHwRegReadConfig32(agRoot,8) & 0xFF);
7434e1bc9a0SAchim Leubner   } else if(smIS_SPC(agRoot))
7444e1bc9a0SAchim Leubner   {
7454e1bc9a0SAchim Leubner     controllerInfo->hwRevision = SPC_READ_DEV_REV;
7464e1bc9a0SAchim Leubner     controllerInfo->sdkInterfaceRev = MATCHING_SPC_FW_VERSION;
7474e1bc9a0SAchim Leubner     controllerInfo->sdkRevision     = STSDK_LL_SPC_VERSION;
7484e1bc9a0SAchim Leubner   }
7494e1bc9a0SAchim Leubner   else
7504e1bc9a0SAchim Leubner   {
7514e1bc9a0SAchim Leubner     controllerInfo->hwRevision = (ossaHwRegReadConfig32(agRoot,8) & 0xFF);
7524e1bc9a0SAchim Leubner   }
7534e1bc9a0SAchim Leubner 
7544e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerInfo: SCRATCH_PAD0 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0)));
7554e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerInfo: SCRATCH_PAD1 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1)));
7564e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerInfo: SCRATCH_PAD2 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_2,  MSGU_SCRATCH_PAD_2)));
7574e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerInfo: SCRATCH_PAD3 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_3,  MSGU_SCRATCH_PAD_3)));
7584e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerInfo: SCRATCH_PAD3 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_3,  MSGU_SCRATCH_PAD_3)));
7594e1bc9a0SAchim Leubner 
7604e1bc9a0SAchim Leubner   if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0) == 0xFFFFFFFF)
7614e1bc9a0SAchim Leubner   {
7624e1bc9a0SAchim Leubner     SA_DBG1(("saGetControllerInfo:AGSA_RC_FAILURE SCRATCH_PAD0 value = 0x%x\n",
7634e1bc9a0SAchim Leubner             siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0) ) );
7644e1bc9a0SAchim Leubner     return AGSA_RC_FAILURE;
7654e1bc9a0SAchim Leubner   }
7664e1bc9a0SAchim Leubner 
7674e1bc9a0SAchim Leubner   if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0) == 0xFFFFFFFF)
7684e1bc9a0SAchim Leubner   {
7694e1bc9a0SAchim Leubner     SA_DBG1(("saGetControllerInfo:AGSA_RC_FAILURE SCRATCH_PAD0 value = 0x%x\n",
7704e1bc9a0SAchim Leubner             siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0) ) );
7714e1bc9a0SAchim Leubner     return AGSA_RC_FAILURE;
7724e1bc9a0SAchim Leubner   }
7734e1bc9a0SAchim Leubner 
7744e1bc9a0SAchim Leubner   if( SCRATCH_PAD1_V_ERROR_STATE(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1)) )
7754e1bc9a0SAchim Leubner   {
7764e1bc9a0SAchim Leubner     SA_DBG1(("saGetControllerInfo: SCRATCH_PAD1 (0x%x) in error state ila %d raae %d Iop0 %d Iop1 %d\n",
7774e1bc9a0SAchim Leubner       siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1),
7784e1bc9a0SAchim Leubner     ( SCRATCH_PAD1_V_ILA_ERROR_STATE(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1)) ? 1 : 0),
7794e1bc9a0SAchim Leubner     ( SCRATCH_PAD1_V_RAAE_ERROR_STATE(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,MSGU_SCRATCH_PAD_1)) ? 1 : 0),
7804e1bc9a0SAchim Leubner     ( SCRATCH_PAD1_V_IOP0_ERROR_STATE(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,MSGU_SCRATCH_PAD_1)) ? 1 : 0),
7814e1bc9a0SAchim Leubner     ( SCRATCH_PAD1_V_IOP1_ERROR_STATE(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,MSGU_SCRATCH_PAD_1)) ? 1 : 0) ));
7824e1bc9a0SAchim Leubner 
7834e1bc9a0SAchim Leubner   }
7844e1bc9a0SAchim Leubner 
7854e1bc9a0SAchim Leubner   if(smIS_SPC(agRoot))
7864e1bc9a0SAchim Leubner   {
7874e1bc9a0SAchim Leubner     /* check HDA mode */
7884e1bc9a0SAchim Leubner     value = ossaHwRegReadExt(agRoot, PCIBAR3, HDA_RSP_OFFSET1MB+HDA_CMD_CODE_OFFSET) & HDA_STATUS_BITS;
7894e1bc9a0SAchim Leubner 
7904e1bc9a0SAchim Leubner     if (value == BOOTTLOADERHDA_IDLE)
7914e1bc9a0SAchim Leubner     {
7924e1bc9a0SAchim Leubner       /* HDA mode */
7934e1bc9a0SAchim Leubner       SA_DBG1(("saGetControllerInfo: HDA mode, value = 0x%x\n", value));
7944e1bc9a0SAchim Leubner       return AGSA_RC_HDA_NO_FW_RUNNING;
7954e1bc9a0SAchim Leubner     }
7964e1bc9a0SAchim Leubner   }
7974e1bc9a0SAchim Leubner   else
7984e1bc9a0SAchim Leubner   {
7994e1bc9a0SAchim Leubner     if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1) &   SCRATCH_PAD1_V_RESERVED )
8004e1bc9a0SAchim Leubner     {
8014e1bc9a0SAchim Leubner       SA_DBG1(("saGetControllerInfo: Warning SCRATCH_PAD1 reserved bits set value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1)));
8024e1bc9a0SAchim Leubner     }
8034e1bc9a0SAchim Leubner     if( si_check_V_HDA(agRoot))
8044e1bc9a0SAchim Leubner     {
8054e1bc9a0SAchim Leubner       /*  Check HDA */
8064e1bc9a0SAchim Leubner       SA_DBG1(("saGetControllerInfo: HDA mode AGSA_RC_HDA_NO_FW_RUNNING\n" ));
8074e1bc9a0SAchim Leubner       return AGSA_RC_HDA_NO_FW_RUNNING;
8084e1bc9a0SAchim Leubner     }
8094e1bc9a0SAchim Leubner 
8104e1bc9a0SAchim Leubner 
8114e1bc9a0SAchim Leubner   }
8124e1bc9a0SAchim Leubner 
8134e1bc9a0SAchim Leubner   /* checking the fw AAP and IOP in ready state */
8144e1bc9a0SAchim Leubner   max_wait_time = WAIT_SECONDS(gWait_2);  /* 2 sec timeout */
8154e1bc9a0SAchim Leubner   max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT);
8164e1bc9a0SAchim Leubner   /* wait until scratch pad 1 and 2 registers in ready state  */
8174e1bc9a0SAchim Leubner   if(smIS_SPCV(agRoot))
8184e1bc9a0SAchim Leubner   {
8194e1bc9a0SAchim Leubner     do
8204e1bc9a0SAchim Leubner     {
8214e1bc9a0SAchim Leubner       ossaStallThread(agRoot, WAIT_INCREMENT);
8224e1bc9a0SAchim Leubner       value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1);
8234e1bc9a0SAchim Leubner       value1 =siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_2, MSGU_SCRATCH_PAD_2);
8244e1bc9a0SAchim Leubner       if(smIS_SPCV(agRoot))
8254e1bc9a0SAchim Leubner       {
8264e1bc9a0SAchim Leubner         if((value & SCRATCH_PAD1_V_RESERVED) )
8274e1bc9a0SAchim Leubner         {
8284e1bc9a0SAchim Leubner           SA_DBG1(("saGetControllerInfo: V reserved SCRATCH_PAD1 value = 0x%x (0x%x)\n", value, SCRATCH_PAD1_V_RESERVED));
8294e1bc9a0SAchim Leubner           ret = AGSA_RC_FW_NOT_IN_READY_STATE;
8304e1bc9a0SAchim Leubner           break;
8314e1bc9a0SAchim Leubner         }
8324e1bc9a0SAchim Leubner       }
8334e1bc9a0SAchim Leubner 
8344e1bc9a0SAchim Leubner       if ((max_wait_count -= WAIT_INCREMENT) == 0)
8354e1bc9a0SAchim Leubner       {
8364e1bc9a0SAchim Leubner         SA_DBG1(("saGetControllerInfo:  timeout SCRATCH_PAD1_V_READY !! SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1));
8374e1bc9a0SAchim Leubner         break;
8384e1bc9a0SAchim Leubner       }
8394e1bc9a0SAchim Leubner 
8404e1bc9a0SAchim Leubner     } while (((value & SCRATCH_PAD1_V_READY) != SCRATCH_PAD1_V_READY) || (value == 0xffffffff));
8414e1bc9a0SAchim Leubner 
8424e1bc9a0SAchim Leubner   }
8434e1bc9a0SAchim Leubner   else
8444e1bc9a0SAchim Leubner   {
8454e1bc9a0SAchim Leubner     do
8464e1bc9a0SAchim Leubner     {
8474e1bc9a0SAchim Leubner       ossaStallThread(agRoot, WAIT_INCREMENT);
8484e1bc9a0SAchim Leubner       value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1);
8494e1bc9a0SAchim Leubner       /* checking bit 4 to 7 for reserved in case we get 0xFFFFFFFF */
8504e1bc9a0SAchim Leubner       if (value & SCRATCH_PAD1_RESERVED)
8514e1bc9a0SAchim Leubner       {
8524e1bc9a0SAchim Leubner         SA_DBG1(("saGetControllerInfo: SCRATCH_PAD1 value = 0x%x\n", value));
8534e1bc9a0SAchim Leubner         ret = AGSA_RC_FW_NOT_IN_READY_STATE;
8544e1bc9a0SAchim Leubner         break;
8554e1bc9a0SAchim Leubner       }
8564e1bc9a0SAchim Leubner       value1 =siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_2,MSGU_SCRATCH_PAD_2);
8574e1bc9a0SAchim Leubner       /* checking bit 4 to 7 for reserved in case we get 0xFFFFFFFF */
8584e1bc9a0SAchim Leubner       if (value1 & SCRATCH_PAD2_RESERVED)
8594e1bc9a0SAchim Leubner       {
8604e1bc9a0SAchim Leubner         SA_DBG1(("saGetControllerInfo: SCRATCH_PAD2 value = 0x%x\n", value1));
8614e1bc9a0SAchim Leubner         ret = AGSA_RC_FW_NOT_IN_READY_STATE;
8624e1bc9a0SAchim Leubner         break;
8634e1bc9a0SAchim Leubner       }
8644e1bc9a0SAchim Leubner       if ((max_wait_count -= WAIT_INCREMENT) == 0)
8654e1bc9a0SAchim Leubner       {
8664e1bc9a0SAchim Leubner         SA_DBG1(("saGetControllerInfo: Timeout!! SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1));
8674e1bc9a0SAchim Leubner         break;
8684e1bc9a0SAchim Leubner       }
8694e1bc9a0SAchim Leubner     } while (((value & SCRATCH_PAD_STATE_MASK) != SCRATCH_PAD1_RDY) || ((value1 & SCRATCH_PAD_STATE_MASK) != SCRATCH_PAD2_RDY));
8704e1bc9a0SAchim Leubner   }
8714e1bc9a0SAchim Leubner 
8724e1bc9a0SAchim Leubner   if (!max_wait_count)
8734e1bc9a0SAchim Leubner   {
8744e1bc9a0SAchim Leubner     SA_DBG1(("saGetControllerInfo: timeout failure\n"));
8754e1bc9a0SAchim Leubner     ret = AGSA_RC_FW_NOT_IN_READY_STATE;
8764e1bc9a0SAchim Leubner   }
8774e1bc9a0SAchim Leubner 
8784e1bc9a0SAchim Leubner   if (ret == AGSA_RC_SUCCESS)
8794e1bc9a0SAchim Leubner   {
8804e1bc9a0SAchim Leubner     SA_DBG1(("saGetControllerInfo: FW Ready, SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1));
8814e1bc9a0SAchim Leubner 
8824e1bc9a0SAchim Leubner     /* read scratch pad0 to get PCI BAR and offset of configuration table */
8834e1bc9a0SAchim Leubner      MSGUCfgTblBase = siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0);
8844e1bc9a0SAchim Leubner     /* get offset */
8854e1bc9a0SAchim Leubner     CfgTblDWIdx = MSGUCfgTblBase & SCRATCH_PAD0_OFFSET_MASK;
8864e1bc9a0SAchim Leubner     /* get PCI BAR */
8874e1bc9a0SAchim Leubner     MSGUCfgTblBase = (MSGUCfgTblBase & SCRATCH_PAD0_BAR_MASK) >> SHIFT26;
8884e1bc9a0SAchim Leubner 
8894e1bc9a0SAchim Leubner     /* convert the PCI BAR to logical bar number */
8904e1bc9a0SAchim Leubner     pcibar = (bit8)mpiGetPCIBarIndex(agRoot, MSGUCfgTblBase);
8914e1bc9a0SAchim Leubner 
8924e1bc9a0SAchim Leubner     /* get controller information */
8934e1bc9a0SAchim Leubner     controllerInfo->signature =         ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx);
8944e1bc9a0SAchim Leubner     controllerInfo->fwInterfaceRev =    ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_INTERFACE_REVISION);
8954e1bc9a0SAchim Leubner     controllerInfo->fwRevision =        ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_FW_REVISION);
8964e1bc9a0SAchim Leubner     controllerInfo->ilaRevision =       ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_ILAT_ILAV_ILASMRN_ILAMRN_ILAMJN);
8974e1bc9a0SAchim Leubner     controllerInfo->maxPendingIO =      ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_MAX_OUTSTANDING_IO_OFFSET);
8984e1bc9a0SAchim Leubner     controllerInfo->maxDevices =       (ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_MAX_SGL_OFFSET) & MAIN_MAX_DEV_BITS);
8994e1bc9a0SAchim Leubner     controllerInfo->maxDevices =        controllerInfo->maxDevices >> SHIFT16;
9004e1bc9a0SAchim Leubner     controllerInfo->maxSgElements =    (ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_MAX_SGL_OFFSET) & MAIN_MAX_SGL_BITS);
9014e1bc9a0SAchim Leubner 
9024e1bc9a0SAchim Leubner     if( smIS_SPC(agRoot))
9034e1bc9a0SAchim Leubner     {
9044e1bc9a0SAchim Leubner       SA_DBG2(("saGetControllerInfo: LINK_CTRL 0x%08x Speed 0x%X Lanes 0x%X \n", ossaHwRegReadConfig32(agRoot,128),
9054e1bc9a0SAchim Leubner         ((ossaHwRegReadConfig32(agRoot,128) & 0x000F0000) >> 16),
9064e1bc9a0SAchim Leubner         ((ossaHwRegReadConfig32(agRoot,128) & 0x0FF00000) >> 20) ));
9074e1bc9a0SAchim Leubner       controllerInfo->PCILinkRate =  ((ossaHwRegReadConfig32(agRoot,128) & 0x000F0000) >> 16);
9084e1bc9a0SAchim Leubner       controllerInfo->PCIWidth =   ((ossaHwRegReadConfig32(agRoot,128) & 0x0FF00000) >> 20);
9094e1bc9a0SAchim Leubner     }
9104e1bc9a0SAchim Leubner     else
9114e1bc9a0SAchim Leubner     {
9124e1bc9a0SAchim Leubner       SA_DBG2(("saGetControllerInfo: LINK_CTRL 0x%08x Speed 0x%X Lanes 0x%X \n", ossaHwRegReadConfig32(agRoot,208),
9134e1bc9a0SAchim Leubner         ((ossaHwRegReadConfig32(agRoot,208) & 0x000F0000) >> 16),
9144e1bc9a0SAchim Leubner         ((ossaHwRegReadConfig32(agRoot,208) & 0x0FF00000) >> 20) ));
9154e1bc9a0SAchim Leubner       controllerInfo->PCILinkRate =  ((ossaHwRegReadConfig32(agRoot,208) & 0x000F0000) >> 16);
9164e1bc9a0SAchim Leubner       controllerInfo->PCIWidth =   ((ossaHwRegReadConfig32(agRoot,208) & 0x0FF00000) >> 20);
9174e1bc9a0SAchim Leubner     }
9184e1bc9a0SAchim Leubner 
9194e1bc9a0SAchim Leubner 
9204e1bc9a0SAchim Leubner     ContrlCapFlag =                     ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_CNTRL_CAP_OFFSET);
9214e1bc9a0SAchim Leubner     controllerInfo->queueSupport =      ContrlCapFlag & MAIN_QSUPPORT_BITS;
9224e1bc9a0SAchim Leubner     controllerInfo->phyCount =         (bit8)((ContrlCapFlag & MAIN_PHY_COUNT_MASK) >> SHIFT19);
9234e1bc9a0SAchim Leubner 
9244e1bc9a0SAchim Leubner 
9254e1bc9a0SAchim Leubner     if(smIS_SPCV(agRoot))
9264e1bc9a0SAchim Leubner     {
9274e1bc9a0SAchim Leubner       controllerInfo->controllerSetting = (bit8)((siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1) & SCRATCH_PAD1_V_BOOTSTATE_MASK ) >> SHIFT4);
9284e1bc9a0SAchim Leubner     }
9294e1bc9a0SAchim Leubner     else
9304e1bc9a0SAchim Leubner     {
9314e1bc9a0SAchim Leubner       controllerInfo->controllerSetting = (bit8)(ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_HDA_FLAGS_OFFSET) & MAIN_HDA_FLAG_BITS);
9324e1bc9a0SAchim Leubner     }
9334e1bc9a0SAchim Leubner     controllerInfo->sasSpecsSupport =   (ContrlCapFlag & MAIN_SAS_SUPPORT_BITS) >> SHIFT25;
9344e1bc9a0SAchim Leubner   }
9354e1bc9a0SAchim Leubner 
9364e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerInfo: signature         0x%X\n", controllerInfo->signature));
9374e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerInfo: fwInterfaceRev    0x%X\n", controllerInfo->fwInterfaceRev));
9384e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerInfo: hwRevision        0x%X\n", controllerInfo->hwRevision));
9394e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerInfo: fwRevision        0x%X\n", controllerInfo->fwRevision));
9404e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerInfo: ilaRevision       0x%X\n", controllerInfo->ilaRevision));
9414e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerInfo: maxPendingIO      0x%X\n", controllerInfo->maxPendingIO));
9424e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerInfo: maxDevices        0x%X\n", controllerInfo->maxDevices));
9434e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerInfo: maxSgElements     0x%X\n", controllerInfo->maxSgElements));
9444e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerInfo: queueSupport      0x%X\n", controllerInfo->queueSupport));
9454e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerInfo: phyCount          0x%X\n", controllerInfo->phyCount));
9464e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerInfo: controllerSetting 0x%X\n", controllerInfo->controllerSetting));
9474e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerInfo: PCILinkRate       0x%X\n", controllerInfo->PCILinkRate));
9484e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerInfo: PCIWidth          0x%X\n", controllerInfo->PCIWidth));
9494e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerInfo: sasSpecsSupport   0x%X\n", controllerInfo->sasSpecsSupport));
9504e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerInfo: sdkInterfaceRev   0x%X\n", controllerInfo->sdkInterfaceRev));
9514e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerInfo: sdkRevision       0x%X\n", controllerInfo->sdkRevision));
9524e1bc9a0SAchim Leubner   if (agNULL != agRoot->sdkData)
9534e1bc9a0SAchim Leubner   {
9544e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6e");
9554e1bc9a0SAchim Leubner   }
9564e1bc9a0SAchim Leubner   return ret;
9574e1bc9a0SAchim Leubner }
9584e1bc9a0SAchim Leubner 
9594e1bc9a0SAchim Leubner /******************************************************************************/
9604e1bc9a0SAchim Leubner /*! \brief SPC Get Controller Status Command
9614e1bc9a0SAchim Leubner  *
9624e1bc9a0SAchim Leubner  *  This command sends Get Controller Status Command to SPC.
9634e1bc9a0SAchim Leubner  *
9644e1bc9a0SAchim Leubner  *  \param agRoot           Handles for this instance of SAS/SATA LL
9654e1bc9a0SAchim Leubner  *  \param controllerStatus controller status
9664e1bc9a0SAchim Leubner  *
9674e1bc9a0SAchim Leubner  *  \return If the MPI command is sent to SPC successfully
9684e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
9694e1bc9a0SAchim Leubner  *          - \e AGSA_RC_FAILURE the MPI command is failure
9704e1bc9a0SAchim Leubner  *
9714e1bc9a0SAchim Leubner  */
9724e1bc9a0SAchim Leubner /*******************************************************************************/
saGetControllerStatus(agsaRoot_t * agRoot,agsaControllerStatus_t * controllerStatus)9734e1bc9a0SAchim Leubner GLOBAL bit32 saGetControllerStatus(
9744e1bc9a0SAchim Leubner                         agsaRoot_t                *agRoot,
9754e1bc9a0SAchim Leubner                         agsaControllerStatus_t    *controllerStatus
9764e1bc9a0SAchim Leubner                         )
9774e1bc9a0SAchim Leubner {
9784e1bc9a0SAchim Leubner   bit32 ret = AGSA_RC_SUCCESS;
9794e1bc9a0SAchim Leubner   agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
9804e1bc9a0SAchim Leubner   spc_GSTableDescriptor_t GSTable;
9814e1bc9a0SAchim Leubner   bit32 max_wait_time;
9824e1bc9a0SAchim Leubner   bit32 max_wait_count;
9834e1bc9a0SAchim Leubner   bit32 i, value, value1;
9844e1bc9a0SAchim Leubner 
9854e1bc9a0SAchim Leubner   if (agNULL != saRoot)
9864e1bc9a0SAchim Leubner   {
9874e1bc9a0SAchim Leubner     smTraceFuncEnter(hpDBG_VERY_LOUD,"6f");
9884e1bc9a0SAchim Leubner   }
9894e1bc9a0SAchim Leubner   /* clean the structure */
9904e1bc9a0SAchim Leubner   si_memset(controllerStatus, 0, sizeof(agsaControllerStatus_t));
9914e1bc9a0SAchim Leubner   si_memset(&GSTable, 0, sizeof(spc_GSTableDescriptor_t));
9924e1bc9a0SAchim Leubner   if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0) == 0xFFFFFFFF)
9934e1bc9a0SAchim Leubner   {
9944e1bc9a0SAchim Leubner     SA_DBG1(("saGetControllerStatus:AGSA_RC_FAILURE SCRATCH_PAD0 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0)));
9954e1bc9a0SAchim Leubner     return AGSA_RC_FAILURE;
9964e1bc9a0SAchim Leubner   }
9974e1bc9a0SAchim Leubner 
9984e1bc9a0SAchim Leubner   if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_3)  & (OSSA_ENCRYPT_ENGINE_FAILURE_MASK | OSSA_DIF_ENGINE_FAILURE_MASK))
9994e1bc9a0SAchim Leubner   {
10004e1bc9a0SAchim Leubner     SA_DBG1(("saGetControllerStatus: BIST error in SCRATCHPAD 3 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_3,  MSGU_SCRATCH_PAD_3)));
10014e1bc9a0SAchim Leubner   }
10024e1bc9a0SAchim Leubner 
10034e1bc9a0SAchim Leubner   if(smIS_SPC(agRoot))
10044e1bc9a0SAchim Leubner   {
10054e1bc9a0SAchim Leubner 
10064e1bc9a0SAchim Leubner     /* read detail fatal errors */
10074e1bc9a0SAchim Leubner     controllerStatus->fatalErrorInfo.errorInfo0 = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_0);
10084e1bc9a0SAchim Leubner     controllerStatus->fatalErrorInfo.errorInfo1 = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_1);
10094e1bc9a0SAchim Leubner     controllerStatus->fatalErrorInfo.errorInfo2 = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_2);
10104e1bc9a0SAchim Leubner     controllerStatus->fatalErrorInfo.errorInfo3 = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_3);
10114e1bc9a0SAchim Leubner 
10124e1bc9a0SAchim Leubner #if defined(SALLSDK_DEBUG)
10134e1bc9a0SAchim Leubner     SA_DBG1(("saGetControllerStatus: SCRATCH_PAD0 value = 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo0));
10144e1bc9a0SAchim Leubner     SA_DBG1(("saGetControllerStatus: SCRATCH_PAD1 value = 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo1));
10154e1bc9a0SAchim Leubner     SA_DBG1(("saGetControllerStatus: SCRATCH_PAD2 value = 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo2));
10164e1bc9a0SAchim Leubner     SA_DBG1(("saGetControllerStatus: SCRATCH_PAD3 value = 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo3));
10174e1bc9a0SAchim Leubner #endif
10184e1bc9a0SAchim Leubner 
10194e1bc9a0SAchim Leubner     /* check HDA mode */
10204e1bc9a0SAchim Leubner     value = ossaHwRegReadExt(agRoot, PCIBAR3, HDA_RSP_OFFSET1MB+HDA_CMD_CODE_OFFSET) & HDA_STATUS_BITS;
10214e1bc9a0SAchim Leubner 
10224e1bc9a0SAchim Leubner     if (value == BOOTTLOADERHDA_IDLE)
10234e1bc9a0SAchim Leubner     {
10244e1bc9a0SAchim Leubner       /* HDA mode */
10254e1bc9a0SAchim Leubner       SA_DBG1(("saGetControllerStatus: HDA mode, value = 0x%x\n", value));
10264e1bc9a0SAchim Leubner       return AGSA_RC_HDA_NO_FW_RUNNING;
10274e1bc9a0SAchim Leubner     }
10284e1bc9a0SAchim Leubner 
10294e1bc9a0SAchim Leubner     /* check error state */
10304e1bc9a0SAchim Leubner     value = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_1);
10314e1bc9a0SAchim Leubner     value1 = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_2);
10324e1bc9a0SAchim Leubner 
10334e1bc9a0SAchim Leubner     /* check AAP or IOP error */
10344e1bc9a0SAchim Leubner     if ((SCRATCH_PAD1_ERR == (value & SCRATCH_PAD_STATE_MASK)) || (SCRATCH_PAD2_ERR == (value1 & SCRATCH_PAD_STATE_MASK)))
10354e1bc9a0SAchim Leubner     {
10364e1bc9a0SAchim Leubner       if (agNULL != saRoot)
10374e1bc9a0SAchim Leubner       {
10384e1bc9a0SAchim Leubner         controllerStatus->fatalErrorInfo.regDumpBusBaseNum0 = saRoot->mainConfigTable.regDumpPCIBAR;
10394e1bc9a0SAchim Leubner         controllerStatus->fatalErrorInfo.regDumpOffset0 = saRoot->mainConfigTable.FatalErrorDumpOffset0;
10404e1bc9a0SAchim Leubner         controllerStatus->fatalErrorInfo.regDumpLen0 = saRoot->mainConfigTable.FatalErrorDumpLength0;
10414e1bc9a0SAchim Leubner         controllerStatus->fatalErrorInfo.regDumpBusBaseNum1 = saRoot->mainConfigTable.regDumpPCIBAR;
10424e1bc9a0SAchim Leubner         controllerStatus->fatalErrorInfo.regDumpOffset1 = saRoot->mainConfigTable.FatalErrorDumpOffset1;
10434e1bc9a0SAchim Leubner         controllerStatus->fatalErrorInfo.regDumpLen1 = saRoot->mainConfigTable.FatalErrorDumpLength1;
10444e1bc9a0SAchim Leubner       }
10454e1bc9a0SAchim Leubner       else
10464e1bc9a0SAchim Leubner       {
10474e1bc9a0SAchim Leubner         controllerStatus->fatalErrorInfo.regDumpBusBaseNum0 = 0;
10484e1bc9a0SAchim Leubner         controllerStatus->fatalErrorInfo.regDumpOffset0 = 0;
10494e1bc9a0SAchim Leubner         controllerStatus->fatalErrorInfo.regDumpLen0 = 0;
10504e1bc9a0SAchim Leubner         controllerStatus->fatalErrorInfo.regDumpBusBaseNum1 = 0;
10514e1bc9a0SAchim Leubner         controllerStatus->fatalErrorInfo.regDumpOffset1 = 0;
10524e1bc9a0SAchim Leubner         controllerStatus->fatalErrorInfo.regDumpLen1 = 0;
10534e1bc9a0SAchim Leubner       }
10544e1bc9a0SAchim Leubner 
10554e1bc9a0SAchim Leubner       if (agNULL != saRoot)
10564e1bc9a0SAchim Leubner       {
10574e1bc9a0SAchim Leubner         smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6f");
10584e1bc9a0SAchim Leubner       }
10594e1bc9a0SAchim Leubner       return AGSA_RC_FW_NOT_IN_READY_STATE;
10604e1bc9a0SAchim Leubner     }
10614e1bc9a0SAchim Leubner 
10624e1bc9a0SAchim Leubner     /* checking the fw AAP and IOP in ready state */
10634e1bc9a0SAchim Leubner     max_wait_time = WAIT_SECONDS(2);  /* 2 sec timeout */
10644e1bc9a0SAchim Leubner     max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT);
10654e1bc9a0SAchim Leubner     /* wait until scratch pad 1 and 2 registers in ready state  */
10664e1bc9a0SAchim Leubner     do
10674e1bc9a0SAchim Leubner     {
10684e1bc9a0SAchim Leubner       ossaStallThread(agRoot, WAIT_INCREMENT);
10694e1bc9a0SAchim Leubner       value = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_1);
10704e1bc9a0SAchim Leubner       /* checking bit 4 to 7 for reserved in case we get 0xFFFFFFFF */
10714e1bc9a0SAchim Leubner       if (value & SCRATCH_PAD1_RESERVED)
10724e1bc9a0SAchim Leubner       {
10734e1bc9a0SAchim Leubner         SA_DBG1(("saGetControllerStatus: (Reserved bit not 0) SCRATCH_PAD1 value = 0x%x\n", value));
10744e1bc9a0SAchim Leubner         ret = AGSA_RC_FAILURE;
10754e1bc9a0SAchim Leubner         break;
10764e1bc9a0SAchim Leubner       }
10774e1bc9a0SAchim Leubner 
10784e1bc9a0SAchim Leubner       value1 = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_2);
10794e1bc9a0SAchim Leubner       /* checking bit 4 to 7 for reserved in case we get 0xFFFFFFFF */
10804e1bc9a0SAchim Leubner       if (value1 & SCRATCH_PAD2_RESERVED)
10814e1bc9a0SAchim Leubner       {
10824e1bc9a0SAchim Leubner         SA_DBG1(("saGetControllerStatus: (Reserved bit not 0) SCRATCH_PAD2 value = 0x%x\n", value1));
10834e1bc9a0SAchim Leubner         ret = AGSA_RC_FAILURE;
10844e1bc9a0SAchim Leubner         break;
10854e1bc9a0SAchim Leubner       }
10864e1bc9a0SAchim Leubner 
10874e1bc9a0SAchim Leubner       if ((max_wait_count -=WAIT_INCREMENT) == 0)
10884e1bc9a0SAchim Leubner       {
10894e1bc9a0SAchim Leubner         SA_DBG1(("saGetControllerStatus: Timeout!! SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1));
10904e1bc9a0SAchim Leubner         break;
10914e1bc9a0SAchim Leubner       }
10924e1bc9a0SAchim Leubner     } while (((value & SCRATCH_PAD_STATE_MASK) != SCRATCH_PAD1_RDY) || ((value1 & SCRATCH_PAD_STATE_MASK) != SCRATCH_PAD2_RDY));
10934e1bc9a0SAchim Leubner 
10944e1bc9a0SAchim Leubner     if (!max_wait_count)
10954e1bc9a0SAchim Leubner     {
10964e1bc9a0SAchim Leubner       SA_DBG1(("saGetControllerStatus: timeout failure\n"));
10974e1bc9a0SAchim Leubner       ret = AGSA_RC_FAILURE;
10984e1bc9a0SAchim Leubner     }
10994e1bc9a0SAchim Leubner 
11004e1bc9a0SAchim Leubner     if (ret == AGSA_RC_SUCCESS)
11014e1bc9a0SAchim Leubner     {
11024e1bc9a0SAchim Leubner       SA_DBG1(("saGetControllerStatus: FW Ready, SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1));
11034e1bc9a0SAchim Leubner 
11044e1bc9a0SAchim Leubner       /* read scratch pad0 to get PCI BAR and offset of configuration table */
11054e1bc9a0SAchim Leubner       value = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_0);
11064e1bc9a0SAchim Leubner       /* get offset */
11074e1bc9a0SAchim Leubner       value1 = value & SCRATCH_PAD0_OFFSET_MASK;
11084e1bc9a0SAchim Leubner       /* get PCI BAR */
11094e1bc9a0SAchim Leubner       value = (value & SCRATCH_PAD0_BAR_MASK) >> SHIFT26;
11104e1bc9a0SAchim Leubner 
11114e1bc9a0SAchim Leubner       /* read GST Table state */
11124e1bc9a0SAchim Leubner       mpiReadGSTable(agRoot, &GSTable);
11134e1bc9a0SAchim Leubner 
11144e1bc9a0SAchim Leubner       /* read register dump information */
11154e1bc9a0SAchim Leubner       controllerStatus->fatalErrorInfo.regDumpBusBaseNum0 = value;
11164e1bc9a0SAchim Leubner       controllerStatus->fatalErrorInfo.regDumpBusBaseNum1 = value;
11174e1bc9a0SAchim Leubner       /* convert the PCI BAR to logical bar number */
11184e1bc9a0SAchim Leubner       value = (bit8)mpiGetPCIBarIndex(agRoot, value);
11194e1bc9a0SAchim Leubner       controllerStatus->fatalErrorInfo.regDumpOffset0 = ossaHwRegReadExt(agRoot, value, value1 + MAIN_FATAL_ERROR_RDUMP0_OFFSET);
11204e1bc9a0SAchim Leubner       controllerStatus->fatalErrorInfo.regDumpLen0    = ossaHwRegReadExt(agRoot, value, value1 + MAIN_FATAL_ERROR_RDUMP0_LENGTH);
11214e1bc9a0SAchim Leubner       controllerStatus->fatalErrorInfo.regDumpOffset1 = ossaHwRegReadExt(agRoot, value, value1 + MAIN_FATAL_ERROR_RDUMP1_OFFSET);
11224e1bc9a0SAchim Leubner       controllerStatus->fatalErrorInfo.regDumpLen1    = ossaHwRegReadExt(agRoot, value, value1 + MAIN_FATAL_ERROR_RDUMP1_LENGTH);
11234e1bc9a0SAchim Leubner 
11244e1bc9a0SAchim Leubner       /* AAP/IOP error state */
11254e1bc9a0SAchim Leubner       SA_DBG2(("saGetControllerStatus: SCRATCH PAD0 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo0));
11264e1bc9a0SAchim Leubner       SA_DBG2(("saGetControllerStatus: SCRATCH PAD1 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo1));
11274e1bc9a0SAchim Leubner       SA_DBG2(("saGetControllerStatus: SCRATCH PAD2 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo2));
11284e1bc9a0SAchim Leubner       SA_DBG2(("saGetControllerStatus: SCRATCH PAD3 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo3));
11294e1bc9a0SAchim Leubner       /* Register Dump information */
11304e1bc9a0SAchim Leubner       SA_DBG2(("saGetControllerStatus: RegDumpOffset0 0x%x\n", controllerStatus->fatalErrorInfo.regDumpOffset0));
11314e1bc9a0SAchim Leubner       SA_DBG2(("saGetControllerStatus: RegDumpLen0    0x%x\n", controllerStatus->fatalErrorInfo.regDumpLen0));
11324e1bc9a0SAchim Leubner       SA_DBG2(("saGetControllerStatus: RegDumpOffset1 0x%x\n", controllerStatus->fatalErrorInfo.regDumpOffset1));
11334e1bc9a0SAchim Leubner       SA_DBG2(("saGetControllerStatus: RegDumpLen1    0x%x\n", controllerStatus->fatalErrorInfo.regDumpLen1));
11344e1bc9a0SAchim Leubner 
11354e1bc9a0SAchim Leubner       controllerStatus->interfaceState = GSTable.GSTLenMPIS & GST_INF_STATE_BITS;
11364e1bc9a0SAchim Leubner       controllerStatus->iqFreezeState0 = GSTable.IQFreezeState0;
11374e1bc9a0SAchim Leubner       controllerStatus->iqFreezeState1 = GSTable.IQFreezeState1;
11384e1bc9a0SAchim Leubner       for (i = 0; i < 8; i++)
11394e1bc9a0SAchim Leubner       {
11404e1bc9a0SAchim Leubner         controllerStatus->phyStatus[i] = GSTable.PhyState[i];
11414e1bc9a0SAchim Leubner         controllerStatus->recoverableErrorInfo[i] = GSTable.recoverErrInfo[i];
11424e1bc9a0SAchim Leubner       }
11434e1bc9a0SAchim Leubner       controllerStatus->tickCount0 = GSTable.MsguTcnt;
11444e1bc9a0SAchim Leubner       controllerStatus->tickCount1 = GSTable.IopTcnt;
11454e1bc9a0SAchim Leubner       controllerStatus->tickCount2 = GSTable.Iop1Tcnt;
11464e1bc9a0SAchim Leubner     }
11474e1bc9a0SAchim Leubner   }
11484e1bc9a0SAchim Leubner   else
11494e1bc9a0SAchim Leubner   {
11504e1bc9a0SAchim Leubner 
11514e1bc9a0SAchim Leubner     SA_DBG1(("saGetControllerStatus: SPCv\n" ));
11524e1bc9a0SAchim Leubner 
11534e1bc9a0SAchim Leubner 
11544e1bc9a0SAchim Leubner     if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1) &   SCRATCH_PAD1_V_RESERVED )
11554e1bc9a0SAchim Leubner     {
11564e1bc9a0SAchim Leubner       SA_DBG1(("saGetControllerStatus: Warning SCRATCH_PAD1 reserved bits set value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1)));
11574e1bc9a0SAchim Leubner     }
11584e1bc9a0SAchim Leubner     if( si_check_V_HDA(agRoot))
11594e1bc9a0SAchim Leubner     {
11604e1bc9a0SAchim Leubner       /*  Check HDA */
11614e1bc9a0SAchim Leubner 
11624e1bc9a0SAchim Leubner       controllerStatus->fatalErrorInfo.errorInfo0 = ossaHwRegRead(agRoot,V_Scratchpad_0_Register );
11634e1bc9a0SAchim Leubner       controllerStatus->fatalErrorInfo.errorInfo1 = ossaHwRegRead(agRoot,V_Scratchpad_1_Register );
11644e1bc9a0SAchim Leubner       controllerStatus->fatalErrorInfo.errorInfo2 = ossaHwRegRead(agRoot,V_Scratchpad_2_Register );
11654e1bc9a0SAchim Leubner       controllerStatus->fatalErrorInfo.errorInfo3 = ossaHwRegRead(agRoot,V_Scratchpad_3_Register );
11664e1bc9a0SAchim Leubner       SA_DBG1(("saGetControllerStatus: HDA mode, AGSA_RC_HDA_NO_FW_RUNNING errorInfo1  = 0x%x\n",controllerStatus->fatalErrorInfo.errorInfo1 ));
11674e1bc9a0SAchim Leubner       return AGSA_RC_HDA_NO_FW_RUNNING;
11684e1bc9a0SAchim Leubner     }
11694e1bc9a0SAchim Leubner 
11704e1bc9a0SAchim Leubner     ret = si_check_V_Ready(agRoot);
11714e1bc9a0SAchim Leubner     /* Check ready */
11724e1bc9a0SAchim Leubner     if (ret == AGSA_RC_SUCCESS)
11734e1bc9a0SAchim Leubner     {
11744e1bc9a0SAchim Leubner       /* read GST Table state */
11754e1bc9a0SAchim Leubner       mpiReadGSTable(agRoot, &GSTable);
11764e1bc9a0SAchim Leubner       controllerStatus->interfaceState = GSTable.GSTLenMPIS & GST_INF_STATE_BITS;
11774e1bc9a0SAchim Leubner       controllerStatus->iqFreezeState0 = GSTable.IQFreezeState0;
11784e1bc9a0SAchim Leubner       controllerStatus->iqFreezeState1 = GSTable.IQFreezeState1;
11794e1bc9a0SAchim Leubner       for (i = 0; i < 8; i++)
11804e1bc9a0SAchim Leubner       {
11814e1bc9a0SAchim Leubner         controllerStatus->phyStatus[i] = GSTable.PhyState[i];
11824e1bc9a0SAchim Leubner         controllerStatus->recoverableErrorInfo[i] = GSTable.recoverErrInfo[i];
11834e1bc9a0SAchim Leubner       }
11844e1bc9a0SAchim Leubner       controllerStatus->tickCount0 = GSTable.MsguTcnt;
11854e1bc9a0SAchim Leubner       controllerStatus->tickCount1 = GSTable.IopTcnt;
11864e1bc9a0SAchim Leubner       controllerStatus->tickCount2 = GSTable.Iop1Tcnt;
11874e1bc9a0SAchim Leubner 
11884e1bc9a0SAchim Leubner       controllerStatus->interfaceState = GSTable.GSTLenMPIS & GST_INF_STATE_BITS;
11894e1bc9a0SAchim Leubner       controllerStatus->iqFreezeState0 = GSTable.IQFreezeState0;
11904e1bc9a0SAchim Leubner       controllerStatus->iqFreezeState1 = GSTable.IQFreezeState1;
11914e1bc9a0SAchim Leubner       for (i = 0; i < 8; i++)
11924e1bc9a0SAchim Leubner       {
11934e1bc9a0SAchim Leubner         if( IS_SDKDATA(agRoot))
11944e1bc9a0SAchim Leubner         {
11954e1bc9a0SAchim Leubner           if (agNULL != saRoot)
11964e1bc9a0SAchim Leubner           {
11974e1bc9a0SAchim Leubner             controllerStatus->phyStatus[i] = ((saRoot->phys[i+8].linkstatus << SHIFT8) | saRoot->phys[i].linkstatus);
11984e1bc9a0SAchim Leubner           }
11994e1bc9a0SAchim Leubner         }
12004e1bc9a0SAchim Leubner         else
12014e1bc9a0SAchim Leubner         {
12024e1bc9a0SAchim Leubner           controllerStatus->phyStatus[i] = 0;
12034e1bc9a0SAchim Leubner         }
12044e1bc9a0SAchim Leubner         controllerStatus->recoverableErrorInfo[i] = GSTable.recoverErrInfo[i];
12054e1bc9a0SAchim Leubner       }
12064e1bc9a0SAchim Leubner       controllerStatus->tickCount0 = GSTable.MsguTcnt;
12074e1bc9a0SAchim Leubner       controllerStatus->tickCount1 = GSTable.IopTcnt;
12084e1bc9a0SAchim Leubner       controllerStatus->tickCount2 = GSTable.Iop1Tcnt;
12094e1bc9a0SAchim Leubner 
12104e1bc9a0SAchim Leubner     }
12114e1bc9a0SAchim Leubner 
12124e1bc9a0SAchim Leubner     SA_DBG1(("saGetControllerStatus: SCRATCH_PAD0 value = 0x%x\n", ossaHwRegRead(agRoot, V_Scratchpad_0_Register)));
12134e1bc9a0SAchim Leubner     SA_DBG1(("saGetControllerStatus: SCRATCH_PAD1 value = 0x%x\n", ossaHwRegRead(agRoot, V_Scratchpad_1_Register)));
12144e1bc9a0SAchim Leubner     SA_DBG1(("saGetControllerStatus: SCRATCH_PAD2 value = 0x%x\n", ossaHwRegRead(agRoot, V_Scratchpad_2_Register)));
12154e1bc9a0SAchim Leubner     SA_DBG1(("saGetControllerStatus: SCRATCH_PAD3 value = 0x%x\n", ossaHwRegRead(agRoot, V_Scratchpad_3_Register)));
12164e1bc9a0SAchim Leubner 
12174e1bc9a0SAchim Leubner     controllerStatus->fatalErrorInfo.errorInfo0 = ossaHwRegRead(agRoot,V_Scratchpad_0_Register );
12184e1bc9a0SAchim Leubner     controllerStatus->fatalErrorInfo.errorInfo1 = ossaHwRegRead(agRoot,V_Scratchpad_1_Register );
12194e1bc9a0SAchim Leubner     controllerStatus->fatalErrorInfo.errorInfo2 = ossaHwRegRead(agRoot,V_Scratchpad_2_Register );
12204e1bc9a0SAchim Leubner     controllerStatus->fatalErrorInfo.errorInfo3 = ossaHwRegRead(agRoot,V_Scratchpad_3_Register );
12214e1bc9a0SAchim Leubner 
12224e1bc9a0SAchim Leubner     controllerStatus->bootStatus = ( (( controllerStatus->fatalErrorInfo.errorInfo1 >>  SHIFT9) & 1 )                | /* bit 1  */
12234e1bc9a0SAchim Leubner                                      (( controllerStatus->fatalErrorInfo.errorInfo3 & 0x3)               << SHIFT16) | /* bit 16 17 */
12244e1bc9a0SAchim Leubner                                     ((( controllerStatus->fatalErrorInfo.errorInfo3 >>  SHIFT14) & 0x7)  << SHIFT18) | /* bit 18 19 20 */
12254e1bc9a0SAchim Leubner                                     ((( controllerStatus->fatalErrorInfo.errorInfo3 >>  SHIFT4 ) & 0x1)  << SHIFT23) | /* bit 23 */
12264e1bc9a0SAchim Leubner                                     ((( controllerStatus->fatalErrorInfo.errorInfo3 >>  SHIFT16) & 0xFF) << SHIFT24) );/* bit 24 31 */
12274e1bc9a0SAchim Leubner 
12284e1bc9a0SAchim Leubner     controllerStatus->bootComponentState[0] = (bit16) (( controllerStatus->fatalErrorInfo.errorInfo1               & 3 ) | 0x8000); /* RAAE_STATE */
12294e1bc9a0SAchim Leubner     controllerStatus->bootComponentState[1] = (bit16) ((( controllerStatus->fatalErrorInfo.errorInfo1 >>  SHIFT10) & 3 ) | 0x8000); /* IOP0_STATE */
12304e1bc9a0SAchim Leubner     controllerStatus->bootComponentState[2] = (bit16) ((( controllerStatus->fatalErrorInfo.errorInfo1 >>  SHIFT12) & 3 ) | 0x8000); /* IOP1_STATE */
12314e1bc9a0SAchim Leubner     controllerStatus->bootComponentState[3] = (bit16) ((( controllerStatus->fatalErrorInfo.errorInfo1 >>  SHIFT4)  & 7 ) | 0x8000); /* BOOTLDR_STATE  */
12324e1bc9a0SAchim Leubner     controllerStatus->bootComponentState[4] = (bit16) ((( controllerStatus->fatalErrorInfo.errorInfo1 >>  SHIFT2)  & 3 ) | 0x8000); /* ILA State */
12334e1bc9a0SAchim Leubner     controllerStatus->bootComponentState[5] = 0;
12344e1bc9a0SAchim Leubner     controllerStatus->bootComponentState[6] = 0;
12354e1bc9a0SAchim Leubner     controllerStatus->bootComponentState[7] = 0;
12364e1bc9a0SAchim Leubner 
12374e1bc9a0SAchim Leubner 
12384e1bc9a0SAchim Leubner 
12394e1bc9a0SAchim Leubner     if(controllerStatus->fatalErrorInfo.errorInfo0 == 0xFFFFFFFF)
12404e1bc9a0SAchim Leubner     {
12414e1bc9a0SAchim Leubner       ret = AGSA_RC_FAILURE;
12424e1bc9a0SAchim Leubner     }
12434e1bc9a0SAchim Leubner 
12444e1bc9a0SAchim Leubner   }
12454e1bc9a0SAchim Leubner 
12464e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: fatalErrorInfo.errorInfo0          0x%x\n", controllerStatus->fatalErrorInfo.errorInfo0));
12474e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: fatalErrorInfo.errorInfo1          0x%x\n", controllerStatus->fatalErrorInfo.errorInfo1));
12484e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: fatalErrorInfo.errorInfo2          0x%x\n", controllerStatus->fatalErrorInfo.errorInfo2));
12494e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: fatalErrorInfo.errorInfo3          0x%x\n", controllerStatus->fatalErrorInfo.errorInfo3));
12504e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: fatalErrorInfo.regDumpBusBaseNum0  0x%x\n", controllerStatus->fatalErrorInfo.regDumpBusBaseNum0));
12514e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: fatalErrorInfo.regDumpOffset0      0x%x\n", controllerStatus->fatalErrorInfo.regDumpOffset0));
12524e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: fatalErrorInfo.regDumpLen0         0x%x\n", controllerStatus->fatalErrorInfo.regDumpLen0));
12534e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: fatalErrorInfo.regDumpBusBaseNum1  0x%x\n", controllerStatus->fatalErrorInfo.regDumpBusBaseNum1));
12544e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: fatalErrorInfo.regDumpOffset1      0x%x\n", controllerStatus->fatalErrorInfo.regDumpOffset1));
12554e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: fatalErrorInfo.regDumpLen1         0x%x\n", controllerStatus->fatalErrorInfo.regDumpLen1));
12564e1bc9a0SAchim Leubner 
12574e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: interfaceState                     0x%x\n", controllerStatus->interfaceState));
12584e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: iqFreezeState0                     0x%x\n", controllerStatus->iqFreezeState0));
12594e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: iqFreezeState1                     0x%x\n", controllerStatus->iqFreezeState1));
12604e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: tickCount0                         0x%x\n", controllerStatus->tickCount0));
12614e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: tickCount1                         0x%x\n", controllerStatus->tickCount1));
12624e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: tickCount2                         0x%x\n", controllerStatus->tickCount2));
12634e1bc9a0SAchim Leubner 
12644e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: phyStatus[0]                       0x%08x\n", controllerStatus->phyStatus[0]));
12654e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: phyStatus[1]                       0x%08x\n", controllerStatus->phyStatus[1]));
12664e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: phyStatus[2]                       0x%08x\n", controllerStatus->phyStatus[2]));
12674e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: phyStatus[3]                       0x%08x\n", controllerStatus->phyStatus[3]));
12684e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: phyStatus[4]                       0x%08x\n", controllerStatus->phyStatus[4]));
12694e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: phyStatus[5]                       0x%08x\n", controllerStatus->phyStatus[5]));
12704e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: phyStatus[6]                       0x%08x\n", controllerStatus->phyStatus[6]));
12714e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: phyStatus[7]                       0x%08x\n", controllerStatus->phyStatus[7]));
12724e1bc9a0SAchim Leubner 
12734e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[0]            0x%08x\n", controllerStatus->recoverableErrorInfo[0]));
12744e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[1]            0x%08x\n", controllerStatus->recoverableErrorInfo[1]));
12754e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[2]            0x%08x\n", controllerStatus->recoverableErrorInfo[2]));
12764e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[3]            0x%08x\n", controllerStatus->recoverableErrorInfo[3]));
12774e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[4]            0x%08x\n", controllerStatus->recoverableErrorInfo[4]));
12784e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[5]            0x%08x\n", controllerStatus->recoverableErrorInfo[5]));
12794e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[6]            0x%08x\n", controllerStatus->recoverableErrorInfo[6]));
12804e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[7]            0x%08x\n", controllerStatus->recoverableErrorInfo[7]));
12814e1bc9a0SAchim Leubner 
12824e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: bootStatus                         0x%08x\n", controllerStatus->bootStatus));
12834e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: bootStatus  Active FW Image        %x\n", (controllerStatus->bootStatus & 1 ) ? 1 : 0 ));
12844e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: bootStatus  Encryption Cap         %x\n", ((controllerStatus->bootStatus & 0x30000 ) >> SHIFT16) ));
12854e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: bootStatus  Encryption Sec Mode    %x\n", ((controllerStatus->bootStatus & 0xC0000 ) >> SHIFT18) ));
12864e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: bootStatus  Encryption AES XTS     %x\n", (controllerStatus->bootStatus & 0x800000 ) ? 1 : 0 ));
12874e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: bootStatus  Encryption Engine Stat 0x%x\n", ((controllerStatus->bootStatus & 0xFF000000 ) >> SHIFT24)  ));
12884e1bc9a0SAchim Leubner 
12894e1bc9a0SAchim Leubner /*
12904e1bc9a0SAchim Leubner 
12914e1bc9a0SAchim Leubner Bit 0 : Active FW Image
12924e1bc9a0SAchim Leubner 0b: Primary Image
12934e1bc9a0SAchim Leubner 1b: Secondary Image
12944e1bc9a0SAchim Leubner 
12954e1bc9a0SAchim Leubner Bit 16-17 :  Encryption Capability
12964e1bc9a0SAchim Leubner 00: Not supported. Controller firmware version doesn't support encryption functionality.
12974e1bc9a0SAchim Leubner 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]).
12984e1bc9a0SAchim Leubner 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]).
12994e1bc9a0SAchim Leubner 11: Enabled. Encryption functionality is enabled and fully functional.
13004e1bc9a0SAchim Leubner Bit 18-21 : Encryption Current Security Mode
13014e1bc9a0SAchim Leubner 0000: Security Mode Factory
13024e1bc9a0SAchim Leubner 0001: Security Mode A
13034e1bc9a0SAchim Leubner 0010: Security Mode B
13044e1bc9a0SAchim Leubner All other values are reserved.
13054e1bc9a0SAchim Leubner Bit22: Reserved
13064e1bc9a0SAchim Leubner Bit 23 : Encryption AES XTS Enabled
13074e1bc9a0SAchim Leubner 0: AES XTS is disabled.
13084e1bc9a0SAchim Leubner 1: AES XTS is enabled
13094e1bc9a0SAchim Leubner Bit 24-31 : Encryption Engine Status
13104e1bc9a0SAchim Leubner */
13114e1bc9a0SAchim Leubner 
13124e1bc9a0SAchim Leubner 
13134e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: bootComponentState[0] RAAE_STATE   0x%x\n", controllerStatus->bootComponentState[0]));
13144e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: bootComponentState[1] IOP0_STATE   0x%x\n", controllerStatus->bootComponentState[1]));
13154e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: bootComponentState[2] IOP1_STATE   0x%x\n", controllerStatus->bootComponentState[2]));
13164e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: bootComponentState[3] BOOTLDR_     0x%x\n", controllerStatus->bootComponentState[3]));
13174e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: bootComponentState[4] ILA State    0x%x\n", controllerStatus->bootComponentState[4]));
13184e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: bootComponentState[5]              0x%x\n", controllerStatus->bootComponentState[5]));
13194e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: bootComponentState[6]              0x%x\n", controllerStatus->bootComponentState[6]));
13204e1bc9a0SAchim Leubner   SA_DBG1(("saGetControllerStatus: bootComponentState[7]              0x%x\n", controllerStatus->bootComponentState[7]));
13214e1bc9a0SAchim Leubner 
13224e1bc9a0SAchim Leubner   if (agNULL != saRoot)
13234e1bc9a0SAchim Leubner   {
13244e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6f");
13254e1bc9a0SAchim Leubner   }
13264e1bc9a0SAchim Leubner 
13274e1bc9a0SAchim Leubner   return ret;
13284e1bc9a0SAchim Leubner }
13294e1bc9a0SAchim Leubner 
13304e1bc9a0SAchim Leubner /******************************************************************************/
13314e1bc9a0SAchim Leubner /*! \brief SPC Get Controller Event Log Information Command
13324e1bc9a0SAchim Leubner  *
13334e1bc9a0SAchim Leubner  *  This command sends Get Controller Event Log Information Command to SPC.
13344e1bc9a0SAchim Leubner  *
13354e1bc9a0SAchim Leubner  *  \param agRoot       Handles for this instance of SAS/SATA LL
13364e1bc9a0SAchim Leubner  *  \param eventLogInfo event log information
13374e1bc9a0SAchim Leubner  *
13384e1bc9a0SAchim Leubner  *  \return If the MPI command is sent to SPC successfully
13394e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
13404e1bc9a0SAchim Leubner  *          - \e AGSA_RC_FAILURE the MPI command is failure
13414e1bc9a0SAchim Leubner  *
13424e1bc9a0SAchim Leubner  */
13434e1bc9a0SAchim Leubner /*******************************************************************************/
saGetControllerEventLogInfo(agsaRoot_t * agRoot,agsaControllerEventLog_t * eventLogInfo)13444e1bc9a0SAchim Leubner GLOBAL bit32 saGetControllerEventLogInfo(
13454e1bc9a0SAchim Leubner                         agsaRoot_t                *agRoot,
13464e1bc9a0SAchim Leubner                         agsaControllerEventLog_t  *eventLogInfo
13474e1bc9a0SAchim Leubner                         )
13484e1bc9a0SAchim Leubner {
13494e1bc9a0SAchim Leubner   bit32 ret           = AGSA_RC_SUCCESS;
13504e1bc9a0SAchim Leubner   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
13514e1bc9a0SAchim Leubner 
13524e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"6g");
13534e1bc9a0SAchim Leubner 
13544e1bc9a0SAchim Leubner   /* sanity check */
13554e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
13564e1bc9a0SAchim Leubner 
13574e1bc9a0SAchim Leubner   eventLogInfo->eventLog1 = saRoot->memoryAllocated.agMemory[MPI_MEM_INDEX + MPI_EVENTLOG_INDEX];
13584e1bc9a0SAchim Leubner   eventLogInfo->eventLog1Option = saRoot->mainConfigTable.eventLogOption;
13594e1bc9a0SAchim Leubner   eventLogInfo->eventLog2 = saRoot->memoryAllocated.agMemory[MPI_MEM_INDEX + MPI_IOP_EVENTLOG_INDEX];
13604e1bc9a0SAchim Leubner   eventLogInfo->eventLog2Option = saRoot->mainConfigTable.IOPeventLogOption;
13614e1bc9a0SAchim Leubner 
13624e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6g");
13634e1bc9a0SAchim Leubner 
13644e1bc9a0SAchim Leubner   return ret;
13654e1bc9a0SAchim Leubner }
13664e1bc9a0SAchim Leubner 
13674e1bc9a0SAchim Leubner /******************************************************************************/
13684e1bc9a0SAchim Leubner /*! \brief SPC Set GPIO Event Setup Command
13694e1bc9a0SAchim Leubner  *
13704e1bc9a0SAchim Leubner  *  This command sends GPIO Event Setup Command to SPC.
13714e1bc9a0SAchim Leubner  *
13724e1bc9a0SAchim Leubner  *  \param agRoot             Handles for this instance of SAS/SATA LL
13734e1bc9a0SAchim Leubner  *  \param agsaContext        Context of this command
13744e1bc9a0SAchim Leubner  *  \param queueNum           Queue number of inbound/outbound queue
13754e1bc9a0SAchim Leubner  *  \param gpioEventSetupInfo Pointer of Event Setup Information structure
13764e1bc9a0SAchim Leubner  *
13774e1bc9a0SAchim Leubner  *  \return If the MPI command is sent to SPC successfully
13784e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
13794e1bc9a0SAchim Leubner  *          - \e AGSA_RC_FAILURE the MPI command is failure
13804e1bc9a0SAchim Leubner  *
13814e1bc9a0SAchim Leubner  */
13824e1bc9a0SAchim Leubner /*******************************************************************************/
saGpioEventSetup(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,agsaGpioEventSetupInfo_t * gpioEventSetupInfo)13834e1bc9a0SAchim Leubner GLOBAL bit32 saGpioEventSetup(
13844e1bc9a0SAchim Leubner                         agsaRoot_t                *agRoot,
13854e1bc9a0SAchim Leubner                         agsaContext_t             *agContext,
13864e1bc9a0SAchim Leubner                         bit32                     queueNum,
13874e1bc9a0SAchim Leubner                         agsaGpioEventSetupInfo_t  *gpioEventSetupInfo
13884e1bc9a0SAchim Leubner                         )
13894e1bc9a0SAchim Leubner {
13904e1bc9a0SAchim Leubner   bit32 ret           = AGSA_RC_SUCCESS;
13914e1bc9a0SAchim Leubner   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
13924e1bc9a0SAchim Leubner   agsaIORequestDesc_t *pRequest;
13934e1bc9a0SAchim Leubner   agsaGPIOCmd_t       payload;
13944e1bc9a0SAchim Leubner 
13954e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"6h");
13964e1bc9a0SAchim Leubner 
13974e1bc9a0SAchim Leubner   /* sanity check */
13984e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
13994e1bc9a0SAchim Leubner 
14004e1bc9a0SAchim Leubner   /* Get request from free IORequests */
14014e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
14024e1bc9a0SAchim Leubner   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
14034e1bc9a0SAchim Leubner 
14044e1bc9a0SAchim Leubner   /* If no LL Control request entry available */
14054e1bc9a0SAchim Leubner   if ( agNULL == pRequest )
14064e1bc9a0SAchim Leubner   {
14074e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
14084e1bc9a0SAchim Leubner     SA_DBG1(("saGpioEventSetup, No request from free list\n" ));
14094e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6h");
14104e1bc9a0SAchim Leubner     return AGSA_RC_BUSY;
14114e1bc9a0SAchim Leubner   }
14124e1bc9a0SAchim Leubner   /* If LL Control request entry avaliable */
14134e1bc9a0SAchim Leubner   else
14144e1bc9a0SAchim Leubner   {
14154e1bc9a0SAchim Leubner     /* Remove the request from free list */
14164e1bc9a0SAchim Leubner     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
14174e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
14184e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
14194e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].agContext = agContext;
14204e1bc9a0SAchim Leubner     pRequest->valid = agTRUE;
14214e1bc9a0SAchim Leubner 
14224e1bc9a0SAchim Leubner     /* set payload to zeros */
14234e1bc9a0SAchim Leubner     si_memset(&payload, 0, sizeof(agsaGPIOCmd_t));
14244e1bc9a0SAchim Leubner     /* build IOMB command and send to SPC */
14254e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, tag), pRequest->HTag);
14264e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, eOBIDGeGsGrGw), GPIO_GE_BIT);
14274e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, GPIEVChange), gpioEventSetupInfo->gpioEventLevel);
14284e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, GPIEVFall), gpioEventSetupInfo->gpioEventFallingEdge);
14294e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, GPIEVRise), gpioEventSetupInfo->gpioEventRisingEdge);
14304e1bc9a0SAchim Leubner     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GPIO, IOMB_SIZE64, queueNum);
14314e1bc9a0SAchim Leubner     if (AGSA_RC_SUCCESS != ret)
14324e1bc9a0SAchim Leubner     {
14334e1bc9a0SAchim Leubner       /* remove the request from IOMap */
14344e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
14354e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
14364e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
14374e1bc9a0SAchim Leubner       pRequest->valid = agFALSE;
14384e1bc9a0SAchim Leubner 
14394e1bc9a0SAchim Leubner       /* return the request to free pool */
14404e1bc9a0SAchim Leubner       if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
14414e1bc9a0SAchim Leubner       {
14424e1bc9a0SAchim Leubner         SA_DBG1(("saGpioEventSetup: saving pRequest (%p) for later use\n", pRequest));
14434e1bc9a0SAchim Leubner         saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
14444e1bc9a0SAchim Leubner       }
14454e1bc9a0SAchim Leubner       else
14464e1bc9a0SAchim Leubner       {
14474e1bc9a0SAchim Leubner         /* return the request to free pool */
14484e1bc9a0SAchim Leubner         saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
14494e1bc9a0SAchim Leubner       }
14504e1bc9a0SAchim Leubner       SA_DBG1(("saGpioEventSetup, sending IOMB failed\n" ));
14514e1bc9a0SAchim Leubner     }
14524e1bc9a0SAchim Leubner   }
14534e1bc9a0SAchim Leubner 
14544e1bc9a0SAchim Leubner   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
14554e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6h");
14564e1bc9a0SAchim Leubner 
14574e1bc9a0SAchim Leubner   return ret;
14584e1bc9a0SAchim Leubner }
14594e1bc9a0SAchim Leubner 
14604e1bc9a0SAchim Leubner /******************************************************************************/
14614e1bc9a0SAchim Leubner /*! \brief SPC Set GPIO Pin Setup Command
14624e1bc9a0SAchim Leubner  *
14634e1bc9a0SAchim Leubner  *  This command sends GPIO Pin Setup Command to SPC.
14644e1bc9a0SAchim Leubner  *
14654e1bc9a0SAchim Leubner  *  \param agRoot             Handles for this instance of SAS/SATA LL
14664e1bc9a0SAchim Leubner  *  \param agsaContext        Context of this command
14674e1bc9a0SAchim Leubner  *  \param queueNum           Queue number of inbound/outbound queue
14684e1bc9a0SAchim Leubner  *  \param gpioPinSetupInfo   Pointer of Event Setup Information structure
14694e1bc9a0SAchim Leubner  *
14704e1bc9a0SAchim Leubner  *  \return If the MPI command is sent to SPC successfully
14714e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
14724e1bc9a0SAchim Leubner  *          - \e AGSA_RC_FAILURE the MPI command is failure
14734e1bc9a0SAchim Leubner  *
14744e1bc9a0SAchim Leubner  */
14754e1bc9a0SAchim Leubner /*******************************************************************************/
saGpioPinSetup(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,agsaGpioPinSetupInfo_t * gpioPinSetupInfo)14764e1bc9a0SAchim Leubner GLOBAL bit32 saGpioPinSetup(
14774e1bc9a0SAchim Leubner                         agsaRoot_t                *agRoot,
14784e1bc9a0SAchim Leubner                         agsaContext_t             *agContext,
14794e1bc9a0SAchim Leubner                         bit32                     queueNum,
14804e1bc9a0SAchim Leubner                         agsaGpioPinSetupInfo_t    *gpioPinSetupInfo
14814e1bc9a0SAchim Leubner                         )
14824e1bc9a0SAchim Leubner {
14834e1bc9a0SAchim Leubner   bit32 ret           = AGSA_RC_SUCCESS;
14844e1bc9a0SAchim Leubner   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
14854e1bc9a0SAchim Leubner   agsaIORequestDesc_t *pRequest;
14864e1bc9a0SAchim Leubner   agsaGPIOCmd_t       payload;
14874e1bc9a0SAchim Leubner 
14884e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"6i");
14894e1bc9a0SAchim Leubner 
14904e1bc9a0SAchim Leubner   /* sanity check */
14914e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
14924e1bc9a0SAchim Leubner 
14934e1bc9a0SAchim Leubner   /* Get request from free IORequests */
14944e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
14954e1bc9a0SAchim Leubner   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
14964e1bc9a0SAchim Leubner 
14974e1bc9a0SAchim Leubner   /* If no LL Control request entry available */
14984e1bc9a0SAchim Leubner   if ( agNULL == pRequest )
14994e1bc9a0SAchim Leubner   {
15004e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
15014e1bc9a0SAchim Leubner     SA_DBG1(("saGpioPinSetup, No request from free list\n" ));
15024e1bc9a0SAchim Leubner     return AGSA_RC_BUSY;
15034e1bc9a0SAchim Leubner   }
15044e1bc9a0SAchim Leubner   /* If LL Control request entry avaliable */
15054e1bc9a0SAchim Leubner   else
15064e1bc9a0SAchim Leubner   {
15074e1bc9a0SAchim Leubner     /* Remove the request from free list */
15084e1bc9a0SAchim Leubner     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
15094e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
15104e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
15114e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].agContext = agContext;
15124e1bc9a0SAchim Leubner     pRequest->valid = agTRUE;
15134e1bc9a0SAchim Leubner 
15144e1bc9a0SAchim Leubner     /* set payload to zeros */
15154e1bc9a0SAchim Leubner     si_memset(&payload, 0, sizeof(agsaGPIOCmd_t));
15164e1bc9a0SAchim Leubner     /* build IOMB command and send to SPC */
15174e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, tag), pRequest->HTag);
15184e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, eOBIDGeGsGrGw), GPIO_GS_BIT);
15194e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, GpioIe), gpioPinSetupInfo->gpioInputEnabled);
15204e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, OT11_0), gpioPinSetupInfo->gpioTypePart1);
15214e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, OT19_12), gpioPinSetupInfo->gpioTypePart2);
15224e1bc9a0SAchim Leubner     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GPIO, IOMB_SIZE64, queueNum);
15234e1bc9a0SAchim Leubner     if (AGSA_RC_SUCCESS != ret)
15244e1bc9a0SAchim Leubner     {
15254e1bc9a0SAchim Leubner       /* remove the request from IOMap */
15264e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
15274e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
15284e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
15294e1bc9a0SAchim Leubner       pRequest->valid = agFALSE;
15304e1bc9a0SAchim Leubner       /* return the request to free pool */
15314e1bc9a0SAchim Leubner       if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
15324e1bc9a0SAchim Leubner       {
15334e1bc9a0SAchim Leubner         SA_DBG1(("saGpioPinSetup: saving pRequest (%p) for later use\n", pRequest));
15344e1bc9a0SAchim Leubner         saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
15354e1bc9a0SAchim Leubner       }
15364e1bc9a0SAchim Leubner       else
15374e1bc9a0SAchim Leubner       {
15384e1bc9a0SAchim Leubner         /* return the request to free pool */
15394e1bc9a0SAchim Leubner         saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
15404e1bc9a0SAchim Leubner       }
15414e1bc9a0SAchim Leubner       SA_DBG1(("saGpioPinSetup, sending IOMB failed\n" ));
15424e1bc9a0SAchim Leubner     }
15434e1bc9a0SAchim Leubner   }
15444e1bc9a0SAchim Leubner 
15454e1bc9a0SAchim Leubner   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
15464e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6i");
15474e1bc9a0SAchim Leubner 
15484e1bc9a0SAchim Leubner   return ret;
15494e1bc9a0SAchim Leubner }
15504e1bc9a0SAchim Leubner 
15514e1bc9a0SAchim Leubner /******************************************************************************/
15524e1bc9a0SAchim Leubner /*! \brief SPC GPIO Read Command
15534e1bc9a0SAchim Leubner  *
15544e1bc9a0SAchim Leubner  *  This command sends GPIO Read Command to SPC.
15554e1bc9a0SAchim Leubner  *
15564e1bc9a0SAchim Leubner  *  \param agRoot       Handles for this instance of SAS/SATA LL
15574e1bc9a0SAchim Leubner  *  \param agsaContext  Context of this command
15584e1bc9a0SAchim Leubner  *  \param queueNum     Queue number of inbound/outbound queue
15594e1bc9a0SAchim Leubner  *
15604e1bc9a0SAchim Leubner  *  \return If the MPI command is sent to SPC successfully
15614e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
15624e1bc9a0SAchim Leubner  *          - \e AGSA_RC_FAILURE the MPI command is failure
15634e1bc9a0SAchim Leubner  *
15644e1bc9a0SAchim Leubner  */
15654e1bc9a0SAchim Leubner /*******************************************************************************/
saGpioRead(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum)15664e1bc9a0SAchim Leubner GLOBAL bit32 saGpioRead(
15674e1bc9a0SAchim Leubner                         agsaRoot_t                *agRoot,
15684e1bc9a0SAchim Leubner                         agsaContext_t             *agContext,
15694e1bc9a0SAchim Leubner                         bit32                     queueNum
15704e1bc9a0SAchim Leubner                         )
15714e1bc9a0SAchim Leubner {
15724e1bc9a0SAchim Leubner   bit32 ret           = AGSA_RC_SUCCESS;
15734e1bc9a0SAchim Leubner   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
15744e1bc9a0SAchim Leubner   agsaIORequestDesc_t *pRequest;
15754e1bc9a0SAchim Leubner   agsaGPIOCmd_t       payload;
15764e1bc9a0SAchim Leubner 
15774e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"6j");
15784e1bc9a0SAchim Leubner 
15794e1bc9a0SAchim Leubner   /* sanity check */
15804e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
15814e1bc9a0SAchim Leubner 
15824e1bc9a0SAchim Leubner   /* Get request from free IORequests */
15834e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
15844e1bc9a0SAchim Leubner   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
15854e1bc9a0SAchim Leubner 
15864e1bc9a0SAchim Leubner   /* If no LL Control request entry available */
15874e1bc9a0SAchim Leubner   if ( agNULL == pRequest )
15884e1bc9a0SAchim Leubner   {
15894e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
15904e1bc9a0SAchim Leubner     SA_DBG1(("saGpioRead, No request from free list\n" ));
15914e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6j");
15924e1bc9a0SAchim Leubner     return AGSA_RC_BUSY;
15934e1bc9a0SAchim Leubner   }
15944e1bc9a0SAchim Leubner   /* If LL Control request entry avaliable */
15954e1bc9a0SAchim Leubner   else
15964e1bc9a0SAchim Leubner   {
15974e1bc9a0SAchim Leubner     /* Remove the request from free list */
15984e1bc9a0SAchim Leubner     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
15994e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
16004e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
16014e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].agContext = agContext;
16024e1bc9a0SAchim Leubner     pRequest->valid = agTRUE;
16034e1bc9a0SAchim Leubner 
16044e1bc9a0SAchim Leubner     /* set payload to zeros */
16054e1bc9a0SAchim Leubner     si_memset(&payload, 0, sizeof(agsaGPIOCmd_t));
16064e1bc9a0SAchim Leubner     /* build IOMB command and send to SPC */
16074e1bc9a0SAchim Leubner     /* set GR bit */
16084e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, tag), pRequest->HTag);
16094e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, eOBIDGeGsGrGw), GPIO_GR_BIT);
16104e1bc9a0SAchim Leubner     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GPIO, IOMB_SIZE64, queueNum);
16114e1bc9a0SAchim Leubner     if (AGSA_RC_SUCCESS != ret)
16124e1bc9a0SAchim Leubner     {
16134e1bc9a0SAchim Leubner       /* remove the request from IOMap */
16144e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
16154e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
16164e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
16174e1bc9a0SAchim Leubner       pRequest->valid = agFALSE;
16184e1bc9a0SAchim Leubner       /* return the request to free pool */
16194e1bc9a0SAchim Leubner       if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
16204e1bc9a0SAchim Leubner       {
16214e1bc9a0SAchim Leubner         SA_DBG1(("saGpioRead: saving pRequest (%p) for later use\n", pRequest));
16224e1bc9a0SAchim Leubner         saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
16234e1bc9a0SAchim Leubner       }
16244e1bc9a0SAchim Leubner       else
16254e1bc9a0SAchim Leubner       {
16264e1bc9a0SAchim Leubner         /* return the request to free pool */
16274e1bc9a0SAchim Leubner         saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
16284e1bc9a0SAchim Leubner       }
16294e1bc9a0SAchim Leubner       SA_DBG1(("saGpioRead, sending IOMB failed\n" ));
16304e1bc9a0SAchim Leubner     }
16314e1bc9a0SAchim Leubner   }
16324e1bc9a0SAchim Leubner   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
16334e1bc9a0SAchim Leubner 
16344e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6j");
16354e1bc9a0SAchim Leubner 
16364e1bc9a0SAchim Leubner   return ret;
16374e1bc9a0SAchim Leubner }
16384e1bc9a0SAchim Leubner 
16394e1bc9a0SAchim Leubner /******************************************************************************/
16404e1bc9a0SAchim Leubner /*! \brief SPC GPIO Write Command
16414e1bc9a0SAchim Leubner  *
16424e1bc9a0SAchim Leubner  *  This command sends GPIO Write Command to SPC.
16434e1bc9a0SAchim Leubner  *
16444e1bc9a0SAchim Leubner  *  \param agRoot         Handles for this instance of SAS/SATA LL
16454e1bc9a0SAchim Leubner  *  \param agsaContext    Context of this command
16464e1bc9a0SAchim Leubner  *  \param queueNum       Queue number of inbound/outbound queue
16474e1bc9a0SAchim Leubner  *  \param gpioWriteMask  GPIO Write Mask
16484e1bc9a0SAchim Leubner  *  \param gpioWriteValue GPIO Write Value
16494e1bc9a0SAchim Leubner  *
16504e1bc9a0SAchim Leubner  *  \return If the MPI command is sent to SPC successfully
16514e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
16524e1bc9a0SAchim Leubner  *          - \e AGSA_RC_FAILURE the MPI command is failure
16534e1bc9a0SAchim Leubner  *
16544e1bc9a0SAchim Leubner  */
16554e1bc9a0SAchim Leubner /*******************************************************************************/
saGpioWrite(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,bit32 gpioWriteMask,bit32 gpioWriteValue)16564e1bc9a0SAchim Leubner GLOBAL bit32 saGpioWrite(
16574e1bc9a0SAchim Leubner                         agsaRoot_t                *agRoot,
16584e1bc9a0SAchim Leubner                         agsaContext_t             *agContext,
16594e1bc9a0SAchim Leubner                         bit32                     queueNum,
16604e1bc9a0SAchim Leubner                         bit32                     gpioWriteMask,
16614e1bc9a0SAchim Leubner                         bit32                     gpioWriteValue
16624e1bc9a0SAchim Leubner                         )
16634e1bc9a0SAchim Leubner {
16644e1bc9a0SAchim Leubner   bit32 ret           = AGSA_RC_SUCCESS;
16654e1bc9a0SAchim Leubner   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
16664e1bc9a0SAchim Leubner   agsaIORequestDesc_t *pRequest;
16674e1bc9a0SAchim Leubner   agsaGPIOCmd_t       payload;
16684e1bc9a0SAchim Leubner 
16694e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"6k");
16704e1bc9a0SAchim Leubner 
16714e1bc9a0SAchim Leubner   /* sanity check */
16724e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
16734e1bc9a0SAchim Leubner 
16744e1bc9a0SAchim Leubner   /* Get request from free IORequests */
16754e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
16764e1bc9a0SAchim Leubner   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
16774e1bc9a0SAchim Leubner 
16784e1bc9a0SAchim Leubner   /* If no LL Control request entry available */
16794e1bc9a0SAchim Leubner   if ( agNULL == pRequest )
16804e1bc9a0SAchim Leubner   {
16814e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
16824e1bc9a0SAchim Leubner     SA_DBG1(("saGpioWrite, No request from free list\n" ));
16834e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6k");
16844e1bc9a0SAchim Leubner     return AGSA_RC_BUSY;
16854e1bc9a0SAchim Leubner   }
16864e1bc9a0SAchim Leubner   /* If LL Control request entry avaliable */
16874e1bc9a0SAchim Leubner   else
16884e1bc9a0SAchim Leubner   {
16894e1bc9a0SAchim Leubner     /* Remove the request from free list */
16904e1bc9a0SAchim Leubner     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
16914e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
16924e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
16934e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].agContext = agContext;
16944e1bc9a0SAchim Leubner     pRequest->valid = agTRUE;
16954e1bc9a0SAchim Leubner 
16964e1bc9a0SAchim Leubner     /* set payload to zeros */
16974e1bc9a0SAchim Leubner     si_memset(&payload, 0, sizeof(agsaGPIOCmd_t));
16984e1bc9a0SAchim Leubner     /* build IOMB command and send to SPC */
16994e1bc9a0SAchim Leubner     /* set GW bit */
17004e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, tag), pRequest->HTag);
17014e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, eOBIDGeGsGrGw), GPIO_GW_BIT);
17024e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, GpioWrMsk), gpioWriteMask);
17034e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, GpioWrVal), gpioWriteValue);
17044e1bc9a0SAchim Leubner     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GPIO, IOMB_SIZE64, queueNum);
17054e1bc9a0SAchim Leubner     if (AGSA_RC_SUCCESS != ret)
17064e1bc9a0SAchim Leubner     {
17074e1bc9a0SAchim Leubner       /* remove the request from IOMap */
17084e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
17094e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
17104e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
17114e1bc9a0SAchim Leubner       pRequest->valid = agFALSE;
17124e1bc9a0SAchim Leubner 
17134e1bc9a0SAchim Leubner       /* return the request to free pool */
17144e1bc9a0SAchim Leubner       if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
17154e1bc9a0SAchim Leubner       {
17164e1bc9a0SAchim Leubner         SA_DBG1(("saGpioWrite: saving pRequest (%p) for later use\n", pRequest));
17174e1bc9a0SAchim Leubner         saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
17184e1bc9a0SAchim Leubner       }
17194e1bc9a0SAchim Leubner       else
17204e1bc9a0SAchim Leubner       {
17214e1bc9a0SAchim Leubner         /* return the request to free pool */
17224e1bc9a0SAchim Leubner         saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
17234e1bc9a0SAchim Leubner       }
17244e1bc9a0SAchim Leubner       SA_DBG1(("saGpioWrite, sending IOMB failed\n" ));
17254e1bc9a0SAchim Leubner     }
17264e1bc9a0SAchim Leubner   }
17274e1bc9a0SAchim Leubner 
17284e1bc9a0SAchim Leubner   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
17294e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6k");
17304e1bc9a0SAchim Leubner 
17314e1bc9a0SAchim Leubner   return ret;
17324e1bc9a0SAchim Leubner }
17334e1bc9a0SAchim Leubner 
17344e1bc9a0SAchim Leubner /******************************************************************************/
17354e1bc9a0SAchim Leubner /*! \brief SPC SAS Diagnostic Execute Command
17364e1bc9a0SAchim Leubner  *
17374e1bc9a0SAchim Leubner  *  This command sends SAS Diagnostic Execute Command to SPC.
17384e1bc9a0SAchim Leubner  *
17394e1bc9a0SAchim Leubner  *  \param agRoot         Handles for this instance of SAS/SATA LL
17404e1bc9a0SAchim Leubner  *  \param agsaContext    Context of this command
17414e1bc9a0SAchim Leubner  *  \param queueNum       Queue number of inbound/outbound queue
17424e1bc9a0SAchim Leubner  *  \param diag           Pointer of SAS Diag Execute Structure
17434e1bc9a0SAchim Leubner  *
17444e1bc9a0SAchim Leubner  *  \return If the MPI command is sent to SPC successfully
17454e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
17464e1bc9a0SAchim Leubner  *          - \e AGSA_RC_FAILURE the MPI command is failure
17474e1bc9a0SAchim Leubner  *
17484e1bc9a0SAchim Leubner  */
17494e1bc9a0SAchim Leubner /*******************************************************************************/
saSASDiagExecute(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,agsaSASDiagExecute_t * diag)17504e1bc9a0SAchim Leubner GLOBAL bit32 saSASDiagExecute(
17514e1bc9a0SAchim Leubner                         agsaRoot_t              *agRoot,
17524e1bc9a0SAchim Leubner                         agsaContext_t           *agContext,
17534e1bc9a0SAchim Leubner                         bit32                    queueNum,
17544e1bc9a0SAchim Leubner                         agsaSASDiagExecute_t    *diag
17554e1bc9a0SAchim Leubner                         )
17564e1bc9a0SAchim Leubner {
17574e1bc9a0SAchim Leubner   bit32                     ret = AGSA_RC_SUCCESS;
17584e1bc9a0SAchim Leubner   agsaLLRoot_t             *saRoot = agNULL;
17594e1bc9a0SAchim Leubner   agsaIORequestDesc_t      *pRequest = agNULL;
17604e1bc9a0SAchim Leubner   bit32  payload[32];
17614e1bc9a0SAchim Leubner   /* sanity check */
17624e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
17634e1bc9a0SAchim Leubner 
17644e1bc9a0SAchim Leubner   saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
17654e1bc9a0SAchim Leubner   /* sanity check */
17664e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != saRoot), "");
17674e1bc9a0SAchim Leubner 
17684e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"6m");
17694e1bc9a0SAchim Leubner 
17704e1bc9a0SAchim Leubner   SA_DBG2(("saSASDiagExecute,command 0x%X\n", diag->command ));
17714e1bc9a0SAchim Leubner   SA_DBG2(("saSASDiagExecute,param0 0x%X\n", diag->param0 ));
17724e1bc9a0SAchim Leubner   SA_DBG2(("saSASDiagExecute,param2 0x%X\n", diag->param2 ));
17734e1bc9a0SAchim Leubner   SA_DBG2(("saSASDiagExecute,param3 0x%X\n", diag->param3 ));
17744e1bc9a0SAchim Leubner   SA_DBG2(("saSASDiagExecute,param4 0x%X\n", diag->param4 ));
17754e1bc9a0SAchim Leubner   SA_DBG2(("saSASDiagExecute,param5 0x%X\n", diag->param5 ));
17764e1bc9a0SAchim Leubner 
17774e1bc9a0SAchim Leubner   /* Get request from free IORequests */
17784e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
17794e1bc9a0SAchim Leubner   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
17804e1bc9a0SAchim Leubner 
17814e1bc9a0SAchim Leubner   /* If no LL Control request entry available */
17824e1bc9a0SAchim Leubner   if ( agNULL == pRequest )
17834e1bc9a0SAchim Leubner   {
17844e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
17854e1bc9a0SAchim Leubner     SA_DBG1(("saSASDiagExecute, No request from free list\n" ));
17864e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6m");
17874e1bc9a0SAchim Leubner     return AGSA_RC_BUSY;
17884e1bc9a0SAchim Leubner   }
17894e1bc9a0SAchim Leubner   /* If LL Control request entry avaliable */
17904e1bc9a0SAchim Leubner   else
17914e1bc9a0SAchim Leubner   {
17924e1bc9a0SAchim Leubner     /* Remove the request from free list */
17934e1bc9a0SAchim Leubner     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
17944e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
17954e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
17964e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].agContext = agContext;
17974e1bc9a0SAchim Leubner     pRequest->valid = agTRUE;
17984e1bc9a0SAchim Leubner     if(smIS_SPC(agRoot))
17994e1bc9a0SAchim Leubner     {
18004e1bc9a0SAchim Leubner       diag->param5 = 0; /* Reserved for SPC */
18014e1bc9a0SAchim Leubner     }
18024e1bc9a0SAchim Leubner 
18034e1bc9a0SAchim Leubner     /* set payload to zeros */
18044e1bc9a0SAchim Leubner     si_memset(&payload, 0, sizeof(payload));
18054e1bc9a0SAchim Leubner     /* set payload to zeros */
18064e1bc9a0SAchim Leubner     if(smIS_SPCV(agRoot))
18074e1bc9a0SAchim Leubner     {
18084e1bc9a0SAchim Leubner       /* build IOMB command and send to SPC */
18094e1bc9a0SAchim Leubner       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, tag),             pRequest->HTag);
18104e1bc9a0SAchim Leubner       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, CmdTypeDescPhyId),diag->command );
18114e1bc9a0SAchim Leubner       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, Pat1Pat2),        diag->param0 );
18124e1bc9a0SAchim Leubner       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, Threshold),       diag->param1 );
18134e1bc9a0SAchim Leubner       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, CodePatErrMsk),   diag->param2 );
18144e1bc9a0SAchim Leubner       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, Pmon),            diag->param3 );
18154e1bc9a0SAchim Leubner       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, PERF1CTL),        diag->param4 );
18164e1bc9a0SAchim Leubner       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, THRSHLD1),        diag->param5 );
18174e1bc9a0SAchim Leubner       ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SAS_DIAG_EXECUTE, IOMB_SIZE128, queueNum);
18184e1bc9a0SAchim Leubner     }
18194e1bc9a0SAchim Leubner     else
18204e1bc9a0SAchim Leubner     {
18214e1bc9a0SAchim Leubner       /* build IOMB command and send to SPC */
18224e1bc9a0SAchim Leubner       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_SASDiagExecuteCmd_t, tag),             pRequest->HTag);
18234e1bc9a0SAchim Leubner       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_SASDiagExecuteCmd_t, CmdTypeDescPhyId),diag->command );
18244e1bc9a0SAchim Leubner       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_SASDiagExecuteCmd_t, Pat1Pat2),        diag->param0 );
18254e1bc9a0SAchim Leubner       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_SASDiagExecuteCmd_t, Threshold),       diag->param1 );
18264e1bc9a0SAchim Leubner       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_SASDiagExecuteCmd_t, CodePatErrMsk),   diag->param2 );
18274e1bc9a0SAchim Leubner       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_SASDiagExecuteCmd_t, Pmon),            diag->param3 );
18284e1bc9a0SAchim Leubner       OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_SASDiagExecuteCmd_t, PERF1CTL),        diag->param4 );
18294e1bc9a0SAchim Leubner       ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SAS_DIAG_EXECUTE, IOMB_SIZE64, queueNum);
18304e1bc9a0SAchim Leubner     }
18314e1bc9a0SAchim Leubner     if (AGSA_RC_SUCCESS != ret)
18324e1bc9a0SAchim Leubner     {
18334e1bc9a0SAchim Leubner       /* remove the request from IOMap */
18344e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
18354e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
18364e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
18374e1bc9a0SAchim Leubner       pRequest->valid = agFALSE;
18384e1bc9a0SAchim Leubner 
18394e1bc9a0SAchim Leubner       /* return the request to free pool */
18404e1bc9a0SAchim Leubner       if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
18414e1bc9a0SAchim Leubner       {
18424e1bc9a0SAchim Leubner         SA_DBG1(("saSASDiagExecute: saving pRequest (%p) for later use\n", pRequest));
18434e1bc9a0SAchim Leubner         saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
18444e1bc9a0SAchim Leubner       }
18454e1bc9a0SAchim Leubner       else
18464e1bc9a0SAchim Leubner       {
18474e1bc9a0SAchim Leubner         /* return the request to free pool */
18484e1bc9a0SAchim Leubner         saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
18494e1bc9a0SAchim Leubner       }
18504e1bc9a0SAchim Leubner       SA_DBG1(("saSASDiagExecute, sending IOMB failed\n" ));
18514e1bc9a0SAchim Leubner       smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6m");
18524e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
18534e1bc9a0SAchim Leubner       return ret;
18544e1bc9a0SAchim Leubner     }
18554e1bc9a0SAchim Leubner   }
18564e1bc9a0SAchim Leubner 
18574e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "6m");
18584e1bc9a0SAchim Leubner   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
18594e1bc9a0SAchim Leubner   return ret;
18604e1bc9a0SAchim Leubner }
18614e1bc9a0SAchim Leubner 
18624e1bc9a0SAchim Leubner /******************************************************************************/
18634e1bc9a0SAchim Leubner /*! \brief SPC SAS Diagnostic Start/End Command
18644e1bc9a0SAchim Leubner  *
18654e1bc9a0SAchim Leubner  *  This command sends SAS Diagnostic Start/End Command to SPC.
18664e1bc9a0SAchim Leubner  *
18674e1bc9a0SAchim Leubner  *  \param agRoot         Handles for this instance of SAS/SATA LL
18684e1bc9a0SAchim Leubner  *  \param agsaContext    Context of this command
18694e1bc9a0SAchim Leubner  *  \param queueNum       Queue number of inbound/outbound queue
18704e1bc9a0SAchim Leubner  *  \param phyId          Phy ID
18714e1bc9a0SAchim Leubner  *  \param operation      Operation of SAS Diagnostic
18724e1bc9a0SAchim Leubner  *
18734e1bc9a0SAchim Leubner  *  \return If the MPI command is sent to SPC successfully
18744e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
18754e1bc9a0SAchim Leubner  *          - \e AGSA_RC_FAILURE the MPI command is failure
18764e1bc9a0SAchim Leubner  *
18774e1bc9a0SAchim Leubner  */
18784e1bc9a0SAchim Leubner /*******************************************************************************/
saSASDiagStartEnd(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,bit32 phyId,bit32 operation)18794e1bc9a0SAchim Leubner GLOBAL bit32 saSASDiagStartEnd(
18804e1bc9a0SAchim Leubner                         agsaRoot_t                *agRoot,
18814e1bc9a0SAchim Leubner                         agsaContext_t             *agContext,
18824e1bc9a0SAchim Leubner                         bit32                     queueNum,
18834e1bc9a0SAchim Leubner                         bit32                     phyId,
18844e1bc9a0SAchim Leubner                         bit32                     operation
18854e1bc9a0SAchim Leubner                         )
18864e1bc9a0SAchim Leubner {
18874e1bc9a0SAchim Leubner   bit32 ret                = AGSA_RC_SUCCESS;
18884e1bc9a0SAchim Leubner   agsaLLRoot_t             *saRoot;
18894e1bc9a0SAchim Leubner   agsaIORequestDesc_t      *pRequest;
18904e1bc9a0SAchim Leubner   agsaSASDiagStartEndCmd_t payload;
18914e1bc9a0SAchim Leubner 
18924e1bc9a0SAchim Leubner   /* sanity check */
18934e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
18944e1bc9a0SAchim Leubner   if (agRoot == agNULL)
18954e1bc9a0SAchim Leubner   {
18964e1bc9a0SAchim Leubner     SA_DBG1(("saSASDiagStartEnd: agRoot == agNULL\n"));
18974e1bc9a0SAchim Leubner     return AGSA_RC_FAILURE;
18984e1bc9a0SAchim Leubner   }
18994e1bc9a0SAchim Leubner   saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
19004e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != saRoot), "");
19014e1bc9a0SAchim Leubner   if (saRoot == agNULL)
19024e1bc9a0SAchim Leubner   {
19034e1bc9a0SAchim Leubner     SA_DBG1(("saSASDiagStartEnd: saRoot == agNULL\n"));
19044e1bc9a0SAchim Leubner     return AGSA_RC_FAILURE;
19054e1bc9a0SAchim Leubner   }
19064e1bc9a0SAchim Leubner 
19074e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"6n");
19084e1bc9a0SAchim Leubner 
19094e1bc9a0SAchim Leubner   SA_DBG3(("saSASDiagStartEnd, phyId 0x%x operation 0x%x\n",phyId,operation ));
19104e1bc9a0SAchim Leubner 
19114e1bc9a0SAchim Leubner   /* Get request from free IORequests */
19124e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
19134e1bc9a0SAchim Leubner   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
19144e1bc9a0SAchim Leubner 
19154e1bc9a0SAchim Leubner   /* If no LL Control request entry available */
19164e1bc9a0SAchim Leubner   if ( agNULL == pRequest )
19174e1bc9a0SAchim Leubner   {
19184e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
19194e1bc9a0SAchim Leubner     SA_DBG1(("saSASDiagStartEnd, No request from free list\n" ));
19204e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6n");
19214e1bc9a0SAchim Leubner     return AGSA_RC_BUSY;
19224e1bc9a0SAchim Leubner   }
19234e1bc9a0SAchim Leubner   /* If LL Control request entry avaliable */
19244e1bc9a0SAchim Leubner   else
19254e1bc9a0SAchim Leubner   {
19264e1bc9a0SAchim Leubner     /* Remove the request from free list */
19274e1bc9a0SAchim Leubner     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
19284e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
19294e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
19304e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].agContext = agContext;
19314e1bc9a0SAchim Leubner     pRequest->valid = agTRUE;
19324e1bc9a0SAchim Leubner 
19334e1bc9a0SAchim Leubner     /* set payload to zeros */
19344e1bc9a0SAchim Leubner     si_memset(&payload, 0, sizeof(agsaSASDiagStartEndCmd_t));
19354e1bc9a0SAchim Leubner     /* build IOMB command and send to SPC */
19364e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagStartEndCmd_t, tag), pRequest->HTag);
19374e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagStartEndCmd_t, OperationPhyId), ((phyId & SM_PHYID_MASK) | (operation << SHIFT8)));
19384e1bc9a0SAchim Leubner     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SAS_DIAG_MODE_START_END, IOMB_SIZE64, queueNum);
19394e1bc9a0SAchim Leubner     if (AGSA_RC_SUCCESS != ret)
19404e1bc9a0SAchim Leubner     {
19414e1bc9a0SAchim Leubner       /* remove the request from IOMap */
19424e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
19434e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
19444e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
19454e1bc9a0SAchim Leubner       pRequest->valid = agFALSE;
19464e1bc9a0SAchim Leubner 
19474e1bc9a0SAchim Leubner       /* return the request to free pool */
19484e1bc9a0SAchim Leubner       if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
19494e1bc9a0SAchim Leubner       {
19504e1bc9a0SAchim Leubner         SA_DBG1(("saSASDiagStartEnd: saving pRequest (%p) for later use\n", pRequest));
19514e1bc9a0SAchim Leubner         saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
19524e1bc9a0SAchim Leubner       }
19534e1bc9a0SAchim Leubner       else
19544e1bc9a0SAchim Leubner       {
19554e1bc9a0SAchim Leubner         /* return the request to free pool */
19564e1bc9a0SAchim Leubner         saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
19574e1bc9a0SAchim Leubner       }
19584e1bc9a0SAchim Leubner       SA_DBG1(("saSASDiagStartEnd, sending IOMB failed\n" ));
19594e1bc9a0SAchim Leubner     }
19604e1bc9a0SAchim Leubner   }
19614e1bc9a0SAchim Leubner 
19624e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6n");
19634e1bc9a0SAchim Leubner   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
19644e1bc9a0SAchim Leubner   return ret;
19654e1bc9a0SAchim Leubner }
19664e1bc9a0SAchim Leubner 
19674e1bc9a0SAchim Leubner /******************************************************************************/
19684e1bc9a0SAchim Leubner /*! \brief Initiate a GET TIME STAMP command
19694e1bc9a0SAchim Leubner  *
19704e1bc9a0SAchim Leubner  *  This function is called to initiate a Get Time Stamp command to the SPC.
19714e1bc9a0SAchim Leubner  *  The completion of this function is reported in ossaGetTimeStampCB().
19724e1bc9a0SAchim Leubner  *
19734e1bc9a0SAchim Leubner  *  \param agRoot      handles for this instance of SAS/SATA hardware
19744e1bc9a0SAchim Leubner  *  \param agContext   the context of this API
19754e1bc9a0SAchim Leubner  *  \param queueNum    queue number
19764e1bc9a0SAchim Leubner  *
19774e1bc9a0SAchim Leubner  *  \return
19784e1bc9a0SAchim Leubner  *          - SUCCESS or FAILURE
19794e1bc9a0SAchim Leubner  */
19804e1bc9a0SAchim Leubner /*******************************************************************************/
saGetTimeStamp(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum)19814e1bc9a0SAchim Leubner GLOBAL bit32 saGetTimeStamp(
19824e1bc9a0SAchim Leubner                       agsaRoot_t        *agRoot,
19834e1bc9a0SAchim Leubner                       agsaContext_t     *agContext,
19844e1bc9a0SAchim Leubner                       bit32             queueNum
19854e1bc9a0SAchim Leubner                       )
19864e1bc9a0SAchim Leubner {
19874e1bc9a0SAchim Leubner   agsaIORequestDesc_t   *pRequest;
19884e1bc9a0SAchim Leubner   agsaGetTimeStampCmd_t payload;
19894e1bc9a0SAchim Leubner   bit32                 ret = AGSA_RC_SUCCESS;
19904e1bc9a0SAchim Leubner   agsaLLRoot_t          *saRoot;
19914e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
19924e1bc9a0SAchim Leubner   if (agRoot == agNULL)
19934e1bc9a0SAchim Leubner   {
19944e1bc9a0SAchim Leubner     SA_DBG1(("saGetTimeStamp: agRoot == agNULL\n"));
19954e1bc9a0SAchim Leubner     return AGSA_RC_FAILURE;
19964e1bc9a0SAchim Leubner   }
19974e1bc9a0SAchim Leubner   saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
19984e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != saRoot), "");
19994e1bc9a0SAchim Leubner   if (saRoot == agNULL)
20004e1bc9a0SAchim Leubner   {
20014e1bc9a0SAchim Leubner     SA_DBG1(("saGetTimeStamp: saRoot == agNULL\n"));
20024e1bc9a0SAchim Leubner     return AGSA_RC_FAILURE;
20034e1bc9a0SAchim Leubner   }
20044e1bc9a0SAchim Leubner 
20054e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"6o");
20064e1bc9a0SAchim Leubner 
20074e1bc9a0SAchim Leubner   /* sanity check */
20084e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
20094e1bc9a0SAchim Leubner 
20104e1bc9a0SAchim Leubner   SA_DBG3(("saGetTimeStamp: agContext %p\n", agContext));
20114e1bc9a0SAchim Leubner 
20124e1bc9a0SAchim Leubner   /* Get request from free IORequests */
20134e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
20144e1bc9a0SAchim Leubner   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
20154e1bc9a0SAchim Leubner 
20164e1bc9a0SAchim Leubner   /* If no LL Control request entry available */
20174e1bc9a0SAchim Leubner   if ( agNULL == pRequest )
20184e1bc9a0SAchim Leubner   {
20194e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
20204e1bc9a0SAchim Leubner     SA_DBG1(("saGetTimeStamp, No request from free list\n" ));
20214e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6o");
20224e1bc9a0SAchim Leubner     return AGSA_RC_BUSY;
20234e1bc9a0SAchim Leubner   }
20244e1bc9a0SAchim Leubner   /* If LL Control request entry avaliable */
20254e1bc9a0SAchim Leubner   else
20264e1bc9a0SAchim Leubner   {
20274e1bc9a0SAchim Leubner     /* Remove the request from free list */
20284e1bc9a0SAchim Leubner     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
20294e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
20304e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
20314e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].agContext = agContext;
20324e1bc9a0SAchim Leubner     pRequest->valid = agTRUE;
20334e1bc9a0SAchim Leubner 
20344e1bc9a0SAchim Leubner     /* build IOMB command and send to SPC */
20354e1bc9a0SAchim Leubner     /* set payload to zeros */
20364e1bc9a0SAchim Leubner     si_memset(&payload, 0, sizeof(agsaGetTimeStampCmd_t));
20374e1bc9a0SAchim Leubner 
20384e1bc9a0SAchim Leubner     /* set tag */
20394e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetTimeStampCmd_t, tag), pRequest->HTag);
20404e1bc9a0SAchim Leubner 
20414e1bc9a0SAchim Leubner     /* build IOMB command and send to SPC */
20424e1bc9a0SAchim Leubner     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_TIME_STAMP, IOMB_SIZE64, queueNum);
20434e1bc9a0SAchim Leubner     if (AGSA_RC_SUCCESS != ret)
20444e1bc9a0SAchim Leubner     {
20454e1bc9a0SAchim Leubner       /* remove the request from IOMap */
20464e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
20474e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
20484e1bc9a0SAchim Leubner       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
20494e1bc9a0SAchim Leubner       pRequest->valid = agFALSE;
20504e1bc9a0SAchim Leubner 
20514e1bc9a0SAchim Leubner       /* return the request to free pool */
20524e1bc9a0SAchim Leubner       if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
20534e1bc9a0SAchim Leubner       {
20544e1bc9a0SAchim Leubner         SA_DBG1(("saGetTimeStamp: saving pRequest (%p) for later use\n", pRequest));
20554e1bc9a0SAchim Leubner         saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
20564e1bc9a0SAchim Leubner       }
20574e1bc9a0SAchim Leubner       else
20584e1bc9a0SAchim Leubner       {
20594e1bc9a0SAchim Leubner         /* return the request to free pool */
20604e1bc9a0SAchim Leubner         saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
20614e1bc9a0SAchim Leubner       }
20624e1bc9a0SAchim Leubner       SA_DBG1(("saGetTimeStamp, sending IOMB failed\n" ));
20634e1bc9a0SAchim Leubner     }
20644e1bc9a0SAchim Leubner   }
20654e1bc9a0SAchim Leubner 
20664e1bc9a0SAchim Leubner   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
20674e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6o");
20684e1bc9a0SAchim Leubner 
20694e1bc9a0SAchim Leubner   return ret;
20704e1bc9a0SAchim Leubner }
20714e1bc9a0SAchim Leubner 
20724e1bc9a0SAchim Leubner /******************************************************************************/
20734e1bc9a0SAchim Leubner /*! \brief Update IOMap Entry
20744e1bc9a0SAchim Leubner  *
20754e1bc9a0SAchim Leubner  *  This function is called to update certain fields of IOMap Entry
20764e1bc9a0SAchim Leubner  *
20774e1bc9a0SAchim Leubner  *  \param pIOMap       IOMap Entry
20784e1bc9a0SAchim Leubner  *  \param HTag         Host Tag
20794e1bc9a0SAchim Leubner  *  \param pRequest     Request
20804e1bc9a0SAchim Leubner  *  \parma agContext    Context of this API
20814e1bc9a0SAchim Leubner  *
20824e1bc9a0SAchim Leubner  *  \return             NA
20834e1bc9a0SAchim Leubner  */
20844e1bc9a0SAchim Leubner /*******************************************************************************/
saUpdateIOMap(agsaIOMap_t * pIOMap,bit32 HTag,agsaIORequestDesc_t * pRequest,agsaContext_t * agContext)20854e1bc9a0SAchim Leubner static void saUpdateIOMap(
20864e1bc9a0SAchim Leubner                         agsaIOMap_t         *pIOMap,
20874e1bc9a0SAchim Leubner                         bit32               HTag,
20884e1bc9a0SAchim Leubner                         agsaIORequestDesc_t *pRequest,
20894e1bc9a0SAchim Leubner                         agsaContext_t       *agContext
20904e1bc9a0SAchim Leubner                         )
20914e1bc9a0SAchim Leubner {
20924e1bc9a0SAchim Leubner   pIOMap->Tag = HTag;
20934e1bc9a0SAchim Leubner   pIOMap->IORequest = (void *)pRequest;
20944e1bc9a0SAchim Leubner   pIOMap->agContext = agContext;
20954e1bc9a0SAchim Leubner }
20964e1bc9a0SAchim Leubner 
20974e1bc9a0SAchim Leubner /******************************************************************************/
20984e1bc9a0SAchim Leubner /*! \brief Get a request from free pool
20994e1bc9a0SAchim Leubner  *
21004e1bc9a0SAchim Leubner  *  This function gets a request from free pool
21014e1bc9a0SAchim Leubner  *
21024e1bc9a0SAchim Leubner  *  \param agRoot       Handles for this instance of SAS/SATA LL
21034e1bc9a0SAchim Leubner  *  \param agsaContext  Context of this command
21044e1bc9a0SAchim Leubner  *
21054e1bc9a0SAchim Leubner  *  \return
21064e1bc9a0SAchim Leubner  *          - \e Pointer to request, in case of success
21074e1bc9a0SAchim Leubner  *          - \e NULL, in case of failure
21084e1bc9a0SAchim Leubner  *
21094e1bc9a0SAchim Leubner  */
21104e1bc9a0SAchim Leubner /*******************************************************************************/
saGetRequestFromFreePool(agsaRoot_t * agRoot,agsaContext_t * agContext)21114e1bc9a0SAchim Leubner agsaIORequestDesc_t* saGetRequestFromFreePool(
21124e1bc9a0SAchim Leubner                                             agsaRoot_t      *agRoot,
21134e1bc9a0SAchim Leubner                                             agsaContext_t   *agContext
21144e1bc9a0SAchim Leubner                                             )
21154e1bc9a0SAchim Leubner {
21164e1bc9a0SAchim Leubner   agsaLLRoot_t          *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
21174e1bc9a0SAchim Leubner   agsaIORequestDesc_t   *pRequest = agNULL;
21184e1bc9a0SAchim Leubner 
21194e1bc9a0SAchim Leubner   /* Acquire LL_IOREQ_LOCKEQ_LOCK */
21204e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
21214e1bc9a0SAchim Leubner 
21224e1bc9a0SAchim Leubner   /* Get request from free IORequests */
21234e1bc9a0SAchim Leubner   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
21244e1bc9a0SAchim Leubner   if (pRequest != agNULL)
21254e1bc9a0SAchim Leubner   {
21264e1bc9a0SAchim Leubner     /* Remove the request from free list */
21274e1bc9a0SAchim Leubner     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
21284e1bc9a0SAchim Leubner 
21294e1bc9a0SAchim Leubner     /* Release LL_IOREQ_LOCKEQ_LOCK */
21304e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
21314e1bc9a0SAchim Leubner 
21324e1bc9a0SAchim Leubner     /* Add the request to IOMap */
21334e1bc9a0SAchim Leubner     saUpdateIOMap(&saRoot->IOMap[pRequest->HTag], pRequest->HTag, pRequest, agContext);
21344e1bc9a0SAchim Leubner     pRequest->valid = agTRUE;
21354e1bc9a0SAchim Leubner   }
21364e1bc9a0SAchim Leubner   else
21374e1bc9a0SAchim Leubner   {
21384e1bc9a0SAchim Leubner     /* Release LL_IOREQ_LOCKEQ_LOCK */
21394e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
21404e1bc9a0SAchim Leubner   }
21414e1bc9a0SAchim Leubner 
21424e1bc9a0SAchim Leubner   return pRequest;
21434e1bc9a0SAchim Leubner }
21444e1bc9a0SAchim Leubner 
21454e1bc9a0SAchim Leubner /******************************************************************************/
21464e1bc9a0SAchim Leubner /*! \brief Return request to free pool
21474e1bc9a0SAchim Leubner  *
21484e1bc9a0SAchim Leubner  *  This function returns the request to free pool
21494e1bc9a0SAchim Leubner  *
21504e1bc9a0SAchim Leubner  *  \param agRoot       Handles for this instance of SAS/SATA LL
21514e1bc9a0SAchim Leubner  *  \param pRequest     Request to be returned
21524e1bc9a0SAchim Leubner  *
21534e1bc9a0SAchim Leubner  *  \return             NA
21544e1bc9a0SAchim Leubner  *
21554e1bc9a0SAchim Leubner  */
21564e1bc9a0SAchim Leubner /*******************************************************************************/
saReturnRequestToFreePool(agsaRoot_t * agRoot,agsaIORequestDesc_t * pRequest)21574e1bc9a0SAchim Leubner void saReturnRequestToFreePool(
21584e1bc9a0SAchim Leubner                             agsaRoot_t          *agRoot,
21594e1bc9a0SAchim Leubner                             agsaIORequestDesc_t *pRequest
21604e1bc9a0SAchim Leubner                             )
21614e1bc9a0SAchim Leubner {
21624e1bc9a0SAchim Leubner   agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
21634e1bc9a0SAchim Leubner 
21644e1bc9a0SAchim Leubner   SA_ASSERT((pRequest->valid), "pRequest->valid");
21654e1bc9a0SAchim Leubner 
21664e1bc9a0SAchim Leubner   /* Remove the request from IOMap */
21674e1bc9a0SAchim Leubner   saUpdateIOMap(&saRoot->IOMap[pRequest->HTag], MARK_OFF, agNULL, agNULL);
21684e1bc9a0SAchim Leubner   pRequest->valid = agFALSE;
21694e1bc9a0SAchim Leubner 
21704e1bc9a0SAchim Leubner   /* Acquire LL_IOREQ_LOCKEQ_LOCK */
21714e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
21724e1bc9a0SAchim Leubner 
21734e1bc9a0SAchim Leubner   if (saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
21744e1bc9a0SAchim Leubner   {
21754e1bc9a0SAchim Leubner     SA_DBG1(("saReturnRequestToFreePool: saving pRequest (%p) for later use\n", pRequest));
21764e1bc9a0SAchim Leubner     saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
21774e1bc9a0SAchim Leubner   }
21784e1bc9a0SAchim Leubner   else
21794e1bc9a0SAchim Leubner   {
21804e1bc9a0SAchim Leubner     /* Return the request to free pool */
21814e1bc9a0SAchim Leubner     saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
21824e1bc9a0SAchim Leubner   }
21834e1bc9a0SAchim Leubner 
21844e1bc9a0SAchim Leubner   /* Release LL_IOREQ_LOCKEQ_LOCK */
21854e1bc9a0SAchim Leubner   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
21864e1bc9a0SAchim Leubner }
21874e1bc9a0SAchim Leubner /******************************************************************************/
21884e1bc9a0SAchim Leubner /*! \brief Initiate a serial GPIO command
21894e1bc9a0SAchim Leubner  *
21904e1bc9a0SAchim Leubner  *  This function is called to initiate a serial GPIO command to the SPC.
21914e1bc9a0SAchim Leubner  *  The completion of this function is reported in ossaSgpioCB().
21924e1bc9a0SAchim Leubner  *
21934e1bc9a0SAchim Leubner  *  \param agRoot      handles for this instance of SAS/SATA hardware
21944e1bc9a0SAchim Leubner  *  \param agContext   the context of this API
21954e1bc9a0SAchim Leubner  *  \param queueNum    queue number
21964e1bc9a0SAchim Leubner  *  \param pSGpioReq   Pointer to the serial GPIO fields
21974e1bc9a0SAchim Leubner  *
21984e1bc9a0SAchim Leubner  *  \return
21994e1bc9a0SAchim Leubner  *          - SUCCESS or FAILURE
22004e1bc9a0SAchim Leubner  */
22014e1bc9a0SAchim Leubner /*******************************************************************************/
saSgpio(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,agsaSGpioReqResponse_t * pSGpioReq)22024e1bc9a0SAchim Leubner GLOBAL bit32 saSgpio(
22034e1bc9a0SAchim Leubner                 agsaRoot_t              *agRoot,
22044e1bc9a0SAchim Leubner                 agsaContext_t           *agContext,
22054e1bc9a0SAchim Leubner                 bit32                   queueNum,
22064e1bc9a0SAchim Leubner                 agsaSGpioReqResponse_t  *pSGpioReq
22074e1bc9a0SAchim Leubner                 )
22084e1bc9a0SAchim Leubner {
22094e1bc9a0SAchim Leubner   bit32                 i;
22104e1bc9a0SAchim Leubner   agsaIORequestDesc_t   *pRequest = agNULL;
22114e1bc9a0SAchim Leubner   agsaSGpioCmd_t        payload = {0};
22124e1bc9a0SAchim Leubner   bit32                 ret = AGSA_RC_BUSY;
22134e1bc9a0SAchim Leubner 
22144e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"6t");
22154e1bc9a0SAchim Leubner 
22164e1bc9a0SAchim Leubner   /* Sanity check */
22174e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
22184e1bc9a0SAchim Leubner 
22194e1bc9a0SAchim Leubner   SA_DBG3(("saSgpio: agContext %p\n", agContext));
22204e1bc9a0SAchim Leubner 
22214e1bc9a0SAchim Leubner   /* Get request from free pool */
22224e1bc9a0SAchim Leubner   pRequest = saGetRequestFromFreePool(agRoot, agContext);
22234e1bc9a0SAchim Leubner   if (agNULL == pRequest)
22244e1bc9a0SAchim Leubner   {
22254e1bc9a0SAchim Leubner     SA_DBG1(("saSgpio, No request from free list\n" ));
22264e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6t");
22274e1bc9a0SAchim Leubner   }
22284e1bc9a0SAchim Leubner   else
22294e1bc9a0SAchim Leubner   {
22304e1bc9a0SAchim Leubner     /* Set payload to zeros */
22314e1bc9a0SAchim Leubner     si_memset(&payload, 0, sizeof(agsaSGpioCmd_t));
22324e1bc9a0SAchim Leubner 
22334e1bc9a0SAchim Leubner     /* set tag */
22344e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSGpioCmd_t, tag), pRequest->HTag);
22354e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSGpioCmd_t, regIndexRegTypeFunctionFrameType),
22364e1bc9a0SAchim Leubner                         (pSGpioReq->smpFrameType |
22374e1bc9a0SAchim Leubner                         ((bit32)pSGpioReq->function << 8)  |
22384e1bc9a0SAchim Leubner                         ((bit32)pSGpioReq->registerType << 16) |
22394e1bc9a0SAchim Leubner                         ((bit32)pSGpioReq->registerIndex << 24)));
22404e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSGpioCmd_t, regCount), pSGpioReq->registerCount);
22414e1bc9a0SAchim Leubner 
22424e1bc9a0SAchim Leubner     if (SA_SAS_SMP_WRITE_GPIO_REGISTER == pSGpioReq->function)
22434e1bc9a0SAchim Leubner     {
22444e1bc9a0SAchim Leubner       for (i = 0; i < pSGpioReq->registerCount; i++)
22454e1bc9a0SAchim Leubner       {
22464e1bc9a0SAchim Leubner         OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSGpioCmd_t, writeData) + (i * 4), pSGpioReq->readWriteData[i]);
22474e1bc9a0SAchim Leubner       }
22484e1bc9a0SAchim Leubner     }
22494e1bc9a0SAchim Leubner 
22504e1bc9a0SAchim Leubner     /* Build IOMB command and send to SPC */
22514e1bc9a0SAchim Leubner     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SGPIO, IOMB_SIZE64, queueNum);
22524e1bc9a0SAchim Leubner     if (AGSA_RC_SUCCESS != ret)
22534e1bc9a0SAchim Leubner     {
22544e1bc9a0SAchim Leubner       /* Return the request to free pool */
22554e1bc9a0SAchim Leubner       saReturnRequestToFreePool(agRoot, pRequest);
22564e1bc9a0SAchim Leubner       SA_DBG1(("saSgpio, sending IOMB failed\n" ));
22574e1bc9a0SAchim Leubner     }
22584e1bc9a0SAchim Leubner 
22594e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6t");
22604e1bc9a0SAchim Leubner   }
22614e1bc9a0SAchim Leubner 
22624e1bc9a0SAchim Leubner   return ret;
22634e1bc9a0SAchim Leubner }
22644e1bc9a0SAchim Leubner 
22654e1bc9a0SAchim Leubner /******************************************************************************/
22664e1bc9a0SAchim Leubner /*! \brief for spc card read Error Registers to memory if error occur
22674e1bc9a0SAchim Leubner  *
22684e1bc9a0SAchim Leubner  *  This function is called to get erorr registers content to memory if error occur.
22694e1bc9a0SAchim Leubner  *
22704e1bc9a0SAchim Leubner  *  \param agRoot      handles for this instance of SAS/SATA hardware
22714e1bc9a0SAchim Leubner  *
22724e1bc9a0SAchim Leubner  *  \return
22734e1bc9a0SAchim Leubner  */
22744e1bc9a0SAchim Leubner /*******************************************************************************/
siSpcGetErrorContent(agsaRoot_t * agRoot)22754e1bc9a0SAchim Leubner LOCAL void siSpcGetErrorContent(
22764e1bc9a0SAchim Leubner                                 agsaRoot_t *agRoot
22774e1bc9a0SAchim Leubner                                )
22784e1bc9a0SAchim Leubner {
22794e1bc9a0SAchim Leubner 
22804e1bc9a0SAchim Leubner   agsaLLRoot_t          *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
22814e1bc9a0SAchim Leubner   bit32       value, value1;
22824e1bc9a0SAchim Leubner 
22834e1bc9a0SAchim Leubner   value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1) & SCRATCH_PAD_STATE_MASK;
22844e1bc9a0SAchim Leubner   value1 = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_2, MSGU_SCRATCH_PAD_2) & SCRATCH_PAD_STATE_MASK;
22854e1bc9a0SAchim Leubner       /* check AAP error */
22864e1bc9a0SAchim Leubner   if ((SCRATCH_PAD1_ERR == value) || (SCRATCH_PAD2_ERR == value1))
22874e1bc9a0SAchim Leubner   {
22884e1bc9a0SAchim Leubner         /* fatal error */
22894e1bc9a0SAchim Leubner         /* get register dump from GSM and save it to LL local memory */
22904e1bc9a0SAchim Leubner       siGetRegisterDumpGSM(agRoot, (void *)&saRoot->registerDump0[0],
22914e1bc9a0SAchim Leubner            REG_DUMP_NUM0, 0, saRoot->mainConfigTable.FatalErrorDumpLength0);
22924e1bc9a0SAchim Leubner       siGetRegisterDumpGSM(agRoot, (void *)&saRoot->registerDump1[0],
22934e1bc9a0SAchim Leubner            REG_DUMP_NUM1, 0, saRoot->mainConfigTable.FatalErrorDumpLength1);
22944e1bc9a0SAchim Leubner   }
22954e1bc9a0SAchim Leubner }
22964e1bc9a0SAchim Leubner 
22974e1bc9a0SAchim Leubner 
22984e1bc9a0SAchim Leubner /******************************************************************************/
22994e1bc9a0SAchim Leubner /*! \brief for spcv card read Error Registers to memory if error occur
23004e1bc9a0SAchim Leubner  *
23014e1bc9a0SAchim Leubner  *  This function is called to get erorr registers content to memory if error occur.
23024e1bc9a0SAchim Leubner  *
23034e1bc9a0SAchim Leubner  *  \param agRoot      handles for this instance of SAS/SATA hardware
23044e1bc9a0SAchim Leubner  *
23054e1bc9a0SAchim Leubner  *  \return
23064e1bc9a0SAchim Leubner  */
23074e1bc9a0SAchim Leubner /*******************************************************************************/
siSpcvGetErrorContent(agsaRoot_t * agRoot)23084e1bc9a0SAchim Leubner LOCAL void siSpcvGetErrorContent(
23094e1bc9a0SAchim Leubner                                  agsaRoot_t *agRoot
23104e1bc9a0SAchim Leubner                                  )
23114e1bc9a0SAchim Leubner {
23124e1bc9a0SAchim Leubner 
23134e1bc9a0SAchim Leubner   agsaLLRoot_t          *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
23144e1bc9a0SAchim Leubner   bit32                 value;
23154e1bc9a0SAchim Leubner 
23164e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"2d");
23174e1bc9a0SAchim Leubner   value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1);
23184e1bc9a0SAchim Leubner 
23194e1bc9a0SAchim Leubner   if(((value & SPCV_RAAE_STATE_MASK) == SPCV_ERROR_VALUE) ||
23204e1bc9a0SAchim Leubner      ((value & SPCV_IOP0_STATE_MASK) == SPCV_ERROR_VALUE) ||
23214e1bc9a0SAchim Leubner      ((value & SPCV_IOP1_STATE_MASK) == SPCV_ERROR_VALUE)
23224e1bc9a0SAchim Leubner     )
23234e1bc9a0SAchim Leubner   {
23244e1bc9a0SAchim Leubner         /* fatal error */
23254e1bc9a0SAchim Leubner         /* get register dump from GSM and save it to LL local memory */
23264e1bc9a0SAchim Leubner     siGetRegisterDumpGSM(agRoot, (void *)&saRoot->registerDump0[0],
23274e1bc9a0SAchim Leubner        REG_DUMP_NUM0, 0, saRoot->mainConfigTable.FatalErrorDumpLength0);
23284e1bc9a0SAchim Leubner     siGetRegisterDumpGSM(agRoot, (void *)&saRoot->registerDump1[0],
23294e1bc9a0SAchim Leubner        REG_DUMP_NUM1, 0, saRoot->mainConfigTable.FatalErrorDumpLength1);
23304e1bc9a0SAchim Leubner   }
23314e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2d");
23324e1bc9a0SAchim Leubner }
23334e1bc9a0SAchim Leubner 
23344e1bc9a0SAchim Leubner #define LEFT_BYTE_FAIL(x, v)   \
23354e1bc9a0SAchim Leubner      do {if( (x) < (v) ) return AGSA_RC_FAILURE; } while(0);
23364e1bc9a0SAchim Leubner 
siDumpInboundQueue(void * buffer,bit32 length,mpiICQueue_t * q)23374e1bc9a0SAchim Leubner LOCAL bit32 siDumpInboundQueue(
23384e1bc9a0SAchim Leubner           void *  buffer,
23394e1bc9a0SAchim Leubner           bit32   length,
23404e1bc9a0SAchim Leubner           mpiICQueue_t  *q
23414e1bc9a0SAchim Leubner           )
23424e1bc9a0SAchim Leubner {
23434e1bc9a0SAchim Leubner   bit8  * _buf = buffer;
23444e1bc9a0SAchim Leubner   si_memcpy( _buf, (bit8*)(q->memoryRegion.virtPtr) + length, 128*256);
23454e1bc9a0SAchim Leubner   return AGSA_RC_SUCCESS;
23464e1bc9a0SAchim Leubner }
23474e1bc9a0SAchim Leubner 
siDumpOutboundQueue(void * buffer,bit32 length,mpiOCQueue_t * q)23484e1bc9a0SAchim Leubner LOCAL bit32 siDumpOutboundQueue(
23494e1bc9a0SAchim Leubner           void *  buffer,
23504e1bc9a0SAchim Leubner           bit32   length,
23514e1bc9a0SAchim Leubner           mpiOCQueue_t  *q)
23524e1bc9a0SAchim Leubner {
23534e1bc9a0SAchim Leubner   bit8  * _buf   = buffer;
23544e1bc9a0SAchim Leubner   si_memcpy( _buf, (bit8*)(q->memoryRegion.virtPtr) + length, 128*256);
23554e1bc9a0SAchim Leubner   return AGSA_RC_SUCCESS;
23564e1bc9a0SAchim Leubner }
23574e1bc9a0SAchim Leubner 
23584e1bc9a0SAchim Leubner 
siWaitForNonFatalTransfer(agsaRoot_t * agRoot,bit32 pcibar)23594e1bc9a0SAchim Leubner LOCAL bit32 siWaitForNonFatalTransfer( agsaRoot_t *agRoot,bit32 pcibar)
23604e1bc9a0SAchim Leubner {
23614e1bc9a0SAchim Leubner   bit32 status = AGSA_RC_SUCCESS;
23624e1bc9a0SAchim Leubner   bit32 ready;
23634e1bc9a0SAchim Leubner   bit32 max_wait_time;
23644e1bc9a0SAchim Leubner   bit32 max_wait_count;
23654e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"2c");
23664e1bc9a0SAchim Leubner 
23674e1bc9a0SAchim Leubner   SA_DBG4(("siWaitForNonFatalTransfer:0 IBDBS 0x%x\n",ossaHwRegReadExt(agRoot,0 ,V_Inbound_Doorbell_Set_Register ) ));
23684e1bc9a0SAchim Leubner   /* Write FDDHSHK  */
23694e1bc9a0SAchim Leubner 
23704e1bc9a0SAchim Leubner 
23714e1bc9a0SAchim Leubner   /* Write bit7 of inbound doorbell set register  step 3 */
23724e1bc9a0SAchim Leubner   ossaHwRegWriteExt(agRoot, 0,V_Inbound_Doorbell_Set_Register, SPCV_MSGU_CFG_TABLE_TRANSFER_DEBUG_INFO );
23734e1bc9a0SAchim Leubner   SA_DBG4(("siWaitForNonFatalTransfer:1 IBDBS 0x%x\n",ossaHwRegReadExt(agRoot,0 ,V_Inbound_Doorbell_Set_Register ) ));
23744e1bc9a0SAchim Leubner 
23754e1bc9a0SAchim Leubner   /* Poll bit7 of inbound doorbell set register until clear step 4 */
23764e1bc9a0SAchim Leubner   max_wait_time = (2000 * 1000); /* wait 2 seconds */
23774e1bc9a0SAchim Leubner   max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT) - WAIT_INCREMENT;
23784e1bc9a0SAchim Leubner   do
23794e1bc9a0SAchim Leubner   {
23804e1bc9a0SAchim Leubner     ossaStallThread(agRoot, WAIT_INCREMENT);
23814e1bc9a0SAchim Leubner     ready = ossaHwRegReadExt(agRoot,0 ,V_Inbound_Doorbell_Set_Register );
23824e1bc9a0SAchim Leubner   } while ( (ready & SPCV_MSGU_CFG_TABLE_TRANSFER_DEBUG_INFO)  && (max_wait_count -= WAIT_INCREMENT));
23834e1bc9a0SAchim Leubner   if(max_wait_count == 0)
23844e1bc9a0SAchim Leubner   {
23854e1bc9a0SAchim Leubner     SA_DBG1(("siWaitForNonFatalTransfer:Timeout IBDBS 0x%x\n",ossaHwRegReadExt(agRoot,0 ,V_Inbound_Doorbell_Set_Register ) ));
23864e1bc9a0SAchim Leubner     status = AGSA_RC_FAILURE;
23874e1bc9a0SAchim Leubner   }
23884e1bc9a0SAchim Leubner 
23894e1bc9a0SAchim Leubner   SA_DBG4(("siWaitForNonFatalTransfer:3 IBDBS 0x%x\n",ossaHwRegReadExt(agRoot,0 ,V_Inbound_Doorbell_Set_Register ) ));
23904e1bc9a0SAchim Leubner 
23914e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2c");
23924e1bc9a0SAchim Leubner   return(status);
23934e1bc9a0SAchim Leubner }
23944e1bc9a0SAchim Leubner 
siWaitForFatalTransfer(agsaRoot_t * agRoot,bit32 pcibar)23954e1bc9a0SAchim Leubner LOCAL bit32 siWaitForFatalTransfer( agsaRoot_t *agRoot,bit32 pcibar)
23964e1bc9a0SAchim Leubner {
23974e1bc9a0SAchim Leubner   bit32 status = AGSA_RC_SUCCESS;
23984e1bc9a0SAchim Leubner   bit32 ready;
23994e1bc9a0SAchim Leubner   bit32 ErrorTableOffset;
24004e1bc9a0SAchim Leubner   bit32 max_wait_time;
24014e1bc9a0SAchim Leubner   bit32 max_wait_count;
24024e1bc9a0SAchim Leubner 
24034e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"2o");
24044e1bc9a0SAchim Leubner 
24054e1bc9a0SAchim Leubner   ErrorTableOffset = siGetTableOffset( agRoot, MAIN_MERRDCTO_MERRDCES );
24064e1bc9a0SAchim Leubner 
24074e1bc9a0SAchim Leubner   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 )));
24084e1bc9a0SAchim Leubner   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)));
24094e1bc9a0SAchim Leubner   /*
24104e1bc9a0SAchim Leubner   2. Write 0x1 to the Fatal Error Debug Dump Handshake control [FDDHSHK] field in Table 73 and
24114e1bc9a0SAchim Leubner   read back the same field (by polling) until it is 0. This prompts the debug agent to copy the next
24124e1bc9a0SAchim Leubner   part of the debug data into GSM shared memory. To check the completion of the copy process, the
24134e1bc9a0SAchim Leubner   host must poll the Fatal/Non Fatal Debug Data Transfer Status [FDDTSTAT] field in the Table
24144e1bc9a0SAchim Leubner   Table 73.
24154e1bc9a0SAchim Leubner   */
24164e1bc9a0SAchim Leubner 
24174e1bc9a0SAchim Leubner   /* Write FDDHSHK  */
24184e1bc9a0SAchim Leubner   ossaHwRegWriteExt(agRoot,pcibar ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_HANDSHAKE, MPI_FATAL_EDUMP_HANDSHAKE_RDY );
24194e1bc9a0SAchim Leubner   SA_DBG4(("siWaitForFatalTransfer:1 MPI_FATAL_EDUMP_TABLE_HANDSHAKE 0x%x\n",ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_HANDSHAKE ) ));
24204e1bc9a0SAchim Leubner 
24214e1bc9a0SAchim Leubner   /* Poll FDDHSHK  until clear  */
24224e1bc9a0SAchim Leubner   max_wait_time = (2000 * 1000); /* wait 2 seconds */
24234e1bc9a0SAchim Leubner   max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT) - WAIT_INCREMENT;
24244e1bc9a0SAchim Leubner   do
24254e1bc9a0SAchim Leubner   {
24264e1bc9a0SAchim Leubner     ossaStallThread(agRoot, WAIT_INCREMENT);
24274e1bc9a0SAchim Leubner     ready = ossaHwRegReadExt(agRoot,0 ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_HANDSHAKE );
24284e1bc9a0SAchim Leubner   } while (ready   && (max_wait_count -= WAIT_INCREMENT));
24294e1bc9a0SAchim Leubner   if(max_wait_count == 0)
24304e1bc9a0SAchim Leubner   {
24314e1bc9a0SAchim Leubner     SA_DBG1(("siWaitForFatalTransfer : 1 Timeout\n"));
24324e1bc9a0SAchim Leubner     status = AGSA_RC_FAILURE;
24334e1bc9a0SAchim Leubner   }
24344e1bc9a0SAchim Leubner 
24354e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2o");
24364e1bc9a0SAchim Leubner   return(status);
24374e1bc9a0SAchim Leubner }
24384e1bc9a0SAchim Leubner 
24394e1bc9a0SAchim Leubner 
24404e1bc9a0SAchim Leubner 
siFatalErrorBuffer(agsaRoot_t * agRoot,agsaForensicData_t * forensicData)24414e1bc9a0SAchim Leubner LOCAL bit32 siFatalErrorBuffer(
24424e1bc9a0SAchim Leubner                   agsaRoot_t *agRoot,
24434e1bc9a0SAchim Leubner                   agsaForensicData_t *forensicData
24444e1bc9a0SAchim Leubner                   )
24454e1bc9a0SAchim Leubner {
24464e1bc9a0SAchim Leubner   bit32 status = AGSA_RC_FAILURE;
24474e1bc9a0SAchim Leubner   bit32 pcibar;
24484e1bc9a0SAchim Leubner   bit32 ErrorTableOffset;
24494e1bc9a0SAchim Leubner   bit32 Accum_len = 0;
24504e1bc9a0SAchim Leubner 
24514e1bc9a0SAchim Leubner   agsaLLRoot_t      *saRoot;
24524e1bc9a0SAchim Leubner   /* sanity check */
24534e1bc9a0SAchim Leubner   SA_ASSERT( (agNULL != agRoot), "");
24544e1bc9a0SAchim Leubner   saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
24554e1bc9a0SAchim Leubner   SA_ASSERT( (agNULL != saRoot), "saRoot");
24564e1bc9a0SAchim Leubner   if(agNULL == saRoot )
24574e1bc9a0SAchim Leubner   {
24584e1bc9a0SAchim Leubner     SA_DBG1(("siFatalErrorBuffer: agNULL  saRoot\n"));
24594e1bc9a0SAchim Leubner     return(status);
24604e1bc9a0SAchim Leubner   }
24614e1bc9a0SAchim Leubner 
24624e1bc9a0SAchim Leubner   if(saRoot->ResetFailed )
24634e1bc9a0SAchim Leubner   {
24644e1bc9a0SAchim Leubner     SA_DBG1(("siFatalErrorBuffer: saRoot->ResetFailed\n"));
24654e1bc9a0SAchim Leubner     return(status);
24664e1bc9a0SAchim Leubner   }
24674e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"2a");
24684e1bc9a0SAchim Leubner   SA_DBG2(("siFatalErrorBuffer:In %p Offset 0x%08x Len 0x%08x Totel len 0x%x\n",
24694e1bc9a0SAchim Leubner                         forensicData->BufferType.dataBuf.directData,
24704e1bc9a0SAchim Leubner                         forensicData->BufferType.dataBuf.directOffset,
24714e1bc9a0SAchim Leubner                         forensicData->BufferType.dataBuf.directLen,
24724e1bc9a0SAchim Leubner 			forensicData->BufferType.dataBuf.readLen ));
24734e1bc9a0SAchim Leubner 
24744e1bc9a0SAchim Leubner   pcibar = siGetPciBar(agRoot);
24754e1bc9a0SAchim Leubner   ErrorTableOffset = siGetTableOffset( agRoot, MAIN_MERRDCTO_MERRDCES );
24764e1bc9a0SAchim Leubner 
24774e1bc9a0SAchim Leubner   SA_DBG3(("siFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_STATUS  0x%x LEN 0x%x\n",
24784e1bc9a0SAchim Leubner       ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_STATUS),
24794e1bc9a0SAchim Leubner       ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN) ));
24804e1bc9a0SAchim Leubner 
24814e1bc9a0SAchim Leubner   /*
24824e1bc9a0SAchim Leubner   This section describes sequence for the host to capture debug data under fatal error conditions.
24834e1bc9a0SAchim Leubner   A fatal error is an error condition that stops the SPCv controller from normal operation and causes it
24844e1bc9a0SAchim Leubner   to be unresponsive to host requests. Since the firmware is non-operational, the host needs to pull the
24854e1bc9a0SAchim Leubner   debug dump information using PCIe MEMBASE II with the assistance of the debug agent which becomes
24864e1bc9a0SAchim Leubner   active when the main controller firmware fails.
24874e1bc9a0SAchim Leubner   */
24884e1bc9a0SAchim Leubner   /*
24894e1bc9a0SAchim Leubner   To capture the fatal error debug data, the host must:
24904e1bc9a0SAchim Leubner   1. Upon detecting the fatal error condition through a fatal error interrupt or by the MSGU scratchpad
24914e1bc9a0SAchim Leubner   registers, capture the first part of the fatal error debug data. Upon fatal error, the first part of the
24924e1bc9a0SAchim Leubner   debug data is located GSM shared memory and its length is updated in the Accumulative Debug
24934e1bc9a0SAchim Leubner   Data Length Transferred [ACCDDLEN] field in Table Table 82. To capture the first part:
24944e1bc9a0SAchim Leubner   */
24954e1bc9a0SAchim Leubner   if(forensicData->BufferType.dataBuf.directOffset == 0)
24964e1bc9a0SAchim Leubner   {
24974e1bc9a0SAchim Leubner     /* start to get data */
24984e1bc9a0SAchim Leubner     /*
24994e1bc9a0SAchim Leubner     a. Program the MEMBASE II Shifting Register with 0x00.
25004e1bc9a0SAchim Leubner     */
25014e1bc9a0SAchim Leubner     ossaHwRegWriteExt(agRoot, pcibar,V_MEMBASE_II_ShiftRegister, saRoot->FatalForensicShiftOffset); // set base to zero
25024e1bc9a0SAchim Leubner 
25034e1bc9a0SAchim Leubner     saRoot->ForensicLastOffset =0;
25044e1bc9a0SAchim Leubner     saRoot->FatalForensicStep = 0;
25054e1bc9a0SAchim Leubner     saRoot->FatalBarLoc = 0;
25064e1bc9a0SAchim Leubner     saRoot->FatalForensicShiftOffset = 0;
25074e1bc9a0SAchim Leubner 
25084e1bc9a0SAchim Leubner     SA_DBG1(("siFatalErrorBuffer: directOffset zero SCRATCH_PAD1 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1) ));
25094e1bc9a0SAchim Leubner   }
25104e1bc9a0SAchim Leubner 
25114e1bc9a0SAchim Leubner   /* Read until Accum_len is retrived */
25124e1bc9a0SAchim Leubner   Accum_len = ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN);
25134e1bc9a0SAchim Leubner 
25144e1bc9a0SAchim Leubner   SA_DBG2(("siFatalErrorBuffer: Accum_len 0x%x\n", Accum_len));
25154e1bc9a0SAchim Leubner   if(Accum_len == 0xFFFFFFFF)
25164e1bc9a0SAchim Leubner   {
25174e1bc9a0SAchim Leubner     SA_DBG1(("siFatalErrorBuffer: Possible PCI issue 0x%x not expected\n", Accum_len));
25184e1bc9a0SAchim Leubner     return(status);
25194e1bc9a0SAchim Leubner   }
25204e1bc9a0SAchim Leubner 
25214e1bc9a0SAchim Leubner   if( Accum_len == 0 || Accum_len >=0x100000 )
25224e1bc9a0SAchim Leubner   {
25234e1bc9a0SAchim Leubner     SA_DBG1(("siFatalErrorBuffer: Accum_len == saRoot->FatalCurrentLength 0x%x\n", Accum_len));
25244e1bc9a0SAchim Leubner     return(IOCTL_ERROR_NO_FATAL_ERROR);
25254e1bc9a0SAchim Leubner   }
25264e1bc9a0SAchim Leubner 
25274e1bc9a0SAchim Leubner   if(saRoot->FatalForensicStep == 0) /* PM Step 1a and 1b */
25284e1bc9a0SAchim Leubner   {
25294e1bc9a0SAchim Leubner     moreData:
25304e1bc9a0SAchim Leubner 	  if(forensicData->BufferType.dataBuf.directData)
25314e1bc9a0SAchim Leubner 	  {
25324e1bc9a0SAchim Leubner       		  siPciCpyMem(agRoot,saRoot->FatalBarLoc ,forensicData->BufferType.dataBuf.directData,forensicData->BufferType.dataBuf.directLen ,1 );
25334e1bc9a0SAchim Leubner 	  }
25344e1bc9a0SAchim Leubner 	  saRoot->FatalBarLoc += forensicData->BufferType.dataBuf.directLen;
25354e1bc9a0SAchim Leubner 	  forensicData->BufferType.dataBuf.directOffset += forensicData->BufferType.dataBuf.directLen;
25364e1bc9a0SAchim Leubner 	  saRoot->ForensicLastOffset  += forensicData->BufferType.dataBuf.directLen;
25374e1bc9a0SAchim Leubner 	  forensicData->BufferType.dataBuf.readLen = forensicData->BufferType.dataBuf.directLen;
25384e1bc9a0SAchim Leubner 
25394e1bc9a0SAchim Leubner 	  if(saRoot->ForensicLastOffset  >= Accum_len)
25404e1bc9a0SAchim Leubner     {
25414e1bc9a0SAchim Leubner       /*
25424e1bc9a0SAchim Leubner       e. Repeat the above 2 steps until all debug data is retrieved as specified in the Accumulative Debug
25434e1bc9a0SAchim Leubner       Data Length Transferred [ACCDDLEN] field.
25444e1bc9a0SAchim Leubner       NOTE: The ACCDDLEN field is cumulative so the host needs to take the difference from the
25454e1bc9a0SAchim Leubner       previous step.
25464e1bc9a0SAchim Leubner       */
25474e1bc9a0SAchim Leubner       /* This section data ends get next section */
25484e1bc9a0SAchim Leubner       SA_DBG1(("siFatalErrorBuffer: Accum_len reached 0x%x directOffset 0x%x\n",Accum_len,forensicData->BufferType.dataBuf.directOffset ));
25494e1bc9a0SAchim Leubner       saRoot->FatalBarLoc = 0;
25504e1bc9a0SAchim Leubner       saRoot->FatalForensicStep = 1;
25514e1bc9a0SAchim Leubner       saRoot->FatalForensicShiftOffset = 0;
25524e1bc9a0SAchim Leubner 		  status = AGSA_RC_COMPLETE;
25534e1bc9a0SAchim Leubner 		  return status;
25544e1bc9a0SAchim Leubner     }
25554e1bc9a0SAchim Leubner     if(saRoot->FatalBarLoc < (64*1024))
25564e1bc9a0SAchim Leubner     {
25574e1bc9a0SAchim Leubner       SA_DBG2(("siFatalErrorBuffer: In same 64k FatalBarLoc 0x%x\n",saRoot->FatalBarLoc ));
25584e1bc9a0SAchim Leubner       status = AGSA_RC_SUCCESS;
25594e1bc9a0SAchim Leubner 		  return status;
25604e1bc9a0SAchim Leubner     }
25614e1bc9a0SAchim Leubner     /*
25624e1bc9a0SAchim Leubner     c. Increment the MEMBASE II Shifting Register value by 0x100.
25634e1bc9a0SAchim Leubner     */
25644e1bc9a0SAchim Leubner     saRoot->FatalForensicShiftOffset+= 0x100;
25654e1bc9a0SAchim Leubner     	  ossaHwRegWriteExt(agRoot, pcibar,V_MEMBASE_II_ShiftRegister, saRoot->FatalForensicShiftOffset);
25664e1bc9a0SAchim Leubner     saRoot->FatalBarLoc = 0;
25674e1bc9a0SAchim Leubner 
25684e1bc9a0SAchim Leubner 	  SA_DBG1(("siFatalErrorBuffer: Get next bar data 0x%x\n",saRoot->FatalForensicShiftOffset));
25694e1bc9a0SAchim Leubner 
25704e1bc9a0SAchim Leubner     status = AGSA_RC_SUCCESS;
25714e1bc9a0SAchim Leubner 
25724e1bc9a0SAchim Leubner 	  SA_DBG1(("siFatalErrorBuffer:Offset 0x%x BarLoc 0x%x\n",saRoot->FatalForensicShiftOffset,saRoot->FatalBarLoc  ));
25734e1bc9a0SAchim Leubner 	  SA_DBG1(("siFatalErrorBuffer: step 0 status %d %p Offset 0x%x Len 0x%x total_len 0x%x\n",
25744e1bc9a0SAchim Leubner                         status,
25754e1bc9a0SAchim Leubner                         forensicData->BufferType.dataBuf.directData,
25764e1bc9a0SAchim Leubner 				  forensicData->BufferType.dataBuf.directOffset,
25774e1bc9a0SAchim Leubner                         forensicData->BufferType.dataBuf.directLen,
25784e1bc9a0SAchim Leubner 				  forensicData->BufferType.dataBuf.readLen ));
25794e1bc9a0SAchim Leubner 	  return(status);
25804e1bc9a0SAchim Leubner   }
25814e1bc9a0SAchim Leubner 
25824e1bc9a0SAchim Leubner   if(saRoot->FatalForensicStep == 1)
25834e1bc9a0SAchim Leubner   {
25844e1bc9a0SAchim Leubner 
25854e1bc9a0SAchim Leubner     /*
25864e1bc9a0SAchim Leubner     3. If Fatal/Non Fatal Debug Data Transfer Status [FDDTSTAT] field indicates status value of
25874e1bc9a0SAchim Leubner     0x00000002 or 0x00000003, read the next part of the fatal debug data by taking the difference
25884e1bc9a0SAchim Leubner     between the preserved ACCDDLEN value from step 2 and the new ACCDDLEN value.To capture
25894e1bc9a0SAchim Leubner     the second part:
25904e1bc9a0SAchim Leubner     a. Program the MEMBASE II Shifting Register with 0x00.
25914e1bc9a0SAchim Leubner     */
25924e1bc9a0SAchim Leubner     SA_DBG1(("siFatalErrorBuffer: FatalForensicStep 1 Accum_len 0x%X MPI_FATAL_EDUMP_TABLE_ACCUM_LEN 0x%x\n",
25934e1bc9a0SAchim Leubner                 Accum_len,
25944e1bc9a0SAchim Leubner                 ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN)));
25954e1bc9a0SAchim Leubner 
25964e1bc9a0SAchim Leubner     saRoot->FatalForensicShiftOffset = 0; /* location in 64k region */
25974e1bc9a0SAchim Leubner     /*
25984e1bc9a0SAchim Leubner     b. Read 64K of the debug data.
25994e1bc9a0SAchim Leubner     */
26004e1bc9a0SAchim Leubner     ossaHwRegWriteExt(agRoot, pcibar,V_MEMBASE_II_ShiftRegister  ,saRoot->FatalForensicShiftOffset);
26014e1bc9a0SAchim Leubner     SA_DBG1(("siFatalErrorBuffer: FatalForensicStep 1\n" ));
26024e1bc9a0SAchim Leubner     /*
26034e1bc9a0SAchim Leubner     2.Write 0x1 to the Fatal Error Debug Dump Handshake control [FDDHSHK]
26044e1bc9a0SAchim Leubner     field inTable 82 and read back the same field (by polling for 2 seconds) until it is 0. This prompts
26054e1bc9a0SAchim Leubner     the debug agent to copy the next part of the debug data into GSM shared memory. To check the
26064e1bc9a0SAchim Leubner     completion of the copy process, the host must poll the Fatal/Non Fatal Debug Data Transfer Status
26074e1bc9a0SAchim Leubner     [FDDTSTAT] field for 2 secondsin the MPI Fatal and Non-Fatal Error Dump Capture Table Table 82.
26084e1bc9a0SAchim Leubner     */
26094e1bc9a0SAchim Leubner     siWaitForFatalTransfer( agRoot,pcibar);
26104e1bc9a0SAchim Leubner 
26114e1bc9a0SAchim Leubner     /*
26124e1bc9a0SAchim Leubner     d. Read the next 64K of the debug data.
26134e1bc9a0SAchim Leubner     */
26144e1bc9a0SAchim Leubner     saRoot->FatalForensicStep = 0;
26154e1bc9a0SAchim Leubner 
26164e1bc9a0SAchim Leubner     if( ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_STATUS) != MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE )
26174e1bc9a0SAchim Leubner     {
26184e1bc9a0SAchim Leubner 
26194e1bc9a0SAchim Leubner       SA_DBG3(("siFatalErrorBuffer:Step 3\n" ));
26204e1bc9a0SAchim Leubner       SA_DBG3(("siFatalErrorBuffer:Step 3 MPI_FATAL_EDUMP_TABLE_STATUS 0x%x\n", ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_STATUS )));
26214e1bc9a0SAchim Leubner       /*
26224e1bc9a0SAchim Leubner       2. Write FDDSTAT to 0x00000000 but preserve the Accumulative Debug Data Length Transferred
26234e1bc9a0SAchim Leubner       [ACCDDLEN] field.
26244e1bc9a0SAchim Leubner       */
26254e1bc9a0SAchim Leubner       ossaHwRegWriteExt(agRoot,pcibar ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_STATUS, 0 );
26264e1bc9a0SAchim Leubner       /*
26274e1bc9a0SAchim Leubner       4. If FDDSTAT is 0x00000002, repeat steps 2 and 3 until you reach this step with FDDSTAT being
26284e1bc9a0SAchim Leubner       equal to 0x00000003.
26294e1bc9a0SAchim Leubner       */
26304e1bc9a0SAchim Leubner       goto moreData;
26314e1bc9a0SAchim Leubner     }
26324e1bc9a0SAchim Leubner     else
26334e1bc9a0SAchim Leubner     {
26344e1bc9a0SAchim Leubner       /*
26354e1bc9a0SAchim Leubner          When FDDSTAT equals 0x00000003 and ACCDDLEN is unchanged, then
26364e1bc9a0SAchim Leubner       */
26374e1bc9a0SAchim Leubner       /*
26384e1bc9a0SAchim Leubner       the fatal error dump is complete. If ACCDDLEN increases, one more read step is required.
26394e1bc9a0SAchim Leubner       The content and format of the debug data is opaque to the host and must be forwarded to PMC-Sierra
26404e1bc9a0SAchim Leubner       Applications support for failure analysis. Debug data is retrieved in several iterations which enables
26414e1bc9a0SAchim Leubner       the host to use a smaller buffer and store the captured debug data in secondary storage during the process.
26424e1bc9a0SAchim Leubner       */
26434e1bc9a0SAchim Leubner 
26444e1bc9a0SAchim Leubner       SA_DBG3(("siFatalErrorBuffer:Step 4\n" ));
26454e1bc9a0SAchim Leubner       SA_DBG1(("siFatalErrorBuffer:  Done  Read 0x%x accum 0x%x\n",
26464e1bc9a0SAchim Leubner                 forensicData->BufferType.dataBuf.directOffset,
26474e1bc9a0SAchim Leubner                 ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN)));
26484e1bc9a0SAchim Leubner 
26494e1bc9a0SAchim Leubner #if defined(SALLSDK_DEBUG)
26504e1bc9a0SAchim Leubner       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) )));
26514e1bc9a0SAchim Leubner       SA_DBG1(("siFatalErrorBuffer: SCRATCH_PAD0 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0)));
26524e1bc9a0SAchim Leubner       SA_DBG1(("siFatalErrorBuffer: SCRATCH_PAD1 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1)));
26534e1bc9a0SAchim Leubner       SA_DBG1(("siFatalErrorBuffer: SCRATCH_PAD2 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_2,  MSGU_SCRATCH_PAD_2)));
26544e1bc9a0SAchim Leubner       SA_DBG1(("siFatalErrorBuffer: SCRATCH_PAD3 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_3,  MSGU_SCRATCH_PAD_3)));
26554e1bc9a0SAchim Leubner #endif
26564e1bc9a0SAchim Leubner       forensicData->BufferType.dataBuf.readLen = 0xFFFFFFFF;
26574e1bc9a0SAchim Leubner       status = AGSA_RC_SUCCESS;
26584e1bc9a0SAchim Leubner 
26594e1bc9a0SAchim Leubner     }
26604e1bc9a0SAchim Leubner   }
26614e1bc9a0SAchim Leubner 
26624e1bc9a0SAchim Leubner 
26634e1bc9a0SAchim Leubner   SA_DBG3(("siFatalErrorBuffer:status 0x%x %p directOffset 0x%x directLen 0x%x readLen 0x%x\n",
26644e1bc9a0SAchim Leubner                         status,
26654e1bc9a0SAchim Leubner                         forensicData->BufferType.dataBuf.directData,
26664e1bc9a0SAchim Leubner                         forensicData->BufferType.dataBuf.directOffset,
26674e1bc9a0SAchim Leubner                         forensicData->BufferType.dataBuf.directLen,
26684e1bc9a0SAchim Leubner                         forensicData->BufferType.dataBuf.readLen ));
26694e1bc9a0SAchim Leubner 
26704e1bc9a0SAchim Leubner       smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2a");
26714e1bc9a0SAchim Leubner   return(status);
26724e1bc9a0SAchim Leubner }
26734e1bc9a0SAchim Leubner 
siNonFatalErrorBuffer(agsaRoot_t * agRoot,agsaForensicData_t * forensicData)26744e1bc9a0SAchim Leubner LOCAL bit32 siNonFatalErrorBuffer(
26754e1bc9a0SAchim Leubner               agsaRoot_t *agRoot,
26764e1bc9a0SAchim Leubner               agsaForensicData_t *forensicData
26774e1bc9a0SAchim Leubner               )
26784e1bc9a0SAchim Leubner {
26794e1bc9a0SAchim Leubner   bit32 status = AGSA_RC_FAILURE;
26804e1bc9a0SAchim Leubner   bit32 pcibar;
26814e1bc9a0SAchim Leubner   bit32 ErrorTableOffset;
26824e1bc9a0SAchim Leubner 
26834e1bc9a0SAchim Leubner   //bit32 i;
26844e1bc9a0SAchim Leubner   bit32 ready;
26854e1bc9a0SAchim Leubner   bit32 biggest;
26864e1bc9a0SAchim Leubner   bit32 max_wait_time;
26874e1bc9a0SAchim Leubner   bit32 max_wait_count;
26884e1bc9a0SAchim Leubner   agsaLLRoot_t      *saRoot;
26894e1bc9a0SAchim Leubner   /* sanity check */
26904e1bc9a0SAchim Leubner   SA_ASSERT( (agNULL != agRoot), "agRoot");
26914e1bc9a0SAchim Leubner   saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
26924e1bc9a0SAchim Leubner   SA_ASSERT( (agNULL != saRoot), "saRoot");
26934e1bc9a0SAchim Leubner   if(agNULL == saRoot )
26944e1bc9a0SAchim Leubner   {
26954e1bc9a0SAchim Leubner     SA_DBG1(("siNonFatalErrorBuffer: agNULL  saRoot\n"));
26964e1bc9a0SAchim Leubner     return(status);
26974e1bc9a0SAchim Leubner   }
26984e1bc9a0SAchim Leubner 
26994e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"2b");
27004e1bc9a0SAchim Leubner   pcibar = siGetPciBar(agRoot);
27014e1bc9a0SAchim Leubner   ErrorTableOffset = siGetTableOffset( agRoot, MAIN_MERRDCTO_MERRDCES );
27024e1bc9a0SAchim Leubner 
27034e1bc9a0SAchim Leubner   SA_DBG4(("siNonFatalErrorBuffer: ErrorTableOffset 0x%x\n",ErrorTableOffset ));
27044e1bc9a0SAchim Leubner 
27054e1bc9a0SAchim Leubner   SA_DBG4(("siNonFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_STATUS Offset 0x%x   0x%x\n",
27064e1bc9a0SAchim Leubner             ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS,
27074e1bc9a0SAchim Leubner             ossaHwRegReadExt(agRoot,pcibar,ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS)));
27084e1bc9a0SAchim Leubner   SA_DBG4(("siNonFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_ACCUM_LEN Offset 0x%x   0x%x\n",
27094e1bc9a0SAchim Leubner             ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN,
27104e1bc9a0SAchim Leubner             ossaHwRegReadExt(agRoot,pcibar,ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN)));
27114e1bc9a0SAchim Leubner 
27124e1bc9a0SAchim Leubner   biggest = saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].totalLength;
27134e1bc9a0SAchim Leubner 
27144e1bc9a0SAchim Leubner   if(biggest >= forensicData->BufferType.dataBuf.directLen )
27154e1bc9a0SAchim Leubner   {
27164e1bc9a0SAchim Leubner     biggest = forensicData->BufferType.dataBuf.directLen;
27174e1bc9a0SAchim Leubner   }
27184e1bc9a0SAchim Leubner   else
27194e1bc9a0SAchim Leubner   {
27204e1bc9a0SAchim Leubner     SA_DBG1(("siNonFatalErrorBuffer: directLen larger than DMA Buffer 0x%x < 0x%x\n",
27214e1bc9a0SAchim Leubner               biggest, forensicData->BufferType.dataBuf.directLen));
27224e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2b");
27234e1bc9a0SAchim Leubner     return(AGSA_RC_FAILURE);
27244e1bc9a0SAchim Leubner   }
27254e1bc9a0SAchim Leubner 
27264e1bc9a0SAchim Leubner   if(saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].virtPtr)
27274e1bc9a0SAchim Leubner   {
27284e1bc9a0SAchim Leubner     si_memset(saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].virtPtr, 0, biggest);
27294e1bc9a0SAchim Leubner   }
27304e1bc9a0SAchim Leubner   else
27314e1bc9a0SAchim Leubner   {
27324e1bc9a0SAchim Leubner     SA_DBG1(("siNonFatalErrorBuffer: Error\n" ));
27334e1bc9a0SAchim Leubner     return(AGSA_RC_FAILURE);
27344e1bc9a0SAchim Leubner   }
27354e1bc9a0SAchim Leubner 
27364e1bc9a0SAchim Leubner 
27374e1bc9a0SAchim Leubner   if(forensicData->BufferType.dataBuf.directOffset)
27384e1bc9a0SAchim Leubner   {
27394e1bc9a0SAchim Leubner     /* Write FDDSTAT and ACCDDLEN to zero step 2 */
27404e1bc9a0SAchim Leubner     ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS, 0);
27414e1bc9a0SAchim Leubner     goto skip_setup;
27424e1bc9a0SAchim Leubner   }
27434e1bc9a0SAchim Leubner 
27444e1bc9a0SAchim Leubner   SA_DBG1(("siNonFatalErrorBuffer: %p Offset 0x%x Len 0x%x total_len 0x%x\n",
27454e1bc9a0SAchim Leubner                         forensicData->BufferType.dataBuf.directData,
27464e1bc9a0SAchim Leubner                         forensicData->BufferType.dataBuf.directOffset,
27474e1bc9a0SAchim Leubner                         forensicData->BufferType.dataBuf.directLen,
27484e1bc9a0SAchim Leubner                         forensicData->BufferType.dataBuf.readLen ));
27494e1bc9a0SAchim Leubner 
27504e1bc9a0SAchim Leubner   SA_DBG1(("siNonFatalErrorBuffer: directOffset zero setup\n" ));
27514e1bc9a0SAchim Leubner   SA_DBG1(("siNonFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_STATUS  0x%x LEN 0x%x\n",
27524e1bc9a0SAchim Leubner       ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_STATUS),
27534e1bc9a0SAchim Leubner       ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN) ));
27544e1bc9a0SAchim Leubner 
27554e1bc9a0SAchim Leubner   SA_DBG1(("siNonFatalErrorBuffer: Clear V_Scratchpad_Rsvd_0_Register 0x%x\n",
27564e1bc9a0SAchim Leubner           ossaHwRegReadExt(agRoot, 0,V_Scratchpad_Rsvd_0_Register) ));
27574e1bc9a0SAchim Leubner   ossaHwRegWriteExt(agRoot, 0,V_Scratchpad_Rsvd_0_Register ,0);
27584e1bc9a0SAchim Leubner 
27594e1bc9a0SAchim Leubner   saRoot->ForensicLastOffset = 0;
27604e1bc9a0SAchim Leubner 
27614e1bc9a0SAchim Leubner   /* WriteACCDDLEN  for error interface Step 0 */
27624e1bc9a0SAchim Leubner   /*ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN ,0);*/
27634e1bc9a0SAchim Leubner 
27644e1bc9a0SAchim Leubner   /* Write DMA get Offset for error interface Step 1 */
27654e1bc9a0SAchim Leubner   ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_LO_OFFSET, saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].phyAddrLower);
27664e1bc9a0SAchim Leubner   ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_HI_OFFSET, saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].phyAddrUpper);
27674e1bc9a0SAchim Leubner   ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_LENGTH, biggest);
27684e1bc9a0SAchim Leubner 
27694e1bc9a0SAchim Leubner   /* Write FDDSTAT and ACCDDLEN to zero step 2 */
27704e1bc9a0SAchim Leubner   ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS, 0);
27714e1bc9a0SAchim Leubner   ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN, 0);
27724e1bc9a0SAchim Leubner 
27734e1bc9a0SAchim Leubner   SA_DBG4(("siNonFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_STATUS Offset 0x%x   0x%x\n",
27744e1bc9a0SAchim Leubner            ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS,
27754e1bc9a0SAchim Leubner            ossaHwRegReadExt(agRoot,pcibar,ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS )));
27764e1bc9a0SAchim Leubner   SA_DBG4(("siNonFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_ACCUM_LEN Offset 0x%x   0x%x\n",
27774e1bc9a0SAchim Leubner            ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN,
27784e1bc9a0SAchim Leubner            ossaHwRegReadExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN)));
27794e1bc9a0SAchim Leubner 
27804e1bc9a0SAchim Leubner   if( 0 != ossaHwRegReadExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN))
27814e1bc9a0SAchim Leubner   {
27824e1bc9a0SAchim Leubner     SA_DBG1(("siNonFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_ACCUM_LEN  0x%x   0x%x\n",
27834e1bc9a0SAchim Leubner              forensicData->BufferType.dataBuf.directOffset,
27844e1bc9a0SAchim Leubner              ossaHwRegReadExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN)));
27854e1bc9a0SAchim Leubner   }
27864e1bc9a0SAchim Leubner   skip_setup:
27874e1bc9a0SAchim Leubner 
27884e1bc9a0SAchim Leubner   if( saRoot->ForensicLastOffset == 0xFFFFFFFF)
27894e1bc9a0SAchim Leubner   {
27904e1bc9a0SAchim Leubner     forensicData->BufferType.dataBuf.readLen = 0xFFFFFFFF;
27914e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2b");
27924e1bc9a0SAchim Leubner     return(AGSA_RC_SUCCESS);
27934e1bc9a0SAchim Leubner   }
27944e1bc9a0SAchim Leubner 
27954e1bc9a0SAchim Leubner 
27964e1bc9a0SAchim Leubner   /* Write bit7 of inbound doorbell set register and wait for complete step 3 and 4*/
27974e1bc9a0SAchim Leubner   siWaitForNonFatalTransfer(agRoot,pcibar);
27984e1bc9a0SAchim Leubner 
27994e1bc9a0SAchim Leubner   SA_DBG3(("siNonFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_STATUS  0x%x LEN 0x%x\n",
28004e1bc9a0SAchim Leubner       ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_STATUS),
28014e1bc9a0SAchim Leubner       ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN) ));
28024e1bc9a0SAchim Leubner 
28034e1bc9a0SAchim Leubner 
28044e1bc9a0SAchim Leubner 
28054e1bc9a0SAchim Leubner   max_wait_time = (2000 * 1000); /* wait 2 seconds */
28064e1bc9a0SAchim Leubner   max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT) - WAIT_INCREMENT;
28074e1bc9a0SAchim Leubner   ready = ossaHwRegReadExt(agRoot,pcibar,ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS );
28084e1bc9a0SAchim Leubner   do
28094e1bc9a0SAchim Leubner   {
28104e1bc9a0SAchim Leubner     ossaStallThread(agRoot, WAIT_INCREMENT);
28114e1bc9a0SAchim Leubner     ready =  ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS );
28124e1bc9a0SAchim Leubner     forensicData->BufferType.dataBuf.directOffset = ossaHwRegReadExt(agRoot,pcibar,ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN);
28134e1bc9a0SAchim Leubner     if( ready == MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_MORE_DATA )
28144e1bc9a0SAchim Leubner     {
28154e1bc9a0SAchim Leubner       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) ));
28164e1bc9a0SAchim Leubner       break;
28174e1bc9a0SAchim Leubner     }
28184e1bc9a0SAchim Leubner   } while ( ready != MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE && (max_wait_count -= WAIT_INCREMENT));
28194e1bc9a0SAchim Leubner 
28204e1bc9a0SAchim Leubner 
28214e1bc9a0SAchim Leubner   if(max_wait_count == 0 || ready == MPI_FATAL_EDUMP_TABLE_STAT_DMA_FAILED)
28224e1bc9a0SAchim Leubner   {
28234e1bc9a0SAchim Leubner     status = AGSA_RC_FAILURE;
28244e1bc9a0SAchim Leubner     SA_DBG1(("siNonFatalErrorBuffer: timeout waiting ready\n"));
28254e1bc9a0SAchim Leubner   }
28264e1bc9a0SAchim Leubner   else
28274e1bc9a0SAchim Leubner   {
28284e1bc9a0SAchim Leubner     forensicData->BufferType.dataBuf.readLen = forensicData->BufferType.dataBuf.directOffset - saRoot->ForensicLastOffset;
28294e1bc9a0SAchim Leubner     if( ready == MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE && forensicData->BufferType.dataBuf.readLen == 0)
28304e1bc9a0SAchim Leubner     {
28314e1bc9a0SAchim Leubner       SA_DBG1(("siNonFatalErrorBuffer:ready 0x%x readLen 0x%x\n",ready ,forensicData->BufferType.dataBuf.readLen));
28324e1bc9a0SAchim Leubner       saRoot->ForensicLastOffset = 0xFFFFFFFF;
28334e1bc9a0SAchim Leubner     }
28344e1bc9a0SAchim Leubner     else
28354e1bc9a0SAchim Leubner     {
28364e1bc9a0SAchim Leubner       saRoot->ForensicLastOffset = forensicData->BufferType.dataBuf.directOffset;
28374e1bc9a0SAchim Leubner     }
28384e1bc9a0SAchim Leubner 
28394e1bc9a0SAchim Leubner     if(forensicData->BufferType.dataBuf.directData )
28404e1bc9a0SAchim Leubner     {
28414e1bc9a0SAchim Leubner       si_memcpy(forensicData->BufferType.dataBuf.directData, saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].virtPtr,biggest);
28424e1bc9a0SAchim Leubner     }
28434e1bc9a0SAchim Leubner     status = AGSA_RC_SUCCESS;
28444e1bc9a0SAchim Leubner   }
28454e1bc9a0SAchim Leubner   /* step 5 */
28464e1bc9a0SAchim Leubner   SA_DBG3(("siNonFatalErrorBuffer: %p directOffset 0x%x directLen 0x%x readLen 0x%x\n",
28474e1bc9a0SAchim Leubner                         forensicData->BufferType.dataBuf.directData,
28484e1bc9a0SAchim Leubner                         forensicData->BufferType.dataBuf.directOffset,
28494e1bc9a0SAchim Leubner                         forensicData->BufferType.dataBuf.directLen,
28504e1bc9a0SAchim Leubner                         forensicData->BufferType.dataBuf.readLen ));
28514e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2b");
28524e1bc9a0SAchim Leubner   return(status);
28534e1bc9a0SAchim Leubner }
28544e1bc9a0SAchim Leubner 
28554e1bc9a0SAchim Leubner 
siGetForensicData(agsaRoot_t * agRoot,agsaContext_t * agContext,agsaForensicData_t * forensicData)28564e1bc9a0SAchim Leubner LOCAL bit32 siGetForensicData(
28574e1bc9a0SAchim Leubner     agsaRoot_t         *agRoot,
28584e1bc9a0SAchim Leubner     agsaContext_t      *agContext,
28594e1bc9a0SAchim Leubner     agsaForensicData_t *forensicData
28604e1bc9a0SAchim Leubner     )
28614e1bc9a0SAchim Leubner {
28624e1bc9a0SAchim Leubner   bit32 status = AGSA_RC_FAILURE;
28634e1bc9a0SAchim Leubner 	agsaLLRoot_t        *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
28644e1bc9a0SAchim Leubner 
28654e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"2Z");
28664e1bc9a0SAchim Leubner 
28674e1bc9a0SAchim Leubner   if(forensicData->DataType == TYPE_GSM_SPACE)
28684e1bc9a0SAchim Leubner 	{
28694e1bc9a0SAchim Leubner #define _1M 0x100000
28704e1bc9a0SAchim Leubner 		if( forensicData->BufferType.gsmBuf.directLen >= _1M )
28714e1bc9a0SAchim Leubner   {
28724e1bc9a0SAchim Leubner 			return AGSA_RC_FAILURE;
28734e1bc9a0SAchim Leubner 		}
28744e1bc9a0SAchim Leubner 
28754e1bc9a0SAchim Leubner 		if(forensicData->BufferType.dataBuf.readLen)
28764e1bc9a0SAchim Leubner     {
28774e1bc9a0SAchim Leubner 			SA_DBG1(("siGetForensicData: Incorrect readLen 0x%08X\n", forensicData->BufferType.dataBuf.readLen));
28784e1bc9a0SAchim Leubner 			forensicData->BufferType.dataBuf.readLen = forensicData->BufferType.dataBuf.directLen;
28794e1bc9a0SAchim Leubner 		}
28804e1bc9a0SAchim Leubner 		if( forensicData->BufferType.dataBuf.directOffset >= ONE_MEGABYTE )
28814e1bc9a0SAchim Leubner 		{
28824e1bc9a0SAchim Leubner 			SA_DBG1(("siGSMDump:	total length > ONE_MEGABYTE  0x%x\n",forensicData->BufferType.dataBuf.directOffset));
28834e1bc9a0SAchim Leubner 			forensicData->BufferType.dataBuf.readLen = 0xFFFFFFFF;
28844e1bc9a0SAchim Leubner 			return(AGSA_RC_SUCCESS);
28854e1bc9a0SAchim Leubner     }
28864e1bc9a0SAchim Leubner 		if(smIS_SPC(agRoot))
28874e1bc9a0SAchim Leubner 		{
28884e1bc9a0SAchim Leubner     if( forensicData->BufferType.dataBuf.directLen >= SIXTYFOURKBYTE )
28894e1bc9a0SAchim Leubner     {
28904e1bc9a0SAchim Leubner       SA_DBG1(("siGetForensicData directLen too large !\n"));
28914e1bc9a0SAchim Leubner       return AGSA_RC_FAILURE;
28924e1bc9a0SAchim Leubner     }
28934e1bc9a0SAchim Leubner     SA_DBG1(("siGetForensicData: TYPE_GSM_SPACE directLen 0x%X directOffset 0x%08X %p\n",
28944e1bc9a0SAchim Leubner                   forensicData->BufferType.dataBuf.directLen,
28954e1bc9a0SAchim Leubner                   forensicData->BufferType.dataBuf.directOffset,
28964e1bc9a0SAchim Leubner                   forensicData->BufferType.dataBuf.directData ));
28974e1bc9a0SAchim Leubner 
28984e1bc9a0SAchim Leubner 
28994e1bc9a0SAchim Leubner     /* Shift BAR4 original address */
29004e1bc9a0SAchim Leubner     if (AGSA_RC_FAILURE == siBar4Shift(agRoot, BAR_SHIFT_GSM_OFFSET + forensicData->BufferType.dataBuf.directOffset))
29014e1bc9a0SAchim Leubner     {
29024e1bc9a0SAchim Leubner       SA_DBG1(("siGSMDump:Shift Bar4 to 0x%x failed\n", 0x0));
29034e1bc9a0SAchim Leubner       return AGSA_RC_FAILURE;
29044e1bc9a0SAchim Leubner     }
29054e1bc9a0SAchim Leubner 
29064e1bc9a0SAchim Leubner 
29074e1bc9a0SAchim Leubner 			//if( forensicData->BufferType.dataBuf.directOffset >= ONE_MEGABYTE )
29084e1bc9a0SAchim Leubner 			//{
29094e1bc9a0SAchim Leubner 			//SA_DBG1(("siGSMDump:  total length > ONE_MEGABYTE  0x%x\n",forensicData->BufferType.dataBuf.directOffset));
29104e1bc9a0SAchim Leubner 			//forensicData->BufferType.dataBuf.readLen = 0xFFFFFFFF;
29114e1bc9a0SAchim Leubner 			//return(AGSA_RC_SUCCESS);
29124e1bc9a0SAchim Leubner 			//}
29134e1bc9a0SAchim Leubner 			forensicData->BufferType.gsmBuf.directOffset = 0;
29144e1bc9a0SAchim Leubner     }
29154e1bc9a0SAchim Leubner     status = siGSMDump( agRoot,
29164e1bc9a0SAchim Leubner 				forensicData->BufferType.gsmBuf.directOffset,
29174e1bc9a0SAchim Leubner 				forensicData->BufferType.gsmBuf.directLen,
29184e1bc9a0SAchim Leubner 				forensicData->BufferType.gsmBuf.directData );
29194e1bc9a0SAchim Leubner 
29204e1bc9a0SAchim Leubner     if(status == AGSA_RC_SUCCESS)
29214e1bc9a0SAchim Leubner     {
29224e1bc9a0SAchim Leubner       forensicData->BufferType.dataBuf.readLen = forensicData->BufferType.dataBuf.directLen;
29234e1bc9a0SAchim Leubner     }
29244e1bc9a0SAchim Leubner 
29254e1bc9a0SAchim Leubner     if( forensicData->BufferType.dataBuf.directOffset == 0 )
29264e1bc9a0SAchim Leubner     {
29274e1bc9a0SAchim Leubner       SA_DBG1(("siGetForensicData: TYPE_GSM_SPACE readLen 0x%08X\n", forensicData->BufferType.dataBuf.readLen));
29284e1bc9a0SAchim Leubner     }
29294e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2Z");
29304e1bc9a0SAchim Leubner 
29314e1bc9a0SAchim Leubner     return status;
29324e1bc9a0SAchim Leubner   }
29334e1bc9a0SAchim Leubner 	else if(forensicData->DataType == TYPE_INBOUND_QUEUE )
29344e1bc9a0SAchim Leubner   {
29354e1bc9a0SAchim Leubner       mpiICQueue_t        *circularQ = NULL;
29364e1bc9a0SAchim Leubner 		SA_DBG2(("siGetForensicData: TYPE_INBOUND \n"));
29374e1bc9a0SAchim Leubner 
29384e1bc9a0SAchim Leubner       if(forensicData->BufferType.queueBuf.queueIndex >=AGSA_MAX_INBOUND_Q )
29394e1bc9a0SAchim Leubner       {
29404e1bc9a0SAchim Leubner         smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2Z");
29414e1bc9a0SAchim Leubner         return AGSA_RC_FAILURE;
29424e1bc9a0SAchim Leubner       }
29434e1bc9a0SAchim Leubner       circularQ = &saRoot->inboundQueue[forensicData->BufferType.queueBuf.queueIndex];
29444e1bc9a0SAchim Leubner       status = siDumpInboundQueue( forensicData->BufferType.queueBuf.directData,
29454e1bc9a0SAchim Leubner                                  forensicData->BufferType.queueBuf.directLen,
29464e1bc9a0SAchim Leubner                                  circularQ );
29474e1bc9a0SAchim Leubner 		smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "2Z");
29484e1bc9a0SAchim Leubner 		return status;
29494e1bc9a0SAchim Leubner     }
29504e1bc9a0SAchim Leubner 	else if(forensicData->DataType == TYPE_OUTBOUND_QUEUE )
29514e1bc9a0SAchim Leubner 	//else if( forensicData->BufferType.queueBuf.queueType == TYPE_OUTBOUND_QUEUE )
29524e1bc9a0SAchim Leubner     {
29534e1bc9a0SAchim Leubner       mpiOCQueue_t        *circularQ = NULL;
29544e1bc9a0SAchim Leubner 		SA_DBG2(("siGetForensicData: TYPE_OUTBOUND\n"));
29554e1bc9a0SAchim Leubner 
29564e1bc9a0SAchim Leubner       if(forensicData->BufferType.queueBuf.queueIndex >= AGSA_MAX_OUTBOUND_Q )
29574e1bc9a0SAchim Leubner       {
29584e1bc9a0SAchim Leubner         smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "2Z");
29594e1bc9a0SAchim Leubner         return AGSA_RC_FAILURE;
29604e1bc9a0SAchim Leubner       }
29614e1bc9a0SAchim Leubner 
29624e1bc9a0SAchim Leubner       circularQ = &saRoot->outboundQueue[forensicData->BufferType.queueBuf.queueIndex];
29634e1bc9a0SAchim Leubner       status = siDumpOutboundQueue(forensicData->BufferType.queueBuf.directData,
29644e1bc9a0SAchim Leubner                                  forensicData->BufferType.queueBuf.directLen,
29654e1bc9a0SAchim Leubner                                  circularQ );
29664e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "2Z");
29674e1bc9a0SAchim Leubner 
29684e1bc9a0SAchim Leubner     return status;
29694e1bc9a0SAchim Leubner   }
29704e1bc9a0SAchim Leubner   else if(forensicData->DataType == TYPE_NON_FATAL  )
29714e1bc9a0SAchim Leubner   {
29724e1bc9a0SAchim Leubner 		// if(smIS_SPCV(agRoot))
29734e1bc9a0SAchim Leubner 		// {
29744e1bc9a0SAchim Leubner 		SA_DBG2(("siGetForensicData:TYPE_NON_FATAL \n"));
29754e1bc9a0SAchim Leubner       status = siNonFatalErrorBuffer(agRoot,forensicData);
29764e1bc9a0SAchim Leubner 		// }
29774e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "2Z");
29784e1bc9a0SAchim Leubner     return status;
29794e1bc9a0SAchim Leubner   }
29804e1bc9a0SAchim Leubner   else if(forensicData->DataType == TYPE_FATAL  )
29814e1bc9a0SAchim Leubner   {
29824e1bc9a0SAchim Leubner 		// if(smIS_SPCV(agRoot))
29834e1bc9a0SAchim Leubner 		//{
29844e1bc9a0SAchim Leubner 		SA_DBG2(("siGetForensicData:TYPE_NON_FATAL \n"));
29854e1bc9a0SAchim Leubner       status = siFatalErrorBuffer(agRoot,forensicData );
29864e1bc9a0SAchim Leubner 		// }
29874e1bc9a0SAchim Leubner 		smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "2Z");
29884e1bc9a0SAchim Leubner 		return status;
29894e1bc9a0SAchim Leubner 	}
29904e1bc9a0SAchim Leubner 	else
29914e1bc9a0SAchim Leubner 	{
29924e1bc9a0SAchim Leubner 		SA_DBG1(("siGetForensicData receive error parameter!\n"));
29934e1bc9a0SAchim Leubner 		smTraceFuncExit(hpDBG_VERY_LOUD, 'h', "2Z");
29944e1bc9a0SAchim Leubner 		return AGSA_RC_FAILURE;
29954e1bc9a0SAchim Leubner 	}
29964e1bc9a0SAchim Leubner 	smTraceFuncExit(hpDBG_VERY_LOUD, 'i', "2Z");
29974e1bc9a0SAchim Leubner 
29984e1bc9a0SAchim Leubner 	return status;
29994e1bc9a0SAchim Leubner }
30004e1bc9a0SAchim Leubner 
30014e1bc9a0SAchim Leubner 
30024e1bc9a0SAchim Leubner //GLOBAL bit32 saGetForensicData(
saGetForensicData(agsaRoot_t * agRoot,agsaContext_t * agContext,agsaForensicData_t * forensicData)30034e1bc9a0SAchim Leubner bit32 saGetForensicData(
30044e1bc9a0SAchim Leubner     agsaRoot_t         *agRoot,
30054e1bc9a0SAchim Leubner     agsaContext_t      *agContext,
30064e1bc9a0SAchim Leubner     agsaForensicData_t *forensicData
30074e1bc9a0SAchim Leubner     )
30084e1bc9a0SAchim Leubner {
30094e1bc9a0SAchim Leubner   bit32 status;
30104e1bc9a0SAchim Leubner   status = siGetForensicData(agRoot, agContext, forensicData);
30114e1bc9a0SAchim Leubner   ossaGetForensicDataCB(agRoot, agContext, status, forensicData);
30124e1bc9a0SAchim Leubner   return status;
30134e1bc9a0SAchim Leubner }
30144e1bc9a0SAchim Leubner 
saGetIOErrorStats(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 flag)30154e1bc9a0SAchim Leubner bit32 saGetIOErrorStats(
30164e1bc9a0SAchim Leubner                          agsaRoot_t        *agRoot,
30174e1bc9a0SAchim Leubner                          agsaContext_t     *agContext,
30184e1bc9a0SAchim Leubner                          bit32              flag
30194e1bc9a0SAchim Leubner                          )
30204e1bc9a0SAchim Leubner {
30214e1bc9a0SAchim Leubner   agsaLLRoot_t  *saRoot = (agsaLLRoot_t*)agRoot->sdkData;
30224e1bc9a0SAchim Leubner   bit32          status = AGSA_RC_SUCCESS;
30234e1bc9a0SAchim Leubner 
30244e1bc9a0SAchim Leubner   ossaGetIOErrorStatsCB(agRoot, agContext, status, &saRoot->IoErrorCount);
30254e1bc9a0SAchim Leubner 
30264e1bc9a0SAchim Leubner   if (flag)
30274e1bc9a0SAchim Leubner   {
30284e1bc9a0SAchim Leubner     /* clear IO error counter */
30294e1bc9a0SAchim Leubner     si_memset(&saRoot->IoErrorCount, 0, sizeof(agsaIOErrorEventStats_t));
30304e1bc9a0SAchim Leubner   }
30314e1bc9a0SAchim Leubner 
30324e1bc9a0SAchim Leubner   return status;
30334e1bc9a0SAchim Leubner }
30344e1bc9a0SAchim Leubner 
saGetIOEventStats(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 flag)30354e1bc9a0SAchim Leubner bit32 saGetIOEventStats(
30364e1bc9a0SAchim Leubner                          agsaRoot_t        *agRoot,
30374e1bc9a0SAchim Leubner                          agsaContext_t     *agContext,
30384e1bc9a0SAchim Leubner                          bit32              flag
30394e1bc9a0SAchim Leubner                          )
30404e1bc9a0SAchim Leubner {
30414e1bc9a0SAchim Leubner   agsaLLRoot_t  *saRoot = (agsaLLRoot_t*)agRoot->sdkData;
30424e1bc9a0SAchim Leubner   bit32          status = AGSA_RC_SUCCESS;
30434e1bc9a0SAchim Leubner 
30444e1bc9a0SAchim Leubner   ossaGetIOEventStatsCB(agRoot, agContext, status, &saRoot->IoEventCount);
30454e1bc9a0SAchim Leubner 
30464e1bc9a0SAchim Leubner   if (flag)
30474e1bc9a0SAchim Leubner   {
30484e1bc9a0SAchim Leubner     /* clear IO event counter */
30494e1bc9a0SAchim Leubner     si_memset(&saRoot->IoEventCount, 0, sizeof(agsaIOErrorEventStats_t));
30504e1bc9a0SAchim Leubner   }
30514e1bc9a0SAchim Leubner 
30524e1bc9a0SAchim Leubner   return status;
30534e1bc9a0SAchim Leubner }
30544e1bc9a0SAchim Leubner 
30554e1bc9a0SAchim Leubner /******************************************************************************/
30564e1bc9a0SAchim Leubner /*! \brief Initiate a GET REGISTER DUMP command
30574e1bc9a0SAchim Leubner  *
30584e1bc9a0SAchim Leubner  *  This function is called to Get Register Dump from the SPC.
30594e1bc9a0SAchim Leubner  *
30604e1bc9a0SAchim Leubner  *  \param agRoot      handles for this instance of SAS/SATA hardware
30614e1bc9a0SAchim Leubner  *  \param agContext   the context of this API
30624e1bc9a0SAchim Leubner  *  \param queueNum    queue number
30634e1bc9a0SAchim Leubner  *  \param regDumpInfo register dump information
30644e1bc9a0SAchim Leubner  *
30654e1bc9a0SAchim Leubner  *  \return
30664e1bc9a0SAchim Leubner  *          - SUCCESS or FAILURE
30674e1bc9a0SAchim Leubner  */
30684e1bc9a0SAchim Leubner /*******************************************************************************/
30694e1bc9a0SAchim Leubner //GLOBAL bit32 saGetRegisterDump(
saGetRegisterDump(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,agsaRegDumpInfo_t * regDumpInfo)30704e1bc9a0SAchim Leubner bit32 saGetRegisterDump(
30714e1bc9a0SAchim Leubner               agsaRoot_t        *agRoot,
30724e1bc9a0SAchim Leubner               agsaContext_t     *agContext,
30734e1bc9a0SAchim Leubner               bit32             queueNum,
30744e1bc9a0SAchim Leubner               agsaRegDumpInfo_t *regDumpInfo
30754e1bc9a0SAchim Leubner               )
30764e1bc9a0SAchim Leubner {
30774e1bc9a0SAchim Leubner   agsaLLRoot_t          *saRoot = agNULL;
30784e1bc9a0SAchim Leubner   bit32                 ret = AGSA_RC_SUCCESS;
30794e1bc9a0SAchim Leubner //  bit32                 value, value1;
30804e1bc9a0SAchim Leubner 
30814e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"6p");
30824e1bc9a0SAchim Leubner 
30834e1bc9a0SAchim Leubner   /* sanity check */
30844e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
30854e1bc9a0SAchim Leubner 
30864e1bc9a0SAchim Leubner   saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
30874e1bc9a0SAchim Leubner   /* sanity check */
30884e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != saRoot), "");
30894e1bc9a0SAchim Leubner 
30904e1bc9a0SAchim Leubner   /* sanity check */
30914e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != regDumpInfo), "");
30924e1bc9a0SAchim Leubner 
30934e1bc9a0SAchim Leubner   SA_DBG3(("saGetRegisterDump: agContext %p\n", agContext));
30944e1bc9a0SAchim Leubner 
30954e1bc9a0SAchim Leubner   if (regDumpInfo->regDumpSrc > 3)
30964e1bc9a0SAchim Leubner   {
30974e1bc9a0SAchim Leubner     SA_DBG1(("saGetRegisterDump, regDumpSrc %d or regDumpNum %d invalid\n",
30984e1bc9a0SAchim Leubner             regDumpInfo->regDumpNum, regDumpInfo->regDumpNum));
30994e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6p");
31004e1bc9a0SAchim Leubner     /* CB error for Register Dump */
31014e1bc9a0SAchim Leubner     ossaGetRegisterDumpCB(agRoot, agContext, OSSA_FAILURE);
31024e1bc9a0SAchim Leubner     return AGSA_RC_FAILURE;
31034e1bc9a0SAchim Leubner   }
31044e1bc9a0SAchim Leubner 
31054e1bc9a0SAchim Leubner   switch(regDumpInfo->regDumpSrc)
31064e1bc9a0SAchim Leubner   {
31074e1bc9a0SAchim Leubner   case REG_DUMP_NONFLASH:
31084e1bc9a0SAchim Leubner     /*First 6 64k data from GSMDUMP, contains IOST and RB info*/
31094e1bc9a0SAchim Leubner     if (regDumpInfo->regDumpNum == GET_IOST_RB_INFO)
31104e1bc9a0SAchim Leubner     {
31114e1bc9a0SAchim Leubner       regDumpInfo->regDumpOffset = regDumpInfo->regDumpOffset + 0;
31124e1bc9a0SAchim Leubner       ret = siGSMDump(agRoot, regDumpInfo->regDumpOffset, regDumpInfo->directLen, regDumpInfo->directData);
31134e1bc9a0SAchim Leubner       /* CB error for Register Dump */
31144e1bc9a0SAchim Leubner       ossaGetRegisterDumpCB(agRoot, agContext, ret);
31154e1bc9a0SAchim Leubner       return ret;
31164e1bc9a0SAchim Leubner     }
31174e1bc9a0SAchim Leubner     /* Last 1MB data from GSMDUMP, contains GSM_SM info*/
31184e1bc9a0SAchim Leubner 
31194e1bc9a0SAchim Leubner     if (regDumpInfo->regDumpNum == GET_GSM_SM_INFO)
31204e1bc9a0SAchim Leubner     {
31214e1bc9a0SAchim Leubner       /* GSM_SM - total 1 Mbytes */
31224e1bc9a0SAchim Leubner       bit32    offset;
31234e1bc9a0SAchim Leubner       if(smIS_SPC(agRoot))
31244e1bc9a0SAchim Leubner       {
31254e1bc9a0SAchim Leubner         offset = regDumpInfo->regDumpOffset + SPC_GSM_SM_OFFSET;
31264e1bc9a0SAchim Leubner       }else if(smIS_SPCV(agRoot))
31274e1bc9a0SAchim Leubner       {
31284e1bc9a0SAchim Leubner         offset = regDumpInfo->regDumpOffset + SPCV_GSM_SM_OFFSET;
31294e1bc9a0SAchim Leubner       } else
31304e1bc9a0SAchim Leubner       {
31314e1bc9a0SAchim Leubner         SA_DBG1(("saGetRegisterDump: the device type is not support\n"));
31324e1bc9a0SAchim Leubner         return AGSA_RC_FAILURE;
31334e1bc9a0SAchim Leubner       }
31344e1bc9a0SAchim Leubner 
31354e1bc9a0SAchim Leubner       ret = siGSMDump(agRoot, offset, regDumpInfo->directLen, regDumpInfo->directData);
31364e1bc9a0SAchim Leubner       /* CB error for Register Dump */
31374e1bc9a0SAchim Leubner       ossaGetRegisterDumpCB(agRoot, agContext, ret);
31384e1bc9a0SAchim Leubner       return ret;
31394e1bc9a0SAchim Leubner     }
31404e1bc9a0SAchim Leubner 
31414e1bc9a0SAchim Leubner     /* check fatal errors */
31424e1bc9a0SAchim Leubner     if(smIS_SPC(agRoot)) {
31434e1bc9a0SAchim Leubner       siSpcGetErrorContent(agRoot);
31444e1bc9a0SAchim Leubner     }
31454e1bc9a0SAchim Leubner     else if(smIS_SPCV(agRoot)) {
31464e1bc9a0SAchim Leubner       siSpcvGetErrorContent(agRoot);
31474e1bc9a0SAchim Leubner     }
31484e1bc9a0SAchim Leubner     /* Then read from local copy */
31494e1bc9a0SAchim Leubner     if (regDumpInfo->directLen > REGISTER_DUMP_BUFF_SIZE)
31504e1bc9a0SAchim Leubner     {
31514e1bc9a0SAchim Leubner       SA_DBG1(("saGetRegisterDump, Request too many bytes %d\n",
31524e1bc9a0SAchim Leubner               regDumpInfo->directLen));
31534e1bc9a0SAchim Leubner       regDumpInfo->directLen = REGISTER_DUMP_BUFF_SIZE;
31544e1bc9a0SAchim Leubner     }
31554e1bc9a0SAchim Leubner 
31564e1bc9a0SAchim Leubner     if (regDumpInfo->regDumpNum == 0)
31574e1bc9a0SAchim Leubner     {
31584e1bc9a0SAchim Leubner       /* Copy the LL Local register dump0 data to the destination */
31594e1bc9a0SAchim Leubner       si_memcpy(regDumpInfo->directData, (bit8 *)&saRoot->registerDump0[0] +
31604e1bc9a0SAchim Leubner                 regDumpInfo->regDumpOffset, regDumpInfo->directLen);
31614e1bc9a0SAchim Leubner     }
31624e1bc9a0SAchim Leubner     else if( regDumpInfo->regDumpNum == 1)
31634e1bc9a0SAchim Leubner     {
31644e1bc9a0SAchim Leubner       /* Copy the LL Local register dump1 data to the destination */
31654e1bc9a0SAchim Leubner       si_memcpy(regDumpInfo->directData, (bit8 *)&saRoot->registerDump1[0] +
31664e1bc9a0SAchim Leubner                 regDumpInfo->regDumpOffset, regDumpInfo->directLen);
31674e1bc9a0SAchim Leubner     } else {
31684e1bc9a0SAchim Leubner       SA_DBG1(("saGetRegisterDump, the regDumpNum value is wrong %x\n",
31694e1bc9a0SAchim Leubner               regDumpInfo->regDumpNum));
31704e1bc9a0SAchim Leubner     }
31714e1bc9a0SAchim Leubner 
31724e1bc9a0SAchim Leubner     /* CB for Register Dump */
31734e1bc9a0SAchim Leubner     ossaGetRegisterDumpCB(agRoot, agContext, OSSA_SUCCESS);
31744e1bc9a0SAchim Leubner     break;
31754e1bc9a0SAchim Leubner 
31764e1bc9a0SAchim Leubner   case REG_DUMP_FLASH:
31774e1bc9a0SAchim Leubner     /* build IOMB command and send to SPC */
31784e1bc9a0SAchim Leubner     ret = mpiNVMReadRegDumpCmd(agRoot, agContext, queueNum,
31794e1bc9a0SAchim Leubner                             regDumpInfo->regDumpNum,
31804e1bc9a0SAchim Leubner                             regDumpInfo->regDumpOffset,
31814e1bc9a0SAchim Leubner                             regDumpInfo->indirectAddrUpper32,
31824e1bc9a0SAchim Leubner                             regDumpInfo->indirectAddrLower32,
31834e1bc9a0SAchim Leubner                             regDumpInfo->indirectLen);
31844e1bc9a0SAchim Leubner 
31854e1bc9a0SAchim Leubner     break;
31864e1bc9a0SAchim Leubner 
31874e1bc9a0SAchim Leubner   default:
31884e1bc9a0SAchim Leubner     break;
31894e1bc9a0SAchim Leubner   }
31904e1bc9a0SAchim Leubner 
31914e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6p");
31924e1bc9a0SAchim Leubner 
31934e1bc9a0SAchim Leubner   return ret;
31944e1bc9a0SAchim Leubner }
31954e1bc9a0SAchim Leubner 
31964e1bc9a0SAchim Leubner /******************************************************************************/
31974e1bc9a0SAchim Leubner /*! \brief Initiate a GET REGISTER DUMP from GSM command
31984e1bc9a0SAchim Leubner  *
31994e1bc9a0SAchim Leubner  *  This function is called to Get Register Dump from the GSM of SPC.
32004e1bc9a0SAchim Leubner  *
32014e1bc9a0SAchim Leubner  *  \param agRoot      handles for this instance of SAS/SATA hardware
32024e1bc9a0SAchim Leubner  *  \param destinationAddress address of the register dump data copied to
32034e1bc9a0SAchim Leubner  *  \param regDumpNum  Register Dump # 0 or 1
32044e1bc9a0SAchim Leubner  *  \param regDumpOffset Offset within the register dump area
32054e1bc9a0SAchim Leubner  *  \param len         Length in bytes of the register dump data to copy
32064e1bc9a0SAchim Leubner  *
32074e1bc9a0SAchim Leubner  *  \return
32084e1bc9a0SAchim Leubner  *          - SUCCESS or FAILURE
32094e1bc9a0SAchim Leubner  */
32104e1bc9a0SAchim Leubner /*******************************************************************************/
32114e1bc9a0SAchim Leubner //GLOBAL bit32 siGetRegisterDumpGSM(
siGetRegisterDumpGSM(agsaRoot_t * agRoot,void * destinationAddress,bit32 regDumpNum,bit32 regDumpOffset,bit32 len)32124e1bc9a0SAchim Leubner bit32 siGetRegisterDumpGSM(
32134e1bc9a0SAchim Leubner                         agsaRoot_t        *agRoot,
32144e1bc9a0SAchim Leubner                         void              *destinationAddress,
32154e1bc9a0SAchim Leubner                         bit32             regDumpNum,
32164e1bc9a0SAchim Leubner                         bit32             regDumpOffset,
32174e1bc9a0SAchim Leubner                         bit32             len
32184e1bc9a0SAchim Leubner                         )
32194e1bc9a0SAchim Leubner {
32204e1bc9a0SAchim Leubner   agsaLLRoot_t          *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
32214e1bc9a0SAchim Leubner   bit32                 ret = AGSA_RC_SUCCESS;
32224e1bc9a0SAchim Leubner   bit32                 rDumpOffset, rDumpLen; //, rDumpValue;
32234e1bc9a0SAchim Leubner   bit8                  *dst;
32244e1bc9a0SAchim Leubner 
32254e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"2V");
32264e1bc9a0SAchim Leubner 
32274e1bc9a0SAchim Leubner   /* sanity check */
32284e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
32294e1bc9a0SAchim Leubner 
32304e1bc9a0SAchim Leubner   dst = (bit8 *)destinationAddress;
32314e1bc9a0SAchim Leubner 
32324e1bc9a0SAchim Leubner   if (regDumpNum > 1)
32334e1bc9a0SAchim Leubner   {
32344e1bc9a0SAchim Leubner     SA_DBG1(("siGetRegisterDump, regDumpNum %d is invalid\n", regDumpNum));
32354e1bc9a0SAchim Leubner     return AGSA_RC_FAILURE;
32364e1bc9a0SAchim Leubner   }
32374e1bc9a0SAchim Leubner 
32384e1bc9a0SAchim Leubner   if (!regDumpNum)
32394e1bc9a0SAchim Leubner   {
32404e1bc9a0SAchim Leubner     rDumpOffset = saRoot->mainConfigTable.FatalErrorDumpOffset0;
32414e1bc9a0SAchim Leubner     rDumpLen = saRoot->mainConfigTable.FatalErrorDumpLength0;
32424e1bc9a0SAchim Leubner   }
32434e1bc9a0SAchim Leubner   else
32444e1bc9a0SAchim Leubner   {
32454e1bc9a0SAchim Leubner     rDumpOffset = saRoot->mainConfigTable.FatalErrorDumpOffset1;
32464e1bc9a0SAchim Leubner     rDumpLen = saRoot->mainConfigTable.FatalErrorDumpLength1;
32474e1bc9a0SAchim Leubner   }
32484e1bc9a0SAchim Leubner 
32494e1bc9a0SAchim Leubner   if (len > rDumpLen)
32504e1bc9a0SAchim Leubner   {
32514e1bc9a0SAchim Leubner     SA_DBG1(("siGetRegisterDump, Request too many bytes %d, rDumpLen %d\n", len, rDumpLen));
32524e1bc9a0SAchim Leubner     len = rDumpLen;
32534e1bc9a0SAchim Leubner   }
32544e1bc9a0SAchim Leubner 
32554e1bc9a0SAchim Leubner   if (regDumpOffset >= len)
32564e1bc9a0SAchim Leubner   {
32574e1bc9a0SAchim Leubner     SA_DBG1(("siGetRegisterDump, Offset is not within the area %d, regDumpOffset%d\n", rDumpLen, regDumpOffset));
32584e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2V");
32594e1bc9a0SAchim Leubner     return AGSA_RC_FAILURE;
32604e1bc9a0SAchim Leubner   }
32614e1bc9a0SAchim Leubner 
32624e1bc9a0SAchim Leubner   /* adjust length to dword boundary */
32634e1bc9a0SAchim Leubner   if ((len % 4) > 0)
32644e1bc9a0SAchim Leubner   {
32654e1bc9a0SAchim Leubner     len = (len/4 + 1) * 4;
32664e1bc9a0SAchim Leubner   }
32674e1bc9a0SAchim Leubner 
32684e1bc9a0SAchim Leubner   ret = siGSMDump(agRoot, rDumpOffset, len, dst);
32694e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2V");
32704e1bc9a0SAchim Leubner 
32714e1bc9a0SAchim Leubner   return ret;
32724e1bc9a0SAchim Leubner }
32734e1bc9a0SAchim Leubner 
32744e1bc9a0SAchim Leubner /******************************************************************************/
32754e1bc9a0SAchim Leubner /*! \brief SPC Get NVMD Command
32764e1bc9a0SAchim Leubner  *
32774e1bc9a0SAchim Leubner  *  This command sends GET_NVMD_DATA Command to SPC.
32784e1bc9a0SAchim Leubner  *
32794e1bc9a0SAchim Leubner  *  \param agRoot       Handles for this instance of SAS/SATA LL
32804e1bc9a0SAchim Leubner  *  \param agContext    Context of SPC FW Flash Update Command
32814e1bc9a0SAchim Leubner  *  \param queueNum     Inbound/outbound queue number
32824e1bc9a0SAchim Leubner  *  \param NVMDInfo     Pointer of NVM Device information
32834e1bc9a0SAchim Leubner  *
32844e1bc9a0SAchim Leubner  *  \return If the MPI command is sent to SPC successfully
32854e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
32864e1bc9a0SAchim Leubner  *          - \e AGSA_RC_FAILURE the MPI command is failure
32874e1bc9a0SAchim Leubner  *
32884e1bc9a0SAchim Leubner  */
32894e1bc9a0SAchim Leubner /*******************************************************************************/
32904e1bc9a0SAchim Leubner //GLOBAL bit32 saGetNVMDCommand(
saGetNVMDCommand(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,agsaNVMDData_t * NVMDInfo)32914e1bc9a0SAchim Leubner bit32 saGetNVMDCommand(
32924e1bc9a0SAchim Leubner   agsaRoot_t                *agRoot,
32934e1bc9a0SAchim Leubner   agsaContext_t             *agContext,
32944e1bc9a0SAchim Leubner   bit32                     queueNum,
32954e1bc9a0SAchim Leubner   agsaNVMDData_t            *NVMDInfo
32964e1bc9a0SAchim Leubner   )
32974e1bc9a0SAchim Leubner {
32984e1bc9a0SAchim Leubner   bit32 ret           = AGSA_RC_SUCCESS;
32994e1bc9a0SAchim Leubner 
33004e1bc9a0SAchim Leubner   /* sanity check */
33014e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
33024e1bc9a0SAchim Leubner 
33034e1bc9a0SAchim Leubner   /* build IOMB command and send to SPC */
33044e1bc9a0SAchim Leubner   ret = mpiGetNVMDCmd(agRoot, agContext, NVMDInfo, queueNum);
33054e1bc9a0SAchim Leubner 
33064e1bc9a0SAchim Leubner   return ret;
33074e1bc9a0SAchim Leubner }
33084e1bc9a0SAchim Leubner 
33094e1bc9a0SAchim Leubner /******************************************************************************/
33104e1bc9a0SAchim Leubner /*! \brief SPC Set NVMD Command
33114e1bc9a0SAchim Leubner  *
33124e1bc9a0SAchim Leubner  *  This command sends SET_NVMD_DATA Command to SPC.
33134e1bc9a0SAchim Leubner  *
33144e1bc9a0SAchim Leubner  *  \param agRoot       Handles for this instance of SAS/SATA LL
33154e1bc9a0SAchim Leubner  *  \param agContext    Context of SPC FW Flash Update Command
33164e1bc9a0SAchim Leubner  *  \param queueNum     Inbound/outbound queue number
33174e1bc9a0SAchim Leubner  *  \param NVMDInfo     Pointer of NVM Device information
33184e1bc9a0SAchim Leubner  *
33194e1bc9a0SAchim Leubner  *  \return If the MPI command is sent to SPC successfully
33204e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
33214e1bc9a0SAchim Leubner  *          - \e AGSA_RC_FAILURE the MPI command is failure
33224e1bc9a0SAchim Leubner  *
33234e1bc9a0SAchim Leubner  */
33244e1bc9a0SAchim Leubner /*******************************************************************************/
33254e1bc9a0SAchim Leubner //GLOBAL bit32 saSetNVMDCommand(
saSetNVMDCommand(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,agsaNVMDData_t * NVMDInfo)33264e1bc9a0SAchim Leubner bit32 saSetNVMDCommand(
33274e1bc9a0SAchim Leubner   agsaRoot_t                *agRoot,
33284e1bc9a0SAchim Leubner   agsaContext_t             *agContext,
33294e1bc9a0SAchim Leubner   bit32                     queueNum,
33304e1bc9a0SAchim Leubner   agsaNVMDData_t            *NVMDInfo
33314e1bc9a0SAchim Leubner   )
33324e1bc9a0SAchim Leubner {
33334e1bc9a0SAchim Leubner   bit32 ret           = AGSA_RC_SUCCESS;
33344e1bc9a0SAchim Leubner 
33354e1bc9a0SAchim Leubner   /* sanity check */
33364e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
33374e1bc9a0SAchim Leubner 
33384e1bc9a0SAchim Leubner   /* build IOMB command and send to SPC */
33394e1bc9a0SAchim Leubner   ret = mpiSetNVMDCmd(agRoot, agContext, NVMDInfo, queueNum);
33404e1bc9a0SAchim Leubner 
33414e1bc9a0SAchim Leubner   return ret;
33424e1bc9a0SAchim Leubner }
33434e1bc9a0SAchim Leubner 
33444e1bc9a0SAchim Leubner 
saSendSMPIoctl(agsaRoot_t * agRoot,agsaDevHandle_t * agDevHandle,bit32 queueNum,agsaSMPFrame_t * pSMPFrame,ossaSMPCompletedCB_t agCB)33454e1bc9a0SAchim Leubner GLOBAL bit32 saSendSMPIoctl(
33464e1bc9a0SAchim Leubner   agsaRoot_t                *agRoot,
33474e1bc9a0SAchim Leubner   agsaDevHandle_t           *agDevHandle,
33484e1bc9a0SAchim Leubner   bit32                      queueNum,
33494e1bc9a0SAchim Leubner   agsaSMPFrame_t            *pSMPFrame,
33504e1bc9a0SAchim Leubner   ossaSMPCompletedCB_t       agCB
33514e1bc9a0SAchim Leubner   )
33524e1bc9a0SAchim Leubner {
33534e1bc9a0SAchim Leubner   bit32 ret           = AGSA_RC_SUCCESS;
33544e1bc9a0SAchim Leubner   //bit32 IR_IP_OV_res_phyId_DPdLen_res = 0;
33554e1bc9a0SAchim Leubner   bit32 retVal;
33564e1bc9a0SAchim Leubner   bit8                      inq, outq;
33574e1bc9a0SAchim Leubner   agsaIORequestDesc_t       *pRequest;
33584e1bc9a0SAchim Leubner   void                      *pMessage;
33594e1bc9a0SAchim Leubner   bit8                      *payload_ptr;
33604e1bc9a0SAchim Leubner   agsaDeviceDesc_t          *pDevice;
33614e1bc9a0SAchim Leubner   bit8                      using_reserved = agFALSE;
33624e1bc9a0SAchim Leubner   agsaPort_t                *pPort;
33634e1bc9a0SAchim Leubner   mpiICQueue_t              *circularQ;
33644e1bc9a0SAchim Leubner   agsaLLRoot_t              *saRoot = agNULL;
33654e1bc9a0SAchim Leubner //  agsaDevHandle_t       	*agDevHandle;
33664e1bc9a0SAchim Leubner 
33674e1bc9a0SAchim Leubner   saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
33684e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != saRoot), "");
33694e1bc9a0SAchim Leubner 
33704e1bc9a0SAchim Leubner   /* sanity check */
33714e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
33724e1bc9a0SAchim Leubner 
33734e1bc9a0SAchim Leubner 
33744e1bc9a0SAchim Leubner 
33754e1bc9a0SAchim Leubner   /* Get request from free IO Requests */
33764e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
33774e1bc9a0SAchim Leubner   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/
33784e1bc9a0SAchim Leubner 
33794e1bc9a0SAchim Leubner   /* If no LL IO request entry available */
33804e1bc9a0SAchim Leubner   if ( agNULL == pRequest )
33814e1bc9a0SAchim Leubner   {
33824e1bc9a0SAchim Leubner     pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests));
33834e1bc9a0SAchim Leubner 
33844e1bc9a0SAchim Leubner     if(agNULL != pRequest)
33854e1bc9a0SAchim Leubner     {
33864e1bc9a0SAchim Leubner       using_reserved = agTRUE;
33874e1bc9a0SAchim Leubner       SA_DBG1(("saSMPStart, using saRoot->freeReservedRequests\n"));
33884e1bc9a0SAchim Leubner     }
33894e1bc9a0SAchim Leubner     else
33904e1bc9a0SAchim Leubner     {
33914e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
33924e1bc9a0SAchim Leubner       SA_DBG1(("saSMPStart, No request from free list Not using saRoot->freeReservedRequests\n"));
33934e1bc9a0SAchim Leubner       smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "9a");
33944e1bc9a0SAchim Leubner       return AGSA_RC_BUSY;
33954e1bc9a0SAchim Leubner     }
33964e1bc9a0SAchim Leubner   }
33974e1bc9a0SAchim Leubner 
33984e1bc9a0SAchim Leubner   inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
33994e1bc9a0SAchim Leubner   outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
34004e1bc9a0SAchim Leubner 
34014e1bc9a0SAchim Leubner 
34024e1bc9a0SAchim Leubner 
34034e1bc9a0SAchim Leubner 
34044e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agDevHandle), "");
34054e1bc9a0SAchim Leubner   /* Find the outgoing port for the device */
34064e1bc9a0SAchim Leubner   if (agNULL == agDevHandle->sdkData)
34074e1bc9a0SAchim Leubner   {
34084e1bc9a0SAchim Leubner 	/* Device has been removed */
34094e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
34104e1bc9a0SAchim Leubner 	SA_DBG1(("saSMPStart, Device has been removed. agDevHandle=%p\n", agDevHandle));
34114e1bc9a0SAchim Leubner 	smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "9a");
34124e1bc9a0SAchim Leubner 	return AGSA_RC_FAILURE;
34134e1bc9a0SAchim Leubner   }
34144e1bc9a0SAchim Leubner 
34154e1bc9a0SAchim Leubner   pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
34164e1bc9a0SAchim Leubner 
34174e1bc9a0SAchim Leubner   pPort = pDevice->pPort;
34184e1bc9a0SAchim Leubner 
34194e1bc9a0SAchim Leubner 
34204e1bc9a0SAchim Leubner 
34214e1bc9a0SAchim Leubner 	  /* If free IOMB avaliable */
34224e1bc9a0SAchim Leubner 	  /* Remove the request from free list */
34234e1bc9a0SAchim Leubner 	  if( using_reserved )
34244e1bc9a0SAchim Leubner 	  {
34254e1bc9a0SAchim Leubner 		saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
34264e1bc9a0SAchim Leubner 	  }
34274e1bc9a0SAchim Leubner 	  else
34284e1bc9a0SAchim Leubner 	  {
34294e1bc9a0SAchim Leubner 		saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
34304e1bc9a0SAchim Leubner 	  }
34314e1bc9a0SAchim Leubner 
34324e1bc9a0SAchim Leubner 	  /* Add the request to the pendingSMPRequests list of the device */
34334e1bc9a0SAchim Leubner 	  saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode));
34344e1bc9a0SAchim Leubner 	  SA_ASSERT((!pRequest->valid), "The pRequest is in use");
34354e1bc9a0SAchim Leubner 	  pRequest->valid			  = agTRUE;
34364e1bc9a0SAchim Leubner 	  ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
34374e1bc9a0SAchim Leubner 
34384e1bc9a0SAchim Leubner 	  /* set up pRequest */
34394e1bc9a0SAchim Leubner 	  pRequest->pIORequestContext = (agsaIORequest_t *)pRequest;
34404e1bc9a0SAchim Leubner 	  pRequest->pDevice 		  = pDevice;
34414e1bc9a0SAchim Leubner 	  pRequest->pPort			  = pPort;
34424e1bc9a0SAchim Leubner 	  pRequest->startTick		  = saRoot->timeTick;
34434e1bc9a0SAchim Leubner 	  pRequest->completionCB	  = (ossaSSPCompletedCB_t)agCB;
34444e1bc9a0SAchim Leubner 	  pRequest->requestType		  = AGSA_SMP_IOCTL_REQUEST;
34454e1bc9a0SAchim Leubner 
34464e1bc9a0SAchim Leubner 	  /* Set request to the sdkData of agIORequest */
34474e1bc9a0SAchim Leubner 	 // agIORequest->sdkData		  = pRequest;
34484e1bc9a0SAchim Leubner 
34494e1bc9a0SAchim Leubner 	  /* save tag to IOMap */
34504e1bc9a0SAchim Leubner 	  saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
34514e1bc9a0SAchim Leubner 	  saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
34524e1bc9a0SAchim Leubner 
34534e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
34544e1bc9a0SAchim Leubner 	  ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
34554e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
34564e1bc9a0SAchim Leubner 
34574e1bc9a0SAchim Leubner 	  /* If LL IO request entry avaliable */
34584e1bc9a0SAchim Leubner 	  /* Get a free inbound queue entry */
34594e1bc9a0SAchim Leubner 	  circularQ = &saRoot->inboundQueue[inq];
34604e1bc9a0SAchim Leubner 	  retVal	= mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage);
34614e1bc9a0SAchim Leubner 
34624e1bc9a0SAchim Leubner 	  if (AGSA_RC_FAILURE == retVal)
34634e1bc9a0SAchim Leubner 	  {
34644e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
34654e1bc9a0SAchim Leubner 		ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
34664e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
34674e1bc9a0SAchim Leubner 		/* if not sending return to free list rare */
34684e1bc9a0SAchim Leubner 		ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
34694e1bc9a0SAchim Leubner 		saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
34704e1bc9a0SAchim Leubner 		pRequest->valid = agFALSE;
34714e1bc9a0SAchim Leubner 		saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
34724e1bc9a0SAchim Leubner 		ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
34734e1bc9a0SAchim Leubner 
34744e1bc9a0SAchim Leubner 		SA_DBG1(("saSMPStart, error when get free IOMB\n"));
34754e1bc9a0SAchim Leubner 		smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "9a");
34764e1bc9a0SAchim Leubner 		return AGSA_RC_FAILURE;
34774e1bc9a0SAchim Leubner 	  }
34784e1bc9a0SAchim Leubner 
34794e1bc9a0SAchim Leubner 	  /* return busy if inbound queue is full */
34804e1bc9a0SAchim Leubner 	  if (AGSA_RC_BUSY == retVal)
34814e1bc9a0SAchim Leubner 	  {
34824e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
34834e1bc9a0SAchim Leubner 		ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
34844e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
34854e1bc9a0SAchim Leubner 		/* if not sending return to free list rare */
34864e1bc9a0SAchim Leubner 		ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
34874e1bc9a0SAchim Leubner 		saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
34884e1bc9a0SAchim Leubner 		pRequest->valid = agFALSE;
34894e1bc9a0SAchim Leubner 		saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
34904e1bc9a0SAchim Leubner 		ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
34914e1bc9a0SAchim Leubner 
34924e1bc9a0SAchim Leubner 		SA_DBG1(("saSMPStart, no more IOMB\n"));
34934e1bc9a0SAchim Leubner 		smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "9a");
34944e1bc9a0SAchim Leubner 		return AGSA_RC_BUSY;
34954e1bc9a0SAchim Leubner 	  }
34964e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
34974e1bc9a0SAchim Leubner 			  ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
34984e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
34994e1bc9a0SAchim Leubner 
35004e1bc9a0SAchim Leubner 
35014e1bc9a0SAchim Leubner 	if(smIS_SPC(agRoot))
35024e1bc9a0SAchim Leubner 	{
35034e1bc9a0SAchim Leubner 	 agsaSMPCmd_t payload;
35044e1bc9a0SAchim Leubner 
35054e1bc9a0SAchim Leubner 
35064e1bc9a0SAchim Leubner 		  bit32 IR_IP_OV_res_phyId_DPdLen_res = 0;
35074e1bc9a0SAchim Leubner 		  /* Prepare the payload of IOMB */
35084e1bc9a0SAchim Leubner 		  si_memset(&payload, 0, sizeof(agsaSMPCmd_V_t));
35094e1bc9a0SAchim Leubner 		  OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, tag), pRequest->HTag);
35104e1bc9a0SAchim Leubner 		  OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, deviceId), pDevice->DeviceMapIndex);
35114e1bc9a0SAchim Leubner 
35124e1bc9a0SAchim Leubner 
35134e1bc9a0SAchim Leubner 
35144e1bc9a0SAchim Leubner 		  /*Indirect request and response*/
35154e1bc9a0SAchim Leubner 		  if (smpFrameFlagIndirectResponse & pSMPFrame->flag && smpFrameFlagIndirectPayload & pSMPFrame->flag) /* */
35164e1bc9a0SAchim Leubner 		  {
35174e1bc9a0SAchim Leubner 
35184e1bc9a0SAchim Leubner 			SA_DBG2(("saSMPStart:V Indirect payload and indirect response\n"));
35194e1bc9a0SAchim Leubner 
35204e1bc9a0SAchim Leubner 			/* Indirect Response mode */
35214e1bc9a0SAchim Leubner 			pRequest->IRmode = INDIRECT_MODE;
35224e1bc9a0SAchim Leubner 			IR_IP_OV_res_phyId_DPdLen_res = 3;
35234e1bc9a0SAchim Leubner 
35244e1bc9a0SAchim Leubner 
35254e1bc9a0SAchim Leubner 			/* payload */
35264e1bc9a0SAchim Leubner 			OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[4]), (pSMPFrame->outFrameAddrLower32));
35274e1bc9a0SAchim Leubner 			OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[5]), (pSMPFrame->outFrameAddrUpper32));
35284e1bc9a0SAchim Leubner 			OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[6]), (pSMPFrame->outFrameLen));
35294e1bc9a0SAchim Leubner 
35304e1bc9a0SAchim Leubner 			OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[8]), (pSMPFrame->inFrameAddrLower32));
35314e1bc9a0SAchim Leubner 			OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[9]), (pSMPFrame->inFrameAddrUpper32));
35324e1bc9a0SAchim Leubner 			OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[10]), (pSMPFrame->inFrameLen));
35334e1bc9a0SAchim Leubner 
35344e1bc9a0SAchim Leubner 		  }
35354e1bc9a0SAchim Leubner 
35364e1bc9a0SAchim Leubner 
35374e1bc9a0SAchim Leubner 		  IR_IP_OV_res_phyId_DPdLen_res |= (pSMPFrame->flag & 3);
35384e1bc9a0SAchim Leubner 		  /* fatal error if missing */
35394e1bc9a0SAchim Leubner 		  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);
35404e1bc9a0SAchim Leubner 		  /* fatal error if missing */
35414e1bc9a0SAchim Leubner 
35424e1bc9a0SAchim Leubner 
35434e1bc9a0SAchim Leubner 		/* check IR bit */
35444e1bc9a0SAchim Leubner 
35454e1bc9a0SAchim Leubner 		/* Build IOMB command and send it to SPC */
35464e1bc9a0SAchim Leubner 		payload_ptr = (bit8 *)&payload;
35474e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
35484e1bc9a0SAchim Leubner 				ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
35494e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
35504e1bc9a0SAchim Leubner 
35514e1bc9a0SAchim Leubner 		ret = mpiSMPCmd(agRoot, pMessage, OPC_INB_SMP_REQUEST, (agsaSMPCmd_t *)payload_ptr, inq, outq);
35524e1bc9a0SAchim Leubner 
35534e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
35544e1bc9a0SAchim Leubner 			  ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
35554e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
35564e1bc9a0SAchim Leubner 
35574e1bc9a0SAchim Leubner 
35584e1bc9a0SAchim Leubner   }
35594e1bc9a0SAchim Leubner 	else /* IOMB is different for SPCV SMP */
35604e1bc9a0SAchim Leubner 	{
35614e1bc9a0SAchim Leubner 	 agsaSMPCmd_V_t vpayload;
35624e1bc9a0SAchim Leubner 
35634e1bc9a0SAchim Leubner 
35644e1bc9a0SAchim Leubner 		  bit32 IR_IP_OV_res_phyId_DPdLen_res = 0;
35654e1bc9a0SAchim Leubner 		  /* Prepare the payload of IOMB */
35664e1bc9a0SAchim Leubner 		  si_memset(&vpayload, 0, sizeof(agsaSMPCmd_V_t));
35674e1bc9a0SAchim Leubner 		  OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, tag), pRequest->HTag);
35684e1bc9a0SAchim Leubner 		  OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, deviceId), pDevice->DeviceMapIndex);
35694e1bc9a0SAchim Leubner 		  OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMPHDR ), *((bit32*)pSMPFrame->outFrameBuf+0) );
35704e1bc9a0SAchim Leubner 
35714e1bc9a0SAchim Leubner 		  /*Indirect request and response*/
35724e1bc9a0SAchim Leubner 		  if (smpFrameFlagIndirectResponse & pSMPFrame->flag && smpFrameFlagIndirectPayload & pSMPFrame->flag) /* */
35734e1bc9a0SAchim Leubner 		  {
35744e1bc9a0SAchim Leubner 
35754e1bc9a0SAchim Leubner 			SA_DBG2(("saSMPStart:V Indirect payload and indirect response\n"));
35764e1bc9a0SAchim Leubner 
35774e1bc9a0SAchim Leubner 			/* Indirect Response mode */
35784e1bc9a0SAchim Leubner 			pRequest->IRmode = INDIRECT_MODE;
35794e1bc9a0SAchim Leubner 			IR_IP_OV_res_phyId_DPdLen_res = 3;
35804e1bc9a0SAchim Leubner 
35814e1bc9a0SAchim Leubner 
35824e1bc9a0SAchim Leubner 			/* payload */
35834e1bc9a0SAchim Leubner 			OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirL_SMPRF15_12 ), (pSMPFrame->outFrameAddrLower32));
35844e1bc9a0SAchim Leubner 			OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirH_or_SMPRF19_16 ), (pSMPFrame->outFrameAddrUpper32));
35854e1bc9a0SAchim Leubner 			OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirLen_or_SMPRF23_20 ), (pSMPFrame->outFrameLen));
35864e1bc9a0SAchim Leubner 
35874e1bc9a0SAchim Leubner 			OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,ISRAL_or_SMPRF31_28), (pSMPFrame->inFrameAddrLower32));
35884e1bc9a0SAchim Leubner 			OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,ISRAH_or_SMPRF35_32), (pSMPFrame->inFrameAddrUpper32));
35894e1bc9a0SAchim Leubner 			OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,ISRL_or_SMPRF39_36), (pSMPFrame->inFrameLen));
35904e1bc9a0SAchim Leubner 
35914e1bc9a0SAchim Leubner 		  }
35924e1bc9a0SAchim Leubner 
35934e1bc9a0SAchim Leubner 		  /*Direct request and indirect response*/
35944e1bc9a0SAchim Leubner 		  else if (smpFrameFlagIndirectResponse & pSMPFrame->flag ) /* */
35954e1bc9a0SAchim Leubner 		  {
35964e1bc9a0SAchim Leubner 
35974e1bc9a0SAchim Leubner   			SA_DBG2(("saSMPStart:V Direct payload and indirect response\n"));
35984e1bc9a0SAchim Leubner 			IR_IP_OV_res_phyId_DPdLen_res = (pSMPFrame->outFrameLen << SHIFT16) | pSMPFrame->flag;
35994e1bc9a0SAchim Leubner 
36004e1bc9a0SAchim Leubner 
36014e1bc9a0SAchim Leubner 			  /* Write IR_IP_OV_res_phyId_DPdLen_res field in the payload*/
36024e1bc9a0SAchim Leubner 			  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);
36034e1bc9a0SAchim Leubner 			  /* setup indirect response frame address */
36044e1bc9a0SAchim Leubner 			  OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRAL_or_SMPRF31_28 ), (pSMPFrame->inFrameAddrLower32));
36054e1bc9a0SAchim Leubner 			  OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRAH_or_SMPRF35_32 ), (pSMPFrame->inFrameAddrUpper32));
36064e1bc9a0SAchim Leubner 			  OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRL_or_SMPRF39_36 ), (pSMPFrame->inFrameLen));
36074e1bc9a0SAchim Leubner 
36084e1bc9a0SAchim Leubner 		  }
36094e1bc9a0SAchim Leubner 		  IR_IP_OV_res_phyId_DPdLen_res |= (pSMPFrame->flag & 3);
36104e1bc9a0SAchim Leubner 		  /* fatal error if missing */
36114e1bc9a0SAchim Leubner 		  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);
36124e1bc9a0SAchim Leubner 		  /* fatal error if missing */
36134e1bc9a0SAchim Leubner 
36144e1bc9a0SAchim Leubner 
36154e1bc9a0SAchim Leubner 		/* check IR bit */
36164e1bc9a0SAchim Leubner 
36174e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
36184e1bc9a0SAchim Leubner 				ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
36194e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
36204e1bc9a0SAchim Leubner 		/* Build IOMB command and send it to SPCv */
36214e1bc9a0SAchim Leubner 		payload_ptr = (bit8 *)&vpayload;
36224e1bc9a0SAchim Leubner 		ret = mpiSMPCmd(agRoot, pMessage, OPC_INB_SMP_REQUEST, (agsaSMPCmd_t *)payload_ptr, inq, outq);
36234e1bc9a0SAchim Leubner 
36244e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
36254e1bc9a0SAchim Leubner 			  ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
36264e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
36274e1bc9a0SAchim Leubner 
36284e1bc9a0SAchim Leubner 
36294e1bc9a0SAchim Leubner   }
36304e1bc9a0SAchim Leubner 
36314e1bc9a0SAchim Leubner 
36324e1bc9a0SAchim Leubner   return ret;
36334e1bc9a0SAchim Leubner }
36344e1bc9a0SAchim Leubner 
36354e1bc9a0SAchim Leubner 
36364e1bc9a0SAchim Leubner /******************************************************************************/
36374e1bc9a0SAchim Leubner /*! \brief Reconfiguration of SAS Parameters Command
36384e1bc9a0SAchim Leubner  *
36394e1bc9a0SAchim Leubner  *  This command Reconfigure the SAS parameters to SPC.
36404e1bc9a0SAchim Leubner  *
36414e1bc9a0SAchim Leubner  *  \param agRoot       Handles for this instance of SAS/SATA LL
36424e1bc9a0SAchim Leubner  *  \param agContext    Context of SPC FW Flash Update Command
36434e1bc9a0SAchim Leubner  *  \param queueNum     Inbound/outbound queue number
36444e1bc9a0SAchim Leubner  *  \param agSASConfig  Pointer of SAS Configuration Parameters
36454e1bc9a0SAchim Leubner  *
36464e1bc9a0SAchim Leubner  *  \return If the MPI command is sent to SPC successfully
36474e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS the MPI command is successfully
36484e1bc9a0SAchim Leubner  *          - \e AGSA_RC_FAILURE the MPI command is failure
36494e1bc9a0SAchim Leubner  *
36504e1bc9a0SAchim Leubner  */
36514e1bc9a0SAchim Leubner /*******************************************************************************/
36524e1bc9a0SAchim Leubner //GLOBAL bit32 saReconfigSASParams(
saReconfigSASParams(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,agsaSASReconfig_t * agSASConfig)36534e1bc9a0SAchim Leubner bit32 saReconfigSASParams(
36544e1bc9a0SAchim Leubner   agsaRoot_t        *agRoot,
36554e1bc9a0SAchim Leubner   agsaContext_t     *agContext,
36564e1bc9a0SAchim Leubner   bit32             queueNum ,
36574e1bc9a0SAchim Leubner   agsaSASReconfig_t *agSASConfig
36584e1bc9a0SAchim Leubner   )
36594e1bc9a0SAchim Leubner {
36604e1bc9a0SAchim Leubner   bit32 ret           = AGSA_RC_SUCCESS;
36614e1bc9a0SAchim Leubner 
36624e1bc9a0SAchim Leubner   /* sanity check */
36634e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
36644e1bc9a0SAchim Leubner 
36654e1bc9a0SAchim Leubner   if(smIS_SPCV(agRoot))
36664e1bc9a0SAchim Leubner   {
36674e1bc9a0SAchim Leubner     SA_DBG1(("saReconfigSASParams: AGSA_RC_FAILURE for SPCv\n" ));
36684e1bc9a0SAchim Leubner     return(AGSA_RC_FAILURE);
36694e1bc9a0SAchim Leubner   }
36704e1bc9a0SAchim Leubner 
36714e1bc9a0SAchim Leubner   /* build IOMB command and send to SPC */
36724e1bc9a0SAchim Leubner   ret = mpiSasReinitializeCmd(agRoot, agContext, agSASConfig, queueNum);
36734e1bc9a0SAchim Leubner 
36744e1bc9a0SAchim Leubner   return ret;
36754e1bc9a0SAchim Leubner }
36764e1bc9a0SAchim Leubner 
36774e1bc9a0SAchim Leubner /******************************************************************************/
36784e1bc9a0SAchim Leubner /*! \brief Dump GSM registers from the controller
36794e1bc9a0SAchim Leubner  *
36804e1bc9a0SAchim Leubner  *  \param agRoot         Handles for this instance of SAS/SATA hardware
36814e1bc9a0SAchim Leubner  *  \param gsmDumpOffset  Offset of GSM
36824e1bc9a0SAchim Leubner  *  \param length         Max is 1 MB
36834e1bc9a0SAchim Leubner  *  \param directData     address of GSM data dump to
36844e1bc9a0SAchim Leubner  *
36854e1bc9a0SAchim Leubner  *  \return
36864e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS saGSMDump is successfully
36874e1bc9a0SAchim Leubner  *          - \e AGSA_RC_FAILURE saGSMDump is not successfully
36884e1bc9a0SAchim Leubner  *
36894e1bc9a0SAchim Leubner  */
36904e1bc9a0SAchim Leubner /*******************************************************************************/
36914e1bc9a0SAchim Leubner //LOCAL bit32 siGSMDump(
siGSMDump(agsaRoot_t * agRoot,bit32 gsmDumpOffset,bit32 length,void * directData)36924e1bc9a0SAchim Leubner bit32 siGSMDump(
36934e1bc9a0SAchim Leubner   agsaRoot_t     *agRoot,
36944e1bc9a0SAchim Leubner   bit32          gsmDumpOffset,
36954e1bc9a0SAchim Leubner   bit32          length,
36964e1bc9a0SAchim Leubner   void           *directData)
36974e1bc9a0SAchim Leubner {
36984e1bc9a0SAchim Leubner   bit8  *dst;
36994e1bc9a0SAchim Leubner   bit32 value, rem, offset = 0;
37004e1bc9a0SAchim Leubner   bit32 i, workOffset, dwLength;
37014e1bc9a0SAchim Leubner   bit32 bar = 0;
37024e1bc9a0SAchim Leubner 
37034e1bc9a0SAchim Leubner   SA_DBG1(("siGSMDump: gsmDumpOffset 0x%x length 0x%x\n", gsmDumpOffset, length));
37044e1bc9a0SAchim Leubner 
37054e1bc9a0SAchim Leubner   /* check max is 64k chunks */
37064e1bc9a0SAchim Leubner   if (length > (64 * 1024))
37074e1bc9a0SAchim Leubner   {
37084e1bc9a0SAchim Leubner     SA_DBG1(("siGSMDump: Max length is greater than 64K  bytes 0x%x\n", length));
37094e1bc9a0SAchim Leubner     return AGSA_RC_FAILURE;
37104e1bc9a0SAchim Leubner   }
37114e1bc9a0SAchim Leubner 
37124e1bc9a0SAchim Leubner   if (gsmDumpOffset & 3)
37134e1bc9a0SAchim Leubner   {
37144e1bc9a0SAchim Leubner     SA_DBG1(("siGSMDump: Not allow NON_DW Boundary 0x%x\n", gsmDumpOffset));
37154e1bc9a0SAchim Leubner     return AGSA_RC_FAILURE;
37164e1bc9a0SAchim Leubner   }
37174e1bc9a0SAchim Leubner 
37184e1bc9a0SAchim Leubner   if ((gsmDumpOffset + length) > ONE_MEGABYTE)
37194e1bc9a0SAchim Leubner   {
37204e1bc9a0SAchim Leubner     SA_DBG1(("siGSMDump: Out of GSM end address boundary 0x%x\n", (gsmDumpOffset+length)));
37214e1bc9a0SAchim Leubner     return AGSA_RC_FAILURE;
37224e1bc9a0SAchim Leubner   }
37234e1bc9a0SAchim Leubner 
37244e1bc9a0SAchim Leubner   if( smIS_SPCV(agRoot))
37254e1bc9a0SAchim Leubner   {
37264e1bc9a0SAchim Leubner     bar = PCIBAR1;
37274e1bc9a0SAchim Leubner   }
37284e1bc9a0SAchim Leubner   else if( smIS_SPC(agRoot))
37294e1bc9a0SAchim Leubner   {
37304e1bc9a0SAchim Leubner     bar = PCIBAR2;
37314e1bc9a0SAchim Leubner   }
37324e1bc9a0SAchim Leubner   else
37334e1bc9a0SAchim Leubner   {
37344e1bc9a0SAchim Leubner     SA_DBG1(("siGSMDump: device type is not supported"));
37354e1bc9a0SAchim Leubner     return AGSA_RC_FAILURE;
37364e1bc9a0SAchim Leubner   }
37374e1bc9a0SAchim Leubner 
37384e1bc9a0SAchim Leubner   workOffset = gsmDumpOffset & 0xFFFF0000;
37394e1bc9a0SAchim Leubner   offset = gsmDumpOffset & 0x0000FFFF;
37404e1bc9a0SAchim Leubner   gsmDumpOffset = workOffset;
37414e1bc9a0SAchim Leubner 
37424e1bc9a0SAchim Leubner   dst = (bit8 *)directData;
37434e1bc9a0SAchim Leubner 
37444e1bc9a0SAchim Leubner   /* adjust length to dword boundary */
37454e1bc9a0SAchim Leubner   rem = length & 3;
37464e1bc9a0SAchim Leubner   dwLength = length >> 2;
37474e1bc9a0SAchim Leubner 
37484e1bc9a0SAchim Leubner   for (i =0; i < dwLength; i++)
37494e1bc9a0SAchim Leubner   {
37504e1bc9a0SAchim Leubner     if((workOffset + offset) > length )
37514e1bc9a0SAchim Leubner     {
37524e1bc9a0SAchim Leubner       break;
37534e1bc9a0SAchim Leubner     }
37544e1bc9a0SAchim Leubner     value = ossaHwRegReadExt(agRoot, bar, (workOffset + offset) & 0x0000FFFF);
37554e1bc9a0SAchim Leubner     /* xfr for dw */
37564e1bc9a0SAchim Leubner     si_memcpy(dst, &value, 4);
37574e1bc9a0SAchim Leubner     dst += 4;
37584e1bc9a0SAchim Leubner     offset += 4;
37594e1bc9a0SAchim Leubner   }
37604e1bc9a0SAchim Leubner 
37614e1bc9a0SAchim Leubner   if (rem != 0)
37624e1bc9a0SAchim Leubner   {
37634e1bc9a0SAchim Leubner     value = ossaHwRegReadExt(agRoot, bar, (workOffset + offset) & 0x0000FFFF);
37644e1bc9a0SAchim Leubner     /* xfr for non_dw */
37654e1bc9a0SAchim Leubner     if(dst)
37664e1bc9a0SAchim Leubner     {
37674e1bc9a0SAchim Leubner       si_memcpy(dst, &value, rem);
37684e1bc9a0SAchim Leubner     }
37694e1bc9a0SAchim Leubner   }
37704e1bc9a0SAchim Leubner 
37714e1bc9a0SAchim Leubner   /* Shift back to BAR4 original address */
37724e1bc9a0SAchim Leubner   if (AGSA_RC_FAILURE == siBar4Shift(agRoot, 0x0))
37734e1bc9a0SAchim Leubner   {
37744e1bc9a0SAchim Leubner     SA_DBG1(("siGSMDump:Shift Bar4 to 0x%x failed\n", 0x0));
37754e1bc9a0SAchim Leubner     return AGSA_RC_FAILURE;
37764e1bc9a0SAchim Leubner   }
37774e1bc9a0SAchim Leubner 
37784e1bc9a0SAchim Leubner   return AGSA_RC_SUCCESS;
37794e1bc9a0SAchim Leubner }
37804e1bc9a0SAchim Leubner 
37814e1bc9a0SAchim Leubner //GLOBAL bit32 saPCIeDiagExecute(
saPCIeDiagExecute(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,agsaPCIeDiagExecute_t * diag)37824e1bc9a0SAchim Leubner bit32 saPCIeDiagExecute(
37834e1bc9a0SAchim Leubner             agsaRoot_t            *agRoot,
37844e1bc9a0SAchim Leubner             agsaContext_t         *agContext,
37854e1bc9a0SAchim Leubner             bit32                 queueNum,
37864e1bc9a0SAchim Leubner             agsaPCIeDiagExecute_t *diag)
37874e1bc9a0SAchim Leubner {
37884e1bc9a0SAchim Leubner   bit32                    ret    = AGSA_RC_SUCCESS;
37894e1bc9a0SAchim Leubner   agsaLLRoot_t            *saRoot = agNULL;
37904e1bc9a0SAchim Leubner   agsaIORequestDesc_t     *pRequest;
37914e1bc9a0SAchim Leubner   bit32  payload[32];
37924e1bc9a0SAchim Leubner 
37934e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"6r");
37944e1bc9a0SAchim Leubner 
37954e1bc9a0SAchim Leubner   /* sanity check */
37964e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
37974e1bc9a0SAchim Leubner 
37984e1bc9a0SAchim Leubner   saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
37994e1bc9a0SAchim Leubner   /* sanity check */
38004e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != saRoot), "");
38014e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != diag), "");
38024e1bc9a0SAchim Leubner 
38034e1bc9a0SAchim Leubner   if(diag->len == 0)
38044e1bc9a0SAchim Leubner   {
38054e1bc9a0SAchim Leubner     SA_DBG1(("saPCIeDiagExecute,  diag->len Zero\n"));
38064e1bc9a0SAchim Leubner   }
38074e1bc9a0SAchim Leubner   SA_DBG1(("saPCIeDiagExecute, diag->command  0x%X\n", diag->command ));
38084e1bc9a0SAchim Leubner   SA_DBG1(("saPCIeDiagExecute, diag->flags  0x%X\n",diag->flags ));
38094e1bc9a0SAchim Leubner   SA_DBG1(("saPCIeDiagExecute,  diag->initialIOSeed  0x%X\n", diag->initialIOSeed));
38104e1bc9a0SAchim Leubner   SA_DBG1(("saPCIeDiagExecute, diag->reserved   0x%X\n",diag->reserved ));
38114e1bc9a0SAchim Leubner   SA_DBG1(("saPCIeDiagExecute, diag->rdAddrLower   0x%X\n", diag->rdAddrLower));
38124e1bc9a0SAchim Leubner   SA_DBG1(("saPCIeDiagExecute, diag->rdAddrUpper   0x%X\n", diag->rdAddrUpper ));
38134e1bc9a0SAchim Leubner   SA_DBG1(("saPCIeDiagExecute, diag->wrAddrLower   0x%X\n", diag->wrAddrLower));
38144e1bc9a0SAchim Leubner   SA_DBG1(("saPCIeDiagExecute, diag->wrAddrUpper   0x%X\n",diag->wrAddrUpper ));
38154e1bc9a0SAchim Leubner   SA_DBG1(("saPCIeDiagExecute,  diag->len   0x%X\n",diag->len  ));
38164e1bc9a0SAchim Leubner   SA_DBG1(("saPCIeDiagExecute, diag->pattern  0x%X\n",diag->pattern ));
38174e1bc9a0SAchim Leubner   SA_DBG1(("saPCIeDiagExecute, %02X %02X %02X %02X %02X %02X\n",
38184e1bc9a0SAchim Leubner                   diag->udtArray[0],
38194e1bc9a0SAchim Leubner                   diag->udtArray[1],
38204e1bc9a0SAchim Leubner                   diag->udtArray[2],
38214e1bc9a0SAchim Leubner                   diag->udtArray[3],
38224e1bc9a0SAchim Leubner                   diag->udtArray[4],
38234e1bc9a0SAchim Leubner                   diag->udtArray[5] ));
38244e1bc9a0SAchim Leubner 
38254e1bc9a0SAchim Leubner    SA_DBG1(("saPCIeDiagExecute, %02X %02X %02X %02X %02X %02X\n",
38264e1bc9a0SAchim Leubner                   diag->udrtArray[0],
38274e1bc9a0SAchim Leubner                   diag->udrtArray[1],
38284e1bc9a0SAchim Leubner                   diag->udrtArray[2],
38294e1bc9a0SAchim Leubner                   diag->udrtArray[3],
38304e1bc9a0SAchim Leubner                   diag->udrtArray[4],
38314e1bc9a0SAchim Leubner                   diag->udrtArray[5]));
38324e1bc9a0SAchim Leubner 
38334e1bc9a0SAchim Leubner 
38344e1bc9a0SAchim Leubner   /* Get request from free IORequests */
38354e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
38364e1bc9a0SAchim Leubner   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
38374e1bc9a0SAchim Leubner 
38384e1bc9a0SAchim Leubner   /* If no LL Control request entry available */
38394e1bc9a0SAchim Leubner   if ( agNULL == pRequest )
38404e1bc9a0SAchim Leubner   {
38414e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
38424e1bc9a0SAchim Leubner     SA_DBG1(("saPCIeDiagExecute, No request from free list\n" ));
38434e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6r");
38444e1bc9a0SAchim Leubner     return AGSA_RC_BUSY;
38454e1bc9a0SAchim Leubner   }
38464e1bc9a0SAchim Leubner   /* If LL Control request entry avaliable */
38474e1bc9a0SAchim Leubner   /* Remove the request from free list */
38484e1bc9a0SAchim Leubner   saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
38494e1bc9a0SAchim Leubner   saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
38504e1bc9a0SAchim Leubner   saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
38514e1bc9a0SAchim Leubner   saRoot->IOMap[pRequest->HTag].agContext = agContext;
38524e1bc9a0SAchim Leubner   pRequest->valid = agTRUE;
38534e1bc9a0SAchim Leubner 
38544e1bc9a0SAchim Leubner   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
38554e1bc9a0SAchim Leubner 
38564e1bc9a0SAchim Leubner   /* set payload to zeros */
38574e1bc9a0SAchim Leubner   si_memset(&payload, 0, sizeof(payload));
38584e1bc9a0SAchim Leubner 
38594e1bc9a0SAchim Leubner   if(smIS_SPCV(agRoot))
38604e1bc9a0SAchim Leubner   {
38614e1bc9a0SAchim Leubner     bit32      UDTR1_UDT0 ,UDT5_UDT2,UDTR5_UDTR2;
38624e1bc9a0SAchim Leubner 
38634e1bc9a0SAchim Leubner     UDTR5_UDTR2 = (( diag->udrtArray[5] << SHIFT24) | (diag->udrtArray[4] << SHIFT16) | (diag->udrtArray[3] << SHIFT8) | diag->udrtArray[2]);
38644e1bc9a0SAchim Leubner     UDT5_UDT2 =   ((  diag->udtArray[5] << SHIFT24) |  (diag->udtArray[4] << SHIFT16) |  (diag->udtArray[3] << SHIFT8) |  diag->udtArray[2]);
38654e1bc9a0SAchim Leubner     UDTR1_UDT0 =  (( diag->udrtArray[1] << SHIFT24) | (diag->udrtArray[0] << SHIFT16) |  (diag->udtArray[1] << SHIFT8) |  diag->udtArray[0]);
38664e1bc9a0SAchim Leubner 
38674e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, tag)        , pRequest->HTag);
38684e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, CmdTypeDesc), diag->command );
38694e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, UUM_EDA)    , diag->flags);
38704e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, UDTR1_UDT0) , UDTR1_UDT0);
38714e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, UDT5_UDT2)  , UDT5_UDT2);
38724e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, UDTR5_UDTR2), UDTR5_UDTR2);
38734e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, Res_IOS)    , diag->initialIOSeed);
38744e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, rdAddrLower), diag->rdAddrLower);
38754e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, rdAddrUpper), diag->rdAddrUpper);
38764e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, wrAddrLower), diag->wrAddrLower);
38774e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, wrAddrUpper), diag->wrAddrUpper);
38784e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, len),         diag->len);
38794e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, pattern),     diag->pattern);
38804e1bc9a0SAchim Leubner     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_PCIE_DIAG_EXECUTE, IOMB_SIZE128, queueNum);
38814e1bc9a0SAchim Leubner   }
38824e1bc9a0SAchim Leubner   else
38834e1bc9a0SAchim Leubner   {
38844e1bc9a0SAchim Leubner     /* build IOMB command and send to SPC */
38854e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, tag),         pRequest->HTag);
38864e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, CmdTypeDesc), diag->command );
38874e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, rdAddrLower), diag->rdAddrLower);
38884e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, rdAddrUpper), diag->rdAddrUpper);
38894e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, wrAddrLower), diag->wrAddrLower);
38904e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, wrAddrUpper), diag->wrAddrUpper);
38914e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, len),         diag->len);
38924e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, pattern),     diag->pattern);
38934e1bc9a0SAchim Leubner     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_PCIE_DIAG_EXECUTE, IOMB_SIZE64, queueNum);
38944e1bc9a0SAchim Leubner   }
38954e1bc9a0SAchim Leubner 
38964e1bc9a0SAchim Leubner   if (AGSA_RC_SUCCESS != ret)
38974e1bc9a0SAchim Leubner   {
38984e1bc9a0SAchim Leubner     /* remove the request from IOMap */
38994e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
39004e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
39014e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].agContext = agNULL;
39024e1bc9a0SAchim Leubner 
39034e1bc9a0SAchim Leubner     ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
39044e1bc9a0SAchim Leubner     pRequest->valid = agFALSE;
39054e1bc9a0SAchim Leubner 
39064e1bc9a0SAchim Leubner     /* return the request to free pool */
39074e1bc9a0SAchim Leubner     saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
39084e1bc9a0SAchim Leubner 
39094e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
39104e1bc9a0SAchim Leubner 
39114e1bc9a0SAchim Leubner     SA_DBG1(("saPCIeDiagExecute, sending IOMB failed\n" ));
39124e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6r");
39134e1bc9a0SAchim Leubner 
39144e1bc9a0SAchim Leubner     return ret;
39154e1bc9a0SAchim Leubner   }
39164e1bc9a0SAchim Leubner 
39174e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "6r");
39184e1bc9a0SAchim Leubner   return ret;
39194e1bc9a0SAchim Leubner }
39204e1bc9a0SAchim Leubner 
39214e1bc9a0SAchim Leubner //GLOBAL bit32 saGetDFEData(
saGetDFEData(agsaRoot_t * agRoot,agsaContext_t * agContext,bit32 queueNum,bit32 interface,bit32 laneNumber,bit32 interations,agsaSgl_t * agSgl)39224e1bc9a0SAchim Leubner bit32 saGetDFEData(
39234e1bc9a0SAchim Leubner                           agsaRoot_t     *agRoot,
39244e1bc9a0SAchim Leubner                           agsaContext_t  *agContext,
39254e1bc9a0SAchim Leubner                           bit32           queueNum,
39264e1bc9a0SAchim Leubner                           bit32           interface,
39274e1bc9a0SAchim Leubner                           bit32           laneNumber,
39284e1bc9a0SAchim Leubner                           bit32           interations,
39294e1bc9a0SAchim Leubner                           agsaSgl_t      *agSgl)
39304e1bc9a0SAchim Leubner {
39314e1bc9a0SAchim Leubner   bit32                    ret    = AGSA_RC_SUCCESS;
39324e1bc9a0SAchim Leubner   agsaLLRoot_t            *saRoot = agNULL;
39334e1bc9a0SAchim Leubner   agsaIORequestDesc_t     *pRequest = agNULL;
39344e1bc9a0SAchim Leubner   bit32  payload[32];
39354e1bc9a0SAchim Leubner   bit32 reserved_In_Ln;
39364e1bc9a0SAchim Leubner 
39374e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"2X");
39384e1bc9a0SAchim Leubner   /* sanity check */
39394e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
39404e1bc9a0SAchim Leubner   saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
39414e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != saRoot), "");
39424e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agSgl), "");
39434e1bc9a0SAchim Leubner 
39444e1bc9a0SAchim Leubner   /* Get request from free IORequests */
39454e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
39464e1bc9a0SAchim Leubner   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
39474e1bc9a0SAchim Leubner 
39484e1bc9a0SAchim Leubner   /* If no LL Control request entry available */
39494e1bc9a0SAchim Leubner   if ( agNULL == pRequest )
39504e1bc9a0SAchim Leubner   {
39514e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
39524e1bc9a0SAchim Leubner     SA_DBG1(("saGetDFEData, No request from free list\n" ));
39534e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2X");
39544e1bc9a0SAchim Leubner     return AGSA_RC_BUSY;
39554e1bc9a0SAchim Leubner   }
39564e1bc9a0SAchim Leubner   /* If LL Control request entry avaliable */
39574e1bc9a0SAchim Leubner   /* Remove the request from free list */
39584e1bc9a0SAchim Leubner   saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
39594e1bc9a0SAchim Leubner   saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
39604e1bc9a0SAchim Leubner   saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
39614e1bc9a0SAchim Leubner   saRoot->IOMap[pRequest->HTag].agContext = agContext;
39624e1bc9a0SAchim Leubner   pRequest->valid = agTRUE;
39634e1bc9a0SAchim Leubner 
39644e1bc9a0SAchim Leubner   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
39654e1bc9a0SAchim Leubner 
39664e1bc9a0SAchim Leubner   /* set payload to zeros */
39674e1bc9a0SAchim Leubner   si_memset(&payload, 0, sizeof(payload));
39684e1bc9a0SAchim Leubner 
39694e1bc9a0SAchim Leubner   if(smIS_SPCV(agRoot))
39704e1bc9a0SAchim Leubner   {
39714e1bc9a0SAchim Leubner     reserved_In_Ln = ((interface & 0x1) << SHIFT7) | (laneNumber & 0x7F);
39724e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDDEFDataCmd_t, tag)        , pRequest->HTag);
39734e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDDEFDataCmd_t, reserved_In_Ln)        , reserved_In_Ln);
39744e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDDEFDataCmd_t, MCNT)        , interations);
39754e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDDEFDataCmd_t, Buf_AddrL)        , agSgl->sgLower);
39764e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDDEFDataCmd_t, Buf_AddrH)        , agSgl->sgUpper);
39774e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDDEFDataCmd_t, Buf_Len)        , agSgl->len);
39784e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDDEFDataCmd_t, E_reserved)        , agSgl->extReserved);
39794e1bc9a0SAchim Leubner     ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_DFE_DATA, IOMB_SIZE128, queueNum);
39804e1bc9a0SAchim Leubner 
39814e1bc9a0SAchim Leubner   }
39824e1bc9a0SAchim Leubner   else
39834e1bc9a0SAchim Leubner   {
39844e1bc9a0SAchim Leubner     /* SPC does not support this command */
39854e1bc9a0SAchim Leubner     ret = AGSA_RC_FAILURE;
39864e1bc9a0SAchim Leubner   }
39874e1bc9a0SAchim Leubner 
39884e1bc9a0SAchim Leubner   if (AGSA_RC_SUCCESS != ret)
39894e1bc9a0SAchim Leubner   {
39904e1bc9a0SAchim Leubner     /* remove the request from IOMap */
39914e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
39924e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
39934e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].agContext = agNULL;
39944e1bc9a0SAchim Leubner 
39954e1bc9a0SAchim Leubner     ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
39964e1bc9a0SAchim Leubner     pRequest->valid = agFALSE;
39974e1bc9a0SAchim Leubner     /* return the request to free pool */
39984e1bc9a0SAchim Leubner     saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
39994e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
40004e1bc9a0SAchim Leubner 
40014e1bc9a0SAchim Leubner     SA_DBG1(("saPCIeDiagExecute, sending IOMB failed\n" ));
40024e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2X");
40034e1bc9a0SAchim Leubner     return ret;
40044e1bc9a0SAchim Leubner   }
40054e1bc9a0SAchim Leubner 
40064e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2X");
40074e1bc9a0SAchim Leubner   return ret;
40084e1bc9a0SAchim Leubner }
40094e1bc9a0SAchim Leubner 
4010