1285809Sscottl/*******************************************************************************
2285809Sscottl*Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved.
3285809Sscottl*
4285809Sscottl*Redistribution and use in source and binary forms, with or without modification, are permitted provided
5285809Sscottl*that the following conditions are met:
6285809Sscottl*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
7285809Sscottl*following disclaimer.
8285809Sscottl*2. Redistributions in binary form must reproduce the above copyright notice,
9285809Sscottl*this list of conditions and the following disclaimer in the documentation and/or other materials provided
10285809Sscottl*with the distribution.
11285809Sscottl*
12285809Sscottl*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13285809Sscottl*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14285809Sscottl*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15285809Sscottl*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16285809Sscottl*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17285809Sscottl*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18285809Sscottl*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19285809Sscottl*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
20285809Sscottl
21285809Sscottl********************************************************************************/
22285809Sscottl/*******************************************************************************/
23285809Sscottl/*! \file saioctlcmd.c
24285809Sscottl *  \brief The file implements the functions of IOCTL MPI Command/Response to/from SPC
25285809Sscottl *
26285809Sscottl */
27285809Sscottl/******************************************************************************/
28285809Sscottl#include <sys/cdefs.h>
29285809Sscottl__FBSDID("$FreeBSD$");
30285809Sscottl#include <dev/pms/config.h>
31285809Sscottl
32285809Sscottl#include <dev/pms/RefTisa/sallsdk/spc/saglobal.h>
33285809Sscottl#ifdef SA_ENABLE_TRACE_FUNCTIONS
34285809Sscottl#ifdef siTraceFileID
35285809Sscottl#undef siTraceFileID
36285809Sscottl#endif
37285809Sscottl#define siTraceFileID 'H'
38285809Sscottl#endif
39285809Sscottl
40285809Sscottlextern bit32 gFPGA_TEST;
41285809Sscottl
42285809Sscottlextern bit32 gWait_3;
43285809Sscottlextern bit32 gWait_2;
44285809Sscottl
45285809Sscottl
46285809Sscottl
47285809SscottlLOCAL bit32 siGSMDump(
48285809Sscottl                      agsaRoot_t     *agRoot,
49285809Sscottl                      bit32          gsmDumpOffset,
50285809Sscottl                      bit32          length,
51285809Sscottl                      void           *directData);
52285809Sscottl
53285809Sscottl#ifdef SPC_ENABLE_PROFILE
54285809Sscottl/******************************************************************************/
55285809Sscottl/*! \brief SPC FW Profile Command
56285809Sscottl *
57285809Sscottl *  This command sends FW Flash Update Command to SPC.
58285809Sscottl *
59285809Sscottl *  \param agRoot          Handles for this instance of SAS/SATA LL
60285809Sscottl *  \param agContext       Context of SPC FW Flash Update Command
61285809Sscottl *  \param queueNum        Inbound/outbound queue number
62285809Sscottl *  \param flashUpdateInfo Pointer of flash update information
63285809Sscottl *
64285809Sscottl *  \return If the MPI command is sent to SPC successfully
65285809Sscottl *          - \e AGSA_RC_SUCCESS the MPI command is successfully
66285809Sscottl *          - \e AGSA_RC_FAILURE the MPI command is failure
67285809Sscottl *
68285809Sscottl */
69285809Sscottl/*******************************************************************************/
70285809SscottlGLOBAL bit32 saFwProfile(
71285809Sscottl  agsaRoot_t                *agRoot,
72285809Sscottl  agsaContext_t             *agContext,
73285809Sscottl  bit32                     queueNum,
74285809Sscottl  agsaFwProfile_t         *fwProfileInfo
75285809Sscottl  )
76285809Sscottl{
77285809Sscottl  bit32 ret           = AGSA_RC_SUCCESS, retVal;
78285809Sscottl  agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
79285809Sscottl  agsaIORequestDesc_t *pRequest;
80285809Sscottl  mpiICQueue_t        *circularQ;
81285809Sscottl  void                *pMessage;
82285809Sscottl  agsaFwProfileIOMB_t *pPayload;
83285809Sscottl  bit8                inq, outq;
84285809Sscottl  bit32               i, tcid_processor_cmd = 0;
85285809Sscottl
86285809Sscottl
87285809Sscottl  /* sanity check */
88285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
89285809Sscottl
90285809Sscottl  /* Get request from free IORequests */
91285809Sscottl  ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
92285809Sscottl  pRequest = (agsaIORequestDesc_t *)saLlistGetHead(&(saRoot->freeIORequests));
93285809Sscottl
94285809Sscottl  /* If no LL Control request entry avaliable */
95285809Sscottl  if ( agNULL == pRequest )
96285809Sscottl  {
97285809Sscottl    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
98285809Sscottl    SA_DBG1(("saFwProfile, No request from free list\n" ));
99285809Sscottl     return AGSA_RC_BUSY;
100285809Sscottl  }
101285809Sscottl  /* If LL Control request entry avaliable */
102285809Sscottl  else
103285809Sscottl  {
104285809Sscottl    /* Assign inbound and outbound Ring Buffer */
105285809Sscottl    inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
106285809Sscottl    outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
107285809Sscottl    SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
108285809Sscottl
109285809Sscottl    /* Remove the request from free list */
110285809Sscottl    saLlistRemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
111285809Sscottl    saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
112285809Sscottl    saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
113285809Sscottl    saRoot->IOMap[pRequest->HTag].agContext = agContext;
114285809Sscottl    pRequest->valid = agTRUE;
115285809Sscottl    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
116285809Sscottl
117285809Sscottl#ifdef SA_LL_IBQ_PROTECT
118285809Sscottl    ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
119285809Sscottl#endif /* SA_LL_IBQ_PROTECT */
120285809Sscottl    /* Get a free inbound queue entry */
121285809Sscottl    circularQ = &saRoot->inboundQueue[inq];
122285809Sscottl    retVal    = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage);
123285809Sscottl
124285809Sscottl    /* if message size is too large return failure */
125285809Sscottl    if (AGSA_RC_FAILURE == retVal)
126285809Sscottl    {
127285809Sscottl#ifdef SA_LL_IBQ_PROTECT
128285809Sscottl      ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
129285809Sscottl#endif  /* SA_LL_IBQ_PROTECT */
130285809Sscottl      ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
131285809Sscottl      /* remove the request from IOMap */
132285809Sscottl      saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
133285809Sscottl      saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
134285809Sscottl      saRoot->IOMap[pRequest->HTag].agContext = agNULL;
135285809Sscottl      pRequest->valid = agFALSE;
136285809Sscottl      /* return the request to free pool */
137285809Sscottl      saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
138285809Sscottl      ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
139285809Sscottl
140285809Sscottl      SA_DBG1(("saFwProfile, error when get free IOMB\n"));
141285809Sscottl      return AGSA_RC_FAILURE;
142285809Sscottl    }
143285809Sscottl
144285809Sscottl    /* return busy if inbound queue is full */
145285809Sscottl    if (AGSA_RC_BUSY == retVal)
146285809Sscottl    {
147285809Sscottl#ifdef SA_LL_IBQ_PROTECT
148285809Sscottl      ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
149285809Sscottl#endif /* SA_LL_IBQ_PROTECT */
150285809Sscottl
151285809Sscottl      ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
152285809Sscottl      /* remove the request from IOMap */
153285809Sscottl      saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
154285809Sscottl      saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
155285809Sscottl      saRoot->IOMap[pRequest->HTag].agContext = agNULL;
156285809Sscottl      pRequest->valid = agFALSE;
157285809Sscottl      /* return the request to free pool */
158285809Sscottl      saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
159285809Sscottl      ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
160285809Sscottl      SA_DBG1(("saFwProfile, no more IOMB\n"));
161285809Sscottl      return AGSA_RC_BUSY;
162285809Sscottl    }
163285809Sscottl
164285809Sscottl    pPayload = (agsaFwProfileIOMB_t *)pMessage;
165285809Sscottl    tcid_processor_cmd = (((fwProfileInfo->tcid)<< 16) | ((fwProfileInfo->processor)<< 8) | fwProfileInfo->cmd);
166285809Sscottl  /* Prepare the FW_FLASH_UPDATE IOMB payload */
167285809Sscottl    OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwProfileIOMB_t, tag), pRequest->HTag);
168285809Sscottl    OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwProfileIOMB_t, tcid_processor_cmd), tcid_processor_cmd);
169285809Sscottl    OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwProfileIOMB_t, codeStartAdd), fwProfileInfo->codeStartAdd);
170285809Sscottl    OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwProfileIOMB_t, codeEndAdd), fwProfileInfo->codeEndAdd);
171285809Sscottl
172285809Sscottl    pPayload->SGLAL = fwProfileInfo->agSgl.sgLower;
173285809Sscottl    pPayload->SGLAH = fwProfileInfo->agSgl.sgUpper;
174285809Sscottl    pPayload->Len = fwProfileInfo->agSgl.len;
175285809Sscottl    pPayload->extReserved = fwProfileInfo->agSgl.extReserved;
176285809Sscottl
177285809Sscottl    /* fill up the reserved bytes with zero */
178285809Sscottl    for (i = 0; i < FWPROFILE_IOMB_RESERVED_LEN; i ++)
179285809Sscottl    {
180285809Sscottl      pPayload->reserved0[i] = 0;
181285809Sscottl    }
182285809Sscottl
183285809Sscottl    /* post the IOMB to SPC */
184285809Sscottl    ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_FW_PROFILE, outq, (bit8)circularQ->priority);
185285809Sscottl
186285809Sscottl#ifdef SA_LL_IBQ_PROTECT
187285809Sscottl    ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
188285809Sscottl#endif /* SA_LL_IBQ_PROTECT */
189285809Sscottl
190285809Sscottl    if (AGSA_RC_FAILURE == ret)
191285809Sscottl    {
192285809Sscottl      ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
193285809Sscottl      /* remove the request from IOMap */
194285809Sscottl      saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
195285809Sscottl      saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
196285809Sscottl      saRoot->IOMap[pRequest->HTag].agContext = agNULL;
197285809Sscottl      pRequest->valid = agFALSE;
198285809Sscottl      /* return the request to free pool */
199285809Sscottl      saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
200285809Sscottl      ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
201285809Sscottl      SA_DBG1(("saFwProfile, error when post FW_PROFILE IOMB\n"));
202285809Sscottl    }
203285809Sscottl  }
204285809Sscottl  return ret;
205285809Sscottl}
206285809Sscottl#endif
207285809Sscottl/******************************************************************************/
208285809Sscottl/*! \brief SPC FW Flash Update Command
209285809Sscottl *
210285809Sscottl *  This command sends FW Flash Update Command to SPC.
211285809Sscottl *
212285809Sscottl *  \param agRoot          Handles for this instance of SAS/SATA LL
213285809Sscottl *  \param agContext       Context of SPC FW Flash Update Command
214285809Sscottl *  \param queueNum        Inbound/outbound queue number
215285809Sscottl *  \param flashUpdateInfo Pointer of flash update information
216285809Sscottl *
217285809Sscottl *  \return If the MPI command is sent to SPC successfully
218285809Sscottl *          - \e AGSA_RC_SUCCESS the MPI command is successfully
219285809Sscottl *          - \e AGSA_RC_FAILURE the MPI command is failure
220285809Sscottl *
221285809Sscottl */
222285809Sscottl/*******************************************************************************/
223285809SscottlGLOBAL bit32 saFwFlashUpdate(
224285809Sscottl  agsaRoot_t                *agRoot,
225285809Sscottl  agsaContext_t             *agContext,
226285809Sscottl  bit32                     queueNum,
227285809Sscottl  agsaUpdateFwFlash_t       *flashUpdateInfo
228285809Sscottl  )
229285809Sscottl{
230285809Sscottl  bit32 ret = AGSA_RC_SUCCESS, retVal;
231285809Sscottl  agsaLLRoot_t        *saRoot;
232285809Sscottl  agsaIORequestDesc_t *pRequest;
233285809Sscottl  mpiICQueue_t        *circularQ;
234285809Sscottl  void                *pMessage;
235285809Sscottl  agsaFwFlashUpdate_t *pPayload;
236285809Sscottl  bit8                inq, outq;
237285809Sscottl  bit32               i;
238285809Sscottl
239285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
240285809Sscottl  if (agRoot == agNULL)
241285809Sscottl  {
242285809Sscottl    SA_DBG1(("saFwFlashUpdate: agRoot == agNULL\n"));
243285809Sscottl    return AGSA_RC_FAILURE;
244285809Sscottl  }
245285809Sscottl  saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
246285809Sscottl  SA_ASSERT((agNULL != saRoot), "");
247285809Sscottl  if (saRoot == agNULL)
248285809Sscottl  {
249285809Sscottl    SA_DBG1(("saFwFlashUpdate: saRoot == agNULL\n"));
250285809Sscottl    return AGSA_RC_FAILURE;
251285809Sscottl  }
252285809Sscottl
253285809Sscottl
254285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD, "6a");
255285809Sscottl  /* sanity check */
256285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
257285809Sscottl  /* Get request from free IORequests */
258285809Sscottl  ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
259285809Sscottl  pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
260285809Sscottl  /* If no LL Control request entry available */
261285809Sscottl  if ( agNULL == pRequest ) {
262285809Sscottl    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
263285809Sscottl    SA_DBG1(("saFwFlashUpdate, No request from free list\n" ));
264285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6a");
265285809Sscottl    return AGSA_RC_BUSY;
266285809Sscottl  }
267285809Sscottl  /* If LL Control request entry avaliable */
268285809Sscottl  else
269285809Sscottl  {
270285809Sscottl    /* Assign inbound and outbound Ring Buffer */
271285809Sscottl    inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
272285809Sscottl    outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
273285809Sscottl    SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
274285809Sscottl    /* Remove the request from free list */
275285809Sscottl    saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
276285809Sscottl    saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
277285809Sscottl    saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
278285809Sscottl    saRoot->IOMap[pRequest->HTag].agContext = agContext;
279285809Sscottl    pRequest->valid = agTRUE;
280285809Sscottl    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
281285809Sscottl#ifdef SA_LL_IBQ_PROTECT
282285809Sscottl    ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
283285809Sscottl#endif /* SA_LL_IBQ_PROTECT */
284285809Sscottl    /* Get a free inbound queue entry */
285285809Sscottl    circularQ = &saRoot->inboundQueue[inq];
286285809Sscottl    retVal    = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage);
287285809Sscottl    /* if message size is too large return failure */
288285809Sscottl    if (AGSA_RC_FAILURE == retVal)
289285809Sscottl    {
290285809Sscottl#ifdef SA_LL_IBQ_PROTECT
291285809Sscottl      ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
292285809Sscottl#endif /* SA_LL_IBQ_PROTECT */
293285809Sscottl      ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
294285809Sscottl      /* remove the request from IOMap */
295285809Sscottl      saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
296285809Sscottl      saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
297285809Sscottl      saRoot->IOMap[pRequest->HTag].agContext = agNULL;
298285809Sscottl      pRequest->valid = agFALSE;
299285809Sscottl      /* return the request to free pool */
300285809Sscottl      saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
301285809Sscottl      ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
302285809Sscottl      SA_DBG1(("saFwFlashUpdate, error when get free IOMB\n"));
303285809Sscottl      smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6a");
304285809Sscottl      return AGSA_RC_FAILURE;
305285809Sscottl    }
306285809Sscottl    /* return busy if inbound queue is full */
307285809Sscottl    if (AGSA_RC_BUSY == retVal)
308285809Sscottl    {
309285809Sscottl#ifdef SA_LL_IBQ_PROTECT
310285809Sscottl      ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
311285809Sscottl#endif /* SA_LL_IBQ_PROTECT */
312285809Sscottl      ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
313285809Sscottl      /* remove the request from IOMap */
314285809Sscottl      saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
315285809Sscottl      saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
316285809Sscottl      saRoot->IOMap[pRequest->HTag].agContext = agNULL;
317285809Sscottl      pRequest->valid = agFALSE;
318285809Sscottl      /* return the request to free pool */
319285809Sscottl      saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
320285809Sscottl      ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
321285809Sscottl      SA_DBG1(("saFwFlashUpdate, no more IOMB\n"));
322285809Sscottl      smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "6a");
323285809Sscottl      return AGSA_RC_BUSY;
324285809Sscottl    }
325285809Sscottl    pPayload = (agsaFwFlashUpdate_t *)pMessage;
326285809Sscottl    /* Prepare the FW_FLASH_UPDATE IOMB payload */
327285809Sscottl    OSSA_WRITE_LE_32( agRoot, pPayload,
328285809Sscottl                      OSSA_OFFSET_OF(agsaFwFlashUpdate_t, tag), pRequest->HTag);
329285809Sscottl    OSSA_WRITE_LE_32( agRoot, pPayload,
330285809Sscottl                      OSSA_OFFSET_OF(agsaFwFlashUpdate_t, curImageOffset),
331285809Sscottl                      flashUpdateInfo->currentImageOffset);
332285809Sscottl    OSSA_WRITE_LE_32( agRoot, pPayload,
333285809Sscottl                      OSSA_OFFSET_OF(agsaFwFlashUpdate_t, curImageLen),
334285809Sscottl                      flashUpdateInfo->currentImageLen);
335285809Sscottl    OSSA_WRITE_LE_32( agRoot, pPayload,
336285809Sscottl                      OSSA_OFFSET_OF(agsaFwFlashUpdate_t, totalImageLen),
337285809Sscottl                      flashUpdateInfo->totalImageLen);
338285809Sscottl    pPayload->SGLAL = flashUpdateInfo->agSgl.sgLower;
339285809Sscottl    pPayload->SGLAH = flashUpdateInfo->agSgl.sgUpper;
340285809Sscottl    pPayload->Len   = flashUpdateInfo->agSgl.len;
341285809Sscottl    pPayload->extReserved = flashUpdateInfo->agSgl.extReserved;
342285809Sscottl    /* fill up the reserved bytes with zero */
343285809Sscottl    for (i = 0; i < FWFLASH_IOMB_RESERVED_LEN; i ++) {
344285809Sscottl      pPayload->reserved0[i] = 0;
345285809Sscottl    }
346285809Sscottl    /* post the IOMB to SPC */
347285809Sscottl    ret = mpiMsgProduce( circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA,
348285809Sscottl                         OPC_INB_FW_FLASH_UPDATE, outq, (bit8)circularQ->priority);
349285809Sscottl#ifdef SA_LL_IBQ_PROTECT
350285809Sscottl    ossaSingleThreadedLeave( agRoot, LL_IOREQ_IBQ0_LOCK + inq );
351285809Sscottl#endif /* SA_LL_IBQ_PROTECT */
352285809Sscottl    if (AGSA_RC_FAILURE == ret) {
353285809Sscottl      ossaSingleThreadedEnter( agRoot, LL_IOREQ_LOCKEQ_LOCK );
354285809Sscottl      /* remove the request from IOMap */
355285809Sscottl      saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
356285809Sscottl      saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
357285809Sscottl      saRoot->IOMap[pRequest->HTag].agContext = agNULL;
358285809Sscottl      pRequest->valid = agFALSE;
359285809Sscottl      /* return the request to free pool */
360285809Sscottl      saLlistIOAdd( &(saRoot->freeIORequests), &(pRequest->linkNode) );
361285809Sscottl      ossaSingleThreadedLeave( agRoot, LL_IOREQ_LOCKEQ_LOCK );
362285809Sscottl      SA_DBG1( ("saFwFlashUpdate, error when post FW_FLASH_UPDATE IOMB\n") );
363285809Sscottl    }
364285809Sscottl  }
365285809Sscottl  smTraceFuncExit( hpDBG_VERY_LOUD, 'd', "6a" );
366285809Sscottl  return ret;
367285809Sscottl}
368285809Sscottl
369285809Sscottl
370285809SscottlGLOBAL bit32 saFlashExtExecute (
371285809Sscottl                  agsaRoot_t            *agRoot,
372285809Sscottl                  agsaContext_t         *agContext,
373285809Sscottl                  bit32                 queueNum,
374285809Sscottl                  agsaFlashExtExecute_t *agFlashExtExe)
375285809Sscottl{
376285809Sscottl
377285809Sscottl  bit32 ret           = AGSA_RC_SUCCESS, retVal;
378285809Sscottl  agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
379285809Sscottl  agsaIORequestDesc_t *pRequest;
380285809Sscottl  mpiICQueue_t        *circularQ;
381285809Sscottl  void                *pMessage;
382285809Sscottl  agsaFwFlashOpExt_t *pPayload;
383285809Sscottl  bit8                inq, outq;
384285809Sscottl
385285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"2R");
386285809Sscottl
387285809Sscottl  /* sanity check */
388285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
389285809Sscottl
390285809Sscottl  /* Get request from free IORequests */
391285809Sscottl  ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
392285809Sscottl  pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
393285809Sscottl
394285809Sscottl  /* If no LL Control request entry available */
395285809Sscottl  if ( agNULL == pRequest )
396285809Sscottl  {
397285809Sscottl    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
398285809Sscottl    SA_DBG1(("saFlashExtExecute, No request from free list\n" ));
399285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2R");
400285809Sscottl    return AGSA_RC_BUSY;
401285809Sscottl  }
402285809Sscottl  /* If LL Control request entry avaliable */
403285809Sscottl  else
404285809Sscottl  {
405285809Sscottl    /* Assign inbound and outbound Ring Buffer */
406285809Sscottl    inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
407285809Sscottl    outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
408285809Sscottl    SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
409285809Sscottl
410285809Sscottl    /* Remove the request from free list */
411285809Sscottl    saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
412285809Sscottl    saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
413285809Sscottl    saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
414285809Sscottl    saRoot->IOMap[pRequest->HTag].agContext = agContext;
415285809Sscottl    pRequest->valid = agTRUE;
416285809Sscottl    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
417285809Sscottl
418285809Sscottl#ifdef SA_LL_IBQ_PROTECT
419285809Sscottl    ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
420285809Sscottl#endif /* SA_LL_IBQ_PROTECT */
421285809Sscottl    /* Get a free inbound queue entry */
422285809Sscottl    circularQ = &saRoot->inboundQueue[inq];
423285809Sscottl    retVal    = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage);
424285809Sscottl
425285809Sscottl    /* if message size is too large return failure */
426285809Sscottl    if (AGSA_RC_FAILURE == retVal)
427285809Sscottl    {
428285809Sscottl#ifdef SA_LL_IBQ_PROTECT
429285809Sscottl      ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
430285809Sscottl#endif   /* SA_LL_IBQ_PROTECT */
431285809Sscottl      ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
432285809Sscottl      /* remove the request from IOMap */
433285809Sscottl      saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
434285809Sscottl      saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
435285809Sscottl      saRoot->IOMap[pRequest->HTag].agContext = agNULL;
436285809Sscottl      pRequest->valid = agFALSE;
437285809Sscottl      /* return the request to free pool */
438285809Sscottl      saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
439285809Sscottl      ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
440285809Sscottl
441285809Sscottl      SA_DBG1(("saFlashExtExecute, error when get free IOMB\n"));
442285809Sscottl      smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2R");
443285809Sscottl      return AGSA_RC_FAILURE;
444285809Sscottl    }
445285809Sscottl
446285809Sscottl    /* return busy if inbound queue is full */
447285809Sscottl    if (AGSA_RC_BUSY == retVal)
448285809Sscottl    {
449285809Sscottl#ifdef SA_LL_IBQ_PROTECT
450285809Sscottl      ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
451285809Sscottl#endif /* SA_LL_IBQ_PROTECT */
452285809Sscottl      ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
453285809Sscottl      /* remove the request from IOMap */
454285809Sscottl      saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
455285809Sscottl      saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
456285809Sscottl      saRoot->IOMap[pRequest->HTag].agContext = agNULL;
457285809Sscottl
458285809Sscottl      pRequest->valid = agFALSE;
459285809Sscottl      /* return the request to free pool */
460285809Sscottl      saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
461285809Sscottl      ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
462285809Sscottl
463285809Sscottl      SA_DBG3(("saFlashExtExecute, no more IOMB\n"));
464285809Sscottl      smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2R");
465285809Sscottl      return AGSA_RC_BUSY;
466285809Sscottl    }
467285809Sscottl
468285809Sscottl    pPayload = (agsaFwFlashOpExt_t *)pMessage;
469285809Sscottl
470285809Sscottl    si_memset(pPayload, 0, sizeof(agsaFwFlashOpExt_t));
471285809Sscottl
472285809Sscottl
473285809Sscottl    /* Prepare the FW_FLASH_UPDATE IOMB payload */
474285809Sscottl    OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t, tag), pRequest->HTag);
475285809Sscottl    OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t,Command ), agFlashExtExe->command);
476285809Sscottl    OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t,PartOffset ), agFlashExtExe->partOffset);
477285809Sscottl    OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t,DataLength ), agFlashExtExe->dataLen);
478285809Sscottl    OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t,SGLAL ), agFlashExtExe->agSgl->sgLower);
479285809Sscottl    OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t,SGLAH ), agFlashExtExe->agSgl->sgUpper);
480285809Sscottl    OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t,Len ), agFlashExtExe->agSgl->len);
481285809Sscottl    OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaFwFlashOpExt_t,E_sgl ), agFlashExtExe->agSgl->extReserved);
482285809Sscottl
483285809Sscottl    /* post the IOMB to SPC */
484285809Sscottl    ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_FLASH_OP_EXT, outq, (bit8)circularQ->priority);
485285809Sscottl
486285809Sscottl#ifdef SA_LL_IBQ_PROTECT
487285809Sscottl    ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
488285809Sscottl#endif /* SA_LL_IBQ_PROTECT */
489285809Sscottl
490285809Sscottl
491285809Sscottl    if (AGSA_RC_FAILURE == ret)
492285809Sscottl    {
493285809Sscottl      ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
494285809Sscottl      /* remove the request from IOMap */
495285809Sscottl      saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
496285809Sscottl      saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
497285809Sscottl      saRoot->IOMap[pRequest->HTag].agContext = agNULL;
498285809Sscottl      pRequest->valid = agFALSE;
499285809Sscottl      /* return the request to free pool */
500285809Sscottl      saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
501285809Sscottl      ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
502285809Sscottl      SA_DBG1(("saFlashExtExecute, error when post FW_FLASH_UPDATE IOMB\n"));
503285809Sscottl    }
504285809Sscottl  }
505285809Sscottl  smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "2R");
506285809Sscottl
507285809Sscottl  return ret;
508285809Sscottl
509285809Sscottl}
510285809Sscottl
511285809Sscottl
512285809Sscottl#ifdef SPC_ENABLE_PROFILE
513285809Sscottl/******************************************************************************/
514285809Sscottl/*! \brief SPC FW_PROFILE Respond
515285809Sscottl *
516285809Sscottl *  This command sends FW Profile Status to TD layer.
517285809Sscottl *
518285809Sscottl *  \param agRoot       Handles for this instance of SAS/SATA LL
519285809Sscottl *  \param payload      FW download response payload
520285809Sscottl *
521285809Sscottl *  \return If the MPI command is sent to SPC successfully
522285809Sscottl *          - \e AGSA_RC_SUCCESS the MPI command is successfully
523285809Sscottl *          - \e AGSA_RC_FAILURE the MPI command is failure
524285809Sscottl *
525285809Sscottl */
526285809Sscottl/*******************************************************************************/
527285809SscottlGLOBAL bit32 mpiFwProfileRsp(
528285809Sscottl  agsaRoot_t             *agRoot,
529285809Sscottl  agsaFwProfileRsp_t *payload
530285809Sscottl  )
531285809Sscottl{
532285809Sscottl  bit32               ret = AGSA_RC_SUCCESS;
533285809Sscottl  agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
534285809Sscottl  agsaIORequestDesc_t *pRequest;
535285809Sscottl  agsaContext_t       *agContext;
536285809Sscottl
537285809Sscottl  bit32     status, tag, len;
538285809Sscottl
539285809Sscottl  /* get request from IOMap */
540285809Sscottl  OSSA_READ_LE_32(AGROOT, &tag, payload, OSSA_OFFSET_OF(agsaFwProfileRsp_t, tag));
541285809Sscottl  OSSA_READ_LE_32(AGROOT, &status, payload, OSSA_OFFSET_OF(agsaFwProfileRsp_t, status));
542285809Sscottl  OSSA_READ_LE_32(AGROOT, &len, payload, OSSA_OFFSET_OF(agsaFwProfileRsp_t, len));
543285809Sscottl  pRequest = saRoot->IOMap[tag].IORequest;
544285809Sscottl  if (agNULL == pRequest)
545285809Sscottl  {
546285809Sscottl    /* remove the request from IOMap */
547285809Sscottl    saRoot->IOMap[tag].Tag = MARK_OFF;
548285809Sscottl    saRoot->IOMap[tag].IORequest = agNULL;
549285809Sscottl    SA_DBG1(("mpiFwProfileRsp: the request is NULL. Tag=%x\n", tag));
550285809Sscottl    return AGSA_RC_FAILURE;
551285809Sscottl  }
552285809Sscottl  agContext = saRoot->IOMap[tag].agContext;
553285809Sscottl  /* remove the request from IOMap */
554285809Sscottl  saRoot->IOMap[tag].Tag = MARK_OFF;
555285809Sscottl  saRoot->IOMap[tag].IORequest = agNULL;
556285809Sscottl  saRoot->IOMap[tag].agContext = agNULL;
557285809Sscottl  ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
558285809Sscottl
559285809Sscottl
560285809Sscottl  if(!pRequest->valid)
561285809Sscottl  {
562285809Sscottl    SA_DBG1(("mpiPortControlRsp: pRequest->valid %d not set\n", pRequest->valid));
563285809Sscottl  }
564285809Sscottl
565285809Sscottl  SA_ASSERT((pRequest->valid), "pRequest->valid");
566285809Sscottl
567285809Sscottl  pRequest->valid = agFALSE;
568285809Sscottl  /* return the request to free pool */
569285809Sscottl  saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
570285809Sscottl  ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
571285809Sscottl
572285809Sscottl  ossaFwProfileCB(agRoot, agContext, status, len);
573285809Sscottl
574285809Sscottl return ret;
575285809Sscottl}
576285809Sscottl#endif
577285809Sscottl/******************************************************************************/
578285809Sscottl/*! \brief SPC FW_FLASH_UPDATE Respond
579285809Sscottl *
580285809Sscottl *  This command sends FW Flash Update Status to TD layer.
581285809Sscottl *
582285809Sscottl *  \param agRoot       Handles for this instance of SAS/SATA LL
583285809Sscottl *  \param payload      FW download response payload
584285809Sscottl *
585285809Sscottl *  \return If the MPI command is sent to SPC successfully
586285809Sscottl *          - \e AGSA_RC_SUCCESS the MPI command is successfully
587285809Sscottl *          - \e AGSA_RC_FAILURE the MPI command is failure
588285809Sscottl *
589285809Sscottl */
590285809Sscottl/*******************************************************************************/
591285809SscottlGLOBAL bit32 mpiFwFlashUpdateRsp(
592285809Sscottl  agsaRoot_t             *agRoot,
593285809Sscottl  agsaFwFlashUpdateRsp_t *payload
594285809Sscottl  )
595285809Sscottl{
596285809Sscottl  bit32               ret = AGSA_RC_SUCCESS;
597285809Sscottl  agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
598285809Sscottl  agsaIORequestDesc_t *pRequest;
599285809Sscottl  agsaContext_t       *agContext;
600285809Sscottl
601285809Sscottl  bit32     status, tag;
602285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"6b");
603285809Sscottl
604285809Sscottl  /* get request from IOMap */
605285809Sscottl  OSSA_READ_LE_32(AGROOT, &tag, payload, OSSA_OFFSET_OF(agsaFwFlashUpdateRsp_t, tag));
606285809Sscottl  OSSA_READ_LE_32(AGROOT, &status, payload, OSSA_OFFSET_OF(agsaFwFlashUpdateRsp_t, status));
607285809Sscottl  pRequest = saRoot->IOMap[tag].IORequest;
608285809Sscottl  agContext = saRoot->IOMap[tag].agContext;
609285809Sscottl  /* remove the request from IOMap */
610285809Sscottl  saRoot->IOMap[tag].Tag = MARK_OFF;
611285809Sscottl  saRoot->IOMap[tag].IORequest = agNULL;
612285809Sscottl  saRoot->IOMap[tag].agContext = agNULL;
613285809Sscottl  ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
614285809Sscottl  SA_ASSERT((pRequest->valid), "pRequest->valid");
615285809Sscottl  pRequest->valid = agFALSE;
616285809Sscottl  /* return the request to free pool */
617285809Sscottl  if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
618285809Sscottl  {
619285809Sscottl    SA_DBG1(("mpiFwFlashUpdateRsp: saving pRequest (%p) for later use\n", pRequest));
620285809Sscottl    saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
621285809Sscottl  }
622285809Sscottl  else
623285809Sscottl  {
624285809Sscottl    /* return the request to free pool */
625285809Sscottl    saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
626285809Sscottl  }
627285809Sscottl  ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
628285809Sscottl
629285809Sscottl  if(status > 1)
630285809Sscottl  {
631285809Sscottl    SA_DBG1(("mpiFwFlashUpdateRsp: status = 0x%x\n",status));
632285809Sscottl  }
633285809Sscottl
634285809Sscottl  ossaFwFlashUpdateCB(agRoot, agContext, status);
635285809Sscottl
636285809Sscottl  smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6b");
637285809Sscottl
638285809Sscottl  return ret;
639285809Sscottl}
640285809Sscottl
641285809SscottlGLOBAL bit32 mpiFwExtFlashUpdateRsp(
642285809Sscottl  agsaRoot_t             *agRoot,
643285809Sscottl  agsaFwFlashOpExtRsp_t *payload
644285809Sscottl  )
645285809Sscottl{
646285809Sscottl  bit32               ret = AGSA_RC_SUCCESS;
647285809Sscottl  agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
648285809Sscottl  agsaIORequestDesc_t *pRequest;
649285809Sscottl  agsaContext_t       *agContext;
650285809Sscottl
651285809Sscottl  agsaFlashExtResponse_t FlashExtRsp;
652285809Sscottl
653285809Sscottl  bit32     Command,Status, tag;
654285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"2T");
655285809Sscottl
656285809Sscottl  /* get request from IOMap */
657285809Sscottl  OSSA_READ_LE_32(AGROOT, &tag, payload, OSSA_OFFSET_OF(agsaFwFlashOpExtRsp_t, tag));
658285809Sscottl  OSSA_READ_LE_32(AGROOT, &Command, payload, OSSA_OFFSET_OF(agsaFwFlashOpExtRsp_t,Command ));
659285809Sscottl  OSSA_READ_LE_32(AGROOT, &Status, payload, OSSA_OFFSET_OF(agsaFwFlashOpExtRsp_t,Status ));
660285809Sscottl  OSSA_READ_LE_32(AGROOT, &FlashExtRsp.epart_sect_size, payload, OSSA_OFFSET_OF(agsaFwFlashOpExtRsp_t,Epart_Size ));
661285809Sscottl  OSSA_READ_LE_32(AGROOT, &FlashExtRsp.epart_size, payload, OSSA_OFFSET_OF(agsaFwFlashOpExtRsp_t,EpartSectSize ));
662285809Sscottl
663285809Sscottl  pRequest = saRoot->IOMap[tag].IORequest;
664285809Sscottl  agContext = saRoot->IOMap[tag].agContext;
665285809Sscottl  /* remove the request from IOMap */
666285809Sscottl  saRoot->IOMap[tag].Tag = MARK_OFF;
667285809Sscottl  saRoot->IOMap[tag].IORequest = agNULL;
668285809Sscottl  saRoot->IOMap[tag].agContext = agNULL;
669285809Sscottl  ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
670285809Sscottl  SA_ASSERT((pRequest->valid), "pRequest->valid");
671285809Sscottl  pRequest->valid = agFALSE;
672285809Sscottl  /* return the request to free pool */
673285809Sscottl  if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
674285809Sscottl  {
675285809Sscottl    SA_DBG1(("mpiFwExtFlashUpdateRsp: saving pRequest (%p) for later use\n", pRequest));
676285809Sscottl    saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
677285809Sscottl  }
678285809Sscottl  else
679285809Sscottl  {
680285809Sscottl    /* return the request to free pool */
681285809Sscottl    saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
682285809Sscottl  }
683285809Sscottl  ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
684285809Sscottl
685285809Sscottl  if(Status > 1)
686285809Sscottl  {
687285809Sscottl    SA_DBG1(("mpiFwExtFlashUpdateRsp: status = 0x%x\n",Status));
688285809Sscottl  }
689285809Sscottl
690285809Sscottl  ossaFlashExtExecuteCB(agRoot, agContext, Status,Command,&FlashExtRsp);
691285809Sscottl
692285809Sscottl  smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2T");
693285809Sscottl
694285809Sscottl  return ret;
695285809Sscottl
696285809Sscottl}
697285809Sscottl
698285809Sscottl
699285809Sscottl/******************************************************************************/
700285809Sscottl/*! \brief SPC Get Controller Information Command
701285809Sscottl *
702285809Sscottl *  This command sends Get Controller Information Command to SPC.
703285809Sscottl *
704285809Sscottl *  \param agRoot         Handles for this instance of SAS/SATA LL
705285809Sscottl *  \param controllerInfo Controller Information
706285809Sscottl *
707285809Sscottl *  \return If the MPI command is sent to SPC successfully
708285809Sscottl *          - \e AGSA_RC_SUCCESS the MPI command is successfully
709285809Sscottl *          - \e AGSA_RC_FAILURE the MPI command is failure
710285809Sscottl *
711285809Sscottl */
712285809Sscottl/*******************************************************************************/
713285809Sscottl
714285809SscottlGLOBAL bit32 saGetControllerInfo(
715285809Sscottl                        agsaRoot_t                *agRoot,
716285809Sscottl                        agsaControllerInfo_t      *controllerInfo
717285809Sscottl                        )
718285809Sscottl{
719285809Sscottl
720285809Sscottl  bit32     ret = AGSA_RC_SUCCESS;
721285809Sscottl  bit32     max_wait_time;
722285809Sscottl  bit32     max_wait_count;
723285809Sscottl  bit32     ContrlCapFlag, MSGUCfgTblBase, CfgTblDWIdx;
724285809Sscottl  bit32     value = 0, value1 = 0;
725285809Sscottl  bit8      pcibar;
726285809Sscottl
727285809Sscottl  if (agNULL != agRoot->sdkData)
728285809Sscottl  {
729285809Sscottl    smTraceFuncEnter(hpDBG_VERY_LOUD,"6e");
730285809Sscottl  }
731285809Sscottl  /* clean the structure */
732285809Sscottl  si_memset(controllerInfo, 0, sizeof(agsaControllerInfo_t));
733285809Sscottl
734285809Sscottl  if(smIS_SPC6V(agRoot))
735285809Sscottl  {
736285809Sscottl    controllerInfo->sdkInterfaceRev = STSDK_LL_INTERFACE_VERSION;
737285809Sscottl    controllerInfo->sdkRevision     = STSDK_LL_VERSION;
738285809Sscottl    controllerInfo->hwRevision = (ossaHwRegReadConfig32(agRoot,8) & 0xFF);
739285809Sscottl  }else  if(smIS_SPC12V(agRoot))
740285809Sscottl  {
741285809Sscottl    controllerInfo->sdkInterfaceRev = STSDK_LL_12G_INTERFACE_VERSION;
742285809Sscottl    controllerInfo->sdkRevision     = STSDK_LL_12G_VERSION;
743285809Sscottl    controllerInfo->hwRevision = (ossaHwRegReadConfig32(agRoot,8) & 0xFF);
744285809Sscottl  } else if(smIS_SPC(agRoot))
745285809Sscottl  {
746285809Sscottl    controllerInfo->hwRevision = SPC_READ_DEV_REV;
747285809Sscottl    controllerInfo->sdkInterfaceRev = MATCHING_SPC_FW_VERSION;
748285809Sscottl    controllerInfo->sdkRevision     = STSDK_LL_SPC_VERSION;
749285809Sscottl  }
750285809Sscottl  else
751285809Sscottl  {
752285809Sscottl    controllerInfo->hwRevision = (ossaHwRegReadConfig32(agRoot,8) & 0xFF);
753285809Sscottl  }
754285809Sscottl
755285809Sscottl  SA_DBG1(("saGetControllerInfo: SCRATCH_PAD0 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0)));
756285809Sscottl  SA_DBG1(("saGetControllerInfo: SCRATCH_PAD1 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1)));
757285809Sscottl  SA_DBG1(("saGetControllerInfo: SCRATCH_PAD2 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_2,  MSGU_SCRATCH_PAD_2)));
758285809Sscottl  SA_DBG1(("saGetControllerInfo: SCRATCH_PAD3 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_3,  MSGU_SCRATCH_PAD_3)));
759285809Sscottl  SA_DBG1(("saGetControllerInfo: SCRATCH_PAD3 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_3,  MSGU_SCRATCH_PAD_3)));
760285809Sscottl
761285809Sscottl  if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0) == 0xFFFFFFFF)
762285809Sscottl  {
763285809Sscottl    SA_DBG1(("saGetControllerInfo:AGSA_RC_FAILURE SCRATCH_PAD0 value = 0x%x\n",
764285809Sscottl            siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0) ) );
765285809Sscottl    return AGSA_RC_FAILURE;
766285809Sscottl  }
767285809Sscottl
768285809Sscottl  if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0) == 0xFFFFFFFF)
769285809Sscottl  {
770285809Sscottl    SA_DBG1(("saGetControllerInfo:AGSA_RC_FAILURE SCRATCH_PAD0 value = 0x%x\n",
771285809Sscottl            siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0) ) );
772285809Sscottl    return AGSA_RC_FAILURE;
773285809Sscottl  }
774285809Sscottl
775285809Sscottl  if( SCRATCH_PAD1_V_ERROR_STATE(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1)) )
776285809Sscottl  {
777285809Sscottl    SA_DBG1(("saGetControllerInfo: SCRATCH_PAD1 (0x%x) in error state ila %d raae %d Iop0 %d Iop1 %d\n",
778285809Sscottl      siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1),
779285809Sscottl    ( SCRATCH_PAD1_V_ILA_ERROR_STATE(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1)) ? 1 : 0),
780285809Sscottl    ( SCRATCH_PAD1_V_RAAE_ERROR_STATE(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,MSGU_SCRATCH_PAD_1)) ? 1 : 0),
781285809Sscottl    ( SCRATCH_PAD1_V_IOP0_ERROR_STATE(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,MSGU_SCRATCH_PAD_1)) ? 1 : 0),
782285809Sscottl    ( SCRATCH_PAD1_V_IOP1_ERROR_STATE(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,MSGU_SCRATCH_PAD_1)) ? 1 : 0) ));
783285809Sscottl
784285809Sscottl  }
785285809Sscottl
786285809Sscottl  if(smIS_SPC(agRoot))
787285809Sscottl  {
788285809Sscottl    /* check HDA mode */
789285809Sscottl    value = ossaHwRegReadExt(agRoot, PCIBAR3, HDA_RSP_OFFSET1MB+HDA_CMD_CODE_OFFSET) & HDA_STATUS_BITS;
790285809Sscottl
791285809Sscottl    if (value == BOOTTLOADERHDA_IDLE)
792285809Sscottl    {
793285809Sscottl      /* HDA mode */
794285809Sscottl      SA_DBG1(("saGetControllerInfo: HDA mode, value = 0x%x\n", value));
795285809Sscottl      return AGSA_RC_HDA_NO_FW_RUNNING;
796285809Sscottl    }
797285809Sscottl  }
798285809Sscottl  else
799285809Sscottl  {
800285809Sscottl    if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1) &   SCRATCH_PAD1_V_RESERVED )
801285809Sscottl    {
802285809Sscottl      SA_DBG1(("saGetControllerInfo: Warning SCRATCH_PAD1 reserved bits set value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1)));
803285809Sscottl    }
804285809Sscottl    if( si_check_V_HDA(agRoot))
805285809Sscottl    {
806285809Sscottl      /*  Check HDA */
807285809Sscottl      SA_DBG1(("saGetControllerInfo: HDA mode AGSA_RC_HDA_NO_FW_RUNNING\n" ));
808285809Sscottl      return AGSA_RC_HDA_NO_FW_RUNNING;
809285809Sscottl    }
810285809Sscottl
811285809Sscottl
812285809Sscottl  }
813285809Sscottl
814285809Sscottl  /* checking the fw AAP and IOP in ready state */
815285809Sscottl  max_wait_time = WAIT_SECONDS(gWait_2);  /* 2 sec timeout */
816285809Sscottl  max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT);
817285809Sscottl  /* wait until scratch pad 1 and 2 registers in ready state  */
818285809Sscottl  if(smIS_SPCV(agRoot))
819285809Sscottl  {
820285809Sscottl    do
821285809Sscottl    {
822285809Sscottl      ossaStallThread(agRoot, WAIT_INCREMENT);
823285809Sscottl      value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1);
824285809Sscottl      value1 =siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_2, MSGU_SCRATCH_PAD_2);
825285809Sscottl      if(smIS_SPCV(agRoot))
826285809Sscottl      {
827285809Sscottl        if((value & SCRATCH_PAD1_V_RESERVED) )
828285809Sscottl        {
829285809Sscottl          SA_DBG1(("saGetControllerInfo: V reserved SCRATCH_PAD1 value = 0x%x (0x%x)\n", value, SCRATCH_PAD1_V_RESERVED));
830285809Sscottl          ret = AGSA_RC_FW_NOT_IN_READY_STATE;
831285809Sscottl          break;
832285809Sscottl        }
833285809Sscottl      }
834285809Sscottl
835285809Sscottl      if ((max_wait_count -= WAIT_INCREMENT) == 0)
836285809Sscottl      {
837285809Sscottl        SA_DBG1(("saGetControllerInfo:  timeout SCRATCH_PAD1_V_READY !! SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1));
838285809Sscottl        break;
839285809Sscottl      }
840285809Sscottl
841285809Sscottl    } while (((value & SCRATCH_PAD1_V_READY) != SCRATCH_PAD1_V_READY) || (value == 0xffffffff));
842285809Sscottl
843285809Sscottl  }
844285809Sscottl  else
845285809Sscottl  {
846285809Sscottl    do
847285809Sscottl    {
848285809Sscottl      ossaStallThread(agRoot, WAIT_INCREMENT);
849285809Sscottl      value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1);
850285809Sscottl      /* checking bit 4 to 7 for reserved in case we get 0xFFFFFFFF */
851285809Sscottl      if (value & SCRATCH_PAD1_RESERVED)
852285809Sscottl      {
853285809Sscottl        SA_DBG1(("saGetControllerInfo: SCRATCH_PAD1 value = 0x%x\n", value));
854285809Sscottl        ret = AGSA_RC_FW_NOT_IN_READY_STATE;
855285809Sscottl        break;
856285809Sscottl      }
857285809Sscottl      value1 =siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_2,MSGU_SCRATCH_PAD_2);
858285809Sscottl      /* checking bit 4 to 7 for reserved in case we get 0xFFFFFFFF */
859285809Sscottl      if (value1 & SCRATCH_PAD2_RESERVED)
860285809Sscottl      {
861285809Sscottl        SA_DBG1(("saGetControllerInfo: SCRATCH_PAD2 value = 0x%x\n", value1));
862285809Sscottl        ret = AGSA_RC_FW_NOT_IN_READY_STATE;
863285809Sscottl        break;
864285809Sscottl      }
865285809Sscottl      if ((max_wait_count -= WAIT_INCREMENT) == 0)
866285809Sscottl      {
867285809Sscottl        SA_DBG1(("saGetControllerInfo: Timeout!! SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1));
868285809Sscottl        break;
869285809Sscottl      }
870285809Sscottl    } while (((value & SCRATCH_PAD_STATE_MASK) != SCRATCH_PAD1_RDY) || ((value1 & SCRATCH_PAD_STATE_MASK) != SCRATCH_PAD2_RDY));
871285809Sscottl  }
872285809Sscottl
873285809Sscottl  if (!max_wait_count)
874285809Sscottl  {
875285809Sscottl    SA_DBG1(("saGetControllerInfo: timeout failure\n"));
876285809Sscottl    ret = AGSA_RC_FW_NOT_IN_READY_STATE;
877285809Sscottl  }
878285809Sscottl
879285809Sscottl  if (ret == AGSA_RC_SUCCESS)
880285809Sscottl  {
881285809Sscottl    SA_DBG1(("saGetControllerInfo: FW Ready, SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1));
882285809Sscottl
883285809Sscottl    /* read scratch pad0 to get PCI BAR and offset of configuration table */
884285809Sscottl     MSGUCfgTblBase = siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0);
885285809Sscottl    /* get offset */
886285809Sscottl    CfgTblDWIdx = MSGUCfgTblBase & SCRATCH_PAD0_OFFSET_MASK;
887285809Sscottl    /* get PCI BAR */
888285809Sscottl    MSGUCfgTblBase = (MSGUCfgTblBase & SCRATCH_PAD0_BAR_MASK) >> SHIFT26;
889285809Sscottl
890285809Sscottl    /* convert the PCI BAR to logical bar number */
891285809Sscottl    pcibar = (bit8)mpiGetPCIBarIndex(agRoot, MSGUCfgTblBase);
892285809Sscottl
893285809Sscottl    /* get controller information */
894285809Sscottl    controllerInfo->signature =         ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx);
895285809Sscottl    controllerInfo->fwInterfaceRev =    ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_INTERFACE_REVISION);
896285809Sscottl    controllerInfo->fwRevision =        ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_FW_REVISION);
897285809Sscottl    controllerInfo->ilaRevision =       ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_ILAT_ILAV_ILASMRN_ILAMRN_ILAMJN);
898285809Sscottl    controllerInfo->maxPendingIO =      ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_MAX_OUTSTANDING_IO_OFFSET);
899285809Sscottl    controllerInfo->maxDevices =       (ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_MAX_SGL_OFFSET) & MAIN_MAX_DEV_BITS);
900285809Sscottl    controllerInfo->maxDevices =        controllerInfo->maxDevices >> SHIFT16;
901285809Sscottl    controllerInfo->maxSgElements =    (ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_MAX_SGL_OFFSET) & MAIN_MAX_SGL_BITS);
902285809Sscottl
903285809Sscottl    if( smIS_SPC(agRoot))
904285809Sscottl    {
905285809Sscottl      SA_DBG2(("saGetControllerInfo: LINK_CTRL 0x%08x Speed 0x%X Lanes 0x%X \n", ossaHwRegReadConfig32(agRoot,128),
906285809Sscottl        ((ossaHwRegReadConfig32(agRoot,128) & 0x000F0000) >> 16),
907285809Sscottl        ((ossaHwRegReadConfig32(agRoot,128) & 0x0FF00000) >> 20) ));
908285809Sscottl      controllerInfo->PCILinkRate =  ((ossaHwRegReadConfig32(agRoot,128) & 0x000F0000) >> 16);
909285809Sscottl      controllerInfo->PCIWidth =   ((ossaHwRegReadConfig32(agRoot,128) & 0x0FF00000) >> 20);
910285809Sscottl    }
911285809Sscottl    else
912285809Sscottl    {
913285809Sscottl      SA_DBG2(("saGetControllerInfo: LINK_CTRL 0x%08x Speed 0x%X Lanes 0x%X \n", ossaHwRegReadConfig32(agRoot,208),
914285809Sscottl        ((ossaHwRegReadConfig32(agRoot,208) & 0x000F0000) >> 16),
915285809Sscottl        ((ossaHwRegReadConfig32(agRoot,208) & 0x0FF00000) >> 20) ));
916285809Sscottl      controllerInfo->PCILinkRate =  ((ossaHwRegReadConfig32(agRoot,208) & 0x000F0000) >> 16);
917285809Sscottl      controllerInfo->PCIWidth =   ((ossaHwRegReadConfig32(agRoot,208) & 0x0FF00000) >> 20);
918285809Sscottl    }
919285809Sscottl
920285809Sscottl
921285809Sscottl    ContrlCapFlag =                     ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_CNTRL_CAP_OFFSET);
922285809Sscottl    controllerInfo->queueSupport =      ContrlCapFlag & MAIN_QSUPPORT_BITS;
923285809Sscottl    controllerInfo->phyCount =         (bit8)((ContrlCapFlag & MAIN_PHY_COUNT_MASK) >> SHIFT19);
924285809Sscottl
925285809Sscottl
926285809Sscottl    if(smIS_SPCV(agRoot))
927285809Sscottl    {
928285809Sscottl      controllerInfo->controllerSetting = (bit8)((siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1) & SCRATCH_PAD1_V_BOOTSTATE_MASK ) >> SHIFT4);
929285809Sscottl    }
930285809Sscottl    else
931285809Sscottl    {
932285809Sscottl      controllerInfo->controllerSetting = (bit8)(ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_HDA_FLAGS_OFFSET) & MAIN_HDA_FLAG_BITS);
933285809Sscottl    }
934285809Sscottl    controllerInfo->sasSpecsSupport =   (ContrlCapFlag & MAIN_SAS_SUPPORT_BITS) >> SHIFT25;
935285809Sscottl  }
936285809Sscottl
937285809Sscottl  SA_DBG1(("saGetControllerInfo: signature         0x%X\n", controllerInfo->signature));
938285809Sscottl  SA_DBG1(("saGetControllerInfo: fwInterfaceRev    0x%X\n", controllerInfo->fwInterfaceRev));
939285809Sscottl  SA_DBG1(("saGetControllerInfo: hwRevision        0x%X\n", controllerInfo->hwRevision));
940285809Sscottl  SA_DBG1(("saGetControllerInfo: fwRevision        0x%X\n", controllerInfo->fwRevision));
941285809Sscottl  SA_DBG1(("saGetControllerInfo: ilaRevision       0x%X\n", controllerInfo->ilaRevision));
942285809Sscottl  SA_DBG1(("saGetControllerInfo: maxPendingIO      0x%X\n", controllerInfo->maxPendingIO));
943285809Sscottl  SA_DBG1(("saGetControllerInfo: maxDevices        0x%X\n", controllerInfo->maxDevices));
944285809Sscottl  SA_DBG1(("saGetControllerInfo: maxSgElements     0x%X\n", controllerInfo->maxSgElements));
945285809Sscottl  SA_DBG1(("saGetControllerInfo: queueSupport      0x%X\n", controllerInfo->queueSupport));
946285809Sscottl  SA_DBG1(("saGetControllerInfo: phyCount          0x%X\n", controllerInfo->phyCount));
947285809Sscottl  SA_DBG1(("saGetControllerInfo: controllerSetting 0x%X\n", controllerInfo->controllerSetting));
948285809Sscottl  SA_DBG1(("saGetControllerInfo: PCILinkRate       0x%X\n", controllerInfo->PCILinkRate));
949285809Sscottl  SA_DBG1(("saGetControllerInfo: PCIWidth          0x%X\n", controllerInfo->PCIWidth));
950285809Sscottl  SA_DBG1(("saGetControllerInfo: sasSpecsSupport   0x%X\n", controllerInfo->sasSpecsSupport));
951285809Sscottl  SA_DBG1(("saGetControllerInfo: sdkInterfaceRev   0x%X\n", controllerInfo->sdkInterfaceRev));
952285809Sscottl  SA_DBG1(("saGetControllerInfo: sdkRevision       0x%X\n", controllerInfo->sdkRevision));
953285809Sscottl  if (agNULL != agRoot->sdkData)
954285809Sscottl  {
955285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6e");
956285809Sscottl  }
957285809Sscottl  return ret;
958285809Sscottl}
959285809Sscottl
960285809Sscottl/******************************************************************************/
961285809Sscottl/*! \brief SPC Get Controller Status Command
962285809Sscottl *
963285809Sscottl *  This command sends Get Controller Status Command to SPC.
964285809Sscottl *
965285809Sscottl *  \param agRoot           Handles for this instance of SAS/SATA LL
966285809Sscottl *  \param controllerStatus controller status
967285809Sscottl *
968285809Sscottl *  \return If the MPI command is sent to SPC successfully
969285809Sscottl *          - \e AGSA_RC_SUCCESS the MPI command is successfully
970285809Sscottl *          - \e AGSA_RC_FAILURE the MPI command is failure
971285809Sscottl *
972285809Sscottl */
973285809Sscottl/*******************************************************************************/
974285809SscottlGLOBAL bit32 saGetControllerStatus(
975285809Sscottl                        agsaRoot_t                *agRoot,
976285809Sscottl                        agsaControllerStatus_t    *controllerStatus
977285809Sscottl                        )
978285809Sscottl{
979285809Sscottl  bit32 ret = AGSA_RC_SUCCESS;
980285809Sscottl  agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
981285809Sscottl  spc_GSTableDescriptor_t GSTable;
982285809Sscottl  bit32 max_wait_time;
983285809Sscottl  bit32 max_wait_count;
984285809Sscottl  bit32 i, value, value1;
985285809Sscottl
986285809Sscottl  if (agNULL != saRoot)
987285809Sscottl  {
988285809Sscottl    smTraceFuncEnter(hpDBG_VERY_LOUD,"6f");
989285809Sscottl  }
990285809Sscottl  /* clean the structure */
991285809Sscottl  si_memset(controllerStatus, 0, sizeof(agsaControllerStatus_t));
992285809Sscottl  si_memset(&GSTable, 0, sizeof(spc_GSTableDescriptor_t));
993285809Sscottl  if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0) == 0xFFFFFFFF)
994285809Sscottl  {
995285809Sscottl    SA_DBG1(("saGetControllerStatus:AGSA_RC_FAILURE SCRATCH_PAD0 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0)));
996285809Sscottl    return AGSA_RC_FAILURE;
997285809Sscottl  }
998285809Sscottl
999285809Sscottl  if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_3)  & (OSSA_ENCRYPT_ENGINE_FAILURE_MASK | OSSA_DIF_ENGINE_FAILURE_MASK))
1000285809Sscottl  {
1001285809Sscottl    SA_DBG1(("saGetControllerStatus: BIST error in SCRATCHPAD 3 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_3,  MSGU_SCRATCH_PAD_3)));
1002285809Sscottl  }
1003285809Sscottl
1004285809Sscottl  if(smIS_SPC(agRoot))
1005285809Sscottl  {
1006285809Sscottl
1007285809Sscottl    /* read detail fatal errors */
1008285809Sscottl    controllerStatus->fatalErrorInfo.errorInfo0 = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_0);
1009285809Sscottl    controllerStatus->fatalErrorInfo.errorInfo1 = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_1);
1010285809Sscottl    controllerStatus->fatalErrorInfo.errorInfo2 = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_2);
1011285809Sscottl    controllerStatus->fatalErrorInfo.errorInfo3 = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_3);
1012285809Sscottl
1013285809Sscottl#if defined(SALLSDK_DEBUG)
1014285809Sscottl    SA_DBG1(("saGetControllerStatus: SCRATCH_PAD0 value = 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo0));
1015285809Sscottl    SA_DBG1(("saGetControllerStatus: SCRATCH_PAD1 value = 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo1));
1016285809Sscottl    SA_DBG1(("saGetControllerStatus: SCRATCH_PAD2 value = 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo2));
1017285809Sscottl    SA_DBG1(("saGetControllerStatus: SCRATCH_PAD3 value = 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo3));
1018285809Sscottl#endif
1019285809Sscottl
1020285809Sscottl    /* check HDA mode */
1021285809Sscottl    value = ossaHwRegReadExt(agRoot, PCIBAR3, HDA_RSP_OFFSET1MB+HDA_CMD_CODE_OFFSET) & HDA_STATUS_BITS;
1022285809Sscottl
1023285809Sscottl    if (value == BOOTTLOADERHDA_IDLE)
1024285809Sscottl    {
1025285809Sscottl      /* HDA mode */
1026285809Sscottl      SA_DBG1(("saGetControllerStatus: HDA mode, value = 0x%x\n", value));
1027285809Sscottl      return AGSA_RC_HDA_NO_FW_RUNNING;
1028285809Sscottl    }
1029285809Sscottl
1030285809Sscottl    /* check error state */
1031285809Sscottl    value = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_1);
1032285809Sscottl    value1 = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_2);
1033285809Sscottl
1034285809Sscottl    /* check AAP or IOP error */
1035285809Sscottl    if ((SCRATCH_PAD1_ERR == (value & SCRATCH_PAD_STATE_MASK)) || (SCRATCH_PAD2_ERR == (value1 & SCRATCH_PAD_STATE_MASK)))
1036285809Sscottl    {
1037285809Sscottl      if (agNULL != saRoot)
1038285809Sscottl      {
1039285809Sscottl        controllerStatus->fatalErrorInfo.regDumpBusBaseNum0 = saRoot->mainConfigTable.regDumpPCIBAR;
1040285809Sscottl        controllerStatus->fatalErrorInfo.regDumpOffset0 = saRoot->mainConfigTable.FatalErrorDumpOffset0;
1041285809Sscottl        controllerStatus->fatalErrorInfo.regDumpLen0 = saRoot->mainConfigTable.FatalErrorDumpLength0;
1042285809Sscottl        controllerStatus->fatalErrorInfo.regDumpBusBaseNum1 = saRoot->mainConfigTable.regDumpPCIBAR;
1043285809Sscottl        controllerStatus->fatalErrorInfo.regDumpOffset1 = saRoot->mainConfigTable.FatalErrorDumpOffset1;
1044285809Sscottl        controllerStatus->fatalErrorInfo.regDumpLen1 = saRoot->mainConfigTable.FatalErrorDumpLength1;
1045285809Sscottl      }
1046285809Sscottl      else
1047285809Sscottl      {
1048285809Sscottl        controllerStatus->fatalErrorInfo.regDumpBusBaseNum0 = 0;
1049285809Sscottl        controllerStatus->fatalErrorInfo.regDumpOffset0 = 0;
1050285809Sscottl        controllerStatus->fatalErrorInfo.regDumpLen0 = 0;
1051285809Sscottl        controllerStatus->fatalErrorInfo.regDumpBusBaseNum1 = 0;
1052285809Sscottl        controllerStatus->fatalErrorInfo.regDumpOffset1 = 0;
1053285809Sscottl        controllerStatus->fatalErrorInfo.regDumpLen1 = 0;
1054285809Sscottl      }
1055285809Sscottl
1056285809Sscottl      if (agNULL != saRoot)
1057285809Sscottl      {
1058285809Sscottl        smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6f");
1059285809Sscottl      }
1060285809Sscottl      return AGSA_RC_FW_NOT_IN_READY_STATE;
1061285809Sscottl    }
1062285809Sscottl
1063285809Sscottl    /* checking the fw AAP and IOP in ready state */
1064285809Sscottl    max_wait_time = WAIT_SECONDS(2);  /* 2 sec timeout */
1065285809Sscottl    max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT);
1066285809Sscottl    /* wait until scratch pad 1 and 2 registers in ready state  */
1067285809Sscottl    do
1068285809Sscottl    {
1069285809Sscottl      ossaStallThread(agRoot, WAIT_INCREMENT);
1070285809Sscottl      value = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_1);
1071285809Sscottl      /* checking bit 4 to 7 for reserved in case we get 0xFFFFFFFF */
1072285809Sscottl      if (value & SCRATCH_PAD1_RESERVED)
1073285809Sscottl      {
1074285809Sscottl        SA_DBG1(("saGetControllerStatus: (Reserved bit not 0) SCRATCH_PAD1 value = 0x%x\n", value));
1075285809Sscottl        ret = AGSA_RC_FAILURE;
1076285809Sscottl        break;
1077285809Sscottl      }
1078285809Sscottl
1079285809Sscottl      value1 = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_2);
1080285809Sscottl      /* checking bit 4 to 7 for reserved in case we get 0xFFFFFFFF */
1081285809Sscottl      if (value1 & SCRATCH_PAD2_RESERVED)
1082285809Sscottl      {
1083285809Sscottl        SA_DBG1(("saGetControllerStatus: (Reserved bit not 0) SCRATCH_PAD2 value = 0x%x\n", value1));
1084285809Sscottl        ret = AGSA_RC_FAILURE;
1085285809Sscottl        break;
1086285809Sscottl      }
1087285809Sscottl
1088285809Sscottl      if ((max_wait_count -=WAIT_INCREMENT) == 0)
1089285809Sscottl      {
1090285809Sscottl        SA_DBG1(("saGetControllerStatus: Timeout!! SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1));
1091285809Sscottl        break;
1092285809Sscottl      }
1093285809Sscottl    } while (((value & SCRATCH_PAD_STATE_MASK) != SCRATCH_PAD1_RDY) || ((value1 & SCRATCH_PAD_STATE_MASK) != SCRATCH_PAD2_RDY));
1094285809Sscottl
1095285809Sscottl    if (!max_wait_count)
1096285809Sscottl    {
1097285809Sscottl      SA_DBG1(("saGetControllerStatus: timeout failure\n"));
1098285809Sscottl      ret = AGSA_RC_FAILURE;
1099285809Sscottl    }
1100285809Sscottl
1101285809Sscottl    if (ret == AGSA_RC_SUCCESS)
1102285809Sscottl    {
1103285809Sscottl      SA_DBG1(("saGetControllerStatus: FW Ready, SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1));
1104285809Sscottl
1105285809Sscottl      /* read scratch pad0 to get PCI BAR and offset of configuration table */
1106285809Sscottl      value = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_0);
1107285809Sscottl      /* get offset */
1108285809Sscottl      value1 = value & SCRATCH_PAD0_OFFSET_MASK;
1109285809Sscottl      /* get PCI BAR */
1110285809Sscottl      value = (value & SCRATCH_PAD0_BAR_MASK) >> SHIFT26;
1111285809Sscottl
1112285809Sscottl      /* read GST Table state */
1113285809Sscottl      mpiReadGSTable(agRoot, &GSTable);
1114285809Sscottl
1115285809Sscottl      /* read register dump information */
1116285809Sscottl      controllerStatus->fatalErrorInfo.regDumpBusBaseNum0 = value;
1117285809Sscottl      controllerStatus->fatalErrorInfo.regDumpBusBaseNum1 = value;
1118285809Sscottl      /* convert the PCI BAR to logical bar number */
1119285809Sscottl      value = (bit8)mpiGetPCIBarIndex(agRoot, value);
1120285809Sscottl      controllerStatus->fatalErrorInfo.regDumpOffset0 = ossaHwRegReadExt(agRoot, value, value1 + MAIN_FATAL_ERROR_RDUMP0_OFFSET);
1121285809Sscottl      controllerStatus->fatalErrorInfo.regDumpLen0    = ossaHwRegReadExt(agRoot, value, value1 + MAIN_FATAL_ERROR_RDUMP0_LENGTH);
1122285809Sscottl      controllerStatus->fatalErrorInfo.regDumpOffset1 = ossaHwRegReadExt(agRoot, value, value1 + MAIN_FATAL_ERROR_RDUMP1_OFFSET);
1123285809Sscottl      controllerStatus->fatalErrorInfo.regDumpLen1    = ossaHwRegReadExt(agRoot, value, value1 + MAIN_FATAL_ERROR_RDUMP1_LENGTH);
1124285809Sscottl
1125285809Sscottl      /* AAP/IOP error state */
1126285809Sscottl      SA_DBG2(("saGetControllerStatus: SCRATCH PAD0 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo0));
1127285809Sscottl      SA_DBG2(("saGetControllerStatus: SCRATCH PAD1 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo1));
1128285809Sscottl      SA_DBG2(("saGetControllerStatus: SCRATCH PAD2 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo2));
1129285809Sscottl      SA_DBG2(("saGetControllerStatus: SCRATCH PAD3 0x%x\n", controllerStatus->fatalErrorInfo.errorInfo3));
1130285809Sscottl      /* Register Dump information */
1131285809Sscottl      SA_DBG2(("saGetControllerStatus: RegDumpOffset0 0x%x\n", controllerStatus->fatalErrorInfo.regDumpOffset0));
1132285809Sscottl      SA_DBG2(("saGetControllerStatus: RegDumpLen0    0x%x\n", controllerStatus->fatalErrorInfo.regDumpLen0));
1133285809Sscottl      SA_DBG2(("saGetControllerStatus: RegDumpOffset1 0x%x\n", controllerStatus->fatalErrorInfo.regDumpOffset1));
1134285809Sscottl      SA_DBG2(("saGetControllerStatus: RegDumpLen1    0x%x\n", controllerStatus->fatalErrorInfo.regDumpLen1));
1135285809Sscottl
1136285809Sscottl      controllerStatus->interfaceState = GSTable.GSTLenMPIS & GST_INF_STATE_BITS;
1137285809Sscottl      controllerStatus->iqFreezeState0 = GSTable.IQFreezeState0;
1138285809Sscottl      controllerStatus->iqFreezeState1 = GSTable.IQFreezeState1;
1139285809Sscottl      for (i = 0; i < 8; i++)
1140285809Sscottl      {
1141285809Sscottl        controllerStatus->phyStatus[i] = GSTable.PhyState[i];
1142285809Sscottl        controllerStatus->recoverableErrorInfo[i] = GSTable.recoverErrInfo[i];
1143285809Sscottl      }
1144285809Sscottl      controllerStatus->tickCount0 = GSTable.MsguTcnt;
1145285809Sscottl      controllerStatus->tickCount1 = GSTable.IopTcnt;
1146285809Sscottl      controllerStatus->tickCount2 = GSTable.Iop1Tcnt;
1147285809Sscottl    }
1148285809Sscottl  }
1149285809Sscottl  else
1150285809Sscottl  {
1151285809Sscottl
1152285809Sscottl    SA_DBG1(("saGetControllerStatus: SPCv\n" ));
1153285809Sscottl
1154285809Sscottl
1155285809Sscottl    if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1) &   SCRATCH_PAD1_V_RESERVED )
1156285809Sscottl    {
1157285809Sscottl      SA_DBG1(("saGetControllerStatus: Warning SCRATCH_PAD1 reserved bits set value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1)));
1158285809Sscottl    }
1159285809Sscottl    if( si_check_V_HDA(agRoot))
1160285809Sscottl    {
1161285809Sscottl      /*  Check HDA */
1162285809Sscottl
1163285809Sscottl      controllerStatus->fatalErrorInfo.errorInfo0 = ossaHwRegRead(agRoot,V_Scratchpad_0_Register );
1164285809Sscottl      controllerStatus->fatalErrorInfo.errorInfo1 = ossaHwRegRead(agRoot,V_Scratchpad_1_Register );
1165285809Sscottl      controllerStatus->fatalErrorInfo.errorInfo2 = ossaHwRegRead(agRoot,V_Scratchpad_2_Register );
1166285809Sscottl      controllerStatus->fatalErrorInfo.errorInfo3 = ossaHwRegRead(agRoot,V_Scratchpad_3_Register );
1167285809Sscottl      SA_DBG1(("saGetControllerStatus: HDA mode, AGSA_RC_HDA_NO_FW_RUNNING errorInfo1  = 0x%x\n",controllerStatus->fatalErrorInfo.errorInfo1 ));
1168285809Sscottl      return AGSA_RC_HDA_NO_FW_RUNNING;
1169285809Sscottl    }
1170285809Sscottl
1171285809Sscottl    ret = si_check_V_Ready(agRoot);
1172285809Sscottl    /* Check ready */
1173285809Sscottl    if (ret == AGSA_RC_SUCCESS)
1174285809Sscottl    {
1175285809Sscottl      /* read GST Table state */
1176285809Sscottl      mpiReadGSTable(agRoot, &GSTable);
1177285809Sscottl      controllerStatus->interfaceState = GSTable.GSTLenMPIS & GST_INF_STATE_BITS;
1178285809Sscottl      controllerStatus->iqFreezeState0 = GSTable.IQFreezeState0;
1179285809Sscottl      controllerStatus->iqFreezeState1 = GSTable.IQFreezeState1;
1180285809Sscottl      for (i = 0; i < 8; i++)
1181285809Sscottl      {
1182285809Sscottl        controllerStatus->phyStatus[i] = GSTable.PhyState[i];
1183285809Sscottl        controllerStatus->recoverableErrorInfo[i] = GSTable.recoverErrInfo[i];
1184285809Sscottl      }
1185285809Sscottl      controllerStatus->tickCount0 = GSTable.MsguTcnt;
1186285809Sscottl      controllerStatus->tickCount1 = GSTable.IopTcnt;
1187285809Sscottl      controllerStatus->tickCount2 = GSTable.Iop1Tcnt;
1188285809Sscottl
1189285809Sscottl      controllerStatus->interfaceState = GSTable.GSTLenMPIS & GST_INF_STATE_BITS;
1190285809Sscottl      controllerStatus->iqFreezeState0 = GSTable.IQFreezeState0;
1191285809Sscottl      controllerStatus->iqFreezeState1 = GSTable.IQFreezeState1;
1192285809Sscottl      for (i = 0; i < 8; i++)
1193285809Sscottl      {
1194285809Sscottl        if( IS_SDKDATA(agRoot))
1195285809Sscottl        {
1196285809Sscottl          if (agNULL != saRoot)
1197285809Sscottl          {
1198285809Sscottl            controllerStatus->phyStatus[i] = ((saRoot->phys[i+8].linkstatus << SHIFT8) | saRoot->phys[i].linkstatus);
1199285809Sscottl          }
1200285809Sscottl        }
1201285809Sscottl        else
1202285809Sscottl        {
1203285809Sscottl          controllerStatus->phyStatus[i] = 0;
1204285809Sscottl        }
1205285809Sscottl        controllerStatus->recoverableErrorInfo[i] = GSTable.recoverErrInfo[i];
1206285809Sscottl      }
1207285809Sscottl      controllerStatus->tickCount0 = GSTable.MsguTcnt;
1208285809Sscottl      controllerStatus->tickCount1 = GSTable.IopTcnt;
1209285809Sscottl      controllerStatus->tickCount2 = GSTable.Iop1Tcnt;
1210285809Sscottl
1211285809Sscottl    }
1212285809Sscottl
1213285809Sscottl    SA_DBG1(("saGetControllerStatus: SCRATCH_PAD0 value = 0x%x\n", ossaHwRegRead(agRoot, V_Scratchpad_0_Register)));
1214285809Sscottl    SA_DBG1(("saGetControllerStatus: SCRATCH_PAD1 value = 0x%x\n", ossaHwRegRead(agRoot, V_Scratchpad_1_Register)));
1215285809Sscottl    SA_DBG1(("saGetControllerStatus: SCRATCH_PAD2 value = 0x%x\n", ossaHwRegRead(agRoot, V_Scratchpad_2_Register)));
1216285809Sscottl    SA_DBG1(("saGetControllerStatus: SCRATCH_PAD3 value = 0x%x\n", ossaHwRegRead(agRoot, V_Scratchpad_3_Register)));
1217285809Sscottl
1218285809Sscottl    controllerStatus->fatalErrorInfo.errorInfo0 = ossaHwRegRead(agRoot,V_Scratchpad_0_Register );
1219285809Sscottl    controllerStatus->fatalErrorInfo.errorInfo1 = ossaHwRegRead(agRoot,V_Scratchpad_1_Register );
1220285809Sscottl    controllerStatus->fatalErrorInfo.errorInfo2 = ossaHwRegRead(agRoot,V_Scratchpad_2_Register );
1221285809Sscottl    controllerStatus->fatalErrorInfo.errorInfo3 = ossaHwRegRead(agRoot,V_Scratchpad_3_Register );
1222285809Sscottl
1223285809Sscottl    controllerStatus->bootStatus = ( (( controllerStatus->fatalErrorInfo.errorInfo1 >>  SHIFT9) & 1 )                | /* bit 1  */
1224285809Sscottl                                     (( controllerStatus->fatalErrorInfo.errorInfo3 & 0x3)               << SHIFT16) | /* bit 16 17 */
1225285809Sscottl                                    ((( controllerStatus->fatalErrorInfo.errorInfo3 >>  SHIFT14) & 0x7)  << SHIFT18) | /* bit 18 19 20 */
1226285809Sscottl                                    ((( controllerStatus->fatalErrorInfo.errorInfo3 >>  SHIFT4 ) & 0x1)  << SHIFT23) | /* bit 23 */
1227285809Sscottl                                    ((( controllerStatus->fatalErrorInfo.errorInfo3 >>  SHIFT16) & 0xFF) << SHIFT24) );/* bit 24 31 */
1228285809Sscottl
1229285809Sscottl    controllerStatus->bootComponentState[0] = (bit16) (( controllerStatus->fatalErrorInfo.errorInfo1               & 3 ) | 0x8000); /* RAAE_STATE */
1230285809Sscottl    controllerStatus->bootComponentState[1] = (bit16) ((( controllerStatus->fatalErrorInfo.errorInfo1 >>  SHIFT10) & 3 ) | 0x8000); /* IOP0_STATE */
1231285809Sscottl    controllerStatus->bootComponentState[2] = (bit16) ((( controllerStatus->fatalErrorInfo.errorInfo1 >>  SHIFT12) & 3 ) | 0x8000); /* IOP1_STATE */
1232285809Sscottl    controllerStatus->bootComponentState[3] = (bit16) ((( controllerStatus->fatalErrorInfo.errorInfo1 >>  SHIFT4)  & 7 ) | 0x8000); /* BOOTLDR_STATE  */
1233285809Sscottl    controllerStatus->bootComponentState[4] = (bit16) ((( controllerStatus->fatalErrorInfo.errorInfo1 >>  SHIFT2)  & 3 ) | 0x8000); /* ILA State */
1234285809Sscottl    controllerStatus->bootComponentState[5] = 0;
1235285809Sscottl    controllerStatus->bootComponentState[6] = 0;
1236285809Sscottl    controllerStatus->bootComponentState[7] = 0;
1237285809Sscottl
1238285809Sscottl
1239285809Sscottl
1240285809Sscottl    if(controllerStatus->fatalErrorInfo.errorInfo0 == 0xFFFFFFFF)
1241285809Sscottl    {
1242285809Sscottl      ret = AGSA_RC_FAILURE;
1243285809Sscottl    }
1244285809Sscottl
1245285809Sscottl  }
1246285809Sscottl
1247285809Sscottl  SA_DBG1(("saGetControllerStatus: fatalErrorInfo.errorInfo0          0x%x\n", controllerStatus->fatalErrorInfo.errorInfo0));
1248285809Sscottl  SA_DBG1(("saGetControllerStatus: fatalErrorInfo.errorInfo1          0x%x\n", controllerStatus->fatalErrorInfo.errorInfo1));
1249285809Sscottl  SA_DBG1(("saGetControllerStatus: fatalErrorInfo.errorInfo2          0x%x\n", controllerStatus->fatalErrorInfo.errorInfo2));
1250285809Sscottl  SA_DBG1(("saGetControllerStatus: fatalErrorInfo.errorInfo3          0x%x\n", controllerStatus->fatalErrorInfo.errorInfo3));
1251285809Sscottl  SA_DBG1(("saGetControllerStatus: fatalErrorInfo.regDumpBusBaseNum0  0x%x\n", controllerStatus->fatalErrorInfo.regDumpBusBaseNum0));
1252285809Sscottl  SA_DBG1(("saGetControllerStatus: fatalErrorInfo.regDumpOffset0      0x%x\n", controllerStatus->fatalErrorInfo.regDumpOffset0));
1253285809Sscottl  SA_DBG1(("saGetControllerStatus: fatalErrorInfo.regDumpLen0         0x%x\n", controllerStatus->fatalErrorInfo.regDumpLen0));
1254285809Sscottl  SA_DBG1(("saGetControllerStatus: fatalErrorInfo.regDumpBusBaseNum1  0x%x\n", controllerStatus->fatalErrorInfo.regDumpBusBaseNum1));
1255285809Sscottl  SA_DBG1(("saGetControllerStatus: fatalErrorInfo.regDumpOffset1      0x%x\n", controllerStatus->fatalErrorInfo.regDumpOffset1));
1256285809Sscottl  SA_DBG1(("saGetControllerStatus: fatalErrorInfo.regDumpLen1         0x%x\n", controllerStatus->fatalErrorInfo.regDumpLen1));
1257285809Sscottl
1258285809Sscottl  SA_DBG1(("saGetControllerStatus: interfaceState                     0x%x\n", controllerStatus->interfaceState));
1259285809Sscottl  SA_DBG1(("saGetControllerStatus: iqFreezeState0                     0x%x\n", controllerStatus->iqFreezeState0));
1260285809Sscottl  SA_DBG1(("saGetControllerStatus: iqFreezeState1                     0x%x\n", controllerStatus->iqFreezeState1));
1261285809Sscottl  SA_DBG1(("saGetControllerStatus: tickCount0                         0x%x\n", controllerStatus->tickCount0));
1262285809Sscottl  SA_DBG1(("saGetControllerStatus: tickCount1                         0x%x\n", controllerStatus->tickCount1));
1263285809Sscottl  SA_DBG1(("saGetControllerStatus: tickCount2                         0x%x\n", controllerStatus->tickCount2));
1264285809Sscottl
1265285809Sscottl  SA_DBG1(("saGetControllerStatus: phyStatus[0]                       0x%08x\n", controllerStatus->phyStatus[0]));
1266285809Sscottl  SA_DBG1(("saGetControllerStatus: phyStatus[1]                       0x%08x\n", controllerStatus->phyStatus[1]));
1267285809Sscottl  SA_DBG1(("saGetControllerStatus: phyStatus[2]                       0x%08x\n", controllerStatus->phyStatus[2]));
1268285809Sscottl  SA_DBG1(("saGetControllerStatus: phyStatus[3]                       0x%08x\n", controllerStatus->phyStatus[3]));
1269285809Sscottl  SA_DBG1(("saGetControllerStatus: phyStatus[4]                       0x%08x\n", controllerStatus->phyStatus[4]));
1270285809Sscottl  SA_DBG1(("saGetControllerStatus: phyStatus[5]                       0x%08x\n", controllerStatus->phyStatus[5]));
1271285809Sscottl  SA_DBG1(("saGetControllerStatus: phyStatus[6]                       0x%08x\n", controllerStatus->phyStatus[6]));
1272285809Sscottl  SA_DBG1(("saGetControllerStatus: phyStatus[7]                       0x%08x\n", controllerStatus->phyStatus[7]));
1273285809Sscottl
1274285809Sscottl  SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[0]            0x%08x\n", controllerStatus->recoverableErrorInfo[0]));
1275285809Sscottl  SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[1]            0x%08x\n", controllerStatus->recoverableErrorInfo[1]));
1276285809Sscottl  SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[2]            0x%08x\n", controllerStatus->recoverableErrorInfo[2]));
1277285809Sscottl  SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[3]            0x%08x\n", controllerStatus->recoverableErrorInfo[3]));
1278285809Sscottl  SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[4]            0x%08x\n", controllerStatus->recoverableErrorInfo[4]));
1279285809Sscottl  SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[5]            0x%08x\n", controllerStatus->recoverableErrorInfo[5]));
1280285809Sscottl  SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[6]            0x%08x\n", controllerStatus->recoverableErrorInfo[6]));
1281285809Sscottl  SA_DBG1(("saGetControllerStatus: recoverableErrorInfo[7]            0x%08x\n", controllerStatus->recoverableErrorInfo[7]));
1282285809Sscottl
1283285809Sscottl  SA_DBG1(("saGetControllerStatus: bootStatus                         0x%08x\n", controllerStatus->bootStatus));
1284285809Sscottl  SA_DBG1(("saGetControllerStatus: bootStatus  Active FW Image        %x\n", (controllerStatus->bootStatus & 1 ) ? 1 : 0 ));
1285285809Sscottl  SA_DBG1(("saGetControllerStatus: bootStatus  Encryption Cap         %x\n", ((controllerStatus->bootStatus & 0x30000 ) >> SHIFT16) ));
1286285809Sscottl  SA_DBG1(("saGetControllerStatus: bootStatus  Encryption Sec Mode    %x\n", ((controllerStatus->bootStatus & 0xC0000 ) >> SHIFT18) ));
1287285809Sscottl  SA_DBG1(("saGetControllerStatus: bootStatus  Encryption AES XTS     %x\n", (controllerStatus->bootStatus & 0x800000 ) ? 1 : 0 ));
1288285809Sscottl  SA_DBG1(("saGetControllerStatus: bootStatus  Encryption Engine Stat 0x%x\n", ((controllerStatus->bootStatus & 0xFF000000 ) >> SHIFT24)  ));
1289285809Sscottl
1290285809Sscottl/*
1291285809Sscottl
1292285809SscottlBit 0 : Active FW Image
1293285809Sscottl0b: Primary Image
1294285809Sscottl1b: Secondary Image
1295285809Sscottl
1296285809SscottlBit 16-17 :  Encryption Capability
1297285809Sscottl00: Not supported. Controller firmware version doesn't support encryption functionality.
1298285809Sscottl01: 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]).
1299285809Sscottl10: 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]).
1300285809Sscottl11: Enabled. Encryption functionality is enabled and fully functional.
1301285809SscottlBit 18-21 : Encryption Current Security Mode
1302285809Sscottl0000: Security Mode Factory
1303285809Sscottl0001: Security Mode A
1304285809Sscottl0010: Security Mode B
1305285809SscottlAll other values are reserved.
1306285809SscottlBit22: Reserved
1307285809SscottlBit 23 : Encryption AES XTS Enabled
1308285809Sscottl0: AES XTS is disabled.
1309285809Sscottl1: AES XTS is enabled
1310285809SscottlBit 24-31 : Encryption Engine Status
1311285809Sscottl*/
1312285809Sscottl
1313285809Sscottl
1314285809Sscottl  SA_DBG1(("saGetControllerStatus: bootComponentState[0] RAAE_STATE   0x%x\n", controllerStatus->bootComponentState[0]));
1315285809Sscottl  SA_DBG1(("saGetControllerStatus: bootComponentState[1] IOP0_STATE   0x%x\n", controllerStatus->bootComponentState[1]));
1316285809Sscottl  SA_DBG1(("saGetControllerStatus: bootComponentState[2] IOP1_STATE   0x%x\n", controllerStatus->bootComponentState[2]));
1317285809Sscottl  SA_DBG1(("saGetControllerStatus: bootComponentState[3] BOOTLDR_     0x%x\n", controllerStatus->bootComponentState[3]));
1318285809Sscottl  SA_DBG1(("saGetControllerStatus: bootComponentState[4] ILA State    0x%x\n", controllerStatus->bootComponentState[4]));
1319285809Sscottl  SA_DBG1(("saGetControllerStatus: bootComponentState[5]              0x%x\n", controllerStatus->bootComponentState[5]));
1320285809Sscottl  SA_DBG1(("saGetControllerStatus: bootComponentState[6]              0x%x\n", controllerStatus->bootComponentState[6]));
1321285809Sscottl  SA_DBG1(("saGetControllerStatus: bootComponentState[7]              0x%x\n", controllerStatus->bootComponentState[7]));
1322285809Sscottl
1323285809Sscottl  if (agNULL != saRoot)
1324285809Sscottl  {
1325285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6f");
1326285809Sscottl  }
1327285809Sscottl
1328285809Sscottl  return ret;
1329285809Sscottl}
1330285809Sscottl
1331285809Sscottl/******************************************************************************/
1332285809Sscottl/*! \brief SPC Get Controller Event Log Information Command
1333285809Sscottl *
1334285809Sscottl *  This command sends Get Controller Event Log Information Command to SPC.
1335285809Sscottl *
1336285809Sscottl *  \param agRoot       Handles for this instance of SAS/SATA LL
1337285809Sscottl *  \param eventLogInfo event log information
1338285809Sscottl *
1339285809Sscottl *  \return If the MPI command is sent to SPC successfully
1340285809Sscottl *          - \e AGSA_RC_SUCCESS the MPI command is successfully
1341285809Sscottl *          - \e AGSA_RC_FAILURE the MPI command is failure
1342285809Sscottl *
1343285809Sscottl */
1344285809Sscottl/*******************************************************************************/
1345285809SscottlGLOBAL bit32 saGetControllerEventLogInfo(
1346285809Sscottl                        agsaRoot_t                *agRoot,
1347285809Sscottl                        agsaControllerEventLog_t  *eventLogInfo
1348285809Sscottl                        )
1349285809Sscottl{
1350285809Sscottl  bit32 ret           = AGSA_RC_SUCCESS;
1351285809Sscottl  agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1352285809Sscottl
1353285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"6g");
1354285809Sscottl
1355285809Sscottl  /* sanity check */
1356285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
1357285809Sscottl
1358285809Sscottl  eventLogInfo->eventLog1 = saRoot->memoryAllocated.agMemory[MPI_MEM_INDEX + MPI_EVENTLOG_INDEX];
1359285809Sscottl  eventLogInfo->eventLog1Option = saRoot->mainConfigTable.eventLogOption;
1360285809Sscottl  eventLogInfo->eventLog2 = saRoot->memoryAllocated.agMemory[MPI_MEM_INDEX + MPI_IOP_EVENTLOG_INDEX];
1361285809Sscottl  eventLogInfo->eventLog2Option = saRoot->mainConfigTable.IOPeventLogOption;
1362285809Sscottl
1363285809Sscottl  smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6g");
1364285809Sscottl
1365285809Sscottl  return ret;
1366285809Sscottl}
1367285809Sscottl
1368285809Sscottl/******************************************************************************/
1369285809Sscottl/*! \brief SPC Set GPIO Event Setup Command
1370285809Sscottl *
1371285809Sscottl *  This command sends GPIO Event Setup Command to SPC.
1372285809Sscottl *
1373285809Sscottl *  \param agRoot             Handles for this instance of SAS/SATA LL
1374285809Sscottl *  \param agsaContext        Context of this command
1375285809Sscottl *  \param queueNum           Queue number of inbound/outbound queue
1376285809Sscottl *  \param gpioEventSetupInfo Pointer of Event Setup Information structure
1377285809Sscottl *
1378285809Sscottl *  \return If the MPI command is sent to SPC successfully
1379285809Sscottl *          - \e AGSA_RC_SUCCESS the MPI command is successfully
1380285809Sscottl *          - \e AGSA_RC_FAILURE the MPI command is failure
1381285809Sscottl *
1382285809Sscottl */
1383285809Sscottl/*******************************************************************************/
1384285809SscottlGLOBAL bit32 saGpioEventSetup(
1385285809Sscottl                        agsaRoot_t                *agRoot,
1386285809Sscottl                        agsaContext_t             *agContext,
1387285809Sscottl                        bit32                     queueNum,
1388285809Sscottl                        agsaGpioEventSetupInfo_t  *gpioEventSetupInfo
1389285809Sscottl                        )
1390285809Sscottl{
1391285809Sscottl  bit32 ret           = AGSA_RC_SUCCESS;
1392285809Sscottl  agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1393285809Sscottl  agsaIORequestDesc_t *pRequest;
1394285809Sscottl  agsaGPIOCmd_t       payload;
1395285809Sscottl
1396285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"6h");
1397285809Sscottl
1398285809Sscottl  /* sanity check */
1399285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
1400285809Sscottl
1401285809Sscottl  /* Get request from free IORequests */
1402285809Sscottl  ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1403285809Sscottl  pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1404285809Sscottl
1405285809Sscottl  /* If no LL Control request entry available */
1406285809Sscottl  if ( agNULL == pRequest )
1407285809Sscottl  {
1408285809Sscottl    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1409285809Sscottl    SA_DBG1(("saGpioEventSetup, No request from free list\n" ));
1410285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6h");
1411285809Sscottl    return AGSA_RC_BUSY;
1412285809Sscottl  }
1413285809Sscottl  /* If LL Control request entry avaliable */
1414285809Sscottl  else
1415285809Sscottl  {
1416285809Sscottl    /* Remove the request from free list */
1417285809Sscottl    saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
1418285809Sscottl    saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
1419285809Sscottl    saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
1420285809Sscottl    saRoot->IOMap[pRequest->HTag].agContext = agContext;
1421285809Sscottl    pRequest->valid = agTRUE;
1422285809Sscottl
1423285809Sscottl    /* set payload to zeros */
1424285809Sscottl    si_memset(&payload, 0, sizeof(agsaGPIOCmd_t));
1425285809Sscottl    /* build IOMB command and send to SPC */
1426285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, tag), pRequest->HTag);
1427285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, eOBIDGeGsGrGw), GPIO_GE_BIT);
1428285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, GPIEVChange), gpioEventSetupInfo->gpioEventLevel);
1429285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, GPIEVFall), gpioEventSetupInfo->gpioEventFallingEdge);
1430285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, GPIEVRise), gpioEventSetupInfo->gpioEventRisingEdge);
1431285809Sscottl    ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GPIO, IOMB_SIZE64, queueNum);
1432285809Sscottl    if (AGSA_RC_SUCCESS != ret)
1433285809Sscottl    {
1434285809Sscottl      /* remove the request from IOMap */
1435285809Sscottl      saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
1436285809Sscottl      saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
1437285809Sscottl      saRoot->IOMap[pRequest->HTag].agContext = agNULL;
1438285809Sscottl      pRequest->valid = agFALSE;
1439285809Sscottl
1440285809Sscottl      /* return the request to free pool */
1441285809Sscottl      if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
1442285809Sscottl      {
1443285809Sscottl        SA_DBG1(("saGpioEventSetup: saving pRequest (%p) for later use\n", pRequest));
1444285809Sscottl        saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1445285809Sscottl      }
1446285809Sscottl      else
1447285809Sscottl      {
1448285809Sscottl        /* return the request to free pool */
1449285809Sscottl        saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1450285809Sscottl      }
1451285809Sscottl      SA_DBG1(("saGpioEventSetup, sending IOMB failed\n" ));
1452285809Sscottl    }
1453285809Sscottl  }
1454285809Sscottl
1455285809Sscottl  ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1456285809Sscottl  smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6h");
1457285809Sscottl
1458285809Sscottl  return ret;
1459285809Sscottl}
1460285809Sscottl
1461285809Sscottl/******************************************************************************/
1462285809Sscottl/*! \brief SPC Set GPIO Pin Setup Command
1463285809Sscottl *
1464285809Sscottl *  This command sends GPIO Pin Setup Command to SPC.
1465285809Sscottl *
1466285809Sscottl *  \param agRoot             Handles for this instance of SAS/SATA LL
1467285809Sscottl *  \param agsaContext        Context of this command
1468285809Sscottl *  \param queueNum           Queue number of inbound/outbound queue
1469285809Sscottl *  \param gpioPinSetupInfo   Pointer of Event Setup Information structure
1470285809Sscottl *
1471285809Sscottl *  \return If the MPI command is sent to SPC successfully
1472285809Sscottl *          - \e AGSA_RC_SUCCESS the MPI command is successfully
1473285809Sscottl *          - \e AGSA_RC_FAILURE the MPI command is failure
1474285809Sscottl *
1475285809Sscottl */
1476285809Sscottl/*******************************************************************************/
1477285809SscottlGLOBAL bit32 saGpioPinSetup(
1478285809Sscottl                        agsaRoot_t                *agRoot,
1479285809Sscottl                        agsaContext_t             *agContext,
1480285809Sscottl                        bit32                     queueNum,
1481285809Sscottl                        agsaGpioPinSetupInfo_t    *gpioPinSetupInfo
1482285809Sscottl                        )
1483285809Sscottl{
1484285809Sscottl  bit32 ret           = AGSA_RC_SUCCESS;
1485285809Sscottl  agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1486285809Sscottl  agsaIORequestDesc_t *pRequest;
1487285809Sscottl  agsaGPIOCmd_t       payload;
1488285809Sscottl
1489285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"6i");
1490285809Sscottl
1491285809Sscottl  /* sanity check */
1492285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
1493285809Sscottl
1494285809Sscottl  /* Get request from free IORequests */
1495285809Sscottl  ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1496285809Sscottl  pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1497285809Sscottl
1498285809Sscottl  /* If no LL Control request entry available */
1499285809Sscottl  if ( agNULL == pRequest )
1500285809Sscottl  {
1501285809Sscottl    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1502285809Sscottl    SA_DBG1(("saGpioPinSetup, No request from free list\n" ));
1503285809Sscottl    return AGSA_RC_BUSY;
1504285809Sscottl  }
1505285809Sscottl  /* If LL Control request entry avaliable */
1506285809Sscottl  else
1507285809Sscottl  {
1508285809Sscottl    /* Remove the request from free list */
1509285809Sscottl    saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
1510285809Sscottl    saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
1511285809Sscottl    saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
1512285809Sscottl    saRoot->IOMap[pRequest->HTag].agContext = agContext;
1513285809Sscottl    pRequest->valid = agTRUE;
1514285809Sscottl
1515285809Sscottl    /* set payload to zeros */
1516285809Sscottl    si_memset(&payload, 0, sizeof(agsaGPIOCmd_t));
1517285809Sscottl    /* build IOMB command and send to SPC */
1518285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, tag), pRequest->HTag);
1519285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, eOBIDGeGsGrGw), GPIO_GS_BIT);
1520285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, GpioIe), gpioPinSetupInfo->gpioInputEnabled);
1521285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, OT11_0), gpioPinSetupInfo->gpioTypePart1);
1522285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, OT19_12), gpioPinSetupInfo->gpioTypePart2);
1523285809Sscottl    ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GPIO, IOMB_SIZE64, queueNum);
1524285809Sscottl    if (AGSA_RC_SUCCESS != ret)
1525285809Sscottl    {
1526285809Sscottl      /* remove the request from IOMap */
1527285809Sscottl      saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
1528285809Sscottl      saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
1529285809Sscottl      saRoot->IOMap[pRequest->HTag].agContext = agNULL;
1530285809Sscottl      pRequest->valid = agFALSE;
1531285809Sscottl      /* return the request to free pool */
1532285809Sscottl      if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
1533285809Sscottl      {
1534285809Sscottl        SA_DBG1(("saGpioPinSetup: saving pRequest (%p) for later use\n", pRequest));
1535285809Sscottl        saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1536285809Sscottl      }
1537285809Sscottl      else
1538285809Sscottl      {
1539285809Sscottl        /* return the request to free pool */
1540285809Sscottl        saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1541285809Sscottl      }
1542285809Sscottl      SA_DBG1(("saGpioPinSetup, sending IOMB failed\n" ));
1543285809Sscottl    }
1544285809Sscottl  }
1545285809Sscottl
1546285809Sscottl  ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1547285809Sscottl  smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6i");
1548285809Sscottl
1549285809Sscottl  return ret;
1550285809Sscottl}
1551285809Sscottl
1552285809Sscottl/******************************************************************************/
1553285809Sscottl/*! \brief SPC GPIO Read Command
1554285809Sscottl *
1555285809Sscottl *  This command sends GPIO Read Command to SPC.
1556285809Sscottl *
1557285809Sscottl *  \param agRoot       Handles for this instance of SAS/SATA LL
1558285809Sscottl *  \param agsaContext  Context of this command
1559285809Sscottl *  \param queueNum     Queue number of inbound/outbound queue
1560285809Sscottl *
1561285809Sscottl *  \return If the MPI command is sent to SPC successfully
1562285809Sscottl *          - \e AGSA_RC_SUCCESS the MPI command is successfully
1563285809Sscottl *          - \e AGSA_RC_FAILURE the MPI command is failure
1564285809Sscottl *
1565285809Sscottl */
1566285809Sscottl/*******************************************************************************/
1567285809SscottlGLOBAL bit32 saGpioRead(
1568285809Sscottl                        agsaRoot_t                *agRoot,
1569285809Sscottl                        agsaContext_t             *agContext,
1570285809Sscottl                        bit32                     queueNum
1571285809Sscottl                        )
1572285809Sscottl{
1573285809Sscottl  bit32 ret           = AGSA_RC_SUCCESS;
1574285809Sscottl  agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1575285809Sscottl  agsaIORequestDesc_t *pRequest;
1576285809Sscottl  agsaGPIOCmd_t       payload;
1577285809Sscottl
1578285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"6j");
1579285809Sscottl
1580285809Sscottl  /* sanity check */
1581285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
1582285809Sscottl
1583285809Sscottl  /* Get request from free IORequests */
1584285809Sscottl  ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1585285809Sscottl  pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1586285809Sscottl
1587285809Sscottl  /* If no LL Control request entry available */
1588285809Sscottl  if ( agNULL == pRequest )
1589285809Sscottl  {
1590285809Sscottl    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1591285809Sscottl    SA_DBG1(("saGpioRead, No request from free list\n" ));
1592285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6j");
1593285809Sscottl    return AGSA_RC_BUSY;
1594285809Sscottl  }
1595285809Sscottl  /* If LL Control request entry avaliable */
1596285809Sscottl  else
1597285809Sscottl  {
1598285809Sscottl    /* Remove the request from free list */
1599285809Sscottl    saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
1600285809Sscottl    saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
1601285809Sscottl    saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
1602285809Sscottl    saRoot->IOMap[pRequest->HTag].agContext = agContext;
1603285809Sscottl    pRequest->valid = agTRUE;
1604285809Sscottl
1605285809Sscottl    /* set payload to zeros */
1606285809Sscottl    si_memset(&payload, 0, sizeof(agsaGPIOCmd_t));
1607285809Sscottl    /* build IOMB command and send to SPC */
1608285809Sscottl    /* set GR bit */
1609285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, tag), pRequest->HTag);
1610285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, eOBIDGeGsGrGw), GPIO_GR_BIT);
1611285809Sscottl    ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GPIO, IOMB_SIZE64, queueNum);
1612285809Sscottl    if (AGSA_RC_SUCCESS != ret)
1613285809Sscottl    {
1614285809Sscottl      /* remove the request from IOMap */
1615285809Sscottl      saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
1616285809Sscottl      saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
1617285809Sscottl      saRoot->IOMap[pRequest->HTag].agContext = agNULL;
1618285809Sscottl      pRequest->valid = agFALSE;
1619285809Sscottl      /* return the request to free pool */
1620285809Sscottl      if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
1621285809Sscottl      {
1622285809Sscottl        SA_DBG1(("saGpioRead: saving pRequest (%p) for later use\n", pRequest));
1623285809Sscottl        saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1624285809Sscottl      }
1625285809Sscottl      else
1626285809Sscottl      {
1627285809Sscottl        /* return the request to free pool */
1628285809Sscottl        saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1629285809Sscottl      }
1630285809Sscottl      SA_DBG1(("saGpioRead, sending IOMB failed\n" ));
1631285809Sscottl    }
1632285809Sscottl  }
1633285809Sscottl  ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1634285809Sscottl
1635285809Sscottl  smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6j");
1636285809Sscottl
1637285809Sscottl  return ret;
1638285809Sscottl}
1639285809Sscottl
1640285809Sscottl/******************************************************************************/
1641285809Sscottl/*! \brief SPC GPIO Write Command
1642285809Sscottl *
1643285809Sscottl *  This command sends GPIO Write Command to SPC.
1644285809Sscottl *
1645285809Sscottl *  \param agRoot         Handles for this instance of SAS/SATA LL
1646285809Sscottl *  \param agsaContext    Context of this command
1647285809Sscottl *  \param queueNum       Queue number of inbound/outbound queue
1648285809Sscottl *  \param gpioWriteMask  GPIO Write Mask
1649285809Sscottl *  \param gpioWriteValue GPIO Write Value
1650285809Sscottl *
1651285809Sscottl *  \return If the MPI command is sent to SPC successfully
1652285809Sscottl *          - \e AGSA_RC_SUCCESS the MPI command is successfully
1653285809Sscottl *          - \e AGSA_RC_FAILURE the MPI command is failure
1654285809Sscottl *
1655285809Sscottl */
1656285809Sscottl/*******************************************************************************/
1657285809SscottlGLOBAL bit32 saGpioWrite(
1658285809Sscottl                        agsaRoot_t                *agRoot,
1659285809Sscottl                        agsaContext_t             *agContext,
1660285809Sscottl                        bit32                     queueNum,
1661285809Sscottl                        bit32                     gpioWriteMask,
1662285809Sscottl                        bit32                     gpioWriteValue
1663285809Sscottl                        )
1664285809Sscottl{
1665285809Sscottl  bit32 ret           = AGSA_RC_SUCCESS;
1666285809Sscottl  agsaLLRoot_t        *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1667285809Sscottl  agsaIORequestDesc_t *pRequest;
1668285809Sscottl  agsaGPIOCmd_t       payload;
1669285809Sscottl
1670285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"6k");
1671285809Sscottl
1672285809Sscottl  /* sanity check */
1673285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
1674285809Sscottl
1675285809Sscottl  /* Get request from free IORequests */
1676285809Sscottl  ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1677285809Sscottl  pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1678285809Sscottl
1679285809Sscottl  /* If no LL Control request entry available */
1680285809Sscottl  if ( agNULL == pRequest )
1681285809Sscottl  {
1682285809Sscottl    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1683285809Sscottl    SA_DBG1(("saGpioWrite, No request from free list\n" ));
1684285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6k");
1685285809Sscottl    return AGSA_RC_BUSY;
1686285809Sscottl  }
1687285809Sscottl  /* If LL Control request entry avaliable */
1688285809Sscottl  else
1689285809Sscottl  {
1690285809Sscottl    /* Remove the request from free list */
1691285809Sscottl    saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
1692285809Sscottl    saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
1693285809Sscottl    saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
1694285809Sscottl    saRoot->IOMap[pRequest->HTag].agContext = agContext;
1695285809Sscottl    pRequest->valid = agTRUE;
1696285809Sscottl
1697285809Sscottl    /* set payload to zeros */
1698285809Sscottl    si_memset(&payload, 0, sizeof(agsaGPIOCmd_t));
1699285809Sscottl    /* build IOMB command and send to SPC */
1700285809Sscottl    /* set GW bit */
1701285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, tag), pRequest->HTag);
1702285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, eOBIDGeGsGrGw), GPIO_GW_BIT);
1703285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, GpioWrMsk), gpioWriteMask);
1704285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGPIOCmd_t, GpioWrVal), gpioWriteValue);
1705285809Sscottl    ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GPIO, IOMB_SIZE64, queueNum);
1706285809Sscottl    if (AGSA_RC_SUCCESS != ret)
1707285809Sscottl    {
1708285809Sscottl      /* remove the request from IOMap */
1709285809Sscottl      saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
1710285809Sscottl      saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
1711285809Sscottl      saRoot->IOMap[pRequest->HTag].agContext = agNULL;
1712285809Sscottl      pRequest->valid = agFALSE;
1713285809Sscottl
1714285809Sscottl      /* return the request to free pool */
1715285809Sscottl      if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
1716285809Sscottl      {
1717285809Sscottl        SA_DBG1(("saGpioWrite: saving pRequest (%p) for later use\n", pRequest));
1718285809Sscottl        saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1719285809Sscottl      }
1720285809Sscottl      else
1721285809Sscottl      {
1722285809Sscottl        /* return the request to free pool */
1723285809Sscottl        saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1724285809Sscottl      }
1725285809Sscottl      SA_DBG1(("saGpioWrite, sending IOMB failed\n" ));
1726285809Sscottl    }
1727285809Sscottl  }
1728285809Sscottl
1729285809Sscottl  ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1730285809Sscottl  smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6k");
1731285809Sscottl
1732285809Sscottl  return ret;
1733285809Sscottl}
1734285809Sscottl
1735285809Sscottl/******************************************************************************/
1736285809Sscottl/*! \brief SPC SAS Diagnostic Execute Command
1737285809Sscottl *
1738285809Sscottl *  This command sends SAS Diagnostic Execute Command to SPC.
1739285809Sscottl *
1740285809Sscottl *  \param agRoot         Handles for this instance of SAS/SATA LL
1741285809Sscottl *  \param agsaContext    Context of this command
1742285809Sscottl *  \param queueNum       Queue number of inbound/outbound queue
1743285809Sscottl *  \param diag           Pointer of SAS Diag Execute Structure
1744285809Sscottl *
1745285809Sscottl *  \return If the MPI command is sent to SPC successfully
1746285809Sscottl *          - \e AGSA_RC_SUCCESS the MPI command is successfully
1747285809Sscottl *          - \e AGSA_RC_FAILURE the MPI command is failure
1748285809Sscottl *
1749285809Sscottl */
1750285809Sscottl/*******************************************************************************/
1751285809SscottlGLOBAL bit32 saSASDiagExecute(
1752285809Sscottl                        agsaRoot_t              *agRoot,
1753285809Sscottl                        agsaContext_t           *agContext,
1754285809Sscottl                        bit32                    queueNum,
1755285809Sscottl                        agsaSASDiagExecute_t    *diag
1756285809Sscottl                        )
1757285809Sscottl{
1758285809Sscottl  bit32                     ret = AGSA_RC_SUCCESS;
1759285809Sscottl  agsaLLRoot_t             *saRoot = agNULL;
1760285809Sscottl  agsaIORequestDesc_t      *pRequest = agNULL;
1761285809Sscottl  bit32  payload[32];
1762285809Sscottl  /* sanity check */
1763285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
1764285809Sscottl
1765285809Sscottl  saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1766285809Sscottl  /* sanity check */
1767285809Sscottl  SA_ASSERT((agNULL != saRoot), "");
1768285809Sscottl
1769285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"6m");
1770285809Sscottl
1771285809Sscottl  SA_DBG2(("saSASDiagExecute,command 0x%X\n", diag->command ));
1772285809Sscottl  SA_DBG2(("saSASDiagExecute,param0 0x%X\n", diag->param0 ));
1773285809Sscottl  SA_DBG2(("saSASDiagExecute,param2 0x%X\n", diag->param2 ));
1774285809Sscottl  SA_DBG2(("saSASDiagExecute,param3 0x%X\n", diag->param3 ));
1775285809Sscottl  SA_DBG2(("saSASDiagExecute,param4 0x%X\n", diag->param4 ));
1776285809Sscottl  SA_DBG2(("saSASDiagExecute,param5 0x%X\n", diag->param5 ));
1777285809Sscottl
1778285809Sscottl  /* Get request from free IORequests */
1779285809Sscottl  ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1780285809Sscottl  pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1781285809Sscottl
1782285809Sscottl  /* If no LL Control request entry available */
1783285809Sscottl  if ( agNULL == pRequest )
1784285809Sscottl  {
1785285809Sscottl    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1786285809Sscottl    SA_DBG1(("saSASDiagExecute, No request from free list\n" ));
1787285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6m");
1788285809Sscottl    return AGSA_RC_BUSY;
1789285809Sscottl  }
1790285809Sscottl  /* If LL Control request entry avaliable */
1791285809Sscottl  else
1792285809Sscottl  {
1793285809Sscottl    /* Remove the request from free list */
1794285809Sscottl    saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
1795285809Sscottl    saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
1796285809Sscottl    saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
1797285809Sscottl    saRoot->IOMap[pRequest->HTag].agContext = agContext;
1798285809Sscottl    pRequest->valid = agTRUE;
1799285809Sscottl    if(smIS_SPC(agRoot))
1800285809Sscottl    {
1801285809Sscottl      diag->param5 = 0; /* Reserved for SPC */
1802285809Sscottl    }
1803285809Sscottl
1804285809Sscottl    /* set payload to zeros */
1805285809Sscottl    si_memset(&payload, 0, sizeof(payload));
1806285809Sscottl    /* set payload to zeros */
1807285809Sscottl    if(smIS_SPCV(agRoot))
1808285809Sscottl    {
1809285809Sscottl      /* build IOMB command and send to SPC */
1810285809Sscottl      OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, tag),             pRequest->HTag);
1811285809Sscottl      OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, CmdTypeDescPhyId),diag->command );
1812285809Sscottl      OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, Pat1Pat2),        diag->param0 );
1813285809Sscottl      OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, Threshold),       diag->param1 );
1814285809Sscottl      OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, CodePatErrMsk),   diag->param2 );
1815285809Sscottl      OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, Pmon),            diag->param3 );
1816285809Sscottl      OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, PERF1CTL),        diag->param4 );
1817285809Sscottl      OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagExecuteCmd_t, THRSHLD1),        diag->param5 );
1818285809Sscottl      ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SAS_DIAG_EXECUTE, IOMB_SIZE128, queueNum);
1819285809Sscottl    }
1820285809Sscottl    else
1821285809Sscottl    {
1822285809Sscottl      /* build IOMB command and send to SPC */
1823285809Sscottl      OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_SASDiagExecuteCmd_t, tag),             pRequest->HTag);
1824285809Sscottl      OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_SASDiagExecuteCmd_t, CmdTypeDescPhyId),diag->command );
1825285809Sscottl      OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_SASDiagExecuteCmd_t, Pat1Pat2),        diag->param0 );
1826285809Sscottl      OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_SASDiagExecuteCmd_t, Threshold),       diag->param1 );
1827285809Sscottl      OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_SASDiagExecuteCmd_t, CodePatErrMsk),   diag->param2 );
1828285809Sscottl      OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_SASDiagExecuteCmd_t, Pmon),            diag->param3 );
1829285809Sscottl      OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_SASDiagExecuteCmd_t, PERF1CTL),        diag->param4 );
1830285809Sscottl      ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SAS_DIAG_EXECUTE, IOMB_SIZE64, queueNum);
1831285809Sscottl    }
1832285809Sscottl    if (AGSA_RC_SUCCESS != ret)
1833285809Sscottl    {
1834285809Sscottl      /* remove the request from IOMap */
1835285809Sscottl      saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
1836285809Sscottl      saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
1837285809Sscottl      saRoot->IOMap[pRequest->HTag].agContext = agNULL;
1838285809Sscottl      pRequest->valid = agFALSE;
1839285809Sscottl
1840285809Sscottl      /* return the request to free pool */
1841285809Sscottl      if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
1842285809Sscottl      {
1843285809Sscottl        SA_DBG1(("saSASDiagExecute: saving pRequest (%p) for later use\n", pRequest));
1844285809Sscottl        saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1845285809Sscottl      }
1846285809Sscottl      else
1847285809Sscottl      {
1848285809Sscottl        /* return the request to free pool */
1849285809Sscottl        saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1850285809Sscottl      }
1851285809Sscottl      SA_DBG1(("saSASDiagExecute, sending IOMB failed\n" ));
1852285809Sscottl      smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6m");
1853285809Sscottl      ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1854285809Sscottl      return ret;
1855285809Sscottl    }
1856285809Sscottl  }
1857285809Sscottl
1858285809Sscottl  smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "6m");
1859285809Sscottl  ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1860285809Sscottl  return ret;
1861285809Sscottl}
1862285809Sscottl
1863285809Sscottl/******************************************************************************/
1864285809Sscottl/*! \brief SPC SAS Diagnostic Start/End Command
1865285809Sscottl *
1866285809Sscottl *  This command sends SAS Diagnostic Start/End Command to SPC.
1867285809Sscottl *
1868285809Sscottl *  \param agRoot         Handles for this instance of SAS/SATA LL
1869285809Sscottl *  \param agsaContext    Context of this command
1870285809Sscottl *  \param queueNum       Queue number of inbound/outbound queue
1871285809Sscottl *  \param phyId          Phy ID
1872285809Sscottl *  \param operation      Operation of SAS Diagnostic
1873285809Sscottl *
1874285809Sscottl *  \return If the MPI command is sent to SPC successfully
1875285809Sscottl *          - \e AGSA_RC_SUCCESS the MPI command is successfully
1876285809Sscottl *          - \e AGSA_RC_FAILURE the MPI command is failure
1877285809Sscottl *
1878285809Sscottl */
1879285809Sscottl/*******************************************************************************/
1880285809SscottlGLOBAL bit32 saSASDiagStartEnd(
1881285809Sscottl                        agsaRoot_t                *agRoot,
1882285809Sscottl                        agsaContext_t             *agContext,
1883285809Sscottl                        bit32                     queueNum,
1884285809Sscottl                        bit32                     phyId,
1885285809Sscottl                        bit32                     operation
1886285809Sscottl                        )
1887285809Sscottl{
1888285809Sscottl  bit32 ret                = AGSA_RC_SUCCESS;
1889285809Sscottl  agsaLLRoot_t             *saRoot;
1890285809Sscottl  agsaIORequestDesc_t      *pRequest;
1891285809Sscottl  agsaSASDiagStartEndCmd_t payload;
1892285809Sscottl
1893285809Sscottl  /* sanity check */
1894285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
1895285809Sscottl  if (agRoot == agNULL)
1896285809Sscottl  {
1897285809Sscottl    SA_DBG1(("saSASDiagStartEnd: agRoot == agNULL\n"));
1898285809Sscottl    return AGSA_RC_FAILURE;
1899285809Sscottl  }
1900285809Sscottl  saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
1901285809Sscottl  SA_ASSERT((agNULL != saRoot), "");
1902285809Sscottl  if (saRoot == agNULL)
1903285809Sscottl  {
1904285809Sscottl    SA_DBG1(("saSASDiagStartEnd: saRoot == agNULL\n"));
1905285809Sscottl    return AGSA_RC_FAILURE;
1906285809Sscottl  }
1907285809Sscottl
1908285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"6n");
1909285809Sscottl
1910285809Sscottl  SA_DBG3(("saSASDiagStartEnd, phyId 0x%x operation 0x%x\n",phyId,operation ));
1911285809Sscottl
1912285809Sscottl  /* Get request from free IORequests */
1913285809Sscottl  ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1914285809Sscottl  pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1915285809Sscottl
1916285809Sscottl  /* If no LL Control request entry available */
1917285809Sscottl  if ( agNULL == pRequest )
1918285809Sscottl  {
1919285809Sscottl    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1920285809Sscottl    SA_DBG1(("saSASDiagStartEnd, No request from free list\n" ));
1921285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6n");
1922285809Sscottl    return AGSA_RC_BUSY;
1923285809Sscottl  }
1924285809Sscottl  /* If LL Control request entry avaliable */
1925285809Sscottl  else
1926285809Sscottl  {
1927285809Sscottl    /* Remove the request from free list */
1928285809Sscottl    saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
1929285809Sscottl    saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
1930285809Sscottl    saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
1931285809Sscottl    saRoot->IOMap[pRequest->HTag].agContext = agContext;
1932285809Sscottl    pRequest->valid = agTRUE;
1933285809Sscottl
1934285809Sscottl    /* set payload to zeros */
1935285809Sscottl    si_memset(&payload, 0, sizeof(agsaSASDiagStartEndCmd_t));
1936285809Sscottl    /* build IOMB command and send to SPC */
1937285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagStartEndCmd_t, tag), pRequest->HTag);
1938285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASDiagStartEndCmd_t, OperationPhyId), ((phyId & SM_PHYID_MASK) | (operation << SHIFT8)));
1939285809Sscottl    ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SAS_DIAG_MODE_START_END, IOMB_SIZE64, queueNum);
1940285809Sscottl    if (AGSA_RC_SUCCESS != ret)
1941285809Sscottl    {
1942285809Sscottl      /* remove the request from IOMap */
1943285809Sscottl      saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
1944285809Sscottl      saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
1945285809Sscottl      saRoot->IOMap[pRequest->HTag].agContext = agNULL;
1946285809Sscottl      pRequest->valid = agFALSE;
1947285809Sscottl
1948285809Sscottl      /* return the request to free pool */
1949285809Sscottl      if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
1950285809Sscottl      {
1951285809Sscottl        SA_DBG1(("saSASDiagStartEnd: saving pRequest (%p) for later use\n", pRequest));
1952285809Sscottl        saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1953285809Sscottl      }
1954285809Sscottl      else
1955285809Sscottl      {
1956285809Sscottl        /* return the request to free pool */
1957285809Sscottl        saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1958285809Sscottl      }
1959285809Sscottl      SA_DBG1(("saSASDiagStartEnd, sending IOMB failed\n" ));
1960285809Sscottl    }
1961285809Sscottl  }
1962285809Sscottl
1963285809Sscottl  smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6n");
1964285809Sscottl  ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1965285809Sscottl  return ret;
1966285809Sscottl}
1967285809Sscottl
1968285809Sscottl/******************************************************************************/
1969285809Sscottl/*! \brief Initiate a GET TIME STAMP command
1970285809Sscottl *
1971285809Sscottl *  This function is called to initiate a Get Time Stamp command to the SPC.
1972285809Sscottl *  The completion of this function is reported in ossaGetTimeStampCB().
1973285809Sscottl *
1974285809Sscottl *  \param agRoot      handles for this instance of SAS/SATA hardware
1975285809Sscottl *  \param agContext   the context of this API
1976285809Sscottl *  \param queueNum    queue number
1977285809Sscottl *
1978285809Sscottl *  \return
1979285809Sscottl *          - SUCCESS or FAILURE
1980285809Sscottl */
1981285809Sscottl/*******************************************************************************/
1982285809SscottlGLOBAL bit32 saGetTimeStamp(
1983285809Sscottl                      agsaRoot_t        *agRoot,
1984285809Sscottl                      agsaContext_t     *agContext,
1985285809Sscottl                      bit32             queueNum
1986285809Sscottl                      )
1987285809Sscottl{
1988285809Sscottl  agsaIORequestDesc_t   *pRequest;
1989285809Sscottl  agsaGetTimeStampCmd_t payload;
1990285809Sscottl  bit32                 ret = AGSA_RC_SUCCESS;
1991285809Sscottl  agsaLLRoot_t          *saRoot;
1992285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
1993285809Sscottl  if (agRoot == agNULL)
1994285809Sscottl  {
1995285809Sscottl    SA_DBG1(("saGetTimeStamp: agRoot == agNULL\n"));
1996285809Sscottl    return AGSA_RC_FAILURE;
1997285809Sscottl  }
1998285809Sscottl  saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
1999285809Sscottl  SA_ASSERT((agNULL != saRoot), "");
2000285809Sscottl  if (saRoot == agNULL)
2001285809Sscottl  {
2002285809Sscottl    SA_DBG1(("saGetTimeStamp: saRoot == agNULL\n"));
2003285809Sscottl    return AGSA_RC_FAILURE;
2004285809Sscottl  }
2005285809Sscottl
2006285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"6o");
2007285809Sscottl
2008285809Sscottl  /* sanity check */
2009285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
2010285809Sscottl
2011285809Sscottl  SA_DBG3(("saGetTimeStamp: agContext %p\n", agContext));
2012285809Sscottl
2013285809Sscottl  /* Get request from free IORequests */
2014285809Sscottl  ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2015285809Sscottl  pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2016285809Sscottl
2017285809Sscottl  /* If no LL Control request entry available */
2018285809Sscottl  if ( agNULL == pRequest )
2019285809Sscottl  {
2020285809Sscottl    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2021285809Sscottl    SA_DBG1(("saGetTimeStamp, No request from free list\n" ));
2022285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6o");
2023285809Sscottl    return AGSA_RC_BUSY;
2024285809Sscottl  }
2025285809Sscottl  /* If LL Control request entry avaliable */
2026285809Sscottl  else
2027285809Sscottl  {
2028285809Sscottl    /* Remove the request from free list */
2029285809Sscottl    saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
2030285809Sscottl    saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
2031285809Sscottl    saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
2032285809Sscottl    saRoot->IOMap[pRequest->HTag].agContext = agContext;
2033285809Sscottl    pRequest->valid = agTRUE;
2034285809Sscottl
2035285809Sscottl    /* build IOMB command and send to SPC */
2036285809Sscottl    /* set payload to zeros */
2037285809Sscottl    si_memset(&payload, 0, sizeof(agsaGetTimeStampCmd_t));
2038285809Sscottl
2039285809Sscottl    /* set tag */
2040285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetTimeStampCmd_t, tag), pRequest->HTag);
2041285809Sscottl
2042285809Sscottl    /* build IOMB command and send to SPC */
2043285809Sscottl    ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_TIME_STAMP, IOMB_SIZE64, queueNum);
2044285809Sscottl    if (AGSA_RC_SUCCESS != ret)
2045285809Sscottl    {
2046285809Sscottl      /* remove the request from IOMap */
2047285809Sscottl      saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
2048285809Sscottl      saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
2049285809Sscottl      saRoot->IOMap[pRequest->HTag].agContext = agNULL;
2050285809Sscottl      pRequest->valid = agFALSE;
2051285809Sscottl
2052285809Sscottl      /* return the request to free pool */
2053285809Sscottl      if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
2054285809Sscottl      {
2055285809Sscottl        SA_DBG1(("saGetTimeStamp: saving pRequest (%p) for later use\n", pRequest));
2056285809Sscottl        saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
2057285809Sscottl      }
2058285809Sscottl      else
2059285809Sscottl      {
2060285809Sscottl        /* return the request to free pool */
2061285809Sscottl        saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2062285809Sscottl      }
2063285809Sscottl      SA_DBG1(("saGetTimeStamp, sending IOMB failed\n" ));
2064285809Sscottl    }
2065285809Sscottl  }
2066285809Sscottl
2067285809Sscottl  ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2068285809Sscottl  smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6o");
2069285809Sscottl
2070285809Sscottl  return ret;
2071285809Sscottl}
2072285809Sscottl
2073285809Sscottl/******************************************************************************/
2074285809Sscottl/*! \brief Update IOMap Entry
2075285809Sscottl *
2076285809Sscottl *  This function is called to update certain fields of IOMap Entry
2077285809Sscottl *
2078285809Sscottl *  \param pIOMap       IOMap Entry
2079285809Sscottl *  \param HTag         Host Tag
2080285809Sscottl *  \param pRequest     Request
2081285809Sscottl *  \parma agContext    Context of this API
2082285809Sscottl *
2083285809Sscottl *  \return             NA
2084285809Sscottl */
2085285809Sscottl/*******************************************************************************/
2086285809Sscottlstatic void saUpdateIOMap(
2087285809Sscottl                        agsaIOMap_t         *pIOMap,
2088285809Sscottl                        bit32               HTag,
2089285809Sscottl                        agsaIORequestDesc_t *pRequest,
2090285809Sscottl                        agsaContext_t       *agContext
2091285809Sscottl                        )
2092285809Sscottl{
2093285809Sscottl  pIOMap->Tag = HTag;
2094285809Sscottl  pIOMap->IORequest = (void *)pRequest;
2095285809Sscottl  pIOMap->agContext = agContext;
2096285809Sscottl}
2097285809Sscottl
2098285809Sscottl/******************************************************************************/
2099285809Sscottl/*! \brief Get a request from free pool
2100285809Sscottl *
2101285809Sscottl *  This function gets a request from free pool
2102285809Sscottl *
2103285809Sscottl *  \param agRoot       Handles for this instance of SAS/SATA LL
2104285809Sscottl *  \param agsaContext  Context of this command
2105285809Sscottl *
2106285809Sscottl *  \return
2107285809Sscottl *          - \e Pointer to request, in case of success
2108285809Sscottl *          - \e NULL, in case of failure
2109285809Sscottl *
2110285809Sscottl */
2111285809Sscottl/*******************************************************************************/
2112285809SscottlagsaIORequestDesc_t* saGetRequestFromFreePool(
2113285809Sscottl                                            agsaRoot_t      *agRoot,
2114285809Sscottl                                            agsaContext_t   *agContext
2115285809Sscottl                                            )
2116285809Sscottl{
2117285809Sscottl  agsaLLRoot_t          *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
2118285809Sscottl  agsaIORequestDesc_t   *pRequest = agNULL;
2119285809Sscottl
2120285809Sscottl  /* Acquire LL_IOREQ_LOCKEQ_LOCK */
2121285809Sscottl  ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2122285809Sscottl
2123285809Sscottl  /* Get request from free IORequests */
2124285809Sscottl  pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2125285809Sscottl  if (pRequest != agNULL)
2126285809Sscottl  {
2127285809Sscottl    /* Remove the request from free list */
2128285809Sscottl    saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
2129285809Sscottl
2130285809Sscottl    /* Release LL_IOREQ_LOCKEQ_LOCK */
2131285809Sscottl    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2132285809Sscottl
2133285809Sscottl    /* Add the request to IOMap */
2134285809Sscottl    saUpdateIOMap(&saRoot->IOMap[pRequest->HTag], pRequest->HTag, pRequest, agContext);
2135285809Sscottl    pRequest->valid = agTRUE;
2136285809Sscottl  }
2137285809Sscottl  else
2138285809Sscottl  {
2139285809Sscottl    /* Release LL_IOREQ_LOCKEQ_LOCK */
2140285809Sscottl    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2141285809Sscottl  }
2142285809Sscottl
2143285809Sscottl  return pRequest;
2144285809Sscottl}
2145285809Sscottl
2146285809Sscottl/******************************************************************************/
2147285809Sscottl/*! \brief Return request to free pool
2148285809Sscottl *
2149285809Sscottl *  This function returns the request to free pool
2150285809Sscottl *
2151285809Sscottl *  \param agRoot       Handles for this instance of SAS/SATA LL
2152285809Sscottl *  \param pRequest     Request to be returned
2153285809Sscottl *
2154285809Sscottl *  \return             NA
2155285809Sscottl *
2156285809Sscottl */
2157285809Sscottl/*******************************************************************************/
2158285809Sscottlvoid saReturnRequestToFreePool(
2159285809Sscottl                            agsaRoot_t          *agRoot,
2160285809Sscottl                            agsaIORequestDesc_t *pRequest
2161285809Sscottl                            )
2162285809Sscottl{
2163285809Sscottl  agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
2164285809Sscottl
2165285809Sscottl  SA_ASSERT((pRequest->valid), "pRequest->valid");
2166285809Sscottl
2167285809Sscottl  /* Remove the request from IOMap */
2168285809Sscottl  saUpdateIOMap(&saRoot->IOMap[pRequest->HTag], MARK_OFF, agNULL, agNULL);
2169285809Sscottl  pRequest->valid = agFALSE;
2170285809Sscottl
2171285809Sscottl  /* Acquire LL_IOREQ_LOCKEQ_LOCK */
2172285809Sscottl  ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2173285809Sscottl
2174285809Sscottl  if (saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
2175285809Sscottl  {
2176285809Sscottl    SA_DBG1(("saReturnRequestToFreePool: saving pRequest (%p) for later use\n", pRequest));
2177285809Sscottl    saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
2178285809Sscottl  }
2179285809Sscottl  else
2180285809Sscottl  {
2181285809Sscottl    /* Return the request to free pool */
2182285809Sscottl    saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2183285809Sscottl  }
2184285809Sscottl
2185285809Sscottl  /* Release LL_IOREQ_LOCKEQ_LOCK */
2186285809Sscottl  ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2187285809Sscottl}
2188285809Sscottl/******************************************************************************/
2189285809Sscottl/*! \brief Initiate a serial GPIO command
2190285809Sscottl *
2191285809Sscottl *  This function is called to initiate a serial GPIO command to the SPC.
2192285809Sscottl *  The completion of this function is reported in ossaSgpioCB().
2193285809Sscottl *
2194285809Sscottl *  \param agRoot      handles for this instance of SAS/SATA hardware
2195285809Sscottl *  \param agContext   the context of this API
2196285809Sscottl *  \param queueNum    queue number
2197285809Sscottl *  \param pSGpioReq   Pointer to the serial GPIO fields
2198285809Sscottl *
2199285809Sscottl *  \return
2200285809Sscottl *          - SUCCESS or FAILURE
2201285809Sscottl */
2202285809Sscottl/*******************************************************************************/
2203285809SscottlGLOBAL bit32 saSgpio(
2204285809Sscottl                agsaRoot_t              *agRoot,
2205285809Sscottl                agsaContext_t           *agContext,
2206285809Sscottl                bit32                   queueNum,
2207285809Sscottl                agsaSGpioReqResponse_t  *pSGpioReq
2208285809Sscottl                )
2209285809Sscottl{
2210285809Sscottl  bit32                 i;
2211285809Sscottl  agsaIORequestDesc_t   *pRequest = agNULL;
2212285809Sscottl  agsaSGpioCmd_t        payload = {0};
2213285809Sscottl  bit32                 ret = AGSA_RC_BUSY;
2214285809Sscottl
2215285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"6t");
2216285809Sscottl
2217285809Sscottl  /* Sanity check */
2218285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
2219285809Sscottl
2220285809Sscottl  SA_DBG3(("saSgpio: agContext %p\n", agContext));
2221285809Sscottl
2222285809Sscottl  /* Get request from free pool */
2223285809Sscottl  pRequest = saGetRequestFromFreePool(agRoot, agContext);
2224285809Sscottl  if (agNULL == pRequest)
2225285809Sscottl  {
2226285809Sscottl    SA_DBG1(("saSgpio, No request from free list\n" ));
2227285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6t");
2228285809Sscottl  }
2229285809Sscottl  else
2230285809Sscottl  {
2231285809Sscottl    /* Set payload to zeros */
2232285809Sscottl    si_memset(&payload, 0, sizeof(agsaSGpioCmd_t));
2233285809Sscottl
2234285809Sscottl    /* set tag */
2235285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSGpioCmd_t, tag), pRequest->HTag);
2236285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSGpioCmd_t, regIndexRegTypeFunctionFrameType),
2237285809Sscottl                        (pSGpioReq->smpFrameType |
2238285809Sscottl                        ((bit32)pSGpioReq->function << 8)  |
2239285809Sscottl                        ((bit32)pSGpioReq->registerType << 16) |
2240285809Sscottl                        ((bit32)pSGpioReq->registerIndex << 24)));
2241285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSGpioCmd_t, regCount), pSGpioReq->registerCount);
2242285809Sscottl
2243285809Sscottl    if (SA_SAS_SMP_WRITE_GPIO_REGISTER == pSGpioReq->function)
2244285809Sscottl    {
2245285809Sscottl      for (i = 0; i < pSGpioReq->registerCount; i++)
2246285809Sscottl      {
2247285809Sscottl        OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSGpioCmd_t, writeData) + (i * 4), pSGpioReq->readWriteData[i]);
2248285809Sscottl      }
2249285809Sscottl    }
2250285809Sscottl
2251285809Sscottl    /* Build IOMB command and send to SPC */
2252285809Sscottl    ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SGPIO, IOMB_SIZE64, queueNum);
2253285809Sscottl    if (AGSA_RC_SUCCESS != ret)
2254285809Sscottl    {
2255285809Sscottl      /* Return the request to free pool */
2256285809Sscottl      saReturnRequestToFreePool(agRoot, pRequest);
2257285809Sscottl      SA_DBG1(("saSgpio, sending IOMB failed\n" ));
2258285809Sscottl    }
2259285809Sscottl
2260285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6t");
2261285809Sscottl  }
2262285809Sscottl
2263285809Sscottl  return ret;
2264285809Sscottl}
2265285809Sscottl
2266285809Sscottl/******************************************************************************/
2267285809Sscottl/*! \brief for spc card read Error Registers to memory if error occur
2268285809Sscottl *
2269285809Sscottl *  This function is called to get erorr registers content to memory if error occur.
2270285809Sscottl *
2271285809Sscottl *  \param agRoot      handles for this instance of SAS/SATA hardware
2272285809Sscottl *
2273285809Sscottl *  \return
2274285809Sscottl */
2275285809Sscottl/*******************************************************************************/
2276285809SscottlLOCAL void siSpcGetErrorContent(
2277285809Sscottl                                agsaRoot_t *agRoot
2278285809Sscottl                               )
2279285809Sscottl{
2280285809Sscottl
2281285809Sscottl  agsaLLRoot_t          *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
2282285809Sscottl  bit32       value, value1;
2283285809Sscottl
2284285809Sscottl  value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1) & SCRATCH_PAD_STATE_MASK;
2285285809Sscottl  value1 = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_2, MSGU_SCRATCH_PAD_2) & SCRATCH_PAD_STATE_MASK;
2286285809Sscottl      /* check AAP error */
2287285809Sscottl  if ((SCRATCH_PAD1_ERR == value) || (SCRATCH_PAD2_ERR == value1))
2288285809Sscottl  {
2289285809Sscottl        /* fatal error */
2290285809Sscottl        /* get register dump from GSM and save it to LL local memory */
2291285809Sscottl      siGetRegisterDumpGSM(agRoot, (void *)&saRoot->registerDump0[0],
2292285809Sscottl           REG_DUMP_NUM0, 0, saRoot->mainConfigTable.FatalErrorDumpLength0);
2293285809Sscottl      siGetRegisterDumpGSM(agRoot, (void *)&saRoot->registerDump1[0],
2294285809Sscottl           REG_DUMP_NUM1, 0, saRoot->mainConfigTable.FatalErrorDumpLength1);
2295285809Sscottl  }
2296285809Sscottl}
2297285809Sscottl
2298285809Sscottl
2299285809Sscottl/******************************************************************************/
2300285809Sscottl/*! \brief for spcv card read Error Registers to memory if error occur
2301285809Sscottl *
2302285809Sscottl *  This function is called to get erorr registers content to memory if error occur.
2303285809Sscottl *
2304285809Sscottl *  \param agRoot      handles for this instance of SAS/SATA hardware
2305285809Sscottl *
2306285809Sscottl *  \return
2307285809Sscottl */
2308285809Sscottl/*******************************************************************************/
2309285809SscottlLOCAL void siSpcvGetErrorContent(
2310285809Sscottl                                 agsaRoot_t *agRoot
2311285809Sscottl                                 )
2312285809Sscottl{
2313285809Sscottl
2314285809Sscottl  agsaLLRoot_t          *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
2315285809Sscottl  bit32                 value;
2316285809Sscottl
2317285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"2d");
2318285809Sscottl  value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1);
2319285809Sscottl
2320285809Sscottl  if(((value & SPCV_RAAE_STATE_MASK) == SPCV_ERROR_VALUE) ||
2321285809Sscottl     ((value & SPCV_IOP0_STATE_MASK) == SPCV_ERROR_VALUE) ||
2322285809Sscottl     ((value & SPCV_IOP1_STATE_MASK) == SPCV_ERROR_VALUE)
2323285809Sscottl    )
2324285809Sscottl  {
2325285809Sscottl        /* fatal error */
2326285809Sscottl        /* get register dump from GSM and save it to LL local memory */
2327285809Sscottl    siGetRegisterDumpGSM(agRoot, (void *)&saRoot->registerDump0[0],
2328285809Sscottl       REG_DUMP_NUM0, 0, saRoot->mainConfigTable.FatalErrorDumpLength0);
2329285809Sscottl    siGetRegisterDumpGSM(agRoot, (void *)&saRoot->registerDump1[0],
2330285809Sscottl       REG_DUMP_NUM1, 0, saRoot->mainConfigTable.FatalErrorDumpLength1);
2331285809Sscottl  }
2332285809Sscottl  smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2d");
2333285809Sscottl}
2334285809Sscottl
2335285809Sscottl#define LEFT_BYTE_FAIL(x, v)   \
2336285809Sscottl     do {if( (x) < (v) ) return AGSA_RC_FAILURE; } while(0);
2337285809Sscottl
2338285809SscottlLOCAL bit32 siDumpInboundQueue(
2339285809Sscottl          void *  buffer,
2340285809Sscottl          bit32   length,
2341285809Sscottl          mpiICQueue_t  *q
2342285809Sscottl          )
2343285809Sscottl{
2344285809Sscottl  bit8  * _buf = buffer;
2345285809Sscottl  si_memcpy( _buf, (bit8*)(q->memoryRegion.virtPtr) + length, 128*256);
2346285809Sscottl  return AGSA_RC_SUCCESS;
2347285809Sscottl}
2348285809Sscottl
2349285809SscottlLOCAL bit32 siDumpOutboundQueue(
2350285809Sscottl          void *  buffer,
2351285809Sscottl          bit32   length,
2352285809Sscottl          mpiOCQueue_t  *q)
2353285809Sscottl{
2354285809Sscottl  bit8  * _buf   = buffer;
2355285809Sscottl  si_memcpy( _buf, (bit8*)(q->memoryRegion.virtPtr) + length, 128*256);
2356285809Sscottl  return AGSA_RC_SUCCESS;
2357285809Sscottl}
2358285809Sscottl
2359285809Sscottl
2360285809SscottlLOCAL bit32 siWaitForNonFatalTransfer( agsaRoot_t *agRoot,bit32 pcibar)
2361285809Sscottl{
2362285809Sscottl  bit32 status = AGSA_RC_SUCCESS;
2363285809Sscottl  bit32 ready;
2364285809Sscottl  bit32 max_wait_time;
2365285809Sscottl  bit32 max_wait_count;
2366285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"2c");
2367285809Sscottl
2368285809Sscottl  SA_DBG4(("siWaitForNonFatalTransfer:0 IBDBS 0x%x\n",ossaHwRegReadExt(agRoot,0 ,V_Inbound_Doorbell_Set_Register ) ));
2369285809Sscottl  /* Write FDDHSHK  */
2370285809Sscottl
2371285809Sscottl
2372285809Sscottl  /* Write bit7 of inbound doorbell set register  step 3 */
2373285809Sscottl  ossaHwRegWriteExt(agRoot, 0,V_Inbound_Doorbell_Set_Register, SPCV_MSGU_CFG_TABLE_TRANSFER_DEBUG_INFO );
2374285809Sscottl  SA_DBG4(("siWaitForNonFatalTransfer:1 IBDBS 0x%x\n",ossaHwRegReadExt(agRoot,0 ,V_Inbound_Doorbell_Set_Register ) ));
2375285809Sscottl
2376285809Sscottl  /* Poll bit7 of inbound doorbell set register until clear step 4 */
2377285809Sscottl  max_wait_time = (2000 * 1000); /* wait 2 seconds */
2378285809Sscottl  max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT) - WAIT_INCREMENT;
2379285809Sscottl  do
2380285809Sscottl  {
2381285809Sscottl    ossaStallThread(agRoot, WAIT_INCREMENT);
2382285809Sscottl    ready = ossaHwRegReadExt(agRoot,0 ,V_Inbound_Doorbell_Set_Register );
2383285809Sscottl  } while ( (ready & SPCV_MSGU_CFG_TABLE_TRANSFER_DEBUG_INFO)  && (max_wait_count -= WAIT_INCREMENT));
2384285809Sscottl  if(max_wait_count == 0)
2385285809Sscottl  {
2386285809Sscottl    SA_DBG1(("siWaitForNonFatalTransfer:Timeout IBDBS 0x%x\n",ossaHwRegReadExt(agRoot,0 ,V_Inbound_Doorbell_Set_Register ) ));
2387285809Sscottl    status = AGSA_RC_FAILURE;
2388285809Sscottl  }
2389285809Sscottl
2390285809Sscottl  SA_DBG4(("siWaitForNonFatalTransfer:3 IBDBS 0x%x\n",ossaHwRegReadExt(agRoot,0 ,V_Inbound_Doorbell_Set_Register ) ));
2391285809Sscottl
2392285809Sscottl  smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2c");
2393285809Sscottl  return(status);
2394285809Sscottl}
2395285809Sscottl
2396285809SscottlLOCAL bit32 siWaitForFatalTransfer( agsaRoot_t *agRoot,bit32 pcibar)
2397285809Sscottl{
2398285809Sscottl  bit32 status = AGSA_RC_SUCCESS;
2399285809Sscottl  bit32 ready;
2400285809Sscottl  bit32 ErrorTableOffset;
2401285809Sscottl  bit32 max_wait_time;
2402285809Sscottl  bit32 max_wait_count;
2403285809Sscottl
2404285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"2o");
2405285809Sscottl
2406285809Sscottl  ErrorTableOffset = siGetTableOffset( agRoot, MAIN_MERRDCTO_MERRDCES );
2407285809Sscottl
2408285809Sscottl  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 )));
2409285809Sscottl  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)));
2410285809Sscottl  /*
2411285809Sscottl  2. Write 0x1 to the Fatal Error Debug Dump Handshake control [FDDHSHK] field in Table 73 and
2412285809Sscottl  read back the same field (by polling) until it is 0. This prompts the debug agent to copy the next
2413285809Sscottl  part of the debug data into GSM shared memory. To check the completion of the copy process, the
2414285809Sscottl  host must poll the Fatal/Non Fatal Debug Data Transfer Status [FDDTSTAT] field in the Table
2415285809Sscottl  Table 73.
2416285809Sscottl  */
2417285809Sscottl
2418285809Sscottl  /* Write FDDHSHK  */
2419285809Sscottl  ossaHwRegWriteExt(agRoot,pcibar ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_HANDSHAKE, MPI_FATAL_EDUMP_HANDSHAKE_RDY );
2420285809Sscottl  SA_DBG4(("siWaitForFatalTransfer:1 MPI_FATAL_EDUMP_TABLE_HANDSHAKE 0x%x\n",ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_HANDSHAKE ) ));
2421285809Sscottl
2422285809Sscottl  /* Poll FDDHSHK  until clear  */
2423285809Sscottl  max_wait_time = (2000 * 1000); /* wait 2 seconds */
2424285809Sscottl  max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT) - WAIT_INCREMENT;
2425285809Sscottl  do
2426285809Sscottl  {
2427285809Sscottl    ossaStallThread(agRoot, WAIT_INCREMENT);
2428285809Sscottl    ready = ossaHwRegReadExt(agRoot,0 ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_HANDSHAKE );
2429285809Sscottl  } while (ready   && (max_wait_count -= WAIT_INCREMENT));
2430285809Sscottl  if(max_wait_count == 0)
2431285809Sscottl  {
2432285809Sscottl    SA_DBG1(("siWaitForFatalTransfer : 1 Timeout\n"));
2433285809Sscottl    status = AGSA_RC_FAILURE;
2434285809Sscottl  }
2435285809Sscottl
2436285809Sscottl  smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2o");
2437285809Sscottl  return(status);
2438285809Sscottl}
2439285809Sscottl
2440285809Sscottl
2441285809Sscottl
2442285809SscottlLOCAL bit32 siFatalErrorBuffer(
2443285809Sscottl                  agsaRoot_t *agRoot,
2444285809Sscottl                  agsaForensicData_t *forensicData
2445285809Sscottl                  )
2446285809Sscottl{
2447285809Sscottl  bit32 status = AGSA_RC_FAILURE;
2448285809Sscottl  bit32 pcibar;
2449285809Sscottl  bit32 ErrorTableOffset;
2450285809Sscottl  bit32 Accum_len = 0;
2451285809Sscottl
2452285809Sscottl  agsaLLRoot_t      *saRoot;
2453285809Sscottl  /* sanity check */
2454285809Sscottl  SA_ASSERT( (agNULL != agRoot), "");
2455285809Sscottl  saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
2456285809Sscottl  SA_ASSERT( (agNULL != saRoot), "saRoot");
2457285809Sscottl  if(agNULL == saRoot )
2458285809Sscottl  {
2459285809Sscottl    SA_DBG1(("siFatalErrorBuffer: agNULL  saRoot\n"));
2460285809Sscottl    return(status);
2461285809Sscottl  }
2462285809Sscottl
2463285809Sscottl  if(saRoot->ResetFailed )
2464285809Sscottl  {
2465285809Sscottl    SA_DBG1(("siFatalErrorBuffer: saRoot->ResetFailed\n"));
2466285809Sscottl    return(status);
2467285809Sscottl  }
2468285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"2a");
2469285809Sscottl  SA_DBG2(("siFatalErrorBuffer:In %p Offset 0x%08x Len 0x%08x Totel len 0x%x\n",
2470285809Sscottl                        forensicData->BufferType.dataBuf.directData,
2471285809Sscottl                        forensicData->BufferType.dataBuf.directOffset,
2472285809Sscottl                        forensicData->BufferType.dataBuf.directLen,
2473285809Sscottl			forensicData->BufferType.dataBuf.readLen ));
2474285809Sscottl
2475285809Sscottl  pcibar = siGetPciBar(agRoot);
2476285809Sscottl  ErrorTableOffset = siGetTableOffset( agRoot, MAIN_MERRDCTO_MERRDCES );
2477285809Sscottl
2478285809Sscottl  SA_DBG3(("siFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_STATUS  0x%x LEN 0x%x\n",
2479285809Sscottl      ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_STATUS),
2480285809Sscottl      ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN) ));
2481285809Sscottl
2482285809Sscottl  /*
2483285809Sscottl  This section describes sequence for the host to capture debug data under fatal error conditions.
2484285809Sscottl  A fatal error is an error condition that stops the SPCv controller from normal operation and causes it
2485285809Sscottl  to be unresponsive to host requests. Since the firmware is non-operational, the host needs to pull the
2486285809Sscottl  debug dump information using PCIe MEMBASE II with the assistance of the debug agent which becomes
2487285809Sscottl  active when the main controller firmware fails.
2488285809Sscottl  */
2489285809Sscottl  /*
2490285809Sscottl  To capture the fatal error debug data, the host must:
2491285809Sscottl  1. Upon detecting the fatal error condition through a fatal error interrupt or by the MSGU scratchpad
2492285809Sscottl  registers, capture the first part of the fatal error debug data. Upon fatal error, the first part of the
2493285809Sscottl  debug data is located GSM shared memory and its length is updated in the Accumulative Debug
2494285809Sscottl  Data Length Transferred [ACCDDLEN] field in Table Table 82. To capture the first part:
2495285809Sscottl  */
2496285809Sscottl  if(forensicData->BufferType.dataBuf.directOffset == 0)
2497285809Sscottl  {
2498285809Sscottl    /* start to get data */
2499285809Sscottl    /*
2500285809Sscottl    a. Program the MEMBASE II Shifting Register with 0x00.
2501285809Sscottl    */
2502285809Sscottl    ossaHwRegWriteExt(agRoot, pcibar,V_MEMBASE_II_ShiftRegister, saRoot->FatalForensicShiftOffset); // set base to zero
2503285809Sscottl
2504285809Sscottl    saRoot->ForensicLastOffset =0;
2505285809Sscottl    saRoot->FatalForensicStep = 0;
2506285809Sscottl    saRoot->FatalBarLoc = 0;
2507285809Sscottl    saRoot->FatalForensicShiftOffset = 0;
2508285809Sscottl
2509285809Sscottl    SA_DBG1(("siFatalErrorBuffer: directOffset zero SCRATCH_PAD1 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1) ));
2510285809Sscottl  }
2511285809Sscottl
2512285809Sscottl  /* Read until Accum_len is retrived */
2513285809Sscottl  Accum_len = ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN);
2514285809Sscottl
2515285809Sscottl  SA_DBG2(("siFatalErrorBuffer: Accum_len 0x%x\n", Accum_len));
2516285809Sscottl  if(Accum_len == 0xFFFFFFFF)
2517285809Sscottl  {
2518285809Sscottl    SA_DBG1(("siFatalErrorBuffer: Possible PCI issue 0x%x not expected\n", Accum_len));
2519285809Sscottl    return(status);
2520285809Sscottl  }
2521285809Sscottl
2522285809Sscottl  if( Accum_len == 0 || Accum_len >=0x100000 )
2523285809Sscottl  {
2524285809Sscottl    SA_DBG1(("siFatalErrorBuffer: Accum_len == saRoot->FatalCurrentLength 0x%x\n", Accum_len));
2525285809Sscottl    return(IOCTL_ERROR_NO_FATAL_ERROR);
2526285809Sscottl  }
2527285809Sscottl
2528285809Sscottl  if(saRoot->FatalForensicStep == 0) /* PM Step 1a and 1b */
2529285809Sscottl  {
2530285809Sscottl    moreData:
2531285809Sscottl	  if(forensicData->BufferType.dataBuf.directData)
2532285809Sscottl	  {
2533285809Sscottl      		  siPciCpyMem(agRoot,saRoot->FatalBarLoc ,forensicData->BufferType.dataBuf.directData,forensicData->BufferType.dataBuf.directLen ,1 );
2534285809Sscottl	  }
2535285809Sscottl	  saRoot->FatalBarLoc += forensicData->BufferType.dataBuf.directLen;
2536285809Sscottl	  forensicData->BufferType.dataBuf.directOffset += forensicData->BufferType.dataBuf.directLen;
2537285809Sscottl	  saRoot->ForensicLastOffset  += forensicData->BufferType.dataBuf.directLen;
2538285809Sscottl	  forensicData->BufferType.dataBuf.readLen = forensicData->BufferType.dataBuf.directLen;
2539285809Sscottl
2540285809Sscottl	  if(saRoot->ForensicLastOffset  >= Accum_len)
2541285809Sscottl    {
2542285809Sscottl      /*
2543285809Sscottl      e. Repeat the above 2 steps until all debug data is retrieved as specified in the Accumulative Debug
2544285809Sscottl      Data Length Transferred [ACCDDLEN] field.
2545285809Sscottl      NOTE: The ACCDDLEN field is cumulative so the host needs to take the difference from the
2546285809Sscottl      previous step.
2547285809Sscottl      */
2548285809Sscottl      /* This section data ends get next section */
2549285809Sscottl      SA_DBG1(("siFatalErrorBuffer: Accum_len reached 0x%x directOffset 0x%x\n",Accum_len,forensicData->BufferType.dataBuf.directOffset ));
2550285809Sscottl      saRoot->FatalBarLoc = 0;
2551285809Sscottl      saRoot->FatalForensicStep = 1;
2552285809Sscottl      saRoot->FatalForensicShiftOffset = 0;
2553285809Sscottl		  status = AGSA_RC_COMPLETE;
2554285809Sscottl		  return status;
2555285809Sscottl    }
2556285809Sscottl    if(saRoot->FatalBarLoc < (64*1024))
2557285809Sscottl    {
2558285809Sscottl      SA_DBG2(("siFatalErrorBuffer: In same 64k FatalBarLoc 0x%x\n",saRoot->FatalBarLoc ));
2559285809Sscottl      status = AGSA_RC_SUCCESS;
2560285809Sscottl		  return status;
2561285809Sscottl    }
2562285809Sscottl    /*
2563285809Sscottl    c. Increment the MEMBASE II Shifting Register value by 0x100.
2564285809Sscottl    */
2565285809Sscottl    saRoot->FatalForensicShiftOffset+= 0x100;
2566285809Sscottl    	  ossaHwRegWriteExt(agRoot, pcibar,V_MEMBASE_II_ShiftRegister, saRoot->FatalForensicShiftOffset);
2567285809Sscottl    saRoot->FatalBarLoc = 0;
2568285809Sscottl
2569285809Sscottl	  SA_DBG1(("siFatalErrorBuffer: Get next bar data 0x%x\n",saRoot->FatalForensicShiftOffset));
2570285809Sscottl
2571285809Sscottl    status = AGSA_RC_SUCCESS;
2572285809Sscottl
2573285809Sscottl	  SA_DBG1(("siFatalErrorBuffer:Offset 0x%x BarLoc 0x%x\n",saRoot->FatalForensicShiftOffset,saRoot->FatalBarLoc  ));
2574285809Sscottl	  SA_DBG1(("siFatalErrorBuffer: step 0 status %d %p Offset 0x%x Len 0x%x total_len 0x%x\n",
2575285809Sscottl                        status,
2576285809Sscottl                        forensicData->BufferType.dataBuf.directData,
2577285809Sscottl				  forensicData->BufferType.dataBuf.directOffset,
2578285809Sscottl                        forensicData->BufferType.dataBuf.directLen,
2579285809Sscottl				  forensicData->BufferType.dataBuf.readLen ));
2580285809Sscottl	  return(status);
2581285809Sscottl  }
2582285809Sscottl
2583285809Sscottl  if(saRoot->FatalForensicStep == 1)
2584285809Sscottl  {
2585285809Sscottl
2586285809Sscottl    /*
2587285809Sscottl    3. If Fatal/Non Fatal Debug Data Transfer Status [FDDTSTAT] field indicates status value of
2588285809Sscottl    0x00000002 or 0x00000003, read the next part of the fatal debug data by taking the difference
2589285809Sscottl    between the preserved ACCDDLEN value from step 2 and the new ACCDDLEN value.To capture
2590285809Sscottl    the second part:
2591285809Sscottl    a. Program the MEMBASE II Shifting Register with 0x00.
2592285809Sscottl    */
2593285809Sscottl    SA_DBG1(("siFatalErrorBuffer: FatalForensicStep 1 Accum_len 0x%X MPI_FATAL_EDUMP_TABLE_ACCUM_LEN 0x%x\n",
2594285809Sscottl                Accum_len,
2595285809Sscottl                ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN)));
2596285809Sscottl
2597285809Sscottl    saRoot->FatalForensicShiftOffset = 0; /* location in 64k region */
2598285809Sscottl    /*
2599285809Sscottl    b. Read 64K of the debug data.
2600285809Sscottl    */
2601285809Sscottl    ossaHwRegWriteExt(agRoot, pcibar,V_MEMBASE_II_ShiftRegister  ,saRoot->FatalForensicShiftOffset);
2602285809Sscottl    SA_DBG1(("siFatalErrorBuffer: FatalForensicStep 1\n" ));
2603285809Sscottl    /*
2604285809Sscottl    2.Write 0x1 to the Fatal Error Debug Dump Handshake control [FDDHSHK]
2605285809Sscottl    field inTable 82 and read back the same field (by polling for 2 seconds) until it is 0. This prompts
2606285809Sscottl    the debug agent to copy the next part of the debug data into GSM shared memory. To check the
2607285809Sscottl    completion of the copy process, the host must poll the Fatal/Non Fatal Debug Data Transfer Status
2608285809Sscottl    [FDDTSTAT] field for 2 secondsin the MPI Fatal and Non-Fatal Error Dump Capture Table Table 82.
2609285809Sscottl    */
2610285809Sscottl    siWaitForFatalTransfer( agRoot,pcibar);
2611285809Sscottl
2612285809Sscottl    /*
2613285809Sscottl    d. Read the next 64K of the debug data.
2614285809Sscottl    */
2615285809Sscottl    saRoot->FatalForensicStep = 0;
2616285809Sscottl
2617285809Sscottl    if( ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_STATUS) != MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE )
2618285809Sscottl    {
2619285809Sscottl
2620285809Sscottl      SA_DBG3(("siFatalErrorBuffer:Step 3\n" ));
2621285809Sscottl      SA_DBG3(("siFatalErrorBuffer:Step 3 MPI_FATAL_EDUMP_TABLE_STATUS 0x%x\n", ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_STATUS )));
2622285809Sscottl      /*
2623285809Sscottl      2. Write FDDSTAT to 0x00000000 but preserve the Accumulative Debug Data Length Transferred
2624285809Sscottl      [ACCDDLEN] field.
2625285809Sscottl      */
2626285809Sscottl      ossaHwRegWriteExt(agRoot,pcibar ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_STATUS, 0 );
2627285809Sscottl      /*
2628285809Sscottl      4. If FDDSTAT is 0x00000002, repeat steps 2 and 3 until you reach this step with FDDSTAT being
2629285809Sscottl      equal to 0x00000003.
2630285809Sscottl      */
2631285809Sscottl      goto moreData;
2632285809Sscottl    }
2633285809Sscottl    else
2634285809Sscottl    {
2635285809Sscottl      /*
2636285809Sscottl         When FDDSTAT equals 0x00000003 and ACCDDLEN is unchanged, then
2637285809Sscottl      */
2638285809Sscottl      /*
2639285809Sscottl      the fatal error dump is complete. If ACCDDLEN increases, one more read step is required.
2640285809Sscottl      The content and format of the debug data is opaque to the host and must be forwarded to PMC-Sierra
2641285809Sscottl      Applications support for failure analysis. Debug data is retrieved in several iterations which enables
2642285809Sscottl      the host to use a smaller buffer and store the captured debug data in secondary storage during the process.
2643285809Sscottl      */
2644285809Sscottl
2645285809Sscottl      SA_DBG3(("siFatalErrorBuffer:Step 4\n" ));
2646285809Sscottl      SA_DBG1(("siFatalErrorBuffer:  Done  Read 0x%x accum 0x%x\n",
2647285809Sscottl                forensicData->BufferType.dataBuf.directOffset,
2648285809Sscottl                ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN)));
2649285809Sscottl
2650285809Sscottl#if defined(SALLSDK_DEBUG)
2651285809Sscottl      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) )));
2652285809Sscottl      SA_DBG1(("siFatalErrorBuffer: SCRATCH_PAD0 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0,  MSGU_SCRATCH_PAD_0)));
2653285809Sscottl      SA_DBG1(("siFatalErrorBuffer: SCRATCH_PAD1 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1,  MSGU_SCRATCH_PAD_1)));
2654285809Sscottl      SA_DBG1(("siFatalErrorBuffer: SCRATCH_PAD2 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_2,  MSGU_SCRATCH_PAD_2)));
2655285809Sscottl      SA_DBG1(("siFatalErrorBuffer: SCRATCH_PAD3 value = 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_3,  MSGU_SCRATCH_PAD_3)));
2656285809Sscottl#endif
2657285809Sscottl      forensicData->BufferType.dataBuf.readLen = 0xFFFFFFFF;
2658285809Sscottl      status = AGSA_RC_SUCCESS;
2659285809Sscottl
2660285809Sscottl    }
2661285809Sscottl  }
2662285809Sscottl
2663285809Sscottl
2664285809Sscottl  SA_DBG3(("siFatalErrorBuffer:status 0x%x %p directOffset 0x%x directLen 0x%x readLen 0x%x\n",
2665285809Sscottl                        status,
2666285809Sscottl                        forensicData->BufferType.dataBuf.directData,
2667285809Sscottl                        forensicData->BufferType.dataBuf.directOffset,
2668285809Sscottl                        forensicData->BufferType.dataBuf.directLen,
2669285809Sscottl                        forensicData->BufferType.dataBuf.readLen ));
2670285809Sscottl
2671285809Sscottl      smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2a");
2672285809Sscottl  return(status);
2673285809Sscottl}
2674285809Sscottl
2675285809SscottlLOCAL bit32 siNonFatalErrorBuffer(
2676285809Sscottl              agsaRoot_t *agRoot,
2677285809Sscottl              agsaForensicData_t *forensicData
2678285809Sscottl              )
2679285809Sscottl{
2680285809Sscottl  bit32 status = AGSA_RC_FAILURE;
2681285809Sscottl  bit32 pcibar;
2682285809Sscottl  bit32 ErrorTableOffset;
2683285809Sscottl
2684285809Sscottl  //bit32 i;
2685285809Sscottl  bit32 ready;
2686285809Sscottl  bit32 biggest;
2687285809Sscottl  bit32 max_wait_time;
2688285809Sscottl  bit32 max_wait_count;
2689285809Sscottl  agsaLLRoot_t      *saRoot;
2690285809Sscottl  /* sanity check */
2691285809Sscottl  SA_ASSERT( (agNULL != agRoot), "agRoot");
2692285809Sscottl  saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
2693285809Sscottl  SA_ASSERT( (agNULL != saRoot), "saRoot");
2694285809Sscottl  if(agNULL == saRoot )
2695285809Sscottl  {
2696285809Sscottl    SA_DBG1(("siNonFatalErrorBuffer: agNULL  saRoot\n"));
2697285809Sscottl    return(status);
2698285809Sscottl  }
2699285809Sscottl
2700285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"2b");
2701285809Sscottl  pcibar = siGetPciBar(agRoot);
2702285809Sscottl  ErrorTableOffset = siGetTableOffset( agRoot, MAIN_MERRDCTO_MERRDCES );
2703285809Sscottl
2704285809Sscottl  SA_DBG4(("siNonFatalErrorBuffer: ErrorTableOffset 0x%x\n",ErrorTableOffset ));
2705285809Sscottl
2706285809Sscottl  SA_DBG4(("siNonFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_STATUS Offset 0x%x   0x%x\n",
2707285809Sscottl            ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS,
2708285809Sscottl            ossaHwRegReadExt(agRoot,pcibar,ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS)));
2709285809Sscottl  SA_DBG4(("siNonFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_ACCUM_LEN Offset 0x%x   0x%x\n",
2710285809Sscottl            ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN,
2711285809Sscottl            ossaHwRegReadExt(agRoot,pcibar,ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN)));
2712285809Sscottl
2713285809Sscottl  biggest = saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].totalLength;
2714285809Sscottl
2715285809Sscottl  if(biggest >= forensicData->BufferType.dataBuf.directLen )
2716285809Sscottl  {
2717285809Sscottl    biggest = forensicData->BufferType.dataBuf.directLen;
2718285809Sscottl  }
2719285809Sscottl  else
2720285809Sscottl  {
2721285809Sscottl    SA_DBG1(("siNonFatalErrorBuffer: directLen larger than DMA Buffer 0x%x < 0x%x\n",
2722285809Sscottl              biggest, forensicData->BufferType.dataBuf.directLen));
2723285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2b");
2724285809Sscottl    return(AGSA_RC_FAILURE);
2725285809Sscottl  }
2726285809Sscottl
2727285809Sscottl  if(saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].virtPtr)
2728285809Sscottl  {
2729285809Sscottl    si_memset(saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].virtPtr, 0, biggest);
2730285809Sscottl  }
2731285809Sscottl  else
2732285809Sscottl  {
2733285809Sscottl    SA_DBG1(("siNonFatalErrorBuffer: Error\n" ));
2734285809Sscottl    return(AGSA_RC_FAILURE);
2735285809Sscottl  }
2736285809Sscottl
2737285809Sscottl
2738285809Sscottl  if(forensicData->BufferType.dataBuf.directOffset)
2739285809Sscottl  {
2740285809Sscottl    /* Write FDDSTAT and ACCDDLEN to zero step 2 */
2741285809Sscottl    ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS, 0);
2742285809Sscottl    goto skip_setup;
2743285809Sscottl  }
2744285809Sscottl
2745285809Sscottl  SA_DBG1(("siNonFatalErrorBuffer: %p Offset 0x%x Len 0x%x total_len 0x%x\n",
2746285809Sscottl                        forensicData->BufferType.dataBuf.directData,
2747285809Sscottl                        forensicData->BufferType.dataBuf.directOffset,
2748285809Sscottl                        forensicData->BufferType.dataBuf.directLen,
2749285809Sscottl                        forensicData->BufferType.dataBuf.readLen ));
2750285809Sscottl
2751285809Sscottl  SA_DBG1(("siNonFatalErrorBuffer: directOffset zero setup\n" ));
2752285809Sscottl  SA_DBG1(("siNonFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_STATUS  0x%x LEN 0x%x\n",
2753285809Sscottl      ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_STATUS),
2754285809Sscottl      ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN) ));
2755285809Sscottl
2756285809Sscottl  SA_DBG1(("siNonFatalErrorBuffer: Clear V_Scratchpad_Rsvd_0_Register 0x%x\n",
2757285809Sscottl          ossaHwRegReadExt(agRoot, 0,V_Scratchpad_Rsvd_0_Register) ));
2758285809Sscottl  ossaHwRegWriteExt(agRoot, 0,V_Scratchpad_Rsvd_0_Register ,0);
2759285809Sscottl
2760285809Sscottl  saRoot->ForensicLastOffset = 0;
2761285809Sscottl
2762285809Sscottl  /* WriteACCDDLEN  for error interface Step 0 */
2763285809Sscottl  /*ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN ,0);*/
2764285809Sscottl
2765285809Sscottl  /* Write DMA get Offset for error interface Step 1 */
2766285809Sscottl  ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_LO_OFFSET, saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].phyAddrLower);
2767285809Sscottl  ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_HI_OFFSET, saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].phyAddrUpper);
2768285809Sscottl  ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_LENGTH, biggest);
2769285809Sscottl
2770285809Sscottl  /* Write FDDSTAT and ACCDDLEN to zero step 2 */
2771285809Sscottl  ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS, 0);
2772285809Sscottl  ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN, 0);
2773285809Sscottl
2774285809Sscottl  SA_DBG4(("siNonFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_STATUS Offset 0x%x   0x%x\n",
2775285809Sscottl           ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS,
2776285809Sscottl           ossaHwRegReadExt(agRoot,pcibar,ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS )));
2777285809Sscottl  SA_DBG4(("siNonFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_ACCUM_LEN Offset 0x%x   0x%x\n",
2778285809Sscottl           ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN,
2779285809Sscottl           ossaHwRegReadExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN)));
2780285809Sscottl
2781285809Sscottl  if( 0 != ossaHwRegReadExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN))
2782285809Sscottl  {
2783285809Sscottl    SA_DBG1(("siNonFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_ACCUM_LEN  0x%x   0x%x\n",
2784285809Sscottl             forensicData->BufferType.dataBuf.directOffset,
2785285809Sscottl             ossaHwRegReadExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN)));
2786285809Sscottl  }
2787285809Sscottl  skip_setup:
2788285809Sscottl
2789285809Sscottl  if( saRoot->ForensicLastOffset == 0xFFFFFFFF)
2790285809Sscottl  {
2791285809Sscottl    forensicData->BufferType.dataBuf.readLen = 0xFFFFFFFF;
2792285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2b");
2793285809Sscottl    return(AGSA_RC_SUCCESS);
2794285809Sscottl  }
2795285809Sscottl
2796285809Sscottl
2797285809Sscottl  /* Write bit7 of inbound doorbell set register and wait for complete step 3 and 4*/
2798285809Sscottl  siWaitForNonFatalTransfer(agRoot,pcibar);
2799285809Sscottl
2800285809Sscottl  SA_DBG3(("siNonFatalErrorBuffer: MPI_FATAL_EDUMP_TABLE_STATUS  0x%x LEN 0x%x\n",
2801285809Sscottl      ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_STATUS),
2802285809Sscottl      ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN) ));
2803285809Sscottl
2804285809Sscottl
2805285809Sscottl
2806285809Sscottl  max_wait_time = (2000 * 1000); /* wait 2 seconds */
2807285809Sscottl  max_wait_count = MAKE_MODULO(max_wait_time,WAIT_INCREMENT) - WAIT_INCREMENT;
2808285809Sscottl  ready = ossaHwRegReadExt(agRoot,pcibar,ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS );
2809285809Sscottl  do
2810285809Sscottl  {
2811285809Sscottl    ossaStallThread(agRoot, WAIT_INCREMENT);
2812285809Sscottl    ready =  ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS );
2813285809Sscottl    forensicData->BufferType.dataBuf.directOffset = ossaHwRegReadExt(agRoot,pcibar,ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN);
2814285809Sscottl    if( ready == MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_MORE_DATA )
2815285809Sscottl    {
2816285809Sscottl      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) ));
2817285809Sscottl      break;
2818285809Sscottl    }
2819285809Sscottl  } while ( ready != MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE && (max_wait_count -= WAIT_INCREMENT));
2820285809Sscottl
2821285809Sscottl
2822285809Sscottl  if(max_wait_count == 0 || ready == MPI_FATAL_EDUMP_TABLE_STAT_DMA_FAILED)
2823285809Sscottl  {
2824285809Sscottl    status = AGSA_RC_FAILURE;
2825285809Sscottl    SA_DBG1(("siNonFatalErrorBuffer: timeout waiting ready\n"));
2826285809Sscottl  }
2827285809Sscottl  else
2828285809Sscottl  {
2829285809Sscottl    forensicData->BufferType.dataBuf.readLen = forensicData->BufferType.dataBuf.directOffset - saRoot->ForensicLastOffset;
2830285809Sscottl    if( ready == MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE && forensicData->BufferType.dataBuf.readLen == 0)
2831285809Sscottl    {
2832285809Sscottl      SA_DBG1(("siNonFatalErrorBuffer:ready 0x%x readLen 0x%x\n",ready ,forensicData->BufferType.dataBuf.readLen));
2833285809Sscottl      saRoot->ForensicLastOffset = 0xFFFFFFFF;
2834285809Sscottl    }
2835285809Sscottl    else
2836285809Sscottl    {
2837285809Sscottl      saRoot->ForensicLastOffset = forensicData->BufferType.dataBuf.directOffset;
2838285809Sscottl    }
2839285809Sscottl
2840285809Sscottl    if(forensicData->BufferType.dataBuf.directData )
2841285809Sscottl    {
2842285809Sscottl      si_memcpy(forensicData->BufferType.dataBuf.directData, saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].virtPtr,biggest);
2843285809Sscottl    }
2844285809Sscottl    status = AGSA_RC_SUCCESS;
2845285809Sscottl  }
2846285809Sscottl  /* step 5 */
2847285809Sscottl  SA_DBG3(("siNonFatalErrorBuffer: %p directOffset 0x%x directLen 0x%x readLen 0x%x\n",
2848285809Sscottl                        forensicData->BufferType.dataBuf.directData,
2849285809Sscottl                        forensicData->BufferType.dataBuf.directOffset,
2850285809Sscottl                        forensicData->BufferType.dataBuf.directLen,
2851285809Sscottl                        forensicData->BufferType.dataBuf.readLen ));
2852285809Sscottl  smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2b");
2853285809Sscottl  return(status);
2854285809Sscottl}
2855285809Sscottl
2856285809Sscottl
2857285809SscottlLOCAL bit32 siGetForensicData(
2858285809Sscottl    agsaRoot_t         *agRoot,
2859285809Sscottl    agsaContext_t      *agContext,
2860285809Sscottl    agsaForensicData_t *forensicData
2861285809Sscottl    )
2862285809Sscottl{
2863285809Sscottl  bit32 status = AGSA_RC_FAILURE;
2864285809Sscottl	agsaLLRoot_t        *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
2865285809Sscottl
2866285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"2Z");
2867285809Sscottl
2868285809Sscottl  if(forensicData->DataType == TYPE_GSM_SPACE)
2869285809Sscottl	{
2870285809Sscottl#define _1M 0x100000
2871285809Sscottl		if( forensicData->BufferType.gsmBuf.directLen >= _1M )
2872285809Sscottl  {
2873285809Sscottl			return AGSA_RC_FAILURE;
2874285809Sscottl		}
2875285809Sscottl
2876285809Sscottl		if(forensicData->BufferType.dataBuf.readLen)
2877285809Sscottl    {
2878285809Sscottl			SA_DBG1(("siGetForensicData: Incorrect readLen 0x%08X\n", forensicData->BufferType.dataBuf.readLen));
2879285809Sscottl			forensicData->BufferType.dataBuf.readLen = forensicData->BufferType.dataBuf.directLen;
2880285809Sscottl		}
2881285809Sscottl		if( forensicData->BufferType.dataBuf.directOffset >= ONE_MEGABYTE )
2882285809Sscottl		{
2883285809Sscottl			SA_DBG1(("siGSMDump:	total length > ONE_MEGABYTE  0x%x\n",forensicData->BufferType.dataBuf.directOffset));
2884285809Sscottl			forensicData->BufferType.dataBuf.readLen = 0xFFFFFFFF;
2885285809Sscottl			return(AGSA_RC_SUCCESS);
2886285809Sscottl    }
2887285809Sscottl		if(smIS_SPC(agRoot))
2888285809Sscottl		{
2889285809Sscottl    if( forensicData->BufferType.dataBuf.directLen >= SIXTYFOURKBYTE )
2890285809Sscottl    {
2891285809Sscottl      SA_DBG1(("siGetForensicData directLen too large !\n"));
2892285809Sscottl      return AGSA_RC_FAILURE;
2893285809Sscottl    }
2894285809Sscottl    SA_DBG1(("siGetForensicData: TYPE_GSM_SPACE directLen 0x%X directOffset 0x%08X %p\n",
2895285809Sscottl                  forensicData->BufferType.dataBuf.directLen,
2896285809Sscottl                  forensicData->BufferType.dataBuf.directOffset,
2897285809Sscottl                  forensicData->BufferType.dataBuf.directData ));
2898285809Sscottl
2899285809Sscottl
2900285809Sscottl    /* Shift BAR4 original address */
2901285809Sscottl    if (AGSA_RC_FAILURE == siBar4Shift(agRoot, BAR_SHIFT_GSM_OFFSET + forensicData->BufferType.dataBuf.directOffset))
2902285809Sscottl    {
2903285809Sscottl      SA_DBG1(("siGSMDump:Shift Bar4 to 0x%x failed\n", 0x0));
2904285809Sscottl      return AGSA_RC_FAILURE;
2905285809Sscottl    }
2906285809Sscottl
2907285809Sscottl
2908285809Sscottl			//if( forensicData->BufferType.dataBuf.directOffset >= ONE_MEGABYTE )
2909285809Sscottl			//{
2910285809Sscottl			//SA_DBG1(("siGSMDump:  total length > ONE_MEGABYTE  0x%x\n",forensicData->BufferType.dataBuf.directOffset));
2911285809Sscottl			//forensicData->BufferType.dataBuf.readLen = 0xFFFFFFFF;
2912285809Sscottl			//return(AGSA_RC_SUCCESS);
2913285809Sscottl			//}
2914285809Sscottl			forensicData->BufferType.gsmBuf.directOffset = 0;
2915285809Sscottl    }
2916285809Sscottl    status = siGSMDump( agRoot,
2917285809Sscottl				forensicData->BufferType.gsmBuf.directOffset,
2918285809Sscottl				forensicData->BufferType.gsmBuf.directLen,
2919285809Sscottl				forensicData->BufferType.gsmBuf.directData );
2920285809Sscottl
2921285809Sscottl    if(status == AGSA_RC_SUCCESS)
2922285809Sscottl    {
2923285809Sscottl      forensicData->BufferType.dataBuf.readLen = forensicData->BufferType.dataBuf.directLen;
2924285809Sscottl    }
2925285809Sscottl
2926285809Sscottl    if( forensicData->BufferType.dataBuf.directOffset == 0 )
2927285809Sscottl    {
2928285809Sscottl      SA_DBG1(("siGetForensicData: TYPE_GSM_SPACE readLen 0x%08X\n", forensicData->BufferType.dataBuf.readLen));
2929285809Sscottl    }
2930285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2Z");
2931285809Sscottl
2932285809Sscottl    return status;
2933285809Sscottl  }
2934285809Sscottl	else if(forensicData->DataType == TYPE_INBOUND_QUEUE )
2935285809Sscottl  {
2936285809Sscottl      mpiICQueue_t        *circularQ = NULL;
2937285809Sscottl		SA_DBG2(("siGetForensicData: TYPE_INBOUND \n"));
2938285809Sscottl
2939285809Sscottl      if(forensicData->BufferType.queueBuf.queueIndex >=AGSA_MAX_INBOUND_Q )
2940285809Sscottl      {
2941285809Sscottl        smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2Z");
2942285809Sscottl        return AGSA_RC_FAILURE;
2943285809Sscottl      }
2944285809Sscottl      circularQ = &saRoot->inboundQueue[forensicData->BufferType.queueBuf.queueIndex];
2945285809Sscottl      status = siDumpInboundQueue( forensicData->BufferType.queueBuf.directData,
2946285809Sscottl                                 forensicData->BufferType.queueBuf.directLen,
2947285809Sscottl                                 circularQ );
2948285809Sscottl		smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "2Z");
2949285809Sscottl		return status;
2950285809Sscottl    }
2951285809Sscottl	else if(forensicData->DataType == TYPE_OUTBOUND_QUEUE )
2952285809Sscottl	//else if( forensicData->BufferType.queueBuf.queueType == TYPE_OUTBOUND_QUEUE )
2953285809Sscottl    {
2954285809Sscottl      mpiOCQueue_t        *circularQ = NULL;
2955285809Sscottl		SA_DBG2(("siGetForensicData: TYPE_OUTBOUND\n"));
2956285809Sscottl
2957285809Sscottl      if(forensicData->BufferType.queueBuf.queueIndex >= AGSA_MAX_OUTBOUND_Q )
2958285809Sscottl      {
2959285809Sscottl        smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "2Z");
2960285809Sscottl        return AGSA_RC_FAILURE;
2961285809Sscottl      }
2962285809Sscottl
2963285809Sscottl      circularQ = &saRoot->outboundQueue[forensicData->BufferType.queueBuf.queueIndex];
2964285809Sscottl      status = siDumpOutboundQueue(forensicData->BufferType.queueBuf.directData,
2965285809Sscottl                                 forensicData->BufferType.queueBuf.directLen,
2966285809Sscottl                                 circularQ );
2967285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "2Z");
2968285809Sscottl
2969285809Sscottl    return status;
2970285809Sscottl  }
2971285809Sscottl  else if(forensicData->DataType == TYPE_NON_FATAL  )
2972285809Sscottl  {
2973285809Sscottl		// if(smIS_SPCV(agRoot))
2974285809Sscottl		// {
2975285809Sscottl		SA_DBG2(("siGetForensicData:TYPE_NON_FATAL \n"));
2976285809Sscottl      status = siNonFatalErrorBuffer(agRoot,forensicData);
2977285809Sscottl		// }
2978285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "2Z");
2979285809Sscottl    return status;
2980285809Sscottl  }
2981285809Sscottl  else if(forensicData->DataType == TYPE_FATAL  )
2982285809Sscottl  {
2983285809Sscottl		// if(smIS_SPCV(agRoot))
2984285809Sscottl		//{
2985285809Sscottl		SA_DBG2(("siGetForensicData:TYPE_NON_FATAL \n"));
2986285809Sscottl      status = siFatalErrorBuffer(agRoot,forensicData );
2987285809Sscottl		// }
2988285809Sscottl		smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "2Z");
2989285809Sscottl		return status;
2990285809Sscottl	}
2991285809Sscottl	else
2992285809Sscottl	{
2993285809Sscottl		SA_DBG1(("siGetForensicData receive error parameter!\n"));
2994285809Sscottl		smTraceFuncExit(hpDBG_VERY_LOUD, 'h', "2Z");
2995285809Sscottl		return AGSA_RC_FAILURE;
2996285809Sscottl	}
2997285809Sscottl	smTraceFuncExit(hpDBG_VERY_LOUD, 'i', "2Z");
2998285809Sscottl
2999285809Sscottl	return status;
3000285809Sscottl}
3001285809Sscottl
3002285809Sscottl
3003285809Sscottl//GLOBAL bit32 saGetForensicData(
3004285809Sscottlbit32 saGetForensicData(
3005285809Sscottl    agsaRoot_t         *agRoot,
3006285809Sscottl    agsaContext_t      *agContext,
3007285809Sscottl    agsaForensicData_t *forensicData
3008285809Sscottl    )
3009285809Sscottl{
3010285809Sscottl  bit32 status;
3011285809Sscottl  status = siGetForensicData(agRoot, agContext, forensicData);
3012285809Sscottl  ossaGetForensicDataCB(agRoot, agContext, status, forensicData);
3013285809Sscottl  return status;
3014285809Sscottl}
3015285809Sscottl
3016285809Sscottlbit32 saGetIOErrorStats(
3017285809Sscottl                         agsaRoot_t        *agRoot,
3018285809Sscottl                         agsaContext_t     *agContext,
3019285809Sscottl                         bit32              flag
3020285809Sscottl                         )
3021285809Sscottl{
3022285809Sscottl  agsaLLRoot_t  *saRoot = (agsaLLRoot_t*)agRoot->sdkData;
3023285809Sscottl  bit32          status = AGSA_RC_SUCCESS;
3024285809Sscottl
3025285809Sscottl  ossaGetIOErrorStatsCB(agRoot, agContext, status, &saRoot->IoErrorCount);
3026285809Sscottl
3027285809Sscottl  if (flag)
3028285809Sscottl  {
3029285809Sscottl    /* clear IO error counter */
3030285809Sscottl    si_memset(&saRoot->IoErrorCount, 0, sizeof(agsaIOErrorEventStats_t));
3031285809Sscottl  }
3032285809Sscottl
3033285809Sscottl  return status;
3034285809Sscottl}
3035285809Sscottl
3036285809Sscottlbit32 saGetIOEventStats(
3037285809Sscottl                         agsaRoot_t        *agRoot,
3038285809Sscottl                         agsaContext_t     *agContext,
3039285809Sscottl                         bit32              flag
3040285809Sscottl                         )
3041285809Sscottl{
3042285809Sscottl  agsaLLRoot_t  *saRoot = (agsaLLRoot_t*)agRoot->sdkData;
3043285809Sscottl  bit32          status = AGSA_RC_SUCCESS;
3044285809Sscottl
3045285809Sscottl  ossaGetIOEventStatsCB(agRoot, agContext, status, &saRoot->IoEventCount);
3046285809Sscottl
3047285809Sscottl  if (flag)
3048285809Sscottl  {
3049285809Sscottl    /* clear IO event counter */
3050285809Sscottl    si_memset(&saRoot->IoEventCount, 0, sizeof(agsaIOErrorEventStats_t));
3051285809Sscottl  }
3052285809Sscottl
3053285809Sscottl  return status;
3054285809Sscottl}
3055285809Sscottl
3056285809Sscottl/******************************************************************************/
3057285809Sscottl/*! \brief Initiate a GET REGISTER DUMP command
3058285809Sscottl *
3059285809Sscottl *  This function is called to Get Register Dump from the SPC.
3060285809Sscottl *
3061285809Sscottl *  \param agRoot      handles for this instance of SAS/SATA hardware
3062285809Sscottl *  \param agContext   the context of this API
3063285809Sscottl *  \param queueNum    queue number
3064285809Sscottl *  \param regDumpInfo register dump information
3065285809Sscottl *
3066285809Sscottl *  \return
3067285809Sscottl *          - SUCCESS or FAILURE
3068285809Sscottl */
3069285809Sscottl/*******************************************************************************/
3070285809Sscottl//GLOBAL bit32 saGetRegisterDump(
3071285809Sscottlbit32 saGetRegisterDump(
3072285809Sscottl              agsaRoot_t        *agRoot,
3073285809Sscottl              agsaContext_t     *agContext,
3074285809Sscottl              bit32             queueNum,
3075285809Sscottl              agsaRegDumpInfo_t *regDumpInfo
3076285809Sscottl              )
3077285809Sscottl{
3078285809Sscottl  agsaLLRoot_t          *saRoot = agNULL;
3079285809Sscottl  bit32                 ret = AGSA_RC_SUCCESS;
3080285809Sscottl//  bit32                 value, value1;
3081285809Sscottl
3082285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"6p");
3083285809Sscottl
3084285809Sscottl  /* sanity check */
3085285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
3086285809Sscottl
3087285809Sscottl  saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
3088285809Sscottl  /* sanity check */
3089285809Sscottl  SA_ASSERT((agNULL != saRoot), "");
3090285809Sscottl
3091285809Sscottl  /* sanity check */
3092285809Sscottl  SA_ASSERT((agNULL != regDumpInfo), "");
3093285809Sscottl
3094285809Sscottl  SA_DBG3(("saGetRegisterDump: agContext %p\n", agContext));
3095285809Sscottl
3096285809Sscottl  if (regDumpInfo->regDumpSrc > 3)
3097285809Sscottl  {
3098285809Sscottl    SA_DBG1(("saGetRegisterDump, regDumpSrc %d or regDumpNum %d invalid\n",
3099285809Sscottl            regDumpInfo->regDumpNum, regDumpInfo->regDumpNum));
3100285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6p");
3101285809Sscottl    /* CB error for Register Dump */
3102285809Sscottl    ossaGetRegisterDumpCB(agRoot, agContext, OSSA_FAILURE);
3103285809Sscottl    return AGSA_RC_FAILURE;
3104285809Sscottl  }
3105285809Sscottl
3106285809Sscottl  switch(regDumpInfo->regDumpSrc)
3107285809Sscottl  {
3108285809Sscottl  case REG_DUMP_NONFLASH:
3109285809Sscottl    /*First 6 64k data from GSMDUMP, contains IOST and RB info*/
3110285809Sscottl    if (regDumpInfo->regDumpNum == GET_IOST_RB_INFO)
3111285809Sscottl    {
3112285809Sscottl      regDumpInfo->regDumpOffset = regDumpInfo->regDumpOffset + 0;
3113285809Sscottl      ret = siGSMDump(agRoot, regDumpInfo->regDumpOffset, regDumpInfo->directLen, regDumpInfo->directData);
3114285809Sscottl      /* CB error for Register Dump */
3115285809Sscottl      ossaGetRegisterDumpCB(agRoot, agContext, ret);
3116285809Sscottl      return ret;
3117285809Sscottl    }
3118285809Sscottl    /* Last 1MB data from GSMDUMP, contains GSM_SM info*/
3119285809Sscottl
3120285809Sscottl    if (regDumpInfo->regDumpNum == GET_GSM_SM_INFO)
3121285809Sscottl    {
3122285809Sscottl      /* GSM_SM - total 1 Mbytes */
3123285809Sscottl      bit32    offset;
3124285809Sscottl      if(smIS_SPC(agRoot))
3125285809Sscottl      {
3126285809Sscottl        offset = regDumpInfo->regDumpOffset + SPC_GSM_SM_OFFSET;
3127285809Sscottl      }else if(smIS_SPCV(agRoot))
3128285809Sscottl      {
3129285809Sscottl        offset = regDumpInfo->regDumpOffset + SPCV_GSM_SM_OFFSET;
3130285809Sscottl      } else
3131285809Sscottl      {
3132285809Sscottl        SA_DBG1(("saGetRegisterDump: the device type is not support\n"));
3133285809Sscottl        return AGSA_RC_FAILURE;
3134285809Sscottl      }
3135285809Sscottl
3136285809Sscottl      ret = siGSMDump(agRoot, offset, regDumpInfo->directLen, regDumpInfo->directData);
3137285809Sscottl      /* CB error for Register Dump */
3138285809Sscottl      ossaGetRegisterDumpCB(agRoot, agContext, ret);
3139285809Sscottl      return ret;
3140285809Sscottl    }
3141285809Sscottl
3142285809Sscottl    /* check fatal errors */
3143285809Sscottl    if(smIS_SPC(agRoot)) {
3144285809Sscottl      siSpcGetErrorContent(agRoot);
3145285809Sscottl    }
3146285809Sscottl    else if(smIS_SPCV(agRoot)) {
3147285809Sscottl      siSpcvGetErrorContent(agRoot);
3148285809Sscottl    }
3149285809Sscottl    /* Then read from local copy */
3150285809Sscottl    if (regDumpInfo->directLen > REGISTER_DUMP_BUFF_SIZE)
3151285809Sscottl    {
3152285809Sscottl      SA_DBG1(("saGetRegisterDump, Request too many bytes %d\n",
3153285809Sscottl              regDumpInfo->directLen));
3154285809Sscottl      regDumpInfo->directLen = REGISTER_DUMP_BUFF_SIZE;
3155285809Sscottl    }
3156285809Sscottl
3157285809Sscottl    if (regDumpInfo->regDumpNum == 0)
3158285809Sscottl    {
3159285809Sscottl      /* Copy the LL Local register dump0 data to the destination */
3160285809Sscottl      si_memcpy(regDumpInfo->directData, (bit8 *)&saRoot->registerDump0[0] +
3161285809Sscottl                regDumpInfo->regDumpOffset, regDumpInfo->directLen);
3162285809Sscottl    }
3163285809Sscottl    else if( regDumpInfo->regDumpNum == 1)
3164285809Sscottl    {
3165285809Sscottl      /* Copy the LL Local register dump1 data to the destination */
3166285809Sscottl      si_memcpy(regDumpInfo->directData, (bit8 *)&saRoot->registerDump1[0] +
3167285809Sscottl                regDumpInfo->regDumpOffset, regDumpInfo->directLen);
3168285809Sscottl    } else {
3169285809Sscottl      SA_DBG1(("saGetRegisterDump, the regDumpNum value is wrong %x\n",
3170285809Sscottl              regDumpInfo->regDumpNum));
3171285809Sscottl    }
3172285809Sscottl
3173285809Sscottl    /* CB for Register Dump */
3174285809Sscottl    ossaGetRegisterDumpCB(agRoot, agContext, OSSA_SUCCESS);
3175285809Sscottl    break;
3176285809Sscottl
3177285809Sscottl  case REG_DUMP_FLASH:
3178285809Sscottl    /* build IOMB command and send to SPC */
3179285809Sscottl    ret = mpiNVMReadRegDumpCmd(agRoot, agContext, queueNum,
3180285809Sscottl                            regDumpInfo->regDumpNum,
3181285809Sscottl                            regDumpInfo->regDumpOffset,
3182285809Sscottl                            regDumpInfo->indirectAddrUpper32,
3183285809Sscottl                            regDumpInfo->indirectAddrLower32,
3184285809Sscottl                            regDumpInfo->indirectLen);
3185285809Sscottl
3186285809Sscottl    break;
3187285809Sscottl
3188285809Sscottl  default:
3189285809Sscottl    break;
3190285809Sscottl  }
3191285809Sscottl
3192285809Sscottl  smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6p");
3193285809Sscottl
3194285809Sscottl  return ret;
3195285809Sscottl}
3196285809Sscottl
3197285809Sscottl/******************************************************************************/
3198285809Sscottl/*! \brief Initiate a GET REGISTER DUMP from GSM command
3199285809Sscottl *
3200285809Sscottl *  This function is called to Get Register Dump from the GSM of SPC.
3201285809Sscottl *
3202285809Sscottl *  \param agRoot      handles for this instance of SAS/SATA hardware
3203285809Sscottl *  \param destinationAddress address of the register dump data copied to
3204285809Sscottl *  \param regDumpNum  Register Dump # 0 or 1
3205285809Sscottl *  \param regDumpOffset Offset within the register dump area
3206285809Sscottl *  \param len         Length in bytes of the register dump data to copy
3207285809Sscottl *
3208285809Sscottl *  \return
3209285809Sscottl *          - SUCCESS or FAILURE
3210285809Sscottl */
3211285809Sscottl/*******************************************************************************/
3212285809Sscottl//GLOBAL bit32 siGetRegisterDumpGSM(
3213285809Sscottlbit32 siGetRegisterDumpGSM(
3214285809Sscottl                        agsaRoot_t        *agRoot,
3215285809Sscottl                        void              *destinationAddress,
3216285809Sscottl                        bit32             regDumpNum,
3217285809Sscottl                        bit32             regDumpOffset,
3218285809Sscottl                        bit32             len
3219285809Sscottl                        )
3220285809Sscottl{
3221285809Sscottl  agsaLLRoot_t          *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
3222285809Sscottl  bit32                 ret = AGSA_RC_SUCCESS;
3223285809Sscottl  bit32                 rDumpOffset, rDumpLen; //, rDumpValue;
3224285809Sscottl  bit8                  *dst;
3225285809Sscottl
3226285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"2V");
3227285809Sscottl
3228285809Sscottl  /* sanity check */
3229285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
3230285809Sscottl
3231285809Sscottl  dst = (bit8 *)destinationAddress;
3232285809Sscottl
3233285809Sscottl  if (regDumpNum > 1)
3234285809Sscottl  {
3235285809Sscottl    SA_DBG1(("siGetRegisterDump, regDumpNum %d is invalid\n", regDumpNum));
3236285809Sscottl    return AGSA_RC_FAILURE;
3237285809Sscottl  }
3238285809Sscottl
3239285809Sscottl  if (!regDumpNum)
3240285809Sscottl  {
3241285809Sscottl    rDumpOffset = saRoot->mainConfigTable.FatalErrorDumpOffset0;
3242285809Sscottl    rDumpLen = saRoot->mainConfigTable.FatalErrorDumpLength0;
3243285809Sscottl  }
3244285809Sscottl  else
3245285809Sscottl  {
3246285809Sscottl    rDumpOffset = saRoot->mainConfigTable.FatalErrorDumpOffset1;
3247285809Sscottl    rDumpLen = saRoot->mainConfigTable.FatalErrorDumpLength1;
3248285809Sscottl  }
3249285809Sscottl
3250285809Sscottl  if (len > rDumpLen)
3251285809Sscottl  {
3252285809Sscottl    SA_DBG1(("siGetRegisterDump, Request too many bytes %d, rDumpLen %d\n", len, rDumpLen));
3253285809Sscottl    len = rDumpLen;
3254285809Sscottl  }
3255285809Sscottl
3256285809Sscottl  if (regDumpOffset >= len)
3257285809Sscottl  {
3258285809Sscottl    SA_DBG1(("siGetRegisterDump, Offset is not within the area %d, regDumpOffset%d\n", rDumpLen, regDumpOffset));
3259285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2V");
3260285809Sscottl    return AGSA_RC_FAILURE;
3261285809Sscottl  }
3262285809Sscottl
3263285809Sscottl  /* adjust length to dword boundary */
3264285809Sscottl  if ((len % 4) > 0)
3265285809Sscottl  {
3266285809Sscottl    len = (len/4 + 1) * 4;
3267285809Sscottl  }
3268285809Sscottl
3269285809Sscottl  ret = siGSMDump(agRoot, rDumpOffset, len, dst);
3270285809Sscottl  smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2V");
3271285809Sscottl
3272285809Sscottl  return ret;
3273285809Sscottl}
3274285809Sscottl
3275285809Sscottl/******************************************************************************/
3276285809Sscottl/*! \brief SPC Get NVMD Command
3277285809Sscottl *
3278285809Sscottl *  This command sends GET_NVMD_DATA Command to SPC.
3279285809Sscottl *
3280285809Sscottl *  \param agRoot       Handles for this instance of SAS/SATA LL
3281285809Sscottl *  \param agContext    Context of SPC FW Flash Update Command
3282285809Sscottl *  \param queueNum     Inbound/outbound queue number
3283285809Sscottl *  \param NVMDInfo     Pointer of NVM Device information
3284285809Sscottl *
3285285809Sscottl *  \return If the MPI command is sent to SPC successfully
3286285809Sscottl *          - \e AGSA_RC_SUCCESS the MPI command is successfully
3287285809Sscottl *          - \e AGSA_RC_FAILURE the MPI command is failure
3288285809Sscottl *
3289285809Sscottl */
3290285809Sscottl/*******************************************************************************/
3291285809Sscottl//GLOBAL bit32 saGetNVMDCommand(
3292285809Sscottlbit32 saGetNVMDCommand(
3293285809Sscottl  agsaRoot_t                *agRoot,
3294285809Sscottl  agsaContext_t             *agContext,
3295285809Sscottl  bit32                     queueNum,
3296285809Sscottl  agsaNVMDData_t            *NVMDInfo
3297285809Sscottl  )
3298285809Sscottl{
3299285809Sscottl  bit32 ret           = AGSA_RC_SUCCESS;
3300285809Sscottl
3301285809Sscottl  /* sanity check */
3302285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
3303285809Sscottl
3304285809Sscottl  /* build IOMB command and send to SPC */
3305285809Sscottl  ret = mpiGetNVMDCmd(agRoot, agContext, NVMDInfo, queueNum);
3306285809Sscottl
3307285809Sscottl  return ret;
3308285809Sscottl}
3309285809Sscottl
3310285809Sscottl/******************************************************************************/
3311285809Sscottl/*! \brief SPC Set NVMD Command
3312285809Sscottl *
3313285809Sscottl *  This command sends SET_NVMD_DATA Command to SPC.
3314285809Sscottl *
3315285809Sscottl *  \param agRoot       Handles for this instance of SAS/SATA LL
3316285809Sscottl *  \param agContext    Context of SPC FW Flash Update Command
3317285809Sscottl *  \param queueNum     Inbound/outbound queue number
3318285809Sscottl *  \param NVMDInfo     Pointer of NVM Device information
3319285809Sscottl *
3320285809Sscottl *  \return If the MPI command is sent to SPC successfully
3321285809Sscottl *          - \e AGSA_RC_SUCCESS the MPI command is successfully
3322285809Sscottl *          - \e AGSA_RC_FAILURE the MPI command is failure
3323285809Sscottl *
3324285809Sscottl */
3325285809Sscottl/*******************************************************************************/
3326285809Sscottl//GLOBAL bit32 saSetNVMDCommand(
3327285809Sscottlbit32 saSetNVMDCommand(
3328285809Sscottl  agsaRoot_t                *agRoot,
3329285809Sscottl  agsaContext_t             *agContext,
3330285809Sscottl  bit32                     queueNum,
3331285809Sscottl  agsaNVMDData_t            *NVMDInfo
3332285809Sscottl  )
3333285809Sscottl{
3334285809Sscottl  bit32 ret           = AGSA_RC_SUCCESS;
3335285809Sscottl
3336285809Sscottl  /* sanity check */
3337285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
3338285809Sscottl
3339285809Sscottl  /* build IOMB command and send to SPC */
3340285809Sscottl  ret = mpiSetNVMDCmd(agRoot, agContext, NVMDInfo, queueNum);
3341285809Sscottl
3342285809Sscottl  return ret;
3343285809Sscottl}
3344285809Sscottl
3345285809Sscottl
3346285809SscottlGLOBAL bit32 saSendSMPIoctl(
3347285809Sscottl  agsaRoot_t                *agRoot,
3348285809Sscottl  agsaDevHandle_t           *agDevHandle,
3349285809Sscottl  bit32                      queueNum,
3350285809Sscottl  agsaSMPFrame_t            *pSMPFrame,
3351285809Sscottl  ossaSMPCompletedCB_t       agCB
3352285809Sscottl  )
3353285809Sscottl{
3354285809Sscottl  bit32 ret           = AGSA_RC_SUCCESS;
3355285809Sscottl  //bit32 IR_IP_OV_res_phyId_DPdLen_res = 0;
3356285809Sscottl  bit32 retVal;
3357285809Sscottl  bit8                      inq, outq;
3358285809Sscottl  agsaIORequestDesc_t       *pRequest;
3359285809Sscottl  void                      *pMessage;
3360285809Sscottl  bit8                      *payload_ptr;
3361285809Sscottl  agsaDeviceDesc_t          *pDevice;
3362285809Sscottl  bit8                      using_reserved = agFALSE;
3363285809Sscottl  agsaPort_t                *pPort;
3364285809Sscottl  mpiICQueue_t              *circularQ;
3365285809Sscottl  agsaLLRoot_t              *saRoot = agNULL;
3366285809Sscottl//  agsaDevHandle_t       	*agDevHandle;
3367285809Sscottl
3368285809Sscottl  saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
3369285809Sscottl  SA_ASSERT((agNULL != saRoot), "");
3370285809Sscottl
3371285809Sscottl  /* sanity check */
3372285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
3373285809Sscottl
3374285809Sscottl
3375285809Sscottl
3376285809Sscottl  /* Get request from free IO Requests */
3377285809Sscottl  ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3378285809Sscottl  pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/
3379285809Sscottl
3380285809Sscottl  /* If no LL IO request entry available */
3381285809Sscottl  if ( agNULL == pRequest )
3382285809Sscottl  {
3383285809Sscottl    pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests));
3384285809Sscottl
3385285809Sscottl    if(agNULL != pRequest)
3386285809Sscottl    {
3387285809Sscottl      using_reserved = agTRUE;
3388285809Sscottl      SA_DBG1(("saSMPStart, using saRoot->freeReservedRequests\n"));
3389285809Sscottl    }
3390285809Sscottl    else
3391285809Sscottl    {
3392285809Sscottl      ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3393285809Sscottl      SA_DBG1(("saSMPStart, No request from free list Not using saRoot->freeReservedRequests\n"));
3394285809Sscottl      smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "9a");
3395285809Sscottl      return AGSA_RC_BUSY;
3396285809Sscottl    }
3397285809Sscottl  }
3398285809Sscottl
3399285809Sscottl  inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
3400285809Sscottl  outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
3401285809Sscottl
3402285809Sscottl
3403285809Sscottl
3404285809Sscottl
3405285809Sscottl  SA_ASSERT((agNULL != agDevHandle), "");
3406285809Sscottl  /* Find the outgoing port for the device */
3407285809Sscottl  if (agNULL == agDevHandle->sdkData)
3408285809Sscottl  {
3409285809Sscottl	/* Device has been removed */
3410285809Sscottl      ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3411285809Sscottl	SA_DBG1(("saSMPStart, Device has been removed. agDevHandle=%p\n", agDevHandle));
3412285809Sscottl	smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "9a");
3413285809Sscottl	return AGSA_RC_FAILURE;
3414285809Sscottl  }
3415285809Sscottl
3416285809Sscottl  pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
3417285809Sscottl
3418285809Sscottl  pPort = pDevice->pPort;
3419285809Sscottl
3420285809Sscottl
3421285809Sscottl
3422285809Sscottl	  /* If free IOMB avaliable */
3423285809Sscottl	  /* Remove the request from free list */
3424285809Sscottl	  if( using_reserved )
3425285809Sscottl	  {
3426285809Sscottl		saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
3427285809Sscottl	  }
3428285809Sscottl	  else
3429285809Sscottl	  {
3430285809Sscottl		saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
3431285809Sscottl	  }
3432285809Sscottl
3433285809Sscottl	  /* Add the request to the pendingSMPRequests list of the device */
3434285809Sscottl	  saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode));
3435285809Sscottl	  SA_ASSERT((!pRequest->valid), "The pRequest is in use");
3436285809Sscottl	  pRequest->valid			  = agTRUE;
3437285809Sscottl	  ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3438285809Sscottl
3439285809Sscottl	  /* set up pRequest */
3440285809Sscottl	  pRequest->pIORequestContext = (agsaIORequest_t *)pRequest;
3441285809Sscottl	  pRequest->pDevice 		  = pDevice;
3442285809Sscottl	  pRequest->pPort			  = pPort;
3443285809Sscottl	  pRequest->startTick		  = saRoot->timeTick;
3444285809Sscottl	  pRequest->completionCB	  = (ossaSSPCompletedCB_t)agCB;
3445285809Sscottl	  pRequest->requestType		  = AGSA_SMP_IOCTL_REQUEST;
3446285809Sscottl
3447285809Sscottl	  /* Set request to the sdkData of agIORequest */
3448285809Sscottl	 // agIORequest->sdkData		  = pRequest;
3449285809Sscottl
3450285809Sscottl	  /* save tag to IOMap */
3451285809Sscottl	  saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
3452285809Sscottl	  saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
3453285809Sscottl
3454285809Sscottl#ifdef SA_LL_IBQ_PROTECT
3455285809Sscottl	  ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
3456285809Sscottl#endif /* SA_LL_IBQ_PROTECT */
3457285809Sscottl
3458285809Sscottl	  /* If LL IO request entry avaliable */
3459285809Sscottl	  /* Get a free inbound queue entry */
3460285809Sscottl	  circularQ = &saRoot->inboundQueue[inq];
3461285809Sscottl	  retVal	= mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage);
3462285809Sscottl
3463285809Sscottl	  if (AGSA_RC_FAILURE == retVal)
3464285809Sscottl	  {
3465285809Sscottl#ifdef SA_LL_IBQ_PROTECT
3466285809Sscottl		ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
3467285809Sscottl#endif /* SA_LL_IBQ_PROTECT */
3468285809Sscottl		/* if not sending return to free list rare */
3469285809Sscottl		ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3470285809Sscottl		saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
3471285809Sscottl		pRequest->valid = agFALSE;
3472285809Sscottl		saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
3473285809Sscottl		ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3474285809Sscottl
3475285809Sscottl		SA_DBG1(("saSMPStart, error when get free IOMB\n"));
3476285809Sscottl		smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "9a");
3477285809Sscottl		return AGSA_RC_FAILURE;
3478285809Sscottl	  }
3479285809Sscottl
3480285809Sscottl	  /* return busy if inbound queue is full */
3481285809Sscottl	  if (AGSA_RC_BUSY == retVal)
3482285809Sscottl	  {
3483285809Sscottl#ifdef SA_LL_IBQ_PROTECT
3484285809Sscottl		ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
3485285809Sscottl#endif /* SA_LL_IBQ_PROTECT */
3486285809Sscottl		/* if not sending return to free list rare */
3487285809Sscottl		ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3488285809Sscottl		saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
3489285809Sscottl		pRequest->valid = agFALSE;
3490285809Sscottl		saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
3491285809Sscottl		ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3492285809Sscottl
3493285809Sscottl		SA_DBG1(("saSMPStart, no more IOMB\n"));
3494285809Sscottl		smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "9a");
3495285809Sscottl		return AGSA_RC_BUSY;
3496285809Sscottl	  }
3497285809Sscottl#ifdef SA_LL_IBQ_PROTECT
3498285809Sscottl			  ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
3499285809Sscottl#endif /* SA_LL_IBQ_PROTECT */
3500285809Sscottl
3501285809Sscottl
3502285809Sscottl	if(smIS_SPC(agRoot))
3503285809Sscottl	{
3504285809Sscottl	 agsaSMPCmd_t payload;
3505285809Sscottl
3506285809Sscottl
3507285809Sscottl		  bit32 IR_IP_OV_res_phyId_DPdLen_res = 0;
3508285809Sscottl		  /* Prepare the payload of IOMB */
3509285809Sscottl		  si_memset(&payload, 0, sizeof(agsaSMPCmd_V_t));
3510285809Sscottl		  OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, tag), pRequest->HTag);
3511285809Sscottl		  OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, deviceId), pDevice->DeviceMapIndex);
3512285809Sscottl
3513285809Sscottl
3514285809Sscottl
3515285809Sscottl		  /*Indirect request and response*/
3516285809Sscottl		  if (smpFrameFlagIndirectResponse & pSMPFrame->flag && smpFrameFlagIndirectPayload & pSMPFrame->flag) /* */
3517285809Sscottl		  {
3518285809Sscottl
3519285809Sscottl			SA_DBG2(("saSMPStart:V Indirect payload and indirect response\n"));
3520285809Sscottl
3521285809Sscottl			/* Indirect Response mode */
3522285809Sscottl			pRequest->IRmode = INDIRECT_MODE;
3523285809Sscottl			IR_IP_OV_res_phyId_DPdLen_res = 3;
3524285809Sscottl
3525285809Sscottl
3526285809Sscottl			/* payload */
3527285809Sscottl			OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[4]), (pSMPFrame->outFrameAddrLower32));
3528285809Sscottl			OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[5]), (pSMPFrame->outFrameAddrUpper32));
3529285809Sscottl			OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[6]), (pSMPFrame->outFrameLen));
3530285809Sscottl
3531285809Sscottl			OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[8]), (pSMPFrame->inFrameAddrLower32));
3532285809Sscottl			OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[9]), (pSMPFrame->inFrameAddrUpper32));
3533285809Sscottl			OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[10]), (pSMPFrame->inFrameLen));
3534285809Sscottl
3535285809Sscottl		  }
3536285809Sscottl
3537285809Sscottl
3538285809Sscottl		  IR_IP_OV_res_phyId_DPdLen_res |= (pSMPFrame->flag & 3);
3539285809Sscottl		  /* fatal error if missing */
3540285809Sscottl		  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);
3541285809Sscottl		  /* fatal error if missing */
3542285809Sscottl
3543285809Sscottl
3544285809Sscottl		/* check IR bit */
3545285809Sscottl
3546285809Sscottl		/* Build IOMB command and send it to SPC */
3547285809Sscottl		payload_ptr = (bit8 *)&payload;
3548285809Sscottl#ifdef SA_LL_IBQ_PROTECT
3549285809Sscottl				ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
3550285809Sscottl#endif /* SA_LL_IBQ_PROTECT */
3551285809Sscottl
3552285809Sscottl		ret = mpiSMPCmd(agRoot, pMessage, OPC_INB_SMP_REQUEST, (agsaSMPCmd_t *)payload_ptr, inq, outq);
3553285809Sscottl
3554285809Sscottl#ifdef SA_LL_IBQ_PROTECT
3555285809Sscottl			  ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
3556285809Sscottl#endif /* SA_LL_IBQ_PROTECT */
3557285809Sscottl
3558285809Sscottl
3559285809Sscottl  }
3560285809Sscottl	else /* IOMB is different for SPCV SMP */
3561285809Sscottl	{
3562285809Sscottl	 agsaSMPCmd_V_t vpayload;
3563285809Sscottl
3564285809Sscottl
3565285809Sscottl		  bit32 IR_IP_OV_res_phyId_DPdLen_res = 0;
3566285809Sscottl		  /* Prepare the payload of IOMB */
3567285809Sscottl		  si_memset(&vpayload, 0, sizeof(agsaSMPCmd_V_t));
3568285809Sscottl		  OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, tag), pRequest->HTag);
3569285809Sscottl		  OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, deviceId), pDevice->DeviceMapIndex);
3570285809Sscottl		  OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMPHDR ), *((bit32*)pSMPFrame->outFrameBuf+0) );
3571285809Sscottl
3572285809Sscottl		  /*Indirect request and response*/
3573285809Sscottl		  if (smpFrameFlagIndirectResponse & pSMPFrame->flag && smpFrameFlagIndirectPayload & pSMPFrame->flag) /* */
3574285809Sscottl		  {
3575285809Sscottl
3576285809Sscottl			SA_DBG2(("saSMPStart:V Indirect payload and indirect response\n"));
3577285809Sscottl
3578285809Sscottl			/* Indirect Response mode */
3579285809Sscottl			pRequest->IRmode = INDIRECT_MODE;
3580285809Sscottl			IR_IP_OV_res_phyId_DPdLen_res = 3;
3581285809Sscottl
3582285809Sscottl
3583285809Sscottl			/* payload */
3584285809Sscottl			OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirL_SMPRF15_12 ), (pSMPFrame->outFrameAddrLower32));
3585285809Sscottl			OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirH_or_SMPRF19_16 ), (pSMPFrame->outFrameAddrUpper32));
3586285809Sscottl			OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirLen_or_SMPRF23_20 ), (pSMPFrame->outFrameLen));
3587285809Sscottl
3588285809Sscottl			OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,ISRAL_or_SMPRF31_28), (pSMPFrame->inFrameAddrLower32));
3589285809Sscottl			OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,ISRAH_or_SMPRF35_32), (pSMPFrame->inFrameAddrUpper32));
3590285809Sscottl			OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,ISRL_or_SMPRF39_36), (pSMPFrame->inFrameLen));
3591285809Sscottl
3592285809Sscottl		  }
3593285809Sscottl
3594285809Sscottl		  /*Direct request and indirect response*/
3595285809Sscottl		  else if (smpFrameFlagIndirectResponse & pSMPFrame->flag ) /* */
3596285809Sscottl		  {
3597285809Sscottl
3598285809Sscottl  			SA_DBG2(("saSMPStart:V Direct payload and indirect response\n"));
3599285809Sscottl			IR_IP_OV_res_phyId_DPdLen_res = (pSMPFrame->outFrameLen << SHIFT16) | pSMPFrame->flag;
3600285809Sscottl
3601285809Sscottl
3602285809Sscottl			  /* Write IR_IP_OV_res_phyId_DPdLen_res field in the payload*/
3603285809Sscottl			  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);
3604285809Sscottl			  /* setup indirect response frame address */
3605285809Sscottl			  OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRAL_or_SMPRF31_28 ), (pSMPFrame->inFrameAddrLower32));
3606285809Sscottl			  OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRAH_or_SMPRF35_32 ), (pSMPFrame->inFrameAddrUpper32));
3607285809Sscottl			  OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRL_or_SMPRF39_36 ), (pSMPFrame->inFrameLen));
3608285809Sscottl
3609285809Sscottl		  }
3610285809Sscottl		  IR_IP_OV_res_phyId_DPdLen_res |= (pSMPFrame->flag & 3);
3611285809Sscottl		  /* fatal error if missing */
3612285809Sscottl		  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);
3613285809Sscottl		  /* fatal error if missing */
3614285809Sscottl
3615285809Sscottl
3616285809Sscottl		/* check IR bit */
3617285809Sscottl
3618285809Sscottl#ifdef SA_LL_IBQ_PROTECT
3619285809Sscottl				ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
3620285809Sscottl#endif /* SA_LL_IBQ_PROTECT */
3621285809Sscottl		/* Build IOMB command and send it to SPCv */
3622285809Sscottl		payload_ptr = (bit8 *)&vpayload;
3623285809Sscottl		ret = mpiSMPCmd(agRoot, pMessage, OPC_INB_SMP_REQUEST, (agsaSMPCmd_t *)payload_ptr, inq, outq);
3624285809Sscottl
3625285809Sscottl#ifdef SA_LL_IBQ_PROTECT
3626285809Sscottl			  ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
3627285809Sscottl#endif /* SA_LL_IBQ_PROTECT */
3628285809Sscottl
3629285809Sscottl
3630285809Sscottl  }
3631285809Sscottl
3632285809Sscottl
3633285809Sscottl  return ret;
3634285809Sscottl}
3635285809Sscottl
3636285809Sscottl
3637285809Sscottl/******************************************************************************/
3638285809Sscottl/*! \brief Reconfiguration of SAS Parameters Command
3639285809Sscottl *
3640285809Sscottl *  This command Reconfigure the SAS parameters to SPC.
3641285809Sscottl *
3642285809Sscottl *  \param agRoot       Handles for this instance of SAS/SATA LL
3643285809Sscottl *  \param agContext    Context of SPC FW Flash Update Command
3644285809Sscottl *  \param queueNum     Inbound/outbound queue number
3645285809Sscottl *  \param agSASConfig  Pointer of SAS Configuration Parameters
3646285809Sscottl *
3647285809Sscottl *  \return If the MPI command is sent to SPC successfully
3648285809Sscottl *          - \e AGSA_RC_SUCCESS the MPI command is successfully
3649285809Sscottl *          - \e AGSA_RC_FAILURE the MPI command is failure
3650285809Sscottl *
3651285809Sscottl */
3652285809Sscottl/*******************************************************************************/
3653285809Sscottl//GLOBAL bit32 saReconfigSASParams(
3654285809Sscottlbit32 saReconfigSASParams(
3655285809Sscottl  agsaRoot_t        *agRoot,
3656285809Sscottl  agsaContext_t     *agContext,
3657285809Sscottl  bit32             queueNum ,
3658285809Sscottl  agsaSASReconfig_t *agSASConfig
3659285809Sscottl  )
3660285809Sscottl{
3661285809Sscottl  bit32 ret           = AGSA_RC_SUCCESS;
3662285809Sscottl
3663285809Sscottl  /* sanity check */
3664285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
3665285809Sscottl
3666285809Sscottl  if(smIS_SPCV(agRoot))
3667285809Sscottl  {
3668285809Sscottl    SA_DBG1(("saReconfigSASParams: AGSA_RC_FAILURE for SPCv\n" ));
3669285809Sscottl    return(AGSA_RC_FAILURE);
3670285809Sscottl  }
3671285809Sscottl
3672285809Sscottl  /* build IOMB command and send to SPC */
3673285809Sscottl  ret = mpiSasReinitializeCmd(agRoot, agContext, agSASConfig, queueNum);
3674285809Sscottl
3675285809Sscottl  return ret;
3676285809Sscottl}
3677285809Sscottl
3678285809Sscottl/******************************************************************************/
3679285809Sscottl/*! \brief Dump GSM registers from the controller
3680285809Sscottl *
3681285809Sscottl *  \param agRoot         Handles for this instance of SAS/SATA hardware
3682285809Sscottl *  \param gsmDumpOffset  Offset of GSM
3683285809Sscottl *  \param length         Max is 1 MB
3684285809Sscottl *  \param directData     address of GSM data dump to
3685285809Sscottl *
3686285809Sscottl *  \return
3687285809Sscottl *          - \e AGSA_RC_SUCCESS saGSMDump is successfully
3688285809Sscottl *          - \e AGSA_RC_FAILURE saGSMDump is not successfully
3689285809Sscottl *
3690285809Sscottl */
3691285809Sscottl/*******************************************************************************/
3692285809Sscottl//LOCAL bit32 siGSMDump(
3693285809Sscottlbit32 siGSMDump(
3694285809Sscottl  agsaRoot_t     *agRoot,
3695285809Sscottl  bit32          gsmDumpOffset,
3696285809Sscottl  bit32          length,
3697285809Sscottl  void           *directData)
3698285809Sscottl{
3699285809Sscottl  bit8  *dst;
3700285809Sscottl  bit32 value, rem, offset = 0;
3701285809Sscottl  bit32 i, workOffset, dwLength;
3702285809Sscottl  bit32 bar = 0;
3703285809Sscottl
3704285809Sscottl  SA_DBG1(("siGSMDump: gsmDumpOffset 0x%x length 0x%x\n", gsmDumpOffset, length));
3705285809Sscottl
3706285809Sscottl  /* check max is 64k chunks */
3707285809Sscottl  if (length > (64 * 1024))
3708285809Sscottl  {
3709285809Sscottl    SA_DBG1(("siGSMDump: Max length is greater than 64K  bytes 0x%x\n", length));
3710285809Sscottl    return AGSA_RC_FAILURE;
3711285809Sscottl  }
3712285809Sscottl
3713285809Sscottl  if (gsmDumpOffset & 3)
3714285809Sscottl  {
3715285809Sscottl    SA_DBG1(("siGSMDump: Not allow NON_DW Boundary 0x%x\n", gsmDumpOffset));
3716285809Sscottl    return AGSA_RC_FAILURE;
3717285809Sscottl  }
3718285809Sscottl
3719285809Sscottl  if ((gsmDumpOffset + length) > ONE_MEGABYTE)
3720285809Sscottl  {
3721285809Sscottl    SA_DBG1(("siGSMDump: Out of GSM end address boundary 0x%x\n", (gsmDumpOffset+length)));
3722285809Sscottl    return AGSA_RC_FAILURE;
3723285809Sscottl  }
3724285809Sscottl
3725285809Sscottl  if( smIS_SPCV(agRoot))
3726285809Sscottl  {
3727285809Sscottl    bar = PCIBAR1;
3728285809Sscottl  }
3729285809Sscottl  else if( smIS_SPC(agRoot))
3730285809Sscottl  {
3731285809Sscottl    bar = PCIBAR2;
3732285809Sscottl  }
3733285809Sscottl  else
3734285809Sscottl  {
3735285809Sscottl    SA_DBG1(("siGSMDump: device type is not supported"));
3736285809Sscottl    return AGSA_RC_FAILURE;
3737285809Sscottl  }
3738285809Sscottl
3739285809Sscottl  workOffset = gsmDumpOffset & 0xFFFF0000;
3740285809Sscottl  offset = gsmDumpOffset & 0x0000FFFF;
3741285809Sscottl  gsmDumpOffset = workOffset;
3742285809Sscottl
3743285809Sscottl  dst = (bit8 *)directData;
3744285809Sscottl
3745285809Sscottl  /* adjust length to dword boundary */
3746285809Sscottl  rem = length & 3;
3747285809Sscottl  dwLength = length >> 2;
3748285809Sscottl
3749285809Sscottl  for (i =0; i < dwLength; i++)
3750285809Sscottl  {
3751285809Sscottl    if((workOffset + offset) > length )
3752285809Sscottl    {
3753285809Sscottl      break;
3754285809Sscottl    }
3755285809Sscottl    value = ossaHwRegReadExt(agRoot, bar, (workOffset + offset) & 0x0000FFFF);
3756285809Sscottl    /* xfr for dw */
3757285809Sscottl    si_memcpy(dst, &value, 4);
3758285809Sscottl    dst += 4;
3759285809Sscottl    offset += 4;
3760285809Sscottl  }
3761285809Sscottl
3762285809Sscottl  if (rem != 0)
3763285809Sscottl  {
3764285809Sscottl    value = ossaHwRegReadExt(agRoot, bar, (workOffset + offset) & 0x0000FFFF);
3765285809Sscottl    /* xfr for non_dw */
3766285809Sscottl    if(dst)
3767285809Sscottl    {
3768285809Sscottl      si_memcpy(dst, &value, rem);
3769285809Sscottl    }
3770285809Sscottl  }
3771285809Sscottl
3772285809Sscottl  /* Shift back to BAR4 original address */
3773285809Sscottl  if (AGSA_RC_FAILURE == siBar4Shift(agRoot, 0x0))
3774285809Sscottl  {
3775285809Sscottl    SA_DBG1(("siGSMDump:Shift Bar4 to 0x%x failed\n", 0x0));
3776285809Sscottl    return AGSA_RC_FAILURE;
3777285809Sscottl  }
3778285809Sscottl
3779285809Sscottl  return AGSA_RC_SUCCESS;
3780285809Sscottl}
3781285809Sscottl
3782285809Sscottl//GLOBAL bit32 saPCIeDiagExecute(
3783285809Sscottlbit32 saPCIeDiagExecute(
3784285809Sscottl            agsaRoot_t            *agRoot,
3785285809Sscottl            agsaContext_t         *agContext,
3786285809Sscottl            bit32                 queueNum,
3787285809Sscottl            agsaPCIeDiagExecute_t *diag)
3788285809Sscottl{
3789285809Sscottl  bit32                    ret    = AGSA_RC_SUCCESS;
3790285809Sscottl  agsaLLRoot_t            *saRoot = agNULL;
3791285809Sscottl  agsaIORequestDesc_t     *pRequest;
3792285809Sscottl  bit32  payload[32];
3793285809Sscottl
3794285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"6r");
3795285809Sscottl
3796285809Sscottl  /* sanity check */
3797285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
3798285809Sscottl
3799285809Sscottl  saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
3800285809Sscottl  /* sanity check */
3801285809Sscottl  SA_ASSERT((agNULL != saRoot), "");
3802285809Sscottl  SA_ASSERT((agNULL != diag), "");
3803285809Sscottl
3804285809Sscottl  if(diag->len == 0)
3805285809Sscottl  {
3806285809Sscottl    SA_DBG1(("saPCIeDiagExecute,  diag->len Zero\n"));
3807285809Sscottl  }
3808285809Sscottl  SA_DBG1(("saPCIeDiagExecute, diag->command  0x%X\n", diag->command ));
3809285809Sscottl  SA_DBG1(("saPCIeDiagExecute, diag->flags  0x%X\n",diag->flags ));
3810285809Sscottl  SA_DBG1(("saPCIeDiagExecute,  diag->initialIOSeed  0x%X\n", diag->initialIOSeed));
3811285809Sscottl  SA_DBG1(("saPCIeDiagExecute, diag->reserved   0x%X\n",diag->reserved ));
3812285809Sscottl  SA_DBG1(("saPCIeDiagExecute, diag->rdAddrLower   0x%X\n", diag->rdAddrLower));
3813285809Sscottl  SA_DBG1(("saPCIeDiagExecute, diag->rdAddrUpper   0x%X\n", diag->rdAddrUpper ));
3814285809Sscottl  SA_DBG1(("saPCIeDiagExecute, diag->wrAddrLower   0x%X\n", diag->wrAddrLower));
3815285809Sscottl  SA_DBG1(("saPCIeDiagExecute, diag->wrAddrUpper   0x%X\n",diag->wrAddrUpper ));
3816285809Sscottl  SA_DBG1(("saPCIeDiagExecute,  diag->len   0x%X\n",diag->len  ));
3817285809Sscottl  SA_DBG1(("saPCIeDiagExecute, diag->pattern  0x%X\n",diag->pattern ));
3818285809Sscottl  SA_DBG1(("saPCIeDiagExecute, %02X %02X %02X %02X %02X %02X\n",
3819285809Sscottl                  diag->udtArray[0],
3820285809Sscottl                  diag->udtArray[1],
3821285809Sscottl                  diag->udtArray[2],
3822285809Sscottl                  diag->udtArray[3],
3823285809Sscottl                  diag->udtArray[4],
3824285809Sscottl                  diag->udtArray[5] ));
3825285809Sscottl
3826285809Sscottl   SA_DBG1(("saPCIeDiagExecute, %02X %02X %02X %02X %02X %02X\n",
3827285809Sscottl                  diag->udrtArray[0],
3828285809Sscottl                  diag->udrtArray[1],
3829285809Sscottl                  diag->udrtArray[2],
3830285809Sscottl                  diag->udrtArray[3],
3831285809Sscottl                  diag->udrtArray[4],
3832285809Sscottl                  diag->udrtArray[5]));
3833285809Sscottl
3834285809Sscottl
3835285809Sscottl  /* Get request from free IORequests */
3836285809Sscottl  ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3837285809Sscottl  pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
3838285809Sscottl
3839285809Sscottl  /* If no LL Control request entry available */
3840285809Sscottl  if ( agNULL == pRequest )
3841285809Sscottl  {
3842285809Sscottl    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3843285809Sscottl    SA_DBG1(("saPCIeDiagExecute, No request from free list\n" ));
3844285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6r");
3845285809Sscottl    return AGSA_RC_BUSY;
3846285809Sscottl  }
3847285809Sscottl  /* If LL Control request entry avaliable */
3848285809Sscottl  /* Remove the request from free list */
3849285809Sscottl  saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
3850285809Sscottl  saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
3851285809Sscottl  saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
3852285809Sscottl  saRoot->IOMap[pRequest->HTag].agContext = agContext;
3853285809Sscottl  pRequest->valid = agTRUE;
3854285809Sscottl
3855285809Sscottl  ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3856285809Sscottl
3857285809Sscottl  /* set payload to zeros */
3858285809Sscottl  si_memset(&payload, 0, sizeof(payload));
3859285809Sscottl
3860285809Sscottl  if(smIS_SPCV(agRoot))
3861285809Sscottl  {
3862285809Sscottl    bit32      UDTR1_UDT0 ,UDT5_UDT2,UDTR5_UDTR2;
3863285809Sscottl
3864285809Sscottl    UDTR5_UDTR2 = (( diag->udrtArray[5] << SHIFT24) | (diag->udrtArray[4] << SHIFT16) | (diag->udrtArray[3] << SHIFT8) | diag->udrtArray[2]);
3865285809Sscottl    UDT5_UDT2 =   ((  diag->udtArray[5] << SHIFT24) |  (diag->udtArray[4] << SHIFT16) |  (diag->udtArray[3] << SHIFT8) |  diag->udtArray[2]);
3866285809Sscottl    UDTR1_UDT0 =  (( diag->udrtArray[1] << SHIFT24) | (diag->udrtArray[0] << SHIFT16) |  (diag->udtArray[1] << SHIFT8) |  diag->udtArray[0]);
3867285809Sscottl
3868285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, tag)        , pRequest->HTag);
3869285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, CmdTypeDesc), diag->command );
3870285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, UUM_EDA)    , diag->flags);
3871285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, UDTR1_UDT0) , UDTR1_UDT0);
3872285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, UDT5_UDT2)  , UDT5_UDT2);
3873285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, UDTR5_UDTR2), UDTR5_UDTR2);
3874285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, Res_IOS)    , diag->initialIOSeed);
3875285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, rdAddrLower), diag->rdAddrLower);
3876285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, rdAddrUpper), diag->rdAddrUpper);
3877285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, wrAddrLower), diag->wrAddrLower);
3878285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, wrAddrUpper), diag->wrAddrUpper);
3879285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, len),         diag->len);
3880285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPCIeDiagExecuteCmd_t, pattern),     diag->pattern);
3881285809Sscottl    ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_PCIE_DIAG_EXECUTE, IOMB_SIZE128, queueNum);
3882285809Sscottl  }
3883285809Sscottl  else
3884285809Sscottl  {
3885285809Sscottl    /* build IOMB command and send to SPC */
3886285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, tag),         pRequest->HTag);
3887285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, CmdTypeDesc), diag->command );
3888285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, rdAddrLower), diag->rdAddrLower);
3889285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, rdAddrUpper), diag->rdAddrUpper);
3890285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, wrAddrLower), diag->wrAddrLower);
3891285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, wrAddrUpper), diag->wrAddrUpper);
3892285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, len),         diag->len);
3893285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsa_SPC_PCIDiagExecuteCmd_t, pattern),     diag->pattern);
3894285809Sscottl    ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_PCIE_DIAG_EXECUTE, IOMB_SIZE64, queueNum);
3895285809Sscottl  }
3896285809Sscottl
3897285809Sscottl  if (AGSA_RC_SUCCESS != ret)
3898285809Sscottl  {
3899285809Sscottl    /* remove the request from IOMap */
3900285809Sscottl    saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
3901285809Sscottl    saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
3902285809Sscottl    saRoot->IOMap[pRequest->HTag].agContext = agNULL;
3903285809Sscottl
3904285809Sscottl    ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3905285809Sscottl    pRequest->valid = agFALSE;
3906285809Sscottl
3907285809Sscottl    /* return the request to free pool */
3908285809Sscottl    saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
3909285809Sscottl
3910285809Sscottl    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3911285809Sscottl
3912285809Sscottl    SA_DBG1(("saPCIeDiagExecute, sending IOMB failed\n" ));
3913285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6r");
3914285809Sscottl
3915285809Sscottl    return ret;
3916285809Sscottl  }
3917285809Sscottl
3918285809Sscottl  smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "6r");
3919285809Sscottl  return ret;
3920285809Sscottl}
3921285809Sscottl
3922285809Sscottl//GLOBAL bit32 saGetDFEData(
3923285809Sscottlbit32 saGetDFEData(
3924285809Sscottl                          agsaRoot_t     *agRoot,
3925285809Sscottl                          agsaContext_t  *agContext,
3926285809Sscottl                          bit32           queueNum,
3927285809Sscottl                          bit32           interface,
3928285809Sscottl                          bit32           laneNumber,
3929285809Sscottl                          bit32           interations,
3930285809Sscottl                          agsaSgl_t      *agSgl)
3931285809Sscottl{
3932285809Sscottl  bit32                    ret    = AGSA_RC_SUCCESS;
3933285809Sscottl  agsaLLRoot_t            *saRoot = agNULL;
3934285809Sscottl  agsaIORequestDesc_t     *pRequest = agNULL;
3935285809Sscottl  bit32  payload[32];
3936285809Sscottl  bit32 reserved_In_Ln;
3937285809Sscottl
3938285809Sscottl  smTraceFuncEnter(hpDBG_VERY_LOUD,"2X");
3939285809Sscottl  /* sanity check */
3940285809Sscottl  SA_ASSERT((agNULL != agRoot), "");
3941285809Sscottl  saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
3942285809Sscottl  SA_ASSERT((agNULL != saRoot), "");
3943285809Sscottl  SA_ASSERT((agNULL != agSgl), "");
3944285809Sscottl
3945285809Sscottl  /* Get request from free IORequests */
3946285809Sscottl  ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3947285809Sscottl  pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
3948285809Sscottl
3949285809Sscottl  /* If no LL Control request entry available */
3950285809Sscottl  if ( agNULL == pRequest )
3951285809Sscottl  {
3952285809Sscottl    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3953285809Sscottl    SA_DBG1(("saGetDFEData, No request from free list\n" ));
3954285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2X");
3955285809Sscottl    return AGSA_RC_BUSY;
3956285809Sscottl  }
3957285809Sscottl  /* If LL Control request entry avaliable */
3958285809Sscottl  /* Remove the request from free list */
3959285809Sscottl  saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
3960285809Sscottl  saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
3961285809Sscottl  saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
3962285809Sscottl  saRoot->IOMap[pRequest->HTag].agContext = agContext;
3963285809Sscottl  pRequest->valid = agTRUE;
3964285809Sscottl
3965285809Sscottl  ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3966285809Sscottl
3967285809Sscottl  /* set payload to zeros */
3968285809Sscottl  si_memset(&payload, 0, sizeof(payload));
3969285809Sscottl
3970285809Sscottl  if(smIS_SPCV(agRoot))
3971285809Sscottl  {
3972285809Sscottl    reserved_In_Ln = ((interface & 0x1) << SHIFT7) | (laneNumber & 0x7F);
3973285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDDEFDataCmd_t, tag)        , pRequest->HTag);
3974285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDDEFDataCmd_t, reserved_In_Ln)        , reserved_In_Ln);
3975285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDDEFDataCmd_t, MCNT)        , interations);
3976285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDDEFDataCmd_t, Buf_AddrL)        , agSgl->sgLower);
3977285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDDEFDataCmd_t, Buf_AddrH)        , agSgl->sgUpper);
3978285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDDEFDataCmd_t, Buf_Len)        , agSgl->len);
3979285809Sscottl    OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDDEFDataCmd_t, E_reserved)        , agSgl->extReserved);
3980285809Sscottl    ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_DFE_DATA, IOMB_SIZE128, queueNum);
3981285809Sscottl
3982285809Sscottl  }
3983285809Sscottl  else
3984285809Sscottl  {
3985285809Sscottl    /* SPC does not support this command */
3986285809Sscottl    ret = AGSA_RC_FAILURE;
3987285809Sscottl  }
3988285809Sscottl
3989285809Sscottl  if (AGSA_RC_SUCCESS != ret)
3990285809Sscottl  {
3991285809Sscottl    /* remove the request from IOMap */
3992285809Sscottl    saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
3993285809Sscottl    saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
3994285809Sscottl    saRoot->IOMap[pRequest->HTag].agContext = agNULL;
3995285809Sscottl
3996285809Sscottl    ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3997285809Sscottl    pRequest->valid = agFALSE;
3998285809Sscottl    /* return the request to free pool */
3999285809Sscottl    saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
4000285809Sscottl    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
4001285809Sscottl
4002285809Sscottl    SA_DBG1(("saPCIeDiagExecute, sending IOMB failed\n" ));
4003285809Sscottl    smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2X");
4004285809Sscottl    return ret;
4005285809Sscottl  }
4006285809Sscottl
4007285809Sscottl  smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2X");
4008285809Sscottl  return ret;
4009285809Sscottl}
4010285809Sscottl
4011