The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/pms/RefTisa/sallsdk/spc/sampicmd.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 5bb812b40868533bb7b5f725efc523bd


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.