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 4011