#include <sys/cdefs.h>
#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);
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 (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;
}
inq = INQ(queueNum);
SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
if (agRequestType & AGSA_SSP_EXT_BIT)
{
size = IOMB_SIZE96;
}
circularQ = &saRoot->inboundQueue[inq];
retVal = mpiMsgFreeGet(circularQ, size, pPayload);
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");
}
if (AGSA_RC_BUSY == retVal)
{
SA_DBG3(("siFastSSPResAlloc: no more IOMB\n"));
smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2D");
}
ret = retVal;
goto ext;
}
saLlistIORemove(&saRoot->freeIORequests, &(*pRequest)->linkNode);
saLlistIOAdd(&pDevice->pendingIORequests, &(*pRequest)->linkNode);
ext:
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
if (AGSA_RC_SUCCESS == ret)
{
saRoot->IOMap[(*pRequest)->HTag].Tag = (*pRequest)->HTag;
saRoot->IOMap[(*pRequest)->HTag].IORequest = (void *)*pRequest;
}
return ret;
}
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");
for (i = 0; i < fr->inqMax - 1; i++)
saSetIBQPI(agRoot, fr->inqList[i], fr->beforePI[fr->inqList[i]]);
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
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;
}
ior = (agsaIORequestDesc_t*)((char*)tmp -
OSSA_OFFSET_OF(agsaIORequestDesc_t, fastLink));
} while (1);
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
siFastSSPReqFree(agRoot, fr);
smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2E");
return AGSA_RC_SUCCESS;
}
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);
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;
}
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;
}
inq = INQ(fc->queueNum);
outq = OUQ(fc->queueNum);
circularQ = &saRoot->inboundQueue[inq];
SA_DBG3(("saFastSSPPrepare: deviceId %d\n", pDevice->DeviceMapIndex));
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_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;
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;
Dir = fc->agRequestType & AGSA_DIR_MASK;
Dir |= fc->flag & TLR_MASK;
if (fc->agRequestType & AGSA_MSG)
{
Dir |= AGSA_MSG_BIT;
}
if (fc->dataLength)
{
SA_DBG5(("saFastSSPPrepare: agSgl %08x:%08x (%x/%x)\n",
pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved));
si_memcpy(&pPayload->AddrLow0, pSgl, sizeof(*pSgl));
}
else
{
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;
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);
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;
Dir |= fc->agRequestType & AGSA_DIR_MASK;
Dir |= fc->flag & TLR_MASK;
if (fc->agRequestType & AGSA_MSG)
{
Dir |= AGSA_MSG_BIT;
}
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
{
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)
{
fr->beforePI[inq] = saGetIBQPI(agRoot, inq);
fr->inqList[fr->inqMax++] = inq;
}
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);
saLlistIORemove(&pDevice->pendingIORequests, &pRequest->linkNode);
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;
}
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;
}
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]);
mpiIBQMsgSend(&saRoot->inboundQueue[inq]);
}
siFastSSPReqFree(agRoot, fr);
return AGSA_RC_SUCCESS;
}
#endif
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;
bit32 encryptFlags = 0;
bit16 size = 0;
bit16 opCode = 0;
bit8 inq = 0, outq = 0;
OSSA_INP_ENTER(agRoot);
smTraceFuncEnter(hpDBG_VERY_LOUD,"Sa");
SA_ASSERT((agNULL != agRoot), "");
SA_ASSERT((agNULL != agIORequest), "");
SA_ASSERT((agNULL != agDevHandle), "");
SA_ASSERT((agNULL != agRequestBody), "");
DBG_DUMP_SSPSTART_CMDIU(agDevHandle,agRequestType,agRequestBody);
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;
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));
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
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;
}
else
{
saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
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 ));
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
(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
(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 = OPC_INB_SSPINIIOSTART;
size = IOMB_SIZE64;
break;
}
pRequest->valid = agTRUE;
pRequest->pIORequestContext = agIORequest;
pRequest->pDevice = pDevice;
pRequest->requestType = agRequestType;
pRequest->pPort = pPort;
pRequest->startTick = saRoot->timeTick;
pRequest->completionCB = agCB;
agIORequest->sdkData = pRequest;
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
#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
{
circularQ = &saRoot->inboundQueue[inq];
retVal = mpiMsgFreeGet(circularQ, size, &pMessage);
}
if (AGSA_RC_FAILURE == retVal)
{
#ifdef SA_LL_IBQ_PROTECT
ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
#endif
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;
}
if (AGSA_RC_BUSY == retVal)
{
#ifdef SA_LL_IBQ_PROTECT
ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
#endif
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;
#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);
}
else
#endif
{
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, tag), pRequest->HTag);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, deviceId), pDevice->DeviceMapIndex);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dataLen), pIRequest->dataLength);
}
#ifdef SA_TESTBASE_EXTRA
DirDW4 |= ((UINT32)pIRequest->bstIndex) << 16;
#endif
if (!(agRequestType & AGSA_SSP_INDIRECT_BIT))
{
si_memcpy(&pPayload->SSPInfoUnit, &pIRequest->sspCmdIU, sizeof(pPayload->SSPInfoUnit));
pPayload->dirMTlr = 0;
DirDW4 |= agRequestType & AGSA_DIR_MASK;
}
else
{
agsaSSPInitiatorRequestIndirect_t *pIndRequest = &(agRequestBody->sspInitiatorReqIndirect);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_0_3_indcdbalL ),pIndRequest->sspInitiatorReqAddrLower32);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_4_7_indcdbalH ),pIndRequest->sspInitiatorReqAddrUpper32 );
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_8_11 ), 0);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_12_15 ), 0);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_16_19 ), 0);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_19_23), 0);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_24_27 ), 0);
DirDW4 |= agRequestType & AGSA_DIR_MASK;
DirDW4 |= ((pIndRequest->sspInitiatorReqLen >> 2) & 0xFF) << SHIFT24;
DirDW4 |= 1 << SHIFT3;
}
DirDW4 |= pIRequest->flag & TLR_MASK;
if (agRequestType & AGSA_MSG)
{
DirDW4 |= AGSA_MSG_BIT;
}
if (pIRequest->flag & AGSA_SAS_ENABLE_SKIP_MASK)
{
DirDW4 |= AGSA_SKIP_MASK_BIT;
DirDW4 |= (pIRequest->flag & AGSA_SAS_SKIP_MASK_OFFSET) << SHIFT8;
}
if( pIRequest->encrypt.enableEncryptionPerLA && pIRequest->dif.enableDIFPerLA)
{
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ),
pIRequest->encrypt.EncryptionPerLAAddrLo );
OSSA_WRITE_LE_32(agRoot, pPayload,
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,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ),
pIRequest->encrypt.EncryptionPerLAAddrHi );
}
else if( pIRequest->encrypt.enableEncryptionPerLA)
{
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ),
pIRequest->encrypt.EncryptionPerLAAddrLo );
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ),
0);
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ),
pIRequest->encrypt.EncryptionPerLAAddrHi );
}
else if (pIRequest->dif.enableDIFPerLA)
{
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ),
0);
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ),
pIRequest->dif.DIFPerLAAddrLo );
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ),
pIRequest->dif.DIFPerLAAddrHi);
}
else
{
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ),
0);
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ),
0);
OSSA_WRITE_LE_32(agRoot, pPayload,
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;
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);
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]);
}
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, udt),
UDTR1_UDTR0_UDT1_UDT0);
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, udtReplacementLo),
UDT5_UDT4_UDT3_UDT2);
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, udtReplacementHi),
UDTR5_UDTR4_UDTR3_UDTR2);
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 );
}
}
}
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;
encryptFlags |= (pIRequest->encrypt.dekInfo.dekIndex & 0xFFFFFF) << SHIFT8;
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;
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, encryptFlagsHi),
encryptFlags);
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, keyTag_W0),
pIRequest->encrypt.keyTag_W0);
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, keyTag_W1),
pIRequest->encrypt.keyTag_W1);
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W0),
pIRequest->encrypt.tweakVal_W0);
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W1),
pIRequest->encrypt.tweakVal_W1);
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W2),
pIRequest->encrypt.tweakVal_W2);
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W3),
pIRequest->encrypt.tweakVal_W3);
}
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));
DirDW4 |= (pIRequest->dif.enableDIFPerLA ? (1 << SHIFT7) : 0);
DirDW4 |= (pIRequest->encrypt.enableEncryptionPerLA ? ( 1 << SHIFT12 ) : 0);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dirMTlr), DirDW4);
if (opCode == OPC_INB_SSP_DIF_ENC_OPSTART)
{
pEncryptPayload->AddrLow0 = pSgl->sgLower;
pEncryptPayload->AddrHi0 = pSgl->sgUpper;
pEncryptPayload->Len0 = pSgl->len;
pEncryptPayload->E0 = pSgl->extReserved;
}
else
{
pPayload->AddrLow0 = pSgl->sgLower;
pPayload->AddrHi0 = pSgl->sgUpper;
pPayload->Len0 = pSgl->len;
pPayload->E0 = pSgl->extReserved;
}
}
else
{
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;
}
}
#ifdef LOOPBACK_MPI
if (loopback)
ret = mpiMsgProduceOQ(circularOQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_OUB_SSP_COMP, outq, (bit8)circularQ->priority);
else
#endif
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
{
agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt);
agsaSSPIniExtIOStartCmd_t *pPayload = (agsaSSPIniExtIOStartCmd_t *)pMessage;
bit32 sspiul;
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);
sspiul = sizeof(agsaSSPCmdInfoUnit_t) +
(pIRequest->sspCmdIUExt.additionalCdbLen & 0xFC);
DirDW4 = sspiul << 16;
si_memcpy(&pPayload->SSPIu[0], &pIRequest->sspCmdIUExt, sspiul);
pPayload->SSPIuLendirMTlr = 0;
DirDW4 |= agRequestType & AGSA_DIR_MASK;
DirDW4 |= pIRequest->flag & TLR_MASK;
if (agRequestType & AGSA_MSG)
{
DirDW4 |= AGSA_MSG_BIT;
}
if (pIRequest->flag & AGSA_SAS_ENABLE_SKIP_MASK)
{
SA_ASSERT(0, "Mode not supported");
}
if (pIRequest->flag & AGSA_SAS_ENABLE_DIF)
{
SA_ASSERT(0, "Mode not supported");
}
if (pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION)
{
SA_ASSERT(0, "Mode not supported");
}
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
{
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, SSPIuLendirMTlr), DirDW4);
pPayload->dataLen = 0;
}
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)
{
DirDW4 = AGSA_MSG_BIT;
}
DirDW4 |= (agRequestBody->sspTaskMgntReq.tmOption & 0x3) << 3;
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);
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;
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, tag), pRequest->HTag);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, deviceId), pDevice->DeviceMapIndex);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, dataLen), pTRequest->dataLength);
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, dataOffset), pTRequest->offset);
SA_DBG3(("saSSPStart, sspOption %08X\n", pTRequest->sspOption ));
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);
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]);
}
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, udt),
UDTR1_UDTR0_UDT1_UDT0);
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, udtReplacementLo),
UDT5_UDT4_UDT3_UDT2);
OSSA_WRITE_LE_32(agRoot, pPayload,
OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, udtReplacementHi),
UDTR5_UDTR4_UDTR3_UDTR2);
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
{
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 );
}
}
}
if(pTRequest->sspOption & SSP_OPTION_AUTO_GOOD_RESPONSE)
{
DirDW5 |= AGSA_SSP_TGT_BITS_AGR;
}
DirDW5 |= (pTRequest->sspOption & SSP_OPTION_BITS) << 2;
if(pTRequest->sspOption & SSP_OPTION_ODS)
{
DirDW5 |= AGSA_SSP_TGT_BITS_ODS;
}
if (pTRequest->dataLength)
{
pSgl = &(pTRequest->agSgl);
SA_DBG5(("saSSPStart: agSgl %08x:%08x (%x/%x)\n",
pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved));
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
{
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, INITagAgrDir), DirDW5);
pPayload->AddrLow0 = 0;
pPayload->AddrHi0 = 0;
pPayload->Len0 = 0;
}
OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t,reserved ), 0);
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;
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);
}
an = (pTResponse->respOption & RESP_OPTION_BITS);
ods = (pTResponse->respOption & RESP_OPTION_ODS);
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));
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;
}
}
}
#ifdef SA_LL_IBQ_PROTECT
ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
#endif
#ifdef SALL_API_TEST
if (ret == AGSA_RC_SUCCESS)
saRoot->LLCounters.IOCounter.numSSPStarted++;
#endif
#ifdef LOOPBACK_MPI
if (loopback)
saRoot->interruptVecIndexBitMap[0] |= (1 << outq);
#endif
smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "Sa");
ext:
OSSA_INP_LEAVE(agRoot);
return ret;
}
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");
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));
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
#endif
if( ABORT_SINGLE == (flag & ABORT_MASK) )
{
agIOToBeAborted = (agsaIORequest_t *)abortParam;
pRequest = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData);
if (agNULL == pRequest)
{
SA_DBG1(("saSSPAbort: ABORT_ALL no pRequest\n"));
smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "Sb");
return AGSA_RC_FAILURE;
}
pDevice = pRequest->pDevice;
pRequestABT = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData);
if (agNULL == pRequestABT)
{
SA_DBG1(("saSSPAbort: ABORT_ALL no pRequestABT\n"));
smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "Sb");
return AGSA_RC_FAILURE;
}
pDeviceABT = pRequestABT->pDevice;
if (agNULL == pDeviceABT)
{
SA_DBG1(("saSSPAbort: ABORT_ALL no pRequestABT->deviceID\n"));
smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "Sb");
return AGSA_RC_FAILURE;
}
if (agNULL != pDevice)
{
pPort = pDevice->pPort;
}
else
{
SA_DBG1(("saSSPAbort: ABORT_ALL no deviceID\n"));
smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "Sb");
return AGSA_RC_FAILURE;
}
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
}
else
{
if (ABORT_ALL == (flag & ABORT_MASK))
{
if (agDevHandle == agNULL)
{
SA_DBG1(("saSSPAbort: agDevHandle == agNULL!!!\n"));
return AGSA_RC_FAILURE;
}
pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
if (agNULL == pDevice)
{
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
{
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);
SA_DBG1(("saSSPAbort: No request from free list Not using saRoot->freeReservedRequests\n"));
smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "Sb");
return AGSA_RC_BUSY;
}
}
if( using_reserved )
{
saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
}
else
{
saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
}
pRequest->valid = agTRUE;
saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode));
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
pRequest->pIORequestContext = agIORequest;
pRequest->requestType = AGSA_SSP_REQTYPE;
pRequest->pDevice = pDevice;
pRequest->pPort = pPort;
pRequest->completionCB = (void*)agCB;
pRequest->startTick = saRoot->timeTick;
agIORequest->sdkData = pRequest;
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
circularQ = &saRoot->inboundQueue[inq];
retVal = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage);
if (AGSA_RC_FAILURE == retVal)
{
#ifdef SA_LL_IBQ_PROTECT
ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
#endif
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
{
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;
}
if (AGSA_RC_BUSY == retVal)
{
#ifdef SA_LL_IBQ_PROTECT
ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
#endif
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
{
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;
}
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
{
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 );
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
#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)
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;
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