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