1 /*******************************************************************************
2 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
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
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.
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
21 ********************************************************************************/
22 /*******************************************************************************/
23 /*! \file saioctlcmd.c
24 * \brief The file implements the functions of IOCTL MPI Command/Response to/from SPC
27 /******************************************************************************/
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30 #include <dev/pms/config.h>
32 #include <dev/pms/RefTisa/sallsdk/spc/saglobal.h>
33 #ifdef SA_ENABLE_TRACE_FUNCTIONS
37 #define siTraceFileID 'H'
40 extern bit32 gFPGA_TEST;
47 LOCAL bit32 siGSMDump(
53 #ifdef SPC_ENABLE_PROFILE
54 /******************************************************************************/
55 /*! \brief SPC FW Profile Command
57 * This command sends FW Flash Update Command to SPC.
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
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
69 /*******************************************************************************/
70 GLOBAL bit32 saFwProfile(
72 agsaContext_t *agContext,
74 agsaFwProfile_t *fwProfileInfo
77 bit32 ret = AGSA_RC_SUCCESS, retVal;
78 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
79 agsaIORequestDesc_t *pRequest;
80 mpiICQueue_t *circularQ;
82 agsaFwProfileIOMB_t *pPayload;
84 bit32 i, tcid_processor_cmd = 0;
88 SA_ASSERT((agNULL != agRoot), "");
90 /* Get request from free IORequests */
91 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
92 pRequest = (agsaIORequestDesc_t *)saLlistGetHead(&(saRoot->freeIORequests));
94 /* If no LL Control request entry avaliable */
95 if ( agNULL == pRequest )
97 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
98 SA_DBG1(("saFwProfile, No request from free list\n" ));
101 /* If LL Control request entry avaliable */
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.");
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);
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);
124 /* if message size is too large return failure */
125 if (AGSA_RC_FAILURE == retVal)
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);
140 SA_DBG1(("saFwProfile, error when get free IOMB\n"));
141 return AGSA_RC_FAILURE;
144 /* return busy if inbound queue is full */
145 if (AGSA_RC_BUSY == retVal)
147 #ifdef SA_LL_IBQ_PROTECT
148 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
149 #endif /* SA_LL_IBQ_PROTECT */
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"));
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);
172 pPayload->SGLAL = fwProfileInfo->agSgl.sgLower;
173 pPayload->SGLAH = fwProfileInfo->agSgl.sgUpper;
174 pPayload->Len = fwProfileInfo->agSgl.len;
175 pPayload->extReserved = fwProfileInfo->agSgl.extReserved;
177 /* fill up the reserved bytes with zero */
178 for (i = 0; i < FWPROFILE_IOMB_RESERVED_LEN; i ++)
180 pPayload->reserved0[i] = 0;
183 /* post the IOMB to SPC */
184 ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_FW_PROFILE, outq, (bit8)circularQ->priority);
186 #ifdef SA_LL_IBQ_PROTECT
187 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
188 #endif /* SA_LL_IBQ_PROTECT */
190 if (AGSA_RC_FAILURE == ret)
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"));
207 /******************************************************************************/
208 /*! \brief SPC FW Flash Update Command
210 * This command sends FW Flash Update Command to SPC.
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
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
222 /*******************************************************************************/
223 GLOBAL bit32 saFwFlashUpdate(
225 agsaContext_t *agContext,
227 agsaUpdateFwFlash_t *flashUpdateInfo
230 bit32 ret = AGSA_RC_SUCCESS, retVal;
231 agsaLLRoot_t *saRoot;
232 agsaIORequestDesc_t *pRequest;
233 mpiICQueue_t *circularQ;
235 agsaFwFlashUpdate_t *pPayload;
239 SA_ASSERT((agNULL != agRoot), "");
240 if (agRoot == agNULL)
242 SA_DBG1(("saFwFlashUpdate: agRoot == agNULL\n"));
243 return AGSA_RC_FAILURE;
245 saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
246 SA_ASSERT((agNULL != saRoot), "");
247 if (saRoot == agNULL)
249 SA_DBG1(("saFwFlashUpdate: saRoot == agNULL\n"));
250 return AGSA_RC_FAILURE;
254 smTraceFuncEnter(hpDBG_VERY_LOUD, "6a");
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");
267 /* If LL Control request entry avaliable */
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)
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;
306 /* return busy if inbound queue is full */
307 if (AGSA_RC_BUSY == retVal)
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");
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;
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") );
365 smTraceFuncExit( hpDBG_VERY_LOUD, 'd', "6a" );
370 GLOBAL bit32 saFlashExtExecute (
372 agsaContext_t *agContext,
374 agsaFlashExtExecute_t *agFlashExtExe)
377 bit32 ret = AGSA_RC_SUCCESS, retVal;
378 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
379 agsaIORequestDesc_t *pRequest;
380 mpiICQueue_t *circularQ;
382 agsaFwFlashOpExt_t *pPayload;
385 smTraceFuncEnter(hpDBG_VERY_LOUD,"2R");
388 SA_ASSERT((agNULL != agRoot), "");
390 /* Get request from free IORequests */
391 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
392 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
394 /* If no LL Control request entry available */
395 if ( agNULL == pRequest )
397 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
398 SA_DBG1(("saFlashExtExecute, No request from free list\n" ));
399 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2R");
402 /* If LL Control request entry avaliable */
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.");
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);
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);
425 /* if message size is too large return failure */
426 if (AGSA_RC_FAILURE == retVal)
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);
441 SA_DBG1(("saFlashExtExecute, error when get free IOMB\n"));
442 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2R");
443 return AGSA_RC_FAILURE;
446 /* return busy if inbound queue is full */
447 if (AGSA_RC_BUSY == retVal)
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;
458 pRequest->valid = agFALSE;
459 /* return the request to free pool */
460 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
461 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
463 SA_DBG3(("saFlashExtExecute, no more IOMB\n"));
464 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2R");
468 pPayload = (agsaFwFlashOpExt_t *)pMessage;
470 si_memset(pPayload, 0, sizeof(agsaFwFlashOpExt_t));
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);
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);
486 #ifdef SA_LL_IBQ_PROTECT
487 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
488 #endif /* SA_LL_IBQ_PROTECT */
491 if (AGSA_RC_FAILURE == ret)
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"));
505 smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "2R");
512 #ifdef SPC_ENABLE_PROFILE
513 /******************************************************************************/
514 /*! \brief SPC FW_PROFILE Respond
516 * This command sends FW Profile Status to TD layer.
518 * \param agRoot Handles for this instance of SAS/SATA LL
519 * \param payload FW download response payload
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
526 /*******************************************************************************/
527 GLOBAL bit32 mpiFwProfileRsp(
529 agsaFwProfileRsp_t *payload
532 bit32 ret = AGSA_RC_SUCCESS;
533 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
534 agsaIORequestDesc_t *pRequest;
535 agsaContext_t *agContext;
537 bit32 status, tag, len;
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)
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;
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);
562 SA_DBG1(("mpiPortControlRsp: pRequest->valid %d not set\n", pRequest->valid));
565 SA_ASSERT((pRequest->valid), "pRequest->valid");
567 pRequest->valid = agFALSE;
568 /* return the request to free pool */
569 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
570 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
572 ossaFwProfileCB(agRoot, agContext, status, len);
577 /******************************************************************************/
578 /*! \brief SPC FW_FLASH_UPDATE Respond
580 * This command sends FW Flash Update Status to TD layer.
582 * \param agRoot Handles for this instance of SAS/SATA LL
583 * \param payload FW download response payload
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
590 /*******************************************************************************/
591 GLOBAL bit32 mpiFwFlashUpdateRsp(
593 agsaFwFlashUpdateRsp_t *payload
596 bit32 ret = AGSA_RC_SUCCESS;
597 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
598 agsaIORequestDesc_t *pRequest;
599 agsaContext_t *agContext;
602 smTraceFuncEnter(hpDBG_VERY_LOUD,"6b");
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)
619 SA_DBG1(("mpiFwFlashUpdateRsp: saving pRequest (%p) for later use\n", pRequest));
620 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
624 /* return the request to free pool */
625 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
627 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
631 SA_DBG1(("mpiFwFlashUpdateRsp: status = 0x%x\n",status));
634 ossaFwFlashUpdateCB(agRoot, agContext, status);
636 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6b");
641 GLOBAL bit32 mpiFwExtFlashUpdateRsp(
643 agsaFwFlashOpExtRsp_t *payload
646 bit32 ret = AGSA_RC_SUCCESS;
647 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
648 agsaIORequestDesc_t *pRequest;
649 agsaContext_t *agContext;
651 agsaFlashExtResponse_t FlashExtRsp;
653 bit32 Command,Status, tag;
654 smTraceFuncEnter(hpDBG_VERY_LOUD,"2T");
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 ));
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)
675 SA_DBG1(("mpiFwExtFlashUpdateRsp: saving pRequest (%p) for later use\n", pRequest));
676 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
680 /* return the request to free pool */
681 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
683 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
687 SA_DBG1(("mpiFwExtFlashUpdateRsp: status = 0x%x\n",Status));
690 ossaFlashExtExecuteCB(agRoot, agContext, Status,Command,&FlashExtRsp);
692 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2T");
699 /******************************************************************************/
700 /*! \brief SPC Get Controller Information Command
702 * This command sends Get Controller Information Command to SPC.
704 * \param agRoot Handles for this instance of SAS/SATA LL
705 * \param controllerInfo Controller Information
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
712 /*******************************************************************************/
714 GLOBAL bit32 saGetControllerInfo(
716 agsaControllerInfo_t *controllerInfo
720 bit32 ret = AGSA_RC_SUCCESS;
722 bit32 max_wait_count;
723 bit32 ContrlCapFlag, MSGUCfgTblBase, CfgTblDWIdx;
724 bit32 value = 0, value1 = 0;
727 if (agNULL != agRoot->sdkData)
729 smTraceFuncEnter(hpDBG_VERY_LOUD,"6e");
731 /* clean the structure */
732 si_memset(controllerInfo, 0, sizeof(agsaControllerInfo_t));
734 if(smIS_SPC6V(agRoot))
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))
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))
746 controllerInfo->hwRevision = SPC_READ_DEV_REV;
747 controllerInfo->sdkInterfaceRev = MATCHING_SPC_FW_VERSION;
748 controllerInfo->sdkRevision = STSDK_LL_SPC_VERSION;
752 controllerInfo->hwRevision = (ossaHwRegReadConfig32(agRoot,8) & 0xFF);
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)));
761 if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0, MSGU_SCRATCH_PAD_0) == 0xFFFFFFFF)
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;
768 if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_0, MSGU_SCRATCH_PAD_0) == 0xFFFFFFFF)
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;
775 if( SCRATCH_PAD1_V_ERROR_STATE(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1)) )
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) ));
789 value = ossaHwRegReadExt(agRoot, PCIBAR3, HDA_RSP_OFFSET1MB+HDA_CMD_CODE_OFFSET) & HDA_STATUS_BITS;
791 if (value == BOOTTLOADERHDA_IDLE)
794 SA_DBG1(("saGetControllerInfo: HDA mode, value = 0x%x\n", value));
795 return AGSA_RC_HDA_NO_FW_RUNNING;
800 if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1) & SCRATCH_PAD1_V_RESERVED )
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)));
804 if( si_check_V_HDA(agRoot))
807 SA_DBG1(("saGetControllerInfo: HDA mode AGSA_RC_HDA_NO_FW_RUNNING\n" ));
808 return AGSA_RC_HDA_NO_FW_RUNNING;
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))
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))
827 if((value & SCRATCH_PAD1_V_RESERVED) )
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;
835 if ((max_wait_count -= WAIT_INCREMENT) == 0)
837 SA_DBG1(("saGetControllerInfo: timeout SCRATCH_PAD1_V_READY !! SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1));
841 } while (((value & SCRATCH_PAD1_V_READY) != SCRATCH_PAD1_V_READY) || (value == 0xffffffff));
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)
853 SA_DBG1(("saGetControllerInfo: SCRATCH_PAD1 value = 0x%x\n", value));
854 ret = AGSA_RC_FW_NOT_IN_READY_STATE;
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)
861 SA_DBG1(("saGetControllerInfo: SCRATCH_PAD2 value = 0x%x\n", value1));
862 ret = AGSA_RC_FW_NOT_IN_READY_STATE;
865 if ((max_wait_count -= WAIT_INCREMENT) == 0)
867 SA_DBG1(("saGetControllerInfo: Timeout!! SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1));
870 } while (((value & SCRATCH_PAD_STATE_MASK) != SCRATCH_PAD1_RDY) || ((value1 & SCRATCH_PAD_STATE_MASK) != SCRATCH_PAD2_RDY));
875 SA_DBG1(("saGetControllerInfo: timeout failure\n"));
876 ret = AGSA_RC_FW_NOT_IN_READY_STATE;
879 if (ret == AGSA_RC_SUCCESS)
881 SA_DBG1(("saGetControllerInfo: FW Ready, SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1));
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);
886 CfgTblDWIdx = MSGUCfgTblBase & SCRATCH_PAD0_OFFSET_MASK;
888 MSGUCfgTblBase = (MSGUCfgTblBase & SCRATCH_PAD0_BAR_MASK) >> SHIFT26;
890 /* convert the PCI BAR to logical bar number */
891 pcibar = (bit8)mpiGetPCIBarIndex(agRoot, MSGUCfgTblBase);
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);
903 if( smIS_SPC(agRoot))
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);
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);
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);
926 if(smIS_SPCV(agRoot))
928 controllerInfo->controllerSetting = (bit8)((siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1) & SCRATCH_PAD1_V_BOOTSTATE_MASK ) >> SHIFT4);
932 controllerInfo->controllerSetting = (bit8)(ossaHwRegReadExt(agRoot, pcibar, (bit32)CfgTblDWIdx + MAIN_HDA_FLAGS_OFFSET) & MAIN_HDA_FLAG_BITS);
934 controllerInfo->sasSpecsSupport = (ContrlCapFlag & MAIN_SAS_SUPPORT_BITS) >> SHIFT25;
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)
955 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6e");
960 /******************************************************************************/
961 /*! \brief SPC Get Controller Status Command
963 * This command sends Get Controller Status Command to SPC.
965 * \param agRoot Handles for this instance of SAS/SATA LL
966 * \param controllerStatus controller status
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
973 /*******************************************************************************/
974 GLOBAL bit32 saGetControllerStatus(
976 agsaControllerStatus_t *controllerStatus
979 bit32 ret = AGSA_RC_SUCCESS;
980 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
981 spc_GSTableDescriptor_t GSTable;
983 bit32 max_wait_count;
984 bit32 i, value, value1;
986 if (agNULL != saRoot)
988 smTraceFuncEnter(hpDBG_VERY_LOUD,"6f");
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)
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;
999 if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_3) & (OSSA_ENCRYPT_ENGINE_FAILURE_MASK | OSSA_DIF_ENGINE_FAILURE_MASK))
1001 SA_DBG1(("saGetControllerStatus: BIST error in SCRATCHPAD 3 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_3, MSGU_SCRATCH_PAD_3)));
1004 if(smIS_SPC(agRoot))
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);
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));
1020 /* check HDA mode */
1021 value = ossaHwRegReadExt(agRoot, PCIBAR3, HDA_RSP_OFFSET1MB+HDA_CMD_CODE_OFFSET) & HDA_STATUS_BITS;
1023 if (value == BOOTTLOADERHDA_IDLE)
1026 SA_DBG1(("saGetControllerStatus: HDA mode, value = 0x%x\n", value));
1027 return AGSA_RC_HDA_NO_FW_RUNNING;
1030 /* check error state */
1031 value = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_1);
1032 value1 = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_2);
1034 /* check AAP or IOP error */
1035 if ((SCRATCH_PAD1_ERR == (value & SCRATCH_PAD_STATE_MASK)) || (SCRATCH_PAD2_ERR == (value1 & SCRATCH_PAD_STATE_MASK)))
1037 if (agNULL != saRoot)
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;
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;
1056 if (agNULL != saRoot)
1058 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6f");
1060 return AGSA_RC_FW_NOT_IN_READY_STATE;
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 */
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)
1074 SA_DBG1(("saGetControllerStatus: (Reserved bit not 0) SCRATCH_PAD1 value = 0x%x\n", value));
1075 ret = AGSA_RC_FAILURE;
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)
1083 SA_DBG1(("saGetControllerStatus: (Reserved bit not 0) SCRATCH_PAD2 value = 0x%x\n", value1));
1084 ret = AGSA_RC_FAILURE;
1088 if ((max_wait_count -=WAIT_INCREMENT) == 0)
1090 SA_DBG1(("saGetControllerStatus: Timeout!! SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1));
1093 } while (((value & SCRATCH_PAD_STATE_MASK) != SCRATCH_PAD1_RDY) || ((value1 & SCRATCH_PAD_STATE_MASK) != SCRATCH_PAD2_RDY));
1095 if (!max_wait_count)
1097 SA_DBG1(("saGetControllerStatus: timeout failure\n"));
1098 ret = AGSA_RC_FAILURE;
1101 if (ret == AGSA_RC_SUCCESS)
1103 SA_DBG1(("saGetControllerStatus: FW Ready, SCRATCH_PAD1/2 value = 0x%x 0x%x\n", value, value1));
1105 /* read scratch pad0 to get PCI BAR and offset of configuration table */
1106 value = ossaHwRegRead(agRoot, MSGU_SCRATCH_PAD_0);
1108 value1 = value & SCRATCH_PAD0_OFFSET_MASK;
1110 value = (value & SCRATCH_PAD0_BAR_MASK) >> SHIFT26;
1112 /* read GST Table state */
1113 mpiReadGSTable(agRoot, &GSTable);
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);
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));
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++)
1141 controllerStatus->phyStatus[i] = GSTable.PhyState[i];
1142 controllerStatus->recoverableErrorInfo[i] = GSTable.recoverErrInfo[i];
1144 controllerStatus->tickCount0 = GSTable.MsguTcnt;
1145 controllerStatus->tickCount1 = GSTable.IopTcnt;
1146 controllerStatus->tickCount2 = GSTable.Iop1Tcnt;
1152 SA_DBG1(("saGetControllerStatus: SPCv\n" ));
1155 if(siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1) & SCRATCH_PAD1_V_RESERVED )
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)));
1159 if( si_check_V_HDA(agRoot))
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;
1171 ret = si_check_V_Ready(agRoot);
1173 if (ret == AGSA_RC_SUCCESS)
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++)
1182 controllerStatus->phyStatus[i] = GSTable.PhyState[i];
1183 controllerStatus->recoverableErrorInfo[i] = GSTable.recoverErrInfo[i];
1185 controllerStatus->tickCount0 = GSTable.MsguTcnt;
1186 controllerStatus->tickCount1 = GSTable.IopTcnt;
1187 controllerStatus->tickCount2 = GSTable.Iop1Tcnt;
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++)
1194 if( IS_SDKDATA(agRoot))
1196 if (agNULL != saRoot)
1198 controllerStatus->phyStatus[i] = ((saRoot->phys[i+8].linkstatus << SHIFT8) | saRoot->phys[i].linkstatus);
1203 controllerStatus->phyStatus[i] = 0;
1205 controllerStatus->recoverableErrorInfo[i] = GSTable.recoverErrInfo[i];
1207 controllerStatus->tickCount0 = GSTable.MsguTcnt;
1208 controllerStatus->tickCount1 = GSTable.IopTcnt;
1209 controllerStatus->tickCount2 = GSTable.Iop1Tcnt;
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)));
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 );
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 */
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;
1240 if(controllerStatus->fatalErrorInfo.errorInfo0 == 0xFFFFFFFF)
1242 ret = AGSA_RC_FAILURE;
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));
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));
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]));
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]));
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) ));
1292 Bit 0 : Active FW Image
1296 Bit 16-17 : Encryption Capability
1297 00: Not supported. Controller firmware version doesn't support encryption functionality.
1298 01: Disabled due to error. Controller firmware supports encryption however, the functionality is currently disabled due to an error. The actual cause of the error is indicated in the error code field (bits [23:16]).
1299 10: Enabled with Error. Encryption is currently enabled however, firmware encountered encryption-related error during initialization which might have caused the controller to enter SMF Security mode and/or disabled access to non-volatile memory for encryption-related information. The actual cause of the error is indicated in the error code field (bits [23:16]).
1300 11: Enabled. Encryption functionality is enabled and fully functional.
1301 Bit 18-21 : Encryption Current Security Mode
1302 0000: Security Mode Factory
1303 0001: Security Mode A
1304 0010: Security Mode B
1305 All other values are reserved.
1307 Bit 23 : Encryption AES XTS Enabled
1308 0: AES XTS is disabled.
1309 1: AES XTS is enabled
1310 Bit 24-31 : Encryption Engine Status
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]));
1323 if (agNULL != saRoot)
1325 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6f");
1331 /******************************************************************************/
1332 /*! \brief SPC Get Controller Event Log Information Command
1334 * This command sends Get Controller Event Log Information Command to SPC.
1336 * \param agRoot Handles for this instance of SAS/SATA LL
1337 * \param eventLogInfo event log information
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
1344 /*******************************************************************************/
1345 GLOBAL bit32 saGetControllerEventLogInfo(
1347 agsaControllerEventLog_t *eventLogInfo
1350 bit32 ret = AGSA_RC_SUCCESS;
1351 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1353 smTraceFuncEnter(hpDBG_VERY_LOUD,"6g");
1356 SA_ASSERT((agNULL != agRoot), "");
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;
1363 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6g");
1368 /******************************************************************************/
1369 /*! \brief SPC Set GPIO Event Setup Command
1371 * This command sends GPIO Event Setup Command to SPC.
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
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
1383 /*******************************************************************************/
1384 GLOBAL bit32 saGpioEventSetup(
1386 agsaContext_t *agContext,
1388 agsaGpioEventSetupInfo_t *gpioEventSetupInfo
1391 bit32 ret = AGSA_RC_SUCCESS;
1392 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1393 agsaIORequestDesc_t *pRequest;
1394 agsaGPIOCmd_t payload;
1396 smTraceFuncEnter(hpDBG_VERY_LOUD,"6h");
1399 SA_ASSERT((agNULL != agRoot), "");
1401 /* Get request from free IORequests */
1402 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1403 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1405 /* If no LL Control request entry available */
1406 if ( agNULL == pRequest )
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;
1413 /* If LL Control request entry avaliable */
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;
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)
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;
1440 /* return the request to free pool */
1441 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
1443 SA_DBG1(("saGpioEventSetup: saving pRequest (%p) for later use\n", pRequest));
1444 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1448 /* return the request to free pool */
1449 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1451 SA_DBG1(("saGpioEventSetup, sending IOMB failed\n" ));
1455 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1456 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6h");
1461 /******************************************************************************/
1462 /*! \brief SPC Set GPIO Pin Setup Command
1464 * This command sends GPIO Pin Setup Command to SPC.
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
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
1476 /*******************************************************************************/
1477 GLOBAL bit32 saGpioPinSetup(
1479 agsaContext_t *agContext,
1481 agsaGpioPinSetupInfo_t *gpioPinSetupInfo
1484 bit32 ret = AGSA_RC_SUCCESS;
1485 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1486 agsaIORequestDesc_t *pRequest;
1487 agsaGPIOCmd_t payload;
1489 smTraceFuncEnter(hpDBG_VERY_LOUD,"6i");
1492 SA_ASSERT((agNULL != agRoot), "");
1494 /* Get request from free IORequests */
1495 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1496 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1498 /* If no LL Control request entry available */
1499 if ( agNULL == pRequest )
1501 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1502 SA_DBG1(("saGpioPinSetup, No request from free list\n" ));
1503 return AGSA_RC_BUSY;
1505 /* If LL Control request entry avaliable */
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;
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)
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)
1534 SA_DBG1(("saGpioPinSetup: saving pRequest (%p) for later use\n", pRequest));
1535 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1539 /* return the request to free pool */
1540 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1542 SA_DBG1(("saGpioPinSetup, sending IOMB failed\n" ));
1546 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1547 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6i");
1552 /******************************************************************************/
1553 /*! \brief SPC GPIO Read Command
1555 * This command sends GPIO Read Command to SPC.
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
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
1566 /*******************************************************************************/
1567 GLOBAL bit32 saGpioRead(
1569 agsaContext_t *agContext,
1573 bit32 ret = AGSA_RC_SUCCESS;
1574 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1575 agsaIORequestDesc_t *pRequest;
1576 agsaGPIOCmd_t payload;
1578 smTraceFuncEnter(hpDBG_VERY_LOUD,"6j");
1581 SA_ASSERT((agNULL != agRoot), "");
1583 /* Get request from free IORequests */
1584 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1585 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1587 /* If no LL Control request entry available */
1588 if ( agNULL == pRequest )
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;
1595 /* If LL Control request entry avaliable */
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;
1605 /* set payload to zeros */
1606 si_memset(&payload, 0, sizeof(agsaGPIOCmd_t));
1607 /* build IOMB command and send to SPC */
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)
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)
1622 SA_DBG1(("saGpioRead: saving pRequest (%p) for later use\n", pRequest));
1623 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1627 /* return the request to free pool */
1628 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1630 SA_DBG1(("saGpioRead, sending IOMB failed\n" ));
1633 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1635 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6j");
1640 /******************************************************************************/
1641 /*! \brief SPC GPIO Write Command
1643 * This command sends GPIO Write Command to SPC.
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
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
1656 /*******************************************************************************/
1657 GLOBAL bit32 saGpioWrite(
1659 agsaContext_t *agContext,
1661 bit32 gpioWriteMask,
1662 bit32 gpioWriteValue
1665 bit32 ret = AGSA_RC_SUCCESS;
1666 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1667 agsaIORequestDesc_t *pRequest;
1668 agsaGPIOCmd_t payload;
1670 smTraceFuncEnter(hpDBG_VERY_LOUD,"6k");
1673 SA_ASSERT((agNULL != agRoot), "");
1675 /* Get request from free IORequests */
1676 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1677 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1679 /* If no LL Control request entry available */
1680 if ( agNULL == pRequest )
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;
1687 /* If LL Control request entry avaliable */
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;
1697 /* set payload to zeros */
1698 si_memset(&payload, 0, sizeof(agsaGPIOCmd_t));
1699 /* build IOMB command and send to SPC */
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)
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;
1714 /* return the request to free pool */
1715 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
1717 SA_DBG1(("saGpioWrite: saving pRequest (%p) for later use\n", pRequest));
1718 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1722 /* return the request to free pool */
1723 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1725 SA_DBG1(("saGpioWrite, sending IOMB failed\n" ));
1729 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1730 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6k");
1735 /******************************************************************************/
1736 /*! \brief SPC SAS Diagnostic Execute Command
1738 * This command sends SAS Diagnostic Execute Command to SPC.
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
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
1750 /*******************************************************************************/
1751 GLOBAL bit32 saSASDiagExecute(
1753 agsaContext_t *agContext,
1755 agsaSASDiagExecute_t *diag
1758 bit32 ret = AGSA_RC_SUCCESS;
1759 agsaLLRoot_t *saRoot = agNULL;
1760 agsaIORequestDesc_t *pRequest = agNULL;
1763 SA_ASSERT((agNULL != agRoot), "");
1765 saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1767 SA_ASSERT((agNULL != saRoot), "");
1769 smTraceFuncEnter(hpDBG_VERY_LOUD,"6m");
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 ));
1778 /* Get request from free IORequests */
1779 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1780 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1782 /* If no LL Control request entry available */
1783 if ( agNULL == pRequest )
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;
1790 /* If LL Control request entry avaliable */
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))
1801 diag->param5 = 0; /* Reserved for SPC */
1804 /* set payload to zeros */
1805 si_memset(&payload, 0, sizeof(payload));
1806 /* set payload to zeros */
1807 if(smIS_SPCV(agRoot))
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);
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);
1832 if (AGSA_RC_SUCCESS != ret)
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;
1840 /* return the request to free pool */
1841 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
1843 SA_DBG1(("saSASDiagExecute: saving pRequest (%p) for later use\n", pRequest));
1844 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1848 /* return the request to free pool */
1849 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1851 SA_DBG1(("saSASDiagExecute, sending IOMB failed\n" ));
1852 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6m");
1853 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1858 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "6m");
1859 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1863 /******************************************************************************/
1864 /*! \brief SPC SAS Diagnostic Start/End Command
1866 * This command sends SAS Diagnostic Start/End Command to SPC.
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
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
1879 /*******************************************************************************/
1880 GLOBAL bit32 saSASDiagStartEnd(
1882 agsaContext_t *agContext,
1888 bit32 ret = AGSA_RC_SUCCESS;
1889 agsaLLRoot_t *saRoot;
1890 agsaIORequestDesc_t *pRequest;
1891 agsaSASDiagStartEndCmd_t payload;
1894 SA_ASSERT((agNULL != agRoot), "");
1895 if (agRoot == agNULL)
1897 SA_DBG1(("saSASDiagStartEnd: agRoot == agNULL\n"));
1898 return AGSA_RC_FAILURE;
1900 saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
1901 SA_ASSERT((agNULL != saRoot), "");
1902 if (saRoot == agNULL)
1904 SA_DBG1(("saSASDiagStartEnd: saRoot == agNULL\n"));
1905 return AGSA_RC_FAILURE;
1908 smTraceFuncEnter(hpDBG_VERY_LOUD,"6n");
1910 SA_DBG3(("saSASDiagStartEnd, phyId 0x%x operation 0x%x\n",phyId,operation ));
1912 /* Get request from free IORequests */
1913 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1914 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1916 /* If no LL Control request entry available */
1917 if ( agNULL == pRequest )
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;
1924 /* If LL Control request entry avaliable */
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;
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)
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;
1948 /* return the request to free pool */
1949 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
1951 SA_DBG1(("saSASDiagStartEnd: saving pRequest (%p) for later use\n", pRequest));
1952 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1956 /* return the request to free pool */
1957 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1959 SA_DBG1(("saSASDiagStartEnd, sending IOMB failed\n" ));
1963 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6n");
1964 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1968 /******************************************************************************/
1969 /*! \brief Initiate a GET TIME STAMP command
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().
1974 * \param agRoot handles for this instance of SAS/SATA hardware
1975 * \param agContext the context of this API
1976 * \param queueNum queue number
1979 * - SUCCESS or FAILURE
1981 /*******************************************************************************/
1982 GLOBAL bit32 saGetTimeStamp(
1984 agsaContext_t *agContext,
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)
1995 SA_DBG1(("saGetTimeStamp: agRoot == agNULL\n"));
1996 return AGSA_RC_FAILURE;
1998 saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
1999 SA_ASSERT((agNULL != saRoot), "");
2000 if (saRoot == agNULL)
2002 SA_DBG1(("saGetTimeStamp: saRoot == agNULL\n"));
2003 return AGSA_RC_FAILURE;
2006 smTraceFuncEnter(hpDBG_VERY_LOUD,"6o");
2009 SA_ASSERT((agNULL != agRoot), "");
2011 SA_DBG3(("saGetTimeStamp: agContext %p\n", agContext));
2013 /* Get request from free IORequests */
2014 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2015 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2017 /* If no LL Control request entry available */
2018 if ( agNULL == pRequest )
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;
2025 /* If LL Control request entry avaliable */
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;
2035 /* build IOMB command and send to SPC */
2036 /* set payload to zeros */
2037 si_memset(&payload, 0, sizeof(agsaGetTimeStampCmd_t));
2040 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetTimeStampCmd_t, tag), pRequest->HTag);
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)
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;
2052 /* return the request to free pool */
2053 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
2055 SA_DBG1(("saGetTimeStamp: saving pRequest (%p) for later use\n", pRequest));
2056 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
2060 /* return the request to free pool */
2061 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2063 SA_DBG1(("saGetTimeStamp, sending IOMB failed\n" ));
2067 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2068 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6o");
2073 /******************************************************************************/
2074 /*! \brief Update IOMap Entry
2076 * This function is called to update certain fields of IOMap Entry
2078 * \param pIOMap IOMap Entry
2079 * \param HTag Host Tag
2080 * \param pRequest Request
2081 * \parma agContext Context of this API
2085 /*******************************************************************************/
2086 static void saUpdateIOMap(
2087 agsaIOMap_t *pIOMap,
2089 agsaIORequestDesc_t *pRequest,
2090 agsaContext_t *agContext
2094 pIOMap->IORequest = (void *)pRequest;
2095 pIOMap->agContext = agContext;
2098 /******************************************************************************/
2099 /*! \brief Get a request from free pool
2101 * This function gets a request from free pool
2103 * \param agRoot Handles for this instance of SAS/SATA LL
2104 * \param agsaContext Context of this command
2107 * - \e Pointer to request, in case of success
2108 * - \e NULL, in case of failure
2111 /*******************************************************************************/
2112 agsaIORequestDesc_t* saGetRequestFromFreePool(
2114 agsaContext_t *agContext
2117 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
2118 agsaIORequestDesc_t *pRequest = agNULL;
2120 /* Acquire LL_IOREQ_LOCKEQ_LOCK */
2121 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2123 /* Get request from free IORequests */
2124 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2125 if (pRequest != agNULL)
2127 /* Remove the request from free list */
2128 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
2130 /* Release LL_IOREQ_LOCKEQ_LOCK */
2131 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2133 /* Add the request to IOMap */
2134 saUpdateIOMap(&saRoot->IOMap[pRequest->HTag], pRequest->HTag, pRequest, agContext);
2135 pRequest->valid = agTRUE;
2139 /* Release LL_IOREQ_LOCKEQ_LOCK */
2140 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2146 /******************************************************************************/
2147 /*! \brief Return request to free pool
2149 * This function returns the request to free pool
2151 * \param agRoot Handles for this instance of SAS/SATA LL
2152 * \param pRequest Request to be returned
2157 /*******************************************************************************/
2158 void saReturnRequestToFreePool(
2160 agsaIORequestDesc_t *pRequest
2163 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
2165 SA_ASSERT((pRequest->valid), "pRequest->valid");
2167 /* Remove the request from IOMap */
2168 saUpdateIOMap(&saRoot->IOMap[pRequest->HTag], MARK_OFF, agNULL, agNULL);
2169 pRequest->valid = agFALSE;
2171 /* Acquire LL_IOREQ_LOCKEQ_LOCK */
2172 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2174 if (saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
2176 SA_DBG1(("saReturnRequestToFreePool: saving pRequest (%p) for later use\n", pRequest));
2177 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
2181 /* Return the request to free pool */
2182 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2185 /* Release LL_IOREQ_LOCKEQ_LOCK */
2186 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2188 /******************************************************************************/
2189 /*! \brief Initiate a serial GPIO command
2191 * This function is called to initiate a serial GPIO command to the SPC.
2192 * The completion of this function is reported in ossaSgpioCB().
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
2200 * - SUCCESS or FAILURE
2202 /*******************************************************************************/
2203 GLOBAL bit32 saSgpio(
2205 agsaContext_t *agContext,
2207 agsaSGpioReqResponse_t *pSGpioReq
2211 agsaIORequestDesc_t *pRequest = agNULL;
2212 agsaSGpioCmd_t payload = {0};
2213 bit32 ret = AGSA_RC_BUSY;
2215 smTraceFuncEnter(hpDBG_VERY_LOUD,"6t");
2218 SA_ASSERT((agNULL != agRoot), "");
2220 SA_DBG3(("saSgpio: agContext %p\n", agContext));
2222 /* Get request from free pool */
2223 pRequest = saGetRequestFromFreePool(agRoot, agContext);
2224 if (agNULL == pRequest)
2226 SA_DBG1(("saSgpio, No request from free list\n" ));
2227 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "6t");
2231 /* Set payload to zeros */
2232 si_memset(&payload, 0, sizeof(agsaSGpioCmd_t));
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);
2243 if (SA_SAS_SMP_WRITE_GPIO_REGISTER == pSGpioReq->function)
2245 for (i = 0; i < pSGpioReq->registerCount; i++)
2247 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSGpioCmd_t, writeData) + (i * 4), pSGpioReq->readWriteData[i]);
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)
2255 /* Return the request to free pool */
2256 saReturnRequestToFreePool(agRoot, pRequest);
2257 SA_DBG1(("saSgpio, sending IOMB failed\n" ));
2260 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6t");
2266 /******************************************************************************/
2267 /*! \brief for spc card read Error Registers to memory if error occur
2269 * This function is called to get erorr registers content to memory if error occur.
2271 * \param agRoot handles for this instance of SAS/SATA hardware
2275 /*******************************************************************************/
2276 LOCAL void siSpcGetErrorContent(
2281 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
2282 bit32 value, value1;
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))
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);
2299 /******************************************************************************/
2300 /*! \brief for spcv card read Error Registers to memory if error occur
2302 * This function is called to get erorr registers content to memory if error occur.
2304 * \param agRoot handles for this instance of SAS/SATA hardware
2308 /*******************************************************************************/
2309 LOCAL void siSpcvGetErrorContent(
2314 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
2317 smTraceFuncEnter(hpDBG_VERY_LOUD,"2d");
2318 value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1);
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)
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);
2332 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2d");
2335 #define LEFT_BYTE_FAIL(x, v) \
2336 do {if( (x) < (v) ) return AGSA_RC_FAILURE; } while(0);
2338 LOCAL bit32 siDumpInboundQueue(
2344 bit8 * _buf = buffer;
2345 si_memcpy( _buf, (bit8*)(q->memoryRegion.virtPtr) + length, 128*256);
2346 return AGSA_RC_SUCCESS;
2349 LOCAL bit32 siDumpOutboundQueue(
2354 bit8 * _buf = buffer;
2355 si_memcpy( _buf, (bit8*)(q->memoryRegion.virtPtr) + length, 128*256);
2356 return AGSA_RC_SUCCESS;
2360 LOCAL bit32 siWaitForNonFatalTransfer( agsaRoot_t *agRoot,bit32 pcibar)
2362 bit32 status = AGSA_RC_SUCCESS;
2364 bit32 max_wait_time;
2365 bit32 max_wait_count;
2366 smTraceFuncEnter(hpDBG_VERY_LOUD,"2c");
2368 SA_DBG4(("siWaitForNonFatalTransfer:0 IBDBS 0x%x\n",ossaHwRegReadExt(agRoot,0 ,V_Inbound_Doorbell_Set_Register ) ));
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 ) ));
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;
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)
2386 SA_DBG1(("siWaitForNonFatalTransfer:Timeout IBDBS 0x%x\n",ossaHwRegReadExt(agRoot,0 ,V_Inbound_Doorbell_Set_Register ) ));
2387 status = AGSA_RC_FAILURE;
2390 SA_DBG4(("siWaitForNonFatalTransfer:3 IBDBS 0x%x\n",ossaHwRegReadExt(agRoot,0 ,V_Inbound_Doorbell_Set_Register ) ));
2392 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2c");
2396 LOCAL bit32 siWaitForFatalTransfer( agsaRoot_t *agRoot,bit32 pcibar)
2398 bit32 status = AGSA_RC_SUCCESS;
2400 bit32 ErrorTableOffset;
2401 bit32 max_wait_time;
2402 bit32 max_wait_count;
2404 smTraceFuncEnter(hpDBG_VERY_LOUD,"2o");
2406 ErrorTableOffset = siGetTableOffset( agRoot, MAIN_MERRDCTO_MERRDCES );
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)));
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
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 ) ));
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;
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)
2432 SA_DBG1(("siWaitForFatalTransfer : 1 Timeout\n"));
2433 status = AGSA_RC_FAILURE;
2436 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2o");
2442 LOCAL bit32 siFatalErrorBuffer(
2444 agsaForensicData_t *forensicData
2447 bit32 status = AGSA_RC_FAILURE;
2449 bit32 ErrorTableOffset;
2450 bit32 Accum_len = 0;
2452 agsaLLRoot_t *saRoot;
2454 SA_ASSERT( (agNULL != agRoot), "");
2455 saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
2456 SA_ASSERT( (agNULL != saRoot), "saRoot");
2457 if(agNULL == saRoot )
2459 SA_DBG1(("siFatalErrorBuffer: agNULL saRoot\n"));
2463 if(saRoot->ResetFailed )
2465 SA_DBG1(("siFatalErrorBuffer: saRoot->ResetFailed\n"));
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 ));
2475 pcibar = siGetPciBar(agRoot);
2476 ErrorTableOffset = siGetTableOffset( agRoot, MAIN_MERRDCTO_MERRDCES );
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) ));
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.
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:
2496 if(forensicData->BufferType.dataBuf.directOffset == 0)
2498 /* start to get data */
2500 a. Program the MEMBASE II Shifting Register with 0x00.
2502 ossaHwRegWriteExt(agRoot, pcibar,V_MEMBASE_II_ShiftRegister, saRoot->FatalForensicShiftOffset); // set base to zero
2504 saRoot->ForensicLastOffset =0;
2505 saRoot->FatalForensicStep = 0;
2506 saRoot->FatalBarLoc = 0;
2507 saRoot->FatalForensicShiftOffset = 0;
2509 SA_DBG1(("siFatalErrorBuffer: directOffset zero SCRATCH_PAD1 0x%x\n", siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1) ));
2512 /* Read until Accum_len is retrived */
2513 Accum_len = ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN);
2515 SA_DBG2(("siFatalErrorBuffer: Accum_len 0x%x\n", Accum_len));
2516 if(Accum_len == 0xFFFFFFFF)
2518 SA_DBG1(("siFatalErrorBuffer: Possible PCI issue 0x%x not expected\n", Accum_len));
2522 if( Accum_len == 0 || Accum_len >=0x100000 )
2524 SA_DBG1(("siFatalErrorBuffer: Accum_len == saRoot->FatalCurrentLength 0x%x\n", Accum_len));
2525 return(IOCTL_ERROR_NO_FATAL_ERROR);
2528 if(saRoot->FatalForensicStep == 0) /* PM Step 1a and 1b */
2531 if(forensicData->BufferType.dataBuf.directData)
2533 siPciCpyMem(agRoot,saRoot->FatalBarLoc ,forensicData->BufferType.dataBuf.directData,forensicData->BufferType.dataBuf.directLen ,1 );
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;
2540 if(saRoot->ForensicLastOffset >= Accum_len)
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
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;
2556 if(saRoot->FatalBarLoc < (64*1024))
2558 SA_DBG2(("siFatalErrorBuffer: In same 64k FatalBarLoc 0x%x\n",saRoot->FatalBarLoc ));
2559 status = AGSA_RC_SUCCESS;
2563 c. Increment the MEMBASE II Shifting Register value by 0x100.
2565 saRoot->FatalForensicShiftOffset+= 0x100;
2566 ossaHwRegWriteExt(agRoot, pcibar,V_MEMBASE_II_ShiftRegister, saRoot->FatalForensicShiftOffset);
2567 saRoot->FatalBarLoc = 0;
2569 SA_DBG1(("siFatalErrorBuffer: Get next bar data 0x%x\n",saRoot->FatalForensicShiftOffset));
2571 status = AGSA_RC_SUCCESS;
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",
2576 forensicData->BufferType.dataBuf.directData,
2577 forensicData->BufferType.dataBuf.directOffset,
2578 forensicData->BufferType.dataBuf.directLen,
2579 forensicData->BufferType.dataBuf.readLen ));
2583 if(saRoot->FatalForensicStep == 1)
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
2591 a. Program the MEMBASE II Shifting Register with 0x00.
2593 SA_DBG1(("siFatalErrorBuffer: FatalForensicStep 1 Accum_len 0x%X MPI_FATAL_EDUMP_TABLE_ACCUM_LEN 0x%x\n",
2595 ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN)));
2597 saRoot->FatalForensicShiftOffset = 0; /* location in 64k region */
2599 b. Read 64K of the debug data.
2601 ossaHwRegWriteExt(agRoot, pcibar,V_MEMBASE_II_ShiftRegister ,saRoot->FatalForensicShiftOffset);
2602 SA_DBG1(("siFatalErrorBuffer: FatalForensicStep 1\n" ));
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.
2610 siWaitForFatalTransfer( agRoot,pcibar);
2613 d. Read the next 64K of the debug data.
2615 saRoot->FatalForensicStep = 0;
2617 if( ossaHwRegReadExt(agRoot,pcibar ,ErrorTableOffset+ MPI_FATAL_EDUMP_TABLE_STATUS) != MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE )
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 )));
2623 2. Write FDDSTAT to 0x00000000 but preserve the Accumulative Debug Data Length Transferred
2626 ossaHwRegWriteExt(agRoot,pcibar ,ErrorTableOffset+MPI_FATAL_EDUMP_TABLE_STATUS, 0 );
2628 4. If FDDSTAT is 0x00000002, repeat steps 2 and 3 until you reach this step with FDDSTAT being
2629 equal to 0x00000003.
2636 When FDDSTAT equals 0x00000003 and ACCDDLEN is unchanged, then
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.
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)));
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)));
2657 forensicData->BufferType.dataBuf.readLen = 0xFFFFFFFF;
2658 status = AGSA_RC_SUCCESS;
2664 SA_DBG3(("siFatalErrorBuffer:status 0x%x %p directOffset 0x%x directLen 0x%x readLen 0x%x\n",
2666 forensicData->BufferType.dataBuf.directData,
2667 forensicData->BufferType.dataBuf.directOffset,
2668 forensicData->BufferType.dataBuf.directLen,
2669 forensicData->BufferType.dataBuf.readLen ));
2671 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2a");
2675 LOCAL bit32 siNonFatalErrorBuffer(
2677 agsaForensicData_t *forensicData
2680 bit32 status = AGSA_RC_FAILURE;
2682 bit32 ErrorTableOffset;
2687 bit32 max_wait_time;
2688 bit32 max_wait_count;
2689 agsaLLRoot_t *saRoot;
2691 SA_ASSERT( (agNULL != agRoot), "agRoot");
2692 saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
2693 SA_ASSERT( (agNULL != saRoot), "saRoot");
2694 if(agNULL == saRoot )
2696 SA_DBG1(("siNonFatalErrorBuffer: agNULL saRoot\n"));
2700 smTraceFuncEnter(hpDBG_VERY_LOUD,"2b");
2701 pcibar = siGetPciBar(agRoot);
2702 ErrorTableOffset = siGetTableOffset( agRoot, MAIN_MERRDCTO_MERRDCES );
2704 SA_DBG4(("siNonFatalErrorBuffer: ErrorTableOffset 0x%x\n",ErrorTableOffset ));
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)));
2713 biggest = saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].totalLength;
2715 if(biggest >= forensicData->BufferType.dataBuf.directLen )
2717 biggest = forensicData->BufferType.dataBuf.directLen;
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);
2727 if(saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].virtPtr)
2729 si_memset(saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].virtPtr, 0, biggest);
2733 SA_DBG1(("siNonFatalErrorBuffer: Error\n" ));
2734 return(AGSA_RC_FAILURE);
2738 if(forensicData->BufferType.dataBuf.directOffset)
2740 /* Write FDDSTAT and ACCDDLEN to zero step 2 */
2741 ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_STATUS, 0);
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 ));
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) ));
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);
2760 saRoot->ForensicLastOffset = 0;
2762 /* WriteACCDDLEN for error interface Step 0 */
2763 /*ossaHwRegWriteExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN ,0);*/
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);
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);
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)));
2781 if( 0 != ossaHwRegReadExt(agRoot, pcibar, ErrorTableOffset + MPI_FATAL_EDUMP_TABLE_ACCUM_LEN))
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)));
2789 if( saRoot->ForensicLastOffset == 0xFFFFFFFF)
2791 forensicData->BufferType.dataBuf.readLen = 0xFFFFFFFF;
2792 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2b");
2793 return(AGSA_RC_SUCCESS);
2797 /* Write bit7 of inbound doorbell set register and wait for complete step 3 and 4*/
2798 siWaitForNonFatalTransfer(agRoot,pcibar);
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) ));
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 );
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 )
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) ));
2819 } while ( ready != MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE && (max_wait_count -= WAIT_INCREMENT));
2822 if(max_wait_count == 0 || ready == MPI_FATAL_EDUMP_TABLE_STAT_DMA_FAILED)
2824 status = AGSA_RC_FAILURE;
2825 SA_DBG1(("siNonFatalErrorBuffer: timeout waiting ready\n"));
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)
2832 SA_DBG1(("siNonFatalErrorBuffer:ready 0x%x readLen 0x%x\n",ready ,forensicData->BufferType.dataBuf.readLen));
2833 saRoot->ForensicLastOffset = 0xFFFFFFFF;
2837 saRoot->ForensicLastOffset = forensicData->BufferType.dataBuf.directOffset;
2840 if(forensicData->BufferType.dataBuf.directData )
2842 si_memcpy(forensicData->BufferType.dataBuf.directData, saRoot->memoryAllocated.agMemory[HDA_DMA_BUFFER].virtPtr,biggest);
2844 status = AGSA_RC_SUCCESS;
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");
2857 LOCAL bit32 siGetForensicData(
2859 agsaContext_t *agContext,
2860 agsaForensicData_t *forensicData
2863 bit32 status = AGSA_RC_FAILURE;
2864 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
2866 smTraceFuncEnter(hpDBG_VERY_LOUD,"2Z");
2868 if(forensicData->DataType == TYPE_GSM_SPACE)
2870 #define _1M 0x100000
2871 if( forensicData->BufferType.gsmBuf.directLen >= _1M )
2873 return AGSA_RC_FAILURE;
2876 if(forensicData->BufferType.dataBuf.readLen)
2878 SA_DBG1(("siGetForensicData: Incorrect readLen 0x%08X\n", forensicData->BufferType.dataBuf.readLen));
2879 forensicData->BufferType.dataBuf.readLen = forensicData->BufferType.dataBuf.directLen;
2881 if( forensicData->BufferType.dataBuf.directOffset >= ONE_MEGABYTE )
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);
2887 if(smIS_SPC(agRoot))
2889 if( forensicData->BufferType.dataBuf.directLen >= SIXTYFOURKBYTE )
2891 SA_DBG1(("siGetForensicData directLen too large !\n"));
2892 return AGSA_RC_FAILURE;
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 ));
2900 /* Shift BAR4 original address */
2901 if (AGSA_RC_FAILURE == siBar4Shift(agRoot, BAR_SHIFT_GSM_OFFSET + forensicData->BufferType.dataBuf.directOffset))
2903 SA_DBG1(("siGSMDump:Shift Bar4 to 0x%x failed\n", 0x0));
2904 return AGSA_RC_FAILURE;
2908 //if( forensicData->BufferType.dataBuf.directOffset >= ONE_MEGABYTE )
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);
2914 forensicData->BufferType.gsmBuf.directOffset = 0;
2916 status = siGSMDump( agRoot,
2917 forensicData->BufferType.gsmBuf.directOffset,
2918 forensicData->BufferType.gsmBuf.directLen,
2919 forensicData->BufferType.gsmBuf.directData );
2921 if(status == AGSA_RC_SUCCESS)
2923 forensicData->BufferType.dataBuf.readLen = forensicData->BufferType.dataBuf.directLen;
2926 if( forensicData->BufferType.dataBuf.directOffset == 0 )
2928 SA_DBG1(("siGetForensicData: TYPE_GSM_SPACE readLen 0x%08X\n", forensicData->BufferType.dataBuf.readLen));
2930 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2Z");
2934 else if(forensicData->DataType == TYPE_INBOUND_QUEUE )
2936 mpiICQueue_t *circularQ = NULL;
2937 SA_DBG2(("siGetForensicData: TYPE_INBOUND \n"));
2939 if(forensicData->BufferType.queueBuf.queueIndex >=AGSA_MAX_INBOUND_Q )
2941 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2Z");
2942 return AGSA_RC_FAILURE;
2944 circularQ = &saRoot->inboundQueue[forensicData->BufferType.queueBuf.queueIndex];
2945 status = siDumpInboundQueue( forensicData->BufferType.queueBuf.directData,
2946 forensicData->BufferType.queueBuf.directLen,
2948 smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "2Z");
2951 else if(forensicData->DataType == TYPE_OUTBOUND_QUEUE )
2952 //else if( forensicData->BufferType.queueBuf.queueType == TYPE_OUTBOUND_QUEUE )
2954 mpiOCQueue_t *circularQ = NULL;
2955 SA_DBG2(("siGetForensicData: TYPE_OUTBOUND\n"));
2957 if(forensicData->BufferType.queueBuf.queueIndex >= AGSA_MAX_OUTBOUND_Q )
2959 smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "2Z");
2960 return AGSA_RC_FAILURE;
2963 circularQ = &saRoot->outboundQueue[forensicData->BufferType.queueBuf.queueIndex];
2964 status = siDumpOutboundQueue(forensicData->BufferType.queueBuf.directData,
2965 forensicData->BufferType.queueBuf.directLen,
2967 smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "2Z");
2971 else if(forensicData->DataType == TYPE_NON_FATAL )
2973 // if(smIS_SPCV(agRoot))
2975 SA_DBG2(("siGetForensicData:TYPE_NON_FATAL \n"));
2976 status = siNonFatalErrorBuffer(agRoot,forensicData);
2978 smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "2Z");
2981 else if(forensicData->DataType == TYPE_FATAL )
2983 // if(smIS_SPCV(agRoot))
2985 SA_DBG2(("siGetForensicData:TYPE_NON_FATAL \n"));
2986 status = siFatalErrorBuffer(agRoot,forensicData );
2988 smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "2Z");
2993 SA_DBG1(("siGetForensicData receive error parameter!\n"));
2994 smTraceFuncExit(hpDBG_VERY_LOUD, 'h', "2Z");
2995 return AGSA_RC_FAILURE;
2997 smTraceFuncExit(hpDBG_VERY_LOUD, 'i', "2Z");
3003 //GLOBAL bit32 saGetForensicData(
3004 bit32 saGetForensicData(
3006 agsaContext_t *agContext,
3007 agsaForensicData_t *forensicData
3011 status = siGetForensicData(agRoot, agContext, forensicData);
3012 ossaGetForensicDataCB(agRoot, agContext, status, forensicData);
3016 bit32 saGetIOErrorStats(
3018 agsaContext_t *agContext,
3022 agsaLLRoot_t *saRoot = (agsaLLRoot_t*)agRoot->sdkData;
3023 bit32 status = AGSA_RC_SUCCESS;
3025 ossaGetIOErrorStatsCB(agRoot, agContext, status, &saRoot->IoErrorCount);
3029 /* clear IO error counter */
3030 si_memset(&saRoot->IoErrorCount, 0, sizeof(agsaIOErrorEventStats_t));
3036 bit32 saGetIOEventStats(
3038 agsaContext_t *agContext,
3042 agsaLLRoot_t *saRoot = (agsaLLRoot_t*)agRoot->sdkData;
3043 bit32 status = AGSA_RC_SUCCESS;
3045 ossaGetIOEventStatsCB(agRoot, agContext, status, &saRoot->IoEventCount);
3049 /* clear IO event counter */
3050 si_memset(&saRoot->IoEventCount, 0, sizeof(agsaIOErrorEventStats_t));
3056 /******************************************************************************/
3057 /*! \brief Initiate a GET REGISTER DUMP command
3059 * This function is called to Get Register Dump from the SPC.
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
3067 * - SUCCESS or FAILURE
3069 /*******************************************************************************/
3070 //GLOBAL bit32 saGetRegisterDump(
3071 bit32 saGetRegisterDump(
3073 agsaContext_t *agContext,
3075 agsaRegDumpInfo_t *regDumpInfo
3078 agsaLLRoot_t *saRoot = agNULL;
3079 bit32 ret = AGSA_RC_SUCCESS;
3080 // bit32 value, value1;
3082 smTraceFuncEnter(hpDBG_VERY_LOUD,"6p");
3085 SA_ASSERT((agNULL != agRoot), "");
3087 saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
3089 SA_ASSERT((agNULL != saRoot), "");
3092 SA_ASSERT((agNULL != regDumpInfo), "");
3094 SA_DBG3(("saGetRegisterDump: agContext %p\n", agContext));
3096 if (regDumpInfo->regDumpSrc > 3)
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;
3106 switch(regDumpInfo->regDumpSrc)
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)
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);
3118 /* Last 1MB data from GSMDUMP, contains GSM_SM info*/
3120 if (regDumpInfo->regDumpNum == GET_GSM_SM_INFO)
3122 /* GSM_SM - total 1 Mbytes */
3124 if(smIS_SPC(agRoot))
3126 offset = regDumpInfo->regDumpOffset + SPC_GSM_SM_OFFSET;
3127 }else if(smIS_SPCV(agRoot))
3129 offset = regDumpInfo->regDumpOffset + SPCV_GSM_SM_OFFSET;
3132 SA_DBG1(("saGetRegisterDump: the device type is not support\n"));
3133 return AGSA_RC_FAILURE;
3136 ret = siGSMDump(agRoot, offset, regDumpInfo->directLen, regDumpInfo->directData);
3137 /* CB error for Register Dump */
3138 ossaGetRegisterDumpCB(agRoot, agContext, ret);
3142 /* check fatal errors */
3143 if(smIS_SPC(agRoot)) {
3144 siSpcGetErrorContent(agRoot);
3146 else if(smIS_SPCV(agRoot)) {
3147 siSpcvGetErrorContent(agRoot);
3149 /* Then read from local copy */
3150 if (regDumpInfo->directLen > REGISTER_DUMP_BUFF_SIZE)
3152 SA_DBG1(("saGetRegisterDump, Request too many bytes %d\n",
3153 regDumpInfo->directLen));
3154 regDumpInfo->directLen = REGISTER_DUMP_BUFF_SIZE;
3157 if (regDumpInfo->regDumpNum == 0)
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);
3163 else if( regDumpInfo->regDumpNum == 1)
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);
3169 SA_DBG1(("saGetRegisterDump, the regDumpNum value is wrong %x\n",
3170 regDumpInfo->regDumpNum));
3173 /* CB for Register Dump */
3174 ossaGetRegisterDumpCB(agRoot, agContext, OSSA_SUCCESS);
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);
3192 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6p");
3197 /******************************************************************************/
3198 /*! \brief Initiate a GET REGISTER DUMP from GSM command
3200 * This function is called to Get Register Dump from the GSM of SPC.
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
3209 * - SUCCESS or FAILURE
3211 /*******************************************************************************/
3212 //GLOBAL bit32 siGetRegisterDumpGSM(
3213 bit32 siGetRegisterDumpGSM(
3215 void *destinationAddress,
3217 bit32 regDumpOffset,
3221 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
3222 bit32 ret = AGSA_RC_SUCCESS;
3223 bit32 rDumpOffset, rDumpLen; //, rDumpValue;
3226 smTraceFuncEnter(hpDBG_VERY_LOUD,"2V");
3229 SA_ASSERT((agNULL != agRoot), "");
3231 dst = (bit8 *)destinationAddress;
3235 SA_DBG1(("siGetRegisterDump, regDumpNum %d is invalid\n", regDumpNum));
3236 return AGSA_RC_FAILURE;
3241 rDumpOffset = saRoot->mainConfigTable.FatalErrorDumpOffset0;
3242 rDumpLen = saRoot->mainConfigTable.FatalErrorDumpLength0;
3246 rDumpOffset = saRoot->mainConfigTable.FatalErrorDumpOffset1;
3247 rDumpLen = saRoot->mainConfigTable.FatalErrorDumpLength1;
3252 SA_DBG1(("siGetRegisterDump, Request too many bytes %d, rDumpLen %d\n", len, rDumpLen));
3256 if (regDumpOffset >= len)
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;
3263 /* adjust length to dword boundary */
3266 len = (len/4 + 1) * 4;
3269 ret = siGSMDump(agRoot, rDumpOffset, len, dst);
3270 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2V");
3275 /******************************************************************************/
3276 /*! \brief SPC Get NVMD Command
3278 * This command sends GET_NVMD_DATA Command to SPC.
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
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
3290 /*******************************************************************************/
3291 //GLOBAL bit32 saGetNVMDCommand(
3292 bit32 saGetNVMDCommand(
3294 agsaContext_t *agContext,
3296 agsaNVMDData_t *NVMDInfo
3299 bit32 ret = AGSA_RC_SUCCESS;
3302 SA_ASSERT((agNULL != agRoot), "");
3304 /* build IOMB command and send to SPC */
3305 ret = mpiGetNVMDCmd(agRoot, agContext, NVMDInfo, queueNum);
3310 /******************************************************************************/
3311 /*! \brief SPC Set NVMD Command
3313 * This command sends SET_NVMD_DATA Command to SPC.
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
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
3325 /*******************************************************************************/
3326 //GLOBAL bit32 saSetNVMDCommand(
3327 bit32 saSetNVMDCommand(
3329 agsaContext_t *agContext,
3331 agsaNVMDData_t *NVMDInfo
3334 bit32 ret = AGSA_RC_SUCCESS;
3337 SA_ASSERT((agNULL != agRoot), "");
3339 /* build IOMB command and send to SPC */
3340 ret = mpiSetNVMDCmd(agRoot, agContext, NVMDInfo, queueNum);
3346 GLOBAL bit32 saSendSMPIoctl(
3348 agsaDevHandle_t *agDevHandle,
3350 agsaSMPFrame_t *pSMPFrame,
3351 ossaSMPCompletedCB_t agCB
3354 bit32 ret = AGSA_RC_SUCCESS;
3355 //bit32 IR_IP_OV_res_phyId_DPdLen_res = 0;
3358 agsaIORequestDesc_t *pRequest;
3361 agsaDeviceDesc_t *pDevice;
3362 bit8 using_reserved = agFALSE;
3364 mpiICQueue_t *circularQ;
3365 agsaLLRoot_t *saRoot = agNULL;
3366 // agsaDevHandle_t *agDevHandle;
3368 saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
3369 SA_ASSERT((agNULL != saRoot), "");
3372 SA_ASSERT((agNULL != agRoot), "");
3376 /* Get request from free IO Requests */
3377 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3378 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/
3380 /* If no LL IO request entry available */
3381 if ( agNULL == pRequest )
3383 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests));
3385 if(agNULL != pRequest)
3387 using_reserved = agTRUE;
3388 SA_DBG1(("saSMPStart, using saRoot->freeReservedRequests\n"));
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;
3399 inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
3400 outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
3405 SA_ASSERT((agNULL != agDevHandle), "");
3406 /* Find the outgoing port for the device */
3407 if (agNULL == agDevHandle->sdkData)
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;
3416 pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
3418 pPort = pDevice->pPort;
3422 /* If free IOMB avaliable */
3423 /* Remove the request from free list */
3424 if( using_reserved )
3426 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
3430 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
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);
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;
3447 /* Set request to the sdkData of agIORequest */
3448 // agIORequest->sdkData = pRequest;
3450 /* save tag to IOMap */
3451 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
3452 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
3454 #ifdef SA_LL_IBQ_PROTECT
3455 ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
3456 #endif /* SA_LL_IBQ_PROTECT */
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);
3463 if (AGSA_RC_FAILURE == retVal)
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);
3475 SA_DBG1(("saSMPStart, error when get free IOMB\n"));
3476 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "9a");
3477 return AGSA_RC_FAILURE;
3480 /* return busy if inbound queue is full */
3481 if (AGSA_RC_BUSY == retVal)
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);
3493 SA_DBG1(("saSMPStart, no more IOMB\n"));
3494 smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "9a");
3495 return AGSA_RC_BUSY;
3497 #ifdef SA_LL_IBQ_PROTECT
3498 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
3499 #endif /* SA_LL_IBQ_PROTECT */
3502 if(smIS_SPC(agRoot))
3504 agsaSMPCmd_t payload;
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);
3515 /*Indirect request and response*/
3516 if (smpFrameFlagIndirectResponse & pSMPFrame->flag && smpFrameFlagIndirectPayload & pSMPFrame->flag) /* */
3519 SA_DBG2(("saSMPStart:V Indirect payload and indirect response\n"));
3521 /* Indirect Response mode */
3522 pRequest->IRmode = INDIRECT_MODE;
3523 IR_IP_OV_res_phyId_DPdLen_res = 3;
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));
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));
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 */
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 */
3552 ret = mpiSMPCmd(agRoot, pMessage, OPC_INB_SMP_REQUEST, (agsaSMPCmd_t *)payload_ptr, inq, outq);
3554 #ifdef SA_LL_IBQ_PROTECT
3555 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
3556 #endif /* SA_LL_IBQ_PROTECT */
3560 else /* IOMB is different for SPCV SMP */
3562 agsaSMPCmd_V_t vpayload;
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) );
3572 /*Indirect request and response*/
3573 if (smpFrameFlagIndirectResponse & pSMPFrame->flag && smpFrameFlagIndirectPayload & pSMPFrame->flag) /* */
3576 SA_DBG2(("saSMPStart:V Indirect payload and indirect response\n"));
3578 /* Indirect Response mode */
3579 pRequest->IRmode = INDIRECT_MODE;
3580 IR_IP_OV_res_phyId_DPdLen_res = 3;
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));
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));
3594 /*Direct request and indirect response*/
3595 else if (smpFrameFlagIndirectResponse & pSMPFrame->flag ) /* */
3598 SA_DBG2(("saSMPStart:V Direct payload and indirect response\n"));
3599 IR_IP_OV_res_phyId_DPdLen_res = (pSMPFrame->outFrameLen << SHIFT16) | pSMPFrame->flag;
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));
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 */
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);
3625 #ifdef SA_LL_IBQ_PROTECT
3626 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
3627 #endif /* SA_LL_IBQ_PROTECT */
3637 /******************************************************************************/
3638 /*! \brief Reconfiguration of SAS Parameters Command
3640 * This command Reconfigure the SAS parameters to SPC.
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
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
3652 /*******************************************************************************/
3653 //GLOBAL bit32 saReconfigSASParams(
3654 bit32 saReconfigSASParams(
3656 agsaContext_t *agContext,
3658 agsaSASReconfig_t *agSASConfig
3661 bit32 ret = AGSA_RC_SUCCESS;
3664 SA_ASSERT((agNULL != agRoot), "");
3666 if(smIS_SPCV(agRoot))
3668 SA_DBG1(("saReconfigSASParams: AGSA_RC_FAILURE for SPCv\n" ));
3669 return(AGSA_RC_FAILURE);
3672 /* build IOMB command and send to SPC */
3673 ret = mpiSasReinitializeCmd(agRoot, agContext, agSASConfig, queueNum);
3678 /******************************************************************************/
3679 /*! \brief Dump GSM registers from the controller
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
3687 * - \e AGSA_RC_SUCCESS saGSMDump is successfully
3688 * - \e AGSA_RC_FAILURE saGSMDump is not successfully
3691 /*******************************************************************************/
3692 //LOCAL bit32 siGSMDump(
3695 bit32 gsmDumpOffset,
3700 bit32 value, rem, offset = 0;
3701 bit32 i, workOffset, dwLength;
3704 SA_DBG1(("siGSMDump: gsmDumpOffset 0x%x length 0x%x\n", gsmDumpOffset, length));
3706 /* check max is 64k chunks */
3707 if (length > (64 * 1024))
3709 SA_DBG1(("siGSMDump: Max length is greater than 64K bytes 0x%x\n", length));
3710 return AGSA_RC_FAILURE;
3713 if (gsmDumpOffset & 3)
3715 SA_DBG1(("siGSMDump: Not allow NON_DW Boundary 0x%x\n", gsmDumpOffset));
3716 return AGSA_RC_FAILURE;
3719 if ((gsmDumpOffset + length) > ONE_MEGABYTE)
3721 SA_DBG1(("siGSMDump: Out of GSM end address boundary 0x%x\n", (gsmDumpOffset+length)));
3722 return AGSA_RC_FAILURE;
3725 if( smIS_SPCV(agRoot))
3729 else if( smIS_SPC(agRoot))
3735 SA_DBG1(("siGSMDump: device type is not supported"));
3736 return AGSA_RC_FAILURE;
3739 workOffset = gsmDumpOffset & 0xFFFF0000;
3740 offset = gsmDumpOffset & 0x0000FFFF;
3741 gsmDumpOffset = workOffset;
3743 dst = (bit8 *)directData;
3745 /* adjust length to dword boundary */
3747 dwLength = length >> 2;
3749 for (i =0; i < dwLength; i++)
3751 if((workOffset + offset) > length )
3755 value = ossaHwRegReadExt(agRoot, bar, (workOffset + offset) & 0x0000FFFF);
3757 si_memcpy(dst, &value, 4);
3764 value = ossaHwRegReadExt(agRoot, bar, (workOffset + offset) & 0x0000FFFF);
3765 /* xfr for non_dw */
3768 si_memcpy(dst, &value, rem);
3772 /* Shift back to BAR4 original address */
3773 if (AGSA_RC_FAILURE == siBar4Shift(agRoot, 0x0))
3775 SA_DBG1(("siGSMDump:Shift Bar4 to 0x%x failed\n", 0x0));
3776 return AGSA_RC_FAILURE;
3779 return AGSA_RC_SUCCESS;
3782 //GLOBAL bit32 saPCIeDiagExecute(
3783 bit32 saPCIeDiagExecute(
3785 agsaContext_t *agContext,
3787 agsaPCIeDiagExecute_t *diag)
3789 bit32 ret = AGSA_RC_SUCCESS;
3790 agsaLLRoot_t *saRoot = agNULL;
3791 agsaIORequestDesc_t *pRequest;
3794 smTraceFuncEnter(hpDBG_VERY_LOUD,"6r");
3797 SA_ASSERT((agNULL != agRoot), "");
3799 saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
3801 SA_ASSERT((agNULL != saRoot), "");
3802 SA_ASSERT((agNULL != diag), "");
3806 SA_DBG1(("saPCIeDiagExecute, diag->len Zero\n"));
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",
3824 diag->udtArray[5] ));
3826 SA_DBG1(("saPCIeDiagExecute, %02X %02X %02X %02X %02X %02X\n",
3832 diag->udrtArray[5]));
3835 /* Get request from free IORequests */
3836 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3837 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
3839 /* If no LL Control request entry available */
3840 if ( agNULL == pRequest )
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;
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;
3855 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3857 /* set payload to zeros */
3858 si_memset(&payload, 0, sizeof(payload));
3860 if(smIS_SPCV(agRoot))
3862 bit32 UDTR1_UDT0 ,UDT5_UDT2,UDTR5_UDTR2;
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]);
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);
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);
3897 if (AGSA_RC_SUCCESS != ret)
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;
3904 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3905 pRequest->valid = agFALSE;
3907 /* return the request to free pool */
3908 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
3910 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3912 SA_DBG1(("saPCIeDiagExecute, sending IOMB failed\n" ));
3913 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "6r");
3918 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "6r");
3922 //GLOBAL bit32 saGetDFEData(
3925 agsaContext_t *agContext,
3932 bit32 ret = AGSA_RC_SUCCESS;
3933 agsaLLRoot_t *saRoot = agNULL;
3934 agsaIORequestDesc_t *pRequest = agNULL;
3936 bit32 reserved_In_Ln;
3938 smTraceFuncEnter(hpDBG_VERY_LOUD,"2X");
3940 SA_ASSERT((agNULL != agRoot), "");
3941 saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
3942 SA_ASSERT((agNULL != saRoot), "");
3943 SA_ASSERT((agNULL != agSgl), "");
3945 /* Get request from free IORequests */
3946 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3947 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
3949 /* If no LL Control request entry available */
3950 if ( agNULL == pRequest )
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;
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;
3965 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
3967 /* set payload to zeros */
3968 si_memset(&payload, 0, sizeof(payload));
3970 if(smIS_SPCV(agRoot))
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);
3985 /* SPC does not support this command */
3986 ret = AGSA_RC_FAILURE;
3989 if (AGSA_RC_SUCCESS != ret)
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;
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);
4002 SA_DBG1(("saPCIeDiagExecute, sending IOMB failed\n" ));
4003 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2X");
4007 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2X");