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/sassp.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 **
    3 *Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved. 
    4 *
    5 *Redistribution and use in source and binary forms, with or without modification, are permitted provided 
    6 *that the following conditions are met: 
    7 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
    8 *following disclaimer. 
    9 *2. Redistributions in binary form must reproduce the above copyright notice, 
   10 *this list of conditions and the following disclaimer in the documentation and/or other materials provided
   11 *with the distribution. 
   12 *
   13 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 
   14 *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   15 *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   16 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
   17 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
   18 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
   19 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
   20 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
   21 
   22 ********************************************************************************/
   23 /*******************************************************************************/
   24 /*! \file sassp.c
   25  *  \brief The file implements the functions for SSP request/response
   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 'O'
   39 #endif
   40 
   41 #ifdef LOOPBACK_MPI
   42 extern int loopback;
   43 #endif
   44 
   45 #ifdef SALLSDK_DEBUG
   46 LOCAL void siDumpSSPStartIu(
   47   agsaDevHandle_t       *agDevHandle,
   48   bit32                 agRequestType,
   49   agsaSASRequestBody_t  *agRequestBody
   50   );
   51 #endif
   52 
   53 #ifdef FAST_IO_TEST
   54 LOCAL bit32 saGetIBQPI(agsaRoot_t *agRoot,
   55                        bit32 queueNum)
   56 {
   57   bit8         inq;
   58   mpiICQueue_t *circularQ;
   59   agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
   60 
   61   inq = INQ(queueNum);
   62   circularQ = &saRoot->inboundQueue[inq];
   63   return circularQ->producerIdx;
   64 }
   65 
   66 LOCAL void saSetIBQPI(agsaRoot_t *agRoot,
   67                       bit32      queueNum,
   68                       bit32      pi)
   69 {
   70   bit8         inq;
   71   mpiICQueue_t *circularQ;
   72   agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
   73 
   74   inq = INQ(queueNum);
   75   circularQ = &saRoot->inboundQueue[inq];
   76   circularQ->producerIdx = pi;
   77 }
   78 
   79 osLOCAL void*
   80 siFastSSPReqAlloc(agsaRoot_t *agRoot)
   81 {
   82   int             idx;
   83   agsaLLRoot_t    *saRoot = (agsaLLRoot_t*)(agRoot->sdkData);
   84   saFastRequest_t *fr;
   85 
   86   if (!saRoot->freeFastIdx)
   87   {
   88     SA_DBG1(("saSuperSSPReqAlloc: no memory ERROR\n"));
   89     SA_ASSERT((0), "");
   90     return 0;
   91   }
   92 
   93   ossaSingleThreadedEnter(agRoot, LL_FAST_IO_LOCK);
   94   saRoot->freeFastIdx--;
   95   idx = saRoot->freeFastIdx;
   96   ossaSingleThreadedLeave(agRoot, LL_FAST_IO_LOCK);
   97 
   98   fr = saRoot->freeFastReq[idx];
   99   SA_ASSERT((fr), "");
  100   fr->valid = 1;
  101 
  102   return fr;
  103 }
  104 
  105 LOCAL void
  106 siFastSSPReqFree(
  107              agsaRoot_t *agRoot,
  108              void       *freq)
  109 {
  110   agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
  111   saFastRequest_t *fr = (saFastRequest_t*)freq;
  112 
  113   SA_DBG2(("siFastSSPReqFree: enter\n"));
  114   SA_ASSERT((fr->valid), "");
  115   if (saRoot->freeFastIdx >= sizeof(saRoot->freeFastReq) /
  116                              sizeof(saRoot->freeFastReq[0]))
  117   {
  118     SA_DBG1(("siFastSSPReqFree: too many handles %d / %d ERROR\n",
  119              saRoot->freeFastIdx, (int)(sizeof(saRoot->freeFastReq) /
  120              sizeof(saRoot->freeFastReq[0]))));
  121     SA_ASSERT((0), "");
  122     return;
  123   }
  124   ossaSingleThreadedEnter(agRoot, LL_FAST_IO_LOCK);
  125   /* not need if only one entry */
  126   /* saRoot->freeFastReq[saRoot->freeFastIdx] = freq;  */
  127   saRoot->freeFastIdx++;
  128   ossaSingleThreadedLeave(agRoot, LL_FAST_IO_LOCK);
  129 
  130   fr->valid = 0;
  131   SA_DBG6(("siFastSSPReqFree: leave\n"));
  132 }
  133 
  134 LOCAL bit32 siFastSSPResAlloc(
  135   agsaRoot_t             *agRoot,
  136   bit32                  queueNum,
  137   bit32                  agRequestType,
  138   agsaDeviceDesc_t       *pDevice,
  139   agsaIORequestDesc_t    **pRequest,
  140   void                   **pPayload
  141   )
  142 {
  143   agsaLLRoot_t *saRoot = (agsaLLRoot_t*)(agRoot->sdkData);
  144   mpiICQueue_t *circularQ;
  145   bit8  inq;
  146   bit16 size = IOMB_SIZE64;
  147   bit32 ret = AGSA_RC_SUCCESS, retVal;
  148 
  149   smTraceFuncEnter(hpDBG_VERY_LOUD,"2D");
  150 
  151   SA_DBG4(("Entering function siFastSSPResAlloc:\n"));
  152 
  153   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  154   *pRequest = (agsaIORequestDesc_t*)saLlistIOGetHead(&saRoot->freeIORequests);
  155 
  156   /* If no LL IO request entry available */
  157   if (agNULL == *pRequest )
  158   {
  159     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  160     SA_DBG1(("siFastSSPResAlloc: No request from free list\n" ));
  161     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2D");
  162     ret = AGSA_RC_BUSY;
  163     goto ext;
  164   }
  165 
  166   /* Get IO request from free IORequests */
  167   /* Assign inbound and outbound Buffer */
  168   inq = INQ(queueNum);
  169   SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
  170 
  171   /* SSP_INI_IO_START_EXT IOMB need at least 80 bytes to support 32 CDB */
  172   if (agRequestType & AGSA_SSP_EXT_BIT)
  173   {
  174     size = IOMB_SIZE96;
  175   }
  176   /* If LL IO request entry avaliable */
  177   /* Get a free inbound queue entry */
  178   circularQ = &saRoot->inboundQueue[inq];
  179   retVal = mpiMsgFreeGet(circularQ, size, pPayload);
  180 
  181   /* if message size is too large return failure */
  182   if (AGSA_RC_SUCCESS != retVal)
  183   {
  184     if (AGSA_RC_FAILURE == retVal)
  185     {
  186       SA_DBG1(("siFastSSPResAlloc: error when get free IOMB\n"));
  187       smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2D");
  188     }
  189 
  190     /* return busy if inbound queue is full */
  191     if (AGSA_RC_BUSY == retVal)
  192     {
  193       SA_DBG3(("siFastSSPResAlloc: no more IOMB\n"));
  194       smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2D");
  195     }
  196     ret = retVal;
  197     goto ext;
  198   }
  199 
  200   /* But add it to the pending queue during FastStart */
  201   /* If free IOMB avaliable */
  202   /* Remove the request from free list */
  203   saLlistIORemove(&saRoot->freeIORequests, &(*pRequest)->linkNode);
  204 
  205   /* Add the request to the pendingIORequests list of the device */
  206   saLlistIOAdd(&pDevice->pendingIORequests, &(*pRequest)->linkNode);
  207 
  208 ext:
  209   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  210 
  211   if (AGSA_RC_SUCCESS == ret)
  212   {
  213     /* save tag and IOrequest pointer to IOMap */
  214     saRoot->IOMap[(*pRequest)->HTag].Tag = (*pRequest)->HTag;
  215     saRoot->IOMap[(*pRequest)->HTag].IORequest = (void *)*pRequest;
  216   }
  217 
  218   return ret;
  219 } /* siFastSSPResAlloc */
  220 
  221 
  222 GLOBAL bit32 saFastSSPCancel(void *ioHandle)
  223 {
  224   agsaRoot_t      *agRoot;
  225   agsaLLRoot_t    *saRoot;
  226   saFastRequest_t *fr;
  227   bit32            i;
  228   agsaIORequestDesc_t *ior;
  229 
  230   SA_ASSERT((ioHandle), "");
  231   fr = (saFastRequest_t*)ioHandle;
  232   SA_ASSERT((fr->valid), "");
  233   agRoot = (agsaRoot_t*)fr->agRoot;
  234   SA_ASSERT((agRoot), "");
  235   saRoot = (agsaLLRoot_t*)(agRoot->sdkData);
  236   SA_ASSERT((saRoot), "");
  237 
  238   smTraceFuncEnter(hpDBG_VERY_LOUD,"2E");
  239 
  240   /* rollback the previously set IBQ PI */
  241   for (i = 0; i < fr->inqMax - 1; i++)
  242     saSetIBQPI(agRoot, fr->inqList[i], fr->beforePI[fr->inqList[i]]);
  243 
  244   /* free all the previous Fast IO Requests */
  245   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  246   /* at least one entry, no need to check for NULL saLlistIOGetHead() */
  247   ior = (agsaIORequestDesc_t*)((char*)saLlistIOGetHead(&fr->requests) -
  248                               OSSA_OFFSET_OF(agsaIORequestDesc_t, fastLink));
  249   do
  250   {
  251     agsaDeviceDesc_t *pDevice;
  252     void             *tmp;
  253 
  254     pDevice = ior->pDevice;
  255     saLlistIORemove(&pDevice->pendingIORequests, &ior->linkNode);
  256     saLlistIOAdd(&saRoot->freeIORequests, &ior->linkNode);
  257 
  258     tmp = (void*)saLlistGetNext(&fr->requests, &ior->fastLink);
  259     if (!tmp)
  260     {
  261       break; /* end of list */
  262     }
  263     ior = (agsaIORequestDesc_t*)((char*)tmp -
  264                                  OSSA_OFFSET_OF(agsaIORequestDesc_t, fastLink));
  265   } while (1);
  266 
  267   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  268 
  269   /* free the IBQ PI tracking struct */
  270   siFastSSPReqFree(agRoot, fr);
  271 
  272   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2E");
  273   return AGSA_RC_SUCCESS;
  274 } /* saFastSSPCancel */
  275 
  276 GLOBAL void *saFastSSPPrepare(
  277                  void                 *ioh,
  278                  agsaFastCommand_t    *fc,
  279                  ossaSSPCompletedCB_t cb,
  280                  void                 *cbArg)
  281 {
  282   bit32            ret = AGSA_RC_SUCCESS;
  283   agsaRoot_t       *agRoot;
  284   agsaLLRoot_t     *saRoot;
  285   mpiICQueue_t     *circularQ;
  286   agsaDeviceDesc_t *pDevice;
  287   agsaSgl_t        *pSgl;
  288   bit32            Dir = 0;
  289   bit8             inq, outq;
  290   saFastRequest_t  *fr;
  291   void             *pMessage;
  292   agsaIORequestDesc_t *pRequest;
  293   bit16            opCode;
  294   bitptr           offsetTag;
  295   bitptr           offsetDeviceId;
  296   bitptr           offsetDataLen;
  297   bitptr           offsetDir;
  298 
  299   agRoot = (agsaRoot_t*)fc->agRoot;
  300   smTraceFuncEnter(hpDBG_VERY_LOUD,"2G");
  301 
  302   OSSA_INP_ENTER(agRoot);
  303 
  304   saRoot = (agsaLLRoot_t*)(agRoot->sdkData);
  305   /* sanity check */
  306   SA_ASSERT((agNULL != saRoot), "");
  307 
  308   SA_DBG4(("Entering function saFastSSPPrepare:\n"));
  309 
  310   fr = (saFastRequest_t*)ioh;
  311   if (!fr)
  312   {
  313     int i;
  314     fr = siFastSSPReqAlloc(agRoot);
  315     if (!fr)
  316     {
  317       SA_ASSERT((0), "");
  318       goto ext;
  319     }
  320 
  321     saLlistIOInitialize(&fr->requests);
  322     for (i = 0; i < AGSA_MAX_INBOUND_Q; i++)
  323       fr->beforePI[i] = (bit32)-1;
  324 
  325     fr->inqMax = 0;
  326     fr->agRoot = agRoot;
  327     ioh = fr;
  328   }
  329 
  330   /* Find the outgoing port for the device */
  331   pDevice = (agsaDeviceDesc_t*)(((agsaDevHandle_t*)fc->devHandle)->sdkData);
  332 
  333   ret = siFastSSPResAlloc(agRoot, fc->queueNum, fc->agRequestType,
  334                           pDevice, &pRequest, &pMessage);
  335   if (ret != AGSA_RC_SUCCESS)
  336   {
  337     SA_ASSERT((0), "");
  338     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2G");
  339     goto ext;
  340   }
  341 
  342   /* Assign inbound and outbound Buffer */
  343   inq = INQ(fc->queueNum);
  344   outq = OUQ(fc->queueNum);
  345   circularQ = &saRoot->inboundQueue[inq];
  346 
  347   SA_DBG3(("saFastSSPPrepare: deviceId %d\n", pDevice->DeviceMapIndex));
  348 
  349   /* set up pRequest */
  350   pRequest->valid = agTRUE;
  351   pRequest->pDevice = pDevice;
  352   pRequest->requestType = fc->agRequestType;
  353 
  354   pRequest->completionCB = cb;
  355   pRequest->pIORequestContext = (agsaIORequest_t*)cbArg;
  356 
  357   pSgl = fc->agSgl;
  358 
  359   switch (fc->agRequestType)
  360   {
  361     /* case AGSA_SSP_INIT_NONDATA: */
  362     case AGSA_SSP_INIT_READ:
  363     case AGSA_SSP_INIT_WRITE:
  364     case AGSA_SSP_INIT_READ_M:
  365     case AGSA_SSP_INIT_WRITE_M:
  366     {
  367       agsaSSPIniIOStartCmd_t *pPayload = (agsaSSPIniIOStartCmd_t *)pMessage;
  368       agsaSSPCmdInfoUnit_t   *piu;
  369 
  370       /* SSPIU less equal 28 bytes */
  371       offsetTag = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, tag);
  372       offsetDeviceId = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, deviceId);
  373       offsetDataLen = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dataLen);
  374       offsetDir = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dirMTlr);
  375 
  376       piu = &pPayload->SSPInfoUnit;
  377 
  378       si_memcpy(piu->lun, fc->lun, sizeof(piu->lun));
  379       si_memcpy(piu->cdb, fc->cdb, sizeof(piu->cdb));
  380       piu->efb_tp_taskAttribute = fc->taskAttribute;
  381       piu->additionalCdbLen = fc->additionalCdbLen;
  382 
  383       /* Mask DIR for Read/Write command */
  384       Dir = fc->agRequestType & AGSA_DIR_MASK;
  385 
  386       /* set TLR */
  387       Dir |= fc->flag & TLR_MASK;
  388       if (fc->agRequestType & AGSA_MSG)
  389       {
  390         /* set M bit */
  391         Dir |= AGSA_MSG_BIT;
  392       }
  393 
  394       /* Setup SGL */
  395       if (fc->dataLength)
  396       {
  397         SA_DBG5(("saFastSSPPrepare: agSgl %08x:%08x (%x/%x)\n",
  398                  pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved));
  399         /*
  400         pPayload->AddrLow0 = pSgl->sgLower;
  401         pPayload->AddrHi0 = pSgl->sgUpper;
  402         pPayload->Len0 = pSgl->len;
  403         pPayload->E0 = pSgl->extReserved;
  404         */
  405         si_memcpy(&pPayload->AddrLow0, pSgl, sizeof(*pSgl));
  406       }
  407       else
  408       {
  409         /* no data transfer */
  410         si_memset(&pPayload->AddrLow0, 0, sizeof(*pSgl));
  411       }
  412 
  413       opCode = OPC_INB_SSPINIIOSTART;
  414       break;
  415     }
  416 
  417     case AGSA_SSP_INIT_READ_EXT:
  418     case AGSA_SSP_INIT_WRITE_EXT:
  419     case AGSA_SSP_INIT_READ_EXT_M:
  420     case AGSA_SSP_INIT_WRITE_EXT_M:
  421     {
  422       agsaSSPIniExtIOStartCmd_t *pPayload =
  423                                     (agsaSSPIniExtIOStartCmd_t *)pMessage;
  424       agsaSSPCmdInfoUnitExt_t   *piu;
  425       bit32 sspiul;
  426 
  427       /* CDB > 16 bytes */
  428       offsetTag = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, tag);
  429       offsetDeviceId = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, deviceId);
  430       offsetDataLen = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, dataLen);
  431       offsetDir = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, SSPIuLendirMTlr);
  432 
  433       /* dword (bit7-bit2) ==> bytes (bit7-bit0) */
  434       /* setup standard CDB bytes + additional CDB bytes in length field */
  435       sspiul = sizeof(agsaSSPCmdInfoUnit_t) + (fc->additionalCdbLen & 0xFC);
  436 
  437       Dir = sspiul << 16;
  438       piu = (agsaSSPCmdInfoUnitExt_t*)pPayload->SSPIu;
  439 
  440       si_memcpy(piu->lun, fc->lun, sizeof(piu->lun));
  441       si_memcpy(piu->cdb, fc->cdb, MIN(sizeof(piu->cdb),
  442                                        16 + fc->additionalCdbLen));
  443       piu->efb_tp_taskAttribute = fc->taskAttribute;
  444       piu->additionalCdbLen = fc->additionalCdbLen;
  445 
  446       /* Mask DIR for Read/Write command */
  447       Dir |= fc->agRequestType & AGSA_DIR_MASK;
  448 
  449       /* set TLR */
  450       Dir |= fc->flag & TLR_MASK;
  451       if (fc->agRequestType & AGSA_MSG)
  452       {
  453         /* set M bit */
  454         Dir |= AGSA_MSG_BIT;
  455       }
  456 
  457       /* Setup SGL */
  458       if (fc->dataLength)
  459       {
  460         SA_DBG5(("saSuperSSPSend: Ext mode, agSgl %08x:%08x (%x/%x)\n",
  461           pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved));
  462 
  463         si_memcpy((&(pPayload->SSPIu[0]) + sspiul), pSgl, sizeof(*pSgl));
  464       }
  465       else //?
  466       {
  467         /* no data transfer */
  468         //pPayload->dataLen = 0;
  469         si_memset((&(pPayload->SSPIu[0]) + sspiul), 0, sizeof(*pSgl));
  470       }
  471       SA_ASSERT((smIS_SPC(agRoot)), "smIS_SPC");
  472       opCode = OPC_INB_SSPINIEXTIOSTART;
  473       break;
  474     }
  475 
  476     default:
  477     {
  478       SA_DBG1(("saSuperSSPSend: Unsupported Request IOMB\n"));
  479       ret = AGSA_RC_FAILURE;
  480       SA_ASSERT((0), "");
  481       smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2G");
  482       goto ext;
  483     }
  484   }
  485 
  486   OSSA_WRITE_LE_32(agRoot, pMessage, offsetTag, pRequest->HTag);
  487   OSSA_WRITE_LE_32(agRoot, pMessage, offsetDeviceId, pDevice->DeviceMapIndex);
  488   OSSA_WRITE_LE_32(agRoot, pMessage, offsetDataLen, fc->dataLength);
  489   OSSA_WRITE_LE_32(agRoot, pMessage, offsetDir, Dir);
  490 
  491   if (fr->beforePI[inq] == -1)
  492   {
  493     /* save the new IBQ' PI */
  494     fr->beforePI[inq] = saGetIBQPI(agRoot, inq);
  495     fr->inqList[fr->inqMax++] = inq;
  496   }
  497 
  498   /* post the IOMB to SPC */
  499   ret = mpiMsgPrepare(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA,
  500                       opCode, outq, 0);
  501   if (AGSA_RC_SUCCESS != ret)
  502   {
  503     SA_ASSERT((0), "");
  504     ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  505     /* Remove the request from pendingIORequests list */
  506     saLlistIORemove(&pDevice->pendingIORequests, &pRequest->linkNode);
  507 
  508     /* Add the request to the free list of the device */
  509     saLlistIOAdd(&saRoot->freeIORequests, &pRequest->linkNode);
  510     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  511 
  512     SA_DBG1(("saFastSSPPrepare: error when post SSP IOMB\n"));
  513     smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2G");
  514     goto ext;
  515   }
  516 
  517   /* Add the request to the pendingFastIORequests list of the device */
  518   saLlistIOAdd(&fr->requests, &pRequest->fastLink);
  519   smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "2G");
  520 
  521 ext:
  522   if (fr && ret != AGSA_RC_SUCCESS)
  523   {
  524     saFastSSPCancel(fr);
  525     ioh = 0;
  526   }
  527   OSSA_INP_LEAVE(agRoot);
  528   return ioh;
  529 } /* saFastSSPPrepare */
  530 
  531 GLOBAL bit32 saFastSSPSend(void *ioHandle)
  532 {
  533   bit8            inq;
  534   agsaRoot_t      *agRoot;
  535   agsaLLRoot_t    *saRoot;
  536   saFastRequest_t *fr;
  537   bit32           i;
  538 
  539   SA_ASSERT((ioHandle), "");
  540   fr = (saFastRequest_t*)ioHandle;
  541   agRoot = (agsaRoot_t*)fr->agRoot;
  542   SA_ASSERT((agRoot), "");
  543   saRoot = (agsaLLRoot_t*)agRoot->sdkData;
  544   SA_ASSERT((saRoot), "");
  545 
  546   SA_DBG4(("Entering function saFastSSPSend:\n"));
  547 
  548   for (i = 0; i < fr->inqMax; i++)
  549   {
  550     inq = INQ(fr->inqList[i]);
  551     /* FW interrupt */
  552     mpiIBQMsgSend(&saRoot->inboundQueue[inq]);
  553   }
  554   /* IORequests are freed in siIODone() */
  555 
  556   siFastSSPReqFree(agRoot, fr);
  557   return AGSA_RC_SUCCESS;
  558 } /* saFastSSPSend */
  559 #endif
  560 
  561 /******************************************************************************/
  562 /*! \brief Start SSP request
  563  *
  564  *  Start SSP request
  565  *
  566  *  \param agRoot handles for this instance of SAS/SATA LLL
  567  *  \param queueNum
  568  *  \param agIORequest
  569  *  \param agDevHandle
  570  *  \param agRequestType
  571  *  \param agRequestBody
  572  *  \param agTMRequest valid for task management
  573  *  \param agCB
  574  *
  575  *  \return If request is started successfully
  576  *          - \e AGSA_RC_SUCCESS request is started successfully
  577  *          - \e AGSA_RC_BUSY request is not started successfully
  578  */
  579 /******************************************************************************/
  580 GLOBAL bit32 saSSPStart(
  581   agsaRoot_t            *agRoot,
  582   agsaIORequest_t       *agIORequest,
  583   bit32                 queueNum,
  584   agsaDevHandle_t       *agDevHandle,
  585   bit32                 agRequestType,
  586   agsaSASRequestBody_t  *agRequestBody,
  587   agsaIORequest_t       *agTMRequest,
  588   ossaSSPCompletedCB_t  agCB)
  589 {
  590   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
  591 #ifdef LOOPBACK_MPI
  592   mpiOCQueue_t        *circularOQ = agNULL;
  593 #endif
  594   mpiICQueue_t        *circularQ  = agNULL;
  595   agsaDeviceDesc_t    *pDevice    = agNULL;
  596   agsaPort_t          *pPort      = agNULL;
  597   agsaIORequestDesc_t *pRequest   = agNULL;
  598   agsaSgl_t           *pSgl       = agNULL;
  599   void                *pMessage   = agNULL;
  600   bit32               ret = AGSA_RC_SUCCESS, retVal = 0;
  601   bit32               DirDW4 = 0;    /* no data and no AutoGR */
  602   bit32               encryptFlags = 0;
  603   bit16               size = 0;
  604   bit16               opCode = 0;
  605   bit8                inq = 0, outq = 0;
  606 
  607 
  608   OSSA_INP_ENTER(agRoot);
  609   smTraceFuncEnter(hpDBG_VERY_LOUD,"Sa");
  610 
  611   /* sanity check */
  612   SA_ASSERT((agNULL != agRoot), "");
  613   SA_ASSERT((agNULL != agIORequest), "");
  614   SA_ASSERT((agNULL != agDevHandle), "");
  615   SA_ASSERT((agNULL != agRequestBody), "");
  616 
  617   DBG_DUMP_SSPSTART_CMDIU(agDevHandle,agRequestType,agRequestBody);
  618 
  619   /* Find the outgoing port for the device */
  620   pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
  621 
  622   if(pDevice == agNULL )
  623   {
  624     SA_ASSERT((pDevice), "pDevice");
  625     ret = AGSA_RC_FAILURE;
  626     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "Sa");
  627     goto ext;
  628   }
  629 
  630   pPort = pDevice->pPort;
  631   /* Assign inbound and outbound Buffer */
  632   inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
  633   outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
  634   SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
  635 
  636   SA_DBG3(("saSSPStart: inq %d outq %d deviceId 0x%x\n", inq,outq,pDevice->DeviceMapIndex));
  637 
  638   /* Get request from free IORequests */
  639   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  640   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
  641 
  642   /* If no LL IO request entry available */
  643   if ( agNULL == pRequest )
  644   {
  645     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  646     SA_DBG1(("saSSPStart, No request from free list\n" ));
  647     smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "Sa");
  648     ret = AGSA_RC_BUSY;
  649     goto ext;
  650   }
  651   /* If LL IO request entry avaliable */
  652   else
  653   {
  654     /* Remove the request from free list */
  655     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
  656     /* Add the request to the pendingIORequests list of the device */
  657     saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode));
  658 
  659     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  660 
  661     SA_ASSERT((!pRequest->valid), "The pRequest is in use");
  662 
  663     SA_DBG3(("saSSPStart, request %p\n", pRequest ));
  664 
  665     /* Decode the flag settings in the standard I/O requests to  decide what size we need. */
  666     /* All other requests will be fine with only 64 byte messages. */
  667     switch ( agRequestType )
  668     {
  669     case AGSA_SSP_INIT_READ:
  670     case AGSA_SSP_INIT_WRITE:
  671     case AGSA_SSP_INIT_NONDATA:
  672     case AGSA_SSP_INIT_READ_M:
  673     case AGSA_SSP_INIT_WRITE_M:
  674         {
  675             agsaSSPInitiatorRequest_t *pIRequest = &(agRequestBody->sspInitiatorReq);
  676 
  677             if ((pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION)   ||
  678 #ifdef SAFLAG_USE_DIF_ENC_IOMB
  679                (pIRequest->flag & AGSA_SAS_USE_DIF_ENC_OPSTART)  ||
  680 #endif /* SAFLAG_USE_DIF_ENC_IOMB */
  681                 (pIRequest->flag & AGSA_SAS_ENABLE_DIF) )
  682             {
  683                 opCode = OPC_INB_SSP_DIF_ENC_OPSTART;
  684                 size = IOMB_SIZE128;
  685             }
  686             else
  687             {
  688                 opCode = OPC_INB_SSPINIIOSTART;
  689                 size = IOMB_SIZE64;
  690             }
  691             break;
  692         }
  693     case AGSA_SSP_INIT_READ_EXT:
  694     case AGSA_SSP_INIT_WRITE_EXT:
  695     case AGSA_SSP_INIT_READ_EXT_M:
  696     case AGSA_SSP_INIT_WRITE_EXT_M:
  697         {
  698           agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt);
  699 
  700           if ((pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION)   ||
  701               (pIRequest->flag & AGSA_SAS_ENABLE_DIF)          ||
  702 #ifdef SAFLAG_USE_DIF_ENC_IOMB
  703               (pIRequest->flag & AGSA_SAS_USE_DIF_ENC_OPSTART) ||
  704 #endif /* SAFLAG_USE_DIF_ENC_IOMB */
  705               (pIRequest->flag & AGSA_SAS_ENABLE_SKIP_MASK))
  706           {
  707               opCode = OPC_INB_SSP_DIF_ENC_OPSTART;
  708               size = IOMB_SIZE128;
  709           }
  710           else
  711           {
  712               SA_ASSERT((smIS_SPC(agRoot)), "smIS_SPC");
  713               opCode = OPC_INB_SSPINIEXTIOSTART;
  714               size = IOMB_SIZE96;
  715           }
  716           break;
  717       }
  718       case  AGSA_SSP_INIT_READ_INDIRECT:
  719       case  AGSA_SSP_INIT_WRITE_INDIRECT:
  720       case  AGSA_SSP_INIT_READ_INDIRECT_M:
  721       case  AGSA_SSP_INIT_WRITE_INDIRECT_M:
  722           {
  723             SA_DBG3(("saSSPStart: agRequestType  0x%X INDIRECT\n", agRequestType));
  724             opCode = OPC_INB_SSP_DIF_ENC_OPSTART;
  725             size = IOMB_SIZE128;
  726             break;
  727           }
  728       case (AGSA_SSP_REQTYPE | AGSA_SSP_TASK_MGNT):
  729       case AGSA_SSP_TASK_MGNT_REQ_M:
  730       case AGSA_SSP_TGT_READ_DATA:
  731       case AGSA_SSP_TGT_READ_GOOD_RESP:
  732       case AGSA_SSP_TGT_WRITE_DATA:
  733       case AGSA_SSP_TGT_WRITE_GOOD_RESP:
  734       case AGSA_SSP_TGT_CMD_OR_TASK_RSP:
  735 
  736         SA_DBG3(("saSSPStart: agRequestType  0x%X (was default)\n", agRequestType));
  737         opCode = OPC_INB_SSPINIIOSTART;
  738         size = IOMB_SIZE64;
  739          break;
  740     default:
  741         SA_DBG1(("saSSPStart: agRequestType UNKNOWN 0x%X\n", agRequestType));
  742         /* OpCode is not used in this case, but Linux complains if it is not initialized. */
  743         opCode = OPC_INB_SSPINIIOSTART;
  744         size = IOMB_SIZE64;
  745         break;
  746     }
  747 
  748     /* If free IOMB avaliable,  set up pRequest*/
  749     pRequest->valid = agTRUE;
  750     pRequest->pIORequestContext = agIORequest;
  751     pRequest->pDevice = pDevice;
  752     pRequest->requestType = agRequestType;
  753     pRequest->pPort = pPort;
  754     pRequest->startTick = saRoot->timeTick;
  755     pRequest->completionCB = agCB;
  756 
  757     /* Set request to the sdkData of agIORequest */
  758     agIORequest->sdkData = pRequest;
  759 
  760     /* save tag and IOrequest pointer to IOMap */
  761     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
  762     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
  763 
  764 #ifdef SA_LL_IBQ_PROTECT
  765     ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
  766 #endif /* SA_LL_IBQ_PROTECT */
  767 
  768     /* Get a free inbound queue entry */
  769 #ifdef LOOPBACK_MPI
  770     if (loopback)
  771     {
  772       SA_DBG2(("saSSPStart: did %d ioq %d / %d tag %d\n", pDevice->DeviceMapIndex, inq, outq, pRequest->HTag));
  773       circularOQ = &saRoot->outboundQueue[outq];
  774       retVal = mpiMsgFreeGetOQ(circularOQ, size, &pMessage);
  775     }
  776     else
  777 #endif /* LOOPBACK_MPI */
  778     {
  779       circularQ = &saRoot->inboundQueue[inq];
  780       retVal = mpiMsgFreeGet(circularQ, size, &pMessage);
  781     }
  782 
  783     /* if message size is too large return failure */
  784     if (AGSA_RC_FAILURE == retVal)
  785     {
  786 #ifdef SA_LL_IBQ_PROTECT
  787       ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
  788 #endif /* SA_LL_IBQ_PROTECT */
  789       /* if not sending return to free list rare */
  790       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  791       saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
  792       pRequest->valid = agFALSE;
  793       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
  794       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  795 
  796       SA_DBG1(("saSSPStart, error when get free IOMB\n"));
  797       smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "Sa");
  798       ret = AGSA_RC_FAILURE;
  799       goto ext;
  800     }
  801 
  802     /* return busy if inbound queue is full */
  803     if (AGSA_RC_BUSY == retVal)
  804     {
  805 #ifdef SA_LL_IBQ_PROTECT
  806       ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
  807 #endif /* SA_LL_IBQ_PROTECT */
  808       /* if not sending return to free list rare */
  809       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  810       saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
  811       pRequest->valid = agFALSE;
  812       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
  813       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
  814 
  815       SA_DBG1(("saSSPStart, no more IOMB\n"));
  816       smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "Sa");
  817       ret = AGSA_RC_BUSY;
  818       goto ext;
  819     }
  820     SA_DBG3(("saSSPStart:agRequestType %X\n" ,agRequestType));
  821 
  822     switch ( agRequestType )
  823     {
  824       case AGSA_SSP_INIT_READ:
  825       case AGSA_SSP_INIT_WRITE:
  826       case AGSA_SSP_INIT_NONDATA:
  827       case AGSA_SSP_INIT_READ_EXT:
  828       case AGSA_SSP_INIT_WRITE_EXT:
  829       case AGSA_SSP_INIT_READ_M:
  830       case AGSA_SSP_INIT_WRITE_M:
  831       case AGSA_SSP_INIT_READ_EXT_M:
  832       case AGSA_SSP_INIT_WRITE_EXT_M:
  833       case AGSA_SSP_INIT_READ_INDIRECT:
  834       case AGSA_SSP_INIT_WRITE_INDIRECT:
  835       case AGSA_SSP_INIT_READ_INDIRECT_M:
  836       case AGSA_SSP_INIT_WRITE_INDIRECT_M:
  837       {
  838         if (!(agRequestType & AGSA_SSP_EXT_BIT))
  839         {
  840           agsaSSPInitiatorRequest_t     *pIRequest = &(agRequestBody->sspInitiatorReq);
  841           agsaSSPIniIOStartCmd_t        *pPayload = (agsaSSPIniIOStartCmd_t *)pMessage;
  842           agsaSSPIniEncryptIOStartCmd_t *pEncryptPayload = (agsaSSPIniEncryptIOStartCmd_t *)pMessage;
  843 
  844           /* Most fields for the SAS IOMB have the same offset regardless of the actual IOMB used. */
  845           /* Be careful with the scatter/gather lists, encryption and DIF options. */
  846 
  847 /*          if( pIRequest->sspCmdIU.cdb[ 0] ==  0x28 || pIRequest->sspCmdIU.cdb[0]== 0x2A)
  848           {
  849             pRequest->requestBlock = ((pIRequest->sspCmdIU.cdb[2] << 24 ) | 
  850                             (pIRequest->sspCmdIU.cdb[3] << 16 ) | 
  851                             (pIRequest->sspCmdIU.cdb[4] <<  8 ) |  
  852                             (pIRequest->sspCmdIU.cdb[5] ) );
  853           }
  854 */
  855 #ifdef LOOPBACK_MPI
  856           if (loopback)
  857           {
  858           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, tag), pRequest->HTag);
  859           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, status), OSSA_IO_SUCCESS);
  860           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, param), 0);
  861           //OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, SSPTag), 0);
  862           }
  863           else
  864 #endif /* LOOPBACK_MPI */
  865           {
  866             /* SSPIU less equal 28 bytes */
  867             /* Configure DWORD 1 */
  868             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, tag), pRequest->HTag);
  869             /* Configure DWORD 2 */
  870             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, deviceId), pDevice->DeviceMapIndex);
  871             /* Configure DWORD 3 */
  872             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dataLen), pIRequest->dataLength);
  873           }
  874 
  875 #ifdef SA_TESTBASE_EXTRA
  876           /* TestBase - Set the host BST entry  */
  877           DirDW4 |= ((UINT32)pIRequest->bstIndex) << 16;
  878 #endif /*  SA_TESTBASE_EXTRA */
  879 
  880           if (!(agRequestType & AGSA_SSP_INDIRECT_BIT))
  881           {
  882             /* Configure DWORD 5-12  */
  883             si_memcpy(&pPayload->SSPInfoUnit, &pIRequest->sspCmdIU, sizeof(pPayload->SSPInfoUnit));
  884             pPayload->dirMTlr     = 0;
  885             /* Mask DIR for Read/Write command */
  886             /* Configure DWORD 4 bit 8-9 */
  887             DirDW4 |= agRequestType & AGSA_DIR_MASK;
  888           }
  889           else /* AGSA_SSP_INDIRECT_BIT was set */
  890           {
  891 
  892             agsaSSPInitiatorRequestIndirect_t *pIndRequest = &(agRequestBody->sspInitiatorReqIndirect);
  893 
  894             /* Configure DWORD 5 */
  895             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_0_3_indcdbalL ),pIndRequest->sspInitiatorReqAddrLower32);
  896             /* Configure DWORD 6 */
  897             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_4_7_indcdbalH ),pIndRequest->sspInitiatorReqAddrUpper32 );
  898             /* Configure DWORD 7 */
  899             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_8_11 ), 0);
  900             /* Configure DWORD 8 */
  901             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_12_15 ), 0);
  902             /* Configure DWORD 9 */
  903             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_16_19 ), 0);
  904             /* Configure DWORD 10 */
  905             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_19_23), 0);
  906             /* Configure DWORD 11 */
  907             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_24_27 ), 0);
  908             /* Mask DIR for Read/Write command */
  909             /* Configure DWORD 4 bit 8-9 */
  910             DirDW4 |= agRequestType & AGSA_DIR_MASK;
  911             /* Configure DWORD 4 bit 24-31 */
  912             DirDW4 |= ((pIndRequest->sspInitiatorReqLen >> 2) & 0xFF) << SHIFT24;
  913             /* Configure DWORD 4 bit 4 */
  914             DirDW4 |= 1 << SHIFT3;
  915           }
  916 
  917           /* set TLR */
  918           DirDW4 |= pIRequest->flag & TLR_MASK;
  919           if (agRequestType & AGSA_MSG)
  920           {
  921             /* set M bit */
  922             DirDW4 |= AGSA_MSG_BIT;
  923           }
  924 
  925           /* check for skipmask operation */
  926           if (pIRequest->flag & AGSA_SAS_ENABLE_SKIP_MASK)
  927           {
  928             DirDW4 |= AGSA_SKIP_MASK_BIT;
  929             /* agsaSSPInitiatorRequestIndirect_t skip mask in flag is offset 5  */
  930             DirDW4 |= (pIRequest->flag & AGSA_SAS_SKIP_MASK_OFFSET) << SHIFT8;
  931           }
  932 
  933 
  934          /* Configure DWORDS 12-14 */
  935          if( pIRequest->encrypt.enableEncryptionPerLA && pIRequest->dif.enableDIFPerLA)
  936          {
  937             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 12 */
  938                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ),
  939                              pIRequest->encrypt.EncryptionPerLAAddrLo );
  940             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 13 */
  941                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ),
  942                              pIRequest->dif.DIFPerLAAddrLo );
  943 
  944             SA_ASSERT(pIRequest->encrypt.EncryptionPerLAAddrHi == pIRequest->dif.DIFPerLAAddrHi, "EPL DPL hi region must be equal");
  945 
  946             if( pIRequest->encrypt.EncryptionPerLAAddrHi != pIRequest->dif.DIFPerLAAddrHi )
  947             {
  948 
  949               SA_DBG1(("saSSPStart: EPL DPL hi region must be equal AGSA_RC_FAILURE\n" ));
  950               smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "Sa");
  951               ret = AGSA_RC_FAILURE;
  952               goto ext;
  953             }
  954 
  955             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 14 */
  956                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ),
  957                              pIRequest->encrypt.EncryptionPerLAAddrHi );
  958           }
  959           else if( pIRequest->encrypt.enableEncryptionPerLA)
  960           {
  961             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 12 */
  962                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ),
  963                              pIRequest->encrypt.EncryptionPerLAAddrLo );
  964             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 13 */
  965                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ),
  966                              0);
  967             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 14 */
  968                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ),
  969                              pIRequest->encrypt.EncryptionPerLAAddrHi );
  970           }
  971           else if (pIRequest->dif.enableDIFPerLA) /* configure DIF */
  972           {
  973             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 12 */
  974                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ),
  975                              0);
  976             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 13 */
  977                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ),
  978                              pIRequest->dif.DIFPerLAAddrLo );
  979             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 14 */
  980                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ),
  981                              pIRequest->dif.DIFPerLAAddrHi);
  982           }
  983           else /* Not EPL or DPL  */
  984           {
  985             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 12 */
  986                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ),
  987                              0);
  988             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 13 */
  989                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ),
  990                              0);
  991             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 14 */
  992                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ),
  993                              0);
  994           }
  995 
  996           if (pIRequest->flag & AGSA_SAS_ENABLE_DIF)
  997           {
  998             bit32 UDTR1_UDTR0_UDT1_UDT0  =  0;
  999             bit32 UDT5_UDT4_UDT3_UDT2     = 0;
 1000             bit32 UDTR5_UDTR4_UDTR3_UDTR2 = 0;
 1001 
 1002             SA_DBG3(("saSSPStart,DIF enableRefBlockCount ref %d enableRefBlockCount  %d enableCrc  %d enableCrcInversion %d\n",
 1003                 pIRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0,
 1004                 pIRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0,
 1005                 pIRequest->dif.flags & DIF_FLAG_BITS_CRC_VER           ? 1 : 0,
 1006                 pIRequest->dif.flags & DIF_FLAG_BITS_CRC_INV           ? 1 : 0  ));
 1007 
 1008             SA_DBG3(("saSSPStart,DIF initialIOSeed %X lbSize %X difAction %X\n",
 1009                 pIRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? 1 : 0,
 1010                 (pIRequest->dif.flags & DIF_FLAG_BITS_BLOCKSIZE_MASK) >> DIF_FLAG_BITS_BLOCKSIZE_SHIFT,
 1011                 pIRequest->dif.flags & DIF_FLAG_BITS_ACTION  ));
 1012 
 1013             SA_DBG3(("saSSPStart,DIF udtArray %2X %2X %2X %2X %2X %2X\n",
 1014                 pIRequest->dif.udtArray[0],
 1015                 pIRequest->dif.udtArray[1],
 1016                 pIRequest->dif.udtArray[2],
 1017                 pIRequest->dif.udtArray[3],
 1018                 pIRequest->dif.udtArray[4],
 1019                 pIRequest->dif.udtArray[5]));
 1020 
 1021             SA_DBG3(("saSSPStart,DIF udrtArray %2X %2X %2X %2X %2X %2X\n",
 1022                 pIRequest->dif.udrtArray[0],
 1023                 pIRequest->dif.udrtArray[1],
 1024                 pIRequest->dif.udrtArray[2],
 1025                 pIRequest->dif.udrtArray[3],
 1026                 pIRequest->dif.udrtArray[4],
 1027                 pIRequest->dif.udrtArray[5]));
 1028 
 1029             SA_DBG3(("saSSPStart,DIF tagUpdateMask %X tagVerifyMask %X DIFPerLAAddrLo %X DIFPerLAAddrHi %X\n",
 1030                 (pIRequest->dif.flags & DIF_FLAG_BITS_UDTVMASK) >> DIF_FLAG_BITS_UDTV_SHIFT,
 1031                 (pIRequest->dif.flags & DIF_FLAG_BITS_UDTUPMASK) >> DIF_FLAG_BITS_UDTUPSHIFT,
 1032                 pIRequest->dif.DIFPerLAAddrLo,
 1033                 pIRequest->dif.DIFPerLAAddrHi));
 1034 
 1035             DirDW4 |= AGSA_DIF_BIT;
 1036 
 1037             /* DWORD 15 */
 1038             SA_DBG3(("saSSPStart, DW 15 DIF_flags 0x%08X\n", pIRequest->dif.flags ));
 1039 
 1040             OSSA_WRITE_LE_32(agRoot, pPayload,
 1041                                OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_flags),
 1042                                pIRequest->dif.flags);
 1043 
 1044             /* Populate the UDT and UDTR bytes as necessary. */
 1045             if ((pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) != AGSA_DIF_INSERT)
 1046             {
 1047                 UDTR1_UDTR0_UDT1_UDT0 = (pIRequest->dif.udtArray[1] << SHIFT8 |
 1048                                          pIRequest->dif.udtArray[0]);
 1049                 UDT5_UDT4_UDT3_UDT2   = (pIRequest->dif.udtArray[5] << SHIFT24 |
 1050                                          pIRequest->dif.udtArray[4] << SHIFT16 |
 1051                                          pIRequest->dif.udtArray[3] << SHIFT8  |
 1052                                          pIRequest->dif.udtArray[2]);
 1053             }
 1054 
 1055             if ((pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_INSERT ||
 1056                 (pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_VERIFY_REPLACE ||
 1057                 (pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_REPLACE_UDT_REPLACE_CRC)
 1058             {
 1059                 UDTR1_UDTR0_UDT1_UDT0 |= (pIRequest->dif.udrtArray[1] << SHIFT24 |
 1060                                           pIRequest->dif.udrtArray[0] << SHIFT16 );
 1061                 UDTR5_UDTR4_UDTR3_UDTR2 = (pIRequest->dif.udrtArray[5] << SHIFT24 |
 1062                                            pIRequest->dif.udrtArray[4] << SHIFT16 |
 1063                                            pIRequest->dif.udrtArray[3] << SHIFT8  |
 1064                                            pIRequest->dif.udrtArray[2]);
 1065             }
 1066 
 1067             /* DWORD 16 is UDT3, UDT2, UDT1 and UDT0 */
 1068             OSSA_WRITE_LE_32(agRoot, pPayload,
 1069                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, udt),
 1070                              UDTR1_UDTR0_UDT1_UDT0);
 1071 
 1072             /* DWORD 17 is UDT5, UDT4, UDT3 and UDT2 */
 1073             OSSA_WRITE_LE_32(agRoot, pPayload,
 1074                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, udtReplacementLo),
 1075                              UDT5_UDT4_UDT3_UDT2);
 1076 
 1077             /* DWORD 18 is UDTR5, UDTR4, UDTR3 and UDTR2 */
 1078             OSSA_WRITE_LE_32(agRoot, pPayload,
 1079                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, udtReplacementHi),
 1080                              UDTR5_UDTR4_UDTR3_UDTR2);
 1081 
 1082             /* DWORD 19 */
 1083             /* Get IOS IOSeed enable bit */
 1084             if( pIRequest->dif.enableDIFPerLA ||
 1085                (pIRequest->dif.flags & DIF_FLAG_BITS_CUST_APP_TAG) )
 1086             {
 1087                 OSSA_WRITE_LE_32(agRoot, pPayload,
 1088                                  OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_seed),
 1089                                 ((pIRequest->dif.DIFPerLARegion0SecCount << SHIFT16) |
 1090                                  (pIRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? pIRequest->dif.initialIOSeed : 0 )));
 1091             }
 1092             else
 1093             {
 1094               if (pIRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED)
 1095               {
 1096                 OSSA_WRITE_LE_32(agRoot, pPayload,
 1097                                  OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_seed),
 1098                                  pIRequest->dif.initialIOSeed );
 1099               }
 1100               else
 1101               {
 1102                 OSSA_WRITE_LE_32(agRoot, pPayload,
 1103                                  OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_seed),  0 );
 1104               }
 1105             }
 1106           }
 1107 
 1108           /* configure encryption */
 1109           if (pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION)
 1110           {
 1111 
 1112             SA_DBG3(("saSSPStart,ENC dekTable 0x%08X dekIndex 0x%08X\n",
 1113                 pIRequest->encrypt.dekInfo.dekTable,
 1114                 pIRequest->encrypt.dekInfo.dekIndex));
 1115 
 1116             SA_DBG3(("saSSPStart,ENC kekIndex 0x%08X sectorSizeIndex 0x%08X cipherMode 0x%08X\n",
 1117                 pIRequest->encrypt.kekIndex,
 1118                 pIRequest->encrypt.sectorSizeIndex,
 1119                 pIRequest->encrypt.cipherMode));
 1120 
 1121             SA_DBG3(("saSSPStart,ENC keyTag_W0 0x%08X keyTag_W1 0x%08X\n",
 1122                 pIRequest->encrypt.keyTag_W0,
 1123                 pIRequest->encrypt.keyTag_W1));
 1124             SA_DBG3(("saSSPStart,ENC tweakVal_W0 0x%08X tweakVal_W1 0x%08X\n",
 1125                 pIRequest->encrypt.tweakVal_W0,
 1126                 pIRequest->encrypt.tweakVal_W1));
 1127             SA_DBG3(("saSSPStart,ENC tweakVal_W2 0x%08X tweakVal_W3 0x%08X\n",
 1128                 pIRequest->encrypt.tweakVal_W2,
 1129                 pIRequest->encrypt.tweakVal_W3));
 1130 
 1131               DirDW4 |= AGSA_ENCRYPT_BIT;
 1132 
 1133               encryptFlags = 0;
 1134 
 1135               if (pIRequest->encrypt.keyTagCheck == agTRUE)
 1136               {
 1137                  encryptFlags |= AGSA_ENCRYPT_KEY_TAG_BIT;
 1138               }
 1139 
 1140               if( pIRequest->encrypt.cipherMode == agsaEncryptCipherModeXTS )
 1141               {
 1142                 encryptFlags |= AGSA_ENCRYPT_XTS_Mode << SHIFT4;
 1143               }
 1144 
 1145               encryptFlags |= pIRequest->encrypt.dekInfo.dekTable << SHIFT2;
 1146 
 1147               /* Always use encryption for DIF fields, skip SKPD */
 1148 
 1149               encryptFlags |= (pIRequest->encrypt.dekInfo.dekIndex & 0xFFFFFF) << SHIFT8;
 1150               /* Configure DWORD 20 */
 1151               OSSA_WRITE_LE_32(agRoot, pPayload,
 1152                                OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, encryptFlagsLo),
 1153                                encryptFlags);
 1154 
 1155               encryptFlags = pIRequest->encrypt.sectorSizeIndex;
 1156 
 1157               encryptFlags |= (pIRequest->encrypt.kekIndex) << SHIFT5;
 1158 
 1159               encryptFlags |= (pIRequest->encrypt.EncryptionPerLRegion0SecCount) << SHIFT16;
 1160               /* Configure DWORD 21 */
 1161               OSSA_WRITE_LE_32(agRoot, pPayload,
 1162                                OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, encryptFlagsHi),
 1163                                encryptFlags);
 1164 
 1165               /* Configure DWORD 22 */
 1166               OSSA_WRITE_LE_32(agRoot, pPayload,
 1167                                OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, keyTag_W0),
 1168                                pIRequest->encrypt.keyTag_W0);
 1169               /* Configure DWORD 23 */
 1170               OSSA_WRITE_LE_32(agRoot, pPayload,
 1171                                OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, keyTag_W1),
 1172                                pIRequest->encrypt.keyTag_W1);
 1173 
 1174               /* Configure DWORD 24 */
 1175               OSSA_WRITE_LE_32(agRoot, pPayload,
 1176                                OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W0),
 1177                                pIRequest->encrypt.tweakVal_W0);
 1178               /* Configure DWORD 25 */
 1179               OSSA_WRITE_LE_32(agRoot, pPayload,
 1180                                OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W1),
 1181                                pIRequest->encrypt.tweakVal_W1);
 1182               /* Configure DWORD 26 */
 1183               OSSA_WRITE_LE_32(agRoot, pPayload,
 1184                                OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W2),
 1185                                pIRequest->encrypt.tweakVal_W2);
 1186               /* Configure DWORD 27 */
 1187               OSSA_WRITE_LE_32(agRoot, pPayload,
 1188                                OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W3),
 1189                                pIRequest->encrypt.tweakVal_W3);
 1190           }
 1191 
 1192           /* Setup SGL */
 1193           if (pIRequest->dataLength)
 1194           {
 1195             pSgl = &(pIRequest->agSgl);
 1196 
 1197             SA_DBG3(("saSSPStart:opCode %X agSgl %08x:%08x (%x/%x)\n",opCode,
 1198                 pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved));
 1199 
 1200             /* Get DIF PER LA flag */
 1201             DirDW4 |= (pIRequest->dif.enableDIFPerLA ? (1 << SHIFT7) : 0);
 1202             DirDW4 |= (pIRequest->encrypt.enableEncryptionPerLA ? ( 1 << SHIFT12 ) : 0);
 1203             /* Configure DWORD 4 */
 1204             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dirMTlr), DirDW4);
 1205 
 1206             if (opCode == OPC_INB_SSP_DIF_ENC_OPSTART)
 1207             {
 1208               /* Configure DWORD 28 */
 1209               pEncryptPayload->AddrLow0 = pSgl->sgLower;
 1210               /* Configure DWORD 29 */
 1211               pEncryptPayload->AddrHi0 = pSgl->sgUpper;
 1212               /* Configure DWORD 30 */
 1213               pEncryptPayload->Len0 = pSgl->len;
 1214               /* Configure DWORD 31 */
 1215               pEncryptPayload->E0 = pSgl->extReserved;
 1216             }
 1217             else
 1218             {
 1219               pPayload->AddrLow0 = pSgl->sgLower;
 1220               pPayload->AddrHi0 = pSgl->sgUpper;
 1221               pPayload->Len0 = pSgl->len;
 1222               pPayload->E0 = pSgl->extReserved;
 1223             }
 1224           }
 1225           else
 1226           {
 1227             /* no data transfer */
 1228             /* Configure DWORD 4 */
 1229             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dirMTlr), DirDW4);
 1230 
 1231             if (opCode == OPC_INB_SSP_DIF_ENC_OPSTART)
 1232             {
 1233                   pEncryptPayload = (agsaSSPIniEncryptIOStartCmd_t *) pPayload;
 1234 
 1235                   pEncryptPayload->AddrLow0 = 0;
 1236                   pEncryptPayload->AddrHi0 = 0;
 1237                   pEncryptPayload->Len0 = 0;
 1238                   pEncryptPayload->E0 = 0;
 1239             }
 1240             else
 1241             {
 1242                 pPayload->AddrLow0 = 0;
 1243                 pPayload->AddrHi0 = 0;
 1244                 pPayload->Len0 = 0;
 1245                 pPayload->E0 = 0;
 1246             }
 1247           }
 1248 
 1249           /* post the IOMB to SPC */
 1250 #ifdef LOOPBACK_MPI
 1251           if (loopback)
 1252             ret = mpiMsgProduceOQ(circularOQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_OUB_SSP_COMP, outq, (bit8)circularQ->priority);
 1253           else
 1254 #endif /* LOOPBACK_MPI */
 1255           ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, opCode, outq, (bit8)circularQ->priority);
 1256           if (AGSA_RC_FAILURE == ret)
 1257           {
 1258             SA_DBG1(("saSSPStart, error when post SSP IOMB\n"));
 1259             ret = AGSA_RC_FAILURE;
 1260           }
 1261         }
 1262         else
 1263         {
 1264           /* additionalCdbLen is not zero and type is Ext - use EXT mode */
 1265           agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt);
 1266           agsaSSPIniExtIOStartCmd_t *pPayload = (agsaSSPIniExtIOStartCmd_t *)pMessage;
 1267           bit32 sspiul;
 1268 
 1269           /*
 1270            * Most fields for the SAS IOMB have the same offset regardless of the actual IOMB used.
 1271            * Be careful with the scatter/gather lists, encryption and DIF options.
 1272            */
 1273           /* CDB > 16 bytes */
 1274           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, tag), pRequest->HTag);
 1275           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, deviceId), pDevice->DeviceMapIndex);
 1276           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, dataLen), pIRequest->dataLength);
 1277           /* dword (bit7-bit2) ==> bytes (bit7-bit0) */
 1278           /* setup standard CDB bytes + additional CDB bytes in length field */
 1279           sspiul = sizeof(agsaSSPCmdInfoUnit_t) +
 1280                     (pIRequest->sspCmdIUExt.additionalCdbLen & 0xFC);
 1281           DirDW4 = sspiul << 16;
 1282           si_memcpy(&pPayload->SSPIu[0], &pIRequest->sspCmdIUExt, sspiul);
 1283           pPayload->SSPIuLendirMTlr = 0;
 1284 
 1285           /* Mask DIR for Read/Write command */
 1286           DirDW4 |= agRequestType & AGSA_DIR_MASK;
 1287 
 1288           /* set TLR */
 1289           DirDW4 |= pIRequest->flag & TLR_MASK;
 1290           if (agRequestType & AGSA_MSG)
 1291           {
 1292             /* set M bit */
 1293             DirDW4 |= AGSA_MSG_BIT;
 1294           }
 1295 
 1296           /* check for skipmask operation */
 1297           if (pIRequest->flag & AGSA_SAS_ENABLE_SKIP_MASK)
 1298           {
 1299             SA_ASSERT(0, "Mode not supported");
 1300           }
 1301 
 1302           /* configure DIF */
 1303           if (pIRequest->flag & AGSA_SAS_ENABLE_DIF)
 1304           {
 1305             SA_ASSERT(0, "Mode not supported");
 1306           }
 1307 
 1308           /* configure encryption */
 1309           if (pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION)
 1310           {
 1311             SA_ASSERT(0, "Mode not supported");
 1312           }
 1313           /* Setup SGL */
 1314           if (pIRequest->dataLength)
 1315           {
 1316             pSgl = &(pIRequest->agSgl);
 1317 
 1318             SA_DBG3(("saSSPStart: Ext mode, agSgl %08x:%08x (%x/%x)\n",
 1319               pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved));
 1320 
 1321             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, SSPIuLendirMTlr), DirDW4);
 1322 
 1323              if (opCode == OPC_INB_SSP_DIF_ENC_OPSTART)
 1324             {
 1325                 si_memcpy((&((agsaSSPIniEncryptIOStartCmd_t *)(pPayload))->AddrLow0), pSgl, sizeof(agsaSgl_t));
 1326             }
 1327             else
 1328             {
 1329                 si_memcpy((&(pPayload->SSPIu[0]) + sspiul), pSgl, sizeof(agsaSgl_t));
 1330             }
 1331           }
 1332           else
 1333           {
 1334             /* no data transfer */
 1335             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, SSPIuLendirMTlr), DirDW4);
 1336             pPayload->dataLen = 0;
 1337           }
 1338 
 1339           /* post the IOMB to SPC */
 1340           if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, opCode, outq,(bit8)circularQ->priority ))
 1341           {
 1342             SA_DBG1(("saSSPStart, error when post SSP Ext IOMB\n"));
 1343             ret = AGSA_RC_FAILURE;
 1344           }
 1345         }
 1346         break;
 1347       }
 1348       case AGSA_SSP_TASK_MGNT_REQ:
 1349       case AGSA_SSP_TASK_MGNT_REQ_M:
 1350       {
 1351         agsaIORequestDesc_t *pTMRequestToAbort = agNULL;
 1352         agsaSSPIniTMStartCmd_t *pPayload = (agsaSSPIniTMStartCmd_t *)pMessage;
 1353 
 1354         if (agRequestType & AGSA_MSG)
 1355         {
 1356           /* set M bit */
 1357           DirDW4 = AGSA_MSG_BIT;
 1358         }
 1359 
 1360         /* set DS and ADS bit */
 1361         DirDW4 |= (agRequestBody->sspTaskMgntReq.tmOption & 0x3) << 3;
 1362 
 1363         /* Prepare the SSP TASK Management payload */
 1364         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, tag), pRequest->HTag);
 1365         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, deviceId), pDevice->DeviceMapIndex);
 1366         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, relatedTag), agRequestBody->sspTaskMgntReq.tagOfTaskToBeManaged);
 1367         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, TMfunction), agRequestBody->sspTaskMgntReq.taskMgntFunction);
 1368         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, dsAdsMReport), DirDW4);
 1369         pPayload->lun[0] = agRequestBody->sspTaskMgntReq.lun[0];
 1370         pPayload->lun[1] = agRequestBody->sspTaskMgntReq.lun[1];
 1371         pPayload->lun[2] = agRequestBody->sspTaskMgntReq.lun[2];
 1372         pPayload->lun[3] = agRequestBody->sspTaskMgntReq.lun[3];
 1373         pPayload->lun[4] = agRequestBody->sspTaskMgntReq.lun[4];
 1374         pPayload->lun[5] = agRequestBody->sspTaskMgntReq.lun[5];
 1375         pPayload->lun[6] = agRequestBody->sspTaskMgntReq.lun[6];
 1376         pPayload->lun[7] = agRequestBody->sspTaskMgntReq.lun[7];
 1377 
 1378         if (agTMRequest)
 1379         {
 1380           pTMRequestToAbort = (agsaIORequestDesc_t *)agTMRequest->sdkData;
 1381           if (pTMRequestToAbort)
 1382           {
 1383             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, relatedTag), pTMRequestToAbort->HTag);
 1384           }
 1385         }
 1386 
 1387         SA_DBG1(("saSSPStart, HTAG 0x%x TM function 0x%x Tag-to-be-aborted 0x%x deviceId 0x%x\n",
 1388                   pPayload->tag, pPayload->TMfunction, pPayload->relatedTag, pPayload->deviceId));
 1389 
 1390         siDumpActiveIORequests(agRoot, saRoot->swConfig.maxActiveIOs);
 1391 
 1392         /* post the IOMB to SPC */
 1393         if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSPINITMSTART, outq, (bit8)circularQ->priority))
 1394         {
 1395           SA_DBG1(("saSSPStart, error when post TM IOMB\n"));
 1396           ret = AGSA_RC_FAILURE;
 1397         }
 1398 
 1399         break;
 1400       }
 1401       case AGSA_SSP_TGT_READ_DATA:
 1402       case AGSA_SSP_TGT_READ_GOOD_RESP:
 1403       case AGSA_SSP_TGT_WRITE_DATA:
 1404       case AGSA_SSP_TGT_WRITE_GOOD_RESP:
 1405       {
 1406         agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq);
 1407         agsaSSPTgtIOStartCmd_t *pPayload = (agsaSSPTgtIOStartCmd_t *)pMessage;
 1408         bit32 DirDW5 = 0;
 1409         /* Prepare the SSP TGT IO Start payload */
 1410         /* Configure DWORD 1 */
 1411         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, tag), pRequest->HTag);
 1412         /* Configure DWORD 2 */
 1413         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, deviceId), pDevice->DeviceMapIndex);
 1414         /* Configure DWORD 3 */
 1415         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, dataLen), pTRequest->dataLength);
 1416         /* Configure DWORD 4 */
 1417         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, dataOffset), pTRequest->offset);
 1418 
 1419         SA_DBG3(("saSSPStart, sspOption %08X\n", pTRequest->sspOption ));
 1420 
 1421         /* Mask DIR and AutoGR bits for Read/Write command */
 1422         DirDW5 = (agRequestType & (AGSA_DIR_MASK | AGSA_AUTO_MASK)) | (pTRequest->agTag << 16);
 1423 
 1424         if (pTRequest->sspOption & SSP_OPTION_DIF )
 1425         {
 1426           bit32 UDTR1_UDTR0_UDT1_UDT0   = 0;
 1427           bit32 UDT5_UDT4_UDT3_UDT2     = 0;
 1428           bit32 UDTR5_UDTR4_UDTR3_UDTR2 = 0;
 1429           SA_DBG3(("saSSPStart,tgt DIF enableRefBlockCount ref %d enableRefBlockCount  %d enableCrc  %d enableCrcInversion %d\n",
 1430               pTRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0,
 1431               pTRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0,
 1432               pTRequest->dif.flags & DIF_FLAG_BITS_CRC_VER           ? 1 : 0,
 1433               pTRequest->dif.flags & DIF_FLAG_BITS_CRC_INV           ? 1 : 0  ));
 1434 
 1435           SA_DBG3(("saSSPStart,tgt DIF initialIOSeed %X lbSize %X difAction %X\n",
 1436               pTRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? 1 : 0,
 1437               (pTRequest->dif.flags & DIF_FLAG_BITS_BLOCKSIZE_MASK ) >> DIF_FLAG_BITS_BLOCKSIZE_SHIFT,
 1438               pTRequest->dif.flags & DIF_FLAG_BITS_ACTION  ));
 1439 
 1440           SA_DBG3(("saSSPStart,tgt DIF udtArray %2X %2X %2X %2X %2X %2X\n",
 1441               pTRequest->dif.udtArray[0],
 1442               pTRequest->dif.udtArray[1],
 1443               pTRequest->dif.udtArray[2],
 1444               pTRequest->dif.udtArray[3],
 1445               pTRequest->dif.udtArray[4],
 1446               pTRequest->dif.udtArray[5]));
 1447 
 1448           SA_DBG3(("saSSPStart,tgt DIF udrtArray %2X %2X %2X %2X %2X %2X\n",
 1449               pTRequest->dif.udrtArray[0],
 1450               pTRequest->dif.udrtArray[1],
 1451               pTRequest->dif.udrtArray[2],
 1452               pTRequest->dif.udrtArray[3],
 1453               pTRequest->dif.udrtArray[4],
 1454               pTRequest->dif.udrtArray[5]));
 1455 
 1456           SA_DBG3(("saSSPStart,tgt DIF tagUpdateMask %X tagVerifyMask %X DIFPerLAAddrLo %X DIFPerLAAddrHi %X\n",
 1457               (pTRequest->dif.flags & DIF_FLAG_BITS_UDTVMASK) >> DIF_FLAG_BITS_UDTV_SHIFT,
 1458               (pTRequest->dif.flags & DIF_FLAG_BITS_UDTUPMASK) >> DIF_FLAG_BITS_UDTUPSHIFT,
 1459               pTRequest->dif.DIFPerLAAddrLo,
 1460               pTRequest->dif.DIFPerLAAddrHi));
 1461 
 1462           DirDW5 |= AGSA_SSP_TGT_BITS_DEE_DIF;
 1463 
 1464 
 1465           SA_DBG3(("saSSPStart,tgt  DW 15 DIF_flags 0x%08X\n", pTRequest->dif.flags ));
 1466 
 1467           OSSA_WRITE_LE_32(agRoot, pPayload,
 1468                              OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_flags),
 1469                              pTRequest->dif.flags);
 1470 
 1471             /* Populate the UDT and UDTR bytes as necessary. */
 1472             if ((pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) != AGSA_DIF_INSERT)
 1473             {
 1474                 UDTR1_UDTR0_UDT1_UDT0 = (pTRequest->dif.udtArray[1] << SHIFT8 |
 1475                                          pTRequest->dif.udtArray[0]);
 1476                 UDT5_UDT4_UDT3_UDT2   = (pTRequest->dif.udtArray[5] << SHIFT24 |
 1477                                          pTRequest->dif.udtArray[4] << SHIFT16 |
 1478                                          pTRequest->dif.udtArray[3] << SHIFT8  |
 1479                                          pTRequest->dif.udtArray[2]);
 1480             }
 1481 
 1482             if ((pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_INSERT ||
 1483                 (pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_VERIFY_REPLACE ||
 1484                 (pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_REPLACE_UDT_REPLACE_CRC)
 1485             {
 1486                 UDTR1_UDTR0_UDT1_UDT0 |= (pTRequest->dif.udrtArray[1] << SHIFT24 |
 1487                                           pTRequest->dif.udrtArray[0] << SHIFT16 );
 1488                 UDTR5_UDTR4_UDTR3_UDTR2 = (pTRequest->dif.udrtArray[5] << SHIFT24 |
 1489                                            pTRequest->dif.udrtArray[4] << SHIFT16 |
 1490                                            pTRequest->dif.udrtArray[3] << SHIFT8  |
 1491                                            pTRequest->dif.udrtArray[2]);
 1492             }
 1493           /* DWORD 8 is UDTR1, UDTR0, UDT1 and UDT0 */
 1494           OSSA_WRITE_LE_32(agRoot, pPayload,
 1495                            OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, udt),
 1496                            UDTR1_UDTR0_UDT1_UDT0);
 1497 
 1498           /* DWORD 9 is UDT5, UDT4, UDT3 and UDT2 */
 1499           OSSA_WRITE_LE_32(agRoot, pPayload,
 1500                            OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, udtReplacementLo),
 1501                            UDT5_UDT4_UDT3_UDT2);
 1502 
 1503           /* DWORD 10 is UDTR5, UDTR4, UDTR3 and UDTR2 */
 1504           OSSA_WRITE_LE_32(agRoot, pPayload,
 1505                            OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, udtReplacementHi),
 1506                            UDTR5_UDTR4_UDTR3_UDTR2);
 1507           /* DWORD 11 */
 1508           /* Get IOS IOSeed enable bit */
 1509           if( pTRequest->dif.flags & DIF_FLAG_BITS_CUST_APP_TAG)
 1510           {
 1511               OSSA_WRITE_LE_32(agRoot, pPayload,
 1512                                OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_seed),
 1513                                ((pTRequest->dif.DIFPerLARegion0SecCount << SHIFT16) |
 1514                                (pTRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? pTRequest->dif.initialIOSeed : 0 )));
 1515           }
 1516           else
 1517           {
 1518               /* Get IOS IOSeed enable bit */
 1519               if (pTRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED)
 1520               {
 1521                   OSSA_WRITE_LE_32(agRoot, pPayload,
 1522                                    OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_seed),
 1523                                    pTRequest->dif.initialIOSeed );
 1524               }
 1525               else
 1526               {
 1527                   OSSA_WRITE_LE_32(agRoot, pPayload,
 1528                                    OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_seed),  0 );
 1529               }
 1530           }
 1531         }
 1532 
 1533         /* Mask DIR and AutoGR bits for Read/Write command */
 1534         if(pTRequest->sspOption & SSP_OPTION_AUTO_GOOD_RESPONSE)
 1535         {
 1536           DirDW5 |= AGSA_SSP_TGT_BITS_AGR;
 1537         }
 1538 
 1539         /* AN, RTE, RDF bits */
 1540         DirDW5 |= (pTRequest->sspOption & SSP_OPTION_BITS) << 2;
 1541 
 1542         /* ODS */
 1543         if(pTRequest->sspOption & SSP_OPTION_ODS)
 1544         {
 1545           DirDW5 |= AGSA_SSP_TGT_BITS_ODS;
 1546         }
 1547 
 1548         /* Setup SGL */
 1549         if (pTRequest->dataLength)
 1550         {
 1551           pSgl = &(pTRequest->agSgl);
 1552 
 1553           SA_DBG5(("saSSPStart: agSgl %08x:%08x (%x/%x)\n",
 1554           pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved));
 1555 
 1556           /* set up dir on the payload */
 1557           /* Configure DWORD 5 */
 1558           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, INITagAgrDir), DirDW5);
 1559 
 1560           pPayload->AddrLow0 = pSgl->sgLower;
 1561           pPayload->AddrHi0 = pSgl->sgUpper;
 1562           pPayload->Len0 = pSgl->len;
 1563           pPayload->E0 = pSgl->extReserved;
 1564         }
 1565         else
 1566         {
 1567           /* no data transfer */
 1568           /* Configure DWORD 5 */
 1569           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, INITagAgrDir), DirDW5);
 1570           pPayload->AddrLow0 = 0;
 1571           pPayload->AddrHi0 = 0;
 1572           pPayload->Len0 = 0;
 1573         }
 1574         /* Configure DWORD 6 */
 1575         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t,reserved ), 0);
 1576 
 1577         /* Build TGT IO START command and send it to SPC */
 1578         if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSPTGTIOSTART, outq, (bit8)circularQ->priority))
 1579         {
 1580           SA_DBG1(("saSSPStart, error when post TGT IOMB\n"));
 1581           ret = AGSA_RC_FAILURE;
 1582         }
 1583 
 1584         break;
 1585       }
 1586       case AGSA_SSP_TGT_CMD_OR_TASK_RSP:
 1587       {
 1588         agsaSSPTargetResponse_t *pTResponse = &(agRequestBody->sspTargetResponse);
 1589         agsaSSPTgtRspStartCmd_t *pPayload = (agsaSSPTgtRspStartCmd_t *)pMessage;
 1590         bit32 ip, an, ods;
 1591 
 1592         if (pTResponse->frameBuf && (pTResponse->respBufLength <= AGSA_MAX_SSPPAYLOAD_VIA_SFO))
 1593         {
 1594           ip = 1;
 1595           si_memcpy(pPayload->reserved, pTResponse->frameBuf, pTResponse->respBufLength);
 1596         }
 1597         else
 1598         {
 1599           ip = 0;
 1600           /* NOTE:
 1601            * 1. reserved field must be ZEROED out. FW depends on it
 1602            * 2. trusted interface. indirect response buffer must be valid.
 1603            */
 1604           si_memset(pPayload->reserved, 0, sizeof(pPayload->reserved));
 1605           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, AddrLow0), pTResponse->respBufLower);
 1606           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, AddrHi0), pTResponse->respBufUpper);
 1607           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, Len0), pTResponse->respBufLength);
 1608           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, E0), 0);
 1609         }
 1610 
 1611         /* TLR setting */
 1612         an = (pTResponse->respOption & RESP_OPTION_BITS);
 1613         /* ODS */
 1614         ods = (pTResponse->respOption & RESP_OPTION_ODS);
 1615 
 1616         /* Prepare the SSP TGT RESPONSE Start payload */
 1617         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, tag), pRequest->HTag);
 1618         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, deviceId), pDevice->DeviceMapIndex);
 1619         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, RspLen), pTResponse->respBufLength);
 1620         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, INITag_IP_AN),
 1621           (pTResponse->agTag << SHIFT16) | ods | (ip << SHIFT10) | (an << SHIFT2));
 1622 
 1623         /* Build TGT RESPONSE START command and send it to SPC */
 1624         if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSPTGTRSPSTART, outq, (bit8)circularQ->priority))
 1625         {
 1626           SA_DBG1(("saSSPStart, error when post TGT RSP IOMB\n"));
 1627           ret = AGSA_RC_FAILURE;
 1628         }
 1629 
 1630         break;
 1631       }
 1632       default:
 1633       {
 1634         SA_DBG1(("saSSPStart, Unsupported Request IOMB\n"));
 1635         ret = AGSA_RC_FAILURE;
 1636         break;
 1637       }
 1638     }
 1639 
 1640   } /* LL IOrequest available */
 1641 
 1642 #ifdef SA_LL_IBQ_PROTECT
 1643   ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
 1644 #endif /* SA_LL_IBQ_PROTECT */
 1645 
 1646 #ifdef SALL_API_TEST
 1647   if (ret == AGSA_RC_SUCCESS)
 1648     saRoot->LLCounters.IOCounter.numSSPStarted++;
 1649 #endif /*SALL_API_TEST  */
 1650 
 1651 #ifdef LOOPBACK_MPI
 1652   if (loopback)
 1653     saRoot->interruptVecIndexBitMap[0] |= (1 << outq);
 1654 #endif /* LOOPBACK_MPI */
 1655   /* goto have leave and trace point info */
 1656   smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "Sa");
 1657 ext:
 1658 
 1659   OSSA_INP_LEAVE(agRoot);
 1660   return ret;
 1661 }
 1662 
 1663 /******************************************************************************/
 1664 /*! \brief Abort SSP request
 1665  *
 1666  *  Abort SSP request
 1667  *
 1668  *  \param agRoot handles for this instance of SAS/SATA LLL
 1669  *  \param queueNum
 1670  *  \param agIORequest
 1671  *  \param agIOToBeAborted
 1672  *
 1673  *  \return If request is aborted successfully
 1674  *          - \e AGSA_RC_SUCCESS request is aborted successfully
 1675  *          - \e AGSA_RC_FAILURE request is not aborted successfully
 1676  */
 1677 /*******************************************************************************/
 1678 GLOBAL bit32 saSSPAbort(
 1679   agsaRoot_t        *agRoot,
 1680   agsaIORequest_t   *agIORequest,
 1681   bit32             queueNum,
 1682   agsaDevHandle_t   *agDevHandle,
 1683   bit32             flag,
 1684   void              *abortParam,
 1685   ossaGenericAbortCB_t  agCB
 1686   )
 1687 {
 1688   bit32 ret = AGSA_RC_SUCCESS, retVal;
 1689   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
 1690   agsaIORequestDesc_t *pRequest;
 1691   agsaIORequestDesc_t *pRequestABT = NULL;
 1692   agsaDeviceDesc_t    *pDevice = NULL;
 1693   agsaDeviceDesc_t    *pDeviceABT = NULL;
 1694   agsaPort_t          *pPort = NULL;
 1695   mpiICQueue_t        *circularQ;
 1696   void                *pMessage;
 1697   agsaSSPAbortCmd_t   *payload;
 1698   agsaIORequest_t     *agIOToBeAborted;
 1699   bit8                inq, outq;
 1700   bit32               using_reserved = agFALSE;
 1701   bit32               flag_copy = flag;
 1702   smTraceFuncEnter(hpDBG_VERY_LOUD,"Sb");
 1703 
 1704   /* sanity check */
 1705   SA_ASSERT((agNULL != agRoot), "");
 1706   SA_ASSERT((agNULL != agIORequest), "");
 1707 
 1708   SA_DBG2(("saSSPAbort: agIORequest %p agDevHandle %p abortParam %p flag 0x%x\n", agIORequest,agDevHandle,abortParam,flag));
 1709 
 1710   /* Assign inbound and outbound Buffer */
 1711   inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
 1712   outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
 1713   SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
 1714 
 1715 #ifdef SA_PRINTOUT_IN_WINDBG
 1716 #ifndef DBG
 1717         DbgPrint("saSSPAbort flag %d\n", flag );
 1718 #endif /* DBG  */
 1719 #endif /* SA_PRINTOUT_IN_WINDBG  */
 1720 
 1721   if( ABORT_SINGLE == (flag & ABORT_MASK) )
 1722   {
 1723     agIOToBeAborted = (agsaIORequest_t *)abortParam;
 1724     /* Get LL IORequest entry for saSSPAbort() */
 1725     pRequest = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData);
 1726     if (agNULL == pRequest)
 1727     {
 1728       /* no pRequest found - can not Abort */
 1729       SA_DBG1(("saSSPAbort: ABORT_ALL no pRequest\n"));
 1730       smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "Sb");
 1731       return AGSA_RC_FAILURE;
 1732     }
 1733     /* Find the device the request sent to */
 1734     pDevice = pRequest->pDevice;
 1735     /* Get LL IORequest entry for IOToBeAborted */
 1736     pRequestABT = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData);
 1737     if (agNULL == pRequestABT)
 1738     {
 1739       /* The IO to Be Abort is no longer exist */
 1740       SA_DBG1(("saSSPAbort: ABORT_ALL no pRequestABT\n"));
 1741       smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "Sb");
 1742       return AGSA_RC_FAILURE;
 1743     }
 1744     /* Find the device the request Abort to */
 1745     pDeviceABT = pRequestABT->pDevice;
 1746 
 1747     if (agNULL == pDeviceABT)
 1748     {
 1749       /* no deviceID - can not build IOMB */
 1750       SA_DBG1(("saSSPAbort: ABORT_ALL no pRequestABT->deviceID\n"));
 1751       smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "Sb");
 1752       return AGSA_RC_FAILURE;
 1753     }
 1754 
 1755     if (agNULL != pDevice)
 1756     {
 1757       /* Find the port the request was sent to */
 1758       pPort = pDevice->pPort;
 1759     }
 1760     else
 1761     {
 1762       /* no deviceID - can not build IOMB */
 1763       SA_DBG1(("saSSPAbort: ABORT_ALL no deviceID\n"));
 1764       smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "Sb");
 1765       return AGSA_RC_FAILURE;
 1766     }
 1767 
 1768     /* Get request from free IORequests */
 1769     ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1770     pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/
 1771   }
 1772   else
 1773   {
 1774     if (ABORT_ALL == (flag & ABORT_MASK))
 1775     {
 1776       /* abort All with Device or Port */
 1777       /* Find the outgoing port for the device */
 1778       if (agDevHandle == agNULL)
 1779       {
 1780         /* no deviceID - can not build IOMB */
 1781         SA_DBG1(("saSSPAbort: agDevHandle == agNULL!!!\n"));
 1782         return AGSA_RC_FAILURE;
 1783       }
 1784       pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
 1785       if (agNULL == pDevice)
 1786       {
 1787         /* no deviceID - can not build IOMB */
 1788         SA_DBG1(("saSSPAbort: ABORT_ALL agNULL == pDevice\n"));
 1789         return AGSA_RC_FAILURE;
 1790       }
 1791       pPort = pDevice->pPort;
 1792       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1793       pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/
 1794     }
 1795     else
 1796     {
 1797       /* only support 00, 01 and 02 for flag */
 1798       SA_DBG1(("saSSPAbort: ABORT_ALL type not supported 0x%X\n",flag));
 1799       smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "Sb");
 1800       return AGSA_RC_FAILURE;
 1801     }
 1802   }
 1803 
 1804   if ( agNULL == pRequest )
 1805   {
 1806     pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests));
 1807     if(agNULL != pRequest)
 1808     {
 1809       using_reserved = agTRUE;
 1810       SA_DBG2(("saSSPAbort: using saRoot->freeReservedRequests\n"));
 1811     }
 1812     else
 1813     {
 1814       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1815       /* If no LL IO request entry available */
 1816       SA_DBG1(("saSSPAbort: No request from free list Not using saRoot->freeReservedRequests\n"));
 1817       smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "Sb");
 1818       return AGSA_RC_BUSY;
 1819     }
 1820   }
 1821 
 1822   /* If free IOMB avaliable */
 1823   /* Remove the request from free list */
 1824   if( using_reserved )
 1825   {
 1826     saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
 1827   }
 1828   else
 1829   {
 1830     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
 1831   }
 1832 
 1833   /* Add the request to the pendingIORequests list of the device */
 1834   pRequest->valid = agTRUE;
 1835   saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode));
 1836 
 1837   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1838 
 1839   /* set up pRequest */
 1840   pRequest->pIORequestContext = agIORequest;
 1841   pRequest->requestType = AGSA_SSP_REQTYPE;
 1842   pRequest->pDevice = pDevice;
 1843   pRequest->pPort = pPort;
 1844   pRequest->completionCB = (void*)agCB;
 1845 /*  pRequest->abortCompletionCB = agCB;*/
 1846   pRequest->startTick = saRoot->timeTick;
 1847 
 1848   /* Set request to the sdkData of agIORequest */
 1849   agIORequest->sdkData = pRequest;
 1850 
 1851   /* save tag and IOrequest pointer to IOMap */
 1852   saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
 1853   saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
 1854 
 1855 
 1856 #ifdef SA_LL_IBQ_PROTECT
 1857   ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
 1858 #endif /* SA_LL_IBQ_PROTECT */
 1859 
 1860   /* If LL IO request entry avaliable */
 1861   /* Get a free inbound queue entry */
 1862   circularQ = &saRoot->inboundQueue[inq];
 1863   retVal    = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage);
 1864 
 1865   /* if message size is too large return failure */
 1866   if (AGSA_RC_FAILURE == retVal)
 1867   {
 1868 #ifdef SA_LL_IBQ_PROTECT
 1869     ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
 1870 #endif /* SA_LL_IBQ_PROTECT */
 1871 
 1872     ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1873     saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
 1874     pRequest->valid = agFALSE;
 1875     if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
 1876     {
 1877       SA_DBG1(("saSSPAbort: saving pRequest (%p) for later use\n", pRequest));
 1878       saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
 1879     }
 1880     else
 1881     {
 1882       /* return the request to free pool */
 1883       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
 1884     }
 1885     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1886 
 1887     SA_DBG1(("saSSPAbort: error when get free IOMB\n"));
 1888 
 1889     smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "Sb");
 1890     return AGSA_RC_FAILURE;
 1891   }
 1892 
 1893   /* return busy if inbound queue is full */
 1894   if (AGSA_RC_BUSY == retVal)
 1895   {
 1896 #ifdef SA_LL_IBQ_PROTECT
 1897     ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
 1898 #endif /* SA_LL_IBQ_PROTECT */
 1899 
 1900     ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1901     saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
 1902     pRequest->valid = agFALSE;
 1903     if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
 1904     {
 1905       SA_DBG1(("saSSPAbort: saving pRequest (%p) for later use\n", pRequest));
 1906       saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
 1907     }
 1908     else
 1909     {
 1910       /* return the request to free pool */
 1911       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
 1912     }
 1913     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
 1914 
 1915     SA_DBG1(("saSSPAbort: no more IOMB\n"));
 1916     smTraceFuncExit(hpDBG_VERY_LOUD, 'h', "Sb");
 1917     return AGSA_RC_BUSY;
 1918   }
 1919 
 1920   /* setup payload */
 1921   payload = (agsaSSPAbortCmd_t*)pMessage;
 1922   OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, tag), pRequest->HTag);
 1923 
 1924   if( ABORT_SINGLE == (flag & ABORT_MASK) )
 1925   {
 1926     if ( agNULL == pDeviceABT )
 1927     {
 1928       SA_DBG1(("saSSPSAbort: no device\n" ));
 1929       smTraceFuncExit(hpDBG_VERY_LOUD, 'i', "Sb");
 1930       return AGSA_RC_FAILURE;
 1931     }
 1932     OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, deviceId), pDeviceABT->DeviceMapIndex);
 1933     OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, HTagAbort), pRequestABT->HTag);
 1934   }
 1935   else
 1936   {
 1937     /* abort all */
 1938     OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, deviceId), pDevice->DeviceMapIndex);
 1939     OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, HTagAbort), 0);
 1940   }
 1941 
 1942   if(flag & ABORT_TSDK_QUARANTINE)
 1943   {
 1944     if(smIS_SPCV(agRoot))
 1945     {
 1946       flag_copy &= ABORT_SCOPE;
 1947       flag_copy |= ABORT_QUARANTINE_SPCV;
 1948     }
 1949   }
 1950   OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, abortAll), flag_copy);
 1951 
 1952   SA_DBG1(("saSSPAbort: HTag 0x%x HTagABT 0x%x deviceId 0x%x flag 0x%x\n", payload->tag, payload->HTagAbort, payload->deviceId,flag));
 1953 
 1954   siCountActiveIORequestsOnDevice( agRoot,   payload->deviceId );
 1955 
 1956   /* post the IOMB to SPC */
 1957   ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSP_ABORT, outq, (bit8)circularQ->priority);
 1958 
 1959 #ifdef SA_LL_IBQ_PROTECT
 1960   ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
 1961 #endif /* SA_LL_IBQ_PROTECT */
 1962 
 1963 #ifdef SALL_API_TEST
 1964   if (AGSA_RC_SUCCESS == ret)
 1965   {
 1966     saRoot->LLCounters.IOCounter.numSSPAborted++;
 1967   }
 1968 #endif
 1969 
 1970   smTraceFuncExit(hpDBG_VERY_LOUD, 'j', "Sb");
 1971 
 1972   return ret;
 1973 }
 1974 
 1975 
 1976 #if defined(SALLSDK_DEBUG)
 1977 /******************************************************************************/
 1978 /*! \brief
 1979  *
 1980  *  Dump StartSSP information
 1981  *
 1982  *  Debug helper routine
 1983  *
 1984  *  \return -none -
 1985  */
 1986 /*******************************************************************************/
 1987 LOCAL void siDumpSSPStartIu(
 1988   agsaDevHandle_t       *agDevHandle,
 1989   bit32                 agRequestType,
 1990   agsaSASRequestBody_t  *agRequestBody
 1991   )
 1992  {
 1993   switch ( agRequestType )
 1994   {
 1995     case AGSA_SSP_INIT_READ:
 1996     case AGSA_SSP_INIT_WRITE:
 1997     {
 1998       agsaSSPInitiatorRequest_t *pIRequest = &(agRequestBody->sspInitiatorReq);
 1999 
 2000       SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - len=%x - attr=%x - CDB:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
 2001         agDevHandle,
 2002         (agRequestType==AGSA_SSP_INIT_READ)? "AGSA_SSP_INIT_READ" : "AGSA_SSP_INIT_WRITE",
 2003         pIRequest->dataLength,
 2004         pIRequest->sspCmdIU.efb_tp_taskAttribute,
 2005         pIRequest->sspCmdIU.cdb[0],
 2006         pIRequest->sspCmdIU.cdb[1],
 2007         pIRequest->sspCmdIU.cdb[2],
 2008         pIRequest->sspCmdIU.cdb[3],
 2009         pIRequest->sspCmdIU.cdb[4],
 2010         pIRequest->sspCmdIU.cdb[5],
 2011         pIRequest->sspCmdIU.cdb[6],
 2012         pIRequest->sspCmdIU.cdb[7],
 2013         pIRequest->sspCmdIU.cdb[8],
 2014         pIRequest->sspCmdIU.cdb[9]
 2015         ));
 2016       break;
 2017     }
 2018 
 2019     case  AGSA_SSP_INIT_READ_EXT:
 2020     case  AGSA_SSP_INIT_WRITE_EXT:
 2021     {
 2022       agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt);
 2023 
 2024       SA_DBG3(("siDumpSSPStartIu: dev=%p - %s - len=%x - attr=%x - CDB:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
 2025         agDevHandle,
 2026         (agRequestType==AGSA_SSP_INIT_READ_EXT)? "AGSA_SSP_INIT_READ_EXT" : "AGSA_SSP_INIT_WRITE_EXT",
 2027         pIRequest->dataLength,
 2028         pIRequest->sspCmdIUExt.efb_tp_taskAttribute,
 2029         pIRequest->sspCmdIUExt.cdb[0],
 2030         pIRequest->sspCmdIUExt.cdb[1],
 2031         pIRequest->sspCmdIUExt.cdb[2],
 2032         pIRequest->sspCmdIUExt.cdb[3],
 2033         pIRequest->sspCmdIUExt.cdb[4],
 2034         pIRequest->sspCmdIUExt.cdb[5],
 2035         pIRequest->sspCmdIUExt.cdb[6],
 2036         pIRequest->sspCmdIUExt.cdb[7],
 2037         pIRequest->sspCmdIUExt.cdb[8],
 2038         pIRequest->sspCmdIUExt.cdb[9]
 2039         ));
 2040       break;
 2041     }
 2042 
 2043     case  AGSA_SSP_INIT_READ_EXT_M:
 2044     case  AGSA_SSP_INIT_WRITE_EXT_M:
 2045     {
 2046       agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt);
 2047 
 2048       SA_DBG3(("siDumpSSPStartIu: dev=%p - %s - len=%x - attr=%x - CDB:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
 2049         agDevHandle,
 2050         (agRequestType==AGSA_SSP_INIT_READ_EXT_M)? "AGSA_SSP_INIT_READ_EXT_M" : "AGSA_SSP_INIT_WRITE_EXT_M",
 2051         pIRequest->dataLength,
 2052         pIRequest->sspCmdIUExt.efb_tp_taskAttribute,
 2053         pIRequest->sspCmdIUExt.cdb[0],
 2054         pIRequest->sspCmdIUExt.cdb[1],
 2055         pIRequest->sspCmdIUExt.cdb[2],
 2056         pIRequest->sspCmdIUExt.cdb[3],
 2057         pIRequest->sspCmdIUExt.cdb[4],
 2058         pIRequest->sspCmdIUExt.cdb[5],
 2059         pIRequest->sspCmdIUExt.cdb[6],
 2060         pIRequest->sspCmdIUExt.cdb[7],
 2061         pIRequest->sspCmdIUExt.cdb[8],
 2062         pIRequest->sspCmdIUExt.cdb[9]
 2063         ));
 2064       break;
 2065     }
 2066 
 2067     case  AGSA_SSP_INIT_READ_INDIRECT:
 2068     case  AGSA_SSP_INIT_WRITE_INDIRECT:
 2069     case  AGSA_SSP_INIT_READ_INDIRECT_M:
 2070     case  AGSA_SSP_INIT_WRITE_INDIRECT_M:
 2071     {
 2072      agsaSSPInitiatorRequestIndirect_t *pIRequest = &(agRequestBody->sspInitiatorReqIndirect);
 2073 
 2074       SA_DBG3(("siDumpSSPStartIu: dev=%p - %s - len=%x - cdblen=%d CDB:U %08x L %08x\n",
 2075         agDevHandle,
 2076         (agRequestType==AGSA_SSP_INIT_READ_INDIRECT ||
 2077          agRequestType==AGSA_SSP_INIT_READ_INDIRECT_M) ? "AGSA_SSP_INIT_READ_INDIRECT" : "AGSA_SSP_INIT_WRITE_INDIRECT",
 2078         pIRequest->dataLength,
 2079         pIRequest->sspInitiatorReqLen,
 2080         pIRequest->sspInitiatorReqAddrUpper32,
 2081         pIRequest->sspInitiatorReqAddrLower32 ));
 2082       break;
 2083     }
 2084 
 2085 
 2086     case AGSA_SSP_TASK_MGNT_REQ:
 2087     {
 2088       agsaSSPScsiTaskMgntReq_t  *pTaskCmd =&agRequestBody->sspTaskMgntReq;
 2089       /* copy payload */
 2090 
 2091       SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - Task Function=%x - Tag to managed=%x",
 2092         agDevHandle,
 2093         "AGSA_SSP_TASK_MGNT_REQ",
 2094         pTaskCmd->taskMgntFunction,
 2095         pTaskCmd->tagOfTaskToBeManaged
 2096         ));
 2097       break;
 2098     }
 2099     case AGSA_SSP_TGT_READ_DATA:
 2100     {
 2101       agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq);
 2102 
 2103       SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n",
 2104                   agDevHandle,
 2105                   "AGSA_SSP_TGT_READ_DATA",
 2106                   pTRequest->dataLength,
 2107                   pTRequest->offset ));
 2108       break;
 2109     }
 2110     case AGSA_SSP_TGT_READ_GOOD_RESP:
 2111     {
 2112       agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq);
 2113 
 2114       SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n",
 2115                   agDevHandle,
 2116                   "AGSA_SSP_TGT_READ_GOOD_RESP",
 2117                   pTRequest->dataLength,
 2118                   pTRequest->offset));
 2119       break;
 2120     }
 2121     case AGSA_SSP_TGT_WRITE_GOOD_RESP:
 2122     {
 2123       agsaSSPTargetRequest_t  *pTRequest = &(agRequestBody->sspTargetReq);
 2124       SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n",
 2125                   agDevHandle,
 2126                   "AGSA_SSP_TGT_WRITE_GOOD_RESP",
 2127                   pTRequest->dataLength,
 2128                   pTRequest->offset ));
 2129 
 2130       break;
 2131     }
 2132     case AGSA_SSP_TGT_WRITE_DATA:
 2133     {
 2134       agsaSSPTargetRequest_t  *pTRequest = &(agRequestBody->sspTargetReq);
 2135 
 2136       SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n",
 2137         agDevHandle,
 2138         "AGSA_SSP_TGT_WRITE_DATA",
 2139         pTRequest->dataLength,
 2140         pTRequest->offset ));
 2141       break;
 2142     }
 2143     case AGSA_SSP_TGT_CMD_OR_TASK_RSP:
 2144     {
 2145       agsaSSPTargetResponse_t *pTResponse = &(agRequestBody->sspTargetResponse);
 2146 
 2147       SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - len=%x PAddr=%08x:%08x  Tag=%x\n",
 2148         agDevHandle,
 2149         "AGSA_SSP_TGT_CMD_OR_TASK_RSP",
 2150         pTResponse->respBufLength,
 2151         pTResponse->respBufUpper,
 2152         pTResponse->respBufLower,
 2153         pTResponse->agTag  ));
 2154       break;
 2155     }
 2156 
 2157     default:
 2158     {
 2159       SA_DBG1(("siDumpSSPStartIu: dev=%p - %s %X\n",
 2160         agDevHandle,
 2161         "Unknown SSP cmd type",
 2162         agRequestType
 2163         ));
 2164       break;
 2165     }
 2166   }
 2167   return;
 2168 }
 2169 #endif /* SALLSDK_DEBUG */

Cache object: 090fa47c68ee1f0f0af25ecc2a9db8aa


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