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