sassp.c revision 285242
143166Snsouch/*******************************************************************************
243166Snsouch**
343166Snsouch*Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved.
443166Snsouch*
543166Snsouch*Redistribution and use in source and binary forms, with or without modification, are permitted provided
643166Snsouch*that the following conditions are met:
743166Snsouch*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
843166Snsouch*following disclaimer.
943166Snsouch*2. Redistributions in binary form must reproduce the above copyright notice,
1043166Snsouch*this list of conditions and the following disclaimer in the documentation and/or other materials provided
1143166Snsouch*with the distribution.
1243166Snsouch*
1343166Snsouch*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
1443166Snsouch*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
1543166Snsouch*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1643166Snsouch*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1743166Snsouch*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
1843166Snsouch*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1943166Snsouch*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2043166Snsouch*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
2143166Snsouch
2243166Snsouch********************************************************************************/
2343166Snsouch/*******************************************************************************/
2443166Snsouch/*! \file sassp.c
2543166Snsouch *  \brief The file implements the functions for SSP request/response
2643288Sdillon *
2743166Snsouch */
2843166Snsouch/*******************************************************************************/
2943166Snsouch#include <sys/cdefs.h>
3043166Snsouch__FBSDID("$FreeBSD: projects/pms/sys/dev/pms/RefTisa/sallsdk/spc/sassp.c 285242 2015-07-07 13:17:02Z achim $");
3143166Snsouch#include <dev/pms/config.h>
3243166Snsouch
3343166Snsouch#include <dev/pms/RefTisa/sallsdk/spc/saglobal.h>
3443166Snsouch#ifdef SA_ENABLE_TRACE_FUNCTIONS
3543166Snsouch#ifdef siTraceFileID
3643166Snsouch#undef siTraceFileID
3743166Snsouch#endif
3843166Snsouch#define siTraceFileID 'O'
3943166Snsouch#endif
4043166Snsouch
4143166Snsouch#ifdef LOOPBACK_MPI
4243166Snsouchextern int loopback;
4343166Snsouch#endif
4443166Snsouch
4543166Snsouch#ifdef SALLSDK_DEBUG
4643166SnsouchLOCAL void siDumpSSPStartIu(
4743166Snsouch  agsaDevHandle_t       *agDevHandle,
4843166Snsouch  bit32                 agRequestType,
4943166Snsouch  agsaSASRequestBody_t  *agRequestBody
5043166Snsouch  );
5143166Snsouch#endif
5243166Snsouch
5343166Snsouch#ifdef FAST_IO_TEST
5443166SnsouchLOCAL bit32 saGetIBQPI(agsaRoot_t *agRoot,
5543166Snsouch                       bit32 queueNum)
5643166Snsouch{
5743166Snsouch  bit8         inq;
5843166Snsouch  mpiICQueue_t *circularQ;
5943166Snsouch  agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
6043166Snsouch
6143166Snsouch  inq = INQ(queueNum);
6243166Snsouch  circularQ = &saRoot->inboundQueue[inq];
6343166Snsouch  return circularQ->producerIdx;
6443166Snsouch}
6543166Snsouch
6643166SnsouchLOCAL void saSetIBQPI(agsaRoot_t *agRoot,
6743166Snsouch                      bit32      queueNum,
6843166Snsouch                      bit32      pi)
6943166Snsouch{
7043166Snsouch  bit8         inq;
7143166Snsouch  mpiICQueue_t *circularQ;
7243166Snsouch  agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
7343166Snsouch
7443166Snsouch  inq = INQ(queueNum);
7543166Snsouch  circularQ = &saRoot->inboundQueue[inq];
7643166Snsouch  circularQ->producerIdx = pi;
7743166Snsouch}
7843166Snsouch
7943166SnsouchosLOCAL void*
8043166SnsouchsiFastSSPReqAlloc(agsaRoot_t *agRoot)
8143166Snsouch{
8243166Snsouch  int             idx;
8343166Snsouch  agsaLLRoot_t    *saRoot = (agsaLLRoot_t*)(agRoot->sdkData);
8443166Snsouch  saFastRequest_t *fr;
8543166Snsouch
8643166Snsouch  if (!saRoot->freeFastIdx)
8743166Snsouch  {
8843166Snsouch    SA_DBG1(("saSuperSSPReqAlloc: no memory ERROR\n"));
8943166Snsouch    SA_ASSERT((0), "");
9043166Snsouch    return 0;
9143166Snsouch  }
9243166Snsouch
9343166Snsouch  ossaSingleThreadedEnter(agRoot, LL_FAST_IO_LOCK);
9443166Snsouch  saRoot->freeFastIdx--;
9543166Snsouch  idx = saRoot->freeFastIdx;
9643166Snsouch  ossaSingleThreadedLeave(agRoot, LL_FAST_IO_LOCK);
9743166Snsouch
9843166Snsouch  fr = saRoot->freeFastReq[idx];
9943166Snsouch  SA_ASSERT((fr), "");
10043166Snsouch  fr->valid = 1;
10143166Snsouch
10243166Snsouch  return fr;
10343166Snsouch}
10443166Snsouch
10543166SnsouchLOCAL void
10643166SnsouchsiFastSSPReqFree(
10743166Snsouch             agsaRoot_t *agRoot,
10843166Snsouch             void       *freq)
10943166Snsouch{
11043166Snsouch  agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
11143166Snsouch  saFastRequest_t *fr = (saFastRequest_t*)freq;
11243166Snsouch
11343166Snsouch  SA_DBG2(("siFastSSPReqFree: enter\n"));
11443166Snsouch  SA_ASSERT((fr->valid), "");
11543166Snsouch  if (saRoot->freeFastIdx >= sizeof(saRoot->freeFastReq) /
11643166Snsouch                             sizeof(saRoot->freeFastReq[0]))
11743166Snsouch  {
11843166Snsouch    SA_DBG1(("siFastSSPReqFree: too many handles %d / %d ERROR\n",
11943166Snsouch             saRoot->freeFastIdx, (int)(sizeof(saRoot->freeFastReq) /
12043166Snsouch             sizeof(saRoot->freeFastReq[0]))));
12143166Snsouch    SA_ASSERT((0), "");
12243166Snsouch    return;
12343166Snsouch  }
12443166Snsouch  ossaSingleThreadedEnter(agRoot, LL_FAST_IO_LOCK);
12543166Snsouch  /* not need if only one entry */
12643166Snsouch  /* saRoot->freeFastReq[saRoot->freeFastIdx] = freq;  */
12743166Snsouch  saRoot->freeFastIdx++;
12843166Snsouch  ossaSingleThreadedLeave(agRoot, LL_FAST_IO_LOCK);
12943166Snsouch
13043166Snsouch  fr->valid = 0;
13143166Snsouch  SA_DBG6(("siFastSSPReqFree: leave\n"));
13243166Snsouch}
13343166Snsouch
13443166SnsouchLOCAL bit32 siFastSSPResAlloc(
13543166Snsouch  agsaRoot_t             *agRoot,
13643166Snsouch  bit32                  queueNum,
13743166Snsouch  bit32                  agRequestType,
13843166Snsouch  agsaDeviceDesc_t       *pDevice,
13943166Snsouch  agsaIORequestDesc_t    **pRequest,
14043166Snsouch  void                   **pPayload
14143166Snsouch  )
14243166Snsouch{
14343166Snsouch  agsaLLRoot_t *saRoot = (agsaLLRoot_t*)(agRoot->sdkData);
14443166Snsouch  mpiICQueue_t *circularQ;
14543166Snsouch  bit8  inq;
14643166Snsouch  bit16 size = IOMB_SIZE64;
14743166Snsouch  bit32 ret = AGSA_RC_SUCCESS, retVal;
14843166Snsouch
14943166Snsouch  smTraceFuncEnter(hpDBG_VERY_LOUD,"2D");
15043166Snsouch
15143166Snsouch  SA_DBG4(("Entering function siFastSSPResAlloc:\n"));
15243166Snsouch
15343166Snsouch  ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
15443166Snsouch  *pRequest = (agsaIORequestDesc_t*)saLlistIOGetHead(&saRoot->freeIORequests);
15543166Snsouch
15643166Snsouch  /* If no LL IO request entry available */
15743166Snsouch  if (agNULL == *pRequest )
15843166Snsouch  {
15943166Snsouch    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
16043166Snsouch    SA_DBG1(("siFastSSPResAlloc: No request from free list\n" ));
16143166Snsouch    smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2D");
16243166Snsouch    ret = AGSA_RC_BUSY;
16343166Snsouch    goto ext;
16443166Snsouch  }
16543166Snsouch
16643166Snsouch  /* Get IO request from free IORequests */
16743166Snsouch  /* Assign inbound and outbound Buffer */
16843166Snsouch  inq = INQ(queueNum);
16943166Snsouch  SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
17043166Snsouch
17143166Snsouch  /* SSP_INI_IO_START_EXT IOMB need at least 80 bytes to support 32 CDB */
17243166Snsouch  if (agRequestType & AGSA_SSP_EXT_BIT)
17343166Snsouch  {
17443166Snsouch    size = IOMB_SIZE96;
17543166Snsouch  }
17643166Snsouch  /* If LL IO request entry avaliable */
17743166Snsouch  /* Get a free inbound queue entry */
17843166Snsouch  circularQ = &saRoot->inboundQueue[inq];
17943166Snsouch  retVal = mpiMsgFreeGet(circularQ, size, pPayload);
18043166Snsouch
18143166Snsouch  /* if message size is too large return failure */
18243166Snsouch  if (AGSA_RC_SUCCESS != retVal)
18343166Snsouch  {
18443166Snsouch    if (AGSA_RC_FAILURE == retVal)
18543166Snsouch    {
18643166Snsouch      SA_DBG1(("siFastSSPResAlloc: error when get free IOMB\n"));
18743166Snsouch      smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2D");
18843166Snsouch    }
18943166Snsouch
19043166Snsouch    /* return busy if inbound queue is full */
19143166Snsouch    if (AGSA_RC_BUSY == retVal)
19243166Snsouch    {
19343166Snsouch      SA_DBG3(("siFastSSPResAlloc: no more IOMB\n"));
19443166Snsouch      smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2D");
19543166Snsouch    }
19643166Snsouch    ret = retVal;
19743166Snsouch    goto ext;
19843166Snsouch  }
19943166Snsouch
20043166Snsouch  /* But add it to the pending queue during FastStart */
20143166Snsouch  /* If free IOMB avaliable */
20243166Snsouch  /* Remove the request from free list */
20343166Snsouch  saLlistIORemove(&saRoot->freeIORequests, &(*pRequest)->linkNode);
20443166Snsouch
20543166Snsouch  /* Add the request to the pendingIORequests list of the device */
20643166Snsouch  saLlistIOAdd(&pDevice->pendingIORequests, &(*pRequest)->linkNode);
20743166Snsouch
20843166Snsouchext:
20943166Snsouch  ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
21043166Snsouch
21143166Snsouch  if (AGSA_RC_SUCCESS == ret)
21243166Snsouch  {
21343166Snsouch    /* save tag and IOrequest pointer to IOMap */
21443166Snsouch    saRoot->IOMap[(*pRequest)->HTag].Tag = (*pRequest)->HTag;
21543166Snsouch    saRoot->IOMap[(*pRequest)->HTag].IORequest = (void *)*pRequest;
21643166Snsouch  }
21743166Snsouch
21843166Snsouch  return ret;
21943166Snsouch} /* siFastSSPResAlloc */
22043166Snsouch
22143166Snsouch
22243166SnsouchGLOBAL bit32 saFastSSPCancel(void *ioHandle)
22343166Snsouch{
22443166Snsouch  agsaRoot_t      *agRoot;
22543166Snsouch  agsaLLRoot_t    *saRoot;
22643166Snsouch  saFastRequest_t *fr;
22743166Snsouch  bit32            i;
22843166Snsouch  agsaIORequestDesc_t *ior;
22943166Snsouch
23043166Snsouch  SA_ASSERT((ioHandle), "");
23143166Snsouch  fr = (saFastRequest_t*)ioHandle;
23243166Snsouch  SA_ASSERT((fr->valid), "");
23343166Snsouch  agRoot = (agsaRoot_t*)fr->agRoot;
23443166Snsouch  SA_ASSERT((agRoot), "");
23543166Snsouch  saRoot = (agsaLLRoot_t*)(agRoot->sdkData);
23643166Snsouch  SA_ASSERT((saRoot), "");
23743166Snsouch
23843166Snsouch  smTraceFuncEnter(hpDBG_VERY_LOUD,"2E");
23943166Snsouch
24043166Snsouch  /* rollback the previously set IBQ PI */
24143166Snsouch  for (i = 0; i < fr->inqMax - 1; i++)
24243166Snsouch    saSetIBQPI(agRoot, fr->inqList[i], fr->beforePI[fr->inqList[i]]);
24343166Snsouch
24443166Snsouch  /* free all the previous Fast IO Requests */
24543166Snsouch  ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
24643166Snsouch  /* at least one entry, no need to check for NULL saLlistIOGetHead() */
24743166Snsouch  ior = (agsaIORequestDesc_t*)((char*)saLlistIOGetHead(&fr->requests) -
24843166Snsouch                              OSSA_OFFSET_OF(agsaIORequestDesc_t, fastLink));
24943166Snsouch  do
25043166Snsouch  {
25143166Snsouch    agsaDeviceDesc_t *pDevice;
25243166Snsouch    void             *tmp;
25343166Snsouch
25443166Snsouch    pDevice = ior->pDevice;
25543166Snsouch    saLlistIORemove(&pDevice->pendingIORequests, &ior->linkNode);
25643166Snsouch    saLlistIOAdd(&saRoot->freeIORequests, &ior->linkNode);
25743166Snsouch
25843166Snsouch    tmp = (void*)saLlistGetNext(&fr->requests, &ior->fastLink);
25943166Snsouch    if (!tmp)
26043166Snsouch    {
26143166Snsouch      break; /* end of list */
26243166Snsouch    }
26343166Snsouch    ior = (agsaIORequestDesc_t*)((char*)tmp -
26443166Snsouch                                 OSSA_OFFSET_OF(agsaIORequestDesc_t, fastLink));
26543166Snsouch  } while (1);
26643166Snsouch
26743166Snsouch  ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
26843166Snsouch
26943166Snsouch  /* free the IBQ PI tracking struct */
27043166Snsouch  siFastSSPReqFree(agRoot, fr);
27143166Snsouch
27243166Snsouch  smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2E");
27343166Snsouch  return AGSA_RC_SUCCESS;
27443166Snsouch} /* saFastSSPCancel */
27543166Snsouch
27643166SnsouchGLOBAL void *saFastSSPPrepare(
27743166Snsouch                 void                 *ioh,
27843166Snsouch                 agsaFastCommand_t    *fc,
27943166Snsouch                 ossaSSPCompletedCB_t cb,
28043166Snsouch                 void                 *cbArg)
28143166Snsouch{
28243166Snsouch  bit32            ret = AGSA_RC_SUCCESS;
28343166Snsouch  agsaRoot_t       *agRoot;
28443166Snsouch  agsaLLRoot_t     *saRoot;
28543166Snsouch  mpiICQueue_t     *circularQ;
28643166Snsouch  agsaDeviceDesc_t *pDevice;
28743166Snsouch  agsaSgl_t        *pSgl;
28843166Snsouch  bit32            Dir = 0;
28943288Sdillon  bit8             inq, outq;
29043288Sdillon  saFastRequest_t  *fr;
29143288Sdillon  void             *pMessage;
29243288Sdillon  agsaIORequestDesc_t *pRequest;
29343166Snsouch  bit16            opCode;
29443166Snsouch  bitptr           offsetTag;
29543166Snsouch  bitptr           offsetDeviceId;
29643166Snsouch  bitptr           offsetDataLen;
29743166Snsouch  bitptr           offsetDir;
29843166Snsouch
29943166Snsouch  agRoot = (agsaRoot_t*)fc->agRoot;
30043166Snsouch  smTraceFuncEnter(hpDBG_VERY_LOUD,"2G");
30143166Snsouch
30243166Snsouch  OSSA_INP_ENTER(agRoot);
30343166Snsouch
30443166Snsouch  saRoot = (agsaLLRoot_t*)(agRoot->sdkData);
30543166Snsouch  /* sanity check */
30643166Snsouch  SA_ASSERT((agNULL != saRoot), "");
30743166Snsouch
30843288Sdillon  SA_DBG4(("Entering function saFastSSPPrepare:\n"));
30943166Snsouch
31043166Snsouch  fr = (saFastRequest_t*)ioh;
31143166Snsouch  if (!fr)
31243166Snsouch  {
31343166Snsouch    int i;
31443166Snsouch    fr = siFastSSPReqAlloc(agRoot);
31543166Snsouch    if (!fr)
31643166Snsouch    {
31743166Snsouch      SA_ASSERT((0), "");
31843166Snsouch      goto ext;
31943166Snsouch    }
32043166Snsouch
32143166Snsouch    saLlistIOInitialize(&fr->requests);
32243166Snsouch    for (i = 0; i < AGSA_MAX_INBOUND_Q; i++)
32343166Snsouch      fr->beforePI[i] = (bit32)-1;
32443166Snsouch
32543166Snsouch    fr->inqMax = 0;
32643166Snsouch    fr->agRoot = agRoot;
32743166Snsouch    ioh = fr;
32843166Snsouch  }
32943166Snsouch
33043166Snsouch  /* Find the outgoing port for the device */
33143166Snsouch  pDevice = (agsaDeviceDesc_t*)(((agsaDevHandle_t*)fc->devHandle)->sdkData);
33243166Snsouch
33343166Snsouch  ret = siFastSSPResAlloc(agRoot, fc->queueNum, fc->agRequestType,
33443166Snsouch                          pDevice, &pRequest, &pMessage);
33543166Snsouch  if (ret != AGSA_RC_SUCCESS)
33643166Snsouch  {
33743166Snsouch    SA_ASSERT((0), "");
33843166Snsouch    smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2G");
33943166Snsouch    goto ext;
34043166Snsouch  }
34143166Snsouch
34243166Snsouch  /* Assign inbound and outbound Buffer */
34343166Snsouch  inq = INQ(fc->queueNum);
34443166Snsouch  outq = OUQ(fc->queueNum);
34543166Snsouch  circularQ = &saRoot->inboundQueue[inq];
34643166Snsouch
34743166Snsouch  SA_DBG3(("saFastSSPPrepare: deviceId %d\n", pDevice->DeviceMapIndex));
34843166Snsouch
34943166Snsouch  /* set up pRequest */
35043166Snsouch  pRequest->valid = agTRUE;
35143166Snsouch  pRequest->pDevice = pDevice;
35243166Snsouch  pRequest->requestType = fc->agRequestType;
35343166Snsouch
35443166Snsouch  pRequest->completionCB = cb;
35543166Snsouch  pRequest->pIORequestContext = (agsaIORequest_t*)cbArg;
35643166Snsouch
35743166Snsouch  pSgl = fc->agSgl;
35843166Snsouch
35943166Snsouch  switch (fc->agRequestType)
36043166Snsouch  {
36143166Snsouch    /* case AGSA_SSP_INIT_NONDATA: */
36243166Snsouch    case AGSA_SSP_INIT_READ:
36343166Snsouch    case AGSA_SSP_INIT_WRITE:
36443166Snsouch    case AGSA_SSP_INIT_READ_M:
36543166Snsouch    case AGSA_SSP_INIT_WRITE_M:
36643166Snsouch    {
36743166Snsouch      agsaSSPIniIOStartCmd_t *pPayload = (agsaSSPIniIOStartCmd_t *)pMessage;
36843166Snsouch      agsaSSPCmdInfoUnit_t   *piu;
36943166Snsouch
37043166Snsouch      /* SSPIU less equal 28 bytes */
37143166Snsouch      offsetTag = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, tag);
37243166Snsouch      offsetDeviceId = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, deviceId);
37343166Snsouch      offsetDataLen = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dataLen);
37443166Snsouch      offsetDir = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dirMTlr);
37543166Snsouch
37643166Snsouch      piu = &pPayload->SSPInfoUnit;
37743166Snsouch
37843166Snsouch      si_memcpy(piu->lun, fc->lun, sizeof(piu->lun));
37943166Snsouch      si_memcpy(piu->cdb, fc->cdb, sizeof(piu->cdb));
38043166Snsouch      piu->efb_tp_taskAttribute = fc->taskAttribute;
38143166Snsouch      piu->additionalCdbLen = fc->additionalCdbLen;
38243166Snsouch
38343166Snsouch      /* Mask DIR for Read/Write command */
38443166Snsouch      Dir = fc->agRequestType & AGSA_DIR_MASK;
38543166Snsouch
38643166Snsouch      /* set TLR */
38743166Snsouch      Dir |= fc->flag & TLR_MASK;
38843166Snsouch      if (fc->agRequestType & AGSA_MSG)
38943166Snsouch      {
39043166Snsouch        /* set M bit */
39143166Snsouch        Dir |= AGSA_MSG_BIT;
39243166Snsouch      }
39343166Snsouch
39443166Snsouch      /* Setup SGL */
39543166Snsouch      if (fc->dataLength)
39643166Snsouch      {
39743166Snsouch        SA_DBG5(("saFastSSPPrepare: agSgl %08x:%08x (%x/%x)\n",
39843166Snsouch                 pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved));
39943166Snsouch        /*
40043166Snsouch        pPayload->AddrLow0 = pSgl->sgLower;
40143166Snsouch        pPayload->AddrHi0 = pSgl->sgUpper;
40243166Snsouch        pPayload->Len0 = pSgl->len;
40343166Snsouch        pPayload->E0 = pSgl->extReserved;
40443166Snsouch        */
40543166Snsouch        si_memcpy(&pPayload->AddrLow0, pSgl, sizeof(*pSgl));
40643166Snsouch      }
40743166Snsouch      else
40843166Snsouch      {
40943166Snsouch        /* no data transfer */
41043166Snsouch        si_memset(&pPayload->AddrLow0, 0, sizeof(*pSgl));
41143166Snsouch      }
41243166Snsouch
41343166Snsouch      opCode = OPC_INB_SSPINIIOSTART;
41443166Snsouch      break;
41543166Snsouch    }
41643166Snsouch
41743166Snsouch    case AGSA_SSP_INIT_READ_EXT:
41843166Snsouch    case AGSA_SSP_INIT_WRITE_EXT:
41943166Snsouch    case AGSA_SSP_INIT_READ_EXT_M:
42043166Snsouch    case AGSA_SSP_INIT_WRITE_EXT_M:
42143166Snsouch    {
42243166Snsouch      agsaSSPIniExtIOStartCmd_t *pPayload =
42343166Snsouch                                    (agsaSSPIniExtIOStartCmd_t *)pMessage;
42443166Snsouch      agsaSSPCmdInfoUnitExt_t   *piu;
42543166Snsouch      bit32 sspiul;
42643166Snsouch
42743166Snsouch      /* CDB > 16 bytes */
42843166Snsouch      offsetTag = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, tag);
42943166Snsouch      offsetDeviceId = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, deviceId);
43043166Snsouch      offsetDataLen = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, dataLen);
43143166Snsouch      offsetDir = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, SSPIuLendirMTlr);
43243166Snsouch
43343166Snsouch      /* dword (bit7-bit2) ==> bytes (bit7-bit0) */
43443166Snsouch      /* setup standard CDB bytes + additional CDB bytes in length field */
43543166Snsouch      sspiul = sizeof(agsaSSPCmdInfoUnit_t) + (fc->additionalCdbLen & 0xFC);
43643166Snsouch
43743166Snsouch      Dir = sspiul << 16;
43843166Snsouch      piu = (agsaSSPCmdInfoUnitExt_t*)pPayload->SSPIu;
43943166Snsouch
44043166Snsouch      si_memcpy(piu->lun, fc->lun, sizeof(piu->lun));
44143166Snsouch      si_memcpy(piu->cdb, fc->cdb, MIN(sizeof(piu->cdb),
44243166Snsouch                                       16 + fc->additionalCdbLen));
44343166Snsouch      piu->efb_tp_taskAttribute = fc->taskAttribute;
44443166Snsouch      piu->additionalCdbLen = fc->additionalCdbLen;
44543166Snsouch
44643166Snsouch      /* Mask DIR for Read/Write command */
44743166Snsouch      Dir |= fc->agRequestType & AGSA_DIR_MASK;
44843166Snsouch
44943166Snsouch      /* set TLR */
45043166Snsouch      Dir |= fc->flag & TLR_MASK;
45143166Snsouch      if (fc->agRequestType & AGSA_MSG)
45243166Snsouch      {
45343166Snsouch        /* set M bit */
45443166Snsouch        Dir |= AGSA_MSG_BIT;
45543166Snsouch      }
45643166Snsouch
45743166Snsouch      /* Setup SGL */
45843166Snsouch      if (fc->dataLength)
45943166Snsouch      {
46043166Snsouch        SA_DBG5(("saSuperSSPSend: Ext mode, agSgl %08x:%08x (%x/%x)\n",
46143166Snsouch          pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved));
46243166Snsouch
46343166Snsouch        si_memcpy((&(pPayload->SSPIu[0]) + sspiul), pSgl, sizeof(*pSgl));
46443166Snsouch      }
46543166Snsouch      else //?
46643166Snsouch      {
46743166Snsouch        /* no data transfer */
46843166Snsouch        //pPayload->dataLen = 0;
46943166Snsouch        si_memset((&(pPayload->SSPIu[0]) + sspiul), 0, sizeof(*pSgl));
47043166Snsouch      }
47143166Snsouch      SA_ASSERT((smIS_SPC(agRoot)), "smIS_SPC");
47243166Snsouch      opCode = OPC_INB_SSPINIEXTIOSTART;
47343166Snsouch      break;
47443166Snsouch    }
47543166Snsouch
47643166Snsouch    default:
47743166Snsouch    {
47843166Snsouch      SA_DBG1(("saSuperSSPSend: Unsupported Request IOMB\n"));
47943166Snsouch      ret = AGSA_RC_FAILURE;
48043166Snsouch      SA_ASSERT((0), "");
48143166Snsouch      smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2G");
48243166Snsouch      goto ext;
48343166Snsouch    }
48443166Snsouch  }
48543166Snsouch
48643166Snsouch  OSSA_WRITE_LE_32(agRoot, pMessage, offsetTag, pRequest->HTag);
48743166Snsouch  OSSA_WRITE_LE_32(agRoot, pMessage, offsetDeviceId, pDevice->DeviceMapIndex);
48843166Snsouch  OSSA_WRITE_LE_32(agRoot, pMessage, offsetDataLen, fc->dataLength);
48943166Snsouch  OSSA_WRITE_LE_32(agRoot, pMessage, offsetDir, Dir);
49043166Snsouch
49143166Snsouch  if (fr->beforePI[inq] == -1)
49243166Snsouch  {
49343166Snsouch    /* save the new IBQ' PI */
49443166Snsouch    fr->beforePI[inq] = saGetIBQPI(agRoot, inq);
49543166Snsouch    fr->inqList[fr->inqMax++] = inq;
49643166Snsouch  }
49743166Snsouch
49843166Snsouch  /* post the IOMB to SPC */
49943166Snsouch  ret = mpiMsgPrepare(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA,
50043166Snsouch                      opCode, outq, 0);
50143166Snsouch  if (AGSA_RC_SUCCESS != ret)
50243166Snsouch  {
50343166Snsouch    SA_ASSERT((0), "");
50443166Snsouch    ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
50543166Snsouch    /* Remove the request from pendingIORequests list */
50643166Snsouch    saLlistIORemove(&pDevice->pendingIORequests, &pRequest->linkNode);
50743166Snsouch
50843166Snsouch    /* Add the request to the free list of the device */
50943166Snsouch    saLlistIOAdd(&saRoot->freeIORequests, &pRequest->linkNode);
51043166Snsouch    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
51143166Snsouch
51243166Snsouch    SA_DBG1(("saFastSSPPrepare: error when post SSP IOMB\n"));
51343166Snsouch    smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2G");
51443166Snsouch    goto ext;
51543166Snsouch  }
51643166Snsouch
51743166Snsouch  /* Add the request to the pendingFastIORequests list of the device */
51843166Snsouch  saLlistIOAdd(&fr->requests, &pRequest->fastLink);
51943166Snsouch  smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "2G");
52043166Snsouch
52143166Snsouchext:
52243166Snsouch  if (fr && ret != AGSA_RC_SUCCESS)
52343166Snsouch  {
52443166Snsouch    saFastSSPCancel(fr);
52543166Snsouch    ioh = 0;
52643166Snsouch  }
52743166Snsouch  OSSA_INP_LEAVE(agRoot);
52843166Snsouch  return ioh;
52943166Snsouch} /* saFastSSPPrepare */
53043166Snsouch
53143166SnsouchGLOBAL bit32 saFastSSPSend(void *ioHandle)
53243166Snsouch{
53343166Snsouch  bit8            inq;
53443166Snsouch  agsaRoot_t      *agRoot;
53543166Snsouch  agsaLLRoot_t    *saRoot;
53643166Snsouch  saFastRequest_t *fr;
53743166Snsouch  bit32           i;
53843166Snsouch
53943166Snsouch  SA_ASSERT((ioHandle), "");
54043166Snsouch  fr = (saFastRequest_t*)ioHandle;
54143166Snsouch  agRoot = (agsaRoot_t*)fr->agRoot;
54243166Snsouch  SA_ASSERT((agRoot), "");
54343166Snsouch  saRoot = (agsaLLRoot_t*)agRoot->sdkData;
54443166Snsouch  SA_ASSERT((saRoot), "");
54543166Snsouch
54643166Snsouch  SA_DBG4(("Entering function saFastSSPSend:\n"));
54743166Snsouch
54843166Snsouch  for (i = 0; i < fr->inqMax; i++)
54943166Snsouch  {
55043166Snsouch    inq = INQ(fr->inqList[i]);
55143166Snsouch    /* FW interrupt */
55243166Snsouch    mpiIBQMsgSend(&saRoot->inboundQueue[inq]);
55343166Snsouch  }
55443166Snsouch  /* IORequests are freed in siIODone() */
55543166Snsouch
55643166Snsouch  siFastSSPReqFree(agRoot, fr);
55743166Snsouch  return AGSA_RC_SUCCESS;
55843166Snsouch} /* saFastSSPSend */
55943166Snsouch#endif
56043166Snsouch
56143166Snsouch/******************************************************************************/
56243166Snsouch/*! \brief Start SSP request
56343166Snsouch *
56443166Snsouch *  Start SSP request
56543166Snsouch *
56643166Snsouch *  \param agRoot handles for this instance of SAS/SATA LLL
56743166Snsouch *  \param queueNum
56843166Snsouch *  \param agIORequest
56943166Snsouch *  \param agDevHandle
57043166Snsouch *  \param agRequestType
57143166Snsouch *  \param agRequestBody
57243166Snsouch *  \param agTMRequest valid for task management
57343166Snsouch *  \param agCB
57443166Snsouch *
57543166Snsouch *  \return If request is started successfully
57643166Snsouch *          - \e AGSA_RC_SUCCESS request is started successfully
57743166Snsouch *          - \e AGSA_RC_BUSY request is not started successfully
57843166Snsouch */
57943166Snsouch/******************************************************************************/
58043166SnsouchGLOBAL bit32 saSSPStart(
58143166Snsouch  agsaRoot_t            *agRoot,
58243166Snsouch  agsaIORequest_t       *agIORequest,
58343166Snsouch  bit32                 queueNum,
58443166Snsouch  agsaDevHandle_t       *agDevHandle,
58543166Snsouch  bit32                 agRequestType,
58643166Snsouch  agsaSASRequestBody_t  *agRequestBody,
58743166Snsouch  agsaIORequest_t       *agTMRequest,
58843166Snsouch  ossaSSPCompletedCB_t  agCB)
58943166Snsouch{
59043166Snsouch  agsaLLRoot_t        *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
59143166Snsouch#ifdef LOOPBACK_MPI
59243166Snsouch  mpiOCQueue_t        *circularOQ = agNULL;
59343166Snsouch#endif
59443166Snsouch  mpiICQueue_t        *circularQ  = agNULL;
59543166Snsouch  agsaDeviceDesc_t    *pDevice    = agNULL;
59643166Snsouch  agsaPort_t          *pPort      = agNULL;
59743166Snsouch  agsaIORequestDesc_t *pRequest   = agNULL;
59843166Snsouch  agsaSgl_t           *pSgl       = agNULL;
59943166Snsouch  void                *pMessage   = agNULL;
60043166Snsouch  bit32               ret = AGSA_RC_SUCCESS, retVal = 0;
60143166Snsouch  bit32               DirDW4 = 0;    /* no data and no AutoGR */
60243166Snsouch  bit32               encryptFlags = 0;
60343166Snsouch  bit16               size = 0;
60443166Snsouch  bit16               opCode = 0;
60543166Snsouch  bit8                inq = 0, outq = 0;
60643166Snsouch
60743166Snsouch
60843166Snsouch  OSSA_INP_ENTER(agRoot);
60943166Snsouch  smTraceFuncEnter(hpDBG_VERY_LOUD,"Sa");
61043166Snsouch
61143166Snsouch  /* sanity check */
61243166Snsouch  SA_ASSERT((agNULL != agRoot), "");
61343166Snsouch  SA_ASSERT((agNULL != agIORequest), "");
61443166Snsouch  SA_ASSERT((agNULL != agDevHandle), "");
61543166Snsouch  SA_ASSERT((agNULL != agRequestBody), "");
61643166Snsouch
61743166Snsouch  DBG_DUMP_SSPSTART_CMDIU(agDevHandle,agRequestType,agRequestBody);
61843166Snsouch
61943166Snsouch  /* Find the outgoing port for the device */
62043166Snsouch  pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
62143166Snsouch
62243166Snsouch  if(pDevice == agNULL )
62343166Snsouch  {
62443166Snsouch    SA_ASSERT((pDevice), "pDevice");
62543166Snsouch    ret = AGSA_RC_FAILURE;
62643166Snsouch    smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "Sa");
62743166Snsouch    goto ext;
62843166Snsouch  }
62943166Snsouch
63043166Snsouch  pPort = pDevice->pPort;
63143166Snsouch  /* Assign inbound and outbound Buffer */
63243166Snsouch  inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
63343166Snsouch  outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
63443166Snsouch  SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
63543166Snsouch
63643166Snsouch  SA_DBG3(("saSSPStart: inq %d outq %d deviceId 0x%x\n", inq,outq,pDevice->DeviceMapIndex));
63743166Snsouch
63843166Snsouch  /* Get request from free IORequests */
63943166Snsouch  ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
64043166Snsouch  pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
64143166Snsouch
64243166Snsouch  /* If no LL IO request entry available */
64343166Snsouch  if ( agNULL == pRequest )
64443166Snsouch  {
64543166Snsouch    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
64643166Snsouch    SA_DBG1(("saSSPStart, No request from free list\n" ));
64743166Snsouch    smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "Sa");
64843166Snsouch    ret = AGSA_RC_BUSY;
64943166Snsouch    goto ext;
65043166Snsouch  }
65143166Snsouch  /* If LL IO request entry avaliable */
65243166Snsouch  else
65343166Snsouch  {
65443166Snsouch    /* Remove the request from free list */
65543166Snsouch    saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
65643166Snsouch    /* Add the request to the pendingIORequests list of the device */
65743166Snsouch    saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode));
65843166Snsouch
65943166Snsouch    ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
66043166Snsouch
66143166Snsouch    SA_ASSERT((!pRequest->valid), "The pRequest is in use");
66243166Snsouch
66343166Snsouch    SA_DBG3(("saSSPStart, request %p\n", pRequest ));
66443166Snsouch
66543166Snsouch    /* Decode the flag settings in the standard I/O requests to  decide what size we need. */
66643166Snsouch    /* All other requests will be fine with only 64 byte messages. */
66743166Snsouch    switch ( agRequestType )
66843166Snsouch    {
66943166Snsouch    case AGSA_SSP_INIT_READ:
67043166Snsouch    case AGSA_SSP_INIT_WRITE:
67143166Snsouch    case AGSA_SSP_INIT_NONDATA:
67243166Snsouch    case AGSA_SSP_INIT_READ_M:
67343166Snsouch    case AGSA_SSP_INIT_WRITE_M:
67443166Snsouch        {
67543166Snsouch            agsaSSPInitiatorRequest_t *pIRequest = &(agRequestBody->sspInitiatorReq);
67643166Snsouch
67743166Snsouch            if ((pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION)   ||
67843166Snsouch#ifdef SAFLAG_USE_DIF_ENC_IOMB
67943166Snsouch               (pIRequest->flag & AGSA_SAS_USE_DIF_ENC_OPSTART)  ||
68043166Snsouch#endif /* SAFLAG_USE_DIF_ENC_IOMB */
68143166Snsouch                (pIRequest->flag & AGSA_SAS_ENABLE_DIF) )
68243166Snsouch            {
68343166Snsouch                opCode = OPC_INB_SSP_DIF_ENC_OPSTART;
68443166Snsouch                size = IOMB_SIZE128;
68543166Snsouch            }
68643166Snsouch            else
68743166Snsouch            {
68843166Snsouch                opCode = OPC_INB_SSPINIIOSTART;
68943166Snsouch                size = IOMB_SIZE64;
69043166Snsouch            }
69143166Snsouch            break;
69243166Snsouch        }
69343166Snsouch    case AGSA_SSP_INIT_READ_EXT:
69443166Snsouch    case AGSA_SSP_INIT_WRITE_EXT:
69543166Snsouch    case AGSA_SSP_INIT_READ_EXT_M:
69643166Snsouch    case AGSA_SSP_INIT_WRITE_EXT_M:
69743166Snsouch        {
69843166Snsouch          agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt);
69943166Snsouch
70043166Snsouch          if ((pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION)   ||
70143166Snsouch              (pIRequest->flag & AGSA_SAS_ENABLE_DIF)          ||
70243166Snsouch#ifdef SAFLAG_USE_DIF_ENC_IOMB
70343166Snsouch              (pIRequest->flag & AGSA_SAS_USE_DIF_ENC_OPSTART) ||
70443166Snsouch#endif /* SAFLAG_USE_DIF_ENC_IOMB */
70543166Snsouch              (pIRequest->flag & AGSA_SAS_ENABLE_SKIP_MASK))
70643166Snsouch          {
70743166Snsouch              opCode = OPC_INB_SSP_DIF_ENC_OPSTART;
70843166Snsouch              size = IOMB_SIZE128;
70943166Snsouch          }
71043166Snsouch          else
71143166Snsouch          {
71243166Snsouch              SA_ASSERT((smIS_SPC(agRoot)), "smIS_SPC");
71343166Snsouch              opCode = OPC_INB_SSPINIEXTIOSTART;
71443166Snsouch              size = IOMB_SIZE96;
71543166Snsouch          }
71643166Snsouch          break;
71743166Snsouch      }
71843166Snsouch      case  AGSA_SSP_INIT_READ_INDIRECT:
71943166Snsouch      case  AGSA_SSP_INIT_WRITE_INDIRECT:
72043166Snsouch      case  AGSA_SSP_INIT_READ_INDIRECT_M:
72143166Snsouch      case  AGSA_SSP_INIT_WRITE_INDIRECT_M:
72243166Snsouch          {
72343166Snsouch            SA_DBG3(("saSSPStart: agRequestType  0x%X INDIRECT\n", agRequestType));
72443166Snsouch            opCode = OPC_INB_SSP_DIF_ENC_OPSTART;
72543166Snsouch            size = IOMB_SIZE128;
72643166Snsouch            break;
72743166Snsouch          }
72843166Snsouch      case (AGSA_SSP_REQTYPE | AGSA_SSP_TASK_MGNT):
72943166Snsouch      case AGSA_SSP_TASK_MGNT_REQ_M:
73043166Snsouch      case AGSA_SSP_TGT_READ_DATA:
73143166Snsouch      case AGSA_SSP_TGT_READ_GOOD_RESP:
73243166Snsouch      case AGSA_SSP_TGT_WRITE_DATA:
73343166Snsouch      case AGSA_SSP_TGT_WRITE_GOOD_RESP:
73443166Snsouch      case AGSA_SSP_TGT_CMD_OR_TASK_RSP:
73543166Snsouch
73643166Snsouch        SA_DBG3(("saSSPStart: agRequestType  0x%X (was default)\n", agRequestType));
73743166Snsouch        opCode = OPC_INB_SSPINIIOSTART;
73843166Snsouch        size = IOMB_SIZE64;
73943166Snsouch         break;
74043166Snsouch    default:
74143166Snsouch        SA_DBG1(("saSSPStart: agRequestType UNKNOWN 0x%X\n", agRequestType));
74243166Snsouch        /* OpCode is not used in this case, but Linux complains if it is not initialized. */
74343166Snsouch        opCode = OPC_INB_SSPINIIOSTART;
74443166Snsouch        size = IOMB_SIZE64;
74543166Snsouch        break;
74643166Snsouch    }
74743166Snsouch
74843166Snsouch    /* If free IOMB avaliable,  set up pRequest*/
74943166Snsouch    pRequest->valid = agTRUE;
75043166Snsouch    pRequest->pIORequestContext = agIORequest;
75143166Snsouch    pRequest->pDevice = pDevice;
75243166Snsouch    pRequest->requestType = agRequestType;
75343166Snsouch    pRequest->pPort = pPort;
75443166Snsouch    pRequest->startTick = saRoot->timeTick;
75543166Snsouch    pRequest->completionCB = agCB;
75643166Snsouch
75743166Snsouch    /* Set request to the sdkData of agIORequest */
75843166Snsouch    agIORequest->sdkData = pRequest;
75943166Snsouch
76043166Snsouch    /* save tag and IOrequest pointer to IOMap */
76143166Snsouch    saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
76243166Snsouch    saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
76343166Snsouch
76443166Snsouch#ifdef SA_LL_IBQ_PROTECT
76543166Snsouch    ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
76643166Snsouch#endif /* SA_LL_IBQ_PROTECT */
76743166Snsouch
76843166Snsouch    /* Get a free inbound queue entry */
76943166Snsouch#ifdef LOOPBACK_MPI
77043166Snsouch    if (loopback)
77143166Snsouch    {
77243166Snsouch      SA_DBG2(("saSSPStart: did %d ioq %d / %d tag %d\n", pDevice->DeviceMapIndex, inq, outq, pRequest->HTag));
77343166Snsouch      circularOQ = &saRoot->outboundQueue[outq];
77443166Snsouch      retVal = mpiMsgFreeGetOQ(circularOQ, size, &pMessage);
77543166Snsouch    }
77643166Snsouch    else
77743166Snsouch#endif /* LOOPBACK_MPI */
77843166Snsouch    {
77943166Snsouch      circularQ = &saRoot->inboundQueue[inq];
78043166Snsouch      retVal = mpiMsgFreeGet(circularQ, size, &pMessage);
78143166Snsouch    }
78243166Snsouch
78343166Snsouch    /* if message size is too large return failure */
78443166Snsouch    if (AGSA_RC_FAILURE == retVal)
78543166Snsouch    {
78643166Snsouch#ifdef SA_LL_IBQ_PROTECT
78743166Snsouch      ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
78843166Snsouch#endif /* SA_LL_IBQ_PROTECT */
78943166Snsouch      /* if not sending return to free list rare */
79043166Snsouch      ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
79143166Snsouch      saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
79243166Snsouch      pRequest->valid = agFALSE;
79343166Snsouch      saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
79443166Snsouch      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");
1657ext:
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/*******************************************************************************/
1678GLOBAL 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/*******************************************************************************/
1987LOCAL 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 */
2170