#include <sys/cdefs.h>
#include <dev/pms/config.h>
#include <dev/pms/freebsd/driver/common/osenv.h>
#include <dev/pms/freebsd/driver/common/ostypes.h>
#include <dev/pms/freebsd/driver/common/osdebug.h>
#include <dev/pms/RefTisa/sallsdk/api/sa.h>
#include <dev/pms/RefTisa/sallsdk/api/saapi.h>
#include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
#include <dev/pms/RefTisa/tisa/api/titypes.h>
#include <dev/pms/RefTisa/tisa/api/ostiapi.h>
#include <dev/pms/RefTisa/tisa/api/tiapi.h>
#include <dev/pms/RefTisa/tisa/api/tiglobal.h>
#ifdef FDS_SM
#include <dev/pms/RefTisa/sat/api/sm.h>
#include <dev/pms/RefTisa/sat/api/smapi.h>
#include <dev/pms/RefTisa/sat/api/tdsmapi.h>
#endif
#ifdef FDS_DM
#include <dev/pms/RefTisa/discovery/api/dm.h>
#include <dev/pms/RefTisa/discovery/api/dmapi.h>
#include <dev/pms/RefTisa/discovery/api/tddmapi.h>
#endif
#include <dev/pms/RefTisa/tisa/sassata/sas/common/tdtypes.h>
#include <dev/pms/freebsd/driver/common/osstring.h>
#include <dev/pms/RefTisa/tisa/sassata/common/tdutil.h>
#ifdef INITIATOR_DRIVER
#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdtypes.h>
#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itddefs.h>
#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdglobl.h>
#endif
#ifdef TARGET_DRIVER
#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdglobl.h>
#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdxchg.h>
#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdtypes.h>
#endif
#include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h>
#include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h>
osGLOBAL bit32
tiINIIOStart(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
void *tiRequestBody,
bit32 interruptContext
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
tdsaDeviceData_t *oneDeviceData;
agsaRoot_t *agRoot = agNULL;
agsaIORequest_t *agIORequest = agNULL;
agsaDevHandle_t *agDevHandle = agNULL;
bit32 agRequestType;
agsaSASRequestBody_t *agSASRequestBody = agNULL;
bit32 tiStatus = tiError;
bit32 saStatus = AGSA_RC_FAILURE;
tdIORequestBody_t *tdIORequestBody;
agsaSSPInitiatorRequest_t *agSSPInitiatorRequest;
#ifdef REMOVED
bit32 i;
#endif
#ifdef SATA_ENABLE
#ifndef FDS_SM
satIOContext_t *satIOContext;
#endif
#endif
#ifdef FDS_SM
smRoot_t *smRoot = &(tdsaAllShared->smRoot);
smIORequest_t *smIORequest;
smDeviceHandle_t *smDeviceHandle;
smScsiInitiatorRequest_t *smSCSIRequest;
#endif
TDSA_INP_ENTER(tiRoot);
TI_DBG6(("tiINIIOStart: start\n"));
TI_DBG6(("tiINIIOStart:: ******* tdsaRoot %p tdsaAllShared %p \n", tdsaRoot,tdsaAllShared));
oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
TI_DBG6(("tiINIIOStart: onedevicedata %p\n", oneDeviceData));
if(oneDeviceData == agNULL)
{
TI_DBG1(("tiINIIOStart: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle ));
tiStatus = tiIONoDevice;
goto ext;
}
if (oneDeviceData->valid != agTRUE || oneDeviceData->registered != agTRUE ||
oneDeviceData->tdPortContext == agNULL )
{
TI_DBG1(("tiINIIOStart: tiDeviceHandle=%p did %d DeviceData was removed\n", tiDeviceHandle, oneDeviceData->id));
TI_DBG6(("tiINIIOStart: device AddrHi 0x%08x AddrLo 0x%08x\n",
oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo));
tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
tdIORequestBody->IOCompletionFunc = itdssIOForDebugging1Completed;
TI_DBG6(("tiINIIOStart: IOCompletionFunc %p\n", tdIORequestBody->IOCompletionFunc));
tiStatus = tiIONoDevice;
goto ext;
}
#if 1
if (tiIORequest->osData == agNULL)
{
TI_DBG1(("tiINIIOStart: tiIORequest->osData is NULL, wrong\n"));
}
#endif
if (oneDeviceData->DeviceType == TD_SAS_DEVICE)
{
TI_DBG6(("tiINIIOStart: calling saSSPStart\n"));
agRoot = oneDeviceData->agRoot;
agDevHandle = oneDeviceData->agDevHandle;
tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t));
tdIORequestBody->IOCompletionFunc = itdssIOCompleted;
tdIORequestBody->tiDevHandle = tiDeviceHandle;
tdIORequestBody->tiIORequest = tiIORequest;
tiIORequest->tdData = tdIORequestBody;
tdIORequestBody->IOType.InitiatorRegIO.expDataLength
= tiScsiRequest->scsiCmnd.expDataLength;
tdIORequestBody->IOType.InitiatorRegIO.sglVirtualAddr
= tiScsiRequest->sglVirtualAddr;
tiStatus = itdssIOPrepareSGL(
tiRoot,
tdIORequestBody,
&tiScsiRequest->agSgl1,
tiScsiRequest->sglVirtualAddr
);
if (tiStatus != tiSuccess)
{
TI_DBG1(("tiINIIOStart: can't get SGL\n"));
goto ext;
}
agIORequest = &(tdIORequestBody->agIORequest);
agIORequest->osData = (void *) tdIORequestBody;
agIORequest->sdkData = agNULL;
agSASRequestBody = &(tdIORequestBody->transport.SAS.agSASRequestBody);
agSSPInitiatorRequest = &(agSASRequestBody->sspInitiatorReq);
agSSPInitiatorRequest->flag = 0;
osti_memcpy(agSSPInitiatorRequest->sspCmdIU.cdb, tiScsiRequest->scsiCmnd.cdb, 16);
osti_memcpy(agSSPInitiatorRequest->sspCmdIU.lun,
tiScsiRequest->scsiCmnd.lun.lun, 8);
agSSPInitiatorRequest->dataLength = tiScsiRequest->scsiCmnd.expDataLength;
TI_DBG6(("tiINIIOStart: tiScsiRequest->scsiCmnd.expDataLength %d\n", tiScsiRequest->scsiCmnd.expDataLength));
agSSPInitiatorRequest->firstBurstSize = 0;
if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_SIMPLE)
{
agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_SIMPLE;
}
else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_ORDERED)
{
agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_ORDERED;
}
else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_HEAD_OF_QUEUE)
{
agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_HEAD_OF_QUEUE;
}
else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_ACA)
{
agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_ACA;
}
if (tiScsiRequest->dataDirection == tiDirectionIn)
{
agRequestType = AGSA_SSP_INIT_READ;
TI_DBG6(("tiINIIOStart: READ\n"));
}
else if (tiScsiRequest->dataDirection == tiDirectionOut)
{
agRequestType = AGSA_SSP_INIT_WRITE;
TI_DBG6(("tiINIIOStart: WRITE\n"));
}
else
{
agRequestType = AGSA_REQ_TYPE_UNKNOWN;
TI_DBG1(("tiINIIOStart: unknown data direction\n"));
}
tdIORequestBody->agRequestType = agRequestType;
TI_DBG6(("tiINIIOStart: device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
TI_DBG6(("tiINIIOStart: device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
if (tdIORequestBody->IOCompletionFunc == agNULL)
{
TI_DBG1(("tiINIIOStart: Error!!!! IOCompletionFunc is NULL\n"));
}
saStatus = saSSPStart(agRoot,
agIORequest,
tdsaRotateQnumber(tiRoot, oneDeviceData),
agDevHandle,
agRequestType,
agSASRequestBody,
agNULL,
&ossaSSPCompleted);
tdIORequestBody->ioStarted = agTRUE;
tdIORequestBody->ioCompleted = agFALSE;
tdIORequestBody->reTries = 0;
if (saStatus == AGSA_RC_SUCCESS)
{
Initiator->NumIOsActive++;
tiStatus = tiSuccess;
}
else
{
tdIORequestBody->ioStarted = agFALSE;
tdIORequestBody->ioCompleted = agTRUE;
if (saStatus == AGSA_RC_BUSY)
{
TI_DBG4(("tiINIIOStart: saSSPStart busy\n"));
tiStatus = tiBusy;
}
else
{
tiStatus = tiError;
}
goto ext;
}
}
#ifdef FDS_SM
else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
{
TI_DBG5(("tiINIIOStart: calling satIOStart\n"));
TI_DBG5(("tiINIIOStart: onedevicedata did %d\n", oneDeviceData->id));
tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t));
tdIORequestBody->tiDevHandle = tiDeviceHandle;
tdIORequestBody->superIOFlag = agFALSE;
tiIORequest->tdData = tdIORequestBody;
tdIORequestBody->tiIORequest = tiIORequest;
smIORequest = (smIORequest_t *)&(tdIORequestBody->smIORequest);
smIORequest->tdData = tdIORequestBody;
smDeviceHandle = (smDeviceHandle_t *)&(oneDeviceData->smDeviceHandle);
smDeviceHandle->tdData = oneDeviceData;
smSCSIRequest = (smScsiInitiatorRequest_t *)&(tdIORequestBody->SM.smSCSIRequest);
osti_memcpy(smSCSIRequest, tiScsiRequest, sizeof(smScsiInitiatorRequest_t));
tiStatus = smIOStart(smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
interruptContext);
}
#else
else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
{
TI_DBG5(("tiINIIOStart: calling satIOStart\n"));
TI_DBG5(("tiINIIOStart: onedevicedata did %d\n", oneDeviceData->id));
#ifdef SATA_ENABLE
tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t));
tdIORequestBody->tiDevHandle = tiDeviceHandle;
tdIORequestBody->tiIORequest = tiIORequest;
tdIORequestBody->IOCompletionFunc = itdssIOForDebugging2Completed;
satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
tdIORequestBody->transport.SATA.tiSenseData.senseData = agNULL;
tdIORequestBody->transport.SATA.tiSenseData.senseLen = 0;
satIOContext->pSatDevData = &oneDeviceData->satDevData;
satIOContext->pFis =
&tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
satIOContext->pScsiCmnd = &tiScsiRequest->scsiCmnd;
satIOContext->pSense = &tdIORequestBody->transport.SATA.sensePayload;
satIOContext->pTiSenseData = &tdIORequestBody->transport.SATA.tiSenseData;
satIOContext->pTiSenseData->senseData = satIOContext->pSense;
satIOContext->tiRequestBody = tiRequestBody;
satIOContext->interruptContext = interruptContext;
satIOContext->ptiDeviceHandle = tiDeviceHandle;
satIOContext->tiScsiXchg = tiScsiRequest;
satIOContext->satIntIoContext = agNULL;
satIOContext->satOrgIOContext = agNULL;
tiIORequest->tdData = tdIORequestBody;
satIOContext->currentLBA = 0;
satIOContext->OrgTL = 0;
TI_DBG5(("tiINIIOStart: pSatDevData=%p\n", satIOContext->pSatDevData ));
tiStatus = satIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
goto ext;
#endif
}
#endif
else
{
tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
tdIORequestBody->IOCompletionFunc = itdssIOForDebugging3Completed;
TI_DBG1(("tiINIIOStart: wrong unspported Device %d\n", oneDeviceData->DeviceType));
}
ext:
TDSA_INP_LEAVE(tiRoot);
return tiStatus;
}
#ifdef FAST_IO_TEST
osGLOBAL bit32
tiINIFastIOSend(void *ioh)
{
bit32 saStatus, tiStatus;
saStatus = saFastSSPSend(ioh);
if (saStatus == AGSA_RC_SUCCESS)
tiStatus = tiSuccess;
else
tiStatus = tiError;
return tiStatus;
}
osGLOBAL bit32
tiINIFastIOCancel(void *ioh)
{
bit32 saStatus, tiStatus;
saStatus = saFastSSPCancel(ioh);
if (saStatus == AGSA_RC_SUCCESS)
tiStatus = tiSuccess;
else
tiStatus = tiError;
return tiStatus;
}
osGLOBAL void*
tiINIFastIOPrepare(
tiRoot_t *tiRoot,
void *ioHandle,
agsaFastCommand_t *fc)
{
tdsaDeviceData_t *oneDeviceData;
tiDeviceHandle_t *tiDeviceHandle = fc->devHandle;
bit32 taskAttribute = fc->taskAttribute;
void *ioh = ioHandle;
TDSA_INP_ENTER(tiRoot);
TI_DBG6(("tiINIFastIOPrepare: enter\n"));
oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
if(oneDeviceData == agNULL)
{
TI_DBG1(("tiINIFastIOPrepare: tiDeviceHandle=%p DeviceData is NULL\n",
tiDeviceHandle));
ioHandle = 0;
TD_ASSERT((0), "");
goto ext;
}
TI_DBG6(("tiINIFastIOPrepare: onedevicedata %p\n", oneDeviceData));
if (oneDeviceData->DeviceType != TD_SAS_DEVICE)
{
TI_DBG1(("tiINISuperIOSend: wrong Device %d\n", oneDeviceData->DeviceType));
ioHandle = 0;
TD_ASSERT((0), "");
goto ext;
}
fc->agRoot = oneDeviceData->agRoot;
TD_ASSERT((NULL != fc->agRoot), "");
fc->devHandle = oneDeviceData->agDevHandle;
TD_ASSERT((NULL != fc->devHandle), "");
fc->safb->oneDeviceData = oneDeviceData;
switch (taskAttribute)
{
case TASK_SIMPLE:
fc->taskAttribute = TD_TASK_SIMPLE;
break;
case TASK_ORDERED:
fc->taskAttribute = TD_TASK_ORDERED;
break;
case TASK_HEAD_OF_QUEUE:
fc->taskAttribute = TD_TASK_HEAD_OF_QUEUE;
break;
case TASK_ACA:
fc->taskAttribute = TD_TASK_ACA;
break;
}
TI_DBG3(("tiINIFastIOPrepare: data direction: %x\n", fc->agRequestType));
TI_DBG6(("tiINIFastIOPrepare: device AddrHi/Lo 0x%08x / 0x%08x\n",
oneDeviceData->SASAddressID.sasAddressHi,
oneDeviceData->SASAddressID.sasAddressLo));
fc->queueNum = tdsaRotateQnumber(tiRoot, oneDeviceData);
ioHandle = saFastSSPPrepare(ioHandle, fc, ossaFastSSPCompleted, fc->safb);
if (!ioHandle)
{
TI_DBG1(("tiINIFastIOPrepare: saSuperSSPSend error\n"));
TD_ASSERT((0), "");
}
ext:
if (ioh && !ioHandle)
{
saFastSSPCancel(ioh);
}
TI_DBG6(("tiINIFastIOPrepare: leave\n"));
TDSA_INP_LEAVE(tiRoot);
return ioHandle;
}
#endif
osGLOBAL bit32 tiINIIOStartDif(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
void *tiRequestBody,
bit32 interruptContext,
tiDif_t *difOption
)
{
return tiBusy;
}
osGLOBAL bit32
tiINISuperIOStart(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiSuperScsiInitiatorRequest_t *tiScsiRequest,
void *tiRequestBody,
bit32 interruptContext
)
{
tdsaRoot_t *tdsaRoot = agNULL;
tdsaContext_t *tdsaAllShared = agNULL;
itdsaIni_t *Initiator = agNULL;
tdsaDeviceData_t *oneDeviceData = agNULL;
tdIORequestBody_t *tdIORequestBody = agNULL;
agsaSSPInitiatorRequest_t *agSSPInitiatorRequest = agNULL;
agsaRoot_t *agRoot = agNULL;
agsaIORequest_t *agIORequest = agNULL;
agsaDevHandle_t *agDevHandle = agNULL;
agsaSASRequestBody_t *agSASRequestBody = agNULL;
bit32 tiStatus = tiError;
bit32 saStatus = AGSA_RC_FAILURE;
bit32 adjusted_length = 0;
bit32 agRequestType = 0;
agBOOLEAN needPlusDataLenAdjustment = agFALSE;
agBOOLEAN needMinusDataLenAdjustment = agFALSE;
#ifdef SATA_ENABLE
#ifndef FDS_SM
satIOContext_t *satIOContext;
#endif
#endif
#ifdef FDS_SM
smRoot_t *smRoot;
smIORequest_t *smIORequest;
smDeviceHandle_t *smDeviceHandle;
smSuperScsiInitiatorRequest_t *smSuperSCSIRequest;
#endif
#ifdef CCBUILD_INDIRECT_CDB
agsaSSPInitiatorRequestIndirect_t *agSSPInitiatorIndRequest = agNULL;
#endif
TD_ASSERT(tiRoot , "tiRoot");
TD_ASSERT(tiIORequest, "tiIORequest");
TD_ASSERT(tiDeviceHandle, "tiDeviceHandle");
TD_ASSERT(tiRequestBody, "tiRequestBody");
TD_ASSERT(tiRoot->tdData, "tiRoot->tdData");
TD_ASSERT(tiDeviceHandle, "tiDeviceHandle");
tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
TD_ASSERT(tdsaRoot, "tdsaRoot");
tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
TD_ASSERT(tdsaAllShared, "tdsaAllShared");
Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
TD_ASSERT(Initiator, "Initiator");
oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
TD_ASSERT(oneDeviceData, "oneDeviceData");
#ifdef FDS_SM
smRoot = &(tdsaAllShared->smRoot);
TD_ASSERT(smRoot , "smRoot");
#endif
TI_DBG6(("tiINISuperIOStart: start\n"));
TI_DBG6(("tiINISuperIOStart:: ******* tdsaRoot %p tdsaAllShared %p \n", tdsaRoot,tdsaAllShared));
TI_DBG6(("tiINISuperIOStart: onedevicedata %p\n", oneDeviceData));
if (oneDeviceData == agNULL)
{
TI_DBG1(("tiINISuperIOStart: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle ));
return tiIONoDevice;
}
if (oneDeviceData->valid != agTRUE || oneDeviceData->registered != agTRUE ||
oneDeviceData->tdPortContext == agNULL )
{
TI_DBG1(("tiINISuperIOStart: tiDeviceHandle=%p did %d DeviceData was removed\n", tiDeviceHandle, oneDeviceData->id));
TI_DBG6(("tiINISuperIOStart: device AddrHi 0x%08x AddrLo 0x%08x\n",
oneDeviceData->SASAddressID.sasAddressHi, oneDeviceData->SASAddressID.sasAddressLo));
tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
tdIORequestBody->IOCompletionFunc = itdssIOForDebugging1Completed;
TI_DBG6(("tiINISuperIOStart: IOCompletionFunc %p\n", tdIORequestBody->IOCompletionFunc));
return tiIONoDevice;
}
#ifdef DBG
if (tiIORequest->osData == agNULL)
{
TI_DBG1(("tiINISuperIOStart: tiIORequest->osData is NULL, wrong\n"));
return tiError;
}
#endif
if (oneDeviceData->DeviceType == TD_SAS_DEVICE)
{
TI_DBG3(("tiINISuperIOStart: calling saSSPStart\n"));
agRoot = oneDeviceData->agRoot;
agDevHandle = oneDeviceData->agDevHandle;
tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
tdIORequestBody->IOCompletionFunc = itdssIOCompleted;
tdIORequestBody->tiDevHandle = tiDeviceHandle;
tdIORequestBody->tiIORequest = tiIORequest;
tiIORequest->tdData = tdIORequestBody;
tdIORequestBody->IOType.InitiatorRegIO.expDataLength
= tiScsiRequest->scsiCmnd.expDataLength;
tdIORequestBody->IOType.InitiatorRegIO.sglVirtualAddr
= tiScsiRequest->sglVirtualAddr;
agIORequest = &(tdIORequestBody->agIORequest);
agIORequest->osData = (void *) tdIORequestBody;
agSASRequestBody = &(tdIORequestBody->transport.SAS.agSASRequestBody);
agSSPInitiatorRequest = &(agSASRequestBody->sspInitiatorReq);
agSSPInitiatorRequest->flag = 0;
if (tiScsiRequest->flags & TI_SCSI_INITIATOR_ENCRYPT)
{
TI_DBG3(("tiINISuperIOStart: TI_SCSI_INITIATOR_ENCRYPT\n"));
agSSPInitiatorRequest->flag |= AGSA_SAS_ENABLE_ENCRYPTION;
TD_ASSERT( sizeof(tiEncrypt_t) == sizeof(agsaEncrypt_t) , "sizeof(tiEncrypt_t) == sizeof(agsaEncrypt_t)");
osti_memcpy(&agSSPInitiatorRequest->encrypt, &tiScsiRequest->Encrypt, sizeof(agsaEncrypt_t));
}
if ((tiScsiRequest->flags & TI_SCSI_INITIATOR_DIF) &&
(tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_READ_10 ||
tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_WRITE_10 ||
tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_WRITE_6 ||
tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_READ_6 ||
tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_READ_12 ||
tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_WRITE_12 ||
tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_WRITE_16 ||
tiScsiRequest->scsiCmnd.cdb[0] == SCSIOPC_READ_16 ))
{
TI_DBG3(("tiINISuperIOStart: TI_SCSI_INITIATOR_DIF\n"));
agSSPInitiatorRequest->flag |= AGSA_SAS_ENABLE_DIF;
osti_memcpy(&agSSPInitiatorRequest->dif, &tiScsiRequest->Dif, sizeof(agsaDif_t));
switch (tiScsiRequest->dataDirection)
{
case tiDirectionOut:
break;
case tiDirectionIn:
if ((agSSPInitiatorRequest->dif.flags & DIF_ACTION_FLAG_MASK) == DIF_INSERT)
{
needPlusDataLenAdjustment = agTRUE;
}
break;
}
if (needPlusDataLenAdjustment == agTRUE)
{
adjusted_length = tiScsiRequest->scsiCmnd.expDataLength;
adjusted_length += (adjusted_length/512) * 8;
agSSPInitiatorRequest->dataLength = adjusted_length;
}
else if (needMinusDataLenAdjustment == agTRUE)
{
adjusted_length = tiScsiRequest->scsiCmnd.expDataLength;
adjusted_length -= (adjusted_length/520) * 8;
agSSPInitiatorRequest->dataLength = adjusted_length;
}
else
{
agSSPInitiatorRequest->dataLength = tiScsiRequest->scsiCmnd.expDataLength;
}
tiStatus = itdssIOPrepareSGL(
tiRoot,
tdIORequestBody,
&tiScsiRequest->agSgl1,
tiScsiRequest->sglVirtualAddr
);
TI_DBG2(("tiINISuperIOStart:TI_SCSI_INITIATOR_DIF needMinusDataLenAdjustment %d needPlusDataLenAdjustment %d difAction %X\n",
needMinusDataLenAdjustment,
needPlusDataLenAdjustment,
agSSPInitiatorRequest->dif.flags & DIF_ACTION_FLAG_MASK));
}
else
{
agSSPInitiatorRequest->dataLength = tiScsiRequest->scsiCmnd.expDataLength;
tiStatus = itdssIOPrepareSGL(
tiRoot,
tdIORequestBody,
&tiScsiRequest->agSgl1,
tiScsiRequest->sglVirtualAddr
);
}
if (tiStatus != tiSuccess)
{
TI_DBG1(("tiINISuperIOStart: can't get SGL\n"));
return tiStatus;
}
TI_DBG6(("tiINISuperIOStart: tiScsiRequest->scsiCmnd.expDataLength %d\n", tiScsiRequest->scsiCmnd.expDataLength));
if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_SIMPLE)
{
agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_SIMPLE;
}
else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_ORDERED)
{
agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_ORDERED;
}
else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_HEAD_OF_QUEUE)
{
agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_HEAD_OF_QUEUE;
}
else if (tiScsiRequest->scsiCmnd.taskAttribute == TASK_ACA)
{
agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute = (bit8)
agSSPInitiatorRequest->sspCmdIU.efb_tp_taskAttribute | TD_TASK_ACA;
}
osti_memcpy(agSSPInitiatorRequest->sspCmdIU.cdb, tiScsiRequest->scsiCmnd.cdb, 16);
osti_memcpy(agSSPInitiatorRequest->sspCmdIU.lun, tiScsiRequest->scsiCmnd.lun.lun, 8);
#ifdef CCBUILD_INDIRECT_CDB
if (tiScsiRequest->flags & TI_SCSI_INITIATOR_INDIRECT_CDB)
{
if (tiScsiRequest->dataDirection == tiDirectionIn)
{
agRequestType = AGSA_SSP_INIT_READ_INDIRECT;
TI_DBG6(("tiINISuperIOStart: Indirect READ\n"));
}
else if (tiScsiRequest->dataDirection == tiDirectionOut)
{
agRequestType = AGSA_SSP_INIT_WRITE_INDIRECT;
TI_DBG6(("tiINISuperIOStart: Indirect WRITE\n"));
}
else
{
agRequestType = AGSA_REQ_TYPE_UNKNOWN;
TI_DBG1(("tiINISuperIOStart: unknown data direction\n"));
}
agSSPInitiatorIndRequest = &(agSASRequestBody->sspInitiatorReqIndirect);
osti_memcpy(tiScsiRequest->IndCDBBuffer, &agSSPInitiatorRequest->sspCmdIU, sizeof(agsaSSPCmdInfoUnit_t));
agSSPInitiatorIndRequest->sspInitiatorReqAddrLower32 = tiScsiRequest->IndCDBLowAddr;
agSSPInitiatorIndRequest->sspInitiatorReqAddrUpper32 = tiScsiRequest->IndCDBHighAddr;
agSSPInitiatorIndRequest->sspInitiatorReqLen = sizeof(agsaSSPCmdInfoUnit_t);
}
else
#endif
{
if (tiScsiRequest->dataDirection == tiDirectionIn)
{
agRequestType = AGSA_SSP_INIT_READ;
TI_DBG6(("tiINISuperIOStart: READ\n"));
}
else if (tiScsiRequest->dataDirection == tiDirectionOut)
{
agRequestType = AGSA_SSP_INIT_WRITE;
TI_DBG6(("tiINISuperIOStart: WRITE\n"));
}
else
{
agRequestType = AGSA_REQ_TYPE_UNKNOWN;
TI_DBG1(("tiINISuperIOStart: unknown data direction\n"));
}
}
tdIORequestBody->agRequestType = agRequestType;
TI_DBG6(("tiINISuperIOStart: device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
TI_DBG6(("tiINISuperIOStart: device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
#ifdef DBG
if (tdIORequestBody->IOCompletionFunc == agNULL)
{
TI_DBG1(("tiINISuperIOStart: Error!!!! IOCompletionFunc is NULL\n"));
return tiError;
}
#endif
saStatus = saSSPStart(agRoot,
agIORequest,
tdsaRotateQnumber(tiRoot, oneDeviceData),
agDevHandle,
agRequestType,
agSASRequestBody,
agNULL,
&ossaSSPCompleted);
if (saStatus == AGSA_RC_SUCCESS)
{
Initiator->NumIOsActive++;
tdIORequestBody->ioStarted = agTRUE;
tdIORequestBody->ioCompleted = agFALSE;
tiStatus = tiSuccess;
}
else
{
tdIORequestBody->ioStarted = agFALSE;
tdIORequestBody->ioCompleted = agTRUE;
if (saStatus == AGSA_RC_BUSY)
{
TI_DBG4(("tiINISuperIOStart: saSSPStart busy\n"));
tiStatus = tiBusy;
}
else
{
tiStatus = tiError;
}
return tiStatus;
}
}
#ifdef FDS_SM
else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
{
TI_DBG5(("tiINISuperIOStart: calling satIOStart\n"));
TI_DBG5(("tiINISuperIOStart: onedevicedata did %d\n", oneDeviceData->id));
TI_DBG5(("tiINISuperIOStart: SATA sasAddressHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
TI_DBG5(("tiINISuperIOStart: SATA sasAddressLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
tdIORequestBody->tiDevHandle = tiDeviceHandle;
tdIORequestBody->superIOFlag = agTRUE;
tiIORequest->tdData = tdIORequestBody;
tdIORequestBody->tiIORequest = tiIORequest;
smIORequest = (smIORequest_t *)&(tdIORequestBody->smIORequest);
smIORequest->tdData = tdIORequestBody;
smIORequest->smData = &tdIORequestBody->smIORequestBody;
smDeviceHandle = (smDeviceHandle_t *)&(oneDeviceData->smDeviceHandle);
smDeviceHandle->tdData = oneDeviceData;
smSuperSCSIRequest = (smSuperScsiInitiatorRequest_t *)&(tdIORequestBody->SM.smSuperSCSIRequest);
osti_memcpy(smSuperSCSIRequest, tiScsiRequest, sizeof(smSuperScsiInitiatorRequest_t));
tiStatus = smSuperIOStart(smRoot,
smIORequest,
smDeviceHandle,
smSuperSCSIRequest,
oneDeviceData->SASAddressID.sasAddressHi,
oneDeviceData->SASAddressID.sasAddressLo,
interruptContext);
}
#else
else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
{
TI_DBG5(("tiINISuperIOStart: calling satIOStart\n"));
TI_DBG5(("tiINISuperIOStart: onedevicedata did %d\n", oneDeviceData->id));
#ifdef SATA_ENABLE
tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
osti_memset(tdIORequestBody, 0, sizeof(tdIORequestBody_t));
tdIORequestBody->tiDevHandle = tiDeviceHandle;
tdIORequestBody->tiIORequest = tiIORequest;
tdIORequestBody->IOCompletionFunc = itdssIOForDebugging2Completed;
satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
tdIORequestBody->transport.SATA.tiSenseData.senseData = agNULL;
tdIORequestBody->transport.SATA.tiSenseData.senseLen = 0;
satIOContext->pSatDevData = &oneDeviceData->satDevData;
satIOContext->pFis =
&tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
satIOContext->pScsiCmnd = &tiScsiRequest->scsiCmnd;
satIOContext->pSense = &tdIORequestBody->transport.SATA.sensePayload;
satIOContext->pTiSenseData = &tdIORequestBody->transport.SATA.tiSenseData;
satIOContext->pTiSenseData->senseData = satIOContext->pSense;
satIOContext->tiRequestBody = tiRequestBody;
satIOContext->interruptContext = interruptContext;
satIOContext->ptiDeviceHandle = tiDeviceHandle;
satIOContext->tiScsiXchg = tiScsiRequest;
satIOContext->superIOFlag = agTRUE;
satIOContext->satIntIoContext = agNULL;
satIOContext->satOrgIOContext = agNULL;
tiIORequest->tdData = tdIORequestBody;
satIOContext->currentLBA = 0;
satIOContext->OrgTL = 0;
TI_DBG5(("tiINISuperIOStart: pSatDevData=%p\n", satIOContext->pSatDevData ));
tiStatus = satIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
satIOContext->tiScsiXchg,
satIOContext);
return tiStatus;
#endif
}
#endif
else
{
tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
tdIORequestBody->IOCompletionFunc = itdssIOForDebugging3Completed;
TI_DBG1(("tiINISuperIOStart: wrong unspported Device %d\n", oneDeviceData->DeviceType));
}
return tiStatus;
}
osGLOBAL bit32
tiINISMPStart(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiSMPFrame_t *tiSMPFrame,
void *tiSMPBody,
bit32 interruptContext
)
{
tdsaDeviceData_t *oneDeviceData;
agsaIORequest_t *agIORequest = agNULL;
tdIORequestBody_t *tdSMPRequestBody = agNULL;
agsaRoot_t *agRoot = agNULL;
agsaDevHandle_t *agDevHandle = agNULL;
agsaSASRequestBody_t *agRequestBody = agNULL;
agsaSMPFrame_t *agSMPFrame = agNULL;
bit32 agRequestType;
bit32 tiStatus = tiError;
bit32 saStatus = AGSA_RC_FAILURE;
bit32 queueNum;
TDSA_INP_ENTER(tiRoot);
TI_DBG6(("tiINISMPStart: start\n"));
oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
TI_DBG6(("tiINISMPStart: onedevicedata %p\n", oneDeviceData));
TI_DBG6(("tiINISMPStart: tiDeviceHandle %p\n", tiDeviceHandle));
if (oneDeviceData == agNULL)
{
TI_DBG1(("tiINISMPStart: tiDeviceHandle=%p Expander DeviceData is NULL\n", tiDeviceHandle ));
return tiError;
}
if (tiIORequest->osData == agNULL)
{
TI_DBG1(("tiINISMPStart: tiIORequest->osData is NULL, wrong\n"));
return tiError;
}
agRoot = oneDeviceData->agRoot;
agDevHandle = oneDeviceData->agDevHandle;
tdSMPRequestBody = (tdIORequestBody_t *)tiSMPBody;
tdSMPRequestBody->tiIORequest = tiIORequest;
tiIORequest->tdData = tdSMPRequestBody;
agIORequest = &(tdSMPRequestBody->agIORequest);
agIORequest->osData = (void *) tdSMPRequestBody;
agRequestBody = &(tdSMPRequestBody->transport.SAS.agSASRequestBody);
agSMPFrame = &(agRequestBody->smpFrame);
if (!DEVICE_IS_SMP_TARGET(oneDeviceData))
{
TI_DBG1(("tiINISMPStart: Target Device is not SMP device\n"));
return tiError;
}
if (tiSMPFrame->flag == 0)
{
TI_DBG6(("tiINISMPStart: Direct SMP\n"));
agSMPFrame->outFrameBuf = tiSMPFrame->outFrameBuf;
agSMPFrame->outFrameLen = tiSMPFrame->outFrameLen;
tdhexdump("tiINISMPStart agSMPFrame", (bit8 *)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen);
agSMPFrame->expectedRespLen = tiSMPFrame->expectedRespLen;
agSMPFrame->inFrameLen = 0;
agSMPFrame->flag = tiSMPFrame->flag;
agRequestType = AGSA_SMP_INIT_REQ;
queueNum = 0;
saStatus = saSMPStart(agRoot,
agIORequest,
queueNum,
agDevHandle,
agRequestType,
agRequestBody,
&ossaSMPCAMCompleted
);
if (saStatus == AGSA_RC_SUCCESS)
{
tiStatus = tiSuccess;
}
else
{
if (saStatus == AGSA_RC_BUSY)
{
TI_DBG1(("tiINISMPStart: saSSPStart busy\n"));
tiStatus = tiBusy;
}
else
{
TI_DBG1(("tiINISMPStart: saSSPStart error\n"));
tiStatus = tiError;
}
return tiStatus;
}
}
else
{
TI_DBG1(("tiINISMPStart: Indirect SMP! Not supported yet\n"));
tiStatus = tiError;
}
return tiStatus;
}
#ifdef TD_INT_COALESCE
osGLOBAL bit32
tiINIIOStartIntCoalesce(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
void *tiRequestBody,
bit32 interruptContext,
tiIntCoalesceContext_t *tiIntCoalesceCxt
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
tdsaDeviceData_t *oneDeviceData;
agsaRoot_t *agRoot = agNULL;
agsaIORequest_t *agIORequest = agNULL;
agsaDevHandle_t *agDevHandle = agNULL;
bit32 agRequestType;
agsaSASRequestBody_t *agSASRequestBody = agNULL;
bit32 tiStatus = tiError;
bit32 saStatus = AGSA_RC_FAILURE;
tdIORequestBody_t *tdIORequestBody;
agsaSSPInitiatorRequest_t *agSSPInitiatorRequest;
tdsaIntCoalesceContext_t *tdsaIntCoalCxt;
agsaIntCoalesceContext_t *agIntCoalCxt;
TI_DBG1(("tiINIIOStartIntCoalesce: start\n"));
oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
TI_DBG6(("tiINIIOStartIntCoalesce: onedevicedata %p\n", oneDeviceData));
if(oneDeviceData == agNULL)
{
TI_DBG1(("tiINIIOStartIntCoalesce: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle ));
return tiIONoDevice;
}
if (oneDeviceData->DeviceType == TD_SAS_DEVICE)
{
TI_DBG6(("tiINIIOStartIntCoalesce: calling saSSPStart\n"));
agRoot = oneDeviceData->agRoot;
agDevHandle = oneDeviceData->agDevHandle;
tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
tdIORequestBody->IOCompletionFunc = itdssIOCompleted;
tdIORequestBody->tiDevHandle = tiDeviceHandle;
tdIORequestBody->tiIORequest = tiIORequest;
tiIORequest->tdData = tdIORequestBody;
tdIORequestBody->IOType.InitiatorRegIO.expDataLength
= tiScsiRequest->scsiCmnd.expDataLength;
tiStatus = itdssIOPrepareSGL(
tiRoot,
tdIORequestBody,
&tiScsiRequest->agSgl1,
tiScsiRequest->sglVirtualAddr
);
if (tiStatus != tiSuccess)
{
TI_DBG1(("tiINIIOStartIntCoalesce: can't get SGL\n"));
return tiStatus;
}
agIORequest = &(tdIORequestBody->agIORequest);
agIORequest->osData = (void *) tdIORequestBody;
agIORequest->sdkData = agNULL;
agSASRequestBody = &(tdIORequestBody->transport.SAS.agSASRequestBody);
agSSPInitiatorRequest = &(agSASRequestBody->sspInitiatorReq);
osti_memcpy(agSSPInitiatorRequest->sspCmdIU.cdb, tiScsiRequest->scsiCmnd.cdb, 16);
osti_memcpy(agSSPInitiatorRequest->sspCmdIU.lun,
tiScsiRequest->scsiCmnd.lun.lun, 8);
agSSPInitiatorRequest->dataLength = tiScsiRequest->scsiCmnd.expDataLength;
TI_DBG6(("tiINIIOStartIntCoalesce: tiScsiRequest->scsiCmnd.expDataLength %d\n", tiScsiRequest->scsiCmnd.expDataLength));
agSSPInitiatorRequest->firstBurstSize = 0;
if (tiScsiRequest->dataDirection == tiDirectionIn)
{
agRequestType = AGSA_SSP_INIT_READ;
TI_DBG6(("tiINIIOStartIntCoalesce: READ\n"));
}
else if (tiScsiRequest->dataDirection == tiDirectionOut)
{
agRequestType = AGSA_SSP_INIT_WRITE;
TI_DBG6(("tiINIIOStartIntCoalesce: WRITE\n"));
}
else
{
agRequestType = AGSA_REQ_TYPE_UNKNOWN;
TI_DBG1(("tiINIIOStartIntCoalesce: unknown data direction\n"));
}
tdIORequestBody->agRequestType = agRequestType;
tdsaIntCoalCxt = (tdsaIntCoalesceContext_t *)tiIntCoalesceCxt->tdData;
agIntCoalCxt = &(tdsaIntCoalCxt->agIntCoalCxt);
#ifdef LL_INT_COALESCE
saStatus = saSSPStartIntCoalesce(agRoot,
agIORequest,
agIntCoalCxt,
agDevHandle,
agRequestType,
agSASRequestBody,
&ossaSSPCompleted);
#endif
tdIORequestBody->ioStarted = agTRUE;
tdIORequestBody->ioCompleted = agFALSE;
if (saStatus == AGSA_RC_SUCCESS)
{
Initiator->NumIOsActive++;
tiStatus = tiSuccess;
}
else
{
TI_DBG1(("tiINIIOStartIntCoalesce: saSSPStart failed\n"));
tdIORequestBody->ioStarted = agFALSE;
tdIORequestBody->ioCompleted = agTRUE;
if (saStatus == AGSA_RC_BUSY)
{
tiStatus = tiBusy;
}
else
{
tiStatus = tiError;
}
return tiStatus;
}
}
else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
{
TI_DBG1(("tiINIIOStartIntCoalesce: SATA not supported yet\n"));
return tiStatus;
}
else
{
TI_DBG1(("tiINIIOStartIntCoalesce: wrong unspported Device %d\n", oneDeviceData->DeviceType));
}
return tiStatus;
}
osGLOBAL bit32
tiINIIOStartIntCoalesceDif(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
void *tiRequestBody,
bit32 interruptContext,
tiIntCoalesceContext_t *tiIntCoalesceCxt,
tiDif_t *difOption
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
tdsaDeviceData_t *oneDeviceData;
agsaRoot_t *agRoot = agNULL;
agsaIORequest_t *agIORequest = agNULL;
agsaDevHandle_t *agDevHandle = agNULL;
bit32 agRequestType;
agsaDifSSPRequestBody_t *agEdcSSPRequestBody = agNULL;
bit32 tiStatus = tiError;
bit32 saStatus = AGSA_RC_FAILURE;
tdIORequestBody_t *tdIORequestBody;
agsaDifSSPInitiatorRequest_t *agEdcSSPInitiatorRequest;
agsaDif_t *agEdc;
bit32 agUpdateMask = 0;
bit32 agVerifyMask = 0;
tdsaIntCoalesceContext_t *tdsaIntCoalCxt;
agsaIntCoalesceContext_t *agIntCoalCxt;
TI_DBG1(("tiINIIOStartIntCoalesceDif: start\n"));
oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
TI_DBG6(("tiINIIOStartIntCoalesceDif: onedevicedata %p\n", oneDeviceData));
if(oneDeviceData == agNULL)
{
TI_DBG1(("tiINIIOStartIntCoalesceDif: tiDeviceHandle=%p DeviceData is NULL\n", tiDeviceHandle ));
return tiIONoDevice;
}
if (oneDeviceData->DeviceType == TD_SAS_DEVICE)
{
TI_DBG6(("tiINIIOStartIntCoalesceDif: calling saSSPStart\n"));
agRoot = oneDeviceData->agRoot;
agDevHandle = oneDeviceData->agDevHandle;
tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
tdIORequestBody->IOCompletionFunc = itdssIOCompleted;
tdIORequestBody->tiDevHandle = tiDeviceHandle;
tdIORequestBody->tiIORequest = tiIORequest;
tiIORequest->tdData = tdIORequestBody;
tdIORequestBody->IOType.InitiatorRegIO.expDataLength
= tiScsiRequest->scsiCmnd.expDataLength;
tiStatus = itdssIOPrepareSGL(
tiRoot,
tdIORequestBody,
&tiScsiRequest->agSgl1,
tiScsiRequest->sglVirtualAddr
);
if (tiStatus != tiSuccess)
{
TI_DBG1(("tiINIIOStartIntCoalesceDif: can't get SGL\n"));
return tiStatus;
}
agIORequest = &(tdIORequestBody->agIORequest);
agIORequest->osData = (void *) tdIORequestBody;
agIORequest->sdkData = agNULL;
agEdcSSPRequestBody = &(tdIORequestBody->transport.SAS.agEdcSSPRequestBody);
agEdcSSPInitiatorRequest = &(agEdcSSPRequestBody->edcSSPInitiatorReq);
osti_memcpy(agEdcSSPInitiatorRequest->sspCmdIU.cdb, tiScsiRequest->scsiCmnd.cdb, 16);
osti_memcpy(agEdcSSPInitiatorRequest->sspCmdIU.lun,
tiScsiRequest->scsiCmnd.lun.lun, 8);
agEdcSSPInitiatorRequest->dataLength = tiScsiRequest->scsiCmnd.expDataLength;
TI_DBG6(("tiINIIOStartIntCoalesceDif: tiScsiRequest->scsiCmnd.expDataLength %d\n", tiScsiRequest->scsiCmnd.expDataLength));
agEdcSSPInitiatorRequest->firstBurstSize = 0;
if (tiScsiRequest->dataDirection == tiDirectionIn)
{
agRequestType = AGSA_SSP_INIT_READ;
TI_DBG1(("tiINIIOStartIntCoalesceDif: READ difAction %X\n",difOption->difAction));
}
else if (tiScsiRequest->dataDirection == tiDirectionOut)
{
agRequestType = AGSA_SSP_INIT_WRITE;
TI_DBG1(("tiINIIOStartIntCoalesceDif: WRITE difAction %X\n",difOption->difAction));
}
else
{
agRequestType = AGSA_REQ_TYPE_UNKNOWN;
TI_DBG1(("tiINIIOStartIntCoalesceDif: unknown data direction\n"));
}
tdIORequestBody->agRequestType = agRequestType;
tdsaIntCoalCxt = (tdsaIntCoalesceContext_t *)tiIntCoalesceCxt->tdData;
agIntCoalCxt = &(tdsaIntCoalCxt->agIntCoalCxt);
agEdc = &(agEdcSSPInitiatorRequest->edc);
osti_memset(agEdc, 0, sizeof(agsaDif_t));
if (difOption->enableBlockCount)
{
agEdc->edcFlag = agEdc->edcFlag | 0x20;
}
if (difOption->enableCrc)
{
agEdc->edcFlag = agEdc->edcFlag | 0x40;
}
if (difOption->enableIOSeed)
{
}
if (difOption->difAction == DIF_INSERT)
{
agEdc->edcFlag = agEdc->edcFlag & 0xFFFFFFF8;
}
else if (difOption->difAction == DIF_VERIFY_FORWARD)
{
agEdc->edcFlag = agEdc->edcFlag | 0x01;
}
else if (difOption->difAction == DIF_VERIFY_DELETE)
{
agEdc->edcFlag = agEdc->edcFlag | 0x02;
}
else
{
agEdc->edcFlag = agEdc->edcFlag | 0x04;
}
agUpdateMask = (difOption->tagUpdateMask) & 0x3F;
agUpdateMask = agUpdateMask << 16;
agEdc->edcFlag = agEdc->edcFlag | agUpdateMask;
agVerifyMask = (difOption->tagVerifyMask) & 0x3F;
agVerifyMask = agVerifyMask << 24;
agEdc->edcFlag = agEdc->edcFlag | agVerifyMask;
agEdc->appTag = difOption->udtArray[0];
agEdc->appTag = (agEdc->appTag << 8) | difOption->udtArray[1];
agEdc->lbaReferenceTag = difOption->udtArray[2];
agEdc->lbaReferenceTag = (agEdc->lbaReferenceTag << 8) | difOption->udtArray[3];
agEdc->lbaReferenceTag = (agEdc->lbaReferenceTag << 8) | difOption->udtArray[4];
agEdc->lbaReferenceTag = (agEdc->lbaReferenceTag << 8) | difOption->udtArray[5];
agEdc->lbSize = 512;
#ifdef LL_INT_COALESCE
saStatus = saSSPStartIntCoalesceEdc(agRoot,
agIORequest,
agIntCoalCxt,
agDevHandle,
agRequestType,
agEdcSSPRequestBody,
&ossaSSPCompleted);
#endif
tdIORequestBody->ioStarted = agTRUE;
tdIORequestBody->ioCompleted = agFALSE;
if (saStatus == AGSA_RC_SUCCESS)
{
Initiator->NumIOsActive++;
tiStatus = tiSuccess;
}
else
{
TI_DBG1(("tiINIIOStartIntCoalesceDif: saSSPStart failed\n"));
tdIORequestBody->ioStarted = agFALSE;
tdIORequestBody->ioCompleted = agTRUE;
if (saStatus == AGSA_RC_BUSY)
{
tiStatus = tiBusy;
}
else
{
tiStatus = tiError;
}
return tiStatus;
}
}
else if (oneDeviceData->DeviceType == TD_SATA_DEVICE)
{
TI_DBG1(("tiINIIOStartIntCoalesceDif: SATA not supported yet\n"));
return tiStatus;
}
else
{
TI_DBG1(("tiINIIOStartIntCoalesceDif: wrong unspported Device %d\n", oneDeviceData->DeviceType));
}
return tiStatus;
}
osGLOBAL bit32
tiINIIntCoalesceInit(
tiRoot_t *tiRoot,
tiIntCoalesceContext_t *tiIntCoalesceCxt,
bit32 count
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
agsaRoot_t *agRoot = agNULL;
tdsaIntCoalesceContext_t *tdsaIntCoalCxtHead
= (tdsaIntCoalesceContext_t *)tdsaAllShared->IntCoalesce;
tdsaIntCoalesceContext_t *tdsaIntCoalCxt;
agsaIntCoalesceContext_t *agIntCoalCxt;
tdList_t *tdsaIntCoalCxtList = agNULL;
bit32 tiStatus = tiError;
TI_DBG1(("tiINIIntCoalesceInit: start\n"));
tdsaSingleThreadedEnter(tiRoot, TD_INTCOAL_LOCK);
if (TDLIST_NOT_EMPTY(&(tdsaIntCoalCxtHead->FreeLink)))
{
TDLIST_DEQUEUE_FROM_HEAD(&tdsaIntCoalCxtList, &(tdsaIntCoalCxtHead->FreeLink));
tdsaSingleThreadedLeave(tiRoot, TD_INTCOAL_LOCK);
tdsaIntCoalCxt
= TDLIST_OBJECT_BASE(tdsaIntCoalesceContext_t, FreeLink, tdsaIntCoalCxtList);
TI_DBG1(("tiINIIntCoalesceInit: id %d\n", tdsaIntCoalCxt->id));
agRoot = &(tdsaAllShared->agRootNonInt);
agIntCoalCxt = &(tdsaIntCoalCxt->agIntCoalCxt);
tdsaIntCoalCxt->tiIntCoalesceCxt = tiIntCoalesceCxt;
tiIntCoalesceCxt->tdData = tdsaIntCoalCxt;
agIntCoalCxt->osData = tdsaIntCoalCxt;
tdsaSingleThreadedEnter(tiRoot, TD_INTCOAL_LOCK);
TDLIST_ENQUEUE_AT_TAIL(&(tdsaIntCoalCxt->MainLink), &(tdsaIntCoalCxtHead->MainLink));
tdsaSingleThreadedLeave(tiRoot, TD_INTCOAL_LOCK);
#ifdef LL_INT_COALESCE
tiStatus = saIntCoalesceInit(agRoot, agIntCoalCxt, count);
#endif
TI_DBG6(("tiINIIntCoalesceInit: status %d\n", tiStatus));
return tiStatus;
}
else
{
tdsaSingleThreadedLeave(tiRoot, TD_INTCOAL_LOCK);
TI_DBG1(("tiINIIntCoalesceInit: no more interrupt coalesce context; return fail\n"));
return tiStatus;
}
}
#endif
osGLOBAL FORCEINLINE bit32
itdssIOPrepareSGL(
tiRoot_t *tiRoot,
tdIORequestBody_t *tdIORequestBody,
tiSgl_t *tiSgl1,
void *sglVirtualAddr
)
{
agsaSgl_t *agSgl;
TI_DBG6(("itdssIOPrepareSGL: start\n"));
agSgl = &(tdIORequestBody->transport.SAS.agSASRequestBody.sspInitiatorReq.agSgl);
agSgl->len = 0;
if (tiSgl1 == agNULL)
{
TI_DBG1(("itdssIOPrepareSGL: Error tiSgl1 is NULL\n"));
return tiError;
}
if (tdIORequestBody->IOType.InitiatorRegIO.expDataLength == 0)
{
TI_DBG6(("itdssIOPrepareSGL: expDataLength is 0\n"));
agSgl->sgUpper = 0;
agSgl->sgLower = 0;
agSgl->len = 0;
CLEAR_ESGL_EXTEND(agSgl->extReserved);
return tiSuccess;
}
agSgl->sgUpper = tiSgl1->upper;
agSgl->sgLower = tiSgl1->lower;
agSgl->len = tiSgl1->len;
agSgl->extReserved = tiSgl1->type;
return tiSuccess;
}
osGLOBAL bit32
tiNumOfLunIOCTLreq(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
void *tiRequestBody,
tiIOCTLPayload_t *agIOCTLPayload,
void *agParam1,
void *agParam2
)
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
agsaRoot_t *agRoot = &(tdsaAllShared->agRootInt);
void *respBuffer = agNULL;
void *osMemHandle = agNULL;
bit32 ostiMemoryStatus = 0;
tdsaDeviceData_t *oneDeviceData = agNULL;
agsaSSPInitiatorRequest_t *agSSPFrame = agNULL;
bit32 status = IOCTL_CALL_SUCCESS;
bit32 agRequestType = 0;
agsaDevHandle_t *agDevHandle = agNULL;
agsaIORequest_t *agIORequest = agNULL;
tdIORequestBody_t *tdIORequestBody = agNULL;
agsaSASRequestBody_t *agSASRequestBody = agNULL;
do
{
if((tiIORequest == agNULL) || (tiRequestBody == agNULL))
{
status = IOCTL_CALL_FAIL;
break;
}
tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
tdIORequestBody->tiIORequest = tiIORequest;
tiIORequest->tdData = tdIORequestBody;
agIORequest = &(tdIORequestBody->agIORequest);
agIORequest->osData = (void *) tdIORequestBody;
agSASRequestBody = &(tdIORequestBody->transport.SAS.agSASRequestBody);
agSSPFrame = &(agSASRequestBody->sspInitiatorReq);
ostiMemoryStatus = ostiAllocMemory( tiRoot,
&osMemHandle,
(void **)&respBuffer,
&(agSSPFrame->agSgl.sgUpper),
&(agSSPFrame->agSgl.sgLower),
8,
REPORT_LUN_LEN,
agFALSE);
if((ostiMemoryStatus != tiSuccess) && (respBuffer == agNULL ))
{
status = IOCTL_CALL_FAIL;
break;
}
osti_memset((void *)respBuffer, 0, REPORT_LUN_LEN);
tdsaAllShared->tdFWControlEx.virtAddr = respBuffer;
tdsaAllShared->tdFWControlEx.len = REPORT_LUN_LEN;
tdsaAllShared->tdFWControlEx.param1 = agParam1;
tdsaAllShared->tdFWControlEx.param2 = agParam2;
tdsaAllShared->tdFWControlEx.payload = agIOCTLPayload;
tdsaAllShared->tdFWControlEx.inProgress = 1;
agRequestType = AGSA_SSP_INIT_READ;
status = IOCTL_CALL_PENDING;
oneDeviceData = (tdsaDeviceData_t *)(tiDeviceHandle->tdData);
agDevHandle = oneDeviceData->agDevHandle;
agSSPFrame->sspCmdIU.cdb[0] = REPORT_LUN_OPCODE;
agSSPFrame->sspCmdIU.cdb[1] = 0x0;
agSSPFrame->sspCmdIU.cdb[2] = 0x0;
agSSPFrame->sspCmdIU.cdb[3] = 0x0;
agSSPFrame->sspCmdIU.cdb[4] = 0x0;
agSSPFrame->sspCmdIU.cdb[5] = 0x0;
agSSPFrame->sspCmdIU.cdb[6] = 0x0;
agSSPFrame->sspCmdIU.cdb[7] = 0x0;
agSSPFrame->sspCmdIU.cdb[8] = 0x0;
agSSPFrame->sspCmdIU.cdb[9] = REPORT_LUN_LEN;
agSSPFrame->sspCmdIU.cdb[10] = 0x0;
agSSPFrame->sspCmdIU.cdb[11] = 0x0;
agSSPFrame->dataLength = REPORT_LUN_LEN;
agSSPFrame->agSgl.len = sizeof(agsaSSPCmdInfoUnit_t);
agSSPFrame->agSgl.extReserved = 0;
CLEAR_ESGL_EXTEND(agSSPFrame->agSgl.extReserved);
status = saSSPStart(agRoot, agIORequest, 0, agDevHandle, agRequestType,agSASRequestBody,agNULL,
&ossaSSPIoctlCompleted);
if(status != AGSA_RC_SUCCESS)
{
ostiFreeMemory(tiRoot,
tdsaAllShared->tdFWControlEx.virtAddr,
tdsaAllShared->tdFWControlEx.len);
tdsaAllShared->tdFWControlEx.payload = NULL;
tdsaAllShared->tdFWControlEx.inProgress = 0;
status = IOCTL_CALL_FAIL;
}
}while(0);
return status;
}