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