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/sasmp.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 sasmp.c
   24  *  \brief The file implements the functions for SMP request/response
   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 'N'
   38 #endif
   39 
   40 /******************************************************************************/
   41 /*! \brief Start SMP request
   42  *
   43  *  Start SMP request
   44  *
   45  *  \param agRoot handles for this instance of SAS/SATA hardware
   46  *  \param queueNum
   47  *  \param agIORequest
   48  *  \param agDevHandle
   49  *  \param agRequestType
   50  *  \param agRequestBody
   51  *  \param agCB
   52  * Spc - support    direct mode direct response
   53  * SpcV - support   direct mode direct response
   54  * SpcV - support indirect mode  direct response
   55  * SpcV - support indirect mode indirect response
   56  *
   57  *  \return If request is started successfully
   58  *          - \e AGSA_RC_SUCCESS request is started successfully
   59  *          - \e AGSA_RC_BUSY No resource available, try again later
   60  */
   61 /*******************************************************************************/
   62 GLOBAL bit32 saSMPStart(
   63   agsaRoot_t            *agRoot,
   64   agsaIORequest_t       *agIORequest,
   65   bit32                 queueNum,
   66   agsaDevHandle_t       *agDevHandle,
   67   bit32                 agRequestType,
   68   agsaSASRequestBody_t  *agRequestBody,
   69   ossaSMPCompletedCB_t  agCB
   70   )
   71 {
   72   bit32                     ret = AGSA_RC_SUCCESS, retVal;
   73   agsaLLRoot_t              *saRoot = agNULL;
   74   mpiICQueue_t              *circularQ;
   75   agsaDeviceDesc_t          *pDevice;
   76   agsaPort_t                *pPort;
   77   agsaIORequestDesc_t       *pRequest;
   78   void                      *pMessage;
   79   bit8                      i, inq, outq;
   80   bit8                      using_reserved = agFALSE;
   81   bit8                      *payload_ptr;
   82   agsaSMPFrame_t            *pSMPFrame;
   83 
   84   SA_DBG4(("saSMPStart: start\n"));
   85 
   86   smTraceFuncEnter(hpDBG_VERY_LOUD, "9a");
   87 
   88   /* sanity check */
   89   SA_ASSERT((agNULL != agRoot), "");
   90   SA_ASSERT((agNULL != agIORequest), "");
   91   SA_ASSERT((agNULL != agDevHandle), "");
   92   SA_ASSERT((agNULL != agRequestBody), "");
   93 
   94   /* sanity check */
   95   saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
   96   SA_ASSERT((agNULL != saRoot), "");
   97 
   98   if(saRoot == agNULL)
   99   {
  100     SA_DBG1(("saSMPStart : saRoot is NULL!!\n"));
  101     return AGSA_RC_FAILURE;
  102   }
  103   
  104   /* Assign inbound and outbound queue number */
  105   inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
  106   outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
  107   SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
  108 
  109   /* Find the outgoing port for the device */
  110   if (agNULL == agDevHandle->sdkData)
  111   {
  112     /* Device has been removed */
  113     SA_DBG1(("saSMPStart, Device has been removed. agDevHandle=%p\n", agDevHandle));
  114     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "9a");
  115     return AGSA_RC_FAILURE;
  116   }
  117 
  118   pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
  119 
  120   pPort = pDevice->pPort;
  121 
  122   /* Get request from free IO Requests */
  123   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  124   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/
  125 
  126   /* If no LL IO request entry available */
  127   if ( agNULL == pRequest )
  128   {
  129 
  130     pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests));
  131 
  132     if(agNULL != pRequest)
  133     {
  134       using_reserved = agTRUE;
  135       SA_DBG1(("saSMPStart, using saRoot->freeReservedRequests\n"));
  136     }
  137     else
  138     {
  139       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  140       SA_DBG1(("saSMPStart, No request from free list Not using saRoot->freeReservedRequests\n"));
  141       smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "9a");
  142       return AGSA_RC_BUSY;
  143     }
  144   }
  145 
  146   /* If free IOMB avaliable */
  147   /* Remove the request from free list */
  148   if( using_reserved )
  149   {
  150     saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
  151   }
  152   else
  153   {
  154     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
  155   }
  156 
  157   /* Add the request to the pendingSMPRequests list of the device */
  158   saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode));
  159   SA_ASSERT((!pRequest->valid), "The pRequest is in use");
  160   pRequest->valid             = agTRUE;
  161   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  162 
  163   /* set up pRequest */
  164   pRequest->pIORequestContext = agIORequest;
  165   pRequest->pDevice           = pDevice;
  166   pRequest->pPort             = pPort;
  167   pRequest->requestType       = agRequestType;
  168   pRequest->startTick         = saRoot->timeTick;
  169   pRequest->completionCB      = (ossaSSPCompletedCB_t)agCB;
  170 
  171   /* Set request to the sdkData of agIORequest */
  172   agIORequest->sdkData        = pRequest;
  173 
  174   /* save tag to IOMap */
  175   saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
  176   saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
  177 
  178 #ifdef SA_LL_IBQ_PROTECT
  179   ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
  180 #endif /* SA_LL_IBQ_PROTECT */
  181 
  182   /* If LL IO request entry avaliable */
  183   /* Get a free inbound queue entry */
  184   circularQ = &saRoot->inboundQueue[inq];
  185   retVal    = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage);
  186 
  187   if (AGSA_RC_FAILURE == retVal)
  188   {
  189 #ifdef SA_LL_IBQ_PROTECT
  190     ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
  191 #endif /* SA_LL_IBQ_PROTECT */
  192     /* if not sending return to free list rare */
  193     ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  194     saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
  195     pRequest->valid = agFALSE;
  196     saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
  197     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  198 
  199     SA_DBG1(("saSMPStart, error when get free IOMB\n"));
  200     smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "9a");
  201     return AGSA_RC_FAILURE;
  202   }
  203 
  204   /* return busy if inbound queue is full */
  205   if (AGSA_RC_BUSY == retVal)
  206   {
  207 #ifdef SA_LL_IBQ_PROTECT
  208     ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
  209 #endif /* SA_LL_IBQ_PROTECT */
  210     /* if not sending return to free list rare */
  211     ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  212     saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
  213     pRequest->valid = agFALSE;
  214     saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
  215     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  216 
  217     SA_DBG1(("saSMPStart, no more IOMB\n"));
  218     smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "9a");
  219     return AGSA_RC_BUSY;
  220   }
  221 
  222   /* Setup SMP Frame */
  223   pSMPFrame = (agsaSMPFrame_t *) &(agRequestBody->smpFrame);
  224 
  225   SA_DBG2(("saSMPStart:DeviceMapIndex 0x%x portId 0x%x portId 0x%x\n",pDevice->DeviceMapIndex,pPort->portId,pPort->portId));
  226 
  227 #if defined(SALLSDK_DEBUG)
  228 
  229   SA_DBG2(("saSMPStart: outFrameBuf  %p\n",pSMPFrame->outFrameBuf));
  230 
  231   if(pSMPFrame->outFrameBuf )
  232   {
  233     SA_DBG2(("saSMPStart: outFrameBuf 0  0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+0) ));
  234     SA_DBG2(("saSMPStart: outFrameBuf 1  0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+1) ));
  235     SA_DBG2(("saSMPStart: outFrameBuf 2  0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+2) ));
  236     SA_DBG2(("saSMPStart: outFrameBuf 3  0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+3) ));
  237     SA_DBG2(("saSMPStart: outFrameBuf 4  0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+4) ));
  238     SA_DBG2(("saSMPStart: outFrameBuf 5  0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+5) ));
  239     SA_DBG2(("saSMPStart: outFrameBuf 6  0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+6) ));
  240     SA_DBG2(("saSMPStart: outFrameBuf 7  0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+7) ));
  241     SA_DBG2(("saSMPStart: outFrameBuf 8  0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+8) ));
  242     SA_DBG2(("saSMPStart: outFrameBuf 9  0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+9) ));
  243     SA_DBG2(("saSMPStart: outFrameBuf 11 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+10) ));
  244     SA_DBG2(("saSMPStart: outFrameBuf 11 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+11) ));
  245   }
  246   SA_DBG2(("saSMPStart: outFrameAddrUpper32 0x%08X\n",pSMPFrame->outFrameAddrUpper32));
  247   SA_DBG2(("saSMPStart: outFrameAddrLower32 0x%08X\n",pSMPFrame->outFrameAddrLower32));
  248   SA_DBG2(("saSMPStart: outFrameLen         0x%08X\n",pSMPFrame->outFrameLen));
  249   SA_DBG2(("saSMPStart: inFrameAddrUpper32  0x%08X\n",pSMPFrame->inFrameAddrUpper32));
  250   SA_DBG2(("saSMPStart: inFrameAddrLower32  0x%08X\n",pSMPFrame->inFrameAddrLower32));
  251   SA_DBG2(("saSMPStart: inFrameLen          0x%08X\n",pSMPFrame->inFrameLen));
  252   SA_DBG2(("saSMPStart: expectedRespLen     0x%08X\n",pSMPFrame->expectedRespLen));
  253   SA_DBG2(("saSMPStart: flag                0x%08X\n",pSMPFrame->flag));
  254 #endif /* SALLSDK_DEBUG */
  255 
  256   if(smIS_SPC(agRoot))
  257   // if(1)
  258   {
  259     agsaSMPCmd_t payload;
  260     switch ( agRequestType )
  261     {
  262       case AGSA_SMP_INIT_REQ:
  263       {
  264         bit32 IR_IP_OV_res_phyId_DPdLen_res = 0;
  265         /* Prepare the payload of IOMB */
  266         si_memset(&payload, 0, sizeof(agsaSMPCmd_t));
  267         OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, tag), pRequest->HTag);
  268         OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, deviceId), pDevice->DeviceMapIndex);
  269 
  270         /* check SMP Response Frame with IR mode */
  271         /* check if the SMP Response is indirect mode */
  272         if (0 == pSMPFrame->inFrameLen)
  273         {
  274           /* PHY override not support */
  275           /* Direct Response mode */
  276           pRequest->IRmode = DIRECT_MODE;
  277         }
  278         else
  279         {
  280           /* Indirect Response mode */
  281           pRequest->IRmode = INDIRECT_MODE;
  282           IR_IP_OV_res_phyId_DPdLen_res = 1;
  283           /* check SMP direct payload mode len */
  284           if (pSMPFrame->outFrameLen > 32)
  285           {
  286 #ifdef SA_LL_IBQ_PROTECT
  287             ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
  288 #endif /* SA_LL_IBQ_PROTECT */
  289             /* if not sending return to free list rare */
  290             ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  291             saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
  292             pRequest->valid = agFALSE;
  293             saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
  294             ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  295             /* can not handle SMP frame length > 32 bytes it if IP=0 and IR=1 */
  296             SA_DBG1(("saSMPStart, outFrameLen > 32 bytes error.\n"));
  297             smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "9a");
  298             return AGSA_RC_FAILURE;
  299           }
  300         }
  301 
  302         /* check Direct mode or Indirect mode for IP mode */
  303         if ( (pSMPFrame->outFrameBuf &&
  304               (pSMPFrame->outFrameLen <= AGSA_MAX_SMPPAYLOAD_VIA_SFO)) ||
  305              ((pSMPFrame->outFrameBuf == agNULL) &&
  306               (pSMPFrame->outFrameLen == 0) )
  307            )
  308         {
  309           SA_DBG4(("saSMPStart: DIRECT Request SMP\n"));
  310 
  311           IR_IP_OV_res_phyId_DPdLen_res = (DIRECT_MODE << 1) | IR_IP_OV_res_phyId_DPdLen_res;
  312 
  313           /* Direct payload length */
  314           IR_IP_OV_res_phyId_DPdLen_res |= (((pSMPFrame->outFrameLen) & 0xff) << SHIFT16);
  315 
  316           /* copy payload - upto 48 bytes */
  317           si_memcpy(&(payload.SMPCmd[0]),pSMPFrame->outFrameBuf,pSMPFrame->outFrameLen);
  318           for ( i = 0; i < pSMPFrame->outFrameLen / sizeof(bit32)+1; i ++ )
  319           {
  320             SA_DBG4(("saSMPStart: payload.SMPCmd[%d] %x\n", i, payload.SMPCmd[i]));
  321           }
  322         }
  323         else
  324         {
  325           SA_DBG4(("saSMPStart: INDIRECT Request SMP\n"));
  326           /* use physical address */
  327           IR_IP_OV_res_phyId_DPdLen_res = (INDIRECT_MODE << 1) | IR_IP_OV_res_phyId_DPdLen_res;
  328 
  329           /* Direct payload length = 0 */
  330           IR_IP_OV_res_phyId_DPdLen_res = IR_IP_OV_res_phyId_DPdLen_res & 0xff00ffff;
  331 
  332           /* payload */
  333           OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[4]), (pSMPFrame->outFrameAddrLower32));
  334           OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[5]), (pSMPFrame->outFrameAddrUpper32));
  335           OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[6]), (pSMPFrame->outFrameLen));
  336         }
  337         /* Write IR_IP_OV_res_phyId_DPdLen_res field in the payload*/
  338         OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, IR_IP_OV_res_phyId_DPdLen_res), IR_IP_OV_res_phyId_DPdLen_res);
  339 
  340         /* check IR bit */
  341         if (IR_IP_OV_res_phyId_DPdLen_res & INDIRECT_MODE)
  342         {
  343           /* setup indirect response frame address */
  344           OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[8]), (pSMPFrame->inFrameAddrLower32));
  345           OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[9]), (pSMPFrame->inFrameAddrUpper32));
  346           OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[10]), (pSMPFrame->inFrameLen));
  347         }
  348 
  349         /* Build IOMB command and send it to SPC */
  350         payload_ptr = (bit8 *)&payload;
  351         ret = mpiSMPCmd(agRoot, pMessage, OPC_INB_SMP_REQUEST, (agsaSMPCmd_t *)payload_ptr, inq, outq);
  352 
  353   #ifdef SA_LL_IBQ_PROTECT
  354         ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
  355   #endif /* SA_LL_IBQ_PROTECT */
  356 
  357         break;
  358       }
  359       default:
  360       {
  361         SA_DBG1(("saSMPStart: SPC unknown agRequestType  %x\n",agRequestType));
  362         break;
  363       }
  364     }
  365 
  366 #ifdef SALL_API_TEST
  367   if (ret == AGSA_RC_SUCCESS)
  368     saRoot->LLCounters.IOCounter.numSMPStarted++;
  369 #endif
  370   }
  371   else /* IOMB is different for SPCV SMP */
  372   {
  373    agsaSMPCmd_V_t vpayload;
  374 
  375     switch ( agRequestType )
  376     {
  377       case AGSA_SMP_INIT_REQ:
  378       {
  379         bit32 IR_IP_OV_res_phyId_DPdLen_res = 0;
  380         /* Prepare the payload of IOMB */
  381         si_memset(&vpayload, 0, sizeof(agsaSMPCmd_V_t));
  382         OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, tag), pRequest->HTag);
  383         OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, deviceId), pDevice->DeviceMapIndex);
  384 
  385         /* Request header must be valid regardless of IP bit */
  386         OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMPHDR ), *((bit32*)pSMPFrame->outFrameBuf+0) );
  387 
  388         /* check SMP Response Frame with IR mode */
  389         /* check if the SMP Response is indirect mode */
  390         // smpFrameFlagDirectResponse smpFrameFlagDirectPayload
  391         if ( 0 == pSMPFrame->flag && pSMPFrame->outFrameBuf )
  392         {
  393           /* PHY override not support */
  394           /* Direct Response mode */
  395           pRequest->IRmode = DIRECT_MODE;
  396           SA_DBG2(("saSMPStart:V DIRECT Request SMP\n"));
  397 
  398           IR_IP_OV_res_phyId_DPdLen_res = (DIRECT_MODE << 1) | IR_IP_OV_res_phyId_DPdLen_res;
  399 
  400           /* Direct payload length */
  401           IR_IP_OV_res_phyId_DPdLen_res |= (((pSMPFrame->outFrameLen) & 0xff) << SHIFT16);
  402           /* Write IR_IP_OV_res_phyId_DPdLen_res field in the payload*/
  403           /* fatal error if missing */
  404           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, IR_IP_OV_res_phyId_DPdLen_res), IR_IP_OV_res_phyId_DPdLen_res);
  405           /* fatal error if missing */
  406 
  407           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMP3_0 ), *((bit32*)pSMPFrame->outFrameBuf+1) );
  408           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMP7_4 ), *((bit32*)pSMPFrame->outFrameBuf+2) );
  409           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMP11_8), *((bit32*)pSMPFrame->outFrameBuf+3) );
  410 
  411           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirL_SMPRF15_12 ),     *((bit32*)pSMPFrame->outFrameBuf+4) );
  412           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirH_or_SMPRF19_16 ),  *((bit32*)pSMPFrame->outFrameBuf+5) );
  413           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirLen_or_SMPRF23_20 ),*((bit32*)pSMPFrame->outFrameBuf+6) );
  414           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,R_or_SMPRF27_24),        *((bit32*)pSMPFrame->outFrameBuf+7) );
  415 
  416           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,ISRAL_or_SMPRF31_28 ),   *((bit32*)pSMPFrame->outFrameBuf+8) );
  417           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,ISRAH_or_SMPRF35_32 ),   *((bit32*)pSMPFrame->outFrameBuf+9) );
  418           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,ISRL_or_SMPRF39_36 ),    *((bit32*)pSMPFrame->outFrameBuf+10) );
  419           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,R_or_SMPRF43_40 ),       *((bit32*)pSMPFrame->outFrameBuf+11) );
  420 
  421         }
  422         else if (smpFrameFlagIndirectResponse & pSMPFrame->flag && smpFrameFlagIndirectPayload & pSMPFrame->flag) /* */
  423         {
  424           /* IR IP */
  425           SA_DBG2(("saSMPStart:V smpFrameFlagIndirectResponse smpFrameFlagIndirectPayload SMP\n"));
  426 
  427           pRequest->IRmode = INDIRECT_MODE;
  428           IR_IP_OV_res_phyId_DPdLen_res = 3;
  429 
  430           /* Indirect payload mode */
  431           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirL_SMPRF15_12 ), pSMPFrame->outFrameAddrLower32);
  432           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirH_or_SMPRF19_16 ), pSMPFrame->outFrameAddrUpper32);
  433           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirLen_or_SMPRF23_20 ), pSMPFrame->outFrameLen);
  434           /* Indirect Response mode */
  435           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRAL_or_SMPRF31_28 ), (pSMPFrame->inFrameAddrLower32));
  436           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRAH_or_SMPRF35_32 ), (pSMPFrame->inFrameAddrUpper32));
  437           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRL_or_SMPRF39_36 ), (pSMPFrame->inFrameLen));
  438         }
  439         else if (smpFrameFlagIndirectPayload & pSMPFrame->flag ) /* */
  440         {
  441           /* IP */
  442           SA_DBG2(("saSMPStart:V  smpFrameFlagIndirectPayload SMP\n"));
  443           pRequest->IRmode = DIRECT_MODE;
  444           IR_IP_OV_res_phyId_DPdLen_res = 2;
  445 
  446           /* Indirect payload mode */
  447           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirL_SMPRF15_12 ), pSMPFrame->outFrameAddrLower32);
  448           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirH_or_SMPRF19_16 ), pSMPFrame->outFrameAddrUpper32);
  449           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirLen_or_SMPRF23_20 ), pSMPFrame->outFrameLen);
  450         }
  451         else if (smpFrameFlagIndirectResponse & pSMPFrame->flag ) /* */
  452         {
  453           /* check IR bit */
  454           /* Indirect Response mode */
  455           pRequest->IRmode = INDIRECT_MODE;
  456           SA_DBG2(("saSMPStart:V smpFrameFlagIndirectResponse SMP\n"));
  457           /* use physical address */
  458           IR_IP_OV_res_phyId_DPdLen_res = 1;
  459           /* Direct payload length */
  460           IR_IP_OV_res_phyId_DPdLen_res |= (((pSMPFrame->outFrameLen) & 0xff) << SHIFT16);
  461 
  462           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMP3_0 ), *((bit32*)pSMPFrame->outFrameBuf+1) );
  463           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMP7_4 ), *((bit32*)pSMPFrame->outFrameBuf+2) );
  464           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMP11_8), *((bit32*)pSMPFrame->outFrameBuf+3) );
  465 
  466           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirL_SMPRF15_12 ),     *((bit32*)pSMPFrame->outFrameBuf+4) );
  467           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirH_or_SMPRF19_16 ),  *((bit32*)pSMPFrame->outFrameBuf+5) );
  468           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirLen_or_SMPRF23_20 ),*((bit32*)pSMPFrame->outFrameBuf+6) );
  469           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,R_or_SMPRF27_24),        *((bit32*)pSMPFrame->outFrameBuf+7) );
  470 
  471           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRAL_or_SMPRF31_28 ), (pSMPFrame->inFrameAddrLower32));
  472           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRAH_or_SMPRF35_32 ), (pSMPFrame->inFrameAddrUpper32));
  473           OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRL_or_SMPRF39_36 ), (pSMPFrame->inFrameLen));
  474         }
  475         IR_IP_OV_res_phyId_DPdLen_res |= (pSMPFrame->flag & 3);
  476         /* fatal error if missing */
  477         OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, IR_IP_OV_res_phyId_DPdLen_res), IR_IP_OV_res_phyId_DPdLen_res);
  478         /* fatal error if missing */
  479       }
  480       /* Build IOMB command and send it to SPCv */
  481       payload_ptr = (bit8 *)&vpayload;
  482       ret = mpiSMPCmd(agRoot, pMessage, OPC_INB_SMP_REQUEST, (agsaSMPCmd_t *)payload_ptr, inq, outq);
  483 
  484 #ifdef SA_LL_IBQ_PROTECT
  485       ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
  486 #endif /* SA_LL_IBQ_PROTECT */
  487 
  488       break;
  489       default:
  490       {
  491         SA_DBG1(("saSMPStart: SPCv unknown agRequestType  %x\n",agRequestType));
  492         break;
  493       }
  494     }
  495   }
  496 
  497   smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "9a");
  498 
  499   /* return */
  500   return ret;
  501 }
  502 
  503 /******************************************************************************/
  504 /*! \brief Abort SMP request
  505  *
  506  *  Abort SMP request
  507  *
  508  *  \param agRoot handles for this instance of SAS/SATA hardware
  509  *  \param queueNum
  510  *  \param agIORequest
  511  *
  512  *  \return If request is aborted successfully
  513  *          - \e AGSA_RC_SUCCESS request is aborted successfully
  514  *          - \e AGSA_RC_FAILURE request is not aborted successfully
  515  */
  516 /*******************************************************************************/
  517 GLOBAL bit32 saSMPAbort(
  518   agsaRoot_t           *agRoot,
  519   agsaIORequest_t      *agIORequest,
  520   bit32                 queueNum,
  521   agsaDevHandle_t      *agDevHandle,
  522   bit32                 flag,
  523   void                 *abortParam,
  524   ossaGenericAbortCB_t  agCB
  525   )
  526 {
  527   bit32 ret = AGSA_RC_SUCCESS;
  528   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
  529   agsaIORequestDesc_t *pRequest;
  530   agsaIORequestDesc_t *pRequestABT = NULL;
  531   agsaIORequest_t     *agIOToBeAborted;
  532   agsaDeviceDesc_t    *pDevice;
  533   agsaSMPAbortCmd_t   payload;
  534   bit32               using_reserved = agFALSE;
  535 
  536   smTraceFuncEnter(hpDBG_VERY_LOUD,"9b");
  537 
  538   /* sanity check */
  539   SA_ASSERT((agNULL != agRoot), "");
  540   SA_ASSERT((agNULL != agIORequest), "");
  541   SA_ASSERT((agNULL != agDevHandle), "");
  542 
  543   SA_DBG3(("saSMPAbort: Aborting request %p\n", agIORequest));
  544 
  545   if( ABORT_SINGLE == (flag & ABORT_MASK) )
  546   {
  547     agIOToBeAborted = (agsaIORequest_t *)abortParam;
  548     /* Get LL IORequest entry for saSMPAbort() */
  549     pRequestABT = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData);
  550     if (agNULL == pRequestABT)
  551     {
  552       /* The IO to Be Abort is no longer exist - can not Abort */
  553       SA_DBG1(("saSMPAbort: pRequestABT AGSA_RC_FAILURE\n"));
  554       smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "9b");
  555       return AGSA_RC_FAILURE;
  556     }
  557 
  558     /* Find the device the request Abort to */
  559     pDevice = pRequestABT->pDevice;
  560 
  561     if (agNULL == pDevice)
  562     {
  563       /* no deviceID - can not build IOMB */
  564       SA_DBG1(("saSMPAbort: pDevice AGSA_RC_FAILURE\n"));
  565       smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "9b");
  566       return AGSA_RC_FAILURE;
  567     }
  568   }
  569   else
  570   {
  571     if (ABORT_ALL == (flag & ABORT_MASK))
  572     {
  573       /* abort All with Device or Port */
  574       /* Find the outgoing port for the device */
  575       pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
  576       if (agNULL == pDevice)
  577       {
  578         /* no deviceID - can not build IOMB */
  579         SA_DBG1(("saSMPAbort:ABORT_ALL pDevice AGSA_RC_FAILURE\n"));
  580         smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "9b");
  581         return AGSA_RC_FAILURE;
  582       }
  583     }
  584     else
  585     {
  586       /* only support 00 and 01 for flag */
  587       SA_DBG1(("saSMPAbort:flag  AGSA_RC_FAILURE\n"));
  588       smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "9b");
  589       return AGSA_RC_FAILURE;
  590     }
  591   }
  592 
  593   /* Get LL IORequest entry */
  594   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  595   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
  596 
  597   /* If no LL IO request entry available */
  598   if ( agNULL == pRequest )
  599   {
  600     pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests)); /**/
  601     /* If no LL Control request entry available */
  602     if(agNULL != pRequest)
  603     {
  604       using_reserved = agTRUE;
  605       SA_DBG1(("saSMPAbort, using saRoot->freeReservedRequests\n"));
  606     }
  607     else
  608     {
  609       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  610       SA_DBG1(("saSMPAbort, No request from free list Not using saRoot->freeReservedRequests\n"));
  611       smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "9b");
  612       return AGSA_RC_BUSY;
  613     }
  614   }
  615 
  616   /* If free IOMB avaliable */
  617   /* Remove the request from free list */
  618   if( using_reserved )
  619   {
  620     saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
  621   }
  622   else
  623   {
  624     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
  625   }
  626 
  627   /* Add the request to the pendingSMPRequests list of the device */
  628   saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode));
  629   SA_ASSERT((!pRequest->valid), "The pRequest is in use");
  630   pRequest->valid             = agTRUE;
  631   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  632   /* set up pRequest */
  633   pRequest->pIORequestContext = agIORequest;
  634   pRequest->requestType       = AGSA_SMP_REQTYPE;
  635   pRequest->completionCB = (void*)agCB;
  636   pRequest->pDevice           = pDevice;
  637   pRequest->startTick         = saRoot->timeTick;
  638 
  639   /* Set request to the sdkData of agIORequest */
  640   agIORequest->sdkData        = pRequest;
  641 
  642   /* save tag to IOMap */
  643   saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
  644   saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
  645 
  646   /* setup payload */
  647   OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPAbortCmd_t, tag), pRequest->HTag);
  648 
  649   if( ABORT_SINGLE == (flag & ABORT_MASK) )
  650   {
  651     if (agNULL == pRequestABT)
  652     {
  653       /* remove the request from IOMap */
  654       saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
  655       saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
  656       saRoot->IOMap[pRequest->HTag].agContext = agNULL;
  657       /* Delete the request from the pendingSMPRequests */
  658       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  659       saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
  660       /* return the request to free pool */
  661       if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
  662       {
  663         SA_DBG1(("saSMPAbort: saving pRequest (%p) for later use\n", pRequest));
  664         saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
  665       }
  666       else
  667       {
  668         /* return the request to free pool */
  669         saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
  670       }
  671       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  672       SA_DBG1(("saSMPAbort, agNULL == pRequestABT\n"));
  673       /* The IO to Be Abort is no longer exist - can not Abort */
  674       smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "9b");
  675       return AGSA_RC_FAILURE;
  676     }
  677     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPAbortCmd_t, HTagAbort), pRequestABT->HTag);
  678   }
  679   else
  680   {
  681     /* abort all */
  682     OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPAbortCmd_t, HTagAbort), 0);
  683   }
  684   OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPAbortCmd_t, deviceId), pDevice->DeviceMapIndex);
  685   OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPAbortCmd_t, Scp), flag);
  686 
  687   SA_DBG1(("saSMPAbort, HTag 0x%x HTagABT 0x%x deviceId 0x%x\n", payload.tag, payload.HTagAbort, payload.deviceId));
  688 
  689   /* build IOMB command and send to SPC */
  690   ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SMP_ABORT, IOMB_SIZE64, queueNum);
  691   if (AGSA_RC_SUCCESS != ret)
  692   {
  693     /* remove the request from IOMap */
  694     saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF;
  695     saRoot->IOMap[pRequest->HTag].IORequest = agNULL;
  696     saRoot->IOMap[pRequest->HTag].agContext = agNULL;
  697     /* Delete the request from the pendingSMPRequests */
  698     ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  699     saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
  700     /* return the request to free pool */
  701     if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
  702     {
  703       SA_DBG1(("saSMPAbort: saving pRequest (%p) for later use\n", pRequest));
  704       saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
  705     }
  706     else
  707     {
  708       /* return the request to free pool */
  709       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
  710     }
  711     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  712     SA_DBG1(("saSMPAbort, sending IOMB failed\n" ));
  713   }
  714 #ifdef SALL_API_TEST
  715   else
  716   {
  717     saRoot->LLCounters.IOCounter.numSMPAborted++;
  718   }
  719 #endif
  720 
  721   smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "9b");
  722 
  723   return ret;
  724 }
  725 
  726 
  727 

Cache object: aff1370e0f5c382e8cf3b9d3015ed345


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