/*******************************************************************************
**
*Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
*
*Redistribution and use in source and binary forms, with or without modification, are permitted provided
*that the following conditions are met:
*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
*following disclaimer.
*2. Redistributions in binary form must reproduce the above copyright notice,
*this list of conditions and the following disclaimer in the documentation and/or other materials provided
*with the distribution.
*
*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
********************************************************************************/
/*******************************************************************************/
/*! \file sassp.c
* \brief The file implements the functions for SSP request/response
*
*/
/*******************************************************************************/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <dev/pms/config.h>
#include <dev/pms/RefTisa/sallsdk/spc/saglobal.h>
#ifdef SA_ENABLE_TRACE_FUNCTIONS
#ifdef siTraceFileID
#undef siTraceFileID
#endif
#define siTraceFileID 'O'
#endif
#ifdef LOOPBACK_MPI
extern int loopback;
#endif
#ifdef SALLSDK_DEBUG
LOCAL void siDumpSSPStartIu(
agsaDevHandle_t *agDevHandle,
bit32 agRequestType,
agsaSASRequestBody_t *agRequestBody
);
#endif
#ifdef FAST_IO_TEST
LOCAL bit32 saGetIBQPI(agsaRoot_t *agRoot,
bit32 queueNum)
{
bit8 inq;
mpiICQueue_t *circularQ;
agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
inq = INQ(queueNum);
circularQ = &saRoot->inboundQueue[inq];
return circularQ->producerIdx;
}
LOCAL void saSetIBQPI(agsaRoot_t *agRoot,
bit32 queueNum,
bit32 pi)
{
bit8 inq;
mpiICQueue_t *circularQ;
agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
inq = INQ(queueNum);
circularQ = &saRoot->inboundQueue[inq];
circularQ->producerIdx = pi;
}
osLOCAL void*
siFastSSPReqAlloc(agsaRoot_t *agRoot)
{
int idx;
agsaLLRoot_t *saRoot = (agsaLLRoot_t*)(agRoot->sdkData);
saFastRequest_t *fr;
if (!saRoot->freeFastIdx)
{
SA_DBG1(("saSuperSSPReqAlloc: no memory ERROR\n"));
SA_ASSERT((0), "");
return 0;
}
ossaSingleThreadedEnter(agRoot, LL_FAST_IO_LOCK);
saRoot->freeFastIdx--;
idx = saRoot->freeFastIdx;
ossaSingleThreadedLeave(agRoot, LL_FAST_IO_LOCK);
fr = saRoot->freeFastReq[idx];
SA_ASSERT((fr), "");
fr->valid = 1;
return fr;
}
LOCAL void
siFastSSPReqFree(
agsaRoot_t *agRoot,
void *freq)
{
agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
saFastRequest_t *fr = (saFastRequest_t*)freq;
SA_DBG2(("siFastSSPReqFree: enter\n"));
SA_ASSERT((fr->valid), "");
if (saRoot->freeFastIdx >= sizeof(saRoot->freeFastReq) /
sizeof(saRoot->freeFastReq[0]))
{
SA_DBG1(("siFastSSPReqFree: too many handles %d / %d ERROR\n",
saRoot->freeFastIdx, (int)(sizeof(saRoot->freeFastReq) /
sizeof(saRoot->freeFastReq[0]))));
SA_ASSERT((0), "");
return;
}
ossaSingleThreadedEnter(agRoot, LL_FAST_IO_LOCK);
/* not need if only one entry */
/* saRoot->freeFastReq[saRoot->freeFastIdx] = freq; */
saRoot->freeFastIdx++;
ossaSingleThreadedLeave(agRoot, LL_FAST_IO_LOCK);
fr->valid = 0;
SA_DBG6(("siFastSSPReqFree: leave\n"));
}
LOCAL bit32 siFastSSPResAlloc(
agsaRoot_t *agRoot,
bit32 queueNum,
bit32 agRequestType,
agsaDeviceDesc_t *pDevice,
agsaIORequestDesc_t **pRequest,
void **pPayload
)
{
agsaLLRoot_t *saRoot = (agsaLLRoot_t*)(agRoot->sdkData);
mpiICQueue_t *circularQ;
bit8 inq;
bit16 size = IOMB_SIZE64;
bit32 ret = AGSA_RC_SUCCESS, retVal;
smTraceFuncEnter(hpDBG_VERY_LOUD,"2D");
SA_DBG4(("Entering function siFastSSPResAlloc:\n"));
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
*pRequest = (agsaIORequestDesc_t*)saLlistIOGetHead(&saRoot->freeIORequests);
/* If no LL IO request entry available */
if (agNULL == *pRequest )
{
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
SA_DBG1(("siFastSSPResAlloc: No request from free list\n" ));
smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2D");
ret = AGSA_RC_BUSY;
goto ext;
}
/* Get IO request from free IORequests */
/* Assign inbound and outbound Buffer */
inq = INQ(queueNum);
SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
/* SSP_INI_IO_START_EXT IOMB need at least 80 bytes to support 32 CDB */
if (agRequestType & AGSA_SSP_EXT_BIT)
{
size = IOMB_SIZE96;
}
/* If LL IO request entry avaliable */
/* Get a free inbound queue entry */
circularQ = &saRoot->inboundQueue[inq];
retVal = mpiMsgFreeGet(circularQ, size, pPayload);
/* if message size is too large return failure */
if (AGSA_RC_SUCCESS != retVal)
{
if (AGSA_RC_FAILURE == retVal)
{
SA_DBG1(("siFastSSPResAlloc: error when get free IOMB\n"));
smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2D");
}
/* return busy if inbound queue is full */
if (AGSA_RC_BUSY == retVal)
{
SA_DBG3(("siFastSSPResAlloc: no more IOMB\n"));
smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2D");
}
ret = retVal;
goto ext;
}
/* But add it to the pending queue during FastStart */
/* If free IOMB avaliable */
/* Remove the request from free list */
saLlistIORemove(&saRoot->freeIORequests, &(*pRequest)->linkNode);
/* Add the request to the pendingIORequests list of the device */
saLlistIOAdd(&pDevice->pendingIORequests, &(*pRequest)->linkNode);
ext:
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
if (AGSA_RC_SUCCESS == ret)
{
/* save tag and IOrequest pointer to IOMap */
saRoot->IOMap[(*pRequest)->HTag].Tag = (*pRequest)->HTag;
saRoot->IOMap[(*pRequest)->HTag].IORequest = (void *)*pRequest;
}
return ret;
} /* siFastSSPResAlloc */
GLOBAL bit32 saFastSSPCancel(void *ioHandle)
{
agsaRoot_t *agRoot;
agsaLLRoot_t *saRoot;
saFastRequest_t *fr;
bit32 i;
agsaIORequestDesc_t *ior;
SA_ASSERT((ioHandle), "");
fr = (saFastRequest_t*)ioHandle;
SA_ASSERT((fr->valid), "");
agRoot = (agsaRoot_t*)fr->agRoot;
SA_ASSERT((agRoot), "");
saRoot = (agsaLLRoot_t*)(agRoot->sdkData);
SA_ASSERT((saRoot), "");
smTraceFuncEnter(hpDBG_VERY_LOUD,"2E");
/* rollback the previously set IBQ PI */
for (i = 0; i < fr->inqMax - 1; i++)
saSetIBQPI(agRoot, fr->inqList[i], fr->beforePI[fr->inqList[i]]);
/* free all the previous Fast IO Requests */
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
/* at least one entry, no need to check for NULL saLlistIOGetHead() */
ior = (agsaIORequestDesc_t*)((char*)saLlistIOGetHead(&fr->requests) -
OSSA_OFFSET_OF(agsaIORequestDesc_t, fastLink));
do
{
agsaDeviceDesc_t *pDevice;
void *tmp;
pDevice = ior->pDevice;
saLlistIORemove(&pDevice->pendingIORequests, &ior->linkNode);
saLlistIOAdd(&saRoot->freeIORequests, &ior->linkNode);
tmp = (void*)saLlistGetNext(&fr->requests, &ior->fastLink);
if (!tmp)
{
break; /* end of list */
}
ior = (agsaIORequestDesc_t*)((char*)tmp -
OSSA_OFFSET_OF(agsaIORequestDesc_t, fastLink));
} while (1);
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
/* free the IBQ PI tracking struct */
siFastSSPReqFree(agRoot, fr);
smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2E");
return AGSA_RC_SUCCESS;
} /* saFastSSPCancel */
GLOBAL void *saFastSSPPrepare(
void *ioh,
agsaFastCommand_t *fc,
ossaSSPCompletedCB_t cb,
void *cbArg)
{
bit32 ret = AGSA_RC_SUCCESS;
agsaRoot_t *agRoot;
agsaLLRoot_t *saRoot;
mpiICQueue_t *circularQ;
agsaDeviceDesc_t *pDevice;
agsaSgl_t *pSgl;
bit32 Dir = 0;
bit8 inq, outq;
saFastRequest_t *fr;
void *pMessage;
agsaIORequestDesc_t *pRequest;
bit16 opCode;
bitptr offsetTag;
bitptr offsetDeviceId;
bitptr offsetDataLen;
bitptr offsetDir;
agRoot = (agsaRoot_t*)fc->agRoot;
smTraceFuncEnter(hpDBG_VERY_LOUD,"2G");
OSSA_INP_ENTER(agRoot);
saRoot = (agsaLLRoot_t*)(agRoot->sdkData);
/* sanity check */
SA_ASSERT((agNULL != saRoot), "");
SA_DBG4(("Entering function saFastSSPPrepare:\n"));
fr = (saFastRequest_t*)ioh;
if (!fr)
{
int i;
fr = siFastSSPReqAlloc(agRoot);
if (!fr)
{
SA_ASSERT((0), "");
goto ext;
}
saLlistIOInitialize(&fr->requests);
for (i = 0; i < AGSA_MAX_INBOUND_Q; i++)
fr->beforePI[i] = (bit32)-1;
fr->inqMax = 0;
fr->agRoot = agRoot;
ioh = fr;
}
/* Find the outgoing port for the device */
pDevice = (agsaDeviceDesc_t*)(((agsaDevHandle_t*)fc->devHandle)->sdkData);
ret = siFastSSPResAlloc(agRoot, fc->queueNum, fc->agRequestType,
pDevice, &pRequest, &pMessage);
if (ret != AGSA_RC_SUCCESS)
{
SA_ASSERT((0), "");
smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2G");
goto ext;
}
/* Assign inbound and outbound Buffer */
inq = INQ(fc->queueNum);
outq = OUQ(fc->queueNum);
circularQ = &saRoot->inboundQueue[inq];
SA_DBG3(("saFastSSPPrepare: deviceId %d\n", pDevice->DeviceMapIndex));
/* set up pRequest */
pRequest->valid = agTRUE;
pRequest->pDevice = pDevice;
pRequest->requestType = fc->agRequestType;
pRequest->completionCB = cb;
pRequest->pIORequestContext = (agsaIORequest_t*)cbArg;
pSgl = fc->agSgl;
switch (fc->agRequestType)
{
/* case AGSA_SSP_INIT_NONDATA: */
case AGSA_SSP_INIT_READ:
case AGSA_SSP_INIT_WRITE:
case AGSA_SSP_INIT_READ_M:
case AGSA_SSP_INIT_WRITE_M:
{
agsaSSPIniIOStartCmd_t *pPayload = (agsaSSPIniIOStartCmd_t *)pMessage;
agsaSSPCmdInfoUnit_t *piu;
/* SSPIU less equal 28 bytes */
offsetTag = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, tag);
offsetDeviceId = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, deviceId);
offsetDataLen = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dataLen);
offsetDir = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dirMTlr);
piu = &pPayload->SSPInfoUnit;
si_memcpy(piu->lun, fc->lun, sizeof(piu->lun));
si_memcpy(piu->cdb, fc->cdb, sizeof(piu->cdb));
piu->efb_tp_taskAttribute = fc->taskAttribute;
piu->additionalCdbLen = fc->additionalCdbLen;
/* Mask DIR for Read/Write command */
Dir = fc->agRequestType & AGSA_DIR_MASK;
/* set TLR */
Dir |= fc->flag & TLR_MASK;
if (fc->agRequestType & AGSA_MSG)
{
/* set M bit */
Dir |= AGSA_MSG_BIT;
}
/* Setup SGL */
if (fc->dataLength)
{
SA_DBG5(("saFastSSPPrepare: agSgl %08x:%08x (%x/%x)\n",
pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved));
/*
pPayload->AddrLow0 = pSgl->sgLower;
pPayload->AddrHi0 = pSgl->sgUpper;
pPayload->Len0 = pSgl->len;
pPayload->E0 = pSgl->extReserved;
*/
si_memcpy(&pPayload->AddrLow0, pSgl, sizeof(*pSgl));
}
else
{
/* no data transfer */
si_memset(&pPayload->AddrLow0, 0, sizeof(*pSgl));
}
opCode = OPC_INB_SSPINIIOSTART;
break;
}
case AGSA_SSP_INIT_READ_EXT:
case AGSA_SSP_INIT_WRITE_EXT:
case AGSA_SSP_INIT_READ_EXT_M:
case AGSA_SSP_INIT_WRITE_EXT_M:
{
agsaSSPIniExtIOStartCmd_t *pPayload =
(agsaSSPIniExtIOStartCmd_t *)pMessage;
agsaSSPCmdInfoUnitExt_t *piu;
bit32 sspiul;
/* CDB > 16 bytes */
offsetTag = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, tag);
offsetDeviceId = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, deviceId);
offsetDataLen = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, dataLen);
offsetDir = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, SSPIuLendirMTlr);
/* dword (bit7-bit2) ==> bytes (bit7-bit0) */
/* setup standard CDB bytes + additional CDB bytes in length field */
sspiul = sizeof(agsaSSPCmdInfoUnit_t) + (fc->additionalCdbLen & 0xFC);
Dir = sspiul << 16;
piu = (agsaSSPCmdInfoUnitExt_t*)pPayload->SSPIu;
si_memcpy(piu->lun, fc->lun, sizeof(piu->lun));
si_memcpy(piu->cdb, fc->cdb, MIN(sizeof(piu->cdb),
16 + fc->additionalCdbLen));
piu->efb_tp_taskAttribute = fc->taskAttribute;
piu->additionalCdbLen = fc->additionalCdbLen;
/* Mask DIR for Read/Write command */
Dir |= fc->agRequestType & AGSA_DIR_MASK;
/* set TLR */
Dir |= fc->flag & TLR_MASK;
if (fc->agRequestType & AGSA_MSG)
{
/* set M bit */
Dir |= AGSA_MSG_BIT;
}
/* Setup SGL */
if (fc->dataLength)
{
SA_DBG5(("saSuperSSPSend: Ext mode, agSgl %08x:%08x (%x/%x)\n",
pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved));
si_memcpy((&(pPayload->SSPIu[0]) + sspiul), pSgl, sizeof(*pSgl));
}
else //?
{
/* no data transfer */
//pPayload->dataLen = 0;
si_memset((&(pPayload->SSPIu[0]) + sspiul), 0, sizeof(*pSgl));
}
SA_ASSERT((smIS_SPC(agRoot)), "smIS_SPC");
opCode = OPC_INB_SSPINIEXTIOSTART;
break;
}
default:
{
SA_DBG1(("saSuperSSPSend: Unsupported Request IOMB\n"));
ret = AGSA_RC_FAILURE;
SA_ASSERT((0), "");
smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2G");
goto ext;
}
}
OSSA_WRITE_LE_32(agRoot, pMessage, offsetTag, pRequest->HTag);
OSSA_WRITE_LE_32(agRoot, pMessage, offsetDeviceId, pDevice->DeviceMapIndex);
OSSA_WRITE_LE_32(agRoot, pMessage, offsetDataLen, fc->dataLength);
OSSA_WRITE_LE_32(agRoot, pMessage, offsetDir, Dir);
if (fr->beforePI[inq] == -1)
{
/* save the new IBQ' PI */
fr->beforePI[inq] = saGetIBQPI(agRoot, inq);
fr->inqList[fr->inqMax++] = inq;
}
/* post the IOMB to SPC */
ret = mpiMsgPrepare(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA,
opCode, outq, 0);
if (AGSA_RC_SUCCESS != ret)
{
SA_ASSERT((0), "");
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
/* Remove the request from pendingIORequests list */
saLlistIORemove(&pDevice->pendingIORequests, &pRequest->linkNode);
/* Add the request to the free list of the device */
saLlistIOAdd(&saRoot->freeIORequests, &pRequest->linkNode);
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
SA_DBG1(("saFastSSPPrepare: error when post SSP IOMB\n"));
smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2G");
goto ext;
}
/* Add the request to the pendingFastIORequests list of the device */
saLlistIOAdd(&fr->requests, &pRequest->fastLink);
smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "2G");
ext:
if (fr && ret != AGSA_RC_SUCCESS)
{
saFastSSPCancel(fr);
ioh = 0;
}
OSSA_INP_LEAVE(agRoot);
return ioh;
} /* saFastSSPPrepare */
GLOBAL bit32 saFastSSPSend(void *ioHandle)
{
bit8 inq;
agsaRoot_t *agRoot;
agsaLLRoot_t *saRoot;
saFastRequest_t *fr;
bit32 i;
SA_ASSERT((ioHandle), "");
fr = (saFastRequest_t*)ioHandle;
agRoot = (agsaRoot_t*)fr->agRoot;
SA_ASSERT((agRoot), "");
saRoot = (agsaLLRoot_t*)agRoot->sdkData;
SA_ASSERT((saRoot), "");
SA_DBG4(("Entering function saFastSSPSend:\n"));
for (i = 0; i < fr->inqMax; i++)
{
inq = INQ(fr->inqList[i]);
/* FW interrupt */
mpiIBQMsgSend(&saRoot->inboundQueue[inq]);
}
/* IORequests are freed in siIODone() */
siFastSSPReqFree(agRoot, fr);
return AGSA_RC_SUCCESS;
} /* saFastSSPSend */
#endif
/******************************************************************************/
/*! \brief Start SSP request
*
* Start SSP request
*
* \param agRoot handles for this instance of SAS/SATA LLL
* \param queueNum
* \param agIORequest
* \param agDevHandle
* \param agRequestType
* \param agRequestBody
* \param agTMRequest valid for task management
* \param agCB
*
* \return If request is started successfully
* - \e AGSA_RC_SUCCESS request is started successfully
* - \e AGSA_RC_BUSY request is not started successfully
*/
/******************************************************************************/
GLOBAL bit32 saSSPStart(
agsaRoot_t *agRoot,
agsaIORequest_t *agIORequest,
bit32 queueNum,
agsaDevHandle_t *agDevHandle,
bit32 agRequestType,
agsaSASRequestBody_t *agRequestBody,
agsaIORequest_t *agTMRequest,
ossaSSPCompletedCB_t agCB)
{
agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
#ifdef LOOPBACK_MPI
mpiOCQueue_t *circularOQ = agNULL;
#endif
mpiICQueue_t *circularQ = agNULL;
agsaDeviceDesc_t *pDevice = agNULL;
agsaPort_t *pPort = agNULL;
agsaIORequestDesc_t *pRequest = agNULL;
agsaSgl_t *pSgl = agNULL;
void *pMessage = agNULL;
bit32 ret = AGSA_RC_SUCCESS, retVal = 0;
bit32 DirDW4 = 0; /* no data and no AutoGR */
bit32 encryptFlags = 0;
bit16 size = 0;
bit16 opCode = 0;
bit8 inq = 0, outq = 0;
OSSA_INP_ENTER(agRoot);
smTraceFuncEnter(hpDBG_VERY_LOUD,"Sa");
/* sanity check */
SA_ASSERT((agNULL != agRoot), "");
SA_ASSERT((agNULL != agIORequest), "");
SA_ASSERT((agNULL != agDevHandle), "");
SA_ASSERT((agNULL != agRequestBody), "");
DBG_DUMP_SSPSTART_CMDIU(agDevHandle,agRequestType,agRequestBody);
/* Find the outgoing port for the device */
pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
if(pDevice == agNULL )
{
SA_ASSERT((pDevice), "pDevice");
ret = AGSA_RC_FAILURE;
smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "Sa");
goto ext;
}
pPort = pDevice->pPort;
/* Assign inbound and outbound Buffer */
inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
SA_DBG3(("saSSPStart: inq %d outq %d deviceId 0x%x\n", inq,outq,pDevice->DeviceMapIndex));
/* Get request from free IORequests */
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
/* If no LL IO request entry available */
if ( agNULL == pRequest )
{
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
SA_DBG1(("saSSPStart, No request from free list\n" ));
smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "Sa");
ret = AGSA_RC_BUSY;
goto ext;
}
/* If LL IO request entry avaliable */
else
{
/* Remove the request from free list */
saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
/* Add the request to the pendingIORequests list of the device */
saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode));
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
SA_ASSERT((!pRequest->valid), "The pRequest is in use");
SA_DBG3(("saSSPStart, request %p\n", pRequest ));
/* Decode the flag settings in the standard I/O requests to decide what size we need. */
/* All other requests will be fine with only 64 byte messages. */
switch ( agRequestType )
{
case AGSA_SSP_INIT_READ:
case AGSA_SSP_INIT_WRITE:
case AGSA_SSP_INIT_NONDATA:
case AGSA_SSP_INIT_READ_M:
case AGSA_SSP_INIT_WRITE_M:
{
agsaSSPInitiatorRequest_t *pIRequest = &(agRequestBody->sspInitiatorReq);
if ((pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION) ||
#ifdef SAFLAG_USE_DIF_ENC_IOMB
(pIRequest->flag & AGSA_SAS_USE_DIF_ENC_OPSTART) ||
#endif /* SAFLAG_USE_DIF_ENC_IOMB */
(pIRequest->flag & AGSA_SAS_ENABLE_DIF) )
{
opCode = OPC_INB_SSP_DIF_ENC_OPSTART;
size = IOMB_SIZE128;
}
else
{
opCode = OPC_INB_SSPINIIOSTART;
size = IOMB_SIZE64;
}
break;
}
case AGSA_SSP_INIT_READ_EXT:
case AGSA_SSP_INIT_WRITE_EXT:
case AGSA_SSP_INIT_READ_EXT_M:
case AGSA_SSP_INIT_WRITE_EXT_M:
{
agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt);
if ((pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION) ||
(pIRequest->flag & AGSA_SAS_ENABLE_DIF) ||
#ifdef SAFLAG_USE_DIF_ENC_IOMB
(pIRequest->flag & AGSA_SAS_USE_DIF_ENC_OPSTART) ||
#endif /* SAFLAG_USE_DIF_ENC_IOMB */
(pIRequest->flag & AGSA_SAS_ENABLE_SKIP_MASK))
{
opCode = OPC_INB_SSP_DIF_ENC_OPSTART;
size = IOMB_SIZE128;
}
else
{
SA_ASSERT((smIS_SPC(agRoot)), "smIS_SPC");
opCode = OPC_INB_SSPINIEXTIOSTART;
size = IOMB_SIZE96;
}
break;
}
case AGSA_SSP_INIT_READ_INDIRECT:
case AGSA_SSP_INIT_WRITE_INDIRECT:
case AGSA_SSP_INIT_READ_INDIRECT_M:
case AGSA_SSP_INIT_WRITE_INDIRECT_M:
{
SA_DBG3(("saSSPStart: agRequestType 0x%X INDIRECT\n", agRequestType));
opCode = OPC_INB_SSP_DIF_ENC_OPSTART;
size = IOMB_SIZE128;
break;
}
case (AGSA_SSP_REQTYPE | AGSA_SSP_TASK_MGNT):
case AGSA_SSP_TASK_MGNT_REQ_M:
case AGSA_SSP_TGT_READ_DATA:
case AGSA_SSP_TGT_READ_GOOD_RESP:
case AGSA_SSP_TGT_WRITE_DATA:
case AGSA_SSP_TGT_WRITE_GOOD_RESP:
case AGSA_SSP_TGT_CMD_OR_TASK_RSP:
SA_DBG3(("saSSPStart: agRequestType 0x%X (was default)\n", agRequestType));
opCode = OPC_INB_SSPINIIOSTART;
size = IOMB_SIZE64;
break;
default:
SA_DBG1(("saSSPStart: agRequestType UNKNOWN 0x%X\n", agRequestType));
/* OpCode is not used in this case, but Linux complains if it is not initialized. */
opCode = OPC_INB_SSPINIIOSTART;
size = IOMB_SIZE64;
break;
}
/* If free IOMB avaliable, set up pRequest*/
pRequest->valid = agTRUE;
pRequest->pIORequestContext = agIORequest;
pRequest->pDevice = pDevice;
pRequest->requestType = agRequestType;
pRequest->pPort = pPort;
pRequest->startTick = saRoot->timeTick;
pRequest->completionCB = agCB;
/* Set request to the sdkData of agIORequest */
agIORequest->sdkData = pRequest;
/* save tag and IOrequest pointer to IOMap */
saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
#ifdef SA_LL_IBQ_PROTECT
ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
#endif /* SA_LL_IBQ_PROTECT */
/* Get a free inbound queue entry */
#ifdef LOOPBACK_MPI
if (loopback)
{
SA_DBG2(("saSSPStart: did %d ioq %d / %d tag %d\n", pDevice->DeviceMapIndex, inq, outq, pRequest->HTag));
circularOQ = &saRoot->outboundQueue[outq];
retVal = mpiMsgFreeGetOQ(circularOQ, size, &pMessage);
}
else
#endif /* LOOPBACK_MPI */
{
circularQ = &saRoot->inboundQueue[inq];
retVal = mpiMsgFreeGet(circularQ, size, &pMessage);
}
/* if message size is too large return failure */
if (AGSA_RC_FAILURE == retVal)
{
#ifdef SA_LL_IBQ_PROTECT
ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
#endif /* SA_LL_IBQ_PROTECT */
/* if not sending return to free list rare */
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
pRequest->valid = agFALSE;
saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
SA_DBG1(("saSSPStart, error when get free IOMB\n"));
smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "Sa");
ret = AGSA_RC_FAILURE;
goto ext;
}
/* return busy if inbound queue is full */
if (AGSA_RC_BUSY == retVal)
{
#ifdef SA_LL_IBQ_PROTECT
ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
#endif /* SA_LL_IBQ_PROTECT */
/* if not sending return to free list rare */
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
pRequest->valid = agFALSE;
saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
SA_DBG1(("saSSPStart, no more IOMB\n"));
smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "Sa");
ret = AGSA_RC_BUSY;
goto ext;
}
SA_DBG3(("saSSPStart:agRequestType %X\n" ,agRequestType));
switch ( agRequestType )
{
case AGSA_SSP_INIT_READ:
case AGSA_SSP_INIT_WRITE:
case AGSA_SSP_INIT_NONDATA:
case AGSA_SSP_INIT_READ_EXT:
case AGSA_SSP_INIT_WRITE_EXT:
case AGSA_SSP_INIT_READ_M:
case AGSA_SSP_INIT_WRITE_M:
case AGSA_SSP_INIT_READ_EXT_M:
case AGSA_SSP_INIT_WRITE_EXT_M:
case AGSA_SSP_INIT_READ_INDIRECT:
case AGSA_SSP_INIT_WRITE_INDIRECT:
case AGSA_SSP_INIT_READ_INDIRECT_M:
case AGSA_SSP_INIT_WRITE_INDIRECT_M:
{
if (!(agRequestType & AGSA_SSP_EXT_BIT))
{
agsaSSPInitiatorRequest_t *pIRequest = &(agRequestBody->sspInitiatorReq);
agsaSSPIniIOStartCmd_t *pPayload = (agsaSSPIniIOStartCmd_t *)pMessage;
agsaSSPIniEncryptIOStartCmd_t *pEncryptPayload = (agsaSSPIniEncryptIOStartCmd_t *)pMessage;
/* Most fields for the SAS IOMB have the same offset regardless of the actual IOMB used. */
/* Be careful with the scatter/gather lists, encryption and DIF options. */
/* if( pIRequest->sspCmdIU.cdb[ 0] == 0x28 || pIRequest->sspCmdIU.cdb[0]== 0x2A)
{
pRequest->requestBlock = ((pIRequest->sspCmdIU.cdb[2] << 24 ) |
(pIRequest->sspCmdIU.cdb[3] << 16 ) |
(pIRequest->sspCmdIU.cdb[4] << 8 ) |
(pIRequest->sspCmdIU.cdb[5] ) );
}
*/
#ifdef LOOPBACK_MPI
if (loopback)
{
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, tag), pRequest->HTag);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, status), OSSA_IO_SUCCESS);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, param), 0);
//OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, SSPTag), 0);
}
else
#endif /* LOOPBACK_MPI */
{
/* SSPIU less equal 28 bytes */
/* Configure DWORD 1 */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, tag), pRequest->HTag);
/* Configure DWORD 2 */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, deviceId), pDevice->DeviceMapIndex);
/* Configure DWORD 3 */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dataLen), pIRequest->dataLength);
}
#ifdef SA_TESTBASE_EXTRA
/* TestBase - Set the host BST entry */
DirDW4 |= ((UINT32)pIRequest->bstIndex) << 16;
#endif /* SA_TESTBASE_EXTRA */
if (!(agRequestType & AGSA_SSP_INDIRECT_BIT))
{
/* Configure DWORD 5-12 */
si_memcpy(&pPayload->SSPInfoUnit, &pIRequest->sspCmdIU, sizeof(pPayload->SSPInfoUnit));
pPayload->dirMTlr = 0;
/* Mask DIR for Read/Write command */
/* Configure DWORD 4 bit 8-9 */
DirDW4 |= agRequestType & AGSA_DIR_MASK;
}
else /* AGSA_SSP_INDIRECT_BIT was set */
{
agsaSSPInitiatorRequestIndirect_t *pIndRequest = &(agRequestBody->sspInitiatorReqIndirect);
/* Configure DWORD 5 */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_0_3_indcdbalL ),pIndRequest->sspInitiatorReqAddrLower32);
/* Configure DWORD 6 */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_4_7_indcdbalH ),pIndRequest->sspInitiatorReqAddrUpper32 );
/* Configure DWORD 7 */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_8_11 ), 0);
/* Configure DWORD 8 */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_12_15 ), 0);
/* Configure DWORD 9 */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_16_19 ), 0);
/* Configure DWORD 10 */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_19_23), 0);
/* Configure DWORD 11 */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_24_27 ), 0);
/* Mask DIR for Read/Write command */
/* Configure DWORD 4 bit 8-9 */
DirDW4 |= agRequestType & AGSA_DIR_MASK;
/* Configure DWORD 4 bit 24-31 */
DirDW4 |= ((pIndRequest->sspInitiatorReqLen >> 2) & 0xFF) << SHIFT24;
/* Configure DWORD 4 bit 4 */
DirDW4 |= 1 << SHIFT3;
}
/* set TLR */
DirDW4 |= pIRequest->flag & TLR_MASK;
if (agRequestType & AGSA_MSG)
{
/* set M bit */
DirDW4 |= AGSA_MSG_BIT;
}
/* check for skipmask operation */
if (pIRequest->flag & AGSA_SAS_ENABLE_SKIP_MASK)
{
DirDW4 |= AGSA_SKIP_MASK_BIT;
/* agsaSSPInitiatorRequestIndirect_t skip mask in flag is offset 5 */
DirDW4 |= (pIRequest->flag & AGSA_SAS_SKIP_MASK_OFFSET) << SHIFT8;
}
/* Configure DWORDS 12-14 */
if( pIRequest->encrypt.enableEncryptionPerLA && pIRequest->dif.enableDIFPerLA)
{
OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 12 */
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ),
pIRequest->encrypt.EncryptionPerLAAddrLo );
OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 13 */
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ),
pIRequest->dif.DIFPerLAAddrLo );
SA_ASSERT(pIRequest->encrypt.EncryptionPerLAAddrHi == pIRequest->dif.DIFPerLAAddrHi, "EPL DPL hi region must be equal");
if( pIRequest->encrypt.EncryptionPerLAAddrHi != pIRequest->dif.DIFPerLAAddrHi )
{
SA_DBG1(("saSSPStart: EPL DPL hi region must be equal AGSA_RC_FAILURE\n" ));
smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "Sa");
ret = AGSA_RC_FAILURE;
goto ext;
}
OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 14 */
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ),
pIRequest->encrypt.EncryptionPerLAAddrHi );
}
else if( pIRequest->encrypt.enableEncryptionPerLA)
{
OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 12 */
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ),
pIRequest->encrypt.EncryptionPerLAAddrLo );
OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 13 */
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ),
0);
OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 14 */
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ),
pIRequest->encrypt.EncryptionPerLAAddrHi );
}
else if (pIRequest->dif.enableDIFPerLA) /* configure DIF */
{
OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 12 */
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ),
0);
OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 13 */
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ),
pIRequest->dif.DIFPerLAAddrLo );
OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 14 */
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ),
pIRequest->dif.DIFPerLAAddrHi);
}
else /* Not EPL or DPL */
{
OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 12 */
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ),
0);
OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 13 */
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ),
0);
OSSA_WRITE_LE_32(agRoot, pPayload, /* DWORD 14 */
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ),
0);
}
if (pIRequest->flag & AGSA_SAS_ENABLE_DIF)
{
bit32 UDTR1_UDTR0_UDT1_UDT0 = 0;
bit32 UDT5_UDT4_UDT3_UDT2 = 0;
bit32 UDTR5_UDTR4_UDTR3_UDTR2 = 0;
SA_DBG3(("saSSPStart,DIF enableRefBlockCount ref %d enableRefBlockCount %d enableCrc %d enableCrcInversion %d\n",
pIRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0,
pIRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0,
pIRequest->dif.flags & DIF_FLAG_BITS_CRC_VER ? 1 : 0,
pIRequest->dif.flags & DIF_FLAG_BITS_CRC_INV ? 1 : 0 ));
SA_DBG3(("saSSPStart,DIF initialIOSeed %X lbSize %X difAction %X\n",
pIRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? 1 : 0,
(pIRequest->dif.flags & DIF_FLAG_BITS_BLOCKSIZE_MASK) >> DIF_FLAG_BITS_BLOCKSIZE_SHIFT,
pIRequest->dif.flags & DIF_FLAG_BITS_ACTION ));
SA_DBG3(("saSSPStart,DIF udtArray %2X %2X %2X %2X %2X %2X\n",
pIRequest->dif.udtArray[0],
pIRequest->dif.udtArray[1],
pIRequest->dif.udtArray[2],
pIRequest->dif.udtArray[3],
pIRequest->dif.udtArray[4],
pIRequest->dif.udtArray[5]));
SA_DBG3(("saSSPStart,DIF udrtArray %2X %2X %2X %2X %2X %2X\n",
pIRequest->dif.udrtArray[0],
pIRequest->dif.udrtArray[1],
pIRequest->dif.udrtArray[2],
pIRequest->dif.udrtArray[3],
pIRequest->dif.udrtArray[4],
pIRequest->dif.udrtArray[5]));
SA_DBG3(("saSSPStart,DIF tagUpdateMask %X tagVerifyMask %X DIFPerLAAddrLo %X DIFPerLAAddrHi %X\n",
(pIRequest->dif.flags & DIF_FLAG_BITS_UDTVMASK) >> DIF_FLAG_BITS_UDTV_SHIFT,
(pIRequest->dif.flags & DIF_FLAG_BITS_UDTUPMASK) >> DIF_FLAG_BITS_UDTUPSHIFT,
pIRequest->dif.DIFPerLAAddrLo,
pIRequest->dif.DIFPerLAAddrHi));
DirDW4 |= AGSA_DIF_BIT;
/* DWORD 15 */
SA_DBG3(("saSSPStart, DW 15 DIF_flags 0x%08X\n", pIRequest->dif.flags ));
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_flags),
pIRequest->dif.flags);
/* Populate the UDT and UDTR bytes as necessary. */
if ((pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) != AGSA_DIF_INSERT)
{
UDTR1_UDTR0_UDT1_UDT0 = (pIRequest->dif.udtArray[1] << SHIFT8 |
pIRequest->dif.udtArray[0]);
UDT5_UDT4_UDT3_UDT2 = (pIRequest->dif.udtArray[5] << SHIFT24 |
pIRequest->dif.udtArray[4] << SHIFT16 |
pIRequest->dif.udtArray[3] << SHIFT8 |
pIRequest->dif.udtArray[2]);
}
if ((pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_INSERT ||
(pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_VERIFY_REPLACE ||
(pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_REPLACE_UDT_REPLACE_CRC)
{
UDTR1_UDTR0_UDT1_UDT0 |= (pIRequest->dif.udrtArray[1] << SHIFT24 |
pIRequest->dif.udrtArray[0] << SHIFT16 );
UDTR5_UDTR4_UDTR3_UDTR2 = (pIRequest->dif.udrtArray[5] << SHIFT24 |
pIRequest->dif.udrtArray[4] << SHIFT16 |
pIRequest->dif.udrtArray[3] << SHIFT8 |
pIRequest->dif.udrtArray[2]);
}
/* DWORD 16 is UDT3, UDT2, UDT1 and UDT0 */
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, udt),
UDTR1_UDTR0_UDT1_UDT0);
/* DWORD 17 is UDT5, UDT4, UDT3 and UDT2 */
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, udtReplacementLo),
UDT5_UDT4_UDT3_UDT2);
/* DWORD 18 is UDTR5, UDTR4, UDTR3 and UDTR2 */
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, udtReplacementHi),
UDTR5_UDTR4_UDTR3_UDTR2);
/* DWORD 19 */
/* Get IOS IOSeed enable bit */
if( pIRequest->dif.enableDIFPerLA ||
(pIRequest->dif.flags & DIF_FLAG_BITS_CUST_APP_TAG) )
{
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_seed),
((pIRequest->dif.DIFPerLARegion0SecCount << SHIFT16) |
(pIRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? pIRequest->dif.initialIOSeed : 0 )));
}
else
{
if (pIRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED)
{
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_seed),
pIRequest->dif.initialIOSeed );
}
else
{
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_seed), 0 );
}
}
}
/* configure encryption */
if (pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION)
{
SA_DBG3(("saSSPStart,ENC dekTable 0x%08X dekIndex 0x%08X\n",
pIRequest->encrypt.dekInfo.dekTable,
pIRequest->encrypt.dekInfo.dekIndex));
SA_DBG3(("saSSPStart,ENC kekIndex 0x%08X sectorSizeIndex 0x%08X cipherMode 0x%08X\n",
pIRequest->encrypt.kekIndex,
pIRequest->encrypt.sectorSizeIndex,
pIRequest->encrypt.cipherMode));
SA_DBG3(("saSSPStart,ENC keyTag_W0 0x%08X keyTag_W1 0x%08X\n",
pIRequest->encrypt.keyTag_W0,
pIRequest->encrypt.keyTag_W1));
SA_DBG3(("saSSPStart,ENC tweakVal_W0 0x%08X tweakVal_W1 0x%08X\n",
pIRequest->encrypt.tweakVal_W0,
pIRequest->encrypt.tweakVal_W1));
SA_DBG3(("saSSPStart,ENC tweakVal_W2 0x%08X tweakVal_W3 0x%08X\n",
pIRequest->encrypt.tweakVal_W2,
pIRequest->encrypt.tweakVal_W3));
DirDW4 |= AGSA_ENCRYPT_BIT;
encryptFlags = 0;
if (pIRequest->encrypt.keyTagCheck == agTRUE)
{
encryptFlags |= AGSA_ENCRYPT_KEY_TAG_BIT;
}
if( pIRequest->encrypt.cipherMode == agsaEncryptCipherModeXTS )
{
encryptFlags |= AGSA_ENCRYPT_XTS_Mode << SHIFT4;
}
encryptFlags |= pIRequest->encrypt.dekInfo.dekTable << SHIFT2;
/* Always use encryption for DIF fields, skip SKPD */
encryptFlags |= (pIRequest->encrypt.dekInfo.dekIndex & 0xFFFFFF) << SHIFT8;
/* Configure DWORD 20 */
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, encryptFlagsLo),
encryptFlags);
encryptFlags = pIRequest->encrypt.sectorSizeIndex;
encryptFlags |= (pIRequest->encrypt.kekIndex) << SHIFT5;
encryptFlags |= (pIRequest->encrypt.EncryptionPerLRegion0SecCount) << SHIFT16;
/* Configure DWORD 21 */
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, encryptFlagsHi),
encryptFlags);
/* Configure DWORD 22 */
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, keyTag_W0),
pIRequest->encrypt.keyTag_W0);
/* Configure DWORD 23 */
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, keyTag_W1),
pIRequest->encrypt.keyTag_W1);
/* Configure DWORD 24 */
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W0),
pIRequest->encrypt.tweakVal_W0);
/* Configure DWORD 25 */
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W1),
pIRequest->encrypt.tweakVal_W1);
/* Configure DWORD 26 */
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W2),
pIRequest->encrypt.tweakVal_W2);
/* Configure DWORD 27 */
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W3),
pIRequest->encrypt.tweakVal_W3);
}
/* Setup SGL */
if (pIRequest->dataLength)
{
pSgl = &(pIRequest->agSgl);
SA_DBG3(("saSSPStart:opCode %X agSgl %08x:%08x (%x/%x)\n",opCode,
pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved));
/* Get DIF PER LA flag */
DirDW4 |= (pIRequest->dif.enableDIFPerLA ? (1 << SHIFT7) : 0);
DirDW4 |= (pIRequest->encrypt.enableEncryptionPerLA ? ( 1 << SHIFT12 ) : 0);
/* Configure DWORD 4 */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dirMTlr), DirDW4);
if (opCode == OPC_INB_SSP_DIF_ENC_OPSTART)
{
/* Configure DWORD 28 */
pEncryptPayload->AddrLow0 = pSgl->sgLower;
/* Configure DWORD 29 */
pEncryptPayload->AddrHi0 = pSgl->sgUpper;
/* Configure DWORD 30 */
pEncryptPayload->Len0 = pSgl->len;
/* Configure DWORD 31 */
pEncryptPayload->E0 = pSgl->extReserved;
}
else
{
pPayload->AddrLow0 = pSgl->sgLower;
pPayload->AddrHi0 = pSgl->sgUpper;
pPayload->Len0 = pSgl->len;
pPayload->E0 = pSgl->extReserved;
}
}
else
{
/* no data transfer */
/* Configure DWORD 4 */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dirMTlr), DirDW4);
if (opCode == OPC_INB_SSP_DIF_ENC_OPSTART)
{
pEncryptPayload = (agsaSSPIniEncryptIOStartCmd_t *) pPayload;
pEncryptPayload->AddrLow0 = 0;
pEncryptPayload->AddrHi0 = 0;
pEncryptPayload->Len0 = 0;
pEncryptPayload->E0 = 0;
}
else
{
pPayload->AddrLow0 = 0;
pPayload->AddrHi0 = 0;
pPayload->Len0 = 0;
pPayload->E0 = 0;
}
}
/* post the IOMB to SPC */
#ifdef LOOPBACK_MPI
if (loopback)
ret = mpiMsgProduceOQ(circularOQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_OUB_SSP_COMP, outq, (bit8)circularQ->priority);
else
#endif /* LOOPBACK_MPI */
ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, opCode, outq, (bit8)circularQ->priority);
if (AGSA_RC_FAILURE == ret)
{
SA_DBG1(("saSSPStart, error when post SSP IOMB\n"));
ret = AGSA_RC_FAILURE;
}
}
else
{
/* additionalCdbLen is not zero and type is Ext - use EXT mode */
agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt);
agsaSSPIniExtIOStartCmd_t *pPayload = (agsaSSPIniExtIOStartCmd_t *)pMessage;
bit32 sspiul;
/*
* Most fields for the SAS IOMB have the same offset regardless of the actual IOMB used.
* Be careful with the scatter/gather lists, encryption and DIF options.
*/
/* CDB > 16 bytes */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, tag), pRequest->HTag);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, deviceId), pDevice->DeviceMapIndex);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, dataLen), pIRequest->dataLength);
/* dword (bit7-bit2) ==> bytes (bit7-bit0) */
/* setup standard CDB bytes + additional CDB bytes in length field */
sspiul = sizeof(agsaSSPCmdInfoUnit_t) +
(pIRequest->sspCmdIUExt.additionalCdbLen & 0xFC);
DirDW4 = sspiul << 16;
si_memcpy(&pPayload->SSPIu[0], &pIRequest->sspCmdIUExt, sspiul);
pPayload->SSPIuLendirMTlr = 0;
/* Mask DIR for Read/Write command */
DirDW4 |= agRequestType & AGSA_DIR_MASK;
/* set TLR */
DirDW4 |= pIRequest->flag & TLR_MASK;
if (agRequestType & AGSA_MSG)
{
/* set M bit */
DirDW4 |= AGSA_MSG_BIT;
}
/* check for skipmask operation */
if (pIRequest->flag & AGSA_SAS_ENABLE_SKIP_MASK)
{
SA_ASSERT(0, "Mode not supported");
}
/* configure DIF */
if (pIRequest->flag & AGSA_SAS_ENABLE_DIF)
{
SA_ASSERT(0, "Mode not supported");
}
/* configure encryption */
if (pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION)
{
SA_ASSERT(0, "Mode not supported");
}
/* Setup SGL */
if (pIRequest->dataLength)
{
pSgl = &(pIRequest->agSgl);
SA_DBG3(("saSSPStart: Ext mode, agSgl %08x:%08x (%x/%x)\n",
pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved));
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, SSPIuLendirMTlr), DirDW4);
if (opCode == OPC_INB_SSP_DIF_ENC_OPSTART)
{
si_memcpy((&((agsaSSPIniEncryptIOStartCmd_t *)(pPayload))->AddrLow0), pSgl, sizeof(agsaSgl_t));
}
else
{
si_memcpy((&(pPayload->SSPIu[0]) + sspiul), pSgl, sizeof(agsaSgl_t));
}
}
else
{
/* no data transfer */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, SSPIuLendirMTlr), DirDW4);
pPayload->dataLen = 0;
}
/* post the IOMB to SPC */
if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, opCode, outq,(bit8)circularQ->priority ))
{
SA_DBG1(("saSSPStart, error when post SSP Ext IOMB\n"));
ret = AGSA_RC_FAILURE;
}
}
break;
}
case AGSA_SSP_TASK_MGNT_REQ:
case AGSA_SSP_TASK_MGNT_REQ_M:
{
agsaIORequestDesc_t *pTMRequestToAbort = agNULL;
agsaSSPIniTMStartCmd_t *pPayload = (agsaSSPIniTMStartCmd_t *)pMessage;
if (agRequestType & AGSA_MSG)
{
/* set M bit */
DirDW4 = AGSA_MSG_BIT;
}
/* set DS and ADS bit */
DirDW4 |= (agRequestBody->sspTaskMgntReq.tmOption & 0x3) << 3;
/* Prepare the SSP TASK Management payload */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, tag), pRequest->HTag);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, deviceId), pDevice->DeviceMapIndex);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, relatedTag), agRequestBody->sspTaskMgntReq.tagOfTaskToBeManaged);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, TMfunction), agRequestBody->sspTaskMgntReq.taskMgntFunction);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, dsAdsMReport), DirDW4);
pPayload->lun[0] = agRequestBody->sspTaskMgntReq.lun[0];
pPayload->lun[1] = agRequestBody->sspTaskMgntReq.lun[1];
pPayload->lun[2] = agRequestBody->sspTaskMgntReq.lun[2];
pPayload->lun[3] = agRequestBody->sspTaskMgntReq.lun[3];
pPayload->lun[4] = agRequestBody->sspTaskMgntReq.lun[4];
pPayload->lun[5] = agRequestBody->sspTaskMgntReq.lun[5];
pPayload->lun[6] = agRequestBody->sspTaskMgntReq.lun[6];
pPayload->lun[7] = agRequestBody->sspTaskMgntReq.lun[7];
if (agTMRequest)
{
pTMRequestToAbort = (agsaIORequestDesc_t *)agTMRequest->sdkData;
if (pTMRequestToAbort)
{
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, relatedTag), pTMRequestToAbort->HTag);
}
}
SA_DBG1(("saSSPStart, HTAG 0x%x TM function 0x%x Tag-to-be-aborted 0x%x deviceId 0x%x\n",
pPayload->tag, pPayload->TMfunction, pPayload->relatedTag, pPayload->deviceId));
siDumpActiveIORequests(agRoot, saRoot->swConfig.maxActiveIOs);
/* post the IOMB to SPC */
if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSPINITMSTART, outq, (bit8)circularQ->priority))
{
SA_DBG1(("saSSPStart, error when post TM IOMB\n"));
ret = AGSA_RC_FAILURE;
}
break;
}
case AGSA_SSP_TGT_READ_DATA:
case AGSA_SSP_TGT_READ_GOOD_RESP:
case AGSA_SSP_TGT_WRITE_DATA:
case AGSA_SSP_TGT_WRITE_GOOD_RESP:
{
agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq);
agsaSSPTgtIOStartCmd_t *pPayload = (agsaSSPTgtIOStartCmd_t *)pMessage;
bit32 DirDW5 = 0;
/* Prepare the SSP TGT IO Start payload */
/* Configure DWORD 1 */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, tag), pRequest->HTag);
/* Configure DWORD 2 */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, deviceId), pDevice->DeviceMapIndex);
/* Configure DWORD 3 */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, dataLen), pTRequest->dataLength);
/* Configure DWORD 4 */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, dataOffset), pTRequest->offset);
SA_DBG3(("saSSPStart, sspOption %08X\n", pTRequest->sspOption ));
/* Mask DIR and AutoGR bits for Read/Write command */
DirDW5 = (agRequestType & (AGSA_DIR_MASK | AGSA_AUTO_MASK)) | (pTRequest->agTag << 16);
if (pTRequest->sspOption & SSP_OPTION_DIF )
{
bit32 UDTR1_UDTR0_UDT1_UDT0 = 0;
bit32 UDT5_UDT4_UDT3_UDT2 = 0;
bit32 UDTR5_UDTR4_UDTR3_UDTR2 = 0;
SA_DBG3(("saSSPStart,tgt DIF enableRefBlockCount ref %d enableRefBlockCount %d enableCrc %d enableCrcInversion %d\n",
pTRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0,
pTRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0,
pTRequest->dif.flags & DIF_FLAG_BITS_CRC_VER ? 1 : 0,
pTRequest->dif.flags & DIF_FLAG_BITS_CRC_INV ? 1 : 0 ));
SA_DBG3(("saSSPStart,tgt DIF initialIOSeed %X lbSize %X difAction %X\n",
pTRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? 1 : 0,
(pTRequest->dif.flags & DIF_FLAG_BITS_BLOCKSIZE_MASK ) >> DIF_FLAG_BITS_BLOCKSIZE_SHIFT,
pTRequest->dif.flags & DIF_FLAG_BITS_ACTION ));
SA_DBG3(("saSSPStart,tgt DIF udtArray %2X %2X %2X %2X %2X %2X\n",
pTRequest->dif.udtArray[0],
pTRequest->dif.udtArray[1],
pTRequest->dif.udtArray[2],
pTRequest->dif.udtArray[3],
pTRequest->dif.udtArray[4],
pTRequest->dif.udtArray[5]));
SA_DBG3(("saSSPStart,tgt DIF udrtArray %2X %2X %2X %2X %2X %2X\n",
pTRequest->dif.udrtArray[0],
pTRequest->dif.udrtArray[1],
pTRequest->dif.udrtArray[2],
pTRequest->dif.udrtArray[3],
pTRequest->dif.udrtArray[4],
pTRequest->dif.udrtArray[5]));
SA_DBG3(("saSSPStart,tgt DIF tagUpdateMask %X tagVerifyMask %X DIFPerLAAddrLo %X DIFPerLAAddrHi %X\n",
(pTRequest->dif.flags & DIF_FLAG_BITS_UDTVMASK) >> DIF_FLAG_BITS_UDTV_SHIFT,
(pTRequest->dif.flags & DIF_FLAG_BITS_UDTUPMASK) >> DIF_FLAG_BITS_UDTUPSHIFT,
pTRequest->dif.DIFPerLAAddrLo,
pTRequest->dif.DIFPerLAAddrHi));
DirDW5 |= AGSA_SSP_TGT_BITS_DEE_DIF;
SA_DBG3(("saSSPStart,tgt DW 15 DIF_flags 0x%08X\n", pTRequest->dif.flags ));
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_flags),
pTRequest->dif.flags);
/* Populate the UDT and UDTR bytes as necessary. */
if ((pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) != AGSA_DIF_INSERT)
{
UDTR1_UDTR0_UDT1_UDT0 = (pTRequest->dif.udtArray[1] << SHIFT8 |
pTRequest->dif.udtArray[0]);
UDT5_UDT4_UDT3_UDT2 = (pTRequest->dif.udtArray[5] << SHIFT24 |
pTRequest->dif.udtArray[4] << SHIFT16 |
pTRequest->dif.udtArray[3] << SHIFT8 |
pTRequest->dif.udtArray[2]);
}
if ((pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_INSERT ||
(pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_VERIFY_REPLACE ||
(pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_REPLACE_UDT_REPLACE_CRC)
{
UDTR1_UDTR0_UDT1_UDT0 |= (pTRequest->dif.udrtArray[1] << SHIFT24 |
pTRequest->dif.udrtArray[0] << SHIFT16 );
UDTR5_UDTR4_UDTR3_UDTR2 = (pTRequest->dif.udrtArray[5] << SHIFT24 |
pTRequest->dif.udrtArray[4] << SHIFT16 |
pTRequest->dif.udrtArray[3] << SHIFT8 |
pTRequest->dif.udrtArray[2]);
}
/* DWORD 8 is UDTR1, UDTR0, UDT1 and UDT0 */
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, udt),
UDTR1_UDTR0_UDT1_UDT0);
/* DWORD 9 is UDT5, UDT4, UDT3 and UDT2 */
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, udtReplacementLo),
UDT5_UDT4_UDT3_UDT2);
/* DWORD 10 is UDTR5, UDTR4, UDTR3 and UDTR2 */
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, udtReplacementHi),
UDTR5_UDTR4_UDTR3_UDTR2);
/* DWORD 11 */
/* Get IOS IOSeed enable bit */
if( pTRequest->dif.flags & DIF_FLAG_BITS_CUST_APP_TAG)
{
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_seed),
((pTRequest->dif.DIFPerLARegion0SecCount << SHIFT16) |
(pTRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? pTRequest->dif.initialIOSeed : 0 )));
}
else
{
/* Get IOS IOSeed enable bit */
if (pTRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED)
{
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_seed),
pTRequest->dif.initialIOSeed );
}
else
{
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_seed), 0 );
}
}
}
/* Mask DIR and AutoGR bits for Read/Write command */
if(pTRequest->sspOption & SSP_OPTION_AUTO_GOOD_RESPONSE)
{
DirDW5 |= AGSA_SSP_TGT_BITS_AGR;
}
/* AN, RTE, RDF bits */
DirDW5 |= (pTRequest->sspOption & SSP_OPTION_BITS) << 2;
/* ODS */
if(pTRequest->sspOption & SSP_OPTION_ODS)
{
DirDW5 |= AGSA_SSP_TGT_BITS_ODS;
}
/* Setup SGL */
if (pTRequest->dataLength)
{
pSgl = &(pTRequest->agSgl);
SA_DBG5(("saSSPStart: agSgl %08x:%08x (%x/%x)\n",
pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved));
/* set up dir on the payload */
/* Configure DWORD 5 */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, INITagAgrDir), DirDW5);
pPayload->AddrLow0 = pSgl->sgLower;
pPayload->AddrHi0 = pSgl->sgUpper;
pPayload->Len0 = pSgl->len;
pPayload->E0 = pSgl->extReserved;
}
else
{
/* no data transfer */
/* Configure DWORD 5 */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, INITagAgrDir), DirDW5);
pPayload->AddrLow0 = 0;
pPayload->AddrHi0 = 0;
pPayload->Len0 = 0;
}
/* Configure DWORD 6 */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t,reserved ), 0);
/* Build TGT IO START command and send it to SPC */
if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSPTGTIOSTART, outq, (bit8)circularQ->priority))
{
SA_DBG1(("saSSPStart, error when post TGT IOMB\n"));
ret = AGSA_RC_FAILURE;
}
break;
}
case AGSA_SSP_TGT_CMD_OR_TASK_RSP:
{
agsaSSPTargetResponse_t *pTResponse = &(agRequestBody->sspTargetResponse);
agsaSSPTgtRspStartCmd_t *pPayload = (agsaSSPTgtRspStartCmd_t *)pMessage;
bit32 ip, an, ods;
if (pTResponse->frameBuf && (pTResponse->respBufLength <= AGSA_MAX_SSPPAYLOAD_VIA_SFO))
{
ip = 1;
si_memcpy(pPayload->reserved, pTResponse->frameBuf, pTResponse->respBufLength);
}
else
{
ip = 0;
/* NOTE:
* 1. reserved field must be ZEROED out. FW depends on it
* 2. trusted interface. indirect response buffer must be valid.
*/
si_memset(pPayload->reserved, 0, sizeof(pPayload->reserved));
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, AddrLow0), pTResponse->respBufLower);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, AddrHi0), pTResponse->respBufUpper);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, Len0), pTResponse->respBufLength);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, E0), 0);
}
/* TLR setting */
an = (pTResponse->respOption & RESP_OPTION_BITS);
/* ODS */
ods = (pTResponse->respOption & RESP_OPTION_ODS);
/* Prepare the SSP TGT RESPONSE Start payload */
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, tag), pRequest->HTag);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, deviceId), pDevice->DeviceMapIndex);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, RspLen), pTResponse->respBufLength);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, INITag_IP_AN),
(pTResponse->agTag << SHIFT16) | ods | (ip << SHIFT10) | (an << SHIFT2));
/* Build TGT RESPONSE START command and send it to SPC */
if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSPTGTRSPSTART, outq, (bit8)circularQ->priority))
{
SA_DBG1(("saSSPStart, error when post TGT RSP IOMB\n"));
ret = AGSA_RC_FAILURE;
}
break;
}
default:
{
SA_DBG1(("saSSPStart, Unsupported Request IOMB\n"));
ret = AGSA_RC_FAILURE;
break;
}
}
} /* LL IOrequest available */
#ifdef SA_LL_IBQ_PROTECT
ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
#endif /* SA_LL_IBQ_PROTECT */
#ifdef SALL_API_TEST
if (ret == AGSA_RC_SUCCESS)
saRoot->LLCounters.IOCounter.numSSPStarted++;
#endif /*SALL_API_TEST */
#ifdef LOOPBACK_MPI
if (loopback)
saRoot->interruptVecIndexBitMap[0] |= (1 << outq);
#endif /* LOOPBACK_MPI */
/* goto have leave and trace point info */
smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "Sa");
ext:
OSSA_INP_LEAVE(agRoot);
return ret;
}
/******************************************************************************/
/*! \brief Abort SSP request
*
* Abort SSP request
*
* \param agRoot handles for this instance of SAS/SATA LLL
* \param queueNum
* \param agIORequest
* \param agIOToBeAborted
*
* \return If request is aborted successfully
* - \e AGSA_RC_SUCCESS request is aborted successfully
* - \e AGSA_RC_FAILURE request is not aborted successfully
*/
/*******************************************************************************/
GLOBAL bit32 saSSPAbort(
agsaRoot_t *agRoot,
agsaIORequest_t *agIORequest,
bit32 queueNum,
agsaDevHandle_t *agDevHandle,
bit32 flag,
void *abortParam,
ossaGenericAbortCB_t agCB
)
{
bit32 ret = AGSA_RC_SUCCESS, retVal;
agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
agsaIORequestDesc_t *pRequest;
agsaIORequestDesc_t *pRequestABT = NULL;
agsaDeviceDesc_t *pDevice = NULL;
agsaDeviceDesc_t *pDeviceABT = NULL;
agsaPort_t *pPort = NULL;
mpiICQueue_t *circularQ;
void *pMessage;
agsaSSPAbortCmd_t *payload;
agsaIORequest_t *agIOToBeAborted;
bit8 inq, outq;
bit32 using_reserved = agFALSE;
bit32 flag_copy = flag;
smTraceFuncEnter(hpDBG_VERY_LOUD,"Sb");
/* sanity check */
SA_ASSERT((agNULL != agRoot), "");
SA_ASSERT((agNULL != agIORequest), "");
SA_DBG2(("saSSPAbort: agIORequest %p agDevHandle %p abortParam %p flag 0x%x\n", agIORequest,agDevHandle,abortParam,flag));
/* Assign inbound and outbound Buffer */
inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
#ifdef SA_PRINTOUT_IN_WINDBG
#ifndef DBG
DbgPrint("saSSPAbort flag %d\n", flag );
#endif /* DBG */
#endif /* SA_PRINTOUT_IN_WINDBG */
if( ABORT_SINGLE == (flag & ABORT_MASK) )
{
agIOToBeAborted = (agsaIORequest_t *)abortParam;
/* Get LL IORequest entry for saSSPAbort() */
pRequest = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData);
if (agNULL == pRequest)
{
/* no pRequest found - can not Abort */
SA_DBG1(("saSSPAbort: ABORT_ALL no pRequest\n"));
smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "Sb");
return AGSA_RC_FAILURE;
}
/* Find the device the request sent to */
pDevice = pRequest->pDevice;
/* Get LL IORequest entry for IOToBeAborted */
pRequestABT = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData);
if (agNULL == pRequestABT)
{
/* The IO to Be Abort is no longer exist */
SA_DBG1(("saSSPAbort: ABORT_ALL no pRequestABT\n"));
smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "Sb");
return AGSA_RC_FAILURE;
}
/* Find the device the request Abort to */
pDeviceABT = pRequestABT->pDevice;
if (agNULL == pDeviceABT)
{
/* no deviceID - can not build IOMB */
SA_DBG1(("saSSPAbort: ABORT_ALL no pRequestABT->deviceID\n"));
smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "Sb");
return AGSA_RC_FAILURE;
}
if (agNULL != pDevice)
{
/* Find the port the request was sent to */
pPort = pDevice->pPort;
}
else
{
/* no deviceID - can not build IOMB */
SA_DBG1(("saSSPAbort: ABORT_ALL no deviceID\n"));
smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "Sb");
return AGSA_RC_FAILURE;
}
/* Get request from free IORequests */
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/
}
else
{
if (ABORT_ALL == (flag & ABORT_MASK))
{
/* abort All with Device or Port */
/* Find the outgoing port for the device */
if (agDevHandle == agNULL)
{
/* no deviceID - can not build IOMB */
SA_DBG1(("saSSPAbort: agDevHandle == agNULL!!!\n"));
return AGSA_RC_FAILURE;
}
pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
if (agNULL == pDevice)
{
/* no deviceID - can not build IOMB */
SA_DBG1(("saSSPAbort: ABORT_ALL agNULL == pDevice\n"));
return AGSA_RC_FAILURE;
}
pPort = pDevice->pPort;
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/
}
else
{
/* only support 00, 01 and 02 for flag */
SA_DBG1(("saSSPAbort: ABORT_ALL type not supported 0x%X\n",flag));
smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "Sb");
return AGSA_RC_FAILURE;
}
}
if ( agNULL == pRequest )
{
pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests));
if(agNULL != pRequest)
{
using_reserved = agTRUE;
SA_DBG2(("saSSPAbort: using saRoot->freeReservedRequests\n"));
}
else
{
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
/* If no LL IO request entry available */
SA_DBG1(("saSSPAbort: No request from free list Not using saRoot->freeReservedRequests\n"));
smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "Sb");
return AGSA_RC_BUSY;
}
}
/* If free IOMB avaliable */
/* Remove the request from free list */
if( using_reserved )
{
saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
}
else
{
saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
}
/* Add the request to the pendingIORequests list of the device */
pRequest->valid = agTRUE;
saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode));
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
/* set up pRequest */
pRequest->pIORequestContext = agIORequest;
pRequest->requestType = AGSA_SSP_REQTYPE;
pRequest->pDevice = pDevice;
pRequest->pPort = pPort;
pRequest->completionCB = (void*)agCB;
/* pRequest->abortCompletionCB = agCB;*/
pRequest->startTick = saRoot->timeTick;
/* Set request to the sdkData of agIORequest */
agIORequest->sdkData = pRequest;
/* save tag and IOrequest pointer to IOMap */
saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
#ifdef SA_LL_IBQ_PROTECT
ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
#endif /* SA_LL_IBQ_PROTECT */
/* If LL IO request entry avaliable */
/* Get a free inbound queue entry */
circularQ = &saRoot->inboundQueue[inq];
retVal = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage);
/* if message size is too large return failure */
if (AGSA_RC_FAILURE == retVal)
{
#ifdef SA_LL_IBQ_PROTECT
ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
#endif /* SA_LL_IBQ_PROTECT */
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
pRequest->valid = agFALSE;
if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
{
SA_DBG1(("saSSPAbort: saving pRequest (%p) for later use\n", pRequest));
saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
}
else
{
/* return the request to free pool */
saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
}
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
SA_DBG1(("saSSPAbort: error when get free IOMB\n"));
smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "Sb");
return AGSA_RC_FAILURE;
}
/* return busy if inbound queue is full */
if (AGSA_RC_BUSY == retVal)
{
#ifdef SA_LL_IBQ_PROTECT
ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
#endif /* SA_LL_IBQ_PROTECT */
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
pRequest->valid = agFALSE;
if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
{
SA_DBG1(("saSSPAbort: saving pRequest (%p) for later use\n", pRequest));
saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
}
else
{
/* return the request to free pool */
saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
}
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
SA_DBG1(("saSSPAbort: no more IOMB\n"));
smTraceFuncExit(hpDBG_VERY_LOUD, 'h', "Sb");
return AGSA_RC_BUSY;
}
/* setup payload */
payload = (agsaSSPAbortCmd_t*)pMessage;
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, tag), pRequest->HTag);
if( ABORT_SINGLE == (flag & ABORT_MASK) )
{
if ( agNULL == pDeviceABT )
{
SA_DBG1(("saSSPSAbort: no device\n" ));
smTraceFuncExit(hpDBG_VERY_LOUD, 'i', "Sb");
return AGSA_RC_FAILURE;
}
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, deviceId), pDeviceABT->DeviceMapIndex);
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, HTagAbort), pRequestABT->HTag);
}
else
{
/* abort all */
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, deviceId), pDevice->DeviceMapIndex);
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, HTagAbort), 0);
}
if(flag & ABORT_TSDK_QUARANTINE)
{
if(smIS_SPCV(agRoot))
{
flag_copy &= ABORT_SCOPE;
flag_copy |= ABORT_QUARANTINE_SPCV;
}
}
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, abortAll), flag_copy);
SA_DBG1(("saSSPAbort: HTag 0x%x HTagABT 0x%x deviceId 0x%x flag 0x%x\n", payload->tag, payload->HTagAbort, payload->deviceId,flag));
siCountActiveIORequestsOnDevice( agRoot, payload->deviceId );
/* post the IOMB to SPC */
ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSP_ABORT, outq, (bit8)circularQ->priority);
#ifdef SA_LL_IBQ_PROTECT
ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
#endif /* SA_LL_IBQ_PROTECT */
#ifdef SALL_API_TEST
if (AGSA_RC_SUCCESS == ret)
{
saRoot->LLCounters.IOCounter.numSSPAborted++;
}
#endif
smTraceFuncExit(hpDBG_VERY_LOUD, 'j', "Sb");
return ret;
}
#if defined(SALLSDK_DEBUG)
/******************************************************************************/
/*! \brief
*
* Dump StartSSP information
*
* Debug helper routine
*
* \return -none -
*/
/*******************************************************************************/
LOCAL void siDumpSSPStartIu(
agsaDevHandle_t *agDevHandle,
bit32 agRequestType,
agsaSASRequestBody_t *agRequestBody
)
{
switch ( agRequestType )
{
case AGSA_SSP_INIT_READ:
case AGSA_SSP_INIT_WRITE:
{
agsaSSPInitiatorRequest_t *pIRequest = &(agRequestBody->sspInitiatorReq);
SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - len=%x - attr=%x - CDB:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
agDevHandle,
(agRequestType==AGSA_SSP_INIT_READ)? "AGSA_SSP_INIT_READ" : "AGSA_SSP_INIT_WRITE",
pIRequest->dataLength,
pIRequest->sspCmdIU.efb_tp_taskAttribute,
pIRequest->sspCmdIU.cdb[0],
pIRequest->sspCmdIU.cdb[1],
pIRequest->sspCmdIU.cdb[2],
pIRequest->sspCmdIU.cdb[3],
pIRequest->sspCmdIU.cdb[4],
pIRequest->sspCmdIU.cdb[5],
pIRequest->sspCmdIU.cdb[6],
pIRequest->sspCmdIU.cdb[7],
pIRequest->sspCmdIU.cdb[8],
pIRequest->sspCmdIU.cdb[9]
));
break;
}
case AGSA_SSP_INIT_READ_EXT:
case AGSA_SSP_INIT_WRITE_EXT:
{
agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt);
SA_DBG3(("siDumpSSPStartIu: dev=%p - %s - len=%x - attr=%x - CDB:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
agDevHandle,
(agRequestType==AGSA_SSP_INIT_READ_EXT)? "AGSA_SSP_INIT_READ_EXT" : "AGSA_SSP_INIT_WRITE_EXT",
pIRequest->dataLength,
pIRequest->sspCmdIUExt.efb_tp_taskAttribute,
pIRequest->sspCmdIUExt.cdb[0],
pIRequest->sspCmdIUExt.cdb[1],
pIRequest->sspCmdIUExt.cdb[2],
pIRequest->sspCmdIUExt.cdb[3],
pIRequest->sspCmdIUExt.cdb[4],
pIRequest->sspCmdIUExt.cdb[5],
pIRequest->sspCmdIUExt.cdb[6],
pIRequest->sspCmdIUExt.cdb[7],
pIRequest->sspCmdIUExt.cdb[8],
pIRequest->sspCmdIUExt.cdb[9]
));
break;
}
case AGSA_SSP_INIT_READ_EXT_M:
case AGSA_SSP_INIT_WRITE_EXT_M:
{
agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt);
SA_DBG3(("siDumpSSPStartIu: dev=%p - %s - len=%x - attr=%x - CDB:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
agDevHandle,
(agRequestType==AGSA_SSP_INIT_READ_EXT_M)? "AGSA_SSP_INIT_READ_EXT_M" : "AGSA_SSP_INIT_WRITE_EXT_M",
pIRequest->dataLength,
pIRequest->sspCmdIUExt.efb_tp_taskAttribute,
pIRequest->sspCmdIUExt.cdb[0],
pIRequest->sspCmdIUExt.cdb[1],
pIRequest->sspCmdIUExt.cdb[2],
pIRequest->sspCmdIUExt.cdb[3],
pIRequest->sspCmdIUExt.cdb[4],
pIRequest->sspCmdIUExt.cdb[5],
pIRequest->sspCmdIUExt.cdb[6],
pIRequest->sspCmdIUExt.cdb[7],
pIRequest->sspCmdIUExt.cdb[8],
pIRequest->sspCmdIUExt.cdb[9]
));
break;
}
case AGSA_SSP_INIT_READ_INDIRECT:
case AGSA_SSP_INIT_WRITE_INDIRECT:
case AGSA_SSP_INIT_READ_INDIRECT_M:
case AGSA_SSP_INIT_WRITE_INDIRECT_M:
{
agsaSSPInitiatorRequestIndirect_t *pIRequest = &(agRequestBody->sspInitiatorReqIndirect);
SA_DBG3(("siDumpSSPStartIu: dev=%p - %s - len=%x - cdblen=%d CDB:U %08x L %08x\n",
agDevHandle,
(agRequestType==AGSA_SSP_INIT_READ_INDIRECT ||
agRequestType==AGSA_SSP_INIT_READ_INDIRECT_M) ? "AGSA_SSP_INIT_READ_INDIRECT" : "AGSA_SSP_INIT_WRITE_INDIRECT",
pIRequest->dataLength,
pIRequest->sspInitiatorReqLen,
pIRequest->sspInitiatorReqAddrUpper32,
pIRequest->sspInitiatorReqAddrLower32 ));
break;
}
case AGSA_SSP_TASK_MGNT_REQ:
{
agsaSSPScsiTaskMgntReq_t *pTaskCmd =&agRequestBody->sspTaskMgntReq;
/* copy payload */
SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - Task Function=%x - Tag to managed=%x",
agDevHandle,
"AGSA_SSP_TASK_MGNT_REQ",
pTaskCmd->taskMgntFunction,
pTaskCmd->tagOfTaskToBeManaged
));
break;
}
case AGSA_SSP_TGT_READ_DATA:
{
agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq);
SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n",
agDevHandle,
"AGSA_SSP_TGT_READ_DATA",
pTRequest->dataLength,
pTRequest->offset ));
break;
}
case AGSA_SSP_TGT_READ_GOOD_RESP:
{
agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq);
SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n",
agDevHandle,
"AGSA_SSP_TGT_READ_GOOD_RESP",
pTRequest->dataLength,
pTRequest->offset));
break;
}
case AGSA_SSP_TGT_WRITE_GOOD_RESP:
{
agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq);
SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n",
agDevHandle,
"AGSA_SSP_TGT_WRITE_GOOD_RESP",
pTRequest->dataLength,
pTRequest->offset ));
break;
}
case AGSA_SSP_TGT_WRITE_DATA:
{
agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq);
SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n",
agDevHandle,
"AGSA_SSP_TGT_WRITE_DATA",
pTRequest->dataLength,
pTRequest->offset ));
break;
}
case AGSA_SSP_TGT_CMD_OR_TASK_RSP:
{
agsaSSPTargetResponse_t *pTResponse = &(agRequestBody->sspTargetResponse);
SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - len=%x PAddr=%08x:%08x Tag=%x\n",
agDevHandle,
"AGSA_SSP_TGT_CMD_OR_TASK_RSP",
pTResponse->respBufLength,
pTResponse->respBufUpper,
pTResponse->respBufLower,
pTResponse->agTag ));
break;
}
default:
{
SA_DBG1(("siDumpSSPStartIu: dev=%p - %s %X\n",
agDevHandle,
"Unknown SSP cmd type",
agRequestType
));
break;
}
}
return;
}
#endif /* SALLSDK_DEBUG */