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