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