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

Cache object: e5c44520fb23e2f918847e1174e98ff8


[ 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.