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 sampicmd.c 24 * \brief The file implements the functions of MPI Inbound IOMB/Command to 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 'I' 37 #endif 38 39 /******************************************************************************/ 40 /*! \brief SAS/SATA LL API ECHO Command 41 * 42 * This command used to test that MPI between host and SPC IOP is operational. 43 * 44 * \param agRoot Handles for this instance of SAS/SATA hardware 45 * \param agContext Context of SPC FW Flash Update Command 46 * \param queueNum Inbound/outbound queue number 47 * \param echoPayload Pointer of Echo payload of IOMB 48 * 49 * \return If the MPI command is sent to SPC successfully 50 * - \e AGSA_RC_SUCCESS the MPI command is successfully 51 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 52 * - \e AGSA_RC_FAILURE the MPI command is failure 53 * 54 */ 55 /*******************************************************************************/ 56 GLOBAL bit32 saEchoCommand( 57 agsaRoot_t *agRoot, 58 agsaContext_t *agContext, 59 bit32 queueNum, 60 void *echoPayload 61 ) 62 { 63 bit32 ret = AGSA_RC_SUCCESS; 64 65 smTraceFuncEnter(hpDBG_VERY_LOUD, "xa"); 66 67 /* setup IOMB payload */ 68 ret = mpiEchoCmd(agRoot, queueNum, agContext, echoPayload); 69 70 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xa"); 71 72 return ret; 73 } 74 75 /******************************************************************************/ 76 /*! \brief Build a IOMB command and send to SPC 77 * 78 * Build an IOMB if there is a free message buffer and Send it to SPC 79 * 80 * \param agRoot Handles for this instance of SAS/SATA hardware 81 * \param payload Pointer of payload in the IOMB 82 * \param category Category of IOMB 83 * \param opcode Opcode of IOMB 84 * \param size Size of IOMB 85 * \param queueNum Inbound/outbound queue number 86 * 87 * \return If the MPI command is sent to SPC successfully 88 * - \e AGSA_RC_SUCCESS the MPI command is successfully 89 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 90 * - \e AGSA_RC_FAILURE the MPI command is failure 91 */ 92 /*******************************************************************************/ 93 GLOBAL bit32 mpiBuildCmd( 94 agsaRoot_t *agRoot, 95 bit32 *payload, 96 mpiMsgCategory_t category, 97 bit16 opcode, 98 bit16 size, 99 bit32 queueNum 100 ) 101 { 102 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 103 mpiICQueue_t *circularQ; 104 void *pMessage; 105 bit32 ret = AGSA_RC_SUCCESS; 106 bit32 retVal; 107 bit8 inq, outq; 108 109 smTraceFuncEnter(hpDBG_VERY_LOUD, "xb"); 110 111 inq = (bit8)(queueNum & MPI_IB_NUM_MASK); 112 outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT); 113 SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range."); 114 SA_ASSERT((AGSA_MAX_OUTBOUND_Q > outq), "The OBQ Number is out of range."); 115 116 #ifdef SA_USE_MAX_Q 117 outq = saRoot->QueueConfig.numOutboundQueues -1; 118 SA_DBG1(("mpiBuildCmd, set OBQ to %d\n",outq)); 119 #endif /* SA_USE_MAX_Q */ 120 /* get a free inbound queue entry */ 121 122 #ifdef SA_LL_IBQ_PROTECT 123 ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 124 #endif /* SA_LL_IBQ_PROTECT */ 125 126 circularQ = &saRoot->inboundQueue[inq]; 127 retVal = mpiMsgFreeGet(circularQ, size, &pMessage); 128 129 /* return FAILURE if error happened */ 130 if (AGSA_RC_FAILURE == retVal) 131 { 132 #ifdef SA_LL_IBQ_PROTECT 133 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 134 #endif /* SA_LL_IBQ_PROTECT */ 135 /* the message size exceeds the inbound queue message size */ 136 SA_DBG1(("mpiBuildCmd, failure\n")); 137 ret = AGSA_RC_FAILURE; 138 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xb"); 139 return ret; 140 } 141 142 /* return BUSY if no more inbound queue entry available */ 143 if (AGSA_RC_BUSY == retVal) 144 { 145 SA_DBG1(("mpiBuildCmd, no more IOMB\n")); 146 ret = AGSA_RC_BUSY; 147 } 148 else 149 { 150 /* copy payload if it is necessary */ 151 if (agNULL != payload) 152 { 153 si_memcpy(pMessage, payload, (size - sizeof(mpiMsgHeader_t))); 154 } 155 156 /* post the message to SPC */ 157 if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, category, opcode, outq, (bit8)circularQ->priority)) 158 { 159 ret = AGSA_RC_FAILURE; 160 } 161 } 162 163 #ifdef SA_LL_IBQ_PROTECT 164 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 165 #endif /* SA_LL_IBQ_PROTECT */ 166 167 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xb"); 168 return ret; 169 } 170 171 /******************************************************************************/ 172 /*! \brief SPC MPI ECHO Command 173 * 174 * This command used to test that MPI between host and SPC IOP is operational. 175 * 176 * \param agRoot Handles for this instance of SAS/SATA LLL 177 * \param queueNum Inbound/outbound queue number 178 * \param tag Tag of this IOMB 179 * \param echoPayload Pointer to the ECHO payload of inbound IOMB 180 * 181 * \return If the MPI command is sent to SPC successfully 182 * - \e AGSA_RC_SUCCESS the MPI command is successfully 183 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 184 * - \e AGSA_RC_FAILURE the MPI command is failure 185 * 186 */ 187 /*******************************************************************************/ 188 GLOBAL bit32 mpiEchoCmd( 189 agsaRoot_t *agRoot, 190 bit32 queueNum, 191 agsaContext_t *agContext, 192 void *echoPayload 193 ) 194 { 195 bit32 ret = AGSA_RC_SUCCESS; 196 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 197 agsaIORequestDesc_t *pRequest; 198 agsaEchoCmd_t payload; 199 200 smTraceFuncEnter(hpDBG_VERY_LOUD, "xc"); 201 202 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 203 /* Get request from free IORequests */ 204 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 205 206 /* If no LL Control request entry available */ 207 if ( agNULL == pRequest ) 208 { 209 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 210 SA_DBG1(("mpiEchoCmd, No request from free list\n" )); 211 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xc"); 212 return AGSA_RC_BUSY; 213 } 214 /* If LL Control request entry avaliable */ 215 else 216 { 217 /* Remove the request from free list */ 218 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 219 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 220 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 221 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 222 saRoot->IOMap[pRequest->HTag].agContext = agContext; 223 pRequest->valid = agTRUE; 224 225 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 226 227 228 /* build IOMB command and send to SPC */ 229 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaEchoCmd_t, tag), pRequest->HTag); 230 /* copy Echo payload */ 231 si_memcpy(&payload.payload[0], echoPayload, (sizeof(agsaEchoCmd_t) - 4)); 232 /* build IOMB command and send to SPC */ 233 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_ECHO, IOMB_SIZE64, queueNum); 234 SA_DBG3(("mpiEchoCmd, return value = %d\n", ret)); 235 if (AGSA_RC_SUCCESS != ret) 236 { 237 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 238 /* remove the request from IOMap */ 239 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 240 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 241 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 242 pRequest->valid = agFALSE; 243 /* return the request to free pool */ 244 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 245 246 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 247 248 SA_DBG1(("mpiEchoCmd, sending IOMB failed\n" )); 249 } 250 #ifdef SALL_API_TEST 251 else 252 { 253 saRoot->LLCounters.IOCounter.numEchoSent++; 254 } 255 #endif 256 257 } 258 259 /* return value */ 260 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xc"); 261 return ret; 262 } 263 264 265 /******************************************************************************/ 266 /*! \brief Get Phy Profile Command SPCv 267 * 268 * This command is get # of phys and support speeds from SPCV. 269 * 270 * \param agRoot Handles for this instance of SAS/SATA LLL 271 * \param agDevHandle Handle of device 272 * 273 * \return If the MPI command is sent to SPC successfully 274 * - \e AGSA_RC_SUCCESS the MPI command is successfully 275 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 276 * - \e AGSA_RC_FAILURE the MPI command is failure 277 * 278 */ 279 /*******************************************************************************/ 280 281 282 GLOBAL bit32 mpiGetPhyProfileCmd( 283 agsaRoot_t *agRoot, 284 agsaContext_t *agContext, 285 bit32 Operation, 286 bit32 PhyId, 287 void *agCB 288 ) 289 { 290 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 291 agsaIORequestDesc_t *pRequest; 292 bit32 ret = AGSA_RC_SUCCESS; 293 agsaGetPhyProfileCmd_V_t payload; 294 295 smTraceFuncEnter(hpDBG_VERY_LOUD, "xd"); 296 297 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 298 /* Get request from free IORequests */ 299 pRequest = (agsaIORequestDesc_t *)saLlistGetHead(&(saRoot->freeIORequests)); 300 301 SA_DBG1(("mpiGetPhyProfileCmd, Operation 0x%x PhyId %d \n",Operation ,PhyId )); 302 303 /* If no LL Control request entry avalibale */ 304 if ( agNULL == pRequest ) 305 { 306 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 307 SA_DBG1(("mpiGetPhyProfileCmd, No request from free list\n" )); 308 return AGSA_RC_BUSY; 309 } 310 /* If LL Control request entry avaliable */ 311 else 312 { 313 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 314 315 /* Remove the request from free list */ 316 saLlistRemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 317 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 318 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 319 saRoot->IOMap[pRequest->HTag].agContext = agContext; 320 321 pRequest->valid = agTRUE; 322 pRequest->completionCB = agCB; 323 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 324 325 326 /* set payload to zeros */ 327 si_memset(&payload, 0, sizeof(agsaGetPhyProfileCmd_V_t)); 328 329 /* set tag field */ 330 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetPhyProfileCmd_V_t, tag), pRequest->HTag); 331 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetPhyProfileCmd_V_t, Reserved_Ppc_SOP_PHYID), (((Operation & 0xF) << SHIFT8 ) | (PhyId & 0xFF) ) ); 332 /* build IOMB command and send to SPC */ 333 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_PHY_PROFILE, IOMB_SIZE128, 0); 334 if (AGSA_RC_SUCCESS != ret) 335 { 336 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 337 pRequest->valid = agFALSE; 338 /* return the request to free pool */ 339 saLlistAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 340 /* remove the request from IOMap */ 341 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 342 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 343 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 344 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 345 346 SA_DBG1(("mpiGetPhyProfileCmd, sending IOMB failed\n" )); 347 } 348 SA_DBG3(("mpiGetPhyProfileCmd, return value = %d\n", ret)); 349 } 350 351 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xd"); 352 /* return value */ 353 return ret; 354 } 355 356 357 GLOBAL bit32 mpiVHistCapCmd( 358 agsaRoot_t *agRoot, 359 agsaContext_t *agContext, 360 bit32 queueNum, 361 bit32 Channel, 362 bit32 NumBitLo, 363 bit32 NumBitHi, 364 bit32 PcieAddrLo, 365 bit32 PcieAddrHi, 366 bit32 ByteCount ) 367 { 368 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 369 agsaIORequestDesc_t *pRequest= agNULL; 370 bit32 ret = AGSA_RC_SUCCESS; 371 agsaGetVHistCap_V_t payload; 372 373 smTraceFuncEnter(hpDBG_VERY_LOUD,"3C"); 374 SA_DBG1(("mpiVHistCapCmd\n")); 375 376 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 377 /* Get request from free IORequests */ 378 pRequest = (agsaIORequestDesc_t *)saLlistGetHead(&(saRoot->freeIORequests)); 379 /* If no LL Control request entry avalibale */ 380 if ( agNULL == pRequest ) 381 { 382 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 383 SA_DBG1((", No request from free list\n" )); 384 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "3C"); 385 return AGSA_RC_BUSY; 386 } 387 /* If LL Control request entry avaliable */ 388 else 389 { 390 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 391 /* Remove the request from free list */ 392 saLlistRemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 393 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 394 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 395 saRoot->IOMap[pRequest->HTag].agContext = agContext; 396 397 pRequest->valid = agTRUE; 398 pRequest->completionCB = (void *)ossaGetPhyProfileCB; 399 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 400 401 /* set payload to zeros */ 402 si_memset(&payload, 0, sizeof(agsaGetVHistCap_V_t)); 403 404 /* set tag field */ 405 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetVHistCap_V_t, tag), pRequest->HTag); 406 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetVHistCap_V_t, Channel), Channel ); 407 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetVHistCap_V_t, NumBitLo), NumBitLo); 408 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetVHistCap_V_t, NumBitHi), NumBitHi); 409 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetVHistCap_V_t, PcieAddrLo),PcieAddrLo); 410 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetVHistCap_V_t, PcieAddrHi),PcieAddrHi); 411 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetVHistCap_V_t, ByteCount), ByteCount ); 412 413 414 /* build IOMB command and send to SPC */ 415 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_VHIST_CAP, IOMB_SIZE128,queueNum ); 416 if (AGSA_RC_SUCCESS != ret) 417 { 418 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 419 pRequest->valid = agFALSE; 420 /* return the request to free pool */ 421 saLlistAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 422 /* remove the request from IOMap */ 423 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 424 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 425 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 426 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 427 428 SA_DBG1(("mpiVHistCapCmd, sending IOMB failed\n" )); 429 } 430 SA_DBG3(("mpiVHistCapCmd, return value = %d\n", ret)); 431 } 432 433 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "3C"); 434 /* return value */ 435 436 return(ret); 437 } 438 439 GLOBAL bit32 mpiSetPhyProfileCmd( 440 agsaRoot_t *agRoot, 441 agsaContext_t *agContext, 442 bit32 Operation, 443 bit32 PhyId, 444 bit32 length, 445 void * buffer 446 ) 447 { 448 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 449 agsaIORequestDesc_t *pRequest; 450 bit32 ret = AGSA_RC_SUCCESS; 451 bit32 i; 452 agsaSetPhyProfileCmd_V_t payload; 453 bit32 * PageData =(bit32 * )buffer; 454 455 smTraceFuncEnter(hpDBG_VERY_LOUD,"2P"); 456 457 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 458 /* Get request from free IORequests */ 459 pRequest = (agsaIORequestDesc_t *)saLlistGetHead(&(saRoot->freeIORequests)); 460 461 SA_DBG1(("mpiSetPhyProfileCmd, Operation 0x%x PhyId %d \n",Operation ,PhyId )); 462 463 /* If no LL Control request entry avalibale */ 464 if ( agNULL == pRequest ) 465 { 466 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 467 SA_DBG1(("mpiSetPhyProfileCmd, No request from free list\n" )); 468 return AGSA_RC_BUSY; 469 } 470 /* If LL Control request entry avaliable */ 471 else 472 { 473 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 474 /* Remove the request from free list */ 475 saLlistRemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 476 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 477 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 478 saRoot->IOMap[pRequest->HTag].agContext = agContext; 479 480 pRequest->valid = agTRUE; 481 pRequest->SOP = (bit16) Operation; 482 pRequest->completionCB = (void *)ossaGetPhyProfileCB; 483 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 484 485 486 /* set payload to zeros */ 487 si_memset(&payload, 0, sizeof(agsaSetPhyProfileCmd_V_t)); 488 489 /* set tag field */ 490 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetPhyProfileCmd_V_t, tag), pRequest->HTag); 491 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetPhyProfileCmd_V_t, Reserved_Ppc_SOP_PHYID), (((Operation & 0xF) << SHIFT8 ) | (PhyId & 0xFF) ) ); 492 493 for(i=0; i < (length / sizeof(bit32)); i++) 494 { 495 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetPhyProfileCmd_V_t, PageSpecificArea[i]),* (PageData+i) ); 496 } 497 498 /* build IOMB command and send to SPC */ 499 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SET_PHY_PROFILE, IOMB_SIZE128, 0); 500 if (AGSA_RC_SUCCESS != ret) 501 { 502 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 503 pRequest->valid = agFALSE; 504 /* return the request to free pool */ 505 saLlistAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 506 /* remove the request from IOMap */ 507 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 508 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 509 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 510 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 511 512 SA_DBG1(("mpiSetPhyProfileCmd, sending IOMB failed\n" )); 513 } 514 SA_DBG3(("mpiGetPhyProfileCmd, return value = %d\n", ret)); 515 } 516 517 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2P"); 518 /* return value */ 519 return ret; 520 } 521 522 523 /******************************************************************************/ 524 /*! \brief Get Device Information Command 525 * 526 * This command is get # of phys and support speeds from SPC. 527 * 528 * \param agRoot Handles for this instance of SAS/SATA LLL 529 * \param agDevHandle Handle of device 530 * \param deviceid Device Id 531 * \param opton oprion 532 * 533 * \return If the MPI command is sent to SPC successfully 534 * - \e AGSA_RC_SUCCESS the MPI command is successfully 535 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 536 * - \e AGSA_RC_FAILURE the MPI command is failure 537 * 538 */ 539 /*******************************************************************************/ 540 GLOBAL bit32 mpiGetDeviceInfoCmd( 541 agsaRoot_t *agRoot, 542 agsaContext_t *agContext, 543 bit32 deviceid, 544 bit32 option, 545 bit32 queueNum 546 ) 547 { 548 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 549 agsaIORequestDesc_t *pRequest; 550 bit32 ret = AGSA_RC_SUCCESS; 551 agsaGetDevInfoCmd_t payload; 552 553 SA_ASSERT((agNULL !=saRoot ), ""); 554 if(saRoot == agNULL) 555 { 556 SA_DBG1(("mpiGetDeviceInfoCmd: saRoot == agNULL\n")); 557 return(AGSA_RC_FAILURE); 558 } 559 smTraceFuncEnter(hpDBG_VERY_LOUD,"2K"); 560 561 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 562 /* Get request from free IORequests */ 563 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 564 565 /* If no LL Control request entry available */ 566 if ( agNULL == pRequest ) 567 { 568 SA_DBG1(("mpiGetDeviceInfoCmd, No request from free list\n" )); 569 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2K"); 570 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 571 return AGSA_RC_BUSY; 572 } 573 /* If LL Control request entry avaliable */ 574 else 575 { 576 /* Remove the request from free list */ 577 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 578 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 579 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 580 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 581 saRoot->IOMap[pRequest->HTag].agContext = agContext; 582 pRequest->valid = agTRUE; 583 pRequest->DeviceInfoCmdOption = (bit8)option; 584 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 585 586 587 /* set payload to zeros */ 588 si_memset(&payload, 0, sizeof(agsaGetDevInfoCmd_t)); 589 590 /* set tag field */ 591 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDevInfoCmd_t, tag), pRequest->HTag); 592 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDevInfoCmd_t, DeviceId), deviceid); 593 /* build IOMB command and send to SPC */ 594 if( smIS_SPC(agRoot)) 595 { 596 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SPC_GET_DEV_INFO, IOMB_SIZE64, queueNum); 597 } 598 else 599 { 600 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_DEV_INFO, IOMB_SIZE64, queueNum); 601 } 602 if (AGSA_RC_SUCCESS != ret) 603 { 604 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 605 /* remove the request from IOMap */ 606 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 607 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 608 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 609 pRequest->valid = agFALSE; 610 /* return the request to free pool */ 611 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 612 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 613 614 SA_DBG1(("mpiGetDeviceInfoCmd, sending IOMB failed\n" )); 615 } 616 SA_DBG3(("mpiGetDeviceInfoCmd, return value = %d\n", ret)); 617 } 618 619 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2K"); 620 /* return value */ 621 return ret; 622 } 623 624 /******************************************************************************/ 625 /*! \brief Set Device Information Command 626 * 627 * This command is Set Device Information to SPC. 628 * 629 * \param agRoot Handles for this instance of SAS/SATA LLL 630 * \param agDevHandle Handle of device 631 * \param deviceid Device Id 632 * \param opton oprion 633 * 634 * \return If the MPI command is sent to SPC successfully 635 * - \e AGSA_RC_SUCCESS the MPI command is successfully 636 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 637 * - \e AGSA_RC_FAILURE the MPI command is failure 638 * 639 */ 640 /*******************************************************************************/ 641 GLOBAL bit32 mpiSetDeviceInfoCmd( 642 agsaRoot_t *agRoot, 643 agsaContext_t *agContext, 644 bit32 deviceid, 645 bit32 option, 646 bit32 queueNum, 647 bit32 param, 648 ossaSetDeviceInfoCB_t agCB 649 ) 650 { 651 agsaLLRoot_t *saRoot = agNULL; 652 agsaIORequestDesc_t *pRequest = agNULL; 653 bit32 ret = AGSA_RC_SUCCESS; 654 agsaSetDevInfoCmd_t payload; 655 656 smTraceFuncEnter(hpDBG_VERY_LOUD,"xe"); 657 658 /* sanity check */ 659 SA_ASSERT((agNULL != agRoot), ""); 660 saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 661 SA_ASSERT((agNULL != saRoot), ""); 662 663 /* Get request from free IORequests */ 664 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 665 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 666 667 SA_DBG2(("mpiSetDeviceInfoCmd, param 0x%08X option 0x%08X\n",param,option )); 668 669 /* If no LL Control request entry available */ 670 if ( agNULL == pRequest ) 671 { 672 SA_DBG1(("mpiSetDeviceInfoCmd, No request from free list\n" )); 673 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xe"); 674 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 675 return AGSA_RC_BUSY; 676 } 677 /* If LL Control request entry avaliable */ 678 else 679 { 680 /* Remove the request from free list */ 681 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 682 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 683 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 684 saRoot->IOMap[pRequest->HTag].agContext = agContext; 685 pRequest->valid = agTRUE; 686 pRequest->completionCB = (ossaSSPCompletedCB_t)agCB; 687 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 688 689 /* set payload to zeros */ 690 si_memset(&payload, 0, sizeof(agsaSetDevInfoCmd_t)); 691 692 /* set tag field */ 693 694 if(smIS_SPC(agRoot)) 695 { 696 option &= SET_DEV_INFO_SPC_DW3_MASK; 697 param &= SET_DEV_INFO_SPC_DW4_MASK; 698 } 699 else 700 { 701 option &= SET_DEV_INFO_V_DW3_MASK; 702 param &= SET_DEV_INFO_V_DW4_MASK; 703 } 704 705 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetDevInfoCmd_t, tag), pRequest->HTag); 706 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetDevInfoCmd_t, deviceId), deviceid); 707 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetDevInfoCmd_t, SA_SR_SI), option); 708 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetDevInfoCmd_t, DEVA_MCN_R_ITNT), param ); 709 710 /* build IOMB command and send to SPC */ 711 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SET_DEV_INFO, IOMB_SIZE64, queueNum); 712 if (AGSA_RC_SUCCESS != ret) 713 { 714 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 715 /* remove the request from IOMap */ 716 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 717 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 718 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 719 pRequest->valid = agFALSE; 720 721 /* return the request to free pool */ 722 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 723 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 724 725 SA_DBG1(("mpiSetDeviceInfoCmd, sending IOMB failed\n" )); 726 } 727 SA_DBG3(("mpiSetDeviceInfoCmd, return value = %d\n", ret)); 728 } 729 730 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xe"); 731 /* return value */ 732 733 return ret; 734 } 735 736 /******************************************************************************/ 737 /*! \brief SPC MPI Phy Start Command 738 * 739 * This command sends to SPC for the I/O. 740 * 741 * \param agRoot Handles for this instance of SAS/SATA LLL 742 * \param tag tage for IOMB 743 * \param phyId the phy id of the link will be started 744 * \param agPhyConfig the phy properity 745 * \param agSASIdentify the SAS identify frame will be sent by the phy 746 * 747 * \return If the MPI command is sent to SPC successfully 748 * - \e AGSA_RC_SUCCESS the MPI command is successfully 749 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 750 * - \e AGSA_RC_FAILURE the MPI command is failure 751 * 752 */ 753 /*******************************************************************************/ 754 GLOBAL bit32 mpiPhyStartCmd( 755 agsaRoot_t *agRoot, 756 bit32 tag, 757 bit32 phyId, 758 agsaPhyConfig_t *agPhyConfig, 759 agsaSASIdentify_t *agSASIdentify, 760 bit32 queueNum 761 ) 762 { 763 bit32 ret = AGSA_RC_SUCCESS; 764 agsaPhyStartCmd_t payload; 765 bit32 *pValue; 766 bit32 *ptemp; 767 bit32 index; 768 bit32 dw2 = 0; 769 770 #if defined(SALLSDK_DEBUG) 771 bit32 Sscd; 772 #endif /* SALLSDK_DEBUG */ 773 smTraceFuncEnter(hpDBG_VERY_LOUD,"xg"); 774 775 /* set payload to zeros */ 776 si_memset(&payload, 0, sizeof(agsaPhyStartCmd_t)); 777 778 pValue = (bit32 *)agSASIdentify; 779 ptemp = (bit32 *)&payload.sasIdentify; 780 index = (agPhyConfig->phyProperties & 0x0ff00) >> SHIFT8; 781 782 #if defined(SALLSDK_DEBUG) 783 Sscd = (agPhyConfig->phyProperties & 0xf0000) >> SHIFT16; 784 #endif /* SALLSDK_DEBUG */ 785 786 SA_DBG1(("mpiPhyStartCmd,phyId = %d dw 2 0x%08X\n",phyId ,((phyId & SM_PHYID_MASK) | ((agPhyConfig->phyProperties & 0xfff) << SHIFT8) | (agPhyConfig->phyProperties & 0xf0000) ))); 787 788 789 SA_DBG2(("mpiPhyStartCmd,phyId 0x%x phyProperties 0x%x index 0x%x Sscd 0x%x\n",phyId, agPhyConfig->phyProperties,index,Sscd)); 790 791 dw2 = ((phyId & SM_PHYID_MASK) | /* PHY id */ 792 ((agPhyConfig->phyProperties & 0x000000FF) << SHIFT8)| /* SLR Mode */ 793 (agPhyConfig->phyProperties & 0x000f0000) | /* SSCD */ 794 (agPhyConfig->phyProperties & 0x00700000) | /* setting bit20, bit21 and bit22 for optical mode */ 795 (agPhyConfig->phyProperties & 0x00800000) ); /* bit23 active cable mode BCT Disable 12g only*/ 796 797 /* Haileah Phy analogsetting bit enable*/ 798 if(smIS_SPC(agRoot)) 799 { 800 if( smIS_spc8081(agRoot)) 801 { 802 dw2 = dw2 | 0x08000; 803 } 804 } 805 806 SA_DBG1(("mpiPhyStartCmd,dw2 0x%08x\n",dw2)); 807 SA_ASSERT(((agSASIdentify->sasAddressHi[0] || agSASIdentify->sasAddressHi[1] || 808 agSASIdentify->sasAddressHi[2] || agSASIdentify->sasAddressHi[3] || 809 agSASIdentify->sasAddressLo[0] || agSASIdentify->sasAddressLo[1] || 810 agSASIdentify->sasAddressLo[2] || agSASIdentify->sasAddressLo[3])), "SAS Address Zero"); 811 812 SA_DBG1(("mpiPhyStartCmd,SAS addr Hi 0x%02X%02X%02X%02X Lo 0x%02X%02X%02X%02X\n", 813 agSASIdentify->sasAddressHi[0],agSASIdentify->sasAddressHi[1], 814 agSASIdentify->sasAddressHi[2],agSASIdentify->sasAddressHi[3], 815 agSASIdentify->sasAddressLo[0],agSASIdentify->sasAddressLo[1], 816 agSASIdentify->sasAddressLo[2],agSASIdentify->sasAddressLo[3])); 817 818 /* setup phy ID field */ 819 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPhyStartCmd_t, SscdAseSHLmMlrPhyId),dw2); 820 821 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPhyStartCmd_t, tag), tag); 822 823 /* setup analog setting index field */ 824 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPhyStartCmd_t, analogSetupIdx), index); 825 /* copy SASIdentify to payload of IOMB */ 826 si_memcpy(ptemp, pValue, sizeof(agsaSASIdentify_t)); 827 828 /* build IOMB command and send to SPC */ 829 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_PHYSTART, IOMB_SIZE64, queueNum); 830 831 SA_DBG3(("mpiPhyStartCmd, return value = %d\n", ret)); 832 833 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xg"); 834 return ret; 835 } 836 837 /******************************************************************************/ 838 /*! \brief SPC MPI Phy Stop Command 839 * 840 * This command sends to SPC for the I/O. 841 * 842 * \param agRoot Handles for this instance of SAS/SATA LLL 843 * \param tag tag of IOMB 844 * \param phyId To stop the phyId 845 * 846 * \return If the MPI command is sent to SPC successfully 847 * - \e AGSA_RC_SUCCESS the MPI command is successfully 848 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 849 * - \e AGSA_RC_FAILURE the MPI command is failure 850 * 851 */ 852 /*******************************************************************************/ 853 GLOBAL bit32 mpiPhyStopCmd( 854 agsaRoot_t *agRoot, 855 bit32 tag, 856 bit32 phyId, 857 bit32 queueNum 858 ) 859 { 860 bit32 ret = AGSA_RC_SUCCESS; 861 agsaPhyStopCmd_t payload; 862 863 smTraceFuncEnter(hpDBG_VERY_LOUD,"xh"); 864 865 /* set payload to zeros */ 866 si_memset(&payload, 0, sizeof(agsaPhyStopCmd_t)); 867 868 /* set tag */ 869 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPhyStopCmd_t, tag), tag); 870 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPhyStopCmd_t, phyId), (phyId & SM_PHYID_MASK )); 871 /* build IOMB command and send to SPC */ 872 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_PHYSTOP, IOMB_SIZE64, queueNum); 873 874 SA_DBG3(("mpiPhyStopCmd, return value = %d\n", ret)); 875 876 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xh"); 877 878 return ret; 879 } 880 881 /******************************************************************************/ 882 /*! \brief SPC MPI SMP Request Command 883 * 884 * This command sends to SPC for the SMP. 885 * 886 * \param agRoot Handles for this instance of SAS/SATA LLL 887 * \param pIomb pointer of IOMB 888 * \param opcode opcode of IOMB 889 * \param payload pointer of payload 890 * \param inq inbound queue number 891 * \param outq outbound queue number 892 * 893 * \return If the MPI command is sent to SPC successfully 894 * - \e AGSA_RC_SUCCESS the MPI command is successfully 895 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 896 * - \e AGSA_RC_FAILURE the MPI command is failure 897 * 898 */ 899 /*******************************************************************************/ 900 GLOBAL bit32 mpiSMPCmd( 901 agsaRoot_t *agRoot, 902 void *pIomb, 903 bit16 opcode, 904 agsaSMPCmd_t *payload, 905 bit8 inq, 906 bit8 outq 907 ) 908 { 909 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 910 mpiICQueue_t *circularQ; 911 bit32 ret = AGSA_RC_SUCCESS; 912 #if defined(SALLSDK_DEBUG) 913 mpiMsgHeader_t *msgHeader; 914 bit32 bc; 915 #endif /* SALLSDK_DEBUG */ 916 smTraceFuncEnter(hpDBG_VERY_LOUD,"xi"); 917 918 SA_DBG6(("mpiSMPCmd: start\n")); 919 920 #if defined(SALLSDK_DEBUG) 921 msgHeader = (mpiMsgHeader_t*)(((bit8*)pIomb) - sizeof(mpiMsgHeader_t)); 922 bc = (((msgHeader->Header) >> SHIFT24) & BC_MASK); 923 #endif /* SALLSDK_DEBUG */ 924 SA_DBG6(("mpiSMPCmd: before msgHeader bc %d\n", bc)); 925 926 /* copy payload if it is necessary */ 927 if (agNULL != payload) 928 { 929 si_memcpy(pIomb, payload, sizeof(agsaSMPCmd_t)); 930 } 931 932 SA_DBG6(("mpiSMPCmd: after msgHeader bc %d\n", bc)); 933 934 /* post the IOMB to SPC */ 935 circularQ = &saRoot->inboundQueue[inq]; 936 if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pIomb, MPI_CATEGORY_SAS_SATA, opcode, outq, (bit8)circularQ->priority)) 937 ret = AGSA_RC_FAILURE; 938 939 SA_DBG3(("mpiSMPCmd, return value = %d\n", ret)); 940 941 /* return value */ 942 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xi"); 943 return ret; 944 } 945 946 /******************************************************************************/ 947 /*! \brief SPC MPI Deregister Device Handle Command 948 * 949 * This command used to deregister(remove) the device handle. 950 * 951 * \param agRoot Handles for this instance of SAS/SATA LLL 952 * \param agDevHandle Device Handle 953 * \param deviceId index of device 954 * \param portId index of port 955 * \param queueNum IQ/OQ number 956 * 957 * \return If the MPI command is sent to SPC successfully 958 * - \e AGSA_RC_SUCCESS the MPI command is successfully 959 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 960 * - \e AGSA_RC_FAILURE the MPI command is failure 961 * 962 */ 963 /*******************************************************************************/ 964 GLOBAL bit32 mpiDeregDevHandleCmd( 965 agsaRoot_t *agRoot, 966 agsaContext_t *agContext, 967 agsaDeviceDesc_t *pDevice, 968 bit32 deviceId, 969 bit32 portId, 970 bit32 queueNum 971 ) 972 { 973 bit32 ret = AGSA_RC_SUCCESS; 974 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 975 agsaIORequestDesc_t *pRequest; 976 agsaDeregDevHandleCmd_t payload; 977 978 smTraceFuncEnter(hpDBG_VERY_LOUD,"xp"); 979 980 /* Get request from free IORequests */ 981 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 982 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 983 984 /* If no LL Control request entry available */ 985 if ( agNULL == pRequest ) 986 { 987 SA_DBG1(("mpiDeregDevHandleCmd, No request from free list\n" )); 988 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xp"); 989 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 990 return AGSA_RC_BUSY; 991 } 992 /* If LL Control request entry avaliable */ 993 else 994 { 995 pRequest->pDevice = pDevice; 996 /* Remove the request from free list */ 997 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 998 pRequest->valid = agTRUE; 999 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 1000 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 1001 saRoot->IOMap[pRequest->HTag].agContext = agContext; 1002 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1003 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1004 1005 /* clean the payload to zeros */ 1006 si_memset(&payload, 0, sizeof(agsaDeregDevHandleCmd_t)); 1007 1008 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDeregDevHandleCmd_t, tag), pRequest->HTag); 1009 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDeregDevHandleCmd_t, deviceId), deviceId); 1010 1011 /* build IOMB command and send it to SPC */ 1012 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_DEREG_DEV_HANDLE, IOMB_SIZE64, queueNum); 1013 if (AGSA_RC_SUCCESS != ret) 1014 { 1015 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1016 /* remove the request from IOMap */ 1017 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 1018 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 1019 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 1020 pRequest->valid = agFALSE; 1021 1022 /* return the request to free pool */ 1023 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1024 1025 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1026 SA_DBG1(("mpiSetVPDCmd, sending IOMB failed\n" )); 1027 } 1028 SA_DBG3(("mpiDeregDevHandleCmd, return value = %d\n", ret)); 1029 } 1030 1031 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xp"); 1032 1033 /* return value */ 1034 return ret; 1035 } 1036 1037 /******************************************************************************/ 1038 /*! \brief SPC MPI Get Device Handle Command 1039 * 1040 * This command used to get device handle. 1041 * 1042 * \param agRoot Handles for this instance of SAS/SATA LLL 1043 * \param agContext Context of Device Handle Command 1044 * \param portId index of port 1045 * \param flags flags 1046 * \param maxDevs Maximum Device Handles 1047 * \param queueNum IQ/OQ number 1048 * \param skipCount skip device entry count 1049 * 1050 * \return If the MPI command is sent to SPC successfully 1051 * - \e AGSA_RC_SUCCESS the MPI command is successfully 1052 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 1053 * - \e AGSA_RC_FAILURE the MPI command is failure 1054 * 1055 */ 1056 /*******************************************************************************/ 1057 GLOBAL bit32 mpiGetDeviceHandleCmd( 1058 agsaRoot_t *agRoot, 1059 agsaContext_t *agContext, 1060 bit32 portId, 1061 bit32 flags, 1062 bit32 maxDevs, 1063 bit32 queueNum, 1064 bit32 skipCount 1065 ) 1066 { 1067 bit32 ret = AGSA_RC_SUCCESS; 1068 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 1069 agsaIORequestDesc_t *pRequest; 1070 agsaGetDevHandleCmd_t payload; 1071 bit32 using_reserved = agFALSE; 1072 1073 smTraceFuncEnter(hpDBG_VERY_LOUD,"xj"); 1074 1075 /* Get request from free CntrlRequests */ 1076 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1077 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 1078 1079 /* If no LL Control request entry available */ 1080 if ( agNULL == pRequest ) 1081 { 1082 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests)); /**/ 1083 if(agNULL != pRequest) 1084 { 1085 using_reserved = agTRUE; 1086 SA_DBG1(("mpiGetDeviceHandleCmd, using saRoot->freeReservedRequests\n")); 1087 } 1088 else 1089 { 1090 SA_DBG1(("mpiGetDeviceHandleCmd, No request from free list Not using saRoot->freeReservedRequests\n")); 1091 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xj"); 1092 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1093 return AGSA_RC_BUSY; 1094 } 1095 } 1096 1097 /* Remove the request from free list */ 1098 if( using_reserved ) 1099 { 1100 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 1101 } 1102 else 1103 { 1104 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1105 } 1106 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 1107 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 1108 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 1109 saRoot->IOMap[pRequest->HTag].agContext = agContext; 1110 pRequest->valid = agTRUE; 1111 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1112 1113 1114 /* clean the payload to zeros */ 1115 si_memset(&payload, 0, sizeof(agsaGetDevHandleCmd_t)); 1116 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDevHandleCmd_t, tag), pRequest->HTag); 1117 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDevHandleCmd_t, DevADevTMaxDIDportId), 1118 ((portId & PORTID_MASK) | (maxDevs << SHIFT8) | (flags << SHIFT24))); 1119 /* set starting Number */ 1120 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDevHandleCmd_t, skipCount), skipCount); 1121 1122 /* build IOMB command and send it to SPC */ 1123 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_DEV_HANDLE, IOMB_SIZE64, queueNum); 1124 if (AGSA_RC_SUCCESS != ret) 1125 { 1126 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1127 /* remove the request from IOMap */ 1128 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 1129 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 1130 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 1131 pRequest->valid = agFALSE; 1132 /* return the request to free pool */ 1133 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) 1134 { 1135 SA_DBG1(("mpiGetDeviceHandleCmd: saving pRequest (%p) for later use\n", pRequest)); 1136 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 1137 } 1138 else 1139 { 1140 /* return the request to free pool */ 1141 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1142 } 1143 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1144 1145 SA_DBG1(("mpiGetDeviceHandleCmd, sending IOMB failed\n" )); 1146 } 1147 SA_DBG3(("mpiGetDeviceHandleCmd, return value = %d\n", ret)); 1148 1149 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xj"); 1150 1151 return ret; 1152 } 1153 1154 /******************************************************************************/ 1155 /*! \brief SPC MPI LOCAL PHY CONTROL Command 1156 * 1157 * This command used to do the SPC Phy operation. 1158 * 1159 * \param agRoot Handles for this instance of SAS/SATA LLL 1160 * \param tag tag of IOMB 1161 * \param phyId PHY Id 1162 * \param operation operation of PHY control 1163 * \param queueNum IQ/OQ number 1164 * 1165 * \return If the MPI command is sent to SPC successfully 1166 * - \e AGSA_RC_SUCCESS the MPI command is successfully 1167 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 1168 * - \e AGSA_RC_FAILURE the MPI command is failure 1169 * 1170 */ 1171 /*******************************************************************************/ 1172 GLOBAL bit32 mpiLocalPhyControlCmd( 1173 agsaRoot_t *agRoot, 1174 bit32 tag, 1175 bit32 phyId, 1176 bit32 operation, 1177 bit32 queueNum 1178 ) 1179 { 1180 bit32 ret = AGSA_RC_SUCCESS; 1181 agsaLocalPhyCntrlCmd_t payload; 1182 smTraceFuncEnter(hpDBG_VERY_LOUD,"xl"); 1183 1184 SA_DBG3(("mpiLocalPhyControlCmd, phyId 0x%X operation 0x%x dw2 0x%x\n",phyId, operation,(((operation & BYTE_MASK) << SHIFT8) | (phyId & SM_PHYID_MASK)))); 1185 1186 /* clean the payload field */ 1187 si_memset(&payload, 0, sizeof(agsaLocalPhyCntrlCmd_t)); 1188 1189 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaLocalPhyCntrlCmd_t, phyOpPhyId), 1190 (((operation & BYTE_MASK) << SHIFT8) | (phyId & SM_PHYID_MASK))); 1191 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaLocalPhyCntrlCmd_t, tag), tag); 1192 /* build IOMB command and send to SPC */ 1193 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_LOCAL_PHY_CONTROL, IOMB_SIZE64, queueNum); 1194 1195 SA_DBG3(("mpiLocalPhyControlCmd, return value = %d\n", ret)); 1196 1197 /* return value */ 1198 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xl"); 1199 return ret; 1200 } 1201 1202 /******************************************************************************/ 1203 /*! \brief Device Handle Accept Command 1204 * 1205 * This command is Device Handle Accept IOMB to SPC. 1206 * 1207 * \param agRoot Handles for this instance of SAS/SATA LLL 1208 * \param agContext Context for the set VPD command 1209 * \param ctag controller tag 1210 * \param deviceId device Id 1211 * \param action action 1212 * \param queueNum queue Number 1213 * 1214 * \return If the MPI command is sent to SPC successfully 1215 * - \e AGSA_RC_SUCCESS the MPI command is successfully 1216 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 1217 * - \e AGSA_RC_FAILURE the MPI command is failure 1218 * 1219 */ 1220 /*******************************************************************************/ 1221 GLOBAL bit32 mpiDevHandleAcceptCmd( 1222 agsaRoot_t *agRoot, 1223 agsaContext_t *agContext, 1224 bit32 ctag, 1225 bit32 deviceId, 1226 bit32 action, 1227 bit32 flag, 1228 bit32 itlnx, 1229 bit32 queueNum 1230 ) 1231 { 1232 bit32 ret = AGSA_RC_SUCCESS; 1233 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 1234 agsaIORequestDesc_t *pRequest; 1235 agsaDevHandleAcceptCmd_t payload; 1236 bit32 DW4 =0; 1237 bit32 mcn =0; 1238 bit32 awt =0; 1239 bit32 ha =0; 1240 1241 smTraceFuncEnter(hpDBG_VERY_LOUD,"xt"); 1242 1243 if(deviceId & 0xFFFF0000) 1244 { 1245 ha = 1; 1246 } 1247 /* Get request from free IORequests */ 1248 ossaSingleThreadedEnter(agRoot,LL_IOREQ_LOCKEQ_LOCK ); 1249 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 1250 1251 SA_DBG2(("mpiDevHandleAcceptCmd, deviceId 0x%x action 0x%x flag 0x%x itlnx 0x%x\n",deviceId,action,flag,itlnx )); 1252 1253 /* If no LL Control request entry available */ 1254 if ( agNULL == pRequest ) 1255 { 1256 ossaSingleThreadedLeave(agRoot,LL_IOREQ_LOCKEQ_LOCK ); 1257 SA_DBG1(("mpiDevHandleAcceptCmd, No request from free list\n" )); 1258 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xt"); 1259 return AGSA_RC_BUSY; 1260 } 1261 /* If LL Control request entry avaliable */ 1262 else 1263 { 1264 /* Remove the request from free list */ 1265 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 1266 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1267 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 1268 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 1269 saRoot->IOMap[pRequest->HTag].agContext = agContext; 1270 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1271 1272 /* Do not mark as valid at this IOMB does not complete in OBQ */ 1273 1274 /* set payload to zeros */ 1275 si_memset(&payload, 0, sizeof(agsaDevHandleAcceptCmd_t)); 1276 1277 /* set tag field */ 1278 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDevHandleAcceptCmd_t, tag), pRequest->HTag); 1279 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDevHandleAcceptCmd_t, deviceId), deviceId); 1280 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDevHandleAcceptCmd_t, Ctag), ctag); 1281 mcn = (flag & 0xF0000) >>SHIFT16; 1282 awt = (flag & 2)>>SHIFT1; 1283 DW4 = (action << SHIFT24) | \ 1284 mcn << SHIFT20 | \ 1285 awt << SHIFT17 | \ 1286 ha << SHIFT16 | \ 1287 itlnx; 1288 SA_DBG2(("mpiDevHandleAcceptCmd,DW4 0x%x\n",DW4 )); 1289 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDevHandleAcceptCmd_t, DevA_MCN_R_R_HA_ITNT),DW4); 1290 } 1291 1292 /* build IOMB command and send to SPC */ 1293 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_DEV_HANDLE_ACCEPT, IOMB_SIZE64, queueNum); 1294 if (AGSA_RC_SUCCESS != ret) 1295 { 1296 SA_DBG1(("mpiDevHandleAcceptCmd, sending IOMB failed\n" )); 1297 } 1298 else 1299 { 1300 SA_DBG1(("mpiDevHandleAcceptCmd, sending IOMB succeeded\n" )); 1301 } 1302 1303 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1304 /* remove the request from IOMap */ 1305 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 1306 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 1307 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 1308 pRequest->valid = agFALSE; 1309 /* return the request to free pool */ 1310 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) 1311 { 1312 SA_DBG1(("mpiDevHandleAcceptCmd: saving pRequest (%p) for later use\n", pRequest)); 1313 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 1314 } 1315 else 1316 { 1317 /* return the request to free pool */ 1318 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1319 } 1320 1321 /* return value */ 1322 ossaSingleThreadedLeave(agRoot,LL_IOREQ_LOCKEQ_LOCK ); 1323 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xt"); 1324 return ret; 1325 } 1326 1327 /******************************************************************************/ 1328 /*! \brief SPC READ REGISTER DUMP Command 1329 * 1330 * This command used to do the SPC Read Register Dump command. 1331 * 1332 * \param agRoot Handles for this instance of SAS/SATA LLL 1333 * \param tag tag of IOMB 1334 * \param cpuId CPU Id 1335 * \param queueNum IQ/OQ number 1336 * \param cpuId AAP1 or IOP 1337 * \param cOffset offset of the register dump data 1338 * \param addrHi Hi address if Register Dump data 1339 * \param addrHi Low address if Register Dump data 1340 * \param len the length of for read 1341 * 1342 * \return If the MPI command is sent to SPC successfully 1343 * - \e AGSA_RC_SUCCESS the MPI command is successfully 1344 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 1345 * - \e AGSA_RC_FAILURE the MPI command is failure 1346 * 1347 */ 1348 /*******************************************************************************/ 1349 GLOBAL bit32 mpiNVMReadRegDumpCmd( 1350 agsaRoot_t *agRoot, 1351 agsaContext_t *agContext, 1352 bit32 queueNum, 1353 bit32 cpuId, 1354 bit32 cOffset, 1355 bit32 addrHi, 1356 bit32 addrLo, 1357 bit32 len 1358 ) 1359 { 1360 bit32 ret = AGSA_RC_SUCCESS; 1361 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 1362 agsaIORequestDesc_t *pRequest; 1363 agsaGetNVMDataCmd_t payload; 1364 bit32 nvmd = 0; 1365 1366 smTraceFuncEnter(hpDBG_VERY_LOUD,"xk"); 1367 1368 /* Get request from free IORequests */ 1369 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1370 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 1371 1372 /* If no LL Control request entry available */ 1373 if ( agNULL == pRequest ) 1374 { 1375 SA_DBG1(("mpiNVMReadRegDumpCmd, No request from free list\n" )); 1376 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xk"); 1377 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1378 return AGSA_RC_BUSY; 1379 } 1380 /* If LL Control request entry avaliable */ 1381 else 1382 { 1383 /* Remove the request from free list */ 1384 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 1385 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1386 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 1387 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 1388 saRoot->IOMap[pRequest->HTag].agContext = agContext; 1389 pRequest->valid = agTRUE; 1390 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1391 1392 /* clean the payload field */ 1393 si_memset(&payload, 0, sizeof(agsaGetNVMDataCmd_t)); 1394 1395 /* only indirect mode */ 1396 if (cpuId <= 1) 1397 { 1398 if (cpuId == 0) 1399 nvmd = AAP1_RDUMP | IRMode; 1400 else 1401 nvmd = IOP_RDUMP | IRMode; 1402 1403 /* setup IOMB */ 1404 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, tag), pRequest->HTag); 1405 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, LEN_IR_VPDD), nvmd); 1406 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, VPDOffset), cOffset); 1407 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, respAddrLo), addrLo); 1408 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, respAddrHi), addrHi); 1409 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, respLen), len); 1410 1411 /* build IOMB command and send to SPC */ 1412 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_NVMD_DATA, IOMB_SIZE64, queueNum); 1413 } 1414 else 1415 { 1416 SA_DBG1(("mpiNVMReadRegDumpCmd, Wrong device type\n" )); 1417 ret = AGSA_RC_FAILURE; 1418 } 1419 1420 if (AGSA_RC_SUCCESS != ret) 1421 { 1422 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1423 /* remove the request from IOMap */ 1424 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 1425 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 1426 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 1427 pRequest->valid = agFALSE; 1428 /* return the request to free pool */ 1429 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1430 1431 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1432 SA_DBG1(("mpiNVMReadRegDumpCmd, sending IOMB failed\n" )); 1433 } 1434 } 1435 1436 SA_DBG3(("mpiNVMReadRegDumpCmd, return value = %d\n", ret)); 1437 1438 /* return value */ 1439 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xk"); 1440 1441 return ret; 1442 } 1443 1444 /******************************************************************************/ 1445 /*! \brief Get NVM Data command 1446 * 1447 * This command is get NVM Data from SPC. 1448 * 1449 * \param agRoot Handles for this instance of SAS/SATA LLL 1450 * \param agContext Context for the VPD command 1451 * \param VPDInfo Pointer of VPD Information 1452 * \param queueNum Queue Number of inbound/outbound queue 1453 * 1454 * \return If the MPI command is sent to SPC successfully 1455 * - \e AGSA_RC_SUCCESS the MPI command is successfully 1456 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 1457 * - \e AGSA_RC_FAILURE the MPI command is failure 1458 * 1459 */ 1460 /*******************************************************************************/ 1461 GLOBAL bit32 mpiGetNVMDCmd( 1462 agsaRoot_t *agRoot, 1463 agsaContext_t *agContext, 1464 agsaNVMDData_t *NVMDInfo, 1465 bit32 queueNum 1466 ) 1467 { 1468 bit32 ret = AGSA_RC_FAILURE; 1469 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 1470 agsaIORequestDesc_t *pRequest; 1471 agsaGetNVMDataCmd_t payload; 1472 1473 smTraceFuncEnter(hpDBG_VERY_LOUD,"xr"); 1474 1475 /* Get request from free IORequests */ 1476 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1477 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 1478 1479 /* If no LL Control request entry available */ 1480 if ( agNULL == pRequest ) 1481 { 1482 SA_DBG1(("mpiGetNVMDCmd, No request from free list\n" )); 1483 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xr"); 1484 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1485 return AGSA_RC_BUSY; 1486 } 1487 /* If LL Control request entry avaliable */ 1488 else 1489 { 1490 SA_DBG3(("mpiGetNVMDCmd, Build IOMB NVMDDevice= 0x%x\n", NVMDInfo->NVMDevice)); 1491 /* Remove the request from free list */ 1492 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 1493 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1494 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 1495 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 1496 saRoot->IOMap[pRequest->HTag].agContext = agContext; 1497 pRequest->valid = agTRUE; 1498 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1499 1500 /* set payload to zeros */ 1501 si_memset(&payload, 0, sizeof(agsaGetNVMDataCmd_t)); 1502 /* set tag field */ 1503 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, tag), pRequest->HTag); 1504 1505 if (NVMDInfo->indirectPayload) 1506 { 1507 /* indirect payload IP = 1 */ 1508 switch (NVMDInfo->NVMDevice) 1509 { 1510 case AGSA_NVMD_TWI_DEVICES: 1511 /* NVMD = 0 */ 1512 /* indirect payload IP = 1 and 0x0 (TWI) */ 1513 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, LEN_IR_VPDD), 1514 (NVMDInfo->TWIDeviceAddress << 16) | (NVMDInfo->TWIBusNumber << 12) | 1515 (NVMDInfo->TWIDevicePageSize << 8) | (NVMDInfo->TWIDeviceAddressSize << 4) | 1516 (NVMDInfo->indirectPayload << 31) | NVMDInfo->NVMDevice); 1517 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, VPDOffset), 1518 NVMDInfo->dataOffsetAddress); 1519 break; 1520 case AGSA_NVMD_CONFIG_SEEPROM: 1521 /* NVMD = 1 */ 1522 /* Data Offset should be 0 */ 1523 if (NVMDInfo->dataOffsetAddress != 0) 1524 { 1525 /* Error for Offset */ 1526 SA_DBG1(("mpiGetNVMDCmd, (IP=1)wrong offset = 0x%x\n", NVMDInfo->dataOffsetAddress)); 1527 } 1528 /* indirect payload IP = 1, NVMD = 0x1 (SEEPROM0) */ 1529 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, LEN_IR_VPDD), 1530 (NVMDInfo->indirectPayload << SHIFT31) | (NVMDInfo->NVMDevice)); 1531 break; 1532 case AGSA_NVMD_VPD_FLASH: 1533 /* indirect payload IP = 1 and 0x4 (FLASH) */ 1534 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, LEN_IR_VPDD), 1535 (NVMDInfo->indirectPayload << SHIFT31) | NVMDInfo->NVMDevice); 1536 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, VPDOffset), 1537 NVMDInfo->dataOffsetAddress); 1538 break; 1539 case AGSA_NVMD_EXPANSION_ROM: 1540 /* indirect payload IP = 1 and 0x7 (EXPANSION ROM PARTITION) */ 1541 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, LEN_IR_VPDD), 1542 (NVMDInfo->indirectPayload << SHIFT31) | NVMDInfo->NVMDevice); 1543 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, VPDOffset), 1544 NVMDInfo->dataOffsetAddress); 1545 break; 1546 case AGSA_NVMD_AAP1_REG_FLASH: /* AGSA_NVMD_REG_FLASH SPCv uses 5 as well */ 1547 /* indirect payload IP = 1 and 0x5 (AGSA_NVMD_AAP1_REG_FLASH ) */ 1548 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, LEN_IR_VPDD), 1549 (NVMDInfo->indirectPayload << SHIFT31) | NVMDInfo->NVMDevice); 1550 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, VPDOffset), 1551 NVMDInfo->dataOffsetAddress); 1552 break; 1553 case AGSA_NVMD_IOP_REG_FLASH: 1554 /* indirect payload IP = 1 and 0x6 ( AGSA_NVMD_IOP_REG_FLASH ) */ 1555 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, LEN_IR_VPDD), 1556 (NVMDInfo->indirectPayload << SHIFT31) | NVMDInfo->NVMDevice); 1557 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, VPDOffset), 1558 NVMDInfo->dataOffsetAddress); 1559 break; 1560 1561 default: 1562 SA_DBG1(("mpiGetNVMDCmd, (IP=1)wrong device type = 0x%x\n", NVMDInfo->NVMDevice)); 1563 break; 1564 } 1565 1566 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, respAddrLo), NVMDInfo->indirectAddrLower32); 1567 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, respAddrHi), NVMDInfo->indirectAddrUpper32); 1568 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, respLen), NVMDInfo->indirectLen); 1569 /* build IOMB command and send to SPC */ 1570 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_NVMD_DATA, IOMB_SIZE64, queueNum); 1571 } 1572 else 1573 { 1574 /* direct payload IP = 0 only for TWI device */ 1575 if (AGSA_NVMD_TWI_DEVICES == NVMDInfo->NVMDevice) 1576 { 1577 /* NVMD = 0 */ 1578 /* indirect payload IP = 0 and 0x0 (TWI) */ 1579 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, LEN_IR_VPDD), 1580 (NVMDInfo->TWIDeviceAddress << SHIFT16) | (NVMDInfo->TWIBusNumber << SHIFT12) | 1581 (NVMDInfo->TWIDevicePageSize << SHIFT8) | (NVMDInfo->TWIDeviceAddressSize << SHIFT4) | 1582 NVMDInfo->NVMDevice); 1583 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, VPDOffset), 1584 NVMDInfo->dataOffsetAddress | (NVMDInfo->directLen << SHIFT24)); 1585 /* build IOMB command and send to SPC */ 1586 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_NVMD_DATA, IOMB_SIZE64, queueNum); 1587 } 1588 else 1589 { 1590 SA_DBG1(("mpiGetNVMDCmd, (IP=0)wrong device type = 0x%x\n", NVMDInfo->NVMDevice)); 1591 ret = AGSA_RC_FAILURE; 1592 /* CB for NVMD with error */ 1593 ossaGetNVMDResponseCB(agRoot, agContext, OSSA_NVMD_MODE_ERROR, 0, NVMDInfo->directLen, agNULL); 1594 } 1595 } 1596 1597 if (AGSA_RC_SUCCESS != ret) 1598 { 1599 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1600 /* remove the request from IOMap */ 1601 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 1602 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 1603 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 1604 pRequest->valid = agFALSE; 1605 1606 /* return the request to free pool */ 1607 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1608 1609 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1610 SA_DBG1(("mpiGetNVMDCmd, sending IOMB failed\n" )); 1611 } 1612 SA_DBG3(("mpiGetNVMDCmd, return value = %d\n", ret)); 1613 } 1614 1615 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xr"); 1616 1617 /* return value */ 1618 return ret; 1619 } 1620 1621 /******************************************************************************/ 1622 /*! \brief Set NVM Data Command 1623 * 1624 * This command is set NVM Data to SPC. 1625 * 1626 * \param agRoot Handles for this instance of SAS/SATA LLL 1627 * \param agContext Context for the set VPD command 1628 * \param NVMDInfo pointer of VPD information 1629 * \param queueNum queue Number 1630 * 1631 * \return If the MPI command is sent to SPC successfully 1632 * - \e AGSA_RC_SUCCESS the MPI command is successfully 1633 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 1634 * - \e AGSA_RC_FAILURE the MPI command is failure 1635 * 1636 */ 1637 /*******************************************************************************/ 1638 GLOBAL bit32 mpiSetNVMDCmd( 1639 agsaRoot_t *agRoot, 1640 agsaContext_t *agContext, 1641 agsaNVMDData_t *NVMDInfo, 1642 bit32 queueNum 1643 ) 1644 { 1645 bit32 ret = AGSA_RC_FAILURE; 1646 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 1647 agsaIORequestDesc_t *pRequest; 1648 agsaSetNVMDataCmd_t payload; 1649 1650 smTraceFuncEnter(hpDBG_VERY_LOUD,"xm"); 1651 1652 1653 /* Get request from free IORequests */ 1654 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1655 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 1656 1657 /* If no LL Control request entry available */ 1658 if ( agNULL == pRequest ) 1659 { 1660 SA_DBG1(("mpiSetNVMDCmd, No request from free list\n" )); 1661 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xm"); 1662 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1663 return AGSA_RC_BUSY; 1664 } 1665 /* If LL Control request entry avaliable */ 1666 else 1667 { 1668 SA_DBG3(("mpiSetNVMDCmd, Build IOMB NVMDDevice= 0x%x\n", NVMDInfo->NVMDevice)); 1669 /* Remove the request from free list */ 1670 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 1671 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1672 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 1673 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 1674 saRoot->IOMap[pRequest->HTag].agContext = agContext; 1675 pRequest->valid = agTRUE; 1676 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1677 1678 /* set payload to zeros */ 1679 si_memset(&payload, 0, sizeof(agsaSetNVMDataCmd_t)); 1680 1681 /* set tag field */ 1682 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, tag), pRequest->HTag); 1683 1684 if (NVMDInfo->indirectPayload) 1685 { 1686 /* indirect payload IP = 1 */ 1687 switch (NVMDInfo->NVMDevice) 1688 { 1689 case AGSA_NVMD_TWI_DEVICES: 1690 /* NVMD = 0 */ 1691 /* indirect payload IP = 1 and 0x0 (TWI) */ 1692 /* set up signature */ 1693 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, Data.indirectData.signature), NVMDInfo->signature); 1694 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, LEN_IR_VPDD), 1695 (NVMDInfo->TWIDeviceAddress << SHIFT16) | (NVMDInfo->TWIBusNumber << SHIFT12) | 1696 (NVMDInfo->TWIDevicePageSize << SHIFT8) | (NVMDInfo->TWIDeviceAddressSize << SHIFT4) | 1697 (NVMDInfo->indirectPayload << SHIFT31) | NVMDInfo->NVMDevice); 1698 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, VPDOffset), 1699 NVMDInfo->dataOffsetAddress); 1700 break; 1701 /* 0x01:SEEPROM-0 and 0x04:FLASH only in indirect mode */ 1702 case AGSA_NVMD_CONFIG_SEEPROM: 1703 /* NVMD=1 */ 1704 /* Data Offset should be 0 */ 1705 /* set up signature */ 1706 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, Data.indirectData.signature), NVMDInfo->signature); 1707 /* indirect payload IP = 1, NVMD = 0x1 (SEEPROM0) */ 1708 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, LEN_IR_VPDD), 1709 (NVMDInfo->indirectPayload << SHIFT31) | NVMDInfo->NVMDevice); 1710 break; 1711 case AGSA_NVMD_VPD_FLASH: 1712 /* indirect payload IP = 1, NVMD=0x4 (FLASH) */ 1713 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, LEN_IR_VPDD), 1714 (NVMDInfo->indirectPayload << SHIFT31) | NVMDInfo->NVMDevice); 1715 /* set up Offset */ 1716 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, VPDOffset), 1717 NVMDInfo->dataOffsetAddress); 1718 break; 1719 default: 1720 SA_DBG1(("mpiSetNVMDCmd, (IP=1)wrong device type = 0x%x\n", NVMDInfo->NVMDevice)); 1721 ret = AGSA_RC_FAILURE; 1722 ossaSetNVMDResponseCB(agRoot, agContext, OSSA_NVMD_MODE_ERROR); 1723 break; 1724 } 1725 1726 /* set up SGL field */ 1727 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, Data.indirectData.ISglAL), (NVMDInfo->indirectAddrLower32)); 1728 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, Data.indirectData.ISglAH), (NVMDInfo->indirectAddrUpper32)); 1729 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, Data.indirectData.ILen), (NVMDInfo->indirectLen)); 1730 /* build IOMB command and send to SPC */ 1731 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SET_NVMD_DATA, IOMB_SIZE64, queueNum); 1732 } 1733 else 1734 { 1735 /* direct payload IP = 0 */ 1736 if (AGSA_NVMD_TWI_DEVICES == NVMDInfo->NVMDevice) 1737 { 1738 /* NVMD = 0 */ 1739 /* indirect payload IP = 0 and 0x0 (TWI) */ 1740 /* not allow write to Config SEEPROM for direct mode, so don't set singature */ 1741 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, LEN_IR_VPDD), 1742 (NVMDInfo->TWIDeviceAddress << SHIFT16) | (NVMDInfo->TWIBusNumber << SHIFT12) | 1743 (NVMDInfo->TWIDevicePageSize << SHIFT8) | (NVMDInfo->TWIDeviceAddressSize << SHIFT4) | 1744 NVMDInfo->NVMDevice); 1745 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, VPDOffset), 1746 NVMDInfo->dataOffsetAddress | (NVMDInfo->directLen << SHIFT24)); 1747 si_memcpy(&payload.Data.NVMData[0], NVMDInfo->directData, NVMDInfo->directLen); 1748 /* build IOMB command and send to SPC */ 1749 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SET_NVMD_DATA, IOMB_SIZE64, queueNum); 1750 } 1751 else 1752 { 1753 SA_DBG1(("mpiSetNVMDCmd, (IP=0)wrong device type = 0x%x\n", NVMDInfo->NVMDevice)); 1754 ret = AGSA_RC_FAILURE; 1755 ossaSetNVMDResponseCB(agRoot, agContext, OSSA_NVMD_MODE_ERROR); 1756 } 1757 } 1758 1759 if (AGSA_RC_SUCCESS != ret) 1760 { 1761 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1762 /* remove the request from IOMap */ 1763 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 1764 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 1765 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 1766 pRequest->valid = agFALSE; 1767 1768 /* return the request to free pool */ 1769 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1770 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1771 SA_DBG1(("mpiSetVPDCmd, sending IOMB failed\n" )); 1772 } 1773 SA_DBG3(("mpiSetNVMDCmd, return value = %d\n", ret)); 1774 } 1775 1776 1777 /* return value */ 1778 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xm"); 1779 return ret; 1780 } 1781 1782 /******************************************************************************/ 1783 /*! \brief Set Device State command 1784 * 1785 * This command is set Device State to SPC. 1786 * 1787 * \param agRoot Handles for this instance of SAS/SATA LLL 1788 * \param agContext Context for the Set Nexus State command 1789 * \param deviceId DeviceId 1790 * \param queueNum Queue Number of inbound/outbound queue 1791 * 1792 * \return If the MPI command is sent to SPC successfully 1793 * - \e AGSA_RC_SUCCESS the MPI command is successfully 1794 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 1795 * - \e AGSA_RC_FAILURE the MPI command is failure 1796 * 1797 */ 1798 /*******************************************************************************/ 1799 GLOBAL bit32 mpiSetDeviceStateCmd( 1800 agsaRoot_t *agRoot, 1801 agsaContext_t *agContext, 1802 bit32 deviceId, 1803 bit32 nds, 1804 bit32 queueNum 1805 ) 1806 { 1807 bit32 ret = AGSA_RC_SUCCESS; 1808 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 1809 agsaIORequestDesc_t *pRequest; 1810 agsaSetDeviceStateCmd_t payload; 1811 1812 smTraceFuncEnter(hpDBG_VERY_LOUD,"xn"); 1813 1814 /* Get request from free IORequests */ 1815 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1816 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 1817 1818 /* If no LL Control request entry available */ 1819 if ( agNULL == pRequest ) 1820 { 1821 SA_DBG1(("mpiSetDeviceStateCmd, No request from free list\n" )); 1822 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xn"); 1823 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1824 return AGSA_RC_BUSY; 1825 } 1826 /* If LL Control request entry avaliable */ 1827 else 1828 { 1829 SA_DBG3(("mpiSetDeviceStateCmd, Build IOMB DeviceId= 0x%x\n", deviceId)); 1830 /* Remove the request from free list */ 1831 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1832 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 1833 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 1834 saRoot->IOMap[pRequest->HTag].agContext = agContext; 1835 pRequest->valid = agTRUE; 1836 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1837 1838 /* set payload to zeros */ 1839 si_memset(&payload, 0, sizeof(agsaSetDeviceStateCmd_t)); 1840 /* set tag field */ 1841 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetDeviceStateCmd_t, tag), pRequest->HTag); 1842 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetDeviceStateCmd_t, deviceId), deviceId); 1843 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetDeviceStateCmd_t, NDS), nds); 1844 1845 /* build IOMB command and send to SPC */ 1846 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SET_DEVICE_STATE, IOMB_SIZE64, queueNum); 1847 if (AGSA_RC_SUCCESS != ret) 1848 { 1849 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1850 /* remove the request from IOMap */ 1851 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 1852 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 1853 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 1854 pRequest->valid = agFALSE; 1855 1856 /* return the request to free pool */ 1857 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1858 1859 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1860 1861 SA_DBG1(("mpiSetNexusStateCmd, sending IOMB failed\n" )); 1862 } 1863 SA_DBG3(("mpiSetDeviceStateCmd, return value = %d\n", ret)); 1864 } 1865 1866 /* return value */ 1867 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xn"); 1868 1869 return ret; 1870 } 1871 1872 /******************************************************************************/ 1873 /*! \brief Get Device State command 1874 * 1875 * This command is get device State to SPC. 1876 * 1877 * \param agRoot Handles for this instance of SAS/SATA LLL 1878 * \param agContext Context for the Get Nexus State command 1879 * \param deviceId DeviceId 1880 * \param queueNum Queue Number of inbound/outbound queue 1881 * 1882 * \return If the MPI command is sent to SPC successfully 1883 * - \e AGSA_RC_SUCCESS the MPI command is successfully 1884 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 1885 * - \e AGSA_RC_FAILURE the MPI command is failure 1886 * 1887 */ 1888 /*******************************************************************************/ 1889 GLOBAL bit32 mpiGetDeviceStateCmd( 1890 agsaRoot_t *agRoot, 1891 agsaContext_t *agContext, 1892 bit32 deviceId, 1893 bit32 queueNum 1894 ) 1895 { 1896 bit32 ret = AGSA_RC_SUCCESS; 1897 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 1898 agsaIORequestDesc_t *pRequest; 1899 agsaGetDeviceStateCmd_t payload; 1900 bit32 using_reserved = agFALSE; 1901 1902 smTraceFuncEnter(hpDBG_VERY_LOUD,"xf"); 1903 1904 /* Get request from free IORequests */ 1905 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1906 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 1907 1908 /* If no LL Control request entry available */ 1909 if ( agNULL == pRequest ) 1910 { 1911 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests)); /**/ 1912 /* If no LL Control request entry available */ 1913 if(agNULL != pRequest) 1914 { 1915 using_reserved = agTRUE; 1916 SA_DBG1(("mpiGetDeviceStateCmd, using saRoot->freeReservedRequests\n")); 1917 } 1918 else 1919 { 1920 SA_DBG1(("mpiGetDeviceStateCmd, No request from free list Not using saRoot->freeReservedRequests\n")); 1921 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xf"); 1922 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1923 return AGSA_RC_BUSY; 1924 } 1925 1926 } 1927 /* If LL Control request entry avaliable */ 1928 SA_DBG3(("mpiGetDeviceStateCmd, Build IOMB DeviceId= 0x%x\n", deviceId)); 1929 /* Remove the request from free list */ 1930 if( using_reserved ) 1931 { 1932 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 1933 } 1934 else 1935 { 1936 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1937 } 1938 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 1939 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 1940 saRoot->IOMap[pRequest->HTag].agContext = agContext; 1941 pRequest->valid = agTRUE; 1942 1943 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1944 1945 /* set payload to zeros */ 1946 si_memset(&payload, 0, sizeof(agsaGetDeviceStateCmd_t)); 1947 /* set tag field */ 1948 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDeviceStateCmd_t, tag), pRequest->HTag); 1949 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetDeviceStateCmd_t, deviceId), deviceId); 1950 1951 /* build IOMB command and send to SPC */ 1952 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_DEVICE_STATE, IOMB_SIZE64, queueNum); 1953 if (AGSA_RC_SUCCESS != ret) 1954 { 1955 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1956 /* remove the request from IOMap */ 1957 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 1958 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 1959 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 1960 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 1961 pRequest->valid = agFALSE; 1962 /* return the request to free pool */ 1963 if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) 1964 { 1965 SA_DBG1(("mpiGetDeviceStateCmd: saving pRequest (%p) for later use\n", pRequest)); 1966 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 1967 } 1968 else 1969 { 1970 /* return the request to free pool */ 1971 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 1972 } 1973 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 1974 1975 SA_DBG1(("mpiGetDeviceStateCmd, sending IOMB failed\n" )); 1976 } 1977 SA_DBG3(("mpiGetDeviceStateCmd, return value = %d\n", ret)); 1978 1979 /* return value */ 1980 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xf"); 1981 1982 return ret; 1983 } 1984 1985 /******************************************************************************/ 1986 /*! \brief SAS ReInitialize command 1987 * 1988 * This command is Reinitialize SAS paremeters to SPC. 1989 * 1990 * \param agRoot Handles for this instance of SAS/SATA LLL 1991 * \param agContext Context for the Get Nexus State command 1992 * \param agSASConfig SAS Configuration Parameters 1993 * \param queueNum Queue Number of inbound/outbound queue 1994 * 1995 * \return If the MPI command is sent to SPC successfully 1996 * - \e AGSA_RC_SUCCESS the MPI command is successfully 1997 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 1998 * - \e AGSA_RC_FAILURE the MPI command is failure 1999 * 2000 */ 2001 /*******************************************************************************/ 2002 GLOBAL bit32 mpiSasReinitializeCmd( 2003 agsaRoot_t *agRoot, 2004 agsaContext_t *agContext, 2005 agsaSASReconfig_t *agSASConfig, 2006 bit32 queueNum 2007 ) 2008 { 2009 bit32 ret = AGSA_RC_SUCCESS; 2010 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 2011 agsaIORequestDesc_t *pRequest; 2012 agsaSasReInitializeCmd_t payload; 2013 2014 smTraceFuncEnter(hpDBG_VERY_LOUD,"xo"); 2015 2016 /* Get request from free IORequests */ 2017 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2018 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 2019 2020 /* If no LL Control request entry available */ 2021 if ( agNULL == pRequest ) 2022 { 2023 SA_DBG1(("mpiSasReinitializeCmd, No request from free list\n" )); 2024 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xo"); 2025 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2026 return AGSA_RC_BUSY; 2027 } 2028 /* If LL Control request entry avaliable */ 2029 else 2030 { 2031 SA_DBG3(("mpiSasReinitializeCmd, Build IOMB SAS_RE_INITIALIZE\n")); 2032 /* Remove the request from free list */ 2033 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 2034 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 2035 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 2036 saRoot->IOMap[pRequest->HTag].agContext = agContext; 2037 pRequest->valid = agTRUE; 2038 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2039 2040 /* set payload to zeros */ 2041 si_memset(&payload, 0, sizeof(agsaSasReInitializeCmd_t)); 2042 2043 /* set tag field */ 2044 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSasReInitializeCmd_t, tag), pRequest->HTag); 2045 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSasReInitializeCmd_t, setFlags), agSASConfig->flags); 2046 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSasReInitializeCmd_t, MaxPorts), agSASConfig->maxPorts); 2047 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSasReInitializeCmd_t, openRejReCmdData), 2048 (agSASConfig->openRejectRetriesCmd << SHIFT16) | agSASConfig->openRejectRetriesData); 2049 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSasReInitializeCmd_t, sataHOLTMO), agSASConfig->sataHolTmo); 2050 2051 2052 /* build IOMB command and send to SPC */ 2053 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SAS_RE_INITIALIZE, IOMB_SIZE64, queueNum); 2054 if (AGSA_RC_SUCCESS != ret) 2055 { 2056 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2057 /* remove the request from IOMap */ 2058 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 2059 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 2060 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 2061 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 2062 pRequest->valid = agFALSE; 2063 2064 /* return the request to free pool */ 2065 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 2066 2067 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2068 2069 SA_DBG1(("mpiSasReinitializeCmd, sending IOMB failed\n" )); 2070 } 2071 SA_DBG3(("mpiSasReinitializeCmd, return value = %d\n", ret)); 2072 } 2073 2074 /* return value */ 2075 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xo"); 2076 2077 return ret; 2078 } 2079 2080 /******************************************************************************/ 2081 /*! \brief SAS Set Controller Configuration Command 2082 * 2083 * This command updates the contents of a controller mode page. 2084 * 2085 * \param agRoot Handles for this instance of SAS/SATA LLL 2086 * \param agContext Context for the Get Nexus State command 2087 * \param agControllerConfig Mode page being sent to the controller 2088 * \param queueNum Queue Number of inbound/outbound queue 2089 * 2090 * \return If the MPI command is sent to SPC successfully 2091 * - \e AGSA_RC_SUCCESS the MPI command is successfully 2092 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 2093 * - \e AGSA_RC_FAILURE the MPI command is failure 2094 * 2095 */ 2096 /*******************************************************************************/ 2097 GLOBAL bit32 2098 mpiSetControllerConfigCmd( 2099 agsaRoot_t *agRoot, 2100 agsaContext_t *agContext, 2101 agsaSetControllerConfigCmd_t *agControllerConfig, 2102 bit32 queueNum, 2103 bit8 modePageContext 2104 ) 2105 { 2106 bit32 ret = AGSA_RC_SUCCESS; 2107 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 2108 agsaIORequestDesc_t *pRequest; 2109 2110 smTraceFuncEnter(hpDBG_VERY_LOUD,"x1"); 2111 2112 SA_DBG2(("mpiSetControllerConfigCmd: agControllerConfig 0x%08x 0x%08x 0x%08x 0x%08x\n", 2113 agControllerConfig->pageCode,agControllerConfig->configPage[0], 2114 agControllerConfig->configPage[1], agControllerConfig->configPage[2])); 2115 SA_DBG2(("mpiSetControllerConfigCmd: agControllerConfig 0x%08x 0x%08x 0x%08x 0x%08x\n", 2116 agControllerConfig->configPage[3],agControllerConfig->configPage[4], 2117 agControllerConfig->configPage[5], agControllerConfig->configPage[6])); 2118 SA_DBG2(("mpiSetControllerConfigCmd: agControllerConfig 0x%08x 0x%08x 0x%08x 0x%08x\n", 2119 agControllerConfig->configPage[7],agControllerConfig->configPage[8], 2120 agControllerConfig->configPage[9], agControllerConfig->configPage[10])); 2121 SA_DBG2(("mpiSetControllerConfigCmd: agControllerConfig 0x%08x 0x%08x\n", 2122 agControllerConfig->configPage[11],agControllerConfig->configPage[12])); 2123 2124 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2125 /* Get request from free IORequests */ 2126 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 2127 2128 /* If no LL Control request entry available */ 2129 if ( agNULL == pRequest ) 2130 { 2131 SA_DBG1(("mpiSetControllerConfigCmd, No request from free list\n" )); 2132 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "x1"); 2133 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2134 return AGSA_RC_BUSY; 2135 } 2136 /* If LL Control request entry avaliable */ 2137 else 2138 { 2139 SA_DBG2(("mpiSetControllerConfigCmd, Build IOMB pageCode 0x%x configPage[0] 0x%x\n",agControllerConfig->pageCode,agControllerConfig->configPage[0])); 2140 /* Remove the request from free list */ 2141 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 2142 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 2143 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 2144 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 2145 saRoot->IOMap[pRequest->HTag].agContext = agContext; 2146 pRequest->valid = agTRUE; 2147 pRequest->modePageContext = modePageContext; 2148 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2149 2150 /* set tag field */ 2151 agControllerConfig->tag = pRequest->HTag; 2152 ret = mpiBuildCmd(agRoot, (bit32 *)agControllerConfig, 2153 MPI_CATEGORY_SAS_SATA, OPC_INB_SET_CONTROLLER_CONFIG, IOMB_SIZE64, 0); 2154 2155 if (AGSA_RC_SUCCESS != ret) 2156 { 2157 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2158 /* remove the request from IOMap */ 2159 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 2160 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 2161 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 2162 pRequest->valid = agFALSE; 2163 2164 /* return the request to free pool */ 2165 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 2166 2167 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2168 2169 SA_DBG1(("mpiSetControllerConfigCmd, sending IOMB failed\n" )); 2170 } 2171 SA_DBG3(("mpiSetControllerConfigCmd, return value = %d\n", ret)); 2172 } 2173 2174 /* return value */ 2175 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "x1"); 2176 2177 return ret; 2178 } 2179 2180 /******************************************************************************/ 2181 /*! \brief SAS Get Controller Configuration Command 2182 * 2183 * This command retrieves the contents of a controller mode page. 2184 * 2185 * \param agRoot Handles for this instance of SAS/SATA LLL 2186 * \param agContext Context for the Get Nexus State command 2187 * \param agControllerConfig Mode page to retrieve from the controller 2188 * \param queueNum Queue Number of inbound/outbound queue 2189 * 2190 * \return If the MPI command is sent to SPC successfully 2191 * - \e AGSA_RC_SUCCESS the MPI command is successfully 2192 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 2193 * - \e AGSA_RC_FAILURE the MPI command is failure 2194 * 2195 */ 2196 /*******************************************************************************/ 2197 GLOBAL bit32 mpiGetControllerConfigCmd( 2198 agsaRoot_t *agRoot, 2199 agsaContext_t *agContext, 2200 agsaGetControllerConfigCmd_t *agControllerConfig, 2201 bit32 queueNum 2202 ) 2203 { 2204 bit32 ret = AGSA_RC_SUCCESS; 2205 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 2206 agsaIORequestDesc_t *pRequest; 2207 2208 smTraceFuncEnter(hpDBG_VERY_LOUD,"xq"); 2209 2210 SA_DBG1(("mpiGetControllerConfigCmd: Tag 0x%0X Page Code %0X\n",agControllerConfig->tag,agControllerConfig->pageCode )); 2211 /* Get request from free IORequests */ 2212 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2213 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 2214 2215 /* If no LL Control request entry available */ 2216 if ( agNULL == pRequest ) 2217 { 2218 SA_DBG1(("mpiGetControllerConfigCmd, No request from free list\n" )); 2219 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xq"); 2220 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2221 return AGSA_RC_BUSY; 2222 } 2223 /* If LL Control request entry avaliable */ 2224 else 2225 { 2226 SA_DBG3(("mpiGetControllerConfig, Build IOMB mpiGetControllerConfigCmd\n")); 2227 /* Remove the request from free list */ 2228 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 2229 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 2230 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 2231 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 2232 saRoot->IOMap[pRequest->HTag].agContext = agContext; 2233 pRequest->valid = agTRUE; 2234 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2235 2236 /* set tag field */ 2237 agControllerConfig->tag = pRequest->HTag; 2238 2239 ret = mpiBuildCmd(agRoot, (bit32 *) agControllerConfig, 2240 MPI_CATEGORY_SAS_SATA, OPC_INB_GET_CONTROLLER_CONFIG, IOMB_SIZE64, 0); 2241 2242 if (AGSA_RC_SUCCESS != ret) 2243 { 2244 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2245 /* remove the request from IOMap */ 2246 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 2247 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 2248 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 2249 pRequest->valid = agFALSE; 2250 2251 /* return the request to free pool */ 2252 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 2253 2254 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2255 2256 SA_DBG1(("mpiGetControllerConfigCmd, sending IOMB failed\n" )); 2257 } 2258 else 2259 { 2260 SA_DBG3(("mpiGetControllerConfigCmd, set OK\n")); 2261 } 2262 SA_DBG3(("mpiGetControllerConfigCmd, return value = %d\n", ret)); 2263 } 2264 2265 /* return value */ 2266 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xq"); 2267 2268 return ret; 2269 } 2270 2271 /******************************************************************************/ 2272 /*! \brief SAS Encryption KEK command 2273 * 2274 * This command updates one or more KEK in a controller that supports encryption. 2275 * 2276 * \param agRoot Handles for this instance of SAS/SATA LLL 2277 * \param agContext Context for the Get Nexus State command 2278 * \param agKekMgmt Kek information that will be sent to the controller 2279 * \param queueNum Queue Number of inbound/outbound queue 2280 * 2281 * \return If the MPI command is sent to SPC successfully 2282 * - \e AGSA_RC_SUCCESS the MPI command is successfully 2283 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 2284 * - \e AGSA_RC_FAILURE the MPI command is failure 2285 * 2286 */ 2287 /*******************************************************************************/ 2288 GLOBAL bit32 mpiKekManagementCmd( 2289 agsaRoot_t *agRoot, 2290 agsaContext_t *agContext, 2291 agsaKekManagementCmd_t *agKekMgmt, 2292 bit32 queueNum 2293 ) 2294 { 2295 bit32 ret = AGSA_RC_SUCCESS; 2296 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 2297 agsaIORequestDesc_t *pRequest; 2298 2299 smTraceFuncEnter(hpDBG_VERY_LOUD,"x2"); 2300 2301 /* Get request from free IORequests */ 2302 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2303 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 2304 2305 /* If no LL Control request entry available */ 2306 if ( agNULL == pRequest ) 2307 { 2308 SA_DBG1(("mpiKekManagementCmd, No request from free list\n" )); 2309 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "x2"); 2310 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2311 return AGSA_RC_BUSY; 2312 } 2313 /* If LL Control request entry avaliable */ 2314 else 2315 { 2316 SA_DBG3(("mpiKekManagementCmd, Build OPC_INB_KEK_MANAGEMENT\n")); 2317 /* Remove the request from free list */ 2318 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 2319 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 2320 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 2321 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 2322 saRoot->IOMap[pRequest->HTag].agContext = agContext; 2323 pRequest->valid = agTRUE; 2324 agKekMgmt->tag = pRequest->HTag; 2325 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2326 2327 SA_DBG1(("mpiKekManagementCmd, 0x%X 0x%X 0x%X\n", agKekMgmt->tag,agKekMgmt->NEWKIDX_CURKIDX_KBF_Reserved_SKNV_KSOP, agKekMgmt->reserved )); 2328 2329 ret = mpiBuildCmd(agRoot, (bit32 *)agKekMgmt, MPI_CATEGORY_SAS_SATA, OPC_INB_KEK_MANAGEMENT, IOMB_SIZE64, 0); 2330 2331 if (AGSA_RC_SUCCESS != ret) 2332 { 2333 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2334 /* remove the request from IOMap */ 2335 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 2336 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 2337 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 2338 pRequest->valid = agFALSE; 2339 /* return the request to free pool */ 2340 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 2341 2342 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2343 SA_DBG1(("mpiKekManagementCmd, sending IOMB failed\n" )); 2344 } 2345 SA_DBG3(("mpiKekManagementCmd, return value = %d\n", ret)); 2346 } 2347 2348 /* return value */ 2349 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "x2"); 2350 2351 return ret; 2352 } 2353 2354 /******************************************************************************/ 2355 /*! \brief SAS Encryption DEK management command 2356 * 2357 * This command updates one or more DEK in a controller that supports encryption. 2358 * 2359 * \param agRoot Handles for this instance of SAS/SATA LLL 2360 * \param agContext Context for the Get Nexus State command 2361 * \param agDekMgmt DEK information that will be sent to the controller 2362 * \param queueNum Queue Number of inbound/outbound queue 2363 * 2364 * \return If the MPI command is sent to SPC successfully 2365 * - \e AGSA_RC_SUCCESS the MPI command is successfully 2366 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 2367 * - \e AGSA_RC_FAILURE the MPI command is failure 2368 * 2369 */ 2370 /*******************************************************************************/ 2371 GLOBAL bit32 mpiDekManagementCmd( 2372 agsaRoot_t *agRoot, 2373 agsaContext_t *agContext, 2374 agsaDekManagementCmd_t *agDekMgmt, 2375 bit32 queueNum 2376 ) 2377 { 2378 bit32 ret = AGSA_RC_SUCCESS; 2379 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 2380 agsaIORequestDesc_t *pRequest; 2381 2382 smTraceFuncEnter(hpDBG_VERY_LOUD,"xs"); 2383 2384 /* Get request from free IORequests */ 2385 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2386 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 2387 2388 /* If no LL Control request entry available */ 2389 if ( agNULL == pRequest ) 2390 { 2391 SA_DBG1(("mpiDekManagementCmd, No request from free list\n" )); 2392 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xs"); 2393 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2394 return AGSA_RC_BUSY; 2395 } 2396 /* If LL Control request entry avaliable */ 2397 else 2398 { 2399 SA_DBG1(("mpiDekManagementCmd, Build OPC_INB_DEK_MANAGEMENT pRequest %p\n",pRequest)); 2400 /* Remove the request from free list */ 2401 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 2402 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 2403 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 2404 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 2405 saRoot->IOMap[pRequest->HTag].agContext = agContext; 2406 pRequest->valid = agTRUE; 2407 agDekMgmt->tag = pRequest->HTag; 2408 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2409 2410 SA_DBG1(("mpiDekManagementCmd: 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n", 2411 agDekMgmt->tag, 2412 agDekMgmt->KEKIDX_Reserved_TBLS_DSOP, 2413 agDekMgmt->dekIndex, 2414 agDekMgmt->tableAddrLo, 2415 agDekMgmt->tableAddrHi, 2416 agDekMgmt->tableEntries, 2417 agDekMgmt->Reserved_DBF_TBL_SIZE )); 2418 ret = mpiBuildCmd(agRoot, (bit32 *) agDekMgmt, MPI_CATEGORY_SAS_SATA, OPC_INB_DEK_MANAGEMENT, IOMB_SIZE64, 0); 2419 2420 if (AGSA_RC_SUCCESS != ret) 2421 { 2422 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2423 /* remove the request from IOMap */ 2424 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 2425 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 2426 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 2427 pRequest->valid = agFALSE; 2428 2429 /* return the request to free pool */ 2430 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 2431 2432 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2433 2434 SA_DBG1(("mpiDekManagementCmd, sending IOMB failed\n" )); 2435 } 2436 SA_DBG3(("mpiDekManagementCmd, return value = %d\n", ret)); 2437 } 2438 2439 /* return value */ 2440 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xs"); 2441 2442 return ret; 2443 } 2444 2445 /******************************************************************************/ 2446 /*! \brief 2447 * 2448 * This command sends operator management command. 2449 * 2450 * \param agRoot Handles for this instance of SAS/SATA LLL 2451 * \param agContext Context 2452 * \param queueNum Queue Number of inbound/outbound queue 2453 * 2454 * \return If the MPI command is sent to SPC successfully 2455 * - \e AGSA_RC_SUCCESS the MPI command is successfully 2456 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 2457 * - \e AGSA_RC_FAILURE the MPI command is failure 2458 * 2459 */ 2460 /*******************************************************************************/ 2461 GLOBAL bit32 mpiOperatorManagementCmd( 2462 agsaRoot_t *agRoot, 2463 bit32 queueNum, 2464 agsaContext_t *agContext, 2465 agsaOperatorMangmentCmd_t *operatorcode ) 2466 { 2467 bit32 ret = AGSA_RC_SUCCESS; 2468 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 2469 agsaIORequestDesc_t *pRequest; 2470 2471 smTraceFuncEnter(hpDBG_VERY_LOUD,"2q"); 2472 2473 SA_DBG1(("mpiOperatorManagementCmd, enter\n" )); 2474 2475 /* Get request from free IORequests */ 2476 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2477 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 2478 2479 /* If no LL Control request entry available */ 2480 if ( agNULL == pRequest ) 2481 { 2482 SA_DBG1(("mpiOperatorManagementCmd, No request from free list\n" )); 2483 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2q"); 2484 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2485 return AGSA_RC_BUSY; 2486 } 2487 /* If LL Control request entry avaliable */ 2488 else 2489 { 2490 SA_DBG1(("mpiOperatorManagementCmd, Build OPC_INB_OPR_MGMT\n")); 2491 /* Remove the request from free list */ 2492 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 2493 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 2494 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 2495 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 2496 saRoot->IOMap[pRequest->HTag].agContext = agContext; 2497 pRequest->valid = agTRUE; 2498 operatorcode->tag = pRequest->HTag; 2499 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2500 2501 ret = mpiBuildCmd(agRoot, (bit32 *)operatorcode , MPI_CATEGORY_SAS_SATA, OPC_INB_OPR_MGMT, IOMB_SIZE128, 0); 2502 2503 if (AGSA_RC_SUCCESS != ret) 2504 { 2505 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2506 /* remove the request from IOMap */ 2507 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 2508 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 2509 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 2510 pRequest->valid = agFALSE; 2511 2512 /* return the request to free pool */ 2513 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 2514 2515 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2516 2517 SA_DBG1(("mpiOperatorManagementCmd, sending IOMB failed\n" )); 2518 } 2519 SA_DBG1(("mpiOperatorManagementCmd, return value = %d\n", ret)); 2520 } 2521 2522 /* return value */ 2523 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2q"); 2524 2525 return ret; 2526 } 2527 2528 /******************************************************************************/ 2529 /*! \brief 2530 * 2531 * This command sends encrypt self test command. 2532 * 2533 * \param agRoot Handles for this instance of SAS/SATA LLL 2534 * \param agContext Context 2535 * \param queueNum Queue Number of inbound/outbound queue 2536 * 2537 * \return If the MPI command is sent to SPC successfully 2538 * - \e AGSA_RC_SUCCESS the MPI command is successfully 2539 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 2540 * - \e AGSA_RC_FAILURE the MPI command is failure 2541 * 2542 */ 2543 /*******************************************************************************/ 2544 GLOBAL bit32 mpiEncryptBistCmd( 2545 agsaRoot_t *agRoot, 2546 bit32 queueNum, 2547 agsaContext_t *agContext, 2548 agsaEncryptBist_t *bist ) 2549 { 2550 bit32 ret = AGSA_RC_SUCCESS; 2551 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 2552 agsaIORequestDesc_t *pRequest; 2553 2554 smTraceFuncEnter(hpDBG_VERY_LOUD,"2z"); 2555 2556 SA_DBG1(("mpiEncryptBistCmd, enter\n" )); 2557 2558 /* Get request from free IORequests */ 2559 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2560 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 2561 2562 /* If no LL Control request entry available */ 2563 if ( agNULL == pRequest ) 2564 { 2565 SA_DBG1(("mpiEncryptBistCmd, No request from free list\n" )); 2566 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2z"); 2567 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2568 return AGSA_RC_BUSY; 2569 } 2570 /* If LL Control request entry avaliable */ 2571 else 2572 { 2573 SA_DBG1(("mpiEncryptBistCmd, Build OPC_INB_ENC_TEST_EXECUTE\n")); 2574 /* Remove the request from free list */ 2575 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 2576 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 2577 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 2578 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 2579 saRoot->IOMap[pRequest->HTag].agContext = agContext; 2580 pRequest->valid = agTRUE; 2581 bist->tag = pRequest->HTag; 2582 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2583 2584 SA_DBG1(("mpiEncryptBistCmd: 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n", 2585 bist->tag, 2586 bist->r_subop, 2587 bist->testDiscption[0], 2588 bist->testDiscption[1], 2589 bist->testDiscption[2], 2590 bist->testDiscption[3], 2591 bist->testDiscption[4] )); 2592 ret = mpiBuildCmd(agRoot, (bit32 *)bist , MPI_CATEGORY_SAS_SATA, OPC_INB_ENC_TEST_EXECUTE, IOMB_SIZE64, 0); 2593 2594 if (AGSA_RC_SUCCESS != ret) 2595 { 2596 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2597 /* remove the request from IOMap */ 2598 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 2599 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 2600 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 2601 pRequest->valid = agFALSE; 2602 2603 /* return the request to free pool */ 2604 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 2605 2606 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2607 2608 SA_DBG1(("mpiEncryptBistCmd, sending IOMB failed\n" )); 2609 } 2610 SA_DBG1(("mpiEncryptBistCmd, return value = %d\n", ret)); 2611 } 2612 2613 /* return value */ 2614 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2z"); 2615 2616 return ret; 2617 } 2618 2619 /******************************************************************************/ 2620 /*! \brief 2621 * 2622 * This command sends set operator command. 2623 * 2624 * \param agRoot Handles for this instance of SAS/SATA LLL 2625 * \param agContext Context 2626 * \param queueNum Queue Number of inbound/outbound queue 2627 * 2628 * \return If the MPI command is sent to SPC successfully 2629 * - \e AGSA_RC_SUCCESS the MPI command is successfully 2630 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 2631 * - \e AGSA_RC_FAILURE the MPI command is failure 2632 * 2633 */ 2634 /*******************************************************************************/ 2635 GLOBAL bit32 2636 mpiSetOperatorCmd( 2637 agsaRoot_t *agRoot, 2638 bit32 queueNum, 2639 agsaContext_t *agContext, 2640 agsaSetOperatorCmd_t *operatorcode 2641 ) 2642 { 2643 bit32 ret = AGSA_RC_SUCCESS; 2644 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 2645 agsaIORequestDesc_t *pRequest; 2646 2647 smTraceFuncEnter(hpDBG_VERY_LOUD,"39"); 2648 2649 SA_DBG1(("mpiSetOperatorCmd, enter\n" )); 2650 2651 /* Get request from free IORequests */ 2652 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2653 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 2654 2655 /* If no LL Control request entry available */ 2656 if ( agNULL == pRequest ) 2657 { 2658 SA_DBG1(("mpiSetOperatorCmd, No request from free list\n" )); 2659 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "39"); 2660 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2661 return AGSA_RC_BUSY; 2662 } 2663 /* If LL Control request entry avaliable */ 2664 else 2665 { 2666 SA_DBG1(("mpiSetOperatorCmd, Build OPC_INB_SET_OPERATOR\n")); 2667 /* Remove the request from free list */ 2668 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 2669 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 2670 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 2671 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 2672 saRoot->IOMap[pRequest->HTag].agContext = agContext; 2673 pRequest->valid = agTRUE; 2674 operatorcode->tag = pRequest->HTag; 2675 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2676 2677 ret = mpiBuildCmd(agRoot, (bit32 *)operatorcode, MPI_CATEGORY_SAS_SATA, OPC_INB_SET_OPERATOR, IOMB_SIZE64, 0); 2678 2679 if (AGSA_RC_SUCCESS != ret) 2680 { 2681 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2682 /* remove the request from IOMap */ 2683 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 2684 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 2685 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 2686 pRequest->valid = agFALSE; 2687 2688 /* return the request to free pool */ 2689 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 2690 2691 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2692 2693 SA_DBG1(("mpiSetOperatorCmd, sending IOMB failed\n" )); 2694 } 2695 SA_DBG1(("mpiSetOperatorCmd, return value = %d\n", ret)); 2696 } 2697 2698 /* return value */ 2699 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "39"); 2700 2701 return ret; 2702 } 2703 2704 /******************************************************************************/ 2705 /*! \brief 2706 * 2707 * This command sends get operator command. 2708 * 2709 * \param agRoot Handles for this instance of SAS/SATA LLL 2710 * \param agContext Context 2711 * \param queueNum Queue Number of inbound/outbound queue 2712 * 2713 * \return If the MPI command is sent to SPC successfully 2714 * - \e AGSA_RC_SUCCESS the MPI command is successfully 2715 * - \e AGSA_RC_BUSY the SPC is no resource, cannot send now 2716 * - \e AGSA_RC_FAILURE the MPI command is failure 2717 * 2718 */ 2719 /*******************************************************************************/ 2720 GLOBAL bit32 2721 mpiGetOperatorCmd( 2722 agsaRoot_t *agRoot, 2723 bit32 queueNum, 2724 agsaContext_t *agContext, 2725 agsaGetOperatorCmd_t *operatorcode 2726 ) 2727 { 2728 bit32 ret = AGSA_RC_SUCCESS; 2729 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 2730 agsaIORequestDesc_t *pRequest; 2731 2732 smTraceFuncEnter(hpDBG_VERY_LOUD,"3e"); 2733 2734 SA_DBG1(("mpiGetOperatorCmd, enter\n" )); 2735 2736 /* Get request from free IORequests */ 2737 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2738 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 2739 2740 /* If no LL Control request entry available */ 2741 if ( agNULL == pRequest ) 2742 { 2743 SA_DBG1(("mpiGetOperatorCmd, No request from free list\n" )); 2744 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "3e"); 2745 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2746 return AGSA_RC_BUSY; 2747 } 2748 /* If LL Control request entry avaliable */ 2749 else 2750 { 2751 SA_DBG1(("mpiGetOperatorCmd, Build OPC_INB_GET_OPERATOR\n")); 2752 /* Remove the request from free list */ 2753 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 2754 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 2755 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 2756 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 2757 saRoot->IOMap[pRequest->HTag].agContext = agContext; 2758 pRequest->valid = agTRUE; 2759 operatorcode->tag = pRequest->HTag; 2760 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2761 2762 ret = mpiBuildCmd(agRoot, (bit32 *)operatorcode, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_OPERATOR, IOMB_SIZE64, 0); 2763 2764 if (AGSA_RC_SUCCESS != ret) 2765 { 2766 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2767 /* remove the request from IOMap */ 2768 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 2769 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 2770 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 2771 pRequest->valid = agFALSE; 2772 2773 /* return the request to free pool */ 2774 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 2775 2776 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2777 2778 SA_DBG1(("mpiGetOperatorCmd, sending IOMB failed\n" )); 2779 } 2780 SA_DBG1(("mpiGetOperatorCmd, return value = %d\n", ret)); 2781 } 2782 2783 /* return value */ 2784 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "3e"); 2785 2786 return ret; 2787 } 2788 2789 GLOBAL bit32 mpiDIFEncryptionOffloadCmd( 2790 agsaRoot_t *agRoot, 2791 agsaContext_t *agContext, 2792 bit32 queueNum, 2793 bit32 op, 2794 agsaDifEncPayload_t *agDifEncOffload, 2795 ossaDIFEncryptionOffloadStartCB_t agCB 2796 ) 2797 { 2798 bit32 ret = AGSA_RC_SUCCESS; 2799 bit32 dw8=0; 2800 bit32 dw9=0; 2801 bit32 dw10=0; 2802 bit32 dw14=0; 2803 bit32 dw15=0; 2804 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData); 2805 agsaIORequestDesc_t *pRequest; 2806 agsaDifEncOffloadCmd_t payload; 2807 smTraceFuncEnter(hpDBG_VERY_LOUD,"2b"); 2808 2809 /* Get request from free IORequests */ 2810 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2811 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 2812 2813 /* If no LL Control request entry available */ 2814 if ( agNULL == pRequest ) 2815 { 2816 SA_DBG1(("mpiDIFEncryptionOffloadCmd: No request from free list\n" )); 2817 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2b"); 2818 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2819 return AGSA_RC_BUSY; 2820 } 2821 /* If LL Control request entry avaliable */ 2822 else 2823 { 2824 SA_DBG1(("mpiDIFEncryptionOffloadCmd: Build OPC_INB_DIF_ENC_OFFLOAD_CMD pRequest %p\n",pRequest)); 2825 /* Remove the request from free list */ 2826 SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 2827 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 2828 saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 2829 saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 2830 saRoot->IOMap[pRequest->HTag].agContext = agContext; 2831 pRequest->valid = agTRUE; 2832 pRequest->completionCB = (ossaSSPCompletedCB_t)agCB; 2833 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2834 2835 si_memset(&payload, 0, sizeof(agsaDifEncOffloadCmd_t)); 2836 SA_DBG1(("mpiDIFEncryptionOffloadCmd: op %d\n",op)); 2837 2838 if(smIS_SPCV(agRoot)) 2839 { 2840 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, tag), pRequest->HTag); 2841 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, option), op); 2842 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, Src_Data_Len), agDifEncOffload->SrcDL); 2843 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, Dst_Data_Len), agDifEncOffload->DstDL); 2844 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, flags), agDifEncOffload->dif.flags); 2845 2846 dw8 = agDifEncOffload->dif.udrtArray[1] << SHIFT24 | 2847 agDifEncOffload->dif.udrtArray[0] << SHIFT16 | 2848 agDifEncOffload->dif.udtArray[1] << SHIFT8 | 2849 agDifEncOffload->dif.udtArray[0]; 2850 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, UDTR01UDT01), dw8); 2851 2852 dw9 = agDifEncOffload->dif.udtArray[5] << SHIFT24 | 2853 agDifEncOffload->dif.udtArray[4] << SHIFT16 | 2854 agDifEncOffload->dif.udtArray[3] << SHIFT8 | 2855 agDifEncOffload->dif.udtArray[2]; 2856 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, UDT2345), dw9); 2857 dw10 = agDifEncOffload->dif.udrtArray[5] << SHIFT24 | 2858 agDifEncOffload->dif.udrtArray[4] << SHIFT16 | 2859 agDifEncOffload->dif.udrtArray[3] << SHIFT8 | 2860 agDifEncOffload->dif.udrtArray[2]; 2861 2862 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, UDTR2345), dw10); 2863 2864 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, DPLR0SecCnt_IOSeed), 2865 agDifEncOffload->dif.DIFPerLARegion0SecCount << SHIFT16 | 2866 agDifEncOffload->dif.initialIOSeed); 2867 2868 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, DPL_Addr_Lo) , agDifEncOffload->dif.DIFPerLAAddrLo); 2869 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, DPL_Addr_Hi) , agDifEncOffload->dif.DIFPerLAAddrHi); 2870 2871 dw14 = agDifEncOffload->encrypt.dekInfo.dekIndex << SHIFT8 | 2872 (agDifEncOffload->encrypt.dekInfo.dekTable & 0x3) << SHIFT2 | 2873 (agDifEncOffload->encrypt.keyTagCheck & 0x1) << SHIFT1; 2874 2875 if (agDifEncOffload->encrypt.cipherMode == agsaEncryptCipherModeXTS) 2876 { 2877 dw14 |= AGSA_ENCRYPT_XTS_Mode << SHIFT4; 2878 } 2879 else 2880 { 2881 dw14 |= (agDifEncOffload->encrypt.cipherMode & 0xF) << SHIFT4; 2882 } 2883 2884 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, KeyIndex_CMode_KTS_ENT_R), dw14); 2885 2886 dw15 = agDifEncOffload->encrypt.EncryptionPerLRegion0SecCount << SHIFT16 | 2887 (agDifEncOffload->encrypt.kekIndex & 0xF) << SHIFT5 | 2888 (agDifEncOffload->encrypt.sectorSizeIndex & 0x1F); 2889 2890 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, EPLR0SecCnt_KS_ENSS), dw15); 2891 2892 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, keyTag_W0), agDifEncOffload->encrypt.keyTag_W0); 2893 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, keyTag_W1), agDifEncOffload->encrypt.keyTag_W1); 2894 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, tweakVal_W0), agDifEncOffload->encrypt.tweakVal_W0); 2895 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, tweakVal_W1), agDifEncOffload->encrypt.tweakVal_W1); 2896 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, tweakVal_W2), agDifEncOffload->encrypt.tweakVal_W2); 2897 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, tweakVal_W3), agDifEncOffload->encrypt.tweakVal_W3); 2898 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, EPL_Addr_Lo), agDifEncOffload->encrypt.EncryptionPerLAAddrLo); 2899 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, EPL_Addr_Hi), agDifEncOffload->encrypt.EncryptionPerLAAddrHi); 2900 2901 si_memcpy((bit32 *) &(payload.SrcSgl), (bit32 *) &(agDifEncOffload->SrcSgl), sizeof(agsaSgl_t)); 2902 si_memcpy((bit32 *) &(payload.DstSgl), (bit32 *) &(agDifEncOffload->DstSgl), sizeof(agsaSgl_t)); 2903 2904 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_DIF_ENC_OFFLOAD_CMD, IOMB_SIZE128, queueNum); 2905 2906 } 2907 else 2908 { 2909 /* SPC does not support this command */ 2910 ret = AGSA_RC_FAILURE; 2911 } 2912 2913 if (AGSA_RC_SUCCESS != ret) 2914 { 2915 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2916 /* remove the request from IOMap */ 2917 saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 2918 saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 2919 saRoot->IOMap[pRequest->HTag].agContext = agNULL; 2920 pRequest->valid = agFALSE; 2921 2922 /* return the request to free pool */ 2923 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 2924 2925 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 2926 2927 SA_DBG1(("mpiDIFEncryptionOffloadCmd: sending IOMB failed\n" )); 2928 } 2929 SA_DBG3(("mpiDIFEncryptionOffloadCmd: return value = %d\n", ret)); 2930 } 2931 2932 /* return value */ 2933 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2b"); 2934 2935 return ret; 2936 } 2937 2938