1 /*******************************************************************************
2 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
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
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.
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
21 ********************************************************************************/
22 /*******************************************************************************/
24 * \brief The file implements the functions of MPI Inbound IOMB/Command to SPC
27 /******************************************************************************/
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30 #include <dev/pms/config.h>
32 #include <dev/pms/RefTisa/sallsdk/spc/saglobal.h>
33 #ifdef SA_ENABLE_TRACE_FUNCTIONS
37 #define siTraceFileID 'I'
40 /******************************************************************************/
41 /*! \brief SAS/SATA LL API ECHO Command
43 * This command used to test that MPI between host and SPC IOP is operational.
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
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
56 /*******************************************************************************/
57 GLOBAL bit32 saEchoCommand(
59 agsaContext_t *agContext,
64 bit32 ret = AGSA_RC_SUCCESS;
66 smTraceFuncEnter(hpDBG_VERY_LOUD, "xa");
68 /* setup IOMB payload */
69 ret = mpiEchoCmd(agRoot, queueNum, agContext, echoPayload);
71 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xa");
76 /******************************************************************************/
77 /*! \brief Build a IOMB command and send to SPC
79 * Build an IOMB if there is a free message buffer and Send it to SPC
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
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
93 /*******************************************************************************/
94 GLOBAL bit32 mpiBuildCmd(
97 mpiMsgCategory_t category,
103 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
104 mpiICQueue_t *circularQ;
106 bit32 ret = AGSA_RC_SUCCESS;
110 smTraceFuncEnter(hpDBG_VERY_LOUD, "xb");
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.");
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 */
123 #ifdef SA_LL_IBQ_PROTECT
124 ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
125 #endif /* SA_LL_IBQ_PROTECT */
127 circularQ = &saRoot->inboundQueue[inq];
128 retVal = mpiMsgFreeGet(circularQ, size, &pMessage);
130 /* return FAILURE if error happened */
131 if (AGSA_RC_FAILURE == retVal)
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");
143 /* return BUSY if no more inbound queue entry available */
144 if (AGSA_RC_BUSY == retVal)
146 SA_DBG1(("mpiBuildCmd, no more IOMB\n"));
151 /* copy payload if it is necessary */
152 if (agNULL != payload)
154 si_memcpy(pMessage, payload, (size - sizeof(mpiMsgHeader_t)));
157 /* post the message to SPC */
158 if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, category, opcode, outq, (bit8)circularQ->priority))
160 ret = AGSA_RC_FAILURE;
164 #ifdef SA_LL_IBQ_PROTECT
165 ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
166 #endif /* SA_LL_IBQ_PROTECT */
168 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xb");
172 /******************************************************************************/
173 /*! \brief SPC MPI ECHO Command
175 * This command used to test that MPI between host and SPC IOP is operational.
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
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
188 /*******************************************************************************/
189 GLOBAL bit32 mpiEchoCmd(
192 agsaContext_t *agContext,
196 bit32 ret = AGSA_RC_SUCCESS;
197 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
198 agsaIORequestDesc_t *pRequest;
199 agsaEchoCmd_t payload;
201 smTraceFuncEnter(hpDBG_VERY_LOUD, "xc");
203 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
204 /* Get request from free IORequests */
205 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
207 /* If no LL Control request entry available */
208 if ( agNULL == pRequest )
210 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
211 SA_DBG1(("mpiEchoCmd, No request from free list\n" ));
212 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xc");
215 /* If LL Control request entry avaliable */
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;
226 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
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)
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));
247 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
249 SA_DBG1(("mpiEchoCmd, sending IOMB failed\n" ));
254 saRoot->LLCounters.IOCounter.numEchoSent++;
261 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xc");
266 /******************************************************************************/
267 /*! \brief Get Phy Profile Command SPCv
269 * This command is get # of phys and support speeds from SPCV.
271 * \param agRoot Handles for this instance of SAS/SATA LLL
272 * \param agDevHandle Handle of device
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
280 /*******************************************************************************/
283 GLOBAL bit32 mpiGetPhyProfileCmd(
285 agsaContext_t *agContext,
291 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
292 agsaIORequestDesc_t *pRequest;
293 bit32 ret = AGSA_RC_SUCCESS;
294 agsaGetPhyProfileCmd_V_t payload;
296 smTraceFuncEnter(hpDBG_VERY_LOUD, "xd");
298 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
299 /* Get request from free IORequests */
300 pRequest = (agsaIORequestDesc_t *)saLlistGetHead(&(saRoot->freeIORequests));
302 SA_DBG1(("mpiGetPhyProfileCmd, Operation 0x%x PhyId %d \n",Operation ,PhyId ));
304 /* If no LL Control request entry avalibale */
305 if ( agNULL == pRequest )
307 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
308 SA_DBG1(("mpiGetPhyProfileCmd, No request from free list\n" ));
311 /* If LL Control request entry avaliable */
314 SA_ASSERT((!pRequest->valid), "The pRequest is in use");
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;
322 pRequest->valid = agTRUE;
323 pRequest->completionCB = agCB;
324 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
327 /* set payload to zeros */
328 si_memset(&payload, 0, sizeof(agsaGetPhyProfileCmd_V_t));
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)
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);
347 SA_DBG1(("mpiGetPhyProfileCmd, sending IOMB failed\n" ));
349 SA_DBG3(("mpiGetPhyProfileCmd, return value = %d\n", ret));
352 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xd");
358 GLOBAL bit32 mpiVHistCapCmd(
360 agsaContext_t *agContext,
369 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
370 agsaIORequestDesc_t *pRequest= agNULL;
371 bit32 ret = AGSA_RC_SUCCESS;
372 agsaGetVHistCap_V_t payload;
374 smTraceFuncEnter(hpDBG_VERY_LOUD,"3C");
375 SA_DBG1(("mpiVHistCapCmd\n"));
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 )
383 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
384 SA_DBG1((", No request from free list\n" ));
385 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "3C");
388 /* If LL Control request entry avaliable */
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;
398 pRequest->valid = agTRUE;
399 pRequest->completionCB = (void *)ossaGetPhyProfileCB;
400 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
402 /* set payload to zeros */
403 si_memset(&payload, 0, sizeof(agsaGetVHistCap_V_t));
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 );
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)
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);
429 SA_DBG1(("mpiVHistCapCmd, sending IOMB failed\n" ));
431 SA_DBG3(("mpiVHistCapCmd, return value = %d\n", ret));
434 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "3C");
440 GLOBAL bit32 mpiSetPhyProfileCmd(
442 agsaContext_t *agContext,
449 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
450 agsaIORequestDesc_t *pRequest;
451 bit32 ret = AGSA_RC_SUCCESS;
453 agsaSetPhyProfileCmd_V_t payload;
454 bit32 * PageData =(bit32 * )buffer;
456 smTraceFuncEnter(hpDBG_VERY_LOUD,"2P");
458 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
459 /* Get request from free IORequests */
460 pRequest = (agsaIORequestDesc_t *)saLlistGetHead(&(saRoot->freeIORequests));
462 SA_DBG1(("mpiSetPhyProfileCmd, Operation 0x%x PhyId %d \n",Operation ,PhyId ));
464 /* If no LL Control request entry avalibale */
465 if ( agNULL == pRequest )
467 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
468 SA_DBG1(("mpiSetPhyProfileCmd, No request from free list\n" ));
471 /* If LL Control request entry avaliable */
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;
481 pRequest->valid = agTRUE;
482 pRequest->SOP = (bit16) Operation;
483 pRequest->completionCB = (void *)ossaGetPhyProfileCB;
484 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
487 /* set payload to zeros */
488 si_memset(&payload, 0, sizeof(agsaSetPhyProfileCmd_V_t));
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) ) );
494 for(i=0; i < (length / sizeof(bit32)); i++)
496 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetPhyProfileCmd_V_t, PageSpecificArea[i]),* (PageData+i) );
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)
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);
513 SA_DBG1(("mpiSetPhyProfileCmd, sending IOMB failed\n" ));
515 SA_DBG3(("mpiGetPhyProfileCmd, return value = %d\n", ret));
518 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2P");
524 /******************************************************************************/
525 /*! \brief Get Device Information Command
527 * This command is get # of phys and support speeds from SPC.
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
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
540 /*******************************************************************************/
541 GLOBAL bit32 mpiGetDeviceInfoCmd(
543 agsaContext_t *agContext,
549 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
550 agsaIORequestDesc_t *pRequest;
551 bit32 ret = AGSA_RC_SUCCESS;
552 agsaGetDevInfoCmd_t payload;
554 SA_ASSERT((agNULL !=saRoot ), "");
557 SA_DBG1(("mpiGetDeviceInfoCmd: saRoot == agNULL\n"));
558 return(AGSA_RC_FAILURE);
560 smTraceFuncEnter(hpDBG_VERY_LOUD,"2K");
562 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
563 /* Get request from free IORequests */
564 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
566 /* If no LL Control request entry available */
567 if ( agNULL == pRequest )
569 SA_DBG1(("mpiGetDeviceInfoCmd, No request from free list\n" ));
570 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2K");
571 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
574 /* If LL Control request entry avaliable */
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);
588 /* set payload to zeros */
589 si_memset(&payload, 0, sizeof(agsaGetDevInfoCmd_t));
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))
597 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SPC_GET_DEV_INFO, IOMB_SIZE64, queueNum);
601 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_DEV_INFO, IOMB_SIZE64, queueNum);
603 if (AGSA_RC_SUCCESS != ret)
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);
615 SA_DBG1(("mpiGetDeviceInfoCmd, sending IOMB failed\n" ));
617 SA_DBG3(("mpiGetDeviceInfoCmd, return value = %d\n", ret));
620 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2K");
625 /******************************************************************************/
626 /*! \brief Set Device Information Command
628 * This command is Set Device Information to SPC.
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
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
641 /*******************************************************************************/
642 GLOBAL bit32 mpiSetDeviceInfoCmd(
644 agsaContext_t *agContext,
649 ossaSetDeviceInfoCB_t agCB
652 agsaLLRoot_t *saRoot = agNULL;
653 agsaIORequestDesc_t *pRequest = agNULL;
654 bit32 ret = AGSA_RC_SUCCESS;
655 agsaSetDevInfoCmd_t payload;
657 smTraceFuncEnter(hpDBG_VERY_LOUD,"xe");
660 SA_ASSERT((agNULL != agRoot), "");
661 saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
662 SA_ASSERT((agNULL != saRoot), "");
664 /* Get request from free IORequests */
665 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
666 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
668 SA_DBG2(("mpiSetDeviceInfoCmd, param 0x%08X option 0x%08X\n",param,option ));
670 /* If no LL Control request entry available */
671 if ( agNULL == pRequest )
673 SA_DBG1(("mpiSetDeviceInfoCmd, No request from free list\n" ));
674 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xe");
675 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
678 /* If LL Control request entry avaliable */
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);
690 /* set payload to zeros */
691 si_memset(&payload, 0, sizeof(agsaSetDevInfoCmd_t));
697 option &= SET_DEV_INFO_SPC_DW3_MASK;
698 param &= SET_DEV_INFO_SPC_DW4_MASK;
702 option &= SET_DEV_INFO_V_DW3_MASK;
703 param &= SET_DEV_INFO_V_DW4_MASK;
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 );
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)
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;
722 /* return the request to free pool */
723 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
724 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
726 SA_DBG1(("mpiSetDeviceInfoCmd, sending IOMB failed\n" ));
728 SA_DBG3(("mpiSetDeviceInfoCmd, return value = %d\n", ret));
731 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xe");
737 /******************************************************************************/
738 /*! \brief SPC MPI Phy Start Command
740 * This command sends to SPC for the I/O.
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
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
754 /*******************************************************************************/
755 GLOBAL bit32 mpiPhyStartCmd(
759 agsaPhyConfig_t *agPhyConfig,
760 agsaSASIdentify_t *agSASIdentify,
764 bit32 ret = AGSA_RC_SUCCESS;
765 agsaPhyStartCmd_t payload;
771 #if defined(SALLSDK_DEBUG)
773 #endif /* SALLSDK_DEBUG */
774 smTraceFuncEnter(hpDBG_VERY_LOUD,"xg");
776 /* set payload to zeros */
777 si_memset(&payload, 0, sizeof(agsaPhyStartCmd_t));
779 pValue = (bit32 *)agSASIdentify;
780 ptemp = (bit32 *)&payload.sasIdentify;
781 index = (agPhyConfig->phyProperties & 0x0ff00) >> SHIFT8;
783 #if defined(SALLSDK_DEBUG)
784 Sscd = (agPhyConfig->phyProperties & 0xf0000) >> SHIFT16;
785 #endif /* SALLSDK_DEBUG */
787 SA_DBG1(("mpiPhyStartCmd,phyId = %d dw 2 0x%08X\n",phyId ,((phyId & SM_PHYID_MASK) | ((agPhyConfig->phyProperties & 0xfff) << SHIFT8) | (agPhyConfig->phyProperties & 0xf0000) )));
790 SA_DBG2(("mpiPhyStartCmd,phyId 0x%x phyProperties 0x%x index 0x%x Sscd 0x%x\n",phyId, agPhyConfig->phyProperties,index,Sscd));
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*/
798 /* Haileah Phy analogsetting bit enable*/
801 if( smIS_spc8081(agRoot))
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");
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]));
819 /* setup phy ID field */
820 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPhyStartCmd_t, SscdAseSHLmMlrPhyId),dw2);
822 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaPhyStartCmd_t, tag), tag);
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));
829 /* build IOMB command and send to SPC */
830 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_PHYSTART, IOMB_SIZE64, queueNum);
832 SA_DBG3(("mpiPhyStartCmd, return value = %d\n", ret));
834 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xg");
838 /******************************************************************************/
839 /*! \brief SPC MPI Phy Stop Command
841 * This command sends to SPC for the I/O.
843 * \param agRoot Handles for this instance of SAS/SATA LLL
844 * \param tag tag of IOMB
845 * \param phyId To stop the phyId
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
853 /*******************************************************************************/
854 GLOBAL bit32 mpiPhyStopCmd(
861 bit32 ret = AGSA_RC_SUCCESS;
862 agsaPhyStopCmd_t payload;
864 smTraceFuncEnter(hpDBG_VERY_LOUD,"xh");
866 /* set payload to zeros */
867 si_memset(&payload, 0, sizeof(agsaPhyStopCmd_t));
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);
875 SA_DBG3(("mpiPhyStopCmd, return value = %d\n", ret));
877 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xh");
882 /******************************************************************************/
883 /*! \brief SPC MPI SMP Request Command
885 * This command sends to SPC for the SMP.
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
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
900 /*******************************************************************************/
901 GLOBAL bit32 mpiSMPCmd(
905 agsaSMPCmd_t *payload,
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;
916 #endif /* SALLSDK_DEBUG */
917 smTraceFuncEnter(hpDBG_VERY_LOUD,"xi");
919 SA_DBG6(("mpiSMPCmd: start\n"));
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));
927 /* copy payload if it is necessary */
928 if (agNULL != payload)
930 si_memcpy(pIomb, payload, sizeof(agsaSMPCmd_t));
933 SA_DBG6(("mpiSMPCmd: after msgHeader bc %d\n", bc));
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;
940 SA_DBG3(("mpiSMPCmd, return value = %d\n", ret));
943 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xi");
947 /******************************************************************************/
948 /*! \brief SPC MPI Deregister Device Handle Command
950 * This command used to deregister(remove) the device handle.
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
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
964 /*******************************************************************************/
965 GLOBAL bit32 mpiDeregDevHandleCmd(
967 agsaContext_t *agContext,
968 agsaDeviceDesc_t *pDevice,
974 bit32 ret = AGSA_RC_SUCCESS;
975 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
976 agsaIORequestDesc_t *pRequest;
977 agsaDeregDevHandleCmd_t payload;
979 smTraceFuncEnter(hpDBG_VERY_LOUD,"xp");
981 /* Get request from free IORequests */
982 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
983 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
985 /* If no LL Control request entry available */
986 if ( agNULL == pRequest )
988 SA_DBG1(("mpiDeregDevHandleCmd, No request from free list\n" ));
989 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xp");
990 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
993 /* If LL Control request entry avaliable */
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);
1006 /* clean the payload to zeros */
1007 si_memset(&payload, 0, sizeof(agsaDeregDevHandleCmd_t));
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);
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)
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;
1023 /* return the request to free pool */
1024 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1026 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1027 SA_DBG1(("mpiSetVPDCmd, sending IOMB failed\n" ));
1029 SA_DBG3(("mpiDeregDevHandleCmd, return value = %d\n", ret));
1032 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xp");
1038 /******************************************************************************/
1039 /*! \brief SPC MPI Get Device Handle Command
1041 * This command used to get device handle.
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
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
1057 /*******************************************************************************/
1058 GLOBAL bit32 mpiGetDeviceHandleCmd(
1060 agsaContext_t *agContext,
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;
1074 smTraceFuncEnter(hpDBG_VERY_LOUD,"xj");
1076 /* Get request from free CntrlRequests */
1077 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1078 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1080 /* If no LL Control request entry available */
1081 if ( agNULL == pRequest )
1083 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests)); /**/
1084 if(agNULL != pRequest)
1086 using_reserved = agTRUE;
1087 SA_DBG1(("mpiGetDeviceHandleCmd, using saRoot->freeReservedRequests\n"));
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;
1098 /* Remove the request from free list */
1099 if( using_reserved )
1101 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1105 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
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);
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);
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)
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)
1136 SA_DBG1(("mpiGetDeviceHandleCmd: saving pRequest (%p) for later use\n", pRequest));
1137 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1141 /* return the request to free pool */
1142 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1144 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1146 SA_DBG1(("mpiGetDeviceHandleCmd, sending IOMB failed\n" ));
1148 SA_DBG3(("mpiGetDeviceHandleCmd, return value = %d\n", ret));
1150 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xj");
1155 /******************************************************************************/
1156 /*! \brief SPC MPI LOCAL PHY CONTROL Command
1158 * This command used to do the SPC Phy operation.
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
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
1172 /*******************************************************************************/
1173 GLOBAL bit32 mpiLocalPhyControlCmd(
1181 bit32 ret = AGSA_RC_SUCCESS;
1182 agsaLocalPhyCntrlCmd_t payload;
1183 smTraceFuncEnter(hpDBG_VERY_LOUD,"xl");
1185 SA_DBG3(("mpiLocalPhyControlCmd, phyId 0x%X operation 0x%x dw2 0x%x\n",phyId, operation,(((operation & BYTE_MASK) << SHIFT8) | (phyId & SM_PHYID_MASK))));
1187 /* clean the payload field */
1188 si_memset(&payload, 0, sizeof(agsaLocalPhyCntrlCmd_t));
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);
1196 SA_DBG3(("mpiLocalPhyControlCmd, return value = %d\n", ret));
1199 smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "xl");
1203 /******************************************************************************/
1204 /*! \brief Device Handle Accept Command
1206 * This command is Device Handle Accept IOMB to SPC.
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
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
1221 /*******************************************************************************/
1222 GLOBAL bit32 mpiDevHandleAcceptCmd(
1224 agsaContext_t *agContext,
1233 bit32 ret = AGSA_RC_SUCCESS;
1234 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1235 agsaIORequestDesc_t *pRequest;
1236 agsaDevHandleAcceptCmd_t payload;
1242 smTraceFuncEnter(hpDBG_VERY_LOUD,"xt");
1244 if(deviceId & 0xFFFF0000)
1248 /* Get request from free IORequests */
1249 ossaSingleThreadedEnter(agRoot,LL_IOREQ_LOCKEQ_LOCK );
1250 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1252 SA_DBG2(("mpiDevHandleAcceptCmd, deviceId 0x%x action 0x%x flag 0x%x itlnx 0x%x\n",deviceId,action,flag,itlnx ));
1254 /* If no LL Control request entry available */
1255 if ( agNULL == pRequest )
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;
1262 /* If LL Control request entry avaliable */
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);
1273 /* Do not mark as valid at this IOMB does not complete in OBQ */
1275 /* set payload to zeros */
1276 si_memset(&payload, 0, sizeof(agsaDevHandleAcceptCmd_t));
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) | \
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);
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)
1297 SA_DBG1(("mpiDevHandleAcceptCmd, sending IOMB failed\n" ));
1301 SA_DBG1(("mpiDevHandleAcceptCmd, sending IOMB succeeded\n" ));
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)
1313 SA_DBG1(("mpiDevHandleAcceptCmd: saving pRequest (%p) for later use\n", pRequest));
1314 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1318 /* return the request to free pool */
1319 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1323 ossaSingleThreadedLeave(agRoot,LL_IOREQ_LOCKEQ_LOCK );
1324 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xt");
1328 /******************************************************************************/
1329 /*! \brief SPC READ REGISTER DUMP Command
1331 * This command used to do the SPC Read Register Dump command.
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
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
1349 /*******************************************************************************/
1350 GLOBAL bit32 mpiNVMReadRegDumpCmd(
1352 agsaContext_t *agContext,
1361 bit32 ret = AGSA_RC_SUCCESS;
1362 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1363 agsaIORequestDesc_t *pRequest;
1364 agsaGetNVMDataCmd_t payload;
1367 smTraceFuncEnter(hpDBG_VERY_LOUD,"xk");
1369 /* Get request from free IORequests */
1370 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1371 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1373 /* If no LL Control request entry available */
1374 if ( agNULL == pRequest )
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;
1381 /* If LL Control request entry avaliable */
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);
1393 /* clean the payload field */
1394 si_memset(&payload, 0, sizeof(agsaGetNVMDataCmd_t));
1396 /* only indirect mode */
1400 nvmd = AAP1_RDUMP | IRMode;
1402 nvmd = IOP_RDUMP | IRMode;
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);
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);
1417 SA_DBG1(("mpiNVMReadRegDumpCmd, Wrong device type\n" ));
1418 ret = AGSA_RC_FAILURE;
1421 if (AGSA_RC_SUCCESS != ret)
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));
1432 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1433 SA_DBG1(("mpiNVMReadRegDumpCmd, sending IOMB failed\n" ));
1437 SA_DBG3(("mpiNVMReadRegDumpCmd, return value = %d\n", ret));
1440 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xk");
1445 /******************************************************************************/
1446 /*! \brief Get NVM Data command
1448 * This command is get NVM Data from SPC.
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
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
1461 /*******************************************************************************/
1462 GLOBAL bit32 mpiGetNVMDCmd(
1464 agsaContext_t *agContext,
1465 agsaNVMDData_t *NVMDInfo,
1469 bit32 ret = AGSA_RC_FAILURE;
1470 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1471 agsaIORequestDesc_t *pRequest;
1472 agsaGetNVMDataCmd_t payload;
1474 smTraceFuncEnter(hpDBG_VERY_LOUD,"xr");
1476 /* Get request from free IORequests */
1477 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1478 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1480 /* If no LL Control request entry available */
1481 if ( agNULL == pRequest )
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;
1488 /* If LL Control request entry avaliable */
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);
1501 /* set payload to zeros */
1502 si_memset(&payload, 0, sizeof(agsaGetNVMDataCmd_t));
1504 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaGetNVMDataCmd_t, tag), pRequest->HTag);
1506 if (NVMDInfo->indirectPayload)
1508 /* indirect payload IP = 1 */
1509 switch (NVMDInfo->NVMDevice)
1511 case AGSA_NVMD_TWI_DEVICES:
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);
1521 case AGSA_NVMD_CONFIG_SEEPROM:
1523 /* Data Offset should be 0 */
1524 if (NVMDInfo->dataOffsetAddress != 0)
1526 /* Error for Offset */
1527 SA_DBG1(("mpiGetNVMDCmd, (IP=1)wrong offset = 0x%x\n", NVMDInfo->dataOffsetAddress));
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));
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);
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);
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);
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);
1563 SA_DBG1(("mpiGetNVMDCmd, (IP=1)wrong device type = 0x%x\n", NVMDInfo->NVMDevice));
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);
1575 /* direct payload IP = 0 only for TWI device */
1576 if (AGSA_NVMD_TWI_DEVICES == NVMDInfo->NVMDevice)
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);
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);
1598 if (AGSA_RC_SUCCESS != ret)
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;
1607 /* return the request to free pool */
1608 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1610 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1611 SA_DBG1(("mpiGetNVMDCmd, sending IOMB failed\n" ));
1613 SA_DBG3(("mpiGetNVMDCmd, return value = %d\n", ret));
1616 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xr");
1622 /******************************************************************************/
1623 /*! \brief Set NVM Data Command
1625 * This command is set NVM Data to SPC.
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
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
1638 /*******************************************************************************/
1639 GLOBAL bit32 mpiSetNVMDCmd(
1641 agsaContext_t *agContext,
1642 agsaNVMDData_t *NVMDInfo,
1646 bit32 ret = AGSA_RC_FAILURE;
1647 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1648 agsaIORequestDesc_t *pRequest;
1649 agsaSetNVMDataCmd_t payload;
1651 smTraceFuncEnter(hpDBG_VERY_LOUD,"xm");
1654 /* Get request from free IORequests */
1655 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1656 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1658 /* If no LL Control request entry available */
1659 if ( agNULL == pRequest )
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;
1666 /* If LL Control request entry avaliable */
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);
1679 /* set payload to zeros */
1680 si_memset(&payload, 0, sizeof(agsaSetNVMDataCmd_t));
1683 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, tag), pRequest->HTag);
1685 if (NVMDInfo->indirectPayload)
1687 /* indirect payload IP = 1 */
1688 switch (NVMDInfo->NVMDevice)
1690 case AGSA_NVMD_TWI_DEVICES:
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);
1702 /* 0x01:SEEPROM-0 and 0x04:FLASH only in indirect mode */
1703 case AGSA_NVMD_CONFIG_SEEPROM:
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);
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);
1717 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSetNVMDataCmd_t, VPDOffset),
1718 NVMDInfo->dataOffsetAddress);
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);
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);
1736 /* direct payload IP = 0 */
1737 if (AGSA_NVMD_TWI_DEVICES == NVMDInfo->NVMDevice)
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);
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);
1760 if (AGSA_RC_SUCCESS != ret)
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;
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" ));
1774 SA_DBG3(("mpiSetNVMDCmd, return value = %d\n", ret));
1779 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xm");
1783 /******************************************************************************/
1784 /*! \brief Set Device State command
1786 * This command is set Device State to SPC.
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
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
1799 /*******************************************************************************/
1800 GLOBAL bit32 mpiSetDeviceStateCmd(
1802 agsaContext_t *agContext,
1808 bit32 ret = AGSA_RC_SUCCESS;
1809 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
1810 agsaIORequestDesc_t *pRequest;
1811 agsaSetDeviceStateCmd_t payload;
1813 smTraceFuncEnter(hpDBG_VERY_LOUD,"xn");
1815 /* Get request from free IORequests */
1816 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1817 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1819 /* If no LL Control request entry available */
1820 if ( agNULL == pRequest )
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;
1827 /* If LL Control request entry avaliable */
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);
1839 /* set payload to zeros */
1840 si_memset(&payload, 0, sizeof(agsaSetDeviceStateCmd_t));
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);
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)
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;
1857 /* return the request to free pool */
1858 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1860 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1862 SA_DBG1(("mpiSetNexusStateCmd, sending IOMB failed\n" ));
1864 SA_DBG3(("mpiSetDeviceStateCmd, return value = %d\n", ret));
1868 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xn");
1873 /******************************************************************************/
1874 /*! \brief Get Device State command
1876 * This command is get device State to SPC.
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
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
1889 /*******************************************************************************/
1890 GLOBAL bit32 mpiGetDeviceStateCmd(
1892 agsaContext_t *agContext,
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;
1903 smTraceFuncEnter(hpDBG_VERY_LOUD,"xf");
1905 /* Get request from free IORequests */
1906 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1907 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
1909 /* If no LL Control request entry available */
1910 if ( agNULL == pRequest )
1912 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests)); /**/
1913 /* If no LL Control request entry available */
1914 if(agNULL != pRequest)
1916 using_reserved = agTRUE;
1917 SA_DBG1(("mpiGetDeviceStateCmd, using saRoot->freeReservedRequests\n"));
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;
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 )
1933 saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1937 saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
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;
1944 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1946 /* set payload to zeros */
1947 si_memset(&payload, 0, sizeof(agsaGetDeviceStateCmd_t));
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);
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)
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)
1966 SA_DBG1(("mpiGetDeviceStateCmd: saving pRequest (%p) for later use\n", pRequest));
1967 saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1971 /* return the request to free pool */
1972 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1974 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1976 SA_DBG1(("mpiGetDeviceStateCmd, sending IOMB failed\n" ));
1978 SA_DBG3(("mpiGetDeviceStateCmd, return value = %d\n", ret));
1981 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xf");
1986 /******************************************************************************/
1987 /*! \brief SAS ReInitialize command
1989 * This command is Reinitialize SAS paremeters to SPC.
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
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
2002 /*******************************************************************************/
2003 GLOBAL bit32 mpiSasReinitializeCmd(
2005 agsaContext_t *agContext,
2006 agsaSASReconfig_t *agSASConfig,
2010 bit32 ret = AGSA_RC_SUCCESS;
2011 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
2012 agsaIORequestDesc_t *pRequest;
2013 agsaSasReInitializeCmd_t payload;
2015 smTraceFuncEnter(hpDBG_VERY_LOUD,"xo");
2017 /* Get request from free IORequests */
2018 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2019 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2021 /* If no LL Control request entry available */
2022 if ( agNULL == pRequest )
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;
2029 /* If LL Control request entry avaliable */
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);
2041 /* set payload to zeros */
2042 si_memset(&payload, 0, sizeof(agsaSasReInitializeCmd_t));
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);
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)
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;
2065 /* return the request to free pool */
2066 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2068 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2070 SA_DBG1(("mpiSasReinitializeCmd, sending IOMB failed\n" ));
2072 SA_DBG3(("mpiSasReinitializeCmd, return value = %d\n", ret));
2076 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xo");
2081 /******************************************************************************/
2082 /*! \brief SAS Set Controller Configuration Command
2084 * This command updates the contents of a controller mode page.
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
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
2097 /*******************************************************************************/
2099 mpiSetControllerConfigCmd(
2101 agsaContext_t *agContext,
2102 agsaSetControllerConfigCmd_t *agControllerConfig,
2104 bit8 modePageContext
2107 bit32 ret = AGSA_RC_SUCCESS;
2108 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
2109 agsaIORequestDesc_t *pRequest;
2111 smTraceFuncEnter(hpDBG_VERY_LOUD,"x1");
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]));
2125 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2126 /* Get request from free IORequests */
2127 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2129 /* If no LL Control request entry available */
2130 if ( agNULL == pRequest )
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;
2137 /* If LL Control request entry avaliable */
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);
2152 agControllerConfig->tag = pRequest->HTag;
2153 ret = mpiBuildCmd(agRoot, (bit32 *)agControllerConfig,
2154 MPI_CATEGORY_SAS_SATA, OPC_INB_SET_CONTROLLER_CONFIG, IOMB_SIZE64, 0);
2156 if (AGSA_RC_SUCCESS != ret)
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;
2165 /* return the request to free pool */
2166 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2168 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2170 SA_DBG1(("mpiSetControllerConfigCmd, sending IOMB failed\n" ));
2172 SA_DBG3(("mpiSetControllerConfigCmd, return value = %d\n", ret));
2176 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "x1");
2181 /******************************************************************************/
2182 /*! \brief SAS Get Controller Configuration Command
2184 * This command retrieves the contents of a controller mode page.
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
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
2197 /*******************************************************************************/
2198 GLOBAL bit32 mpiGetControllerConfigCmd(
2200 agsaContext_t *agContext,
2201 agsaGetControllerConfigCmd_t *agControllerConfig,
2205 bit32 ret = AGSA_RC_SUCCESS;
2206 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
2207 agsaIORequestDesc_t *pRequest;
2209 smTraceFuncEnter(hpDBG_VERY_LOUD,"xq");
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));
2216 /* If no LL Control request entry available */
2217 if ( agNULL == pRequest )
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;
2224 /* If LL Control request entry avaliable */
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);
2238 agControllerConfig->tag = pRequest->HTag;
2240 ret = mpiBuildCmd(agRoot, (bit32 *) agControllerConfig,
2241 MPI_CATEGORY_SAS_SATA, OPC_INB_GET_CONTROLLER_CONFIG, IOMB_SIZE64, 0);
2243 if (AGSA_RC_SUCCESS != ret)
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;
2252 /* return the request to free pool */
2253 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2255 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2257 SA_DBG1(("mpiGetControllerConfigCmd, sending IOMB failed\n" ));
2261 SA_DBG3(("mpiGetControllerConfigCmd, set OK\n"));
2263 SA_DBG3(("mpiGetControllerConfigCmd, return value = %d\n", ret));
2267 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xq");
2272 /******************************************************************************/
2273 /*! \brief SAS Encryption KEK command
2275 * This command updates one or more KEK in a controller that supports encryption.
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
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
2288 /*******************************************************************************/
2289 GLOBAL bit32 mpiKekManagementCmd(
2291 agsaContext_t *agContext,
2292 agsaKekManagementCmd_t *agKekMgmt,
2296 bit32 ret = AGSA_RC_SUCCESS;
2297 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
2298 agsaIORequestDesc_t *pRequest;
2300 smTraceFuncEnter(hpDBG_VERY_LOUD,"x2");
2302 /* Get request from free IORequests */
2303 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2304 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2306 /* If no LL Control request entry available */
2307 if ( agNULL == pRequest )
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;
2314 /* If LL Control request entry avaliable */
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);
2328 SA_DBG1(("mpiKekManagementCmd, 0x%X 0x%X 0x%X\n", agKekMgmt->tag,agKekMgmt->NEWKIDX_CURKIDX_KBF_Reserved_SKNV_KSOP, agKekMgmt->reserved ));
2330 ret = mpiBuildCmd(agRoot, (bit32 *)agKekMgmt, MPI_CATEGORY_SAS_SATA, OPC_INB_KEK_MANAGEMENT, IOMB_SIZE64, 0);
2332 if (AGSA_RC_SUCCESS != ret)
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));
2343 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2344 SA_DBG1(("mpiKekManagementCmd, sending IOMB failed\n" ));
2346 SA_DBG3(("mpiKekManagementCmd, return value = %d\n", ret));
2350 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "x2");
2355 /******************************************************************************/
2356 /*! \brief SAS Encryption DEK management command
2358 * This command updates one or more DEK in a controller that supports encryption.
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
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
2371 /*******************************************************************************/
2372 GLOBAL bit32 mpiDekManagementCmd(
2374 agsaContext_t *agContext,
2375 agsaDekManagementCmd_t *agDekMgmt,
2379 bit32 ret = AGSA_RC_SUCCESS;
2380 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
2381 agsaIORequestDesc_t *pRequest;
2383 smTraceFuncEnter(hpDBG_VERY_LOUD,"xs");
2385 /* Get request from free IORequests */
2386 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2387 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2389 /* If no LL Control request entry available */
2390 if ( agNULL == pRequest )
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;
2397 /* If LL Control request entry avaliable */
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);
2411 SA_DBG1(("mpiDekManagementCmd: 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n",
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);
2421 if (AGSA_RC_SUCCESS != ret)
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;
2430 /* return the request to free pool */
2431 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2433 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2435 SA_DBG1(("mpiDekManagementCmd, sending IOMB failed\n" ));
2437 SA_DBG3(("mpiDekManagementCmd, return value = %d\n", ret));
2441 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "xs");
2446 /******************************************************************************/
2449 * This command sends operator management command.
2451 * \param agRoot Handles for this instance of SAS/SATA LLL
2452 * \param agContext Context
2453 * \param queueNum Queue Number of inbound/outbound queue
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
2461 /*******************************************************************************/
2462 GLOBAL bit32 mpiOperatorManagementCmd(
2465 agsaContext_t *agContext,
2466 agsaOperatorMangmentCmd_t *operatorcode )
2468 bit32 ret = AGSA_RC_SUCCESS;
2469 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
2470 agsaIORequestDesc_t *pRequest;
2472 smTraceFuncEnter(hpDBG_VERY_LOUD,"2q");
2474 SA_DBG1(("mpiOperatorManagementCmd, enter\n" ));
2476 /* Get request from free IORequests */
2477 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2478 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2480 /* If no LL Control request entry available */
2481 if ( agNULL == pRequest )
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;
2488 /* If LL Control request entry avaliable */
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);
2502 ret = mpiBuildCmd(agRoot, (bit32 *)operatorcode , MPI_CATEGORY_SAS_SATA, OPC_INB_OPR_MGMT, IOMB_SIZE128, 0);
2504 if (AGSA_RC_SUCCESS != ret)
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;
2513 /* return the request to free pool */
2514 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2516 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2518 SA_DBG1(("mpiOperatorManagementCmd, sending IOMB failed\n" ));
2520 SA_DBG1(("mpiOperatorManagementCmd, return value = %d\n", ret));
2524 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2q");
2529 /******************************************************************************/
2532 * This command sends encrypt self test command.
2534 * \param agRoot Handles for this instance of SAS/SATA LLL
2535 * \param agContext Context
2536 * \param queueNum Queue Number of inbound/outbound queue
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
2544 /*******************************************************************************/
2545 GLOBAL bit32 mpiEncryptBistCmd(
2548 agsaContext_t *agContext,
2549 agsaEncryptBist_t *bist )
2551 bit32 ret = AGSA_RC_SUCCESS;
2552 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
2553 agsaIORequestDesc_t *pRequest;
2555 smTraceFuncEnter(hpDBG_VERY_LOUD,"2z");
2557 SA_DBG1(("mpiEncryptBistCmd, enter\n" ));
2559 /* Get request from free IORequests */
2560 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2561 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2563 /* If no LL Control request entry available */
2564 if ( agNULL == pRequest )
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;
2571 /* If LL Control request entry avaliable */
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);
2585 SA_DBG1(("mpiEncryptBistCmd: 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n",
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);
2595 if (AGSA_RC_SUCCESS != ret)
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;
2604 /* return the request to free pool */
2605 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2607 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2609 SA_DBG1(("mpiEncryptBistCmd, sending IOMB failed\n" ));
2611 SA_DBG1(("mpiEncryptBistCmd, return value = %d\n", ret));
2615 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2z");
2620 /******************************************************************************/
2623 * This command sends set operator command.
2625 * \param agRoot Handles for this instance of SAS/SATA LLL
2626 * \param agContext Context
2627 * \param queueNum Queue Number of inbound/outbound queue
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
2635 /*******************************************************************************/
2640 agsaContext_t *agContext,
2641 agsaSetOperatorCmd_t *operatorcode
2644 bit32 ret = AGSA_RC_SUCCESS;
2645 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
2646 agsaIORequestDesc_t *pRequest;
2648 smTraceFuncEnter(hpDBG_VERY_LOUD,"39");
2650 SA_DBG1(("mpiSetOperatorCmd, enter\n" ));
2652 /* Get request from free IORequests */
2653 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2654 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2656 /* If no LL Control request entry available */
2657 if ( agNULL == pRequest )
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;
2664 /* If LL Control request entry avaliable */
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);
2678 ret = mpiBuildCmd(agRoot, (bit32 *)operatorcode, MPI_CATEGORY_SAS_SATA, OPC_INB_SET_OPERATOR, IOMB_SIZE64, 0);
2680 if (AGSA_RC_SUCCESS != ret)
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;
2689 /* return the request to free pool */
2690 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2692 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2694 SA_DBG1(("mpiSetOperatorCmd, sending IOMB failed\n" ));
2696 SA_DBG1(("mpiSetOperatorCmd, return value = %d\n", ret));
2700 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "39");
2705 /******************************************************************************/
2708 * This command sends get operator command.
2710 * \param agRoot Handles for this instance of SAS/SATA LLL
2711 * \param agContext Context
2712 * \param queueNum Queue Number of inbound/outbound queue
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
2720 /*******************************************************************************/
2725 agsaContext_t *agContext,
2726 agsaGetOperatorCmd_t *operatorcode
2729 bit32 ret = AGSA_RC_SUCCESS;
2730 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
2731 agsaIORequestDesc_t *pRequest;
2733 smTraceFuncEnter(hpDBG_VERY_LOUD,"3e");
2735 SA_DBG1(("mpiGetOperatorCmd, enter\n" ));
2737 /* Get request from free IORequests */
2738 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2739 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2741 /* If no LL Control request entry available */
2742 if ( agNULL == pRequest )
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;
2749 /* If LL Control request entry avaliable */
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);
2763 ret = mpiBuildCmd(agRoot, (bit32 *)operatorcode, MPI_CATEGORY_SAS_SATA, OPC_INB_GET_OPERATOR, IOMB_SIZE64, 0);
2765 if (AGSA_RC_SUCCESS != ret)
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;
2774 /* return the request to free pool */
2775 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2777 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2779 SA_DBG1(("mpiGetOperatorCmd, sending IOMB failed\n" ));
2781 SA_DBG1(("mpiGetOperatorCmd, return value = %d\n", ret));
2785 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "3e");
2790 GLOBAL bit32 mpiDIFEncryptionOffloadCmd(
2792 agsaContext_t *agContext,
2795 agsaDifEncPayload_t *agDifEncOffload,
2796 ossaDIFEncryptionOffloadStartCB_t agCB
2799 bit32 ret = AGSA_RC_SUCCESS;
2805 agsaLLRoot_t *saRoot = (agsaLLRoot_t *) (agRoot->sdkData);
2806 agsaIORequestDesc_t *pRequest;
2807 agsaDifEncOffloadCmd_t payload;
2808 smTraceFuncEnter(hpDBG_VERY_LOUD,"2b");
2810 /* Get request from free IORequests */
2811 ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2812 pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
2814 /* If no LL Control request entry available */
2815 if ( agNULL == pRequest )
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;
2822 /* If LL Control request entry avaliable */
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);
2836 si_memset(&payload, 0, sizeof(agsaDifEncOffloadCmd_t));
2837 SA_DBG1(("mpiDIFEncryptionOffloadCmd: op %d\n",op));
2839 if(smIS_SPCV(agRoot))
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);
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);
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];
2863 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, UDTR2345), dw10);
2865 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, DPLR0SecCnt_IOSeed),
2866 agDifEncOffload->dif.DIFPerLARegion0SecCount << SHIFT16 |
2867 agDifEncOffload->dif.initialIOSeed);
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);
2872 dw14 = agDifEncOffload->encrypt.dekInfo.dekIndex << SHIFT8 |
2873 (agDifEncOffload->encrypt.dekInfo.dekTable & 0x3) << SHIFT2 |
2874 (agDifEncOffload->encrypt.keyTagCheck & 0x1) << SHIFT1;
2876 if (agDifEncOffload->encrypt.cipherMode == agsaEncryptCipherModeXTS)
2878 dw14 |= AGSA_ENCRYPT_XTS_Mode << SHIFT4;
2882 dw14 |= (agDifEncOffload->encrypt.cipherMode & 0xF) << SHIFT4;
2885 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, KeyIndex_CMode_KTS_ENT_R), dw14);
2887 dw15 = agDifEncOffload->encrypt.EncryptionPerLRegion0SecCount << SHIFT16 |
2888 (agDifEncOffload->encrypt.kekIndex & 0xF) << SHIFT5 |
2889 (agDifEncOffload->encrypt.sectorSizeIndex & 0x1F);
2891 OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaDifEncOffloadCmd_t, EPLR0SecCnt_KS_ENSS), dw15);
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);
2902 si_memcpy((bit32 *) &(payload.SrcSgl), (bit32 *) &(agDifEncOffload->SrcSgl), sizeof(agsaSgl_t));
2903 si_memcpy((bit32 *) &(payload.DstSgl), (bit32 *) &(agDifEncOffload->DstSgl), sizeof(agsaSgl_t));
2905 ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_DIF_ENC_OFFLOAD_CMD, IOMB_SIZE128, queueNum);
2910 /* SPC does not support this command */
2911 ret = AGSA_RC_FAILURE;
2914 if (AGSA_RC_SUCCESS != ret)
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;
2923 /* return the request to free pool */
2924 saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
2926 ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
2928 SA_DBG1(("mpiDIFEncryptionOffloadCmd: sending IOMB failed\n" ));
2930 SA_DBG3(("mpiDIFEncryptionOffloadCmd: return value = %d\n", ret));
2934 smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2b");