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