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 saphy.c 24 * \brief The file implements the functions to Start, Stop a phy 25 * 26 * 27 */ 28 /******************************************************************************/ 29 #include <sys/cdefs.h> 30 #include <dev/pms/config.h> 31 32 #include <dev/pms/RefTisa/sallsdk/spc/saglobal.h> 33 #ifdef SA_ENABLE_TRACE_FUNCTIONS 34 #ifdef siTraceFileID 35 #undef siTraceFileID 36 #endif 37 #define siTraceFileID 'K' 38 #endif 39 40 41 extern bit32 gFPGA_TEST; 42 /******************************************************************************/ 43 /*! \brief Start a Phy 44 * 45 * Start a Phy 46 * 47 * \param agRoot handles for this instance of SAS/SATA hardware 48 * \param agContext 49 * \param phyId the phy id of the link will be started 50 * \param agPhyConfig the phy configuration 51 * \param agSASIdentify the SAS identify frame will be sent by the phy 52 * 53 * \return If phy is started successfully 54 * - \e AGSA_RC_SUCCESS phy is started successfully 55 * - \e AGSA_RC_BUSY phy is already started or starting 56 * - \e AGSA_RC_FAILURE phy is not started successfully 57 */ 58 /*******************************************************************************/ 59 GLOBAL bit32 saPhyStart( 60 agsaRoot_t *agRoot, 61 agsaContext_t *agContext, 62 bit32 queueNum, 63 bit32 phyId, 64 agsaPhyConfig_t *agPhyConfig, 65 agsaSASIdentify_t *agSASIdentify 66 ) 67 { 68 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 69 agsaIORequestDesc_t *pRequest; 70 bit32 ret = AGSA_RC_SUCCESS; 71 bit32 using_reserved = agFALSE; 72 73 smTraceFuncEnter(hpDBG_VERY_LOUD, "7a"); 74 75 /* sanity check */ 76 SA_ASSERT((agNULL != agRoot), ""); 77 SA_ASSERT((agNULL != agSASIdentify), ""); 78 79 SA_DBG3(("saPhyStart: phy%d started with ID %08X:%08X\n", 80 phyId, 81 SA_IDFRM_GET_SAS_ADDRESSHI(agSASIdentify), 82 SA_IDFRM_GET_SAS_ADDRESSLO(agSASIdentify))); 83 84 /* If phyId is invalid, return failure */ 85 if ( phyId >= saRoot->phyCount ) 86 { 87 ret = AGSA_RC_FAILURE; 88 } 89 /* If phyId is valid */ 90 else 91 { 92 /* Get request from free IORequests */ 93 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 94 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /* */ 95 /* If no LL Control request entry available */ 96 if ( agNULL == pRequest ) 97 { 98 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests)); 99 /* If no LL Control request entry available */ 100 if(agNULL != pRequest) 101 { 102 using_reserved = agTRUE; 103 SA_DBG1(("saPhyStart, using saRoot->freeReservedRequests\n")); 104 } 105 else 106 { 107 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 108 SA_DBG1(("saPhyStart, No request from free list Not using saRoot->freeReservedRequests\n")); 109 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "7a"); 110 return AGSA_RC_BUSY; 111 } 112 } 113 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 114 pRequest->valid = agTRUE; 115 /* If LL Control request entry avaliable */ 116 if( using_reserved ) 117 { 118 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 119 } 120 else 121 { 122 /* Remove the request from free list */ 123 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 124 } 125 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 126 127 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 128 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 129 saRoot->IOMap[pRequest->HTag].agContext = agContext; 130 pRequest->valid = agTRUE; 131 132 /* Build the Phy Start IOMB command and send to SPC */ 133 134 smTrace(hpDBG_VERY_LOUD,"P2", phyId); 135 /* TP:P2 phyId */ 136 137 ret = mpiPhyStartCmd(agRoot, pRequest->HTag, phyId, agPhyConfig, agSASIdentify, queueNum); 138 if (AGSA_RC_SUCCESS != ret) 139 { 140 /* remove the request from IOMap */ 141 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 142 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 143 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 144 pRequest->valid = agFALSE; 145 146 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 147 /* return the request to free pool */ 148 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) 149 { 150 SA_DBG1(("saPhyStart: saving pRequest (%p) for later use\n", pRequest)); 151 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 152 } 153 else 154 { 155 /* return the request to free pool */ 156 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 157 } 158 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 159 SA_DBG1(("saPhyStart, sending IOMB failed\n" )); 160 } 161 } 162 163 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "7a"); 164 165 return ret; 166 } 167 168 /******************************************************************************/ 169 /*! \brief Stop a Phy 170 * 171 * Stop a Phy 172 * 173 * \param agRoot handles for this instance of SAS/SATA hardware 174 * \param agContext the context of this API 175 * \param phyId the phy id of the link will be stopped 176 * 177 * \return If phy is stopped successfully 178 * - \e AGSA_RC_SUCCESS phy is stopped successfully 179 * - \e AGSA_RC_FAILURE phy is not stopped successfully 180 */ 181 /*******************************************************************************/ 182 GLOBAL bit32 saPhyStop( 183 agsaRoot_t *agRoot, 184 agsaContext_t *agContext, 185 bit32 queueNum, 186 bit32 phyId 187 ) 188 { 189 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 190 agsaIORequestDesc_t *pRequest; 191 bit32 ret = AGSA_RC_SUCCESS; 192 bit32 using_reserved = agFALSE; 193 194 smTraceFuncEnter(hpDBG_VERY_LOUD,"7b"); 195 196 /* sanity check */ 197 SA_ASSERT((agNULL != agRoot), ""); 198 199 SA_DBG2(("saPhyStop: phy%d stop\n", phyId)); 200 201 if(1) 202 { 203 mpiOCQueue_t *circularQ; 204 int i; 205 SA_DBG4(("saPhyStop:\n")); 206 for ( i = 0; i < saRoot->QueueConfig.numOutboundQueues; i++ ) 207 { 208 circularQ = &saRoot->outboundQueue[i]; 209 OSSA_READ_LE_32(circularQ->agRoot, &circularQ->producerIdx, circularQ->piPointer, 0); 210 if(circularQ->producerIdx != circularQ->consumerIdx) 211 { 212 SA_DBG1(("saPhyStop: PI 0x%03x CI 0x%03x\n",circularQ->producerIdx, circularQ->consumerIdx )); 213 } 214 } 215 } 216 217 if(smIS_SPC(agRoot)) 218 { 219 phyId &= 0xF; 220 } 221 /* If phyId is invalid, return failure */ 222 if ( (phyId & 0xF) >= saRoot->phyCount ) 223 { 224 ret = AGSA_RC_FAILURE; 225 SA_DBG1(("saPhyStop: phy%d - failure with phyId\n", phyId)); 226 } 227 else 228 { 229 /* If phyId is valid */ 230 /* Get request from free IORequests */ 231 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 232 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/ 233 /* If no LL Control request entry available */ 234 if ( agNULL == pRequest ) 235 { 236 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests)); 237 /* If no LL Control request entry available */ 238 if(agNULL != pRequest) 239 { 240 using_reserved = agTRUE; 241 SA_DBG1(("saPhyStop: using saRoot->freeReservedRequests\n")); 242 } 243 else 244 { 245 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 246 SA_DBG1(("saPhyStop, No request from free list Not using saRoot->freeReservedRequests\n")); 247 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "7b"); 248 return AGSA_RC_BUSY; 249 } 250 } 251 /* Remove the request from free list */ 252 if( using_reserved ) 253 { 254 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 255 } 256 else 257 { 258 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 259 } 260 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 261 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 262 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 263 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 264 saRoot->IOMap[pRequest->HTag].agContext = agContext; 265 pRequest->valid = agTRUE; 266 267 /* build IOMB command and send to SPC */ 268 ret = mpiPhyStopCmd(agRoot, pRequest->HTag, phyId, queueNum); 269 if (AGSA_RC_SUCCESS != ret) 270 { 271 /* remove the request from IOMap */ 272 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 273 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 274 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 275 276 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 277 /* return the request to free pool */ 278 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) 279 { 280 SA_DBG2(("saPhyStop: saving pRequest (%p) for later use\n", pRequest)); 281 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 282 } 283 else 284 { 285 /* return the request to free pool */ 286 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 287 } 288 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 289 SA_DBG1(("saPhyStop, sending IOMB failed\n" )); 290 } 291 } 292 293 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "7b"); 294 295 return ret; 296 } 297 298 /******************************************************************************/ 299 /*! \brief CallBack Routine to stop a Phy 300 * 301 * CallBack for Stop a Phy 302 * 303 * \param agRoot handles for this instance of SAS/SATA hardware 304 * \param phyId the phy id of the link will be stopped 305 * \param status the status of the phy 306 * \param agContext the context of the saPhyStop 307 * 308 * \return If phy is stopped successfully 309 * - \e AGSA_RC_SUCCESS phy is stopped successfully 310 * - \e AGSA_RC_FAILURE phy is not stopped successfully 311 */ 312 /*******************************************************************************/ 313 GLOBAL bit32 siPhyStopCB( 314 agsaRoot_t *agRoot, 315 bit32 phyId, 316 bit32 status, 317 agsaContext_t *agContext, 318 bit32 portId, 319 bit32 npipps 320 ) 321 { 322 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 323 agsaPhy_t *pPhy; 324 agsaPort_t *pPort; 325 bit32 ret = AGSA_RC_SUCCESS; 326 bit32 iomb_status = status; 327 328 smTraceFuncEnter(hpDBG_VERY_LOUD,"7c"); 329 330 /* sanity check */ 331 SA_ASSERT((agNULL != agRoot), ""); 332 333 /* If phyId is invalid, return failure */ 334 if ( phyId >= saRoot->phyCount ) 335 { 336 ret = AGSA_RC_FAILURE; 337 SA_DBG1(("siPhyStopCB: phy%d - failure with phyId\n", phyId)); 338 /* makeup for CB */ 339 status = (status << SHIFT8) | phyId; 340 status |= ((npipps & PORT_STATE_MASK) << SHIFT16); 341 ossaHwCB(agRoot, agNULL, OSSA_HW_EVENT_PHY_STOP_STATUS, status, agContext, agNULL); 342 } 343 /* If phyId is valid */ 344 else 345 { 346 pPhy = &(saRoot->phys[phyId]); 347 348 /* get the port of the phy */ 349 pPort = pPhy->pPort; 350 351 /* makeup for CB */ 352 status = (status << SHIFT8) | phyId; 353 status |= ((npipps & PORT_STATE_MASK) << SHIFT16); 354 /* Callback to stop phy */ 355 if ( agNULL != pPort ) 356 { 357 if ( iomb_status == OSSA_SUCCESS && (OSSA_PORT_INVALID == (npipps & PORT_STATE_MASK) )) 358 { 359 SA_DBG1(("siPhyStopCB: phy%d invalidating port\n", phyId)); 360 /* invalid port state, remove the port */ 361 pPort->status |= PORT_INVALIDATING; 362 saRoot->PortMap[portId].PortStatus |= PORT_INVALIDATING; 363 /* invalid the port */ 364 siPortInvalid(agRoot, pPort); 365 /* map out the portmap */ 366 saRoot->PortMap[pPort->portId].PortContext = agNULL; 367 saRoot->PortMap[pPort->portId].PortID = PORT_MARK_OFF; 368 saRoot->PortMap[pPort->portId].PortStatus |= PORT_INVALIDATING; 369 } 370 ossaHwCB(agRoot, &(pPort->portContext), OSSA_HW_EVENT_PHY_STOP_STATUS, status, agContext, agNULL); 371 } 372 else 373 { 374 SA_DBG1(("siPhyStopCB: phy%d - Port is not established\n", phyId)); 375 ossaHwCB(agRoot, agNULL, OSSA_HW_EVENT_PHY_STOP_STATUS, status, agContext, agNULL); 376 } 377 378 /* set PHY_STOPPED status */ 379 PHY_STATUS_SET(pPhy, PHY_STOPPED); 380 381 /* Exclude the phy from a port */ 382 if ( agNULL != pPort ) 383 { 384 /* Acquire port list lock */ 385 ossaSingleThreadedEnter(agRoot, LL_PORT_LOCK); 386 387 /* Delete the phy from the port */ 388 pPort->phyMap[phyId] = agFALSE; 389 saRoot->phys[phyId].pPort = agNULL; 390 391 /* Release port list lock */ 392 ossaSingleThreadedLeave(agRoot, LL_PORT_LOCK); 393 } 394 } 395 396 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "7c"); 397 398 /* return */ 399 return ret; 400 } 401 402 /******************************************************************************/ 403 /*! \brief Initiate a Local PHY control command 404 * 405 * This function is called to initiate a PHY control command to the local PHY. 406 * The completion of this function is reported in ossaLocalPhyControlCB() 407 408 * 409 * \param agRoot handles for this instance of SAS/SATA hardware 410 * \param agContext the context of this API 411 * \param phyId phy number 412 * \param phyOperation 413 * one of AGSA_PHY_LINK_RESET, AGSA_PHY_HARD_RESET, AGSA_PHY_ENABLE_SPINUP 414 * 415 * \return 416 * - none 417 */ 418 /*******************************************************************************/ 419 GLOBAL bit32 saLocalPhyControl( 420 agsaRoot_t *agRoot, 421 agsaContext_t *agContext, 422 bit32 queueNum, 423 bit32 phyId, 424 bit32 phyOperation, 425 ossaLocalPhyControlCB_t agCB 426 ) 427 { 428 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 429 agsaIORequestDesc_t *pRequest; 430 agsaPhyErrCounters_t errorParam; 431 bit32 ret = AGSA_RC_SUCCESS; 432 bit32 value, value1, value2, copyPhyId; 433 bit32 count = 100; 434 bit32 using_reserved = agFALSE; 435 436 437 /* sanity check */ 438 SA_ASSERT((agNULL != saRoot), ""); 439 if(saRoot == agNULL) 440 { 441 SA_DBG1(("saLocalPhyControl: saRoot == agNULL\n")); 442 return(AGSA_RC_FAILURE); 443 } 444 smTraceFuncEnter(hpDBG_VERY_LOUD,"7d"); 445 446 si_memset(&errorParam,0,sizeof(agsaPhyErrCounters_t)); 447 SA_DBG2(("saLocalPhyControl: phy%d operation %08X\n", phyId, phyOperation)); 448 449 switch(phyOperation) 450 { 451 case AGSA_PHY_LINK_RESET: 452 case AGSA_PHY_HARD_RESET: 453 case AGSA_PHY_NOTIFY_ENABLE_SPINUP: 454 case AGSA_PHY_BROADCAST_ASYNCH_EVENT: 455 case AGSA_PHY_COMINIT_OOB: 456 { 457 /* Get request from free IORequests */ 458 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 459 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/ 460 461 /* If no LL Control request entry available */ 462 if ( agNULL == pRequest ) 463 { 464 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests)); 465 /* If no LL Control request entry available */ 466 if(agNULL != pRequest) 467 { 468 using_reserved = agTRUE; 469 SA_DBG1(("saLocalPhyControl, using saRoot->freeReservedRequests\n")); 470 } 471 else 472 { 473 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 474 SA_DBG1(("saLocalPhyControl, No request from free list Not using saRoot->freeReservedRequests\n")); 475 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "7d"); 476 return AGSA_RC_BUSY; 477 } 478 } 479 if( using_reserved ) 480 { 481 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 482 } 483 else 484 { 485 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 486 } 487 /* Remove the request from free list */ 488 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 489 pRequest->completionCB = (void*)agCB; 490 // pRequest->abortCompletionCB = agCB; 491 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 492 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 493 saRoot->IOMap[pRequest->HTag].agContext = agContext; 494 pRequest->valid = agTRUE; 495 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 496 497 /* Build the local phy control IOMB command and send to SPC */ 498 ret = mpiLocalPhyControlCmd(agRoot, pRequest->HTag, phyId, phyOperation, queueNum); 499 if (AGSA_RC_SUCCESS != ret) 500 { 501 /* remove the request from IOMap */ 502 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 503 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 504 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 505 pRequest->valid = agFALSE; 506 507 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 508 /* return the request to free pool */ 509 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) 510 { 511 SA_DBG1(("saLocalPhyControl: saving pRequest (%p) for later use\n", pRequest)); 512 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 513 } 514 else 515 { 516 /* return the request to free pool */ 517 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 518 } 519 SA_DBG1(("saLocalPhyControl, sending IOMB failed\n" )); 520 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 521 return ret; 522 } 523 } 524 break; 525 case AGSA_PHY_GET_ERROR_COUNTS: 526 { 527 if(smIS_SPCV(agRoot)) 528 { 529 530 SA_ASSERT((smIS_SPC(agRoot)), "SPC only"); 531 SA_DBG1(("saLocalPhyControl: V AGSA_PHY_GET_ERROR_COUNTS\n" )); 532 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "7d"); 533 return AGSA_RC_FAILURE; 534 } 535 /* If phyId is invalid, return failure */ 536 if ( phyId >= saRoot->phyCount ) 537 { 538 ret = AGSA_RC_FAILURE; 539 si_memset(&errorParam, 0, sizeof(agsaPhyErrCounters_t)); 540 SA_DBG1(("saLocalPhyControl: phy%d - failure with phyId\n", phyId)); 541 /* call back with the status */ 542 543 if( agCB == agNULL ) 544 { 545 ossaLocalPhyControlCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam); 546 } 547 else 548 { 549 agCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam); 550 } 551 smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "7d"); 552 return ret; 553 } 554 /* save phyId */ 555 copyPhyId = phyId; 556 /* map 0x030000 or 0x040000 based on phyId to BAR4(0x20), BAT2(win) to access the register */ 557 if (phyId < 4) 558 { 559 /* for phyId = 0, 1, 2, 3 */ 560 value = 0x030000; 561 } 562 else 563 { 564 /* for phyId = 4, 5, 6, 7 */ 565 phyId = phyId - 4; 566 value = 0x040000; 567 } 568 569 /* Need to make sure DEVICE_LCLK_GENERATION register bit 6 is 0 */ 570 value1 = ossaHwRegReadExt(agRoot, PCIBAR2, SPC_REG_DEVICE_LCLK); 571 572 SA_DBG3(("saLocalPhyControl: TOP DEVICE LCLK Register value = %08X\n", value1)); 573 /* If LCLK_CLEAR bit set then disable it */ 574 if (value1 & DEVICE_LCLK_CLEAR) 575 { 576 ossaHwRegWriteExt(agRoot, PCIBAR2, SPC_REG_DEVICE_LCLK, (value1 & 0xFFFFFFBF) ); 577 SA_DBG3(("saLocalPhyControl: TOP DEVICE LCLK value = %08X\n", (value1 & 0xFFFFFFBF))); 578 } 579 580 if (AGSA_RC_FAILURE == siBar4Shift(agRoot, value)) 581 { 582 SA_DBG1(("saLocalPhyControl:Shift Bar4 to 0x%x failed\n", value)); 583 phyId = copyPhyId; 584 /* call back with the status */ 585 586 if( agCB == agNULL ) 587 { 588 ossaLocalPhyControlCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam); 589 } 590 else 591 { 592 agCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam); 593 } 594 595 smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "7d"); 596 return AGSA_RC_FAILURE; 597 } 598 599 /* set LCLK = 1 and LCLK_CLEAR = 0 */ 600 SPC_WRITE_COUNTER_CNTL(phyId, LCLK); 601 602 /* LCLK bit should be low to be able to read error registers */ 603 while((value = SPC_READ_COUNTER_CNTL(phyId)) & LCLK) 604 { 605 if(--count == 0) 606 { 607 SA_DBG1(("saLocalPhyControl: Timeout,SPC_COUNTER_CNTL value = %08X\n", value)); 608 ret = AGSA_RC_FAILURE; 609 break; 610 } 611 } /* while */ 612 613 value = SPC_READ_COUNTER_CNTL(phyId); 614 SA_DBG3(("saLocalPhyControl: SPC_COUNTER_CNTL value = %08X\n", value)); 615 616 /* invalidDword */ 617 errorParam.invalidDword = SPC_READ_INV_DW_COUNT(phyId); 618 /* runningDisparityError */ 619 errorParam.runningDisparityError = SPC_READ_DISP_ERR_COUNT(phyId); 620 /* lossOfDwordSynch */ 621 errorParam.lossOfDwordSynch = SPC_READ_LOSS_DW_COUNT(phyId); 622 /* phyResetProblem */ 623 errorParam.phyResetProblem = SPC_READ_PHY_RESET_COUNT(phyId); 624 /* codeViolation */ 625 errorParam.codeViolation = SPC_READ_CODE_VIO_COUNT(phyId); 626 /* never occurred in SPC8x6G */ 627 errorParam.elasticityBufferOverflow = 0; 628 errorParam.receivedErrorPrimitive = 0; 629 errorParam.inboundCRCError = 0; 630 631 SA_DBG3(("saLocalPhyControl:INV_DW_COUNT 0x%x\n", SPC_READ_INV_DW_COUNT(phyId))); 632 SA_DBG3(("saLocalPhyControl:DISP_ERR_COUNT 0x%x\n", SPC_READ_DISP_ERR_COUNT(phyId))); 633 SA_DBG3(("saLocalPhyControl:LOSS_DW_COUNT 0x%x\n", SPC_READ_LOSS_DW_COUNT(phyId))); 634 SA_DBG3(("saLocalPhyControl:PHY_RESET_COUNT 0x%x\n", SPC_READ_PHY_RESET_COUNT(phyId))); 635 SA_DBG3(("saLocalPhyControl:CODE_VIOLATION_COUNT 0x%x\n", SPC_READ_CODE_VIO_COUNT(phyId))); 636 637 /* Shift back to BAR4 original address */ 638 if (AGSA_RC_FAILURE == siBar4Shift(agRoot, 0x0)) 639 { 640 SA_DBG1(("saLocalPhyControl:Shift Bar4 to 0x%x failed\n", 0x0)); 641 ret = AGSA_RC_FAILURE; 642 } 643 644 /* restore back the Top Device LCLK generation register value */ 645 ossaHwRegWriteExt(agRoot, PCIBAR2, SPC_REG_DEVICE_LCLK, value1); 646 647 /* restore phyId */ 648 phyId = copyPhyId; 649 /* call back with the status */ 650 651 if (AGSA_RC_SUCCESS == ret) 652 { 653 if( agCB == agNULL ) 654 { 655 ossaLocalPhyControlCB(agRoot, agContext, copyPhyId, phyOperation, OSSA_SUCCESS, (void *)&errorParam); 656 } 657 else 658 { 659 agCB(agRoot, agContext, copyPhyId, phyOperation, OSSA_SUCCESS, (void *)&errorParam); 660 } 661 } 662 else 663 { 664 if( agCB == agNULL ) 665 { 666 ossaLocalPhyControlCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam); 667 } 668 else 669 { 670 agCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam); 671 } 672 } 673 break; 674 } 675 case AGSA_PHY_CLEAR_ERROR_COUNTS: 676 { 677 if(smIS_SPCV(agRoot)) 678 { 679 680 SA_ASSERT((smIS_SPC(agRoot)), "SPC only"); 681 SA_DBG1(("saLocalPhyControl: V AGSA_PHY_CLEAR_ERROR_COUNTS\n" )); 682 smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "7d"); 683 return AGSA_RC_FAILURE; 684 } 685 /* If phyId is invalid, return failure */ 686 if ( phyId >= saRoot->phyCount ) 687 { 688 si_memset(&errorParam, 0, sizeof(agsaPhyErrCountersPage_t)); 689 SA_DBG3(("saLocalPhyControl(CLEAR): phy%d - failure with phyId\n", phyId)); 690 /* call back with the status */ 691 if( agCB == agNULL ) 692 { 693 ossaLocalPhyControlCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam); 694 } 695 else 696 { 697 agCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam); 698 } 699 smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "7d"); 700 return AGSA_RC_FAILURE; 701 } 702 /* save phyId */ 703 copyPhyId = phyId; 704 /* map 0x030000 or 0x040000 based on phyId to BAR4(0x20), BAT2(win) to access the register */ 705 if (phyId < 4) 706 { 707 /* for phyId = 0, 1, 2, 3 */ 708 value = 0x030000; 709 } 710 else 711 { 712 /* for phyId = 4, 5, 6, 7 */ 713 phyId = phyId - 4; 714 value = 0x040000; 715 } 716 /* Need to make sure DEVICE_LCLK_GENERATION register bit 6 is 1 */ 717 value2 = ossaHwRegReadExt(agRoot, PCIBAR2, SPC_REG_DEVICE_LCLK); 718 719 SA_DBG3(("saLocalPhyControl: TOP DEVICE LCLK Register value = %08X\n", value2)); 720 /* If LCLK_CLEAR bit not set then set it */ 721 if ((value2 & DEVICE_LCLK_CLEAR) == 0) 722 { 723 ossaHwRegWriteExt(agRoot, PCIBAR2, SPC_REG_DEVICE_LCLK, (value2 | DEVICE_LCLK_CLEAR) ); 724 SA_DBG3(("saLocalPhyControl: TOP DEVICE LCLK value = %08X\n", (value2 & 0xFFFFFFBF))); 725 } 726 727 if (AGSA_RC_FAILURE == siBar4Shift(agRoot, value)) 728 { 729 SA_DBG1(("saLocalPhyControl(CLEAR):Shift Bar4 to 0x%x failed\n", value)); 730 phyId = copyPhyId; 731 /* call back with the status */ 732 if( agCB == agNULL ) 733 { 734 ossaLocalPhyControlCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam); 735 } 736 else 737 { 738 agCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam); 739 } 740 smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "7d"); 741 return AGSA_RC_FAILURE; 742 } 743 744 /* read Counter Control register */ 745 value1 = SPC_READ_COUNTER_CNTL(phyId); 746 SA_DBG3(("saLocalPhyControl(CLEAR): SPC_COUNTER_CNTL value = %08X\n", value1)); 747 /* set LCLK and LCLK_CLEAR */ 748 SPC_WRITE_COUNTER_CNTL(phyId, (LCLK_CLEAR | LCLK)); 749 /* read back the value of register */ 750 /* poll LCLK bit = 0 */ 751 while((value = SPC_READ_COUNTER_CNTL(phyId)) & LCLK) 752 { 753 if(--count == 0) 754 { 755 SA_DBG1(("saLocalPhyControl: Timeout,SPC_COUNTER_CNTL value = %08X\n", value)); 756 ret = AGSA_RC_FAILURE; 757 break; 758 } 759 } /* while */ 760 761 value = SPC_READ_COUNTER_CNTL(phyId); 762 SA_DBG3(("saLocalPhyControl(CLEAR): SPC_COUNTER_CNTL value = %08X\n", value)); 763 764 /* restore the value */ 765 SPC_WRITE_COUNTER_CNTL(phyId, value1); 766 767 /* Shift back to BAR4 original address */ 768 if (AGSA_RC_FAILURE == siBar4Shift(agRoot, 0x0)) 769 { 770 SA_DBG1(("saLocalPhyControl:Shift Bar4 to 0x%x failed\n", 0x0)); 771 ret = AGSA_RC_FAILURE; 772 } 773 774 /* restore back the Top Device LCLK generation register value */ 775 ossaHwRegWriteExt(agRoot, PCIBAR2, SPC_REG_DEVICE_LCLK, value2); 776 777 /* restore phyId */ 778 phyId = copyPhyId; 779 /* call back with the status */ 780 if (AGSA_RC_SUCCESS == ret) 781 { 782 if( agCB == agNULL ) 783 { 784 ossaLocalPhyControlCB(agRoot, agContext, phyId, phyOperation, OSSA_SUCCESS, agNULL); 785 } 786 else 787 { 788 agCB(agRoot, agContext, phyId, phyOperation, OSSA_SUCCESS, agNULL); 789 } 790 } 791 else 792 { 793 if( agCB == agNULL ) 794 { 795 ossaLocalPhyControlCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam); 796 } 797 else 798 { 799 agCB(agRoot, agContext, phyId, phyOperation, OSSA_FAILURE, (void *)&errorParam); 800 } 801 } 802 break; 803 } 804 case AGSA_PHY_GET_BW_COUNTS: 805 { 806 SA_ASSERT((smIS_SPC(agRoot)), "SPCv only"); 807 SA_DBG1(("saLocalPhyControl: AGSA_PHY_GET_BW_COUNTS\n" )); 808 break; 809 } 810 811 default: 812 ret = AGSA_RC_FAILURE; 813 SA_ASSERT(agFALSE, "(saLocalPhyControl) Unknown operation"); 814 break; 815 } 816 817 smTraceFuncExit(hpDBG_VERY_LOUD, 'h', "7d"); 818 return ret; 819 } 820 821 822 GLOBAL bit32 saGetPhyProfile( 823 agsaRoot_t *agRoot, 824 agsaContext_t *agContext, 825 bit32 queueNum, 826 bit32 ppc, 827 bit32 phyId 828 ) 829 { 830 bit32 ret = AGSA_RC_SUCCESS; 831 832 agsaLLRoot_t *saRoot = agNULL; 833 agsaPhyErrCountersPage_t errorParam; 834 835 ossaLocalPhyControlCB_t agCB = ossaGetPhyProfileCB; 836 837 /* sanity check */ 838 SA_ASSERT((agNULL != agRoot), ""); 839 saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 840 SA_ASSERT((agNULL != saRoot), ""); 841 842 if(saRoot == agNULL) 843 { 844 SA_DBG3(("saGetPhyProfile : saRoot is NULL")); 845 return AGSA_RC_FAILURE; 846 } 847 848 SA_DBG1(("saGetPhyProfile: ppc 0x%x phyID %d\n", ppc,phyId)); 849 850 switch(ppc) 851 { 852 case AGSA_SAS_PHY_ERR_COUNTERS_PAGE: 853 { 854 if(smIS_SPCV(agRoot)) 855 { 856 857 SA_DBG1(("saGetPhyProfile: V AGSA_SAS_PHY_ERR_COUNTERS_PAGE\n" )); 858 859 ret = mpiGetPhyProfileCmd( agRoot,agContext,ppc ,phyId,agCB); 860 smTraceFuncExit(hpDBG_VERY_LOUD, 'i', "7d"); 861 return ret; 862 } 863 } 864 case AGSA_SAS_PHY_ERR_COUNTERS_CLR_PAGE: 865 { 866 /* If phyId is invalid, return failure */ 867 if ( phyId >= saRoot->phyCount ) 868 { 869 si_memset(&errorParam, 0, sizeof(agsaPhyErrCountersPage_t)); 870 SA_DBG3(("saGetPhyProfile(CLEAR): phy%d - failure with phyId\n", phyId)); 871 /* call back with the status */ 872 ossaGetPhyProfileCB(agRoot, agContext, phyId, ppc, OSSA_FAILURE, (void *)&errorParam); 873 smTraceFuncExit(hpDBG_VERY_LOUD, 'j', "7d"); 874 return AGSA_RC_FAILURE; 875 } 876 if(smIS_SPCV(agRoot)) 877 { 878 SA_DBG1(("saGetPhyProfile: V AGSA_SAS_PHY_ERR_COUNTERS_CLR_PAGE\n" )); 879 880 ret = mpiGetPhyProfileCmd( agRoot,agContext, ppc,phyId,agCB); 881 smTraceFuncExit(hpDBG_VERY_LOUD, 'k', "7d"); 882 return ret; 883 } 884 885 } 886 case AGSA_SAS_PHY_BW_COUNTERS_PAGE: 887 { 888 SA_DBG1(("saGetPhyProfile: AGSA_SAS_PHY_BW_COUNTERS_PAGE\n" )); 889 ret = mpiGetPhyProfileCmd( agRoot,agContext,ppc ,phyId,agCB); 890 break; 891 } 892 case AGSA_SAS_PHY_ANALOG_SETTINGS_PAGE: 893 { 894 SA_DBG1(("saGetPhyProfile: AGSA_SAS_PHY_ANALOG_SETTINGS_PAGE\n" )); 895 ret = mpiGetPhyProfileCmd( agRoot,agContext,ppc ,phyId,agCB); 896 break; 897 } 898 899 case AGSA_SAS_PHY_GENERAL_STATUS_PAGE: 900 { 901 SA_DBG1(("saGetPhyProfile: AGSA_SAS_PHY_GENERAL_STATUS_PAGE\n" )); 902 ret = mpiGetPhyProfileCmd( agRoot,agContext,ppc ,phyId,agCB); 903 break; 904 } 905 case AGSA_PHY_SNW3_PAGE: 906 { 907 SA_DBG1(("saGetPhyProfile: AGSA_PHY_SNW3_PAGE\n" )); 908 ret = mpiGetPhyProfileCmd( agRoot,agContext,ppc ,phyId,agCB); 909 break; 910 } 911 case AGSA_PHY_RATE_CONTROL_PAGE: 912 { 913 SA_DBG1(("saGetPhyProfile: AGSA_PHY_RATE_CONTROL_PAGE\n" )); 914 ret = mpiGetPhyProfileCmd( agRoot,agContext,ppc ,phyId,agCB); 915 break; 916 } 917 case AGSA_SAS_PHY_OPEN_REJECT_RETRY_BACKOFF_THRESHOLD_PAGE: 918 { 919 SA_DBG1(("saGetPhyProfile: AGSA_SAS_PHY_OPEN_REJECT_RETRY_BACKOFF_THRESHOLD_PAGE\n" )); 920 ret = mpiGetPhyProfileCmd( agRoot,agContext,ppc ,phyId,agCB); 921 break; 922 } 923 924 default: 925 SA_DBG1(("saGetPhyProfile: Unknown operation 0x%X\n",ppc )); 926 SA_ASSERT(agFALSE, "saGetPhyProfile Unknown operation " ); 927 break; 928 929 } 930 return ret; 931 932 } 933 934 935 GLOBAL bit32 saSetPhyProfile ( 936 agsaRoot_t *agRoot, 937 agsaContext_t *agContext, 938 bit32 queueNum, 939 bit32 ppc, 940 bit32 length, 941 void *buffer, 942 bit32 phyID 943 ) 944 { 945 bit32 ret = AGSA_RC_SUCCESS; 946 947 SA_DBG1(("saSetPhyProfile: ppc 0x%x length 0x%x phyID %d\n", ppc,length,phyID)); 948 949 switch(ppc) 950 { 951 case AGSA_SAS_PHY_ANALOG_SETTINGS_PAGE: 952 { 953 SA_DBG1(("saSetPhyProfile: AGSA_SAS_PHY_ANALOG_SETTINGS_PAGE\n" )); 954 ret = mpiSetPhyProfileCmd( agRoot,agContext,ppc ,phyID,length,buffer); 955 break; 956 } 957 case AGSA_PHY_SNW3_PAGE: 958 { 959 SA_DBG1(("saSetPhyProfile: AGSA_PHY_SNW3_PAGE\n" )); 960 ret = mpiSetPhyProfileCmd( agRoot,agContext,ppc ,phyID,length,buffer); 961 break; 962 } 963 case AGSA_PHY_RATE_CONTROL_PAGE: 964 { 965 SA_DBG1(("saSetPhyProfile: AGSA_PHY_RATE_CONTROL_PAGE\n" )); 966 ret = mpiSetPhyProfileCmd( agRoot,agContext,ppc ,phyID,length,buffer); 967 break; 968 } 969 case AGSA_SAS_PHY_MISC_PAGE: 970 { 971 SA_DBG1(("saSetPhyProfile: AGSA_SAS_PHY_MISC_PAGE\n")); 972 ret = mpiSetPhyProfileCmd( agRoot,agContext,ppc ,phyID,length,buffer); 973 break; 974 } 975 976 default: 977 SA_DBG1(("saSetPhyProfile: Unknown operation 0x%X\n",ppc )); 978 SA_ASSERT(agFALSE, "saSetPhyProfile Unknown operation " ); 979 ret = AGSA_RC_FAILURE; 980 break; 981 } 982 return ret; 983 } 984 985 986 /******************************************************************************/ 987 /*! \brief Initiate a HW Event Ack command 988 * 989 * This function is called to initiate a HW Event Ack command to the SPC. 990 * The completion of this function is reported in ossaHwEventAckCB(). 991 * 992 * \param agRoot handles for this instance of SAS/SATA hardware 993 * \param agContext the context of this API 994 * \param queueNum queue number 995 * \param eventSource point to the event source structure 996 * \param param0 997 * \param param1 998 * 999 * \return 1000 * - none 1001 */ 1002 /*******************************************************************************/ 1003 GLOBAL bit32 saHwEventAck( 1004 agsaRoot_t *agRoot, 1005 agsaContext_t *agContext, 1006 bit32 queueNum, 1007 agsaEventSource_t *eventSource, 1008 bit32 param0, 1009 bit32 param1 1010 ) 1011 { 1012 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 1013 agsaIORequestDesc_t *pRequest; 1014 agsaPortContext_t *agPortContext; 1015 agsaPort_t *pPort = agNULL; 1016 agsaSASHwEventAckCmd_t payload; 1017 bit32 phyportid; 1018 bit32 ret = AGSA_RC_SUCCESS; 1019 bit32 using_reserved = agFALSE; 1020 1021 smTraceFuncEnter(hpDBG_VERY_LOUD,"7e"); 1022 1023 /* sanity check */ 1024 SA_ASSERT((agNULL != saRoot), ""); 1025 if(saRoot == agNULL) 1026 { 1027 SA_DBG1(("saHwEventAck: saRoot == agNULL\n")); 1028 return(AGSA_RC_FAILURE); 1029 } 1030 1031 SA_DBG2(("saHwEventAck: agContext %p eventSource %p\n", agContext, eventSource)); 1032 SA_DBG1(("saHwEventAck: event 0x%x param0 0x%x param1 0x%x\n", eventSource->event, param0, param1)); 1033 1034 agPortContext = eventSource->agPortContext; 1035 1036 /* Get request from free IORequests */ 1037 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1038 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/ 1039 1040 /* If no LL Control request entry available */ 1041 if ( agNULL == pRequest ) 1042 { 1043 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests)); /**/ 1044 if(agNULL != pRequest) 1045 { 1046 using_reserved = agTRUE; 1047 SA_DBG1(("saHwEventAck, using saRoot->freeReservedRequests\n")); 1048 } 1049 else 1050 { 1051 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1052 /* If no LL Control request entry available */ 1053 SA_DBG1(("saHwEventAck, No request from free list Not using saRoot->freeReservedRequests\n")); 1054 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "7e"); 1055 return AGSA_RC_BUSY; 1056 } 1057 } 1058 if( using_reserved ) 1059 { 1060 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 1061 } 1062 else 1063 { 1064 /* Remove the request from free list */ 1065 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1066 } 1067 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1068 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 1069 1070 SA_DBG2(("saHwEventAck: queueNum 0x%x HTag 0x%x\n",queueNum ,pRequest->HTag)); 1071 1072 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 1073 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 1074 saRoot->IOMap[pRequest->HTag].agContext = agContext; 1075 pRequest->valid = agTRUE; 1076 1077 /* build IOMB command and send to SPC */ 1078 /* set payload to zeros */ 1079 si_memset(&payload, 0, sizeof(agsaSASHwEventAckCmd_t)); 1080 1081 /* find port id */ 1082 if (agPortContext) 1083 { 1084 pPort = (agsaPort_t *) (agPortContext->sdkData); 1085 if (pPort) 1086 { 1087 if(eventSource->event == OSSA_HW_EVENT_PHY_DOWN) 1088 { 1089 pPort->tobedeleted = agTRUE; 1090 } 1091 SA_DBG3(("saHwEventAck,pPort->portId %X\n",pPort->portId)); 1092 1093 if(smIS_SPC(agRoot)) 1094 { 1095 /* fillup PORT_ID field */ 1096 phyportid = pPort->portId & 0xF; 1097 } 1098 else 1099 { 1100 /* fillup PORT_ID field */ 1101 phyportid = pPort->portId & 0xFF; 1102 1103 } 1104 } 1105 else 1106 { 1107 /* pPort is NULL - set PORT_ID to not intialized */ 1108 if(smIS_SPC(agRoot)) 1109 { 1110 phyportid = 0xF; 1111 } 1112 else 1113 { 1114 phyportid = 0xFF; 1115 } 1116 } 1117 } 1118 else 1119 { 1120 /* agPortContext is NULL - set PORT_ID to not intialized */ 1121 if(smIS_SPC(agRoot)) 1122 { 1123 phyportid = 0xF; 1124 } 1125 else 1126 { 1127 phyportid = 0xFF; 1128 } 1129 } 1130 1131 pRequest->pPort = pPort; 1132 1133 SA_DBG3(("saHwEventAck,eventSource->param 0x%X\n",eventSource->param)); 1134 SA_DBG3(("saHwEventAck,eventSource->event 0x%X\n",eventSource->event)); 1135 1136 if(smIS_SPC(agRoot)) 1137 { 1138 /* fillup up PHY_ID */ 1139 phyportid |= ((eventSource->param & 0x0000000F) << 4); 1140 /* fillup SEA field */ 1141 phyportid |= (eventSource->event & 0x0000FFFF) << 8; 1142 SA_DBG3(("saHwEventAck: portId 0x%x phyId 0x%x SEA 0x%x\n", phyportid & 0xF, 1143 eventSource->param & 0x0000000F, eventSource->event & 0x0000FFFF)); 1144 } 1145 else 1146 { 1147 /* fillup up PHY_ID */ 1148 phyportid |= ((eventSource->param & 0x000000FF) << SHIFT24); 1149 /* fillup SEA field */ 1150 phyportid |= (eventSource->event & 0x00FFFFFF) << SHIFT8; 1151 SA_DBG3(("saHwEventAck: portId 0x%x phyId 0x%x SEA 0x%x\n", phyportid & 0xFF, 1152 eventSource->param & 0x0000000F, eventSource->event & 0x0000FFFF)); 1153 } 1154 1155 pRequest->HwAckType = (bit16)phyportid; 1156 1157 SA_DBG1(("saHwEventAck,phyportid 0x%X HwAckType 0x%X\n",phyportid,pRequest->HwAckType)); 1158 /* set tag */ 1159 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASHwEventAckCmd_t, tag), pRequest->HTag); 1160 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASHwEventAckCmd_t, sEaPhyIdPortId), phyportid); 1161 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASHwEventAckCmd_t, Param0), param0); 1162 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSASHwEventAckCmd_t, Param1), param1); 1163 1164 /* build IOMB command and send to SPC */ 1165 1166 if(smIS_SPC(agRoot)) 1167 { 1168 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SPC_SAS_HW_EVENT_ACK, IOMB_SIZE64, queueNum); 1169 } 1170 else 1171 { 1172 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SAS_HW_EVENT_ACK, IOMB_SIZE64, queueNum); 1173 } 1174 1175 if (AGSA_RC_SUCCESS != ret) 1176 { 1177 /* remove the request from IOMap */ 1178 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 1179 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 1180 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 1181 pRequest->valid = agFALSE; 1182 1183 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1184 /* return the request to free pool */ 1185 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) 1186 { 1187 SA_DBG1(("saHwEventAck: saving pRequest (%p) for later use\n", pRequest)); 1188 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 1189 } 1190 else 1191 { 1192 /* return the request to free pool */ 1193 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1194 } 1195 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1196 SA_DBG1(("saHwEventAck, sending IOMB failed\n" )); 1197 } 1198 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "7e"); 1199 1200 return ret; 1201 } 1202 1203 1204 GLOBAL bit32 saVhistCapture( 1205 agsaRoot_t *agRoot, 1206 agsaContext_t *agContext, 1207 bit32 queueNum, 1208 bit32 Channel, 1209 bit32 NumBitLo, 1210 bit32 NumBitHi, 1211 bit32 PcieAddrLo, 1212 bit32 PcieAddrHi, 1213 bit32 ByteCount ) 1214 { 1215 1216 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 1217 agsaIORequestDesc_t *pRequest; 1218 bit32 ret = AGSA_RC_SUCCESS; 1219 bit32 using_reserved = agFALSE; 1220 1221 smTraceFuncEnter(hpDBG_VERY_LOUD,"3N"); 1222 1223 /* sanity check */ 1224 SA_ASSERT((agNULL != agRoot), ""); 1225 1226 SA_DBG1(("saVhistCapture:Channel 0x%08X 0x%08X%08X 0x%08X%08X count 0x%X\n",Channel, NumBitHi, NumBitLo ,PcieAddrHi,PcieAddrLo,ByteCount)); 1227 1228 { 1229 /* Get request from free IORequests */ 1230 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1231 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /* */ 1232 /* If no LL Control request entry available */ 1233 if ( agNULL == pRequest ) 1234 { 1235 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests)); 1236 /* If no LL Control request entry available */ 1237 if(agNULL != pRequest) 1238 { 1239 using_reserved = agTRUE; 1240 SA_DBG1((", using saRoot->freeReservedRequests\n")); 1241 } 1242 else 1243 { 1244 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1245 SA_DBG1(("saVhistCapture: No request from free list Not using saRoot->freeReservedRequests\n")); 1246 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "3N"); 1247 return AGSA_RC_BUSY; 1248 } 1249 } 1250 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 1251 pRequest->valid = agTRUE; 1252 /* If LL Control request entry avaliable */ 1253 if( using_reserved ) 1254 { 1255 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 1256 } 1257 else 1258 { 1259 /* Remove the request from free list */ 1260 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1261 } 1262 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1263 1264 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 1265 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 1266 saRoot->IOMap[pRequest->HTag].agContext = agContext; 1267 pRequest->valid = agTRUE; 1268 1269 /* Build the VhisCapture IOMB command and send to SPCv */ 1270 1271 ret = mpiVHistCapCmd(agRoot,agContext, queueNum, Channel, NumBitLo, NumBitHi ,PcieAddrLo, PcieAddrHi, ByteCount); 1272 if (AGSA_RC_SUCCESS != ret) 1273 { 1274 /* remove the request from IOMap */ 1275 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 1276 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 1277 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 1278 pRequest->valid = agFALSE; 1279 1280 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1281 /* return the request to free pool */ 1282 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) 1283 { 1284 SA_DBG1(("saPhyStart: saving pRequest (%p) for later use\n", pRequest)); 1285 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 1286 } 1287 else 1288 { 1289 /* return the request to free pool */ 1290 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1291 } 1292 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1293 SA_DBG1(("saVhistCapture: sending IOMB failed\n" )); 1294 } 1295 } 1296 1297 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "3N"); 1298 1299 return ret; 1300 } 1301 1302