#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/tisa/api/titypes.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/sat/api/sm.h>
#include <dev/pms/RefTisa/sat/api/smapi.h>
#include <dev/pms/RefTisa/sat/api/tdsmapi.h>
#include <dev/pms/RefTisa/sat/src/smdefs.h>
#include <dev/pms/RefTisa/sat/src/smproto.h>
#include <dev/pms/RefTisa/sat/src/smtypes.h>
osGLOBAL bit32
smRegisterDevice(
smRoot_t *smRoot,
agsaDevHandle_t *agDevHandle,
smDeviceHandle_t *smDeviceHandle,
agsaDevHandle_t *agExpDevHandle,
bit32 phyID,
bit32 DeviceType
)
{
smDeviceData_t *oneDeviceData = agNULL;
SM_DBG2(("smRegisterDevice: start\n"));
if (smDeviceHandle == agNULL)
{
SM_DBG1(("smRegisterDevice: smDeviceHandle is NULL!!!\n"));
return SM_RC_FAILURE;
}
if (agDevHandle == agNULL)
{
SM_DBG1(("smRegisterDevice: agDevHandle is NULL!!!\n"));
return SM_RC_FAILURE;
}
oneDeviceData = smAddToSharedcontext(smRoot, agDevHandle, smDeviceHandle, agExpDevHandle, phyID);
if (oneDeviceData != agNULL)
{
oneDeviceData->satDeviceType = DeviceType;
return SM_RC_SUCCESS;
}
else
{
return SM_RC_FAILURE;
}
}
osGLOBAL bit32
smDeregisterDevice(
smRoot_t *smRoot,
agsaDevHandle_t *agDevHandle,
smDeviceHandle_t *smDeviceHandle
)
{
bit32 status = SM_RC_FAILURE;
SM_DBG2(("smDeregisterDevice: start\n"));
if (smDeviceHandle == agNULL)
{
SM_DBG1(("smDeregisterDevice: smDeviceHandle is NULL!!!\n"));
return SM_RC_FAILURE;
}
if (agDevHandle == agNULL)
{
SM_DBG1(("smDeregisterDevice: agDevHandle is NULL!!!\n"));
return SM_RC_FAILURE;
}
status = smRemoveFromSharedcontext(smRoot, agDevHandle, smDeviceHandle);
return status;
}
osGLOBAL bit32
smIOAbort(
smRoot_t *smRoot,
smIORequest_t *tasktag
)
{
smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData;
smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
agsaRoot_t *agRoot;
smIORequestBody_t *smIORequestBody = agNULL;
smIORequestBody_t *smIONewRequestBody = agNULL;
agsaIORequest_t *agIORequest = agNULL;
bit32 status = SM_RC_FAILURE;
agsaIORequest_t *agAbortIORequest;
smIORequestBody_t *smAbortIORequestBody;
#if 1
bit32 PhysUpper32;
bit32 PhysLower32;
bit32 memAllocStatus;
void *osMemHandle;
#endif
smSatIOContext_t *satIOContext;
smSatInternalIo_t *satIntIo;
smSatIOContext_t *satAbortIOContext;
SM_DBG1(("smIOAbort: start\n"));
SM_DBG2(("smIOAbort: tasktag %p\n", tasktag));
agRoot = smAllShared->agRoot;
smIORequestBody = (smIORequestBody_t *)tasktag->smData;
if (smIORequestBody == agNULL)
{
SM_DBG1(("smIOAbort: smIORequestBody is NULL!!!\n"));
return SM_RC_FAILURE;
}
satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
satIntIo = satIOContext->satIntIoContext;
if (satIntIo == agNULL)
{
SM_DBG2(("smIOAbort: External, OS generated\n"));
agIORequest = &(smIORequestBody->agIORequest);
}
else
{
SM_DBG2(("smIOAbort: Internal, SM generated\n"));
smIONewRequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody;
agIORequest = &(smIONewRequestBody->agIORequest);
}
#if 1
memAllocStatus = tdsmAllocMemory(
smRoot,
&osMemHandle,
(void **)&smAbortIORequestBody,
&PhysUpper32,
&PhysLower32,
8,
sizeof(smIORequestBody_t),
agTRUE
);
if (memAllocStatus != SM_RC_SUCCESS)
{
SM_DBG1(("smIOAbort: tdsmAllocMemory failed...!!!\n"));
return SM_RC_FAILURE;
}
if (smAbortIORequestBody == agNULL)
{
SM_DBG1(("smIOAbort: tdsmAllocMemory returned NULL smAbortIORequestBody!!!\n"));
return SM_RC_FAILURE;
}
smIOReInit(smRoot, smAbortIORequestBody);
smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
satAbortIOContext = &(smAbortIORequestBody->transport.SATA.satIOContext);
satAbortIOContext->smRequestBody = smAbortIORequestBody;
smAbortIORequestBody->smDevHandle = smIORequestBody->smDevHandle;
agAbortIORequest = &(smAbortIORequestBody->agIORequest);
agAbortIORequest->osData = (void *) smAbortIORequestBody;
agAbortIORequest->sdkData = agNULL;
smAbortIORequestBody->smIOToBeAbortedRequest = tasktag;
status = saSATAAbort(agRoot, agAbortIORequest, 0, agNULL, 0, agIORequest, smaSATAAbortCB);
SM_DBG2(("smIOAbort: return status=0x%x\n", status));
#endif
if (status == AGSA_RC_SUCCESS)
{
return SM_RC_SUCCESS;
}
else
{
SM_DBG1(("smIOAbort: failed to call saSATAAbort, status=%d!!!\n", status));
tdsmFreeMemory(smRoot,
smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(smIORequestBody_t)
);
return SM_RC_FAILURE;
}
}
osGLOBAL bit32
smIOAbortAll(
smRoot_t *smRoot,
smDeviceHandle_t *smDeviceHandle
)
{
smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData;
smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
agsaRoot_t *agRoot;
bit32 status = SM_RC_FAILURE;
agsaIORequest_t *agAbortIORequest;
smIORequestBody_t *smAbortIORequestBody;
smSatIOContext_t *satAbortIOContext;
smDeviceData_t *oneDeviceData = agNULL;
agsaDevHandle_t *agDevHandle;
bit32 PhysUpper32;
bit32 PhysLower32;
bit32 memAllocStatus;
void *osMemHandle;
SM_DBG2(("smIOAbortAll: start\n"));
agRoot = smAllShared->agRoot;
if (smDeviceHandle == agNULL)
{
SM_DBG1(("smIOAbortAll: smDeviceHandle is NULL!!!\n"));
return SM_RC_FAILURE;
}
oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
if (oneDeviceData == agNULL)
{
SM_DBG1(("smIOAbortAll: oneDeviceData is NULL!!!\n"));
return SM_RC_FAILURE;
}
if (oneDeviceData->valid == agFALSE)
{
SM_DBG1(("smIOAbortAll: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id));
return SM_RC_FAILURE;
}
agDevHandle = oneDeviceData->agDevHandle;
if (agDevHandle == agNULL)
{
SM_DBG1(("smIOAbortAll: agDevHandle is NULL!!!\n"));
return SM_RC_FAILURE;
}
memAllocStatus = tdsmAllocMemory(
smRoot,
&osMemHandle,
(void **)&smAbortIORequestBody,
&PhysUpper32,
&PhysLower32,
8,
sizeof(smIORequestBody_t),
agTRUE
);
if (memAllocStatus != SM_RC_SUCCESS)
{
SM_DBG1(("smIOAbortAll: tdsmAllocMemory failed...!!!\n"));
return SM_RC_FAILURE;
}
if (smAbortIORequestBody == agNULL)
{
SM_DBG1(("smIOAbortAll: tdsmAllocMemory returned NULL smAbortIORequestBody!!!\n"));
return SM_RC_FAILURE;
}
smIOReInit(smRoot, smAbortIORequestBody);
smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
satAbortIOContext = &(smAbortIORequestBody->transport.SATA.satIOContext);
satAbortIOContext->smRequestBody = smAbortIORequestBody;
smAbortIORequestBody->smDevHandle = smDeviceHandle;
agAbortIORequest = &(smAbortIORequestBody->agIORequest);
agAbortIORequest->osData = (void *) smAbortIORequestBody;
agAbortIORequest->sdkData = agNULL;
oneDeviceData->OSAbortAll = agTRUE;
status = saSATAAbort(agRoot, agAbortIORequest, tdsmRotateQnumber(smRoot, smDeviceHandle), agDevHandle, 1, agNULL, smaSATAAbortCB);
if (status != AGSA_RC_SUCCESS)
{
SM_DBG1(("smIOAbortAll: failed to call saSATAAbort, status=%d!!!\n", status));
tdsmFreeMemory(smRoot,
smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(smIORequestBody_t)
);
}
return status;
}
osGLOBAL bit32
smSuperIOStart(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smSuperScsiInitiatorRequest_t *smSCSIRequest,
bit32 AddrHi,
bit32 AddrLo,
bit32 interruptContext
)
{
smDeviceData_t *oneDeviceData = agNULL;
smIORequestBody_t *smIORequestBody = agNULL;
smSatIOContext_t *satIOContext = agNULL;
bit32 status = SM_RC_FAILURE;
SM_DBG2(("smSuperIOStart: start\n"));
oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
if (oneDeviceData == agNULL)
{
SM_DBG1(("smSuperIOStart: oneDeviceData is NULL!!!\n"));
return SM_RC_FAILURE;
}
if (oneDeviceData->valid == agFALSE)
{
SM_DBG1(("smSuperIOStart: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id));
return SM_RC_FAILURE;
}
smIORequestBody = (smIORequestBody_t*)smIORequest->smData;
if (smIORequestBody == agNULL)
{
SM_DBG1(("smSuperIOStart: smIORequestBody is NULL!!!\n"));
return SM_RC_FAILURE;
}
smIOReInit(smRoot, smIORequestBody);
SM_DBG3(("smSuperIOStart: io ID %d!!!\n", smIORequestBody->id ));
oneDeviceData->sasAddressHi = AddrHi;
oneDeviceData->sasAddressLo = AddrLo;
smIORequestBody->smIORequest = smIORequest;
smIORequestBody->smDevHandle = smDeviceHandle;
satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
smIORequestBody->transport.SATA.smSenseData.senseData = agNULL;
smIORequestBody->transport.SATA.smSenseData.senseLen = 0;
satIOContext->pSatDevData = oneDeviceData;
satIOContext->pFis =
&smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
satIOContext->pScsiCmnd = &smSCSIRequest->scsiCmnd;
satIOContext->pSense = &smIORequestBody->transport.SATA.sensePayload;
satIOContext->pSmSenseData = &smIORequestBody->transport.SATA.smSenseData;
satIOContext->pSmSenseData->senseData = satIOContext->pSense;
satIOContext->smRequestBody = smIORequestBody;
satIOContext->interruptContext = interruptContext;
satIOContext->psmDeviceHandle = smDeviceHandle;
satIOContext->smScsiXchg = smSCSIRequest;
satIOContext->superIOFlag = agTRUE;
satIOContext->satIntIoContext = agNULL;
satIOContext->satOrgIOContext = agNULL;
satIOContext->currentLBA = 0;
satIOContext->OrgTL = 0;
status = smsatIOStart(smRoot, smIORequest, smDeviceHandle, (smScsiInitiatorRequest_t *)smSCSIRequest, satIOContext);
return status;
}
FORCEINLINE bit32
smIOStart(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smSCSIRequest,
bit32 interruptContext
)
{
smDeviceData_t *oneDeviceData = agNULL;
smIORequestBody_t *smIORequestBody = agNULL;
smSatIOContext_t *satIOContext = agNULL;
bit32 status = SM_RC_FAILURE;
SM_DBG2(("smIOStart: start\n"));
oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
if (oneDeviceData == agNULL)
{
SM_DBG1(("smIOStart: oneDeviceData is NULL!!!\n"));
return SM_RC_FAILURE;
}
if (oneDeviceData->valid == agFALSE)
{
SM_DBG1(("smIOStart: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id));
return SM_RC_FAILURE;
}
smIORequestBody = (smIORequestBody_t*)smIORequest->smData;
if (smIORequestBody == agNULL)
{
SM_DBG1(("smIOStart: smIORequestBody is NULL!!!\n"));
return SM_RC_FAILURE;
}
smIOReInit(smRoot, smIORequestBody);
SM_DBG3(("smIOStart: io ID %d!!!\n", smIORequestBody->id ));
smIORequestBody->smIORequest = smIORequest;
smIORequestBody->smDevHandle = smDeviceHandle;
satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
smIORequestBody->transport.SATA.smSenseData.senseData = agNULL;
smIORequestBody->transport.SATA.smSenseData.senseLen = 0;
satIOContext->pSatDevData = oneDeviceData;
satIOContext->pFis =
&smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
satIOContext->pScsiCmnd = &smSCSIRequest->scsiCmnd;
satIOContext->pSense = &smIORequestBody->transport.SATA.sensePayload;
satIOContext->pSmSenseData = &smIORequestBody->transport.SATA.smSenseData;
satIOContext->pSmSenseData->senseData = satIOContext->pSense;
satIOContext->smRequestBody = smIORequestBody;
satIOContext->interruptContext = interruptContext;
satIOContext->psmDeviceHandle = smDeviceHandle;
satIOContext->smScsiXchg = smSCSIRequest;
satIOContext->superIOFlag = agFALSE;
satIOContext->satIntIoContext = agNULL;
satIOContext->satOrgIOContext = agNULL;
satIOContext->currentLBA = 0;
satIOContext->OrgTL = 0;
status = smsatIOStart(smRoot, smIORequest, smDeviceHandle, smSCSIRequest, satIOContext);
return status;
}
osGLOBAL bit32
smTaskManagement(
smRoot_t *smRoot,
smDeviceHandle_t *smDeviceHandle,
bit32 task,
smLUN_t *lun,
smIORequest_t *taskTag,
smIORequest_t *currentTaskTag
)
{
smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData;
smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
agsaRoot_t *agRoot = smAllShared->agRoot;
smDeviceData_t *oneDeviceData = agNULL;
smIORequestBody_t *smIORequestBody = agNULL;
bit32 status;
agsaContext_t *agContext = agNULL;
smSatIOContext_t *satIOContext;
SM_DBG1(("smTaskManagement: start\n"));
oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
if (task == SM_LOGICAL_UNIT_RESET || task == SM_TARGET_WARM_RESET || task == SM_ABORT_TASK)
{
if (task == AG_LOGICAL_UNIT_RESET)
{
if ( (lun->lun[0] | lun->lun[1] | lun->lun[2] | lun->lun[3] |
lun->lun[4] | lun->lun[5] | lun->lun[6] | lun->lun[7] ) != 0 )
{
SM_DBG1(("smTaskManagement: *** REJECT *** LUN not zero, did %d!!!\n",
oneDeviceData->id));
return SM_RC_FAILURE;
}
}
oneDeviceData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
oneDeviceData->satAbortAfterReset = agFALSE;
saSetDeviceState(agRoot,
agNULL,
tdsmRotateQnumber(smRoot, smDeviceHandle),
oneDeviceData->agDevHandle,
SA_DS_IN_RECOVERY
);
if (oneDeviceData->directlyAttached == agFALSE)
{
SM_DBG1(("smTaskManagement: LUN reset or device reset expander attached!!!\n"));
status = smPhyControlSend(smRoot,
oneDeviceData,
SMP_PHY_CONTROL_HARD_RESET,
currentTaskTag,
tdsmRotateQnumber(smRoot, smDeviceHandle)
);
return status;
}
else
{
SM_DBG1(("smTaskManagement: LUN reset or device reset directly attached\n"));
smIORequestBody = (smIORequestBody_t*)currentTaskTag->smData;
if (smIORequestBody == agNULL)
{
SM_DBG1(("smTaskManagement: smIORequestBody is NULL!!!\n"));
return SM_RC_FAILURE;
}
smIOReInit(smRoot, smIORequestBody);
satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
satIOContext->smRequestBody = smIORequestBody;
smIORequestBody->smDevHandle = smDeviceHandle;
agContext = &(oneDeviceData->agDeviceResetContext);
agContext->osData = currentTaskTag;
status = saLocalPhyControl(agRoot,
agContext,
tdsmRotateQnumber(smRoot, smDeviceHandle) &0xFFFF,
oneDeviceData->phyID,
AGSA_PHY_HARD_RESET,
smLocalPhyControlCB
);
if ( status == AGSA_RC_SUCCESS)
{
return SM_RC_SUCCESS;
}
else if (status == AGSA_RC_BUSY)
{
return SM_RC_BUSY;
}
else if (status == AGSA_RC_FAILURE)
{
return SM_RC_FAILURE;
}
else
{
SM_DBG1(("smTaskManagement: unknown status %d\n",status));
return SM_RC_FAILURE;
}
}
}
else
{
smIORequestBody = (smIORequestBody_t*)currentTaskTag->smData;
if (smIORequestBody == agNULL)
{
SM_DBG1(("smTaskManagement: smIORequestBody is NULL!!!\n"));
return SM_RC_FAILURE;
}
smIOReInit(smRoot, smIORequestBody);
status = smsatTaskManagement(smRoot,
smDeviceHandle,
task,
lun,
taskTag,
currentTaskTag,
smIORequestBody
);
return status;
}
return SM_RC_SUCCESS;
}
osGLOBAL smIORequestBody_t *
smDequeueIO(smRoot_t *smRoot)
{
smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData;
smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
smIORequestBody_t *smIORequestBody = agNULL;
smList_t *IOListList;
SM_DBG2(("smDequeueIO: start\n"));
tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
if (SMLIST_EMPTY(&(smAllShared->freeIOList)))
{
SM_DBG1(("smDequeueIO: empty freeIOList!!!\n"));
tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
return agNULL;
}
SMLIST_DEQUEUE_FROM_HEAD(&IOListList, &(smAllShared->freeIOList));
smIORequestBody = SMLIST_OBJECT_BASE(smIORequestBody_t, satIoBodyLink, IOListList);
SMLIST_DEQUEUE_THIS(&(smIORequestBody->satIoBodyLink));
SMLIST_ENQUEUE_AT_TAIL(&(smIORequestBody->satIoBodyLink), &(smAllShared->mainIOList));
tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
if (smIORequestBody->InUse == agTRUE)
{
SM_DBG1(("smDequeueIO: wrong. already in USE ID %d!!!!\n", smIORequestBody->id));
}
smIOReInit(smRoot, smIORequestBody);
SM_DBG2(("smDequeueIO: io ID %d!\n", smIORequestBody->id));
if (smIORequestBody->satIoBodyLink.flink == agNULL)
{
SM_DBG1(("smDequeueIO: io ID %d, flink is NULL!!!\n", smIORequestBody->id));
}
if (smIORequestBody->satIoBodyLink.blink == agNULL)
{
SM_DBG1(("smDequeueIO: io ID %d, blink is NULL!!!\n", smIORequestBody->id));
}
return smIORequestBody;
}
osGLOBAL void
smsatAbort(
smRoot_t *smRoot,
agsaRoot_t *agRoot,
smSatIOContext_t *satIOContext
)
{
smIORequestBody_t *smIORequestBody = agNULL;
smIORequestBody_t *smToBeAbortedIORequestBody;
agsaIORequest_t *agToBeAbortedIORequest;
agsaIORequest_t *agAbortIORequest;
smSatIOContext_t *satAbortIOContext;
bit32 PhysUpper32;
bit32 PhysLower32;
bit32 memAllocStatus;
void *osMemHandle;
SM_DBG2(("smsatAbort: start\n"));
if (satIOContext == agNULL)
{
SM_DBG1(("smsatAbort: satIOContext is NULL, wrong!!!\n"));
return;
}
smToBeAbortedIORequestBody = (smIORequestBody_t *)satIOContext->smRequestBody;
agToBeAbortedIORequest = (agsaIORequest_t *)&(smToBeAbortedIORequestBody->agIORequest);
memAllocStatus = tdsmAllocMemory(
smRoot,
&osMemHandle,
(void **)&smIORequestBody,
&PhysUpper32,
&PhysLower32,
8,
sizeof(smIORequestBody_t),
agTRUE
);
if (memAllocStatus != tiSuccess)
{
SM_DBG1(("smsatAbort: ostiAllocMemory failed...\n"));
return;
}
if (smIORequestBody == agNULL)
{
SM_DBG1(("smsatAbort: ostiAllocMemory returned NULL smIORequestBody\n"));
return;
}
smIOReInit(smRoot, smIORequestBody);
smIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
smIORequestBody->smDevHandle = smToBeAbortedIORequestBody->smDevHandle;
satAbortIOContext = &(smIORequestBody->transport.SATA.satIOContext);
satAbortIOContext->smRequestBody = smIORequestBody;
agAbortIORequest = &(smIORequestBody->agIORequest);
agAbortIORequest->osData = (void *) smIORequestBody;
agAbortIORequest->sdkData = agNULL;
saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agToBeAbortedIORequest, smaSATAAbortCB);
SM_DBG1(("satAbort: end!!!\n"));
return;
}
osGLOBAL bit32
smsatStartCheckPowerMode(
smRoot_t *smRoot,
smIORequest_t *currentTaskTag,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
smSatInternalIo_t *satIntIo = agNULL;
smDeviceData_t *oneDeviceData = agNULL;
smSatIOContext_t *satNewIOContext;
bit32 status;
SM_DBG1(("smsatStartCheckPowerMode: start\n"));
oneDeviceData = satIOContext->pSatDevData;
SM_DBG6(("smsatStartCheckPowerMode: before alloc\n"));
satIntIo = smsatAllocIntIoResource( smRoot,
currentTaskTag,
oneDeviceData,
0,
satIntIo);
SM_DBG6(("smsatStartCheckPowerMode: before after\n"));
if (satIntIo == agNULL)
{
SM_DBG1(("smsatStartCheckPowerMode: can't alloacate!!!\n"));
return SM_RC_FAILURE;
}
satNewIOContext = smsatPrepareNewIO(satIntIo,
currentTaskTag,
oneDeviceData,
agNULL,
satIOContext);
SM_DBG6(("smsatStartCheckPowerMode: TD satIOContext %p \n", satIOContext));
SM_DBG6(("smsatStartCheckPowerMode: SM satNewIOContext %p \n", satNewIOContext));
SM_DBG6(("smsatStartCheckPowerMode: TD smScsiXchg %p \n", satIOContext->smScsiXchg));
SM_DBG6(("smsatStartCheckPowerMode: SM smScsiXchg %p \n", satNewIOContext->smScsiXchg));
SM_DBG2(("smsatStartCheckPowerMode: satNewIOContext %p \n", satNewIOContext));
status = smsatCheckPowerMode(smRoot,
&satIntIo->satIntSmIORequest,
smDeviceHandle,
satNewIOContext->smScsiXchg,
satNewIOContext);
if (status != SM_RC_SUCCESS)
{
SM_DBG1(("smsatStartCheckPowerMode: failed in sending!!!\n"));
smsatFreeIntIoResource( smRoot,
oneDeviceData,
satIntIo);
return SM_RC_FAILURE;
}
SM_DBG6(("smsatStartCheckPowerMode: end\n"));
return status;
}
osGLOBAL bit32
smsatStartResetDevice(
smRoot_t *smRoot,
smIORequest_t *currentTaskTag,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
smSatInternalIo_t *satIntIo = agNULL;
smDeviceData_t *oneDeviceData = agNULL;
smSatIOContext_t *satNewIOContext;
bit32 status;
SM_DBG1(("smsatStartResetDevice: start\n"));
oneDeviceData = satIOContext->pSatDevData;
SM_DBG6(("smsatStartResetDevice: before alloc\n"));
satIntIo = smsatAllocIntIoResource( smRoot,
currentTaskTag,
oneDeviceData,
0,
satIntIo);
SM_DBG6(("smsatStartResetDevice: before after\n"));
if (satIntIo == agNULL)
{
SM_DBG1(("smsatStartResetDevice: can't alloacate!!!\n"));
return SM_RC_FAILURE;
}
satNewIOContext = smsatPrepareNewIO(satIntIo,
currentTaskTag,
oneDeviceData,
agNULL,
satIOContext);
SM_DBG6(("smsatStartResetDevice: TD satIOContext %p \n", satIOContext));
SM_DBG6(("smsatStartResetDevice: SM satNewIOContext %p \n", satNewIOContext));
SM_DBG6(("smsatStartResetDevice: TD smScsiXchg %p \n", satIOContext->smScsiXchg));
SM_DBG6(("smsatStartResetDevice: SM smScsiXchg %p \n", satNewIOContext->smScsiXchg));
SM_DBG6(("smsatStartResetDevice: satNewIOContext %p \n", satNewIOContext));
if (oneDeviceData->satDeviceType == SATA_ATAPI_DEVICE)
{
status = smsatDeviceReset(smRoot,
&satIntIo->satIntSmIORequest,
smDeviceHandle,
satNewIOContext->smScsiXchg,
satNewIOContext);
}
else
{
status = smsatResetDevice(smRoot,
&satIntIo->satIntSmIORequest,
smDeviceHandle,
satNewIOContext->smScsiXchg,
satNewIOContext);
}
if (status != SM_RC_SUCCESS)
{
SM_DBG1(("smsatStartResetDevice: failed in sending!!!\n"));
smsatFreeIntIoResource( smRoot,
oneDeviceData,
satIntIo);
return SM_RC_FAILURE;
}
SM_DBG6(("smsatStartResetDevice: end\n"));
return status;
}
osGLOBAL bit32
smsatTmAbortTask(
smRoot_t *smRoot,
smIORequest_t *currentTaskTag,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext,
smIORequest_t *taskTag)
{
smDeviceData_t *oneDeviceData = agNULL;
smSatIOContext_t *satTempIOContext = agNULL;
smList_t *elementHdr;
bit32 found = agFALSE;
smIORequestBody_t *smIORequestBody = agNULL;
smIORequest_t *smIOReq = agNULL;
bit32 status;
SM_DBG1(("smsatTmAbortTask: start\n"));
oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
elementHdr = oneDeviceData->satIoLinkList.flink;
while (elementHdr != &oneDeviceData->satIoLinkList)
{
satTempIOContext = SMLIST_OBJECT_BASE( smSatIOContext_t,
satIoContextLink,
elementHdr );
if ( satTempIOContext != agNULL)
{
smIORequestBody = (smIORequestBody_t *) satTempIOContext->smRequestBody;
smIOReq = smIORequestBody->smIORequest;
}
elementHdr = elementHdr->flink;
if ( smIOReq == taskTag)
{
found = agTRUE;
satIOContext->satToBeAbortedIOContext = satTempIOContext;
SM_DBG1(("smsatTmAbortTask: found matching tag.\n"));
break;
}
}
tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
if (found == agFALSE )
{
SM_DBG1(("smsatTmAbortTask: *** REJECT *** no match!!!\n"));
if (smIORequestBody)
{
if (smIORequestBody->IOType.InitiatorTMIO.osMemHandle != agNULL)
{
tdsmFreeMemory(
smRoot,
smIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(smIORequestBody_t)
);
}
}
else
{
SM_DBG1(("smsatTmAbortTask: smIORequestBody is NULL!!!\n"));
}
return SM_RC_FAILURE;
}
if (satTempIOContext == agNULL)
{
SM_DBG1(("smsatTmAbortTask: satTempIOContext is NULL!!!\n"));
return SM_RC_FAILURE;
}
oneDeviceData->satTmTaskTag = currentTaskTag;
oneDeviceData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
oneDeviceData->satAbortAfterReset = agTRUE;
if ( (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
(satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ)
)
{
SM_DBG1(("smsatTmAbortTask: calling satStartCheckPowerMode!!!\n"));
status = smsatStartCheckPowerMode(
smRoot,
currentTaskTag,
smDeviceHandle,
smScsiRequest,
satIOContext
);
}
else
{
SM_DBG1(("smsatTmAbortTask: calling satStartResetDevice!!!\n"));
status = smsatStartResetDevice(
smRoot,
currentTaskTag,
smDeviceHandle,
smScsiRequest,
satIOContext
);
}
return status;
}
osGLOBAL bit32
smsatTaskManagement(
smRoot_t *smRoot,
smDeviceHandle_t *smDeviceHandle,
bit32 task,
smLUN_t *lun,
smIORequest_t *taskTag,
smIORequest_t *currentTaskTag,
smIORequestBody_t *smIORequestBody
)
{
smSatIOContext_t *satIOContext = agNULL;
smDeviceData_t *oneDeviceData = agNULL;
bit32 status;
SM_DBG1(("smsatTaskManagement: start\n"));
oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
satIOContext->pSatDevData = oneDeviceData;
satIOContext->pFis =
&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
satIOContext->smRequestBody = smIORequestBody;
satIOContext->psmDeviceHandle = smDeviceHandle;
satIOContext->satIntIoContext = agNULL;
satIOContext->satOrgIOContext = agNULL;
satIOContext->currentLBA = 0;
satIOContext->OrgTL = 0;
satIOContext->TMF = task;
satIOContext->satToBeAbortedIOContext = agNULL;
if (task == AG_ABORT_TASK)
{
status = smsatTmAbortTask( smRoot,
currentTaskTag,
smDeviceHandle,
agNULL,
satIOContext,
taskTag);
return status;
}
else
{
SM_DBG1(("smsatTaskManagement: UNSUPPORTED TM task=0x%x!!!\n", task ));
return SM_RC_FAILURE;
}
return SM_RC_SUCCESS;
}
osGLOBAL bit32
smPhyControlSend(
smRoot_t *smRoot,
smDeviceData_t *oneDeviceData,
bit8 phyOp,
smIORequest_t *CurrentTaskTag,
bit32 queueNumber
)
{
smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData;
smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
agsaRoot_t *agRoot = smAllShared->agRoot;
agsaDevHandle_t *agExpDevHandle;
smpReqPhyControl_t smpPhyControlReq;
void *osMemHandle;
bit32 PhysUpper32;
bit32 PhysLower32;
bit32 memAllocStatus;
bit32 expectedRspLen = 0;
smSMPRequestBody_t *smSMPRequestBody;
agsaSASRequestBody_t *agSASRequestBody;
agsaSMPFrame_t *agSMPFrame;
agsaIORequest_t *agIORequest;
smSMPFrameHeader_t smSMPFrameHeader;
bit32 status;
bit8 *pSmpBody;
bit32 smpBodySize;
bit32 agRequestType;
SM_DBG2(("smPhyControlSend: start\n"));
agExpDevHandle = oneDeviceData->agExpDevHandle;
if (agExpDevHandle == agNULL)
{
SM_DBG1(("smPhyControlSend: agExpDevHandle is NULL!!!\n"));
return SM_RC_FAILURE;
}
SM_DBG5(("smPhyControlSend: phyID %d\n", oneDeviceData->phyID));
sm_memset(&smpPhyControlReq, 0, sizeof(smpReqPhyControl_t));
smpPhyControlReq.phyIdentifier = (bit8)oneDeviceData->phyID;
smpPhyControlReq.phyOperation = phyOp;
memAllocStatus = tdsmAllocMemory(
smRoot,
&osMemHandle,
(void **)&smSMPRequestBody,
&PhysUpper32,
&PhysLower32,
8,
sizeof(smSMPRequestBody_t),
agTRUE
);
if (memAllocStatus != SM_RC_SUCCESS)
{
SM_DBG1(("smPhyControlSend: tdsmAllocMemory failed...!!!\n"));
return SM_RC_FAILURE;
}
if (smSMPRequestBody == agNULL)
{
SM_DBG1(("smPhyControlSend: tdsmAllocMemory returned NULL smSMPRequestBody!!!\n"));
return SM_RC_FAILURE;
}
smSMPRequestBody->osMemHandle = osMemHandle;
smSMPRequestBody->smDeviceData = oneDeviceData;
smSMPRequestBody->smDevHandle = oneDeviceData->smDevHandle;
smSMPRequestBody->SMPCompletionFunc = smSMPCompleted;
smSMPRequestBody->CurrentTaskTag = CurrentTaskTag;
if (CurrentTaskTag != agNULL)
{
CurrentTaskTag->smData = smSMPRequestBody;
}
smSMPRequestBody->retries = 0;
#ifdef TD_INTERNAL_DEBUG
SM_DBG4(("smPhyControlSend: SMPRequestbody %p\n", smSMPRequestBody));
SM_DBG4(("smPhyControlSend: callback fn %p\n", smSMPRequestBody->SMPCompletionFunc));
#endif
agIORequest = &(smSMPRequestBody->agIORequest);
agIORequest->osData = (void *) smSMPRequestBody;
agIORequest->sdkData = agNULL;
agSASRequestBody = &(smSMPRequestBody->agSASRequestBody);
agSMPFrame = &(agSASRequestBody->smpFrame);
SM_DBG3(("smPhyControlSend: agIORequest %p\n", agIORequest));
SM_DBG3(("smPhyControlSend: SMPRequestbody %p\n", smSMPRequestBody));
expectedRspLen = 4;
pSmpBody = (bit8 *)&smpPhyControlReq;
smpBodySize = sizeof(smpReqPhyControl_t);
agRequestType = AGSA_SMP_INIT_REQ;
if (SMIsSPC(agRoot))
{
if ( (smpBodySize + 4) <= SMP_DIRECT_PAYLOAD_LIMIT)
{
SM_DBG3(("smPhyControlSend: DIRECT smp payload\n"));
sm_memset(&smSMPFrameHeader, 0, sizeof(smSMPFrameHeader_t));
sm_memset(smSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT);
smSMPFrameHeader.smpFrameType = SMP_REQUEST;
smSMPFrameHeader.smpFunction = (bit8)SMP_PHY_CONTROL;
smSMPFrameHeader.smpFunctionResult = 0;
smSMPFrameHeader.smpReserved = 0;
sm_memcpy(smSMPRequestBody->smpPayload, &smSMPFrameHeader, 4);
sm_memcpy((smSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize);
agSMPFrame->outFrameBuf = smSMPRequestBody->smpPayload;
agSMPFrame->outFrameLen = smpBodySize + 4;
agSMPFrame->inFrameLen = 0;
#if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER)
agSMPFrame->expectedRespLen = 0;
#else
agSMPFrame->expectedRespLen = expectedRspLen;
#endif
}
else
{
SM_DBG1(("smPhyControlSend: INDIRECT smp payload, not supported!!!\n"));
tdsmFreeMemory(
smRoot,
osMemHandle,
sizeof(smSMPRequestBody_t)
);
return SM_RC_FAILURE;
}
}
else
{
SM_DBG3(("smPhyControlSend: DIRECT smp payload\n"));
agSMPFrame->flag = 0;
sm_memset(&smSMPFrameHeader, 0, sizeof(smSMPFrameHeader_t));
sm_memset(smSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT);
smSMPFrameHeader.smpFrameType = SMP_REQUEST;
smSMPFrameHeader.smpFunction = (bit8)SMP_PHY_CONTROL;
smSMPFrameHeader.smpFunctionResult = 0;
smSMPFrameHeader.smpReserved = 0;
sm_memcpy(smSMPRequestBody->smpPayload, &smSMPFrameHeader, 4);
sm_memcpy((smSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize);
agSMPFrame->outFrameBuf = smSMPRequestBody->smpPayload;
agSMPFrame->outFrameLen = smpBodySize + 4;
agSMPFrame->inFrameLen = 0;
#if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER)
agSMPFrame->expectedRespLen = 0;
#else
agSMPFrame->expectedRespLen = expectedRspLen;
#endif
}
status = saSMPStart(
agRoot,
agIORequest,
queueNumber,
agExpDevHandle,
agRequestType,
agSASRequestBody,
&smSMPCompletedCB
);
if (status == AGSA_RC_SUCCESS)
{
return SM_RC_SUCCESS;
}
else if (status == AGSA_RC_BUSY)
{
SM_DBG1(("smPhyControlSend: saSMPStart is busy!!!\n"));
tdsmFreeMemory(
smRoot,
osMemHandle,
sizeof(smSMPRequestBody_t)
);
return SM_RC_BUSY;
}
else
{
SM_DBG1(("smPhyControlSend: saSMPStart is failed. status %d!!!\n", status));
tdsmFreeMemory(
smRoot,
osMemHandle,
sizeof(smSMPRequestBody_t)
);
return SM_RC_FAILURE;
}
}
osGLOBAL void
smEnqueueIO(
smRoot_t *smRoot,
smSatIOContext_t *satIOContext
)
{
smIntRoot_t *smIntRoot = agNULL;
smIntContext_t *smAllShared = agNULL;
smIORequestBody_t *smIORequestBody;
SM_DBG3(("smEnqueueIO: start\n"));
smIORequestBody = (smIORequestBody_t *)satIOContext->smRequestBody;
smIntRoot = (smIntRoot_t *)smRoot->smData;
smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
if (satIOContext->satIntIoContext == agNULL)
{
SM_DBG2(("smEnqueueIO: external command!!!, io ID %d!!!\n", smIORequestBody->id));
if (smIORequestBody->satIoBodyLink.flink == agNULL)
{
SM_DBG1(("smEnqueueIO: external command!!!, io ID %d, flink is NULL!!!\n", smIORequestBody->id));
}
if (smIORequestBody->satIoBodyLink.blink == agNULL)
{
SM_DBG1(("smEnqueueIO: external command!!!, io ID %d, blink is NULL!!!\n", smIORequestBody->id));
}
}
else
{
SM_DBG2(("smEnqueueIO: internal command!!!, io ID %d!!!\n", smIORequestBody->id));
if (smIORequestBody->satIoBodyLink.flink == agNULL)
{
SM_DBG1(("smEnqueueIO: internal command!!!, io ID %d, flink is NULL!!!\n", smIORequestBody->id));
}
if (smIORequestBody->satIoBodyLink.blink == agNULL)
{
SM_DBG1(("smEnqueueIO: internal command!!!, io ID %d, blink is NULL!!!\n", smIORequestBody->id));
}
}
if (smIORequestBody->smIORequest == agNULL)
{
SM_DBG1(("smEnqueueIO: smIORequest is NULL, io ID %d!!!\n", smIORequestBody->id));
}
if (smIORequestBody->InUse == agTRUE)
{
smIORequestBody->InUse = agFALSE;
tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
SMLIST_DEQUEUE_THIS(&(smIORequestBody->satIoBodyLink));
SMLIST_ENQUEUE_AT_TAIL(&(smIORequestBody->satIoBodyLink), &(smAllShared->freeIOList));
tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
}
else
{
SM_DBG2(("smEnqueueIO: check!!!, io ID %d!!!\n", smIORequestBody->id));
}
return;
}
FORCEINLINE void
smsatFreeIntIoResource(
smRoot_t *smRoot,
smDeviceData_t *satDevData,
smSatInternalIo_t *satIntIo
)
{
SM_DBG3(("smsatFreeIntIoResource: start\n"));
if (satIntIo == agNULL)
{
SM_DBG2(("smsatFreeIntIoResource: allowed call\n"));
return;
}
satIntIo->satOrgSmIORequest = agNULL;
if (satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength != 0)
{
SM_DBG3(("smsatFreeIntIoResource: DMA len %d\n", satIntIo->satIntDmaMem.totalLength));
SM_DBG3(("smsatFreeIntIoResource: pointer %p\n", satIntIo->satIntDmaMem.osHandle));
tdsmFreeMemory( smRoot,
satIntIo->satIntDmaMem.osHandle,
satIntIo->satIntDmaMem.totalLength);
satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength = 0;
}
if (satIntIo->satIntReqBodyMem.totalLength != 0)
{
SM_DBG3(("smsatFreeIntIoResource: req body len %d\n", satIntIo->satIntReqBodyMem.totalLength));
tdsmFreeMemory( smRoot,
satIntIo->satIntReqBodyMem.osHandle,
satIntIo->satIntReqBodyMem.totalLength);
satIntIo->satIntReqBodyMem.totalLength = 0;
}
SM_DBG3(("smsatFreeIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
SMLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
SMLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satFreeIntIoLinkList));
tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
return;
}
osGLOBAL smSatInternalIo_t *
smsatAllocIntIoResource(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceData_t *satDevData,
bit32 dmaAllocLength,
smSatInternalIo_t *satIntIo)
{
smList_t *smList = agNULL;
bit32 memAllocStatus;
SM_DBG3(("smsatAllocIntIoResource: start\n"));
SM_DBG3(("smsatAllocIntIoResource: satIntIo %p\n", satIntIo));
if (satDevData == agNULL)
{
SM_DBG1(("smsatAllocIntIoResource: ***** ASSERT satDevData is null!!!\n"));
return agNULL;
}
tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
if (!SMLIST_EMPTY(&(satDevData->satFreeIntIoLinkList)))
{
SMLIST_DEQUEUE_FROM_HEAD(&smList, &(satDevData->satFreeIntIoLinkList));
}
else
{
tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
SM_DBG1(("smsatAllocIntIoResource() no more internal free link!!!\n"));
return agNULL;
}
if (smList == agNULL)
{
tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
SM_DBG1(("smsatAllocIntIoResource() FAIL to alloc satIntIo!!!\n"));
return agNULL;
}
satIntIo = SMLIST_OBJECT_BASE( smSatInternalIo_t, satIntIoLink, smList);
SM_DBG3(("smsatAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
SMLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
SMLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satActiveIntIoLinkList));
tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
#ifdef REMOVED
tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
SMLIST_DEQUEUE_THIS (smList);
SMLIST_ENQUEUE_AT_TAIL (smList, &(satDevData->satActiveIntIoLinkList));
tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
satIntIo = SMLIST_OBJECT_BASE( smSatInternalIo_t, satIntIoLink, smList);
SM_DBG3(("smsatAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
#endif
satIntIo->satIntReqBodyMem.totalLength = sizeof(smIORequestBody_t);
memAllocStatus = tdsmAllocMemory( smRoot,
&satIntIo->satIntReqBodyMem.osHandle,
(void **)&satIntIo->satIntRequestBody,
&satIntIo->satIntReqBodyMem.physAddrUpper,
&satIntIo->satIntReqBodyMem.physAddrLower,
8,
satIntIo->satIntReqBodyMem.totalLength,
agTRUE );
if (memAllocStatus != SM_RC_SUCCESS)
{
SM_DBG1(("smsatAllocIntIoResource() FAIL to alloc mem for Req Body!!!\n"));
tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
SMLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
SMLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
return agNULL;
}
if (dmaAllocLength != 0)
{
satIntIo->satIntDmaMem.totalLength = dmaAllocLength;
memAllocStatus = tdsmAllocMemory( smRoot,
&satIntIo->satIntDmaMem.osHandle,
(void **)&satIntIo->satIntDmaMem.virtPtr,
&satIntIo->satIntDmaMem.physAddrUpper,
&satIntIo->satIntDmaMem.physAddrLower,
8,
satIntIo->satIntDmaMem.totalLength,
agFALSE);
SM_DBG3(("smsatAllocIntIoResource: len %d \n", satIntIo->satIntDmaMem.totalLength));
SM_DBG3(("smsatAllocIntIoResource: pointer %p \n", satIntIo->satIntDmaMem.osHandle));
if (memAllocStatus != SM_RC_SUCCESS)
{
SM_DBG1(("smsatAllocIntIoResource() FAIL to alloc mem for DMA mem!!!\n"));
tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
SMLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
SMLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
tdsmFreeMemory( smRoot,
satIntIo->satIntReqBodyMem.osHandle,
satIntIo->satIntReqBodyMem.totalLength);
return agNULL;
}
}
satIntIo->satIntSmIORequest.tdData = agNULL;
satIntIo->satIntSmIORequest.smData = satIntIo->satIntRequestBody;
satIntIo->satOrgSmIORequest = smIORequest;
if (dmaAllocLength != 0)
{
satIntIo->satIntSmScsiXchg.sglVirtualAddr = satIntIo->satIntDmaMem.virtPtr;
OSSA_WRITE_LE_32(agNULL, &satIntIo->satIntSmScsiXchg.smSgl1.len, 0,
satIntIo->satIntDmaMem.totalLength);
satIntIo->satIntSmScsiXchg.smSgl1.lower = satIntIo->satIntDmaMem.physAddrLower;
satIntIo->satIntSmScsiXchg.smSgl1.upper = satIntIo->satIntDmaMem.physAddrUpper;
satIntIo->satIntSmScsiXchg.smSgl1.type = tiSgl;
satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength = satIntIo->satIntDmaMem.totalLength;
}
else
{
satIntIo->satIntSmScsiXchg.sglVirtualAddr = agNULL;
satIntIo->satIntSmScsiXchg.smSgl1.len = 0;
satIntIo->satIntSmScsiXchg.smSgl1.lower = 0;
satIntIo->satIntSmScsiXchg.smSgl1.upper = 0;
satIntIo->satIntSmScsiXchg.smSgl1.type = tiSgl;
satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength = 0;
}
SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.len %d\n", satIntIo->satIntSmScsiXchg.smSgl1.len));
SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.upper %d\n", satIntIo->satIntSmScsiXchg.smSgl1.upper));
SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.lower %d\n", satIntIo->satIntSmScsiXchg.smSgl1.lower));
SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.type %d\n", satIntIo->satIntSmScsiXchg.smSgl1.type));
SM_DBG5(("smsatAllocIntIoResource: return satIntIo %p\n", satIntIo));
return satIntIo;
}
osGLOBAL smDeviceData_t *
smAddToSharedcontext(
smRoot_t *smRoot,
agsaDevHandle_t *agDevHandle,
smDeviceHandle_t *smDeviceHandle,
agsaDevHandle_t *agExpDevHandle,
bit32 phyID
)
{
smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData;
smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
smDeviceData_t *oneDeviceData = agNULL;
smList_t *DeviceListList;
bit32 new_device = agTRUE;
SM_DBG2(("smAddToSharedcontext: start\n"));
DeviceListList = smAllShared->MainDeviceList.flink;
while (DeviceListList != &(smAllShared->MainDeviceList))
{
oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, MainLink, DeviceListList);
if (oneDeviceData == agNULL)
{
SM_DBG1(("smAddToSharedcontext: oneDeviceData is NULL!!!\n"));
return agNULL;
}
if (oneDeviceData->agDevHandle == agDevHandle)
{
SM_DBG2(("smAddToSharedcontext: did %d\n", oneDeviceData->id));
new_device = agFALSE;
break;
}
DeviceListList = DeviceListList->flink;
}
if (new_device == agTRUE)
{
SM_DBG2(("smAddToSharedcontext: new device\n"));
tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK);
if (SMLIST_EMPTY(&(smAllShared->FreeDeviceList)))
{
tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
SM_DBG1(("smAddToSharedcontext: empty DeviceData FreeLink!!!\n"));
smDeviceHandle->smData = agNULL;
return agNULL;
}
SMLIST_DEQUEUE_FROM_HEAD(&DeviceListList, &(smAllShared->FreeDeviceList));
tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, FreeLink, DeviceListList);
oneDeviceData->smRoot = smRoot;
oneDeviceData->agDevHandle = agDevHandle;
oneDeviceData->valid = agTRUE;
smDeviceHandle->smData = oneDeviceData;
oneDeviceData->smDevHandle = smDeviceHandle;
if (agExpDevHandle == agNULL)
{
oneDeviceData->directlyAttached = agTRUE;
}
else
{
oneDeviceData->directlyAttached = agFALSE;
}
oneDeviceData->agExpDevHandle = agExpDevHandle;
oneDeviceData->phyID = phyID;
oneDeviceData->satPendingIO = 0;
oneDeviceData->satPendingNCQIO = 0;
oneDeviceData->satPendingNONNCQIO = 0;
tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK);
SMLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->MainLink), &(smAllShared->MainDeviceList));
tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
SM_DBG2(("smAddToSharedcontext: new case did %d\n", oneDeviceData->id));
}
else
{
SM_DBG2(("smAddToSharedcontext: old device\n"));
oneDeviceData->smRoot = smRoot;
oneDeviceData->agDevHandle = agDevHandle;
oneDeviceData->valid = agTRUE;
smDeviceHandle->smData = oneDeviceData;
oneDeviceData->smDevHandle = smDeviceHandle;
if (agExpDevHandle == agNULL)
{
oneDeviceData->directlyAttached = agTRUE;
}
else
{
oneDeviceData->directlyAttached = agFALSE;
}
oneDeviceData->agExpDevHandle = agExpDevHandle;
oneDeviceData->phyID = phyID;
oneDeviceData->satPendingIO = 0;
oneDeviceData->satPendingNCQIO = 0;
oneDeviceData->satPendingNONNCQIO = 0;
SM_DBG2(("smAddToSharedcontext: old case did %d\n", oneDeviceData->id));
}
return oneDeviceData;
}
osGLOBAL bit32
smRemoveFromSharedcontext(
smRoot_t *smRoot,
agsaDevHandle_t *agDevHandle,
smDeviceHandle_t *smDeviceHandle
)
{
smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData;
smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
smDeviceData_t *oneDeviceData = agNULL;
SM_DBG2(("smRemoveFromSharedcontext: start\n"));
oneDeviceData = smFindInSharedcontext(smRoot, agDevHandle);
if (oneDeviceData == agNULL)
{
return SM_RC_FAILURE;
}
else
{
if (oneDeviceData->valid == agTRUE)
{
smDeviceDataReInit(smRoot, oneDeviceData);
tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK);
SMLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink));
SMLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(smAllShared->FreeDeviceList));
tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
return SM_RC_SUCCESS;
}
else
{
SM_DBG1(("smRemoveFromSharedcontext: did %d bad case!!!\n", oneDeviceData->id));
return SM_RC_FAILURE;
}
}
}
osGLOBAL smDeviceData_t *
smFindInSharedcontext(
smRoot_t *smRoot,
agsaDevHandle_t *agDevHandle
)
{
smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData;
smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
smDeviceData_t *oneDeviceData = agNULL;
smList_t *DeviceListList;
SM_DBG2(("smFindInSharedcontext: start\n"));
tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK);
if (SMLIST_EMPTY(&(smAllShared->MainDeviceList)))
{
SM_DBG1(("smFindInSharedcontext: empty MainDeviceList!!!\n"));
tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
return agNULL;
}
else
{
tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
}
DeviceListList = smAllShared->MainDeviceList.flink;
while (DeviceListList != &(smAllShared->MainDeviceList))
{
oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, MainLink, DeviceListList);
if (oneDeviceData == agNULL)
{
SM_DBG1(("smFindInSharedcontext: oneDeviceData is NULL!!!\n"));
return agNULL;
}
if ((oneDeviceData->agDevHandle == agDevHandle) &&
(oneDeviceData->valid == agTRUE)
)
{
SM_DBG2(("smFindInSharedcontext: found, did %d\n", oneDeviceData->id));
return oneDeviceData;
}
DeviceListList = DeviceListList->flink;
}
SM_DBG2(("smFindInSharedcontext: not found\n"));
return agNULL;
}
osGLOBAL smSatIOContext_t *
smsatPrepareNewIO(
smSatInternalIo_t *satNewIntIo,
smIORequest_t *smOrgIORequest,
smDeviceData_t *satDevData,
smIniScsiCmnd_t *scsiCmnd,
smSatIOContext_t *satOrgIOContext
)
{
smSatIOContext_t *satNewIOContext;
smIORequestBody_t *smNewIORequestBody;
SM_DBG3(("smsatPrepareNewIO: start\n"));
satNewIntIo->satOrgSmIORequest = smOrgIORequest;
smNewIORequestBody = (smIORequestBody_t *)satNewIntIo->satIntRequestBody;
satNewIOContext = &(smNewIORequestBody->transport.SATA.satIOContext);
satNewIOContext->pSatDevData = satDevData;
satNewIOContext->pFis = &(smNewIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
satNewIOContext->pScsiCmnd = &(satNewIntIo->satIntSmScsiXchg.scsiCmnd);
if (scsiCmnd != agNULL)
{
sm_memcpy(satNewIOContext->pScsiCmnd->cdb, scsiCmnd->cdb, 16);
}
satNewIOContext->pSense = &(smNewIORequestBody->transport.SATA.sensePayload);
satNewIOContext->pSmSenseData = &(smNewIORequestBody->transport.SATA.smSenseData);
satNewIOContext->pSmSenseData->senseData = satNewIOContext->pSense;
satNewIOContext->smRequestBody = satNewIntIo->satIntRequestBody;
satNewIOContext->interruptContext = satNewIOContext->interruptContext;
satNewIOContext->satIntIoContext = satNewIntIo;
satNewIOContext->psmDeviceHandle = satOrgIOContext->psmDeviceHandle;
satNewIOContext->satOrgIOContext = satOrgIOContext;
satNewIOContext->smScsiXchg = satOrgIOContext->smScsiXchg;
return satNewIOContext;
}
osGLOBAL void
smsatSetDevInfo(
smDeviceData_t *oneDeviceData,
agsaSATAIdentifyData_t *SATAIdData
)
{
SM_DBG3(("smsatSetDevInfo: start\n"));
oneDeviceData->satDriveState = SAT_DEV_STATE_NORMAL;
oneDeviceData->satFormatState = agFALSE;
oneDeviceData->satDeviceFaultState = agFALSE;
oneDeviceData->satTmTaskTag = agNULL;
oneDeviceData->satAbortAfterReset = agFALSE;
oneDeviceData->satAbortCalled = agFALSE;
oneDeviceData->satSectorDone = 0;
oneDeviceData->satNCQMaxIO = SATAIdData->queueDepth + 1;
SM_DBG3(("smsatSetDevInfo: max queue depth %d\n",oneDeviceData->satNCQMaxIO));
if (SATAIdData->sataCapabilities & 0x100)
{
SM_DBG3(("smsatSetDevInfo: device supports NCQ\n"));
oneDeviceData->satNCQ = agTRUE;
}
else
{
SM_DBG3(("smsatSetDevInfo: no NCQ\n"));
oneDeviceData->satNCQ = agFALSE;
}
if ((SATAIdData->commandSetSupported1 & 0x400) &&
(SATAIdData->commandSetFeatureEnabled1 & 0x400) )
{
SM_DBG3(("smsatSetDevInfo: support 48 bit addressing\n"));
oneDeviceData->sat48BitSupport = agTRUE;
}
else
{
SM_DBG3(("smsatSetDevInfo: NO 48 bit addressing\n"));
oneDeviceData->sat48BitSupport = agFALSE;
}
if (SATAIdData->commandSetFeatureSupportedExt & 0x02)
{
SM_DBG3(("smsatSetDevInfo: SMART self-test supported \n"));
oneDeviceData->satSMARTSelfTest = agTRUE;
}
else
{
SM_DBG3(("smsatSetDevInfo: no SMART self-test suppored\n"));
oneDeviceData->satSMARTSelfTest = agFALSE;
}
if (SATAIdData->commandSetSupported & 0x01)
{
SM_DBG3(("smsatSetDevInfo: SMART feature set supported \n"));
oneDeviceData->satSMARTFeatureSet = agTRUE;
}
else
{
SM_DBG3(("smsatSetDevInfo: no SMART feature set suppored\n"));
oneDeviceData->satSMARTFeatureSet = agFALSE;
}
if (SATAIdData->commandSetFeatureEnabled & 0x01)
{
SM_DBG3(("smsatSetDevInfo: SMART enabled \n"));
oneDeviceData->satSMARTEnabled = agTRUE;
}
else
{
SM_DBG3(("smsatSetDevInfo: no SMART enabled\n"));
oneDeviceData->satSMARTEnabled = agFALSE;
}
oneDeviceData->satVerifyState = 0;
if (SATAIdData->commandSetSupported & 0x4)
{
SM_DBG3(("smsatSetDevInfo: Removable Media supported \n"));
oneDeviceData->satRemovableMedia = agTRUE;
}
else
{
SM_DBG3(("smsatSetDevInfo: no Removable Media suppored\n"));
oneDeviceData->satRemovableMedia = agFALSE;
}
if (SATAIdData->commandSetFeatureEnabled & 0x4)
{
SM_DBG3(("smsatSetDevInfo: Removable Media enabled\n"));
oneDeviceData->satRemovableMediaEnabled = agTRUE;
}
else
{
SM_DBG3(("smsatSetDevInfo: no Removable Media enabled\n"));
oneDeviceData->satRemovableMediaEnabled = agFALSE;
}
if (SATAIdData->dma_lba_iod_ios_stimer & 0x100)
{
SM_DBG3(("smsatSetDevInfo: DMA supported \n"));
oneDeviceData->satDMASupport = agTRUE;
}
else
{
SM_DBG3(("smsatSetDevInfo: no DMA suppored\n"));
oneDeviceData->satDMASupport = agFALSE;
}
if (SATAIdData->word62_74[0] & 0x8000)
{
SM_DBG3(("satSetDevInfo: DMADIR enabled\n"));
oneDeviceData->satDMADIRSupport = agTRUE;
}
else
{
SM_DBG3(("satSetDevInfo: DMADIR disabled\n"));
oneDeviceData->satDMADIRSupport = agFALSE;
}
if (SATAIdData->ultraDMAModes & 0x7F7F)
{
SM_DBG3(("smsatSetDevInfo: DMA enabled \n"));
oneDeviceData->satDMAEnabled = agTRUE;
if (SATAIdData->ultraDMAModes & 0x40)
{
oneDeviceData->satUltraDMAMode = 6;
}
else if (SATAIdData->ultraDMAModes & 0x20)
{
oneDeviceData->satUltraDMAMode = 5;
}
else if (SATAIdData->ultraDMAModes & 0x10)
{
oneDeviceData->satUltraDMAMode = 4;
}
else if (SATAIdData->ultraDMAModes & 0x08)
{
oneDeviceData->satUltraDMAMode = 3;
}
else if (SATAIdData->ultraDMAModes & 0x04)
{
oneDeviceData->satUltraDMAMode = 2;
}
else if (SATAIdData->ultraDMAModes & 0x01)
{
oneDeviceData->satUltraDMAMode = 1;
}
}
else
{
SM_DBG3(("smsatSetDevInfo: no DMA enabled\n"));
oneDeviceData->satDMAEnabled = agFALSE;
oneDeviceData->satUltraDMAMode = 0;
}
oneDeviceData->satMaxUserAddrSectors
= (SATAIdData->numOfUserAddressableSectorsHi << (8*2) )
+ SATAIdData->numOfUserAddressableSectorsLo;
SM_DBG3(("smsatSetDevInfo: MaxUserAddrSectors 0x%x decimal %d\n", oneDeviceData->satMaxUserAddrSectors, oneDeviceData->satMaxUserAddrSectors));
if (SATAIdData->commandSetSupported & 0x40)
{
SM_DBG3(("smsatSetDevInfo: Read Look-ahead is supported\n"));
oneDeviceData->satReadLookAheadSupport= agTRUE;
}
else
{
SM_DBG3(("smsatSetDevInfo: Read Look-ahead is not supported\n"));
oneDeviceData->satReadLookAheadSupport= agFALSE;
}
if (SATAIdData->commandSetSupported & 0x20)
{
SM_DBG3(("smsatSetDevInfo: Volatile Write Cache is supported\n"));
oneDeviceData->satVolatileWriteCacheSupport = agTRUE;
}
else
{
SM_DBG3(("smsatSetDevInfo: Volatile Write Cache is not supported\n"));
oneDeviceData->satVolatileWriteCacheSupport = agFALSE;
}
if (SATAIdData->commandSetFeatureEnabled & 0x20)
{
SM_DBG3(("smsatSetDevInfo: write cache enabled\n"));
oneDeviceData->satWriteCacheEnabled = agTRUE;
}
else
{
SM_DBG3(("smsatSetDevInfo: no write cache enabled\n"));
oneDeviceData->satWriteCacheEnabled = agFALSE;
}
if (SATAIdData->commandSetFeatureEnabled & 0x40)
{
SM_DBG3(("smsatSetDevInfo: look ahead enabled\n"));
oneDeviceData->satLookAheadEnabled = agTRUE;
}
else
{
SM_DBG3(("smsatSetDevInfo: no look ahead enabled\n"));
oneDeviceData->satLookAheadEnabled = agFALSE;
}
if (SATAIdData->commandSetFeatureDefault & 0x100)
{
SM_DBG3(("smsatSetDevInfo: device supports WWN\n"));
oneDeviceData->satWWNSupport = agTRUE;
}
else
{
SM_DBG3(("smsatSetDevInfo: no WWN\n"));
oneDeviceData->satWWNSupport = agFALSE;
}
if (SATAIdData->sataFeaturesSupported & 0x4)
{
SM_DBG3(("smsatSetDevInfo: device supports DMA Setup Auto-Activate\n"));
oneDeviceData->satDMASetupAA = agTRUE;
}
else
{
SM_DBG3(("smsatSetDevInfo: no DMA Setup Auto-Activate\n"));
oneDeviceData->satDMASetupAA = agFALSE;
}
if (SATAIdData->word77 & 0x10)
{
SM_DBG3(("smsatSetDevInfo: device supports NCQ Queue Management Command\n"));
oneDeviceData->satNCQQMgntCmd = agTRUE;
}
else
{
SM_DBG3(("smsatSetDevInfo: no NCQ Queue Management Command\n"));
oneDeviceData->satNCQQMgntCmd = agFALSE;
}
return;
}
osGLOBAL void
smsatInquiryStandard(
bit8 *pInquiry,
agsaSATAIdentifyData_t *pSATAIdData,
smIniScsiCmnd_t *scsiCmnd
)
{
smLUN_t *pLun;
pLun = &scsiCmnd->lun;
SM_DBG5(("smsatInquiryStandard: start\n"));
if (pInquiry == agNULL)
{
SM_DBG1(("smsatInquiryStandard: pInquiry is NULL, wrong\n"));
return;
}
else
{
SM_DBG5(("smsatInquiryStandard: pInquiry is NOT NULL\n"));
}
if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) )
{
pInquiry[0] = 0x7F;
}
else
{
pInquiry[0] = 0x00;
}
if (pSATAIdData->rm_ataDevice & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
{
pInquiry[1] = 0x80;
}
else
{
pInquiry[1] = 0x00;
}
pInquiry[2] = 0x05;
pInquiry[3] = 0x12;
pInquiry[4] = 0x1F;
pInquiry[5] = 0x00;
if (pSATAIdData->sataCapabilities & 0x100)
{
pInquiry[6] = 0x00;
pInquiry[7] = 0x02;
}
else
{
pInquiry[6] = 0x80;
pInquiry[7] = 0x00;
}
sm_strncpy((char*)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8);
pInquiry[16] = pSATAIdData->modelNumber[1];
pInquiry[17] = pSATAIdData->modelNumber[0];
pInquiry[18] = pSATAIdData->modelNumber[3];
pInquiry[19] = pSATAIdData->modelNumber[2];
pInquiry[20] = pSATAIdData->modelNumber[5];
pInquiry[21] = pSATAIdData->modelNumber[4];
pInquiry[22] = pSATAIdData->modelNumber[7];
pInquiry[23] = pSATAIdData->modelNumber[6];
pInquiry[24] = pSATAIdData->modelNumber[9];
pInquiry[25] = pSATAIdData->modelNumber[8];
pInquiry[26] = pSATAIdData->modelNumber[11];
pInquiry[27] = pSATAIdData->modelNumber[10];
pInquiry[28] = pSATAIdData->modelNumber[13];
pInquiry[29] = pSATAIdData->modelNumber[12];
pInquiry[30] = pSATAIdData->modelNumber[15];
pInquiry[31] = pSATAIdData->modelNumber[14];
if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
(pSATAIdData->firmwareVersion[5] == 0x20 ) &&
(pSATAIdData->firmwareVersion[6] == 0x20 ) &&
(pSATAIdData->firmwareVersion[7] == 0x20 )
)
{
pInquiry[32] = pSATAIdData->firmwareVersion[1];
pInquiry[33] = pSATAIdData->firmwareVersion[0];
pInquiry[34] = pSATAIdData->firmwareVersion[3];
pInquiry[35] = pSATAIdData->firmwareVersion[2];
}
else
{
pInquiry[32] = pSATAIdData->firmwareVersion[5];
pInquiry[33] = pSATAIdData->firmwareVersion[4];
pInquiry[34] = pSATAIdData->firmwareVersion[7];
pInquiry[35] = pSATAIdData->firmwareVersion[6];
}
#ifdef REMOVED
pInquiry[16] = pSATAIdData->modelNumber[0];
pInquiry[17] = pSATAIdData->modelNumber[1];
pInquiry[18] = pSATAIdData->modelNumber[2];
pInquiry[19] = pSATAIdData->modelNumber[3];
pInquiry[20] = pSATAIdData->modelNumber[4];
pInquiry[21] = pSATAIdData->modelNumber[5];
pInquiry[22] = pSATAIdData->modelNumber[6];
pInquiry[23] = pSATAIdData->modelNumber[7];
pInquiry[24] = pSATAIdData->modelNumber[8];
pInquiry[25] = pSATAIdData->modelNumber[9];
pInquiry[26] = pSATAIdData->modelNumber[10];
pInquiry[27] = pSATAIdData->modelNumber[11];
pInquiry[28] = pSATAIdData->modelNumber[12];
pInquiry[29] = pSATAIdData->modelNumber[13];
pInquiry[30] = pSATAIdData->modelNumber[14];
pInquiry[31] = pSATAIdData->modelNumber[15];
if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
(pSATAIdData->firmwareVersion[5] == 0x20 ) &&
(pSATAIdData->firmwareVersion[6] == 0x20 ) &&
(pSATAIdData->firmwareVersion[7] == 0x20 )
)
{
pInquiry[32] = pSATAIdData->firmwareVersion[0];
pInquiry[33] = pSATAIdData->firmwareVersion[1];
pInquiry[34] = pSATAIdData->firmwareVersion[2];
pInquiry[35] = pSATAIdData->firmwareVersion[3];
}
else
{
pInquiry[32] = pSATAIdData->firmwareVersion[4];
pInquiry[33] = pSATAIdData->firmwareVersion[5];
pInquiry[34] = pSATAIdData->firmwareVersion[6];
pInquiry[35] = pSATAIdData->firmwareVersion[7];
}
#endif
SM_DBG5(("smsatInquiryStandard: end\n"));
return;
}
osGLOBAL void
smsatInquiryPage0(
bit8 *pInquiry,
agsaSATAIdentifyData_t *pSATAIdData
)
{
SM_DBG5(("smsatInquiryPage0: start\n"));
pInquiry[0] = 0x00;
pInquiry[1] = 0x00;
pInquiry[2] = 0x00;
pInquiry[3] = 8 - 3;
pInquiry[4] = 0x00;
pInquiry[5] = 0x80;
pInquiry[6] = 0x83;
pInquiry[7] = 0x89;
pInquiry[8] = 0xB1;
return;
}
osGLOBAL void
smsatInquiryPage83(
bit8 *pInquiry,
agsaSATAIdentifyData_t *pSATAIdData,
smDeviceData_t *oneDeviceData
)
{
satSimpleSATAIdentifyData_t *pSimpleData;
pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
SM_DBG5(("smsatInquiryPage83: start\n"));
pInquiry[0] = 0x00;
pInquiry[1] = 0x83;
pInquiry[2] = 0;
if ( oneDeviceData->satWWNSupport)
{
#ifndef PMC_FREEBSD
pInquiry[3] = 12;
pInquiry[4] = 0x01;
pInquiry[5] = 0x03;
pInquiry[6] = 0x00;
pInquiry[7] = 0x08;
pInquiry[8] = (bit8)((pSATAIdData->namingAuthority) >> 8);
pInquiry[9] = (bit8)((pSATAIdData->namingAuthority) & 0xFF);
pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8);
pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF);
pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8);
pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF);
pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8);
pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF);
#else
pInquiry[3] = 24;
pInquiry[4] = 0x01;
pInquiry[5] = 0x03;
pInquiry[6] = 0x00;
pInquiry[7] = 0x08;
pInquiry[8] = (bit8)((pSATAIdData->namingAuthority) >> 8);
pInquiry[9] = (bit8)((pSATAIdData->namingAuthority) & 0xFF);
pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8);
pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF);
pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8);
pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF);
pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8);
pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF);
pInquiry[16] = 0x61;
pInquiry[17] = 0x93;
pInquiry[18] = 0x00;
pInquiry[19] = 0x08;
SM_DBG5(("smsatInquiryPage83: sasAddressHi 0x%08x\n", oneDeviceData->sasAddressHi));
SM_DBG5(("smsatInquiryPage83: sasAddressLo 0x%08x\n", oneDeviceData->sasAddressLo));
pInquiry[20] = ((oneDeviceData->sasAddressHi) & 0xFF000000 ) >> 24;
pInquiry[21] = ((oneDeviceData->sasAddressHi) & 0xFF0000 ) >> 16;
pInquiry[22] = ((oneDeviceData->sasAddressHi) & 0xFF00 ) >> 8;
pInquiry[23] = (oneDeviceData->sasAddressHi) & 0xFF;
pInquiry[24] = ((oneDeviceData->sasAddressLo) & 0xFF000000 ) >> 24;
pInquiry[25] = ((oneDeviceData->sasAddressLo) & 0xFF0000 ) >> 16;
pInquiry[26] = ((oneDeviceData->sasAddressLo) & 0xFF00 ) >> 8;
pInquiry[27] = (oneDeviceData->sasAddressLo) & 0xFF;
#endif
}
else
{
#ifndef PMC_FREEBSD
pInquiry[3] = 72;
pInquiry[4] = 0x02;
pInquiry[5] = 0x01;
pInquiry[6] = 0x00;
pInquiry[7] = 0x44;
sm_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8);
pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8);
pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff);
pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8);
pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff);
pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8);
pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff);
pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8);
pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff);
pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8);
pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff);
pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8);
pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff);
pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8);
pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff);
pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8);
pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff);
pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8);
pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff);
pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8);
pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff);
pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8);
pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff);
pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8);
pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff);
pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8);
pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff);
pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8);
pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff);
pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8);
pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff);
pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8);
pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff);
pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8);
pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff);
pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8);
pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff);
pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8);
pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff);
pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8);
pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff);
pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8);
pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff);
pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8);
pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff);
pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8);
pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff);
pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8);
pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff);
pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8);
pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff);
pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8);
pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff);
pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8);
pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff);
pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8);
pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff);
pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8);
pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff);
pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8);
pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff);
#else
pInquiry[3] = 84;
pInquiry[4] = 0x02;
pInquiry[5] = 0x01;
pInquiry[6] = 0x00;
pInquiry[7] = 0x44;
sm_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8);
pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8);
pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff);
pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8);
pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff);
pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8);
pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff);
pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8);
pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff);
pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8);
pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff);
pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8);
pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff);
pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8);
pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff);
pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8);
pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff);
pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8);
pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff);
pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8);
pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff);
pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8);
pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff);
pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8);
pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff);
pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8);
pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff);
pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8);
pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff);
pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8);
pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff);
pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8);
pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff);
pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8);
pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff);
pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8);
pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff);
pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8);
pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff);
pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8);
pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff);
pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8);
pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff);
pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8);
pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff);
pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8);
pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff);
pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8);
pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff);
pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8);
pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff);
pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8);
pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff);
pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8);
pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff);
pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8);
pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff);
pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8);
pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff);
pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8);
pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff);
pInquiry[76] = 0x61;
pInquiry[77] = 0x93;
pInquiry[78] = 0x00;
pInquiry[79] = 0x08;
SM_DBG5(("smsatInquiryPage83: NO WWN sasAddressHi 0x%08x\n", oneDeviceData->sasAddressHi));
SM_DBG5(("smsatInquiryPage83: No WWN sasAddressLo 0x%08x\n", oneDeviceData->sasAddressLo));
pInquiry[80] = ((oneDeviceData->sasAddressHi) & 0xFF000000 ) >> 24;
pInquiry[81] = ((oneDeviceData->sasAddressHi) & 0xFF0000 ) >> 16;
pInquiry[82] = ((oneDeviceData->sasAddressHi) & 0xFF00 ) >> 8;
pInquiry[83] = (oneDeviceData->sasAddressHi) & 0xFF;
pInquiry[84] = ((oneDeviceData->sasAddressLo) & 0xFF000000 ) >> 24;
pInquiry[85] = ((oneDeviceData->sasAddressLo) & 0xFF0000 ) >> 16;
pInquiry[86] = ((oneDeviceData->sasAddressLo) & 0xFF00 ) >> 8;
pInquiry[87] = (oneDeviceData->sasAddressLo) & 0xFF;
#endif
}
return;
}
osGLOBAL void
smsatInquiryPage89(
bit8 *pInquiry,
agsaSATAIdentifyData_t *pSATAIdData,
smDeviceData_t *oneDeviceData,
bit32 len
)
{
satSimpleSATAIdentifyData_t *pSimpleData;
pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
SM_DBG5(("smsatInquiryPage89: start\n"));
pInquiry[0] = 0x00;
pInquiry[1] = 0x89;
pInquiry[2] = 0x02;
pInquiry[3] = 0x38;
pInquiry[4] = 0x0;
pInquiry[5] = 0x0;
pInquiry[6] = 0x0;
pInquiry[7] = 0x0;
sm_strncpy((char*)&pInquiry[8], "PMC-SIERRA", 8);
sm_strncpy((char*)&pInquiry[16], "Tachyon-SPC ", 16);
sm_strncpy((char*)&pInquiry[32], "01", 4);
pInquiry[36] = 0x34;
if (oneDeviceData->satDeviceType == SATA_ATA_DEVICE)
{
pInquiry[37] = (bit8)((oneDeviceData->satPMField) >> (4 * 7));
}
else
{
pInquiry[37] = (bit8)(0x40 + (bit8)(((oneDeviceData->satPMField) >> (4 * 7))));
}
pInquiry[38] = 0;
pInquiry[39] = 0;
if (oneDeviceData->satDeviceType == SATA_ATA_DEVICE)
{
pInquiry[40] = 0x01;
pInquiry[41] = 0x00;
pInquiry[42] = 0x00;
pInquiry[43] = 0x00;
pInquiry[44] = 0x00;
pInquiry[45] = 0x00;
pInquiry[46] = 0x00;
pInquiry[47] = 0x00;
pInquiry[48] = 0x01;
pInquiry[49] = 0x00;
}
else
{
pInquiry[40] = 0x01;
pInquiry[41] = 0x00;
pInquiry[42] = 0x00;
pInquiry[43] = 0x00;
pInquiry[44] = 0x00;
pInquiry[45] = 0x00;
pInquiry[46] = 0x00;
pInquiry[47] = 0x00;
pInquiry[48] = 0x01;
pInquiry[49] = 0x00;
}
pInquiry[50] = 0x00;
pInquiry[51] = 0x00;
pInquiry[52] = 0x00;
pInquiry[53] = 0x00;
pInquiry[54] = 0x00;
pInquiry[55] = 0x00;
if (oneDeviceData->satDeviceType == SATA_ATA_DEVICE)
{
pInquiry[56] = 0xEC;
}
else
{
pInquiry[56] = 0xA1;
}
pInquiry[57] = 0x0;
pInquiry[58] = 0x0;
pInquiry[59] = 0x0;
if (len < SATA_PAGE89_INQUIRY_SIZE)
{
sm_memcpy(&pInquiry[60], pSimpleData, MIN((len - 60), sizeof(satSimpleSATAIdentifyData_t)));
}
else
{
sm_memcpy(&pInquiry[60], pSimpleData, sizeof(satSimpleSATAIdentifyData_t));
}
return;
}
osGLOBAL void
smsatInquiryPage80(
bit8 *pInquiry,
agsaSATAIdentifyData_t *pSATAIdData
)
{
SM_DBG5(("smsatInquiryPage89: start\n"));
pInquiry[0] = 0x00;
pInquiry[1] = 0x80;
pInquiry[2] = 0x00;
pInquiry[3] = 0x14;
pInquiry[4] = pSATAIdData->serialNumber[1];
pInquiry[5] = pSATAIdData->serialNumber[0];
pInquiry[6] = pSATAIdData->serialNumber[3];
pInquiry[7] = pSATAIdData->serialNumber[2];
pInquiry[8] = pSATAIdData->serialNumber[5];
pInquiry[9] = pSATAIdData->serialNumber[4];
pInquiry[10] = pSATAIdData->serialNumber[7];
pInquiry[11] = pSATAIdData->serialNumber[6];
pInquiry[12] = pSATAIdData->serialNumber[9];
pInquiry[13] = pSATAIdData->serialNumber[8];
pInquiry[14] = pSATAIdData->serialNumber[11];
pInquiry[15] = pSATAIdData->serialNumber[10];
pInquiry[16] = pSATAIdData->serialNumber[13];
pInquiry[17] = pSATAIdData->serialNumber[12];
pInquiry[18] = pSATAIdData->serialNumber[15];
pInquiry[19] = pSATAIdData->serialNumber[14];
pInquiry[20] = pSATAIdData->serialNumber[17];
pInquiry[21] = pSATAIdData->serialNumber[16];
pInquiry[22] = pSATAIdData->serialNumber[19];
pInquiry[23] = pSATAIdData->serialNumber[18];
return;
}
osGLOBAL void
smsatInquiryPageB1(
bit8 *pInquiry,
agsaSATAIdentifyData_t *pSATAIdData
)
{
bit32 i;
satSimpleSATAIdentifyData_t *pSimpleData;
SM_DBG5(("smsatInquiryPageB1: start\n"));
pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
pInquiry[0] = 0x00;
pInquiry[1] = 0xB1;
pInquiry[2] = 0x0;
pInquiry[3] = 0x3C;
pInquiry[4] = (bit8) ((pSimpleData->word[217]) >> 8);
pInquiry[5] = (bit8) ((pSimpleData->word[217]) & 0xFF);
pInquiry[6] = 0x0;
pInquiry[7] = (bit8) ((pSimpleData->word[168]) & 0xF);
for (i=8;i<64;i++)
{
pInquiry[i] = 0x0;
}
return;
}
osGLOBAL void
smsatDefaultTranslation(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smSatIOContext_t *satIOContext,
smScsiRspSense_t *pSense,
bit8 ataStatus,
bit8 ataError,
bit32 interruptContext
)
{
SM_DBG5(("smsatDefaultTranslation: start\n"));
if ( ataStatus & DF_ATA_STATUS_MASK )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_HARDWARE_ERROR,
0,
SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
interruptContext );
return;
}
if ( ataStatus & ERR_ATA_STATUS_MASK )
{
if ( ataError & NM_ATA_ERROR_MASK )
{
SM_DBG1(("smsatDefaultTranslation: NM_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
ataError, smIORequest));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_NOT_READY,
0,
SCSI_SNSCODE_MEDIUM_NOT_PRESENT,
satIOContext);
}
else if (ataError & UNC_ATA_ERROR_MASK)
{
SM_DBG1(("smsatDefaultTranslation: UNC_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
ataError, smIORequest));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_MEDIUM_ERROR,
0,
SCSI_SNSCODE_UNRECOVERED_READ_ERROR,
satIOContext);
}
else if (ataError & IDNF_ATA_ERROR_MASK)
{
SM_DBG1(("smsatDefaultTranslation: IDNF_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
ataError, smIORequest));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_MEDIUM_ERROR,
0,
SCSI_SNSCODE_RECORD_NOT_FOUND,
satIOContext);
}
else if (ataError & MC_ATA_ERROR_MASK)
{
SM_DBG1(("smsatDefaultTranslation: MC_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
ataError, smIORequest));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_UNIT_ATTENTION,
0,
SCSI_SNSCODE_NOT_READY_TO_READY_CHANGE,
satIOContext);
}
else if (ataError & MCR_ATA_ERROR_MASK)
{
SM_DBG1(("smsatDefaultTranslation: MCR_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
ataError, smIORequest));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_UNIT_ATTENTION,
0,
SCSI_SNSCODE_OPERATOR_MEDIUM_REMOVAL_REQUEST,
satIOContext);
}
else if (ataError & ICRC_ATA_ERROR_MASK)
{
SM_DBG1(("smsatDefaultTranslation: ICRC_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
ataError, smIORequest));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ABORTED_COMMAND,
0,
SCSI_SNSCODE_INFORMATION_UNIT_CRC_ERROR,
satIOContext);
}
else if (ataError & ABRT_ATA_ERROR_MASK)
{
SM_DBG1(("smsatDefaultTranslation: ABRT_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
ataError, smIORequest));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ABORTED_COMMAND,
0,
SCSI_SNSCODE_NO_ADDITIONAL_INFO,
satIOContext);
}
else
{
SM_DBG1(("smsatDefaultTranslation: **** UNEXPECTED ATA_ERROR **** ataError= 0x%x, smIORequest=%p!!!\n",
ataError, smIORequest));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_HARDWARE_ERROR,
0,
SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
satIOContext);
}
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
interruptContext );
return;
}
else
{
SM_DBG1(("smsatDefaultTranslation: *** UNEXPECTED ATA status 0x%x *** smIORequest=%p!!!\n",
ataStatus, smIORequest));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_HARDWARE_ERROR,
0,
SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
interruptContext );
return;
}
return;
}
osGLOBAL bit32
smIDStart(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle
)
{
smDeviceData_t *oneDeviceData = agNULL;
smIORequestBody_t *smIORequestBody = agNULL;
smSatIOContext_t *satIOContext = agNULL;
bit32 status = SM_RC_FAILURE;
SM_DBG2(("smIDStart: start, smIORequest %p\n", smIORequest));
oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
if (oneDeviceData == agNULL)
{
SM_DBG1(("smIDStart: oneDeviceData is NULL!!!\n"));
return SM_RC_FAILURE;
}
if (oneDeviceData->valid == agFALSE)
{
SM_DBG1(("smIDStart: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id));
return SM_RC_FAILURE;
}
smIORequestBody = (smIORequestBody_t*)smIORequest->smData;
if (smIORequestBody == agNULL)
{
SM_DBG1(("smIDStart: smIORequestBody is NULL!!!\n"));
return SM_RC_FAILURE;
}
smIOReInit(smRoot, smIORequestBody);
SM_DBG3(("smIDStart: io ID %d!!!\n", smIORequestBody->id ));
smIORequestBody->smIORequest = smIORequest;
smIORequestBody->smDevHandle = smDeviceHandle;
satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
satIOContext->pSatDevData = oneDeviceData;
satIOContext->pFis = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
satIOContext->smRequestBody = smIORequestBody;
satIOContext->psmDeviceHandle = smDeviceHandle;
satIOContext->smScsiXchg = agNULL;
SM_DBG3(("smIDStart: smIORequestBody %p smIORequestBody->smIORequest %p!!!\n", smIORequestBody, smIORequestBody->smIORequest));
SM_DBG1(("smIDStart: did %d\n", oneDeviceData->id));
status = smsatIDSubStart( smRoot,
smIORequest,
smDeviceHandle,
agNULL,
satIOContext);
if (status != SM_RC_SUCCESS)
{
SM_DBG1(("smIDStart: smsatIDSubStart failure %d!!!\n", status));
}
SM_DBG2(("smIDStart: exit\n"));
return status;
}
osGLOBAL bit32
smsatIDSubStart(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smSCSIRequest,
smSatIOContext_t *satIOContext
)
{
smSatInternalIo_t *satIntIo = agNULL;
smDeviceData_t *satDevData = agNULL;
smIORequestBody_t *smIORequestBody;
smSatIOContext_t *satNewIOContext;
bit32 status;
SM_DBG2(("smsatIDSubStart: start\n"));
satDevData = satIOContext->pSatDevData;
satIntIo = smsatAllocIntIoResource( smRoot,
smIORequest,
satDevData,
sizeof(agsaSATAIdentifyData_t),
satIntIo);
if (satIntIo == agNULL)
{
SM_DBG1(("smsatIDSubStart: can't alloacate!!!\n"));
return SM_RC_FAILURE;
}
satIOContext->satIntIoContext = satIntIo;
satIntIo->satOrgSmIORequest = smIORequest;
smIORequestBody = satIntIo->satIntRequestBody;
satNewIOContext = &(smIORequestBody->transport.SATA.satIOContext);
satNewIOContext->pSatDevData = satDevData;
satNewIOContext->pFis = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
satNewIOContext->pScsiCmnd = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
satNewIOContext->pSense = &(smIORequestBody->transport.SATA.sensePayload);
satNewIOContext->pSmSenseData = &(smIORequestBody->transport.SATA.smSenseData);
satNewIOContext->smRequestBody = satIntIo->satIntRequestBody;
satNewIOContext->satIntIoContext = satIntIo;
satNewIOContext->psmDeviceHandle = smDeviceHandle;
satNewIOContext->satOrgIOContext = satIOContext;
satNewIOContext->smScsiXchg = &(satIntIo->satIntSmScsiXchg);
SM_DBG6(("smsatIDSubStart: SM satIOContext %p \n", satIOContext));
SM_DBG6(("smsatIDSubStart: SM satNewIOContext %p \n", satNewIOContext));
SM_DBG6(("smsatIDSubStart: SM tiScsiXchg %p \n", satIOContext->smScsiXchg));
SM_DBG6(("smsatIDSubStart: SM tiScsiXchg %p \n", satNewIOContext->smScsiXchg));
SM_DBG3(("smsatIDSubStart: satNewIOContext %p smIORequestBody %p\n", satNewIOContext, smIORequestBody));
status = smsatIDStart(smRoot,
&satIntIo->satIntSmIORequest,
smDeviceHandle,
satNewIOContext->smScsiXchg,
satNewIOContext);
if (status != SM_RC_SUCCESS)
{
SM_DBG1(("smsatIDSubStart: failed in sending %d!!!\n", status));
smsatFreeIntIoResource( smRoot,
satDevData,
satIntIo);
return SM_RC_FAILURE;
}
SM_DBG2(("smsatIDSubStart: end\n"));
return status;
}
osGLOBAL bit32
smsatIDStart(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smSCSIRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
smDeviceData_t *pSatDevData;
agsaFisRegHostToDevice_t *fis;
#ifdef SM_INTERNAL_DEBUG
smIORequestBody_t *smIORequestBody;
smSatInternalIo_t *satIntIoContext;
#endif
pSatDevData = satIOContext->pSatDevData;
fis = satIOContext->pFis;
SM_DBG2(("smsatIDStart: start\n"));
#ifdef SM_INTERNAL_DEBUG
satIntIoContext = satIOContext->satIntIoContext;
smIORequestBody = satIntIoContext->satIntRequestBody;
#endif
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
{
SM_DBG2(("smsatIDStart: IDENTIFY_PACKET_DEVICE\n"));
fis->h.command = SAT_IDENTIFY_PACKET_DEVICE;
}
else
{
SM_DBG2(("smsatIDStart: IDENTIFY_DEVICE\n"));
fis->h.command = SAT_IDENTIFY_DEVICE;
}
fis->h.features = 0;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
satIOContext->satCompleteCB = &smsatIDStartCB;
satIOContext->reqType = agRequestType;
#ifdef SM_INTERNAL_DEBUG
smhexdump("smsatIDStart", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
smhexdump("smsatIDStart LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
#endif
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
SM_DBG2(("smsatIDStart: end status %d\n", status));
return status;
}
osGLOBAL FORCEINLINE bit32
smsatIOStart(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smSCSIRequest,
smSatIOContext_t *satIOContext
)
{
smDeviceData_t *pSatDevData = satIOContext->pSatDevData;
smScsiRspSense_t *pSense = satIOContext->pSense;
smIniScsiCmnd_t *scsiCmnd = &smSCSIRequest->scsiCmnd;
smLUN_t *pLun = &scsiCmnd->lun;
smSatInternalIo_t *pSatIntIo = agNULL;
bit32 status = SM_RC_FAILURE;
SM_DBG2(("smsatIOStart: start\n"));
if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) &&
(scsiCmnd->cdb[0] != SCSIOPC_INQUIRY)
)
{
SM_DBG1(("smsatIOStart: *** REJECT *** LUN not zero, cdb[0]=0x%x did %d !!!\n",
scsiCmnd->cdb[0], pSatDevData->id));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_NOT_SUPPORTED,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
SM_DBG2(("smsatIOStart: satPendingIO %d satNCQMaxIO %d\n",pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
if (pSatDevData->IDDeviceValid == agFALSE && (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY))
{
SM_DBG1(("smsatIOStart: invalid identify device data did %d !!!\n", pSatDevData->id));
SM_DBG1(("smsatIOStart: satPendingIO %d satNCQMaxIO %d\n", pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
SM_DBG1(("smsatIOStart: satPendingNCQIO %d satPendingNONNCQIO %d\n", pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
return SM_RC_NODEVICE;
}
if (pSatDevData->satDriveState == SAT_DEV_STATE_IN_RECOVERY)
{
SM_DBG1(("smsatIOStart: IN RECOVERY STATE cdb[0]=0x%x did=%d !!!\n",
scsiCmnd->cdb[0], pSatDevData->id));
SM_DBG2(("smsatIOStart: device %p satPendingIO %d satNCQMaxIO %d\n", pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
SM_DBG2(("smsatIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
return SM_RC_DEVICE_BUSY;
}
if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
{
if (scsiCmnd->cdb[0] == SCSIOPC_REPORT_LUN)
{
return smsatReportLun(smRoot, smIORequest, smDeviceHandle, smSCSIRequest, satIOContext);
}
else
{
return smsatPacket(smRoot, smIORequest, smDeviceHandle, smSCSIRequest, satIOContext);
}
}
else
{
switch(scsiCmnd->cdb[0])
{
case SCSIOPC_READ_10:
status = smsatRead10( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_WRITE_10:
status = smsatWrite10( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_READ_6:
status = smsatRead6( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_READ_12:
SM_DBG5(("smsatIOStart: SCSIOPC_READ_12\n"));
status = smsatRead12( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_READ_16:
status = smsatRead16( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_WRITE_6:
status = smsatWrite6( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_WRITE_12:
SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_12 \n"));
status = smsatWrite12( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_WRITE_16:
SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_16 \n"));
status = smsatWrite16( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_VERIFY_10:
status = smsatVerify10( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_VERIFY_12:
SM_DBG5(("smsatIOStart: SCSIOPC_VERIFY_12\n"));
status = smsatVerify12( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_VERIFY_16:
SM_DBG5(("smsatIOStart: SCSIOPC_VERIFY_16\n"));
status = smsatVerify16( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_TEST_UNIT_READY:
status = smsatTestUnitReady( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_INQUIRY:
status = smsatInquiry( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_REQUEST_SENSE:
status = smsatRequestSense( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_MODE_SENSE_6:
status = smsatModeSense6( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_MODE_SENSE_10:
status = smsatModeSense10( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_READ_CAPACITY_10:
status = smsatReadCapacity10( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_READ_CAPACITY_16:
status = smsatReadCapacity16( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_REPORT_LUN:
status = smsatReportLun( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_FORMAT_UNIT:
SM_DBG5(("smsatIOStart: SCSIOPC_FORMAT_UNIT\n"));
status = smsatFormatUnit( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_SEND_DIAGNOSTIC:
SM_DBG5(("smsatIOStart: SCSIOPC_SEND_DIAGNOSTIC\n"));
status = smsatSendDiagnostic( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_START_STOP_UNIT:
SM_DBG5(("smsatIOStart: SCSIOPC_START_STOP_UNIT\n"));
status = smsatStartStopUnit( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_WRITE_SAME_10:
SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_SAME_10\n"));
status = smsatWriteSame10( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_WRITE_SAME_16:
SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_SAME_16\n"));
status = smsatWriteSame16( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_LOG_SENSE:
SM_DBG5(("smsatIOStart: SCSIOPC_LOG_SENSE\n"));
status = smsatLogSense( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_MODE_SELECT_6:
SM_DBG5(("smsatIOStart: SCSIOPC_MODE_SELECT_6\n"));
status = smsatModeSelect6( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_MODE_SELECT_10:
SM_DBG5(("smsatIOStart: SCSIOPC_MODE_SELECT_10\n"));
status = smsatModeSelect10( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_SYNCHRONIZE_CACHE_10:
SM_DBG5(("smsatIOStart: SCSIOPC_SYNCHRONIZE_CACHE_10\n"));
status = smsatSynchronizeCache10( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_SYNCHRONIZE_CACHE_16:
SM_DBG5(("smsatIOStart: SCSIOPC_SYNCHRONIZE_CACHE_16\n"));
status = smsatSynchronizeCache16( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_WRITE_AND_VERIFY_10:
SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_AND_VERIFY_10\n"));
status = smsatWriteAndVerify10( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_WRITE_AND_VERIFY_12:
SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_AND_VERIFY_12\n"));
status = smsatWriteAndVerify12( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_WRITE_AND_VERIFY_16:
SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_AND_VERIFY_16\n"));
status = smsatWriteAndVerify16( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_READ_MEDIA_SERIAL_NUMBER:
SM_DBG5(("smsatIOStart: SCSIOPC_READ_MEDIA_SERIAL_NUMBER\n"));
status = smsatReadMediaSerialNumber( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_READ_BUFFER:
SM_DBG5(("smsatIOStart: SCSIOPC_READ_BUFFER\n"));
status = smsatReadBuffer( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_WRITE_BUFFER:
SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_BUFFER\n"));
status = smsatWriteBuffer( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_REASSIGN_BLOCKS:
SM_DBG5(("smsatIOStart: SCSIOPC_REASSIGN_BLOCKS\n"));
status = smsatReassignBlocks( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
case SCSIOPC_ATA_PASS_THROUGH12:
case SCSIOPC_ATA_PASS_THROUGH16:
SM_DBG5(("smsatIOStart: SCSIOPC_ATA_PASS_THROUGH\n"));
status = smsatPassthrough( smRoot,
smIORequest,
smDeviceHandle,
smSCSIRequest,
satIOContext);
break;
default:
SM_DBG1(("smsatIOStart: unsupported SCSI cdb[0]=0x%x did=%d !!!\n",
scsiCmnd->cdb[0], pSatDevData->id));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
status = SM_RC_SUCCESS;
break;
}
}
if (status == SM_RC_BUSY || status == SM_RC_DEVICE_BUSY)
{
SM_DBG1(("smsatIOStart: BUSY did %d!!!\n", pSatDevData->id));
SM_DBG2(("smsatIOStart: LL is busy or target queue is full\n"));
SM_DBG2(("smsatIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
SM_DBG2(("smsatIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
pSatIntIo = satIOContext->satIntIoContext;
smsatFreeIntIoResource( smRoot,
pSatDevData,
pSatIntIo);
}
return status;
}
osGLOBAL void
smsatSetSensePayload(
smScsiRspSense_t *pSense,
bit8 SnsKey,
bit32 SnsInfo,
bit16 SnsCode,
smSatIOContext_t *satIOContext)
{
bit32 i;
bit32 senseLength;
bit8 tmp = 0;
SM_DBG2(("smsatSetSensePayload: start\n"));
senseLength = sizeof(smScsiRspSense_t);
for (i=0;i< senseLength;i++)
{
((bit8*)pSense)[i] = 0;
}
pSense->snsRespCode = 0x70;
pSense->senseKey = SnsKey;
pSense->info[0] = (bit8)((SnsInfo >> 24) & 0xff);
pSense->info[1] = (bit8)((SnsInfo >> 16) & 0xff);
pSense->info[2] = (bit8)((SnsInfo >> 8) & 0xff);
pSense->info[3] = (bit8)((SnsInfo) & 0xff);
pSense->addSenseLen = 11;
pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF);
pSense->senseQual = (bit8)(SnsCode & 0xFF);
switch(SnsKey)
{
case SCSI_SNSKEY_ILLEGAL_REQUEST:
pSense->skeySpecific[0] = 0xC8;
break;
default:
break;
}
if (satIOContext != agNULL)
{
satIOContext->pSmSenseData->senseLen = 18;
}
else
{
SM_DBG1(("smsatSetSensePayload: satIOContext is NULL!!!\n"));
}
if (SnsCode == SCSI_SNSCODE_ATA_PASS_THROUGH_INFORMATION_AVAILABLE)
{
tmp = satIOContext->extend << 7 | satIOContext->Sector_Cnt_Upper_Nonzero << 6 | satIOContext->LBA_Upper_Nonzero << 5;
SM_DBG3(("smsatSetSensePayload: extend 0x%x Sector_Cnt_Upper_Nonzero 0x%x LBA_Upper_Nonzero 0x%x\n",
satIOContext->extend, satIOContext->Sector_Cnt_Upper_Nonzero, satIOContext->LBA_Upper_Nonzero));
SM_DBG3(("smsatSetSensePayload: tmp 0x%x\n", tmp));
pSense->cmdSpecific[0] = tmp;
pSense->cmdSpecific[1] = satIOContext->LBAHigh07;
pSense->cmdSpecific[2] = satIOContext->LBAMid07;
pSense->cmdSpecific[3] = satIOContext->LBALow07;
}
return;
}
GLOBAL bit32
smsatDecodeSATADeviceType(
bit8 *pSignature
)
{
bit32 deviceType = UNKNOWN_DEVICE;
if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
&& (pSignature)[2] == 0x00 && (pSignature)[3] == 0x00
&& (pSignature)[4] == 0xA0 )
{
deviceType = SATA_ATA_DEVICE;
}
else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
&& (pSignature)[2] == 0x00 && (pSignature)[3] == 0x00
&& (pSignature)[4] == 0x00 )
{
deviceType = SATA_ATA_DEVICE;
}
else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
&& (pSignature)[2] == 0x14 && (pSignature)[3] == 0xEB
&& ( (pSignature)[4] == 0x00 || (pSignature)[4] == 0x10) )
{
deviceType = SATA_ATAPI_DEVICE;
}
else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
&& (pSignature)[2] == 0x69 && (pSignature)[3] == 0x96
&& (pSignature)[4] == 0x00 )
{
deviceType = SATA_PM_DEVICE;
}
else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
&& (pSignature)[2] == 0x3C && (pSignature)[3] == 0xC3
&& (pSignature)[4] == 0x00 )
{
deviceType = SATA_SEMB_DEVICE;
}
else if ( (pSignature)[0] == 0xFF && (pSignature)[1] == 0xFF
&& (pSignature)[2] == 0xFF && (pSignature)[3] == 0xFF
&& (pSignature)[4] == 0xFF )
{
deviceType = SATA_SEMB_WO_SEP_DEVICE;
}
return deviceType;
}
osGLOBAL bit32
smsatPacket(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
smDeviceData_t *pSatDevData;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
SM_DBG3(("smsatPacket: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_PACKET;
if (pSatDevData->satDMADIRSupport)
{
fis->h.features = (smScsiRequest->dataDirection == smDirectionIn)? 0x04 : 0;
}
else
{
fis->h.features = 0;
}
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
fis->h.features |= 0x01;
}
else
{
fis->h.features |= 0x0;
}
if ( scsiCmnd->expDataLength > 0xFFFF )
{
fis->d.lbaMid = 0xFF;
fis->d.lbaHigh = 0xFF;
}
else
{
fis->d.lbaMid = (bit8)scsiCmnd->expDataLength;
fis->d.lbaHigh = (bit8)(scsiCmnd->expDataLength>>8);
}
fis->d.lbaLow = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
satIOContext->ATACmd = SAT_PACKET;
if (smScsiRequest->dataDirection == smDirectionIn)
{
agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
}
else
{
agRequestType = AGSA_SATA_PROTOCOL_H2D_PKT;
}
satIOContext->satCompleteCB = &smsatPacketCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart(smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG3(("smsatPacket: return\n"));
return (status);
}
osGLOBAL bit32
smsatSetFeaturesPIO(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status = SM_RC_FAILURE;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
fis = satIOContext->pFis;
SM_DBG2(("smsatSetFeaturesPIO: start\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SET_FEATURES;
fis->h.features = 0x03;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
fis->d.sectorCount = 0x0C;
satIOContext->satCompleteCB = &smsatSetFeaturesPIOCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG2(("smsatSetFeaturesPIO: return\n"));
if (smIORequest->tdData == smIORequest->smData)
{
SM_DBG1(("smsatSetFeaturesPIO: incorrect smIORequest\n"));
}
return status;
}
osGLOBAL bit32
smsatRequestSenseForATAPI(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
smDeviceData_t *pSatDevData;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
scsiCmnd->cdb[0] = SCSIOPC_REQUEST_SENSE;
scsiCmnd->cdb[1] = 0;
scsiCmnd->cdb[2] = 0;
scsiCmnd->cdb[3] = 0;
scsiCmnd->cdb[4] = (bit8)scsiCmnd->expDataLength;
scsiCmnd->cdb[5] = 0;
SM_DBG3(("smsatRequestSenseForATAPI: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_PACKET;
if (pSatDevData->satDMADIRSupport)
{
fis->h.features = (smScsiRequest->dataDirection == smDirectionIn)? 0x04 : 0;
}
else
{
fis->h.features = 0;
}
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
fis->h.features |= 0x01;
}
else
{
fis->h.features |= 0x0;
}
fis->d.lbaLow = 0;
fis->d.lbaMid = (bit8)scsiCmnd->expDataLength;
fis->d.lbaHigh = (bit8)(scsiCmnd->expDataLength>>8);
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
satIOContext->ATACmd = SAT_PACKET;
agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
satIOContext->satCompleteCB = &smsatRequestSenseForATAPICB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG3(("smsatRequestSenseForATAPI: return\n"));
return (status);
}
osGLOBAL bit32
smsatDeviceReset(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
fis = satIOContext->pFis;
SM_DBG3(("smsatDeviceReset: start\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_DEVICE_RESET;
fis->h.features = 0;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET;
satIOContext->satCompleteCB = &smsatDeviceResetCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG3(("smsatDeviceReset: return\n"));
return status;
}
osGLOBAL bit32
smsatExecuteDeviceDiagnostic(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
fis = satIOContext->pFis;
SM_DBG3(("smsatExecuteDeviceDiagnostic: start\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_EXECUTE_DEVICE_DIAGNOSTIC;
fis->h.features = 0;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatExecuteDeviceDiagnosticCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG3(("smsatExecuteDeviceDiagnostic: return\n"));
return status;
}
osGLOBAL void
smsatSetDeferredSensePayload(
smScsiRspSense_t *pSense,
bit8 SnsKey,
bit32 SnsInfo,
bit16 SnsCode,
smSatIOContext_t *satIOContext
)
{
SM_DBG2(("smsatSetDeferredSensePayload: start\n"));
return;
}
GLOBAL bit32
smsatRead6(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
smDeviceData_t *pSatDevData;
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit16 tl = 0;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
SM_DBG2(("smsatRead6: start\n"));
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatRead6: return control!!!\n"));
return SM_RC_SUCCESS;
}
lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
+ (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
tl = scsiCmnd->cdb[4];
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
if (lba > SAT_TR_LBA_LIMIT - 1)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatRead6: return LBA out of range!!!\n"));
return SM_RC_SUCCESS;
}
}
if (lba + tl <= SAT_TR_LBA_LIMIT)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatRead6: case 2\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_DMA;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[3];
fis->d.lbaMid = scsiCmnd->cdb[2];
fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f);
fis->d.device = 0x40;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (tl == 0)
{
fis->d.sectorCount = 0xff;
}
else
{
fis->d.sectorCount = scsiCmnd->cdb[4];
}
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
}
else
{
SM_DBG5(("smsatRead6: case 1\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[3];
fis->d.lbaMid = scsiCmnd->cdb[2];
fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f);
fis->d.device = 0x40;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (tl == 0)
{
fis->d.sectorCount = 0xff;
}
else
{
fis->d.sectorCount = scsiCmnd->cdb[4];
}
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
}
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatRead6: case 3\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_DMA_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[3];
fis->d.lbaMid = scsiCmnd->cdb[2];
fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f);
fis->d.device = 0x40;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (tl == 0)
{
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0x01;
}
else
{
fis->d.sectorCount = scsiCmnd->cdb[4];
fis->d.sectorCountExp = 0;
}
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
}
else
{
SM_DBG5(("smsatRead6: case 4\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[3];
fis->d.lbaMid = scsiCmnd->cdb[2];
fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f);
fis->d.device = 0x40;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (tl == 0)
{
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0x01;
}
else
{
fis->d.sectorCount = scsiCmnd->cdb[4];
fis->d.sectorCountExp = 0;
}
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
}
}
if (pSatDevData->satNCQ == agTRUE)
{
if (pSatDevData->sat48BitSupport != agTRUE)
{
SM_DBG1(("smsatRead6: case 5 !!! error NCQ but 28 bit address support!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
SM_DBG5(("smsatRead6: case 5\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_FPDMA_QUEUED;
fis->d.lbaLow = scsiCmnd->cdb[3];
fis->d.lbaMid = scsiCmnd->cdb[2];
fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f);
fis->d.device = 0x40;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
if (tl == 0)
{
fis->h.features = 0;
fis->d.featuresExp = 0x01;
}
else
{
fis->h.features = scsiCmnd->cdb[4];
fis->d.featuresExp = 0;
}
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
}
satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return (status);
}
osGLOBAL FORCEINLINE bit32
smsatRead10(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
smDeviceData_t *pSatDevData = satIOContext->pSatDevData;
smScsiRspSense_t *pSense = satIOContext->pSense;
smIniScsiCmnd_t *scsiCmnd = &smScsiRequest->scsiCmnd;
agsaFisRegHostToDevice_t *fis = satIOContext->pFis;
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[8];
bit8 TL[8];
bit32 AllChk = agFALSE;
SM_DBG2(("smsatRead10: start\n"));
SM_DBG2(("smsatRead10: pSatDevData did=%d\n", pSatDevData->id));
if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatRead10: return FUA_NV!!!\n"));
return SM_RC_SUCCESS;
}
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatRead10: return control!!!\n"));
return SM_RC_SUCCESS;
}
LBA[0] = 0;
LBA[1] = 0;
LBA[2] = 0;
LBA[3] = 0;
LBA[4] = scsiCmnd->cdb[2];
LBA[5] = scsiCmnd->cdb[3];
LBA[6] = scsiCmnd->cdb[4];
LBA[7] = scsiCmnd->cdb[5];
TL[0] = 0;
TL[1] = 0;
TL[2] = 0;
TL[3] = 0;
TL[4] = 0;
TL[5] = 0;
TL[6] = scsiCmnd->cdb[7];
TL[7] = scsiCmnd->cdb[8];
lba = (scsiCmnd->cdb[2] << 24) + (scsiCmnd->cdb[3] << 16)
+ (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
SM_DBG5(("smsatRead10: lba %d functioned lba %d\n", lba, smsatComputeCDB10LBA(satIOContext)));
SM_DBG5(("smsatRead10: lba 0x%x functioned lba 0x%x\n", lba, smsatComputeCDB10LBA(satIOContext)));
SM_DBG5(("smsatRead10: tl %d functioned tl %d\n", tl, smsatComputeCDB10TL(satIOContext)));
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatRead10: return LBA out of range, not EXT!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
else
{
AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatRead10: return LBA out of range, EXT!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
if (pSatDevData->satNCQ == agTRUE)
{
if (pSatDevData->sat48BitSupport != agTRUE)
{
SM_DBG1(("smsatRead10: case 5 !!! error NCQ but 28 bit address support!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
SM_DBG6(("smsatRead10: case 5\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_FPDMA_QUEUED;
fis->h.features = scsiCmnd->cdb[8];
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
fis->d.device = 0xC0;
else
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = scsiCmnd->cdb[7];
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
}
else if (pSatDevData->sat48BitSupport == agTRUE)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatRead10: case 3\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_DMA_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[8];
fis->d.sectorCountExp = scsiCmnd->cdb[7];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
satIOContext->ATACmd = SAT_READ_DMA_EXT;
}
else
{
SM_DBG5(("smsatRead10: case 4\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
fis->h.command = SAT_READ_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[8];
fis->d.sectorCountExp = scsiCmnd->cdb[7];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
}
}
else
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatRead10: case 2\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_DMA;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device =
(bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[8];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
satIOContext->ATACmd = SAT_READ_DMA;
}
else
{
SM_DBG5(("smsatRead10: case 1\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device =
(bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[8];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
satIOContext->ATACmd = SAT_READ_SECTORS;
}
}
satIOContext->currentLBA = lba;
satIOContext->OrgTL = tl;
if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
{
LoopNum = smsatComputeLoopNum(tl, 0x100);
}
else
{
LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
SM_DBG5(("smsatRead10: NON CHAINED data\n"));
satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
}
else
{
SM_DBG2(("smsatRead10: CHAINED data!!!\n"));
if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
{
fis->d.sectorCount = 0x0;
smsatSplitSGL(smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext,
NON_BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE,
(satIOContext->OrgTL)*SATA_SECTOR_SIZE,
agTRUE);
}
else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
{
fis->d.sectorCount = 0xFF;
fis->d.sectorCountExp = 0xFF;
smsatSplitSGL(smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext,
BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE,
(satIOContext->OrgTL)*SATA_SECTOR_SIZE,
agTRUE);
}
else
{
fis->h.features = 0xFF;
fis->d.featuresExp = 0xFF;
smsatSplitSGL(smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext,
BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE,
(satIOContext->OrgTL)*SATA_SECTOR_SIZE,
agTRUE);
}
satIOContext->satCompleteCB = &smsatChainedDataIOCB;
}
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG5(("smsatRead10: return\n"));
return (status);
}
osGLOBAL bit32
smsatRead12(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
smDeviceData_t *pSatDevData;
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[8];
bit8 TL[8];
bit32 AllChk = agFALSE;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
SM_DBG5(("smsatRead12: start\n"));
if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatRead12: return FUA_NV!!!\n"));
return SM_RC_SUCCESS;
}
if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatRead12: return control!!!\n"));
return SM_RC_SUCCESS;
}
sm_memset(LBA, 0, sizeof(LBA));
sm_memset(TL, 0, sizeof(TL));
LBA[0] = 0;
LBA[1] = 0;
LBA[2] = 0;
LBA[3] = 0;
LBA[4] = scsiCmnd->cdb[2];
LBA[5] = scsiCmnd->cdb[3];
LBA[6] = scsiCmnd->cdb[4];
LBA[7] = scsiCmnd->cdb[5];
TL[0] = 0;
TL[1] = 0;
TL[2] = 0;
TL[3] = 0;
TL[4] = scsiCmnd->cdb[6];
TL[5] = scsiCmnd->cdb[7];
TL[6] = scsiCmnd->cdb[8];
TL[7] = scsiCmnd->cdb[9];
lba = smsatComputeCDB12LBA(satIOContext);
tl = smsatComputeCDB12TL(satIOContext);
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatRead12: return LBA out of range, not EXT!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
else
{
AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatRead12: return LBA out of range, EXT!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatRead12: case 2\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_DMA;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device =
(bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[9];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
satIOContext->ATACmd = SAT_READ_DMA;
}
else
{
SM_DBG5(("smsatRead12: case 1\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device =
(bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[9];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
satIOContext->ATACmd = SAT_READ_SECTORS;
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatRead12: case 3\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_DMA_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[9];
fis->d.sectorCountExp = scsiCmnd->cdb[8];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
satIOContext->ATACmd = SAT_READ_DMA_EXT;
}
else
{
SM_DBG5(("smsatRead12: case 4\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
fis->h.command = SAT_READ_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[9];
fis->d.sectorCountExp = scsiCmnd->cdb[8];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
}
}
if (pSatDevData->satNCQ == agTRUE)
{
if (pSatDevData->sat48BitSupport != agTRUE)
{
SM_DBG1(("smsatRead12: case 5 !!! error NCQ but 28 bit address support!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
SM_DBG6(("smsatRead12: case 5\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_FPDMA_QUEUED;
fis->h.features = scsiCmnd->cdb[9];
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
fis->d.device = 0xC0;
else
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = scsiCmnd->cdb[8];
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
}
satIOContext->currentLBA = lba;
satIOContext->OrgTL = tl;
if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
{
LoopNum = smsatComputeLoopNum(tl, 0xFF);
}
else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
{
LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
}
else
{
LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
SM_DBG5(("smsatRead12: NON CHAINED data\n"));
satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
}
else
{
SM_DBG1(("smsatRead12: CHAINED data\n"));
if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
{
fis->d.sectorCount = 0xFF;
}
else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
{
fis->d.sectorCount = 0xFF;
fis->d.sectorCountExp = 0xFF;
}
else
{
fis->h.features = 0xFF;
fis->d.featuresExp = 0xFF;
}
satIOContext->satCompleteCB = &smsatChainedDataIOCB;
}
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG5(("smsatRead12: return\n"));
return (status);
}
osGLOBAL bit32
smsatRead16(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
smDeviceData_t *pSatDevData;
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[8];
bit8 TL[8];
bit32 AllChk = agFALSE;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
SM_DBG5(("smsatRead16: start\n"));
if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatRead16: return FUA_NV!!!\n"));
return SM_RC_SUCCESS;
}
if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatRead16: return control!!!\n"));
return SM_RC_SUCCESS;
}
sm_memset(LBA, 0, sizeof(LBA));
sm_memset(TL, 0, sizeof(TL));
LBA[0] = scsiCmnd->cdb[2];
LBA[1] = scsiCmnd->cdb[3];
LBA[2] = scsiCmnd->cdb[4];
LBA[3] = scsiCmnd->cdb[5];
LBA[4] = scsiCmnd->cdb[6];
LBA[5] = scsiCmnd->cdb[7];
LBA[6] = scsiCmnd->cdb[8];
LBA[7] = scsiCmnd->cdb[9];
TL[0] = 0;
TL[1] = 0;
TL[2] = 0;
TL[3] = 0;
TL[4] = scsiCmnd->cdb[10];
TL[5] = scsiCmnd->cdb[11];
TL[6] = scsiCmnd->cdb[12];
TL[7] = scsiCmnd->cdb[13];
lba = smsatComputeCDB16LBA(satIOContext);
tl = smsatComputeCDB16TL(satIOContext);
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatRead16: return LBA out of range, not EXT!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
else
{
AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatRead16: return LBA out of range, EXT!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatRead16: case 2\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_DMA;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[9];
fis->d.lbaMid = scsiCmnd->cdb[8];
fis->d.lbaHigh = scsiCmnd->cdb[7];
fis->d.device =
(bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[13];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
satIOContext->ATACmd = SAT_READ_DMA;
}
else
{
SM_DBG5(("smsatRead16: case 1\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[9];
fis->d.lbaMid = scsiCmnd->cdb[8];
fis->d.lbaHigh = scsiCmnd->cdb[7];
fis->d.device =
(bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[13];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
satIOContext->ATACmd = SAT_READ_SECTORS;
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatRead16: case 3\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_DMA_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[9];
fis->d.lbaMid = scsiCmnd->cdb[8];
fis->d.lbaHigh = scsiCmnd->cdb[7];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[6];
fis->d.lbaMidExp = scsiCmnd->cdb[5];
fis->d.lbaHighExp = scsiCmnd->cdb[4];
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[13];
fis->d.sectorCountExp = scsiCmnd->cdb[12];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
satIOContext->ATACmd = SAT_READ_DMA_EXT;
}
else
{
SM_DBG5(("smsatRead16: case 4\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
fis->h.command = SAT_READ_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[9];
fis->d.lbaMid = scsiCmnd->cdb[8];
fis->d.lbaHigh = scsiCmnd->cdb[7];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[6];
fis->d.lbaMidExp = scsiCmnd->cdb[5];
fis->d.lbaHighExp = scsiCmnd->cdb[4];
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[13];
fis->d.sectorCountExp = scsiCmnd->cdb[12];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
}
}
if (pSatDevData->satNCQ == agTRUE)
{
if (pSatDevData->sat48BitSupport != agTRUE)
{
SM_DBG1(("smsatRead16: case 5 !!! error NCQ but 28 bit address support!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
SM_DBG6(("smsatRead16: case 5\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_FPDMA_QUEUED;
fis->h.features = scsiCmnd->cdb[13];
fis->d.lbaLow = scsiCmnd->cdb[9];
fis->d.lbaMid = scsiCmnd->cdb[8];
fis->d.lbaHigh = scsiCmnd->cdb[7];
if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
fis->d.device = 0xC0;
else
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[6];
fis->d.lbaMidExp = scsiCmnd->cdb[5];
fis->d.lbaHighExp = scsiCmnd->cdb[4];
fis->d.featuresExp = scsiCmnd->cdb[12];
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
}
satIOContext->currentLBA = lba;
satIOContext->OrgTL = tl;
if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
{
LoopNum = smsatComputeLoopNum(tl, 0xFF);
}
else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
{
LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
}
else
{
LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
SM_DBG5(("smsatRead16: NON CHAINED data\n"));
satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
}
else
{
SM_DBG1(("smsatRead16: CHAINED data!!!\n"));
if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
{
fis->d.sectorCount = 0xFF;
}
else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
{
fis->d.sectorCount = 0xFF;
fis->d.sectorCountExp = 0xFF;
}
else
{
fis->h.features = 0xFF;
fis->d.featuresExp = 0xFF;
}
satIOContext->satCompleteCB = &smsatChainedDataIOCB;
}
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG5(("smsatRead16: return\n"));
return (status);
}
osGLOBAL bit32
smsatWrite6(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
smDeviceData_t *pSatDevData;
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit16 tl = 0;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
SM_DBG5(("smsatWrite6: start\n"));
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatWrite6: return control!!!\n"));
return SM_RC_SUCCESS;
}
lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
+ (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
tl = scsiCmnd->cdb[4];
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
if (lba > SAT_TR_LBA_LIMIT - 1)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatWrite6: return LBA out of range!!!\n"));
return SM_RC_SUCCESS;
}
}
if (lba + tl <= SAT_TR_LBA_LIMIT)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatWrite6: case 2\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[3];
fis->d.lbaMid = scsiCmnd->cdb[2];
fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f);
fis->d.device = 0x40;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (tl == 0)
{
fis->d.sectorCount = 0xff;
}
else
{
fis->d.sectorCount = scsiCmnd->cdb[4];
}
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
}
else
{
SM_DBG5(("smsatWrite6: case 1\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[3];
fis->d.lbaMid = scsiCmnd->cdb[2];
fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f);
fis->d.device = 0x40;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (tl == 0)
{
fis->d.sectorCount = 0xff;
}
else
{
fis->d.sectorCount = scsiCmnd->cdb[4];
}
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
}
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatWrite6: case 3\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[3];
fis->d.lbaMid = scsiCmnd->cdb[2];
fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f);
fis->d.device = 0x40;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (tl == 0)
{
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0x01;
}
else
{
fis->d.sectorCount = scsiCmnd->cdb[4];
fis->d.sectorCountExp = 0;
}
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
}
else
{
SM_DBG5(("smsatWrite6: case 4\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[3];
fis->d.lbaMid = scsiCmnd->cdb[2];
fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f);
fis->d.device = 0x40;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (tl == 0)
{
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0x01;
}
else
{
fis->d.sectorCount = scsiCmnd->cdb[4];
fis->d.sectorCountExp = 0;
}
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
}
}
if (pSatDevData->satNCQ == agTRUE)
{
if (pSatDevData->sat48BitSupport != agTRUE)
{
SM_DBG5(("smsatWrite6: case 5 !!! error NCQ but 28 bit address support!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
SM_DBG5(("smsatWrite6: case 5\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_FPDMA_QUEUED;
fis->d.lbaLow = scsiCmnd->cdb[3];
fis->d.lbaMid = scsiCmnd->cdb[2];
fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f);
fis->d.device = 0x40;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
if (tl == 0)
{
fis->h.features = 0;
fis->d.featuresExp = 0x01;
}
else
{
fis->h.features = scsiCmnd->cdb[4];
fis->d.featuresExp = 0;
}
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
}
satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return (status);
}
osGLOBAL FORCEINLINE bit32
smsatWrite10(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
smDeviceData_t *pSatDevData = satIOContext->pSatDevData;
smScsiRspSense_t *pSense = satIOContext->pSense;
smIniScsiCmnd_t *scsiCmnd = &smScsiRequest->scsiCmnd;
agsaFisRegHostToDevice_t *fis = satIOContext->pFis;
bit32 status = SM_RC_FAILURE;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit32 AllChk = agFALSE;
bit8 LBA[8];
bit8 TL[8];
SM_DBG2(("smsatWrite10: start\n"));
if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatWrite10: return FUA_NV!!!\n"));
return SM_RC_SUCCESS;
}
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatWrite10: return control!!!\n"));
return SM_RC_SUCCESS;
}
LBA[0] = 0;
LBA[1] = 0;
LBA[2] = 0;
LBA[3] = 0;
LBA[4] = scsiCmnd->cdb[2];
LBA[5] = scsiCmnd->cdb[3];
LBA[6] = scsiCmnd->cdb[4];
LBA[7] = scsiCmnd->cdb[5];
TL[0] = 0;
TL[1] = 0;
TL[2] = 0;
TL[3] = 0;
TL[4] = 0;
TL[5] = 0;
TL[6] = scsiCmnd->cdb[7];
TL[7] = scsiCmnd->cdb[8];
lba = (scsiCmnd->cdb[2] << (24)) + (scsiCmnd->cdb[3] << (16))
+ (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
SM_DBG5(("smsatWrite10: lba %d functioned lba %d\n", lba, smsatComputeCDB10LBA(satIOContext)));
SM_DBG5(("smsatWrite10: tl %d functioned tl %d\n", tl, smsatComputeCDB10TL(satIOContext)));
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatWrite10: return LBA out of range, not EXT!!!\n"));
SM_DBG1(("smsatWrite10: cdb 0x%x 0x%x 0x%x 0x%x!!!\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
SM_DBG1(("smsatWrite10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x!!!\n", lba, SAT_TR_LBA_LIMIT));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
else
{
AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatWrite10: return LBA out of range, EXT!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
if (pSatDevData->satNCQ == agTRUE)
{
if (pSatDevData->sat48BitSupport != agTRUE)
{
SM_DBG1(("smsatWrite10: case 5 !!! error NCQ but 28 bit address support!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
SM_DBG6(("smsatWrite10: case 5\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_FPDMA_QUEUED;
fis->h.features = scsiCmnd->cdb[8];
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
fis->d.device = 0xC0;
else
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = scsiCmnd->cdb[7];
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
}
else if (pSatDevData->sat48BitSupport == agTRUE)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatWrite10: case 3\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA_EXT;
satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[8];
fis->d.sectorCountExp = scsiCmnd->cdb[7];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
}
else
{
SM_DBG5(("smsatWrite10: case 4\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[8];
fis->d.sectorCountExp = scsiCmnd->cdb[7];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
}
}
else
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatWrite10: case 2\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[8];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satIOContext->ATACmd = SAT_WRITE_DMA;
}
else
{
SM_DBG5(("smsatWrite10: case 1\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[8];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
satIOContext->ATACmd = SAT_WRITE_SECTORS;
}
}
satIOContext->currentLBA = lba;
satIOContext->OrgTL = tl;
if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
{
LoopNum = smsatComputeLoopNum(tl, 0x100);
}
else
{
LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
SM_DBG5(("smsatWrite10: NON CHAINED data\n"));
satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
}
else
{
SM_DBG2(("smsatWrite10: CHAINED data!!!\n"));
if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
{
fis->d.sectorCount = 0x0;
smsatSplitSGL(smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext,
NON_BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE,
(satIOContext->OrgTL)*SATA_SECTOR_SIZE,
agTRUE);
}
else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
fis->h.command == SAT_WRITE_DMA_EXT ||
fis->h.command == SAT_WRITE_DMA_FUA_EXT
)
{
fis->d.sectorCount = 0xFF;
fis->d.sectorCountExp = 0xFF;
smsatSplitSGL(smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext,
BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE,
(satIOContext->OrgTL)*SATA_SECTOR_SIZE,
agTRUE);
}
else
{
fis->h.features = 0xFF;
fis->d.featuresExp = 0xFF;
smsatSplitSGL(smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext,
BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE,
(satIOContext->OrgTL)*SATA_SECTOR_SIZE,
agTRUE);
}
satIOContext->satCompleteCB = &smsatChainedDataIOCB;
}
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return (status);
}
osGLOBAL bit32
smsatWrite12(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
smDeviceData_t *pSatDevData;
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[8];
bit8 TL[8];
bit32 AllChk = agFALSE;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
SM_DBG5(("smsatWrite12: start\n"));
if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatWrite12: return FUA_NV!!!\n"));
return SM_RC_SUCCESS;
}
if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatWrite10: return control!!!\n"));
return SM_RC_SUCCESS;
}
sm_memset(LBA, 0, sizeof(LBA));
sm_memset(TL, 0, sizeof(TL));
LBA[0] = 0;
LBA[1] = 0;
LBA[2] = 0;
LBA[3] = 0;
LBA[4] = scsiCmnd->cdb[2];
LBA[5] = scsiCmnd->cdb[3];
LBA[6] = scsiCmnd->cdb[4];
LBA[7] = scsiCmnd->cdb[5];
TL[0] = 0;
TL[1] = 0;
TL[2] = 0;
TL[3] = 0;
TL[4] = scsiCmnd->cdb[6];
TL[5] = scsiCmnd->cdb[7];
TL[6] = scsiCmnd->cdb[8];
TL[7] = scsiCmnd->cdb[9];
lba = smsatComputeCDB12LBA(satIOContext);
tl = smsatComputeCDB12TL(satIOContext);
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatWrite12: return LBA out of range, not EXT!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
else
{
AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatWrite12: return LBA out of range, EXT!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatWrite10: case 2\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[9];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satIOContext->ATACmd = SAT_WRITE_DMA;
}
else
{
SM_DBG5(("smsatWrite10: case 1\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[9];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
satIOContext->ATACmd = SAT_WRITE_SECTORS;
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatWrite10: case 3\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[9];
fis->d.sectorCountExp = scsiCmnd->cdb[8];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
}
else
{
SM_DBG5(("smsatWrite10: case 4\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[9];
fis->d.sectorCountExp = scsiCmnd->cdb[8];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
}
}
if (pSatDevData->satNCQ == agTRUE)
{
if (pSatDevData->sat48BitSupport != agTRUE)
{
SM_DBG5(("smsatWrite10: case 5 !!! error NCQ but 28 bit address support!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
SM_DBG6(("smsatWrite10: case 5\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_FPDMA_QUEUED;
fis->h.features = scsiCmnd->cdb[9];
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
fis->d.device = 0xC0;
else
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = scsiCmnd->cdb[8];
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
}
satIOContext->currentLBA = lba;
satIOContext->OrgTL = tl;
if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
{
LoopNum = smsatComputeLoopNum(tl, 0xFF);
}
else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
fis->h.command == SAT_WRITE_DMA_EXT ||
fis->h.command == SAT_WRITE_DMA_FUA_EXT
)
{
LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
}
else
{
LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
SM_DBG5(("smsatWrite10: NON CHAINED data\n"));
satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
}
else
{
SM_DBG1(("smsatWrite10: CHAINED data\n"));
if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
{
fis->d.sectorCount = 0xFF;
}
else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
fis->h.command == SAT_WRITE_DMA_EXT ||
fis->h.command == SAT_WRITE_DMA_FUA_EXT
)
{
fis->d.sectorCount = 0xFF;
fis->d.sectorCountExp = 0xFF;
}
else
{
fis->h.features = 0xFF;
fis->d.featuresExp = 0xFF;
}
satIOContext->satCompleteCB = &smsatChainedDataIOCB;
}
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return (status);
}
osGLOBAL bit32
smsatWrite16(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
smDeviceData_t *pSatDevData;
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[8];
bit8 TL[8];
bit32 AllChk = agFALSE;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
SM_DBG5(("smsatWrite16: start\n"));
if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatWrite16: return FUA_NV!!!\n"));
return SM_RC_SUCCESS;
}
if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatWrite16: return control!!!\n"));
return SM_RC_SUCCESS;
}
sm_memset(LBA, 0, sizeof(LBA));
sm_memset(TL, 0, sizeof(TL));
LBA[0] = scsiCmnd->cdb[2];
LBA[1] = scsiCmnd->cdb[3];
LBA[2] = scsiCmnd->cdb[4];
LBA[3] = scsiCmnd->cdb[5];
LBA[4] = scsiCmnd->cdb[6];
LBA[5] = scsiCmnd->cdb[7];
LBA[6] = scsiCmnd->cdb[8];
LBA[7] = scsiCmnd->cdb[9];
TL[0] = 0;
TL[1] = 0;
TL[2] = 0;
TL[3] = 0;
TL[4] = scsiCmnd->cdb[10];
TL[5] = scsiCmnd->cdb[11];
TL[6] = scsiCmnd->cdb[12];
TL[7] = scsiCmnd->cdb[13];
lba = smsatComputeCDB16LBA(satIOContext);
tl = smsatComputeCDB16TL(satIOContext);
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatWrite16: return LBA out of range, not EXT!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
else
{
AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatWrite16: return LBA out of range, EXT!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatWrite16: case 2\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[9];
fis->d.lbaMid = scsiCmnd->cdb[8];
fis->d.lbaHigh = scsiCmnd->cdb[7];
fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[13];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satIOContext->ATACmd = SAT_WRITE_DMA;
}
else
{
SM_DBG5(("smsatWrite16: case 1\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[9];
fis->d.lbaMid = scsiCmnd->cdb[8];
fis->d.lbaHigh = scsiCmnd->cdb[7];
fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[13];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
satIOContext->ATACmd = SAT_WRITE_SECTORS;
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatWrite16: case 3\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[9];
fis->d.lbaMid = scsiCmnd->cdb[8];
fis->d.lbaHigh = scsiCmnd->cdb[7];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[6];
fis->d.lbaMidExp = scsiCmnd->cdb[5];
fis->d.lbaHighExp = scsiCmnd->cdb[4];
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[13];
fis->d.sectorCountExp = scsiCmnd->cdb[12];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
}
else
{
SM_DBG5(("smsatWrite16: case 4\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[9];
fis->d.lbaMid = scsiCmnd->cdb[8];
fis->d.lbaHigh = scsiCmnd->cdb[7];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[6];
fis->d.lbaMidExp = scsiCmnd->cdb[5];
fis->d.lbaHighExp = scsiCmnd->cdb[4];
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[13];
fis->d.sectorCountExp = scsiCmnd->cdb[12];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
}
}
if (pSatDevData->satNCQ == agTRUE)
{
if (pSatDevData->sat48BitSupport != agTRUE)
{
SM_DBG5(("smsatWrite16: case 5 !!! error NCQ but 28 bit address support!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
SM_DBG6(("smsatWrite16: case 5\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_FPDMA_QUEUED;
fis->h.features = scsiCmnd->cdb[13];
fis->d.lbaLow = scsiCmnd->cdb[9];
fis->d.lbaMid = scsiCmnd->cdb[8];
fis->d.lbaHigh = scsiCmnd->cdb[7];
if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
fis->d.device = 0xC0;
else
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[6];
fis->d.lbaMidExp = scsiCmnd->cdb[5];
fis->d.lbaHighExp = scsiCmnd->cdb[4];
fis->d.featuresExp = scsiCmnd->cdb[12];
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
}
satIOContext->currentLBA = lba;
satIOContext->OrgTL = tl;
if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
{
LoopNum = smsatComputeLoopNum(tl, 0xFF);
}
else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
fis->h.command == SAT_WRITE_DMA_EXT ||
fis->h.command == SAT_WRITE_DMA_FUA_EXT
)
{
LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
}
else
{
LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
SM_DBG5(("smsatWrite16: NON CHAINED data\n"));
satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
}
else
{
SM_DBG1(("smsatWrite16: CHAINED data!!!\n"));
if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
{
fis->d.sectorCount = 0xFF;
}
else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
fis->h.command == SAT_WRITE_DMA_EXT ||
fis->h.command == SAT_WRITE_DMA_FUA_EXT
)
{
fis->d.sectorCount = 0xFF;
fis->d.sectorCountExp = 0xFF;
}
else
{
fis->h.features = 0xFF;
fis->d.featuresExp = 0xFF;
}
satIOContext->satCompleteCB = &smsatChainedDataIOCB;
}
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return (status);
}
osGLOBAL bit32
smsatVerify10(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
smDeviceData_t *pSatDevData;
agsaFisRegHostToDevice_t *fis;
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[8];
bit8 TL[8];
bit32 AllChk = agFALSE;
pSense = satIOContext->pSense;
scsiCmnd = &smScsiRequest->scsiCmnd;
pSatDevData = satIOContext->pSatDevData;
fis = satIOContext->pFis;
SM_DBG5(("smsatVerify10: start\n"));
if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatVerify10: no byte checking!!!\n"));
return SM_RC_SUCCESS;
}
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatVerify10: return control!!!\n"));
return SM_RC_SUCCESS;
}
sm_memset(LBA, 0, sizeof(LBA));
sm_memset(TL, 0, sizeof(TL));
LBA[0] = 0;
LBA[1] = 0;
LBA[2] = 0;
LBA[3] = 0;
LBA[4] = scsiCmnd->cdb[2];
LBA[5] = scsiCmnd->cdb[3];
LBA[6] = scsiCmnd->cdb[4];
LBA[7] = scsiCmnd->cdb[5];
TL[0] = 0;
TL[1] = 0;
TL[2] = 0;
TL[3] = 0;
TL[4] = 0;
TL[5] = 0;
TL[6] = scsiCmnd->cdb[7];
TL[7] = scsiCmnd->cdb[8];
lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
+ (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatVerify10: return LBA out of range, not EXT!!!\n"));
SM_DBG1(("smsatVerify10: cdb 0x%x 0x%x 0x%x 0x%x!!!\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
SM_DBG1(("smsatVerify10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x!!!\n", lba, SAT_TR_LBA_LIMIT));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
else
{
AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatVerify10: return LBA out of range, EXT!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
SM_DBG5(("smsatVerify10: SAT_READ_VERIFY_SECTORS_EXT\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[8];
fis->d.sectorCountExp = scsiCmnd->cdb[7];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
}
else
{
SM_DBG5(("smsatVerify10: SAT_READ_VERIFY_SECTORS\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[8];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
}
satIOContext->currentLBA = lba;
satIOContext->OrgTL = tl;
if (fis->h.command == SAT_READ_VERIFY_SECTORS)
{
LoopNum = smsatComputeLoopNum(tl, 0xFF);
}
else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
{
LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
}
else
{
SM_DBG1(("smsatVerify10: error case 1!!!\n"));
LoopNum = 1;
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
SM_DBG5(("smsatVerify10: NON CHAINED data\n"));
satIOContext->satCompleteCB = &smsatNonChainedVerifyCB;
}
else
{
SM_DBG1(("smsatVerify10: CHAINED data!!!\n"));
if (fis->h.command == SAT_READ_VERIFY_SECTORS)
{
fis->d.sectorCount = 0xFF;
}
else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
{
fis->d.sectorCount = 0xFF;
fis->d.sectorCountExp = 0xFF;
}
else
{
SM_DBG1(("smsatVerify10: error case 2!!!\n"));
}
satIOContext->satCompleteCB = &smsatChainedVerifyCB;
}
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return (status);
}
osGLOBAL bit32
smsatVerify12(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
smDeviceData_t *pSatDevData;
agsaFisRegHostToDevice_t *fis;
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[8];
bit8 TL[8];
bit32 AllChk = agFALSE;
pSense = satIOContext->pSense;
scsiCmnd = &smScsiRequest->scsiCmnd;
pSatDevData = satIOContext->pSatDevData;
fis = satIOContext->pFis;
SM_DBG5(("smsatVerify12: start\n"));
if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatVerify12: no byte checking!!!\n"));
return SM_RC_SUCCESS;
}
if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatVerify12: return control!!!\n"));
return SM_RC_SUCCESS;
}
sm_memset(LBA, 0, sizeof(LBA));
sm_memset(TL, 0, sizeof(TL));
LBA[0] = 0;
LBA[1] = 0;
LBA[2] = 0;
LBA[3] = 0;
LBA[4] = scsiCmnd->cdb[2];
LBA[5] = scsiCmnd->cdb[3];
LBA[6] = scsiCmnd->cdb[4];
LBA[7] = scsiCmnd->cdb[5];
TL[0] = 0;
TL[1] = 0;
TL[2] = 0;
TL[3] = 0;
TL[4] = scsiCmnd->cdb[6];
TL[5] = scsiCmnd->cdb[7];
TL[6] = scsiCmnd->cdb[8];
TL[7] = scsiCmnd->cdb[9];
lba = smsatComputeCDB12LBA(satIOContext);
tl = smsatComputeCDB12TL(satIOContext);
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatVerify12: return LBA out of range, not EXT!!!\n"));
SM_DBG1(("smsatVerify12: cdb 0x%x 0x%x 0x%x 0x%x!!!\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
SM_DBG1(("smsatVerify12: lba 0x%x SAT_TR_LBA_LIMIT 0x%x!!!\n", lba, SAT_TR_LBA_LIMIT));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
else
{
AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatVerify12: return LBA out of range, EXT!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
SM_DBG5(("smsatVerify12: SAT_READ_VERIFY_SECTORS_EXT\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[9];
fis->d.sectorCountExp = scsiCmnd->cdb[8];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
}
else
{
SM_DBG5(("smsatVerify12: SAT_READ_VERIFY_SECTORS\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[9];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
}
satIOContext->currentLBA = lba;
satIOContext->OrgTL = tl;
if (fis->h.command == SAT_READ_VERIFY_SECTORS)
{
LoopNum = smsatComputeLoopNum(tl, 0xFF);
}
else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
{
LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
}
else
{
SM_DBG1(("smsatVerify12: error case 1!!!\n"));
LoopNum = 1;
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
SM_DBG5(("smsatVerify12: NON CHAINED data\n"));
satIOContext->satCompleteCB = &smsatNonChainedVerifyCB;
}
else
{
SM_DBG1(("smsatVerify12: CHAINED data!!!\n"));
if (fis->h.command == SAT_READ_VERIFY_SECTORS)
{
fis->d.sectorCount = 0xFF;
}
else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
{
fis->d.sectorCount = 0xFF;
fis->d.sectorCountExp = 0xFF;
}
else
{
SM_DBG1(("smsatVerify12: error case 2!!!\n"));
}
satIOContext->satCompleteCB = &smsatChainedVerifyCB;
}
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return (status);
}
osGLOBAL bit32
smsatVerify16(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
smDeviceData_t *pSatDevData;
agsaFisRegHostToDevice_t *fis;
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[8];
bit8 TL[8];
bit32 AllChk = agFALSE;
pSense = satIOContext->pSense;
scsiCmnd = &smScsiRequest->scsiCmnd;
pSatDevData = satIOContext->pSatDevData;
fis = satIOContext->pFis;
SM_DBG5(("smsatVerify16: start\n"));
if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatVerify16: no byte checking!!!\n"));
return SM_RC_SUCCESS;
}
if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatVerify16: return control!!!\n"));
return SM_RC_SUCCESS;
}
sm_memset(LBA, 0, sizeof(LBA));
sm_memset(TL, 0, sizeof(TL));
LBA[0] = scsiCmnd->cdb[2];
LBA[1] = scsiCmnd->cdb[3];
LBA[2] = scsiCmnd->cdb[4];
LBA[3] = scsiCmnd->cdb[5];
LBA[4] = scsiCmnd->cdb[6];
LBA[5] = scsiCmnd->cdb[7];
LBA[6] = scsiCmnd->cdb[8];
LBA[7] = scsiCmnd->cdb[9];
TL[0] = 0;
TL[1] = 0;
TL[2] = 0;
TL[3] = 0;
TL[4] = scsiCmnd->cdb[10];
TL[5] = scsiCmnd->cdb[11];
TL[6] = scsiCmnd->cdb[12];
TL[7] = scsiCmnd->cdb[13];
lba = smsatComputeCDB16LBA(satIOContext);
tl = smsatComputeCDB16TL(satIOContext);
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatVerify16: return LBA out of range, not EXT!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
else
{
AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatVerify16: return LBA out of range, EXT!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
SM_DBG5(("smsatVerify16: SAT_READ_VERIFY_SECTORS_EXT\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[9];
fis->d.lbaMid = scsiCmnd->cdb[8];
fis->d.lbaHigh = scsiCmnd->cdb[7];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[6];
fis->d.lbaMidExp = scsiCmnd->cdb[5];
fis->d.lbaHighExp = scsiCmnd->cdb[4];
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[13];
fis->d.sectorCountExp = scsiCmnd->cdb[12];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
}
else
{
SM_DBG5(("smsatVerify16: SAT_READ_VERIFY_SECTORS\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[9];
fis->d.lbaMid = scsiCmnd->cdb[8];
fis->d.lbaHigh = scsiCmnd->cdb[7];
fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[13];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
}
satIOContext->currentLBA = lba;
satIOContext->OrgTL = tl;
if (fis->h.command == SAT_READ_VERIFY_SECTORS)
{
LoopNum = smsatComputeLoopNum(tl, 0xFF);
}
else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
{
LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
}
else
{
SM_DBG1(("smsatVerify16: error case 1!!!\n"));
LoopNum = 1;
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
SM_DBG5(("smsatVerify16: NON CHAINED data\n"));
satIOContext->satCompleteCB = &smsatNonChainedVerifyCB;
}
else
{
SM_DBG1(("smsatVerify16: CHAINED data!!!\n"));
if (fis->h.command == SAT_READ_VERIFY_SECTORS)
{
fis->d.sectorCount = 0xFF;
}
else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
{
fis->d.sectorCount = 0xFF;
fis->d.sectorCountExp = 0xFF;
}
else
{
SM_DBG1(("smsatVerify16: error case 2!!!\n"));
}
satIOContext->satCompleteCB = &smsatChainedVerifyCB;
}
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return (status);
}
osGLOBAL bit32
smsatTestUnitReady(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
smDeviceData_t *pSatDevData;
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
SM_DBG5(("smsatTestUnitReady: start\n"));
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatTestUnitReady: return control!!!\n"));
return SM_RC_SUCCESS;
}
if (pSatDevData->satStopState == agTRUE)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_NOT_READY,
0,
SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatTestUnitReady: stop state!!!\n"));
return SM_RC_SUCCESS;
}
if (pSatDevData->satDriveState == SAT_DEV_STATE_FORMAT_IN_PROGRESS)
{
SM_DBG1(("smsatTestUnitReady: FORMAT_IN_PROGRESS!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_NOT_READY,
0,
SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_FORMAT_IN_PROGRESS,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatTestUnitReady: format in progress!!!\n"));
return SM_RC_SUCCESS;
}
if (pSatDevData->satPendingIO != 0)
{
if (pSatDevData->satDeviceFaultState == agTRUE)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_HARDWARE_ERROR,
0,
SCSI_SNSCODE_LOGICAL_UNIT_FAILURE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatTestUnitReady: previous command ended in error!!!\n"));
return SM_RC_SUCCESS;
}
}
if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
{
SM_DBG5(("smsatTestUnitReady: sending get media status cmnd\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_GET_MEDIA_STATUS;
fis->h.features = 0;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatTestUnitReadyCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return (status);
}
SM_DBG5(("smsatTestUnitReady: sending check power mode cmnd\n"));
status = smsatTestUnitReady_1( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return (status);
}
osGLOBAL bit32
smsatTestUnitReady_1(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
fis = satIOContext->pFis;
SM_DBG5(("smsatTestUnitReady_1: start\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_CHECK_POWER_MODE;
fis->h.features = 0;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatTestUnitReadyCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG5(("smsatTestUnitReady_1: return\n"));
return status;
}
osGLOBAL bit32
smsatInquiry(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
smDeviceData_t *pSatDevData;
bit32 status;
pSense = satIOContext->pSense;
scsiCmnd = &smScsiRequest->scsiCmnd;
pSatDevData = satIOContext->pSatDevData;
SM_DBG5(("smsatInquiry: start\n"));
SM_DBG5(("smsatInquiry: pSatDevData did %d\n", pSatDevData->id));
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatInquiry: return control!!!\n"));
return SM_RC_SUCCESS;
}
if ( !(scsiCmnd->cdb[1] & SCSI_EVPD_MASK) &&
(scsiCmnd->cdb[2] != 0)
)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatInquiry: return EVPD and PAGE CODE!!!\n"));
return SM_RC_SUCCESS;
}
SM_DBG6(("smsatInquiry: allocation length 0x%x %d\n", ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4], ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4]));
if ( pSatDevData->IDDeviceValid == agFALSE)
{
status = smsatStartIDDev(
smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext
);
SM_DBG6(("smsatInquiry: end status %d\n", status));
return status;
}
else
{
SM_DBG6(("smsatInquiry: calling satInquiryIntCB\n"));
smsatInquiryIntCB(
smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext
);
return SM_RC_SUCCESS;
}
}
osGLOBAL bit32
smsatStartIDDev(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
smSatInternalIo_t *satIntIo = agNULL;
smDeviceData_t *satDevData = agNULL;
smIORequestBody_t *smIORequestBody;
smSatIOContext_t *satNewIOContext;
bit32 status;
SM_DBG5(("smsatStartIDDev: start\n"));
satDevData = satIOContext->pSatDevData;
SM_DBG6(("smsatStartIDDev: before alloc\n"));
satIntIo = smsatAllocIntIoResource( smRoot,
smIORequest,
satDevData,
sizeof(agsaSATAIdentifyData_t),
satIntIo);
SM_DBG6(("smsatStartIDDev: before after\n"));
if (satIntIo == agNULL)
{
SM_DBG1(("smsatStartIDDev: can't alloacate!!!\n"));
return SM_RC_FAILURE;
}
satIntIo->satOrgSmIORequest = smIORequest;
smIORequestBody = satIntIo->satIntRequestBody;
satNewIOContext = &(smIORequestBody->transport.SATA.satIOContext);
satNewIOContext->pSatDevData = satDevData;
satNewIOContext->pFis = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
satNewIOContext->pScsiCmnd = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
satNewIOContext->pSense = &(smIORequestBody->transport.SATA.sensePayload);
satNewIOContext->pSmSenseData = &(smIORequestBody->transport.SATA.smSenseData);
satNewIOContext->smRequestBody = satIntIo->satIntRequestBody;
satNewIOContext->interruptContext = tiInterruptContext;
satNewIOContext->satIntIoContext = satIntIo;
satNewIOContext->psmDeviceHandle = agNULL;
satNewIOContext->satOrgIOContext = satIOContext;
satNewIOContext->smScsiXchg = &(satIntIo->satIntSmScsiXchg);
SM_DBG6(("smsatStartIDDev: OS satIOContext %p \n", satIOContext));
SM_DBG6(("smsatStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
SM_DBG6(("smsatStartIDDev: OS tiScsiXchg %p \n", satIOContext->smScsiXchg));
SM_DBG6(("smsatStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->smScsiXchg));
SM_DBG1(("smsatStartIDDev: satNewIOContext %p smIORequestBody %p!!!\n", satNewIOContext, smIORequestBody));
status = smsatSendIDDev( smRoot,
&satIntIo->satIntSmIORequest,
smDeviceHandle,
satNewIOContext->smScsiXchg,
satNewIOContext);
if (status != SM_RC_SUCCESS)
{
SM_DBG1(("smsatStartIDDev: failed in sending!!!\n"));
smsatFreeIntIoResource( smRoot,
satDevData,
satIntIo);
return SM_RC_FAILURE;
}
SM_DBG6(("smsatStartIDDev: end\n"));
return status;
}
osGLOBAL bit32
smsatSendIDDev(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
smDeviceData_t *pSatDevData;
agsaFisRegHostToDevice_t *fis;
#ifdef SM_INTERNAL_DEBUG
smIORequestBody_t *smIORequestBody;
smSatInternalIo_t *satIntIoContext;
#endif
pSatDevData = satIOContext->pSatDevData;
fis = satIOContext->pFis;
SM_DBG6(("smsatSendIDDev: start\n"));
SM_DBG6(("smsatSendIDDev: did %d\n", pSatDevData->id));
#ifdef SM_INTERNAL_DEBUG
satIntIoContext = satIOContext->satIntIoContext;
smIORequestBody = satIntIoContext->satIntRequestBody;
#endif
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
fis->h.command = SAT_IDENTIFY_PACKET_DEVICE;
else
fis->h.command = SAT_IDENTIFY_DEVICE;
fis->h.features = 0;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
satIOContext->satCompleteCB = &smsatInquiryCB;
satIOContext->reqType = agRequestType;
#ifdef SM_INTERNAL_DEBUG
smhexdump("smsatSendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
smhexdump("smsatSendIDDev LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
#endif
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG6(("smsatSendIDDev: end status %d\n", status));
return status;
}
osGLOBAL bit32
smsatRequestSense(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
smScsiRspSense_t *pSense;
smDeviceData_t *pSatDevData;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
smIORequestBody_t *smIORequestBody;
smSatInternalIo_t *satIntIo = agNULL;
smSatIOContext_t *satIOContext2;
bit8 *pDataBuffer = agNULL;
bit32 allocationLen = 0;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
pDataBuffer = (bit8 *) smScsiRequest->sglVirtualAddr;
allocationLen = scsiCmnd->cdb[4];
allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
SM_DBG5(("smsatRequestSense: start\n"));
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatRequestSense: return control!!!\n"));
return SM_RC_SUCCESS;
}
if ( scsiCmnd->cdb[1] & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatRequestSense: DESC bit is set, which we don't support!!!\n"));
return SM_RC_SUCCESS;
}
if (pSatDevData->satSMARTEnabled == agTRUE)
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART;
fis->h.features = SAT_SMART_RETURN_STATUS;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.lbaLow = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMid = 0x4F;
fis->d.lbaMidExp = 0;
fis->d.lbaHigh = 0xC2;
fis->d.lbaHighExp = 0;
fis->d.device = 0;
fis->d.control = 0;
fis->d.reserved4 = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatRequestSenseCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG4(("smsatRequestSense: if return, status %d\n", status));
return (status);
}
else
{
SM_DBG4(("smsatRequestSense: before satIntIo %p\n", satIntIo));
satIntIo = smsatAllocIntIoResource( smRoot,
smIORequest,
pSatDevData,
smScsiRequest->scsiCmnd.expDataLength,
satIntIo);
SM_DBG4(("smsatRequestSense: after satIntIo %p\n", satIntIo));
if (satIntIo == agNULL)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_NO_SENSE,
0,
SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
satIOContext);
sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext );
SM_DBG1(("smsatRequestSense: else fail 1!!!\n"));
return SM_RC_SUCCESS;
}
if (satIntIo == agNULL)
{
SM_DBG4(("smsatRequestSense: satIntIo is NULL\n"));
}
else
{
SM_DBG4(("smsatRequestSense: satIntIo is NOT NULL\n"));
}
satIntIo->satOrgSmIORequest = smIORequest;
smIORequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody;
satIOContext2 = &(smIORequestBody->transport.SATA.satIOContext);
satIOContext2->pSatDevData = pSatDevData;
satIOContext2->pFis = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
satIOContext2->pScsiCmnd = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
satIOContext2->pSense = &(smIORequestBody->transport.SATA.sensePayload);
satIOContext2->pSmSenseData = &(smIORequestBody->transport.SATA.smSenseData);
satIOContext2->pSmSenseData->senseData = satIOContext2->pSense;
satIOContext2->smRequestBody = satIntIo->satIntRequestBody;
satIOContext2->interruptContext = satIOContext->interruptContext;
satIOContext2->satIntIoContext = satIntIo;
satIOContext2->psmDeviceHandle = smDeviceHandle;
satIOContext2->satOrgIOContext = satIOContext;
SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.len %d\n", satIntIo->satIntSmScsiXchg.smSgl1.len));
SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.upper %d\n", satIntIo->satIntSmScsiXchg.smSgl1.upper));
SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.lower %d\n", satIntIo->satIntSmScsiXchg.smSgl1.lower));
SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.type %d\n", satIntIo->satIntSmScsiXchg.smSgl1.type));
status = smsatRequestSense_1( smRoot,
&(satIntIo->satIntSmIORequest),
smDeviceHandle,
&(satIntIo->satIntSmScsiXchg),
satIOContext2);
if (status != SM_RC_SUCCESS)
{
smsatFreeIntIoResource( smRoot,
pSatDevData,
satIntIo);
smsatSetSensePayload( pSense,
SCSI_SNSKEY_NO_SENSE,
0,
SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
satIOContext);
sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
agNULL,
satIOContext->interruptContext );
SM_DBG1(("smsatRequestSense: else fail 2!!!\n"));
return SM_RC_SUCCESS;
}
SM_DBG4(("smsatRequestSense: else return success\n"));
return SM_RC_SUCCESS;
}
}
osGLOBAL bit32
smsatRequestSense_1(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
fis = satIOContext->pFis;
SM_DBG5(("smsatRequestSense_1: start\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_CHECK_POWER_MODE;
fis->h.features = 0;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatRequestSenseCB;
satIOContext->reqType = agRequestType;
SM_DBG4(("smsatRequestSense_1: smSgl1.len %d\n", smScsiRequest->smSgl1.len));
SM_DBG4(("smsatRequestSense_1: smSgl1.upper %d\n", smScsiRequest->smSgl1.upper));
SM_DBG4(("smsatRequestSense_1: smSgl1.lower %d\n", smScsiRequest->smSgl1.lower));
SM_DBG4(("smsatRequestSense_1: smSgl1.type %d\n", smScsiRequest->smSgl1.type));
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
osGLOBAL bit32
smsatModeSense6(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
smScsiRspSense_t *pSense;
bit32 allocationLen;
smIniScsiCmnd_t *scsiCmnd;
bit32 pageSupported;
bit8 page;
bit8 *pModeSense;
smDeviceData_t *pSatDevData;
bit8 PC;
bit8 AllPages[MODE_SENSE6_RETURN_ALL_PAGES_LEN];
bit8 Control[MODE_SENSE6_CONTROL_PAGE_LEN];
bit8 RWErrorRecovery[MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN];
bit8 Caching[MODE_SENSE6_CACHING_LEN];
bit8 InfoExceptionCtrl[MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN];
bit8 lenRead = 0;
pSense = satIOContext->pSense;
scsiCmnd = &smScsiRequest->scsiCmnd;
pModeSense = (bit8 *) smScsiRequest->sglVirtualAddr;
pSatDevData = satIOContext->pSatDevData;
SM_DBG5(("smsatModeSense6: start\n"));
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatModeSense6: return control!!!\n"));
return SM_RC_SUCCESS;
}
PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PC_MASK);
if (PC != 0)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatModeSense6: return due to PC value pc 0x%x!!!\n", PC >> 6));
return SM_RC_SUCCESS;
}
page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PAGE_CODE_MASK);
SM_DBG5(("smsatModeSense6: page=0x%x\n", page));
allocationLen = scsiCmnd->cdb[4];
allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
switch(page)
{
case MODESENSE_RETURN_ALL_PAGES:
case MODESENSE_CONTROL_PAGE:
case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE:
case MODESENSE_CACHING:
case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE:
pageSupported = agTRUE;
break;
case MODESENSE_VENDOR_SPECIFIC_PAGE:
default:
pageSupported = agFALSE;
break;
}
if (pageSupported == agFALSE)
{
SM_DBG1(("smsatModeSense6 *** ERROR *** not supported page 0x%x did %d!!!\n",
page, pSatDevData->id));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
switch(page)
{
case MODESENSE_RETURN_ALL_PAGES:
lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_RETURN_ALL_PAGES_LEN);
break;
case MODESENSE_CONTROL_PAGE:
lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_CONTROL_PAGE_LEN);
break;
case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE:
lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
break;
case MODESENSE_CACHING:
lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_CACHING_LEN);
break;
case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE:
lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
break;
default:
SM_DBG1(("smsatModeSense6: default error page %d!!!\n", page));
break;
}
if (page == MODESENSE_RETURN_ALL_PAGES)
{
SM_DBG5(("smsatModeSense6: MODESENSE_RETURN_ALL_PAGES\n"));
AllPages[0] = (bit8)(lenRead - 1);
AllPages[1] = 0x00;
AllPages[2] = 0x00;
AllPages[3] = 0x08;
AllPages[4] = 0x04;
AllPages[5] = 0x00;
AllPages[6] = 0x00;
AllPages[7] = 0x00;
AllPages[8] = 0x00;
AllPages[9] = 0x00;
AllPages[10] = 0x02;
AllPages[11] = 0x00;
AllPages[12] = 0x01;
AllPages[13] = 0x0A;
AllPages[14] = 0x40;
AllPages[15] = 0x00;
AllPages[16] = 0x00;
AllPages[17] = 0x00;
AllPages[18] = 0x00;
AllPages[19] = 0x00;
AllPages[20] = 0x00;
AllPages[21] = 0x00;
AllPages[22] = 0x00;
AllPages[23] = 0x00;
AllPages[24] = 0x08;
AllPages[25] = 0x12;
if (pSatDevData->satWriteCacheEnabled == agTRUE)
{
AllPages[26] = 0x04;
}
else
{
AllPages[26] = 0x00;
}
AllPages[27] = 0x00;
AllPages[28] = 0x00;
AllPages[29] = 0x00;
AllPages[30] = 0x00;
AllPages[31] = 0x00;
AllPages[32] = 0x00;
AllPages[33] = 0x00;
AllPages[34] = 0x00;
AllPages[35] = 0x00;
if (pSatDevData->satLookAheadEnabled == agTRUE)
{
AllPages[36] = 0x00;
}
else
{
AllPages[36] = 0x20;
}
AllPages[37] = 0x00;
AllPages[38] = 0x00;
AllPages[39] = 0x00;
AllPages[40] = 0x00;
AllPages[41] = 0x00;
AllPages[42] = 0x00;
AllPages[43] = 0x00;
AllPages[44] = 0x0A;
AllPages[45] = 0x0A;
AllPages[46] = 0x02;
if (pSatDevData->satNCQ == agTRUE)
{
AllPages[47] = 0x12;
}
else
{
AllPages[47] = 0x02;
}
AllPages[48] = 0x00;
AllPages[49] = 0x00;
AllPages[50] = 0x00;
AllPages[51] = 0x00;
AllPages[52] = 0xFF;
AllPages[53] = 0xFF;
AllPages[54] = 0x00;
AllPages[55] = 0x00;
AllPages[56] = 0x1C;
AllPages[57] = 0x0A;
if (pSatDevData->satSMARTEnabled == agTRUE)
{
AllPages[58] = 0x00;
}
else
{
AllPages[58] = 0x08;
}
AllPages[59] = 0x00;
AllPages[60] = 0x00;
AllPages[61] = 0x00;
AllPages[62] = 0x00;
AllPages[63] = 0x00;
AllPages[64] = 0x00;
AllPages[65] = 0x00;
AllPages[66] = 0x00;
AllPages[67] = 0x00;
sm_memcpy(pModeSense, &AllPages, lenRead);
}
else if (page == MODESENSE_CONTROL_PAGE)
{
SM_DBG5(("smsatModeSense6: MODESENSE_CONTROL_PAGE\n"));
Control[0] = MODE_SENSE6_CONTROL_PAGE_LEN - 1;
Control[1] = 0x00;
Control[2] = 0x00;
Control[3] = 0x08;
Control[4] = 0x04;
Control[5] = 0x00;
Control[6] = 0x00;
Control[7] = 0x00;
Control[8] = 0x00;
Control[9] = 0x00;
Control[10] = 0x02;
Control[11] = 0x00;
Control[12] = 0x0A;
Control[13] = 0x0A;
Control[14] = 0x02;
if (pSatDevData->satNCQ == agTRUE)
{
Control[15] = 0x12;
}
else
{
Control[15] = 0x02;
}
Control[16] = 0x00;
Control[17] = 0x00;
Control[18] = 0x00;
Control[19] = 0x00;
Control[20] = 0xFF;
Control[21] = 0xFF;
Control[22] = 0x00;
Control[23] = 0x00;
sm_memcpy(pModeSense, &Control, lenRead);
}
else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
{
SM_DBG5(("smsatModeSense6: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
RWErrorRecovery[0] = MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN - 1;
RWErrorRecovery[1] = 0x00;
RWErrorRecovery[2] = 0x00;
RWErrorRecovery[3] = 0x08;
RWErrorRecovery[4] = 0x04;
RWErrorRecovery[5] = 0x00;
RWErrorRecovery[6] = 0x00;
RWErrorRecovery[7] = 0x00;
RWErrorRecovery[8] = 0x00;
RWErrorRecovery[9] = 0x00;
RWErrorRecovery[10] = 0x02;
RWErrorRecovery[11] = 0x00;
RWErrorRecovery[12] = 0x01;
RWErrorRecovery[13] = 0x0A;
RWErrorRecovery[14] = 0x40;
RWErrorRecovery[15] = 0x00;
RWErrorRecovery[16] = 0x00;
RWErrorRecovery[17] = 0x00;
RWErrorRecovery[18] = 0x00;
RWErrorRecovery[19] = 0x00;
RWErrorRecovery[20] = 0x00;
RWErrorRecovery[21] = 0x00;
RWErrorRecovery[22] = 0x00;
RWErrorRecovery[23] = 0x00;
sm_memcpy(pModeSense, &RWErrorRecovery, lenRead);
}
else if (page == MODESENSE_CACHING)
{
SM_DBG5(("smsatModeSense6: MODESENSE_CACHING\n"));
if (allocationLen == 4 && page == MODESENSE_CACHING)
{
SM_DBG5(("smsatModeSense6: linux 2.6.8.24 support\n"));
Caching[0] = 0x20 - 1;
Caching[1] = 0x00;
Caching[2] = 0x00;
Caching[3] = 0x08;
sm_memcpy(pModeSense, &Caching, 4);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return SM_RC_SUCCESS;
}
Caching[0] = MODE_SENSE6_CACHING_LEN - 1;
Caching[1] = 0x00;
Caching[2] = 0x00;
Caching[3] = 0x08;
Caching[4] = 0x04;
Caching[5] = 0x00;
Caching[6] = 0x00;
Caching[7] = 0x00;
Caching[8] = 0x00;
Caching[9] = 0x00;
Caching[10] = 0x02;
Caching[11] = 0x00;
Caching[12] = 0x08;
Caching[13] = 0x12;
if (pSatDevData->satWriteCacheEnabled == agTRUE)
{
Caching[14] = 0x04;
}
else
{
Caching[14] = 0x00;
}
Caching[15] = 0x00;
Caching[16] = 0x00;
Caching[17] = 0x00;
Caching[18] = 0x00;
Caching[19] = 0x00;
Caching[20] = 0x00;
Caching[21] = 0x00;
Caching[22] = 0x00;
Caching[23] = 0x00;
if (pSatDevData->satLookAheadEnabled == agTRUE)
{
Caching[24] = 0x00;
}
else
{
Caching[24] = 0x20;
}
Caching[25] = 0x00;
Caching[26] = 0x00;
Caching[27] = 0x00;
Caching[28] = 0x00;
Caching[29] = 0x00;
Caching[30] = 0x00;
Caching[31] = 0x00;
sm_memcpy(pModeSense, &Caching, lenRead);
}
else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
{
SM_DBG5(("smsatModeSense6: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
InfoExceptionCtrl[0] = MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN - 1;
InfoExceptionCtrl[1] = 0x00;
InfoExceptionCtrl[2] = 0x00;
InfoExceptionCtrl[3] = 0x08;
InfoExceptionCtrl[4] = 0x04;
InfoExceptionCtrl[5] = 0x00;
InfoExceptionCtrl[6] = 0x00;
InfoExceptionCtrl[7] = 0x00;
InfoExceptionCtrl[8] = 0x00;
InfoExceptionCtrl[9] = 0x00;
InfoExceptionCtrl[10] = 0x02;
InfoExceptionCtrl[11] = 0x00;
InfoExceptionCtrl[12] = 0x1C;
InfoExceptionCtrl[13] = 0x0A;
if (pSatDevData->satSMARTEnabled == agTRUE)
{
InfoExceptionCtrl[14] = 0x00;
}
else
{
InfoExceptionCtrl[14] = 0x08;
}
InfoExceptionCtrl[15] = 0x00;
InfoExceptionCtrl[16] = 0x00;
InfoExceptionCtrl[17] = 0x00;
InfoExceptionCtrl[18] = 0x00;
InfoExceptionCtrl[19] = 0x00;
InfoExceptionCtrl[20] = 0x00;
InfoExceptionCtrl[21] = 0x00;
InfoExceptionCtrl[22] = 0x00;
InfoExceptionCtrl[23] = 0x00;
sm_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
}
else
{
SM_DBG1(("smsatModeSense6: Error page %d!!!\n", page));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
if (allocationLen > lenRead)
{
SM_DBG6(("smsatModeSense6 reporting underrun lenRead=0x%x allocationLen=0x%x\n", lenRead, allocationLen));
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOUnderRun,
allocationLen - lenRead,
agNULL,
satIOContext->interruptContext );
}
else
{
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
}
return SM_RC_SUCCESS;
}
osGLOBAL bit32
smsatModeSense10(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
smScsiRspSense_t *pSense;
bit32 allocationLen;
smIniScsiCmnd_t *scsiCmnd;
bit32 pageSupported;
bit8 page;
bit8 *pModeSense;
smDeviceData_t *pSatDevData;
bit8 PC;
bit8 LLBAA;
bit32 index;
bit8 AllPages[MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN];
bit8 Control[MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN];
bit8 RWErrorRecovery[MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN];
bit8 Caching[MODE_SENSE10_CACHING_LLBAA_LEN];
bit8 InfoExceptionCtrl[MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN];
bit8 lenRead = 0;
pSense = satIOContext->pSense;
scsiCmnd = &smScsiRequest->scsiCmnd;
pModeSense = (bit8 *) smScsiRequest->sglVirtualAddr;
pSatDevData = satIOContext->pSatDevData;
SM_DBG5(("smsatModeSense10: start\n"));
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatModeSense10: return control!!!\n"));
return SM_RC_SUCCESS;
}
PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PC_MASK);
if (PC != 0)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatModeSense10: return due to PC value pc 0x%x!!!\n", PC));
return SM_RC_SUCCESS;
}
LLBAA = (bit8)((scsiCmnd->cdb[1]) & SCSI_MODE_SENSE10_LLBAA_MASK);
page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PAGE_CODE_MASK);
SM_DBG5(("smsatModeSense10: page=0x%x, did %d\n", page, pSatDevData->id));
allocationLen = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
switch(page)
{
case MODESENSE_RETURN_ALL_PAGES:
case MODESENSE_CONTROL_PAGE:
case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE:
case MODESENSE_CACHING:
case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE:
pageSupported = agTRUE;
break;
case MODESENSE_VENDOR_SPECIFIC_PAGE:
default:
pageSupported = agFALSE;
break;
}
if (pageSupported == agFALSE)
{
SM_DBG1(("smsatModeSense10 *** ERROR *** not supported page 0x%x did %d!!!\n", page, pSatDevData->id));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
switch(page)
{
case MODESENSE_RETURN_ALL_PAGES:
if (LLBAA)
{
lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN);
}
else
{
lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_RETURN_ALL_PAGES_LEN);
}
break;
case MODESENSE_CONTROL_PAGE:
if (LLBAA)
{
lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN);
}
else
{
lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CONTROL_PAGE_LEN);
}
break;
case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE:
if (LLBAA)
{
lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN);
}
else
{
lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
}
break;
case MODESENSE_CACHING:
if (LLBAA)
{
lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CACHING_LLBAA_LEN);
}
else
{
lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CACHING_LEN);
}
break;
case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE:
if (LLBAA)
{
lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN);
}
else
{
lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
}
break;
default:
SM_DBG1(("smsatModeSense10: default error page %d!!!\n", page));
break;
}
if (page == MODESENSE_RETURN_ALL_PAGES)
{
SM_DBG5(("smsatModeSense10: MODESENSE_RETURN_ALL_PAGES\n"));
AllPages[0] = 0;
AllPages[1] = (bit8)(lenRead - 2);
AllPages[2] = 0x00;
AllPages[3] = 0x00;
if (LLBAA)
{
AllPages[4] = 0x00;
AllPages[4] = (bit8)(AllPages[4] | 0x1);
}
else
{
AllPages[4] = 0x00;
}
AllPages[5] = 0x00;
AllPages[6] = 0x00;
if (LLBAA)
{
AllPages[7] = 0x10;
}
else
{
AllPages[7] = 0x08;
}
if (LLBAA)
{
AllPages[8] = 0x04;
AllPages[9] = 0x00;
AllPages[10] = 0x00;
AllPages[11] = 0x00;
AllPages[12] = 0x00;
AllPages[13] = 0x00;
AllPages[14] = 0x00;
AllPages[15] = 0x00;
AllPages[16] = 0x00;
AllPages[17] = 0x00;
AllPages[18] = 0x00;
AllPages[19] = 0x00;
AllPages[20] = 0x00;
AllPages[21] = 0x00;
AllPages[22] = 0x02;
AllPages[23] = 0x00;
}
else
{
AllPages[8] = 0x04;
AllPages[9] = 0x00;
AllPages[10] = 0x00;
AllPages[11] = 0x00;
AllPages[12] = 0x00;
AllPages[13] = 0x00;
AllPages[14] = 0x02;
AllPages[15] = 0x00;
}
if (LLBAA)
{
index = 24;
}
else
{
index = 16;
}
AllPages[index+0] = 0x01;
AllPages[index+1] = 0x0A;
AllPages[index+2] = 0x40;
AllPages[index+3] = 0x00;
AllPages[index+4] = 0x00;
AllPages[index+5] = 0x00;
AllPages[index+6] = 0x00;
AllPages[index+7] = 0x00;
AllPages[index+8] = 0x00;
AllPages[index+9] = 0x00;
AllPages[index+10] = 0x00;
AllPages[index+11] = 0x00;
AllPages[index+12] = 0x08;
AllPages[index+13] = 0x12;
if (pSatDevData->satWriteCacheEnabled == agTRUE)
{
AllPages[index+14] = 0x04;
}
else
{
AllPages[index+14] = 0x00;
}
AllPages[index+15] = 0x00;
AllPages[index+16] = 0x00;
AllPages[index+17] = 0x00;
AllPages[index+18] = 0x00;
AllPages[index+19] = 0x00;
AllPages[index+20] = 0x00;
AllPages[index+21] = 0x00;
AllPages[index+22] = 0x00;
AllPages[index+23] = 0x00;
if (pSatDevData->satLookAheadEnabled == agTRUE)
{
AllPages[index+24] = 0x00;
}
else
{
AllPages[index+24] = 0x20;
}
AllPages[index+25] = 0x00;
AllPages[index+26] = 0x00;
AllPages[index+27] = 0x00;
AllPages[index+28] = 0x00;
AllPages[index+29] = 0x00;
AllPages[index+30] = 0x00;
AllPages[index+31] = 0x00;
AllPages[index+32] = 0x0A;
AllPages[index+33] = 0x0A;
AllPages[index+34] = 0x02;
if (pSatDevData->satNCQ == agTRUE)
{
AllPages[index+35] = 0x12;
}
else
{
AllPages[index+35] = 0x02;
}
AllPages[index+36] = 0x00;
AllPages[index+37] = 0x00;
AllPages[index+38] = 0x00;
AllPages[index+39] = 0x00;
AllPages[index+40] = 0xFF;
AllPages[index+41] = 0xFF;
AllPages[index+42] = 0x00;
AllPages[index+43] = 0x00;
AllPages[index+44] = 0x1C;
AllPages[index+45] = 0x0A;
if (pSatDevData->satSMARTEnabled == agTRUE)
{
AllPages[index+46] = 0x00;
}
else
{
AllPages[index+46] = 0x08;
}
AllPages[index+47] = 0x00;
AllPages[index+48] = 0x00;
AllPages[index+49] = 0x00;
AllPages[index+50] = 0x00;
AllPages[index+51] = 0x00;
AllPages[index+52] = 0x00;
AllPages[index+53] = 0x00;
AllPages[index+54] = 0x00;
AllPages[index+55] = 0x00;
sm_memcpy(pModeSense, &AllPages, lenRead);
}
else if (page == MODESENSE_CONTROL_PAGE)
{
SM_DBG5(("smsatModeSense10: MODESENSE_CONTROL_PAGE\n"));
Control[0] = 0;
Control[1] = (bit8)(lenRead - 2);
Control[2] = 0x00;
Control[3] = 0x00;
if (LLBAA)
{
Control[4] = 0x00;
Control[4] = (bit8)(Control[4] | 0x1);
}
else
{
Control[4] = 0x00;
}
Control[5] = 0x00;
Control[6] = 0x00;
if (LLBAA)
{
Control[7] = 0x10;
}
else
{
Control[7] = 0x08;
}
if (LLBAA)
{
Control[8] = 0x04;
Control[9] = 0x00;
Control[10] = 0x00;
Control[11] = 0x00;
Control[12] = 0x00;
Control[13] = 0x00;
Control[14] = 0x00;
Control[15] = 0x00;
Control[16] = 0x00;
Control[17] = 0x00;
Control[18] = 0x00;
Control[19] = 0x00;
Control[20] = 0x00;
Control[21] = 0x00;
Control[22] = 0x02;
Control[23] = 0x00;
}
else
{
Control[8] = 0x04;
Control[9] = 0x00;
Control[10] = 0x00;
Control[11] = 0x00;
Control[12] = 0x00;
Control[13] = 0x00;
Control[14] = 0x02;
Control[15] = 0x00;
}
if (LLBAA)
{
index = 24;
}
else
{
index = 16;
}
Control[index+0] = 0x0A;
Control[index+1] = 0x0A;
Control[index+2] = 0x02;
if (pSatDevData->satNCQ == agTRUE)
{
Control[index+3] = 0x12;
}
else
{
Control[index+3] = 0x02;
}
Control[index+4] = 0x00;
Control[index+5] = 0x00;
Control[index+6] = 0x00;
Control[index+7] = 0x00;
Control[index+8] = 0xFF;
Control[index+9] = 0xFF;
Control[index+10] = 0x00;
Control[index+11] = 0x00;
sm_memcpy(pModeSense, &Control, lenRead);
}
else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
{
SM_DBG5(("smsatModeSense10: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
RWErrorRecovery[0] = 0;
RWErrorRecovery[1] = (bit8)(lenRead - 2);
RWErrorRecovery[2] = 0x00;
RWErrorRecovery[3] = 0x00;
if (LLBAA)
{
RWErrorRecovery[4] = 0x00;
RWErrorRecovery[4] = (bit8)(RWErrorRecovery[4] | 0x1);
}
else
{
RWErrorRecovery[4] = 0x00;
}
RWErrorRecovery[5] = 0x00;
RWErrorRecovery[6] = 0x00;
if (LLBAA)
{
RWErrorRecovery[7] = 0x10;
}
else
{
RWErrorRecovery[7] = 0x08;
}
if (LLBAA)
{
RWErrorRecovery[8] = 0x04;
RWErrorRecovery[9] = 0x00;
RWErrorRecovery[10] = 0x00;
RWErrorRecovery[11] = 0x00;
RWErrorRecovery[12] = 0x00;
RWErrorRecovery[13] = 0x00;
RWErrorRecovery[14] = 0x00;
RWErrorRecovery[15] = 0x00;
RWErrorRecovery[16] = 0x00;
RWErrorRecovery[17] = 0x00;
RWErrorRecovery[18] = 0x00;
RWErrorRecovery[19] = 0x00;
RWErrorRecovery[20] = 0x00;
RWErrorRecovery[21] = 0x00;
RWErrorRecovery[22] = 0x02;
RWErrorRecovery[23] = 0x00;
}
else
{
RWErrorRecovery[8] = 0x04;
RWErrorRecovery[9] = 0x00;
RWErrorRecovery[10] = 0x00;
RWErrorRecovery[11] = 0x00;
RWErrorRecovery[12] = 0x00;
RWErrorRecovery[13] = 0x00;
RWErrorRecovery[14] = 0x02;
RWErrorRecovery[15] = 0x00;
}
if (LLBAA)
{
index = 24;
}
else
{
index = 16;
}
RWErrorRecovery[index+0] = 0x01;
RWErrorRecovery[index+1] = 0x0A;
RWErrorRecovery[index+2] = 0x40;
RWErrorRecovery[index+3] = 0x00;
RWErrorRecovery[index+4] = 0x00;
RWErrorRecovery[index+5] = 0x00;
RWErrorRecovery[index+6] = 0x00;
RWErrorRecovery[index+7] = 0x00;
RWErrorRecovery[index+8] = 0x00;
RWErrorRecovery[index+9] = 0x00;
RWErrorRecovery[index+10] = 0x00;
RWErrorRecovery[index+11] = 0x00;
sm_memcpy(pModeSense, &RWErrorRecovery, lenRead);
}
else if (page == MODESENSE_CACHING)
{
SM_DBG5(("smsatModeSense10: MODESENSE_CACHING\n"));
Caching[0] = 0;
Caching[1] = (bit8)(lenRead - 2);
Caching[2] = 0x00;
Caching[3] = 0x00;
if (LLBAA)
{
Caching[4] = 0x00;
Caching[4] = (bit8)(Caching[4] | 0x1);
}
else
{
Caching[4] = 0x00;
}
Caching[5] = 0x00;
Caching[6] = 0x00;
if (LLBAA)
{
Caching[7] = 0x10;
}
else
{
Caching[7] = 0x08;
}
if (LLBAA)
{
Caching[8] = 0x04;
Caching[9] = 0x00;
Caching[10] = 0x00;
Caching[11] = 0x00;
Caching[12] = 0x00;
Caching[13] = 0x00;
Caching[14] = 0x00;
Caching[15] = 0x00;
Caching[16] = 0x00;
Caching[17] = 0x00;
Caching[18] = 0x00;
Caching[19] = 0x00;
Caching[20] = 0x00;
Caching[21] = 0x00;
Caching[22] = 0x02;
Caching[23] = 0x00;
}
else
{
Caching[8] = 0x04;
Caching[9] = 0x00;
Caching[10] = 0x00;
Caching[11] = 0x00;
Caching[12] = 0x00;
Caching[13] = 0x00;
Caching[14] = 0x02;
Caching[15] = 0x00;
}
if (LLBAA)
{
index = 24;
}
else
{
index = 16;
}
Caching[index+0] = 0x08;
Caching[index+1] = 0x12;
if (pSatDevData->satWriteCacheEnabled == agTRUE)
{
Caching[index+2] = 0x04;
}
else
{
Caching[index+2] = 0x00;
}
Caching[index+3] = 0x00;
Caching[index+4] = 0x00;
Caching[index+5] = 0x00;
Caching[index+6] = 0x00;
Caching[index+7] = 0x00;
Caching[index+8] = 0x00;
Caching[index+9] = 0x00;
Caching[index+10] = 0x00;
Caching[index+11] = 0x00;
if (pSatDevData->satLookAheadEnabled == agTRUE)
{
Caching[index+12] = 0x00;
}
else
{
Caching[index+12] = 0x20;
}
Caching[index+13] = 0x00;
Caching[index+14] = 0x00;
Caching[index+15] = 0x00;
Caching[index+16] = 0x00;
Caching[index+17] = 0x00;
Caching[index+18] = 0x00;
Caching[index+19] = 0x00;
sm_memcpy(pModeSense, &Caching, lenRead);
}
else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
{
SM_DBG5(("smsatModeSense10: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
InfoExceptionCtrl[0] = 0;
InfoExceptionCtrl[1] = (bit8)(lenRead - 2);
InfoExceptionCtrl[2] = 0x00;
InfoExceptionCtrl[3] = 0x00;
if (LLBAA)
{
InfoExceptionCtrl[4] = 0x00;
InfoExceptionCtrl[4] = (bit8)(InfoExceptionCtrl[4] | 0x1);
}
else
{
InfoExceptionCtrl[4] = 0x00;
}
InfoExceptionCtrl[5] = 0x00;
InfoExceptionCtrl[6] = 0x00;
if (LLBAA)
{
InfoExceptionCtrl[7] = 0x10;
}
else
{
InfoExceptionCtrl[7] = 0x08;
}
if (LLBAA)
{
InfoExceptionCtrl[8] = 0x04;
InfoExceptionCtrl[9] = 0x00;
InfoExceptionCtrl[10] = 0x00;
InfoExceptionCtrl[11] = 0x00;
InfoExceptionCtrl[12] = 0x00;
InfoExceptionCtrl[13] = 0x00;
InfoExceptionCtrl[14] = 0x00;
InfoExceptionCtrl[15] = 0x00;
InfoExceptionCtrl[16] = 0x00;
InfoExceptionCtrl[17] = 0x00;
InfoExceptionCtrl[18] = 0x00;
InfoExceptionCtrl[19] = 0x00;
InfoExceptionCtrl[20] = 0x00;
InfoExceptionCtrl[21] = 0x00;
InfoExceptionCtrl[22] = 0x02;
InfoExceptionCtrl[23] = 0x00;
}
else
{
InfoExceptionCtrl[8] = 0x04;
InfoExceptionCtrl[9] = 0x00;
InfoExceptionCtrl[10] = 0x00;
InfoExceptionCtrl[11] = 0x00;
InfoExceptionCtrl[12] = 0x00;
InfoExceptionCtrl[13] = 0x00;
InfoExceptionCtrl[14] = 0x02;
InfoExceptionCtrl[15] = 0x00;
}
if (LLBAA)
{
index = 24;
}
else
{
index = 16;
}
InfoExceptionCtrl[index+0] = 0x1C;
InfoExceptionCtrl[index+1] = 0x0A;
if (pSatDevData->satSMARTEnabled == agTRUE)
{
InfoExceptionCtrl[index+2] = 0x00;
}
else
{
InfoExceptionCtrl[index+2] = 0x08;
}
InfoExceptionCtrl[index+3] = 0x00;
InfoExceptionCtrl[index+4] = 0x00;
InfoExceptionCtrl[index+5] = 0x00;
InfoExceptionCtrl[index+6] = 0x00;
InfoExceptionCtrl[index+7] = 0x00;
InfoExceptionCtrl[index+8] = 0x00;
InfoExceptionCtrl[index+9] = 0x00;
InfoExceptionCtrl[index+10] = 0x00;
InfoExceptionCtrl[index+11] = 0x00;
sm_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
}
else
{
SM_DBG1(("smsatModeSense10: Error page %d!!!\n", page));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
if (allocationLen > lenRead)
{
SM_DBG1(("smsatModeSense10: reporting underrun lenRead=0x%x allocationLen=0x%x smIORequest=%p\n", lenRead, allocationLen, smIORequest));
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOUnderRun,
allocationLen - lenRead,
agNULL,
satIOContext->interruptContext );
}
else
{
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
}
return SM_RC_SUCCESS;
}
osGLOBAL bit32
smsatReadCapacity10(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
bit8 dataBuffer[8] = {0};
bit32 allocationLen;
bit8 *pVirtAddr = agNULL;
smDeviceData_t *pSatDevData;
agsaSATAIdentifyData_t *pSATAIdData;
bit32 lastLba;
bit32 word117_118;
bit32 word117;
bit32 word118;
pSense = satIOContext->pSense;
pVirtAddr = (bit8 *) smScsiRequest->sglVirtualAddr;
scsiCmnd = &smScsiRequest->scsiCmnd;
pSatDevData = satIOContext->pSatDevData;
pSATAIdData = &pSatDevData->satIdentifyData;
allocationLen = scsiCmnd->expDataLength;
SM_DBG5(("smsatReadCapacity10: start\n"));
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatReadCapacity10: return control!!!\n"));
return SM_RC_SUCCESS;
}
if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]))
{
SM_DBG1(("smsatReadCapacity10: *** ERROR *** logical address non zero, did %d!!!\n",
pSatDevData->id));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
if ( ((scsiCmnd->cdb[8]) & SCSI_READ_CAPACITY10_PMI_MASK) != 0 )
{
SM_DBG1(("smsatReadCapacity10: *** ERROR *** PMI is not zero, did %d\n",
pSatDevData->id));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
if ( (pSATAIdData->maxLBA32_47 != 0 ) || (pSATAIdData->maxLBA48_63 != 0))
{
dataBuffer[0] = 0xFF;
dataBuffer[1] = 0xFF;
dataBuffer[2] = 0xFF;
dataBuffer[3] = 0xFF;
SM_DBG1(("smsatReadCapacity10: returns 0xFFFFFFFF!!!\n"));
}
else
{
lastLba = (((pSATAIdData->maxLBA16_31) << 16) ) |
(pSATAIdData->maxLBA0_15);
lastLba = lastLba - 1;
dataBuffer[0] = (bit8)((lastLba >> 24) & 0xFF);
dataBuffer[1] = (bit8)((lastLba >> 16) & 0xFF);
dataBuffer[2] = (bit8)((lastLba >> 8) & 0xFF);
dataBuffer[3] = (bit8)((lastLba ) & 0xFF);
SM_DBG3(("smsatReadCapacity10: lastLba is 0x%x %d\n", lastLba, lastLba));
SM_DBG3(("smsatReadCapacity10: LBA 0 is 0x%x %d\n", dataBuffer[0], dataBuffer[0]));
SM_DBG3(("smsatReadCapacity10: LBA 1 is 0x%x %d\n", dataBuffer[1], dataBuffer[1]));
SM_DBG3(("smsatReadCapacity10: LBA 2 is 0x%x %d\n", dataBuffer[2], dataBuffer[2]));
SM_DBG3(("smsatReadCapacity10: LBA 3 is 0x%x %d\n", dataBuffer[3], dataBuffer[3]));
}
}
else
{
lastLba = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
(pSATAIdData->numOfUserAddressableSectorsLo);
lastLba = lastLba - 1;
dataBuffer[0] = (bit8)((lastLba >> 24) & 0xFF);
dataBuffer[1] = (bit8)((lastLba >> 16) & 0xFF);
dataBuffer[2] = (bit8)((lastLba >> 8) & 0xFF);
dataBuffer[3] = (bit8)((lastLba ) & 0xFF);
}
if (((pSATAIdData->word104_107[2]) & 0x1000) == 0)
{
SM_DBG5(("smsatReadCapacity10: Default Block Length is 512\n"));
dataBuffer[4] = 0x00;
dataBuffer[5] = 0x00;
dataBuffer[6] = 0x02;
dataBuffer[7] = 0x00;
}
else
{
word118 = pSATAIdData->word112_126[6];
word117 = pSATAIdData->word112_126[5];
word117_118 = (word118 << 16) + word117;
word117_118 = word117_118 * 2;
dataBuffer[4] = (bit8)((word117_118 >> 24) & 0xFF);
dataBuffer[5] = (bit8)((word117_118 >> 16) & 0xFF);
dataBuffer[6] = (bit8)((word117_118 >> 8) & 0xFF);
dataBuffer[7] = (bit8)(word117_118 & 0xFF);
SM_DBG1(("smsatReadCapacity10: Nondefault word118 %d 0x%x !!!\n", word118, word118));
SM_DBG1(("smsatReadCapacity10: Nondefault word117 %d 0x%x !!!\n", word117, word117));
SM_DBG1(("smsatReadCapacity10: Nondefault Block Length is %d 0x%x !!!\n",word117_118, word117_118));
}
pSatDevData->satMaxLBA[0] = 0;
pSatDevData->satMaxLBA[1] = 0;
pSatDevData->satMaxLBA[2] = 0;
pSatDevData->satMaxLBA[3] = 0;
pSatDevData->satMaxLBA[4] = dataBuffer[0];
pSatDevData->satMaxLBA[5] = dataBuffer[1];
pSatDevData->satMaxLBA[6] = dataBuffer[2];
pSatDevData->satMaxLBA[7] = dataBuffer[3];
SM_DBG4(("smsatReadCapacity10: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , did %d\n",
dataBuffer[0], dataBuffer[1], dataBuffer[2], dataBuffer[3],
dataBuffer[4], dataBuffer[5], dataBuffer[6], dataBuffer[7],
pSatDevData->id));
sm_memcpy(pVirtAddr, dataBuffer, MIN(allocationLen, 8));
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return SM_RC_SUCCESS;
}
osGLOBAL bit32
smsatReadCapacity16(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
bit8 dataBuffer[32] = {0};
bit8 *pVirtAddr = agNULL;
smDeviceData_t *pSatDevData;
agsaSATAIdentifyData_t *pSATAIdData;
bit32 lastLbaLo;
bit32 allocationLen;
bit32 readCapacityLen = 32;
bit32 i = 0;
pSense = satIOContext->pSense;
pVirtAddr = (bit8 *) smScsiRequest->sglVirtualAddr;
scsiCmnd = &smScsiRequest->scsiCmnd;
pSatDevData = satIOContext->pSatDevData;
pSATAIdData = &pSatDevData->satIdentifyData;
SM_DBG5(("smsatReadCapacity16: start\n"));
allocationLen = (((bit32)scsiCmnd->cdb[10]) << 24) |
(((bit32)scsiCmnd->cdb[11]) << 16) |
(((bit32)scsiCmnd->cdb[12]) << 8 ) |
(((bit32)scsiCmnd->cdb[13]) );
allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
#ifdef REMOVED
if (allocationLen < readCapacityLen)
{
SM_DBG1(("smsatReadCapacity16: *** ERROR *** insufficient len=0x%x readCapacityLen=0x%x!!!\n", allocationLen, readCapacityLen));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
#endif
if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatReadCapacity16: return control!!!\n"));
return SM_RC_SUCCESS;
}
if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]) ||
(scsiCmnd->cdb[6] || scsiCmnd->cdb[7] || scsiCmnd->cdb[8] || scsiCmnd->cdb[9]) )
{
SM_DBG1(("smsatReadCapacity16: *** ERROR *** logical address non zero, did %d\n",
pSatDevData->id));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
if ( ((scsiCmnd->cdb[14]) & SCSI_READ_CAPACITY16_PMI_MASK) != 0 )
{
SM_DBG1(("smsatReadCapacity16: *** ERROR *** PMI is not zero, did %d\n",
pSatDevData->id));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
dataBuffer[0] = (bit8)(((pSATAIdData->maxLBA48_63) >> 8) & 0xff);
dataBuffer[1] = (bit8)((pSATAIdData->maxLBA48_63) & 0xff);
dataBuffer[2] = (bit8)(((pSATAIdData->maxLBA32_47) >> 8) & 0xff);
dataBuffer[3] = (bit8)((pSATAIdData->maxLBA32_47) & 0xff);
lastLbaLo = (((pSATAIdData->maxLBA16_31) << 16) ) | (pSATAIdData->maxLBA0_15);
lastLbaLo = lastLbaLo - 1;
dataBuffer[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
dataBuffer[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
dataBuffer[6] = (bit8)((lastLbaLo >> 8) & 0xFF);
dataBuffer[7] = (bit8)((lastLbaLo ) & 0xFF);
}
else
{
dataBuffer[0] = 0;
dataBuffer[1] = 0;
dataBuffer[2] = 0;
dataBuffer[3] = 0;
lastLbaLo = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
(pSATAIdData->numOfUserAddressableSectorsLo);
lastLbaLo = lastLbaLo - 1;
dataBuffer[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
dataBuffer[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
dataBuffer[6] = (bit8)((lastLbaLo >> 8) & 0xFF);
dataBuffer[7] = (bit8)((lastLbaLo ) & 0xFF);
}
dataBuffer[8] = 0x00;
dataBuffer[9] = 0x00;
dataBuffer[10] = 0x02;
dataBuffer[11] = 0x00;
pSatDevData->satMaxLBA[0] = dataBuffer[0];
pSatDevData->satMaxLBA[1] = dataBuffer[1];
pSatDevData->satMaxLBA[2] = dataBuffer[2];
pSatDevData->satMaxLBA[3] = dataBuffer[3];
pSatDevData->satMaxLBA[4] = dataBuffer[4];
pSatDevData->satMaxLBA[5] = dataBuffer[5];
pSatDevData->satMaxLBA[6] = dataBuffer[6];
pSatDevData->satMaxLBA[7] = dataBuffer[7];
SM_DBG5(("smsatReadCapacity16: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , did %d\n",
dataBuffer[0], dataBuffer[1], dataBuffer[2], dataBuffer[3],
dataBuffer[4], dataBuffer[5], dataBuffer[6], dataBuffer[7],
dataBuffer[8], dataBuffer[9], dataBuffer[10], dataBuffer[11],
pSatDevData->id));
if (allocationLen > 0xC)
{
for(i=12;i<=31;i++)
{
dataBuffer[i] = 0x00;
}
}
sm_memcpy(pVirtAddr, dataBuffer, MIN(allocationLen, readCapacityLen));
if (allocationLen > readCapacityLen)
{
SM_DBG1(("smsatReadCapacity16: reporting underrun readCapacityLen=0x%x allocationLen=0x%x !!!\n", readCapacityLen, allocationLen));
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOUnderRun,
allocationLen - readCapacityLen,
agNULL,
satIOContext->interruptContext );
}
else
{
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
}
return SM_RC_SUCCESS;
}
osGLOBAL bit32
smsatReportLun(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
smScsiRspSense_t *pSense;
bit8 dataBuffer[16] = {0};
bit32 allocationLen;
bit32 reportLunLen;
smScsiReportLun_t *pReportLun;
smIniScsiCmnd_t *scsiCmnd;
#ifdef TD_DEBUG_ENABLE
smDeviceData_t *pSatDevData;
#endif
pSense = satIOContext->pSense;
pReportLun = (smScsiReportLun_t *) dataBuffer;
scsiCmnd = &smScsiRequest->scsiCmnd;
#ifdef TD_DEBUG_ENABLE
pSatDevData = satIOContext->pSatDevData;
#endif
SM_DBG5(("smsatReportLun: start\n"));
allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) |
(((bit32)scsiCmnd->cdb[7]) << 16) |
(((bit32)scsiCmnd->cdb[8]) << 8 ) |
(((bit32)scsiCmnd->cdb[9]) );
allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
reportLunLen = 16;
if (allocationLen < reportLunLen)
{
SM_DBG1(("smsatReportLun: *** ERROR *** insufficient len=0x%x did %d\n",
reportLunLen, pSatDevData->id));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
pReportLun->len[0] = 0;
pReportLun->len[1] = 0;
pReportLun->len[2] = 0;
pReportLun->len[3] = sizeof (tiLUN_t);
pReportLun->reserved = 0;
pReportLun->lunList[0].lun[0] = 0;
pReportLun->lunList[0].lun[1] = 0;
pReportLun->lunList[0].lun[2] = 0;
pReportLun->lunList[0].lun[3] = 0;
pReportLun->lunList[0].lun[4] = 0;
pReportLun->lunList[0].lun[5] = 0;
pReportLun->lunList[0].lun[6] = 0;
pReportLun->lunList[0].lun[7] = 0;
sm_memcpy(smScsiRequest->sglVirtualAddr, dataBuffer, MIN(allocationLen, reportLunLen));
if (allocationLen > reportLunLen)
{
SM_DBG1(("smsatReportLun: reporting underrun reportLunLen=0x%x allocationLen=0x%x !!!\n", reportLunLen, allocationLen));
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOUnderRun,
allocationLen - reportLunLen,
agNULL,
satIOContext->interruptContext );
}
else
{
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
}
return SM_RC_SUCCESS;
}
osGLOBAL bit32
smsatFormatUnit(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
bit32 index = 0;
pSense = satIOContext->pSense;
scsiCmnd = &smScsiRequest->scsiCmnd;
SM_DBG5(("smsatFormatUnit: start\n"));
if ( ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) == 0) ||
((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK))
)
{
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
SM_DBG1(("smsatFormatUnit: return opcode!!!\n"));
return SM_RC_SUCCESS;
}
if ( (((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x00) ||
((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x06)) )
{
if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x00)
{
index = 8;
}
if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x01)
{
index = 10;
}
if ((scsiCmnd->cdb[index] != 0) || (scsiCmnd->cdb[index+1] != 0))
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatFormatUnit: return defect list format!!!\n"));
return SM_RC_SUCCESS;
}
}
if ( (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
(scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_CMPLIST_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatFormatUnit: return cmplist!!!\n"));
return SM_RC_SUCCESS;
}
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatFormatUnit: return control!!!\n"));
return SM_RC_SUCCESS;
}
if (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK)
{
if ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) ||
( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK)) ||
( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
!(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK))
)
{
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
SM_DBG5(("smsatFormatUnit: return defect list case 1\n"));
return SM_RC_SUCCESS;
}
if ( ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
!(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
!(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
||
( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
!(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
||
( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG5(("smsatFormatUnit: return defect list case 2\n"));
return SM_RC_SUCCESS;
}
}
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
SM_DBG5(("smsatFormatUnit: return last\n"));
return SM_RC_SUCCESS;
}
osGLOBAL bit32
smsatSendDiagnostic(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
smDeviceData_t *pSatDevData;
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 parmLen;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
SM_DBG5(("smsatSendDiagnostic: start\n"));
pSatDevData->satVerifyState = 0;
pSatDevData->satBGPendingDiag = agFALSE;
if ( (scsiCmnd->cdb[1] & SCSI_PF_MASK) ||
(scsiCmnd->cdb[1] & SCSI_DEVOFFL_MASK) ||
(scsiCmnd->cdb[1] & SCSI_UNITOFFL_MASK) ||
( (scsiCmnd->cdb[3] != 0) || (scsiCmnd->cdb[4] != 0) )
)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatSendDiagnostic: return PF, DEVOFFL, UNITOFFL, PARAM LIST!!!\n"));
return SM_RC_SUCCESS;
}
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatSendDiagnostic: return control!!!\n"));
return SM_RC_SUCCESS;
}
parmLen = (scsiCmnd->cdb[3] << 8) + scsiCmnd->cdb[4];
if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
(pSatDevData->satSMARTSelfTest == agFALSE)
)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatSendDiagnostic: return Table 29 case 1!!!\n"));
return SM_RC_SUCCESS;
}
if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
(pSatDevData->satSMARTSelfTest == agTRUE) &&
(pSatDevData->satSMARTEnabled == agFALSE)
)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ABORTED_COMMAND,
0,
SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG5(("smsatSendDiagnostic: return Table 29 case 2\n"));
return SM_RC_SUCCESS;
}
if ( ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
(pSatDevData->satSMARTSelfTest == agFALSE))
||
((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
(pSatDevData->satSMARTSelfTest == agTRUE) &&
(pSatDevData->satSMARTEnabled == agFALSE))
)
{
if (pSatDevData->sat48BitSupport == agTRUE)
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.device = 0x40;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
}
else
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.device = 0x40;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
}
satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG5(("smsatSendDiagnostic: return Table 29 case 4\n"));
return (status);
}
if ( (scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
(pSatDevData->satSMARTSelfTest == agTRUE) &&
(pSatDevData->satSMARTEnabled == agTRUE)
)
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART;
fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;
fis->d.lbaLow = 0x81;
fis->d.lbaMid = 0x4F;
fis->d.lbaHigh = 0xC2;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.device = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG5(("smsatSendDiagnostic: return Table 29 case 5\n"));
return (status);
}
if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
(pSatDevData->satSMARTSelfTest == agTRUE) &&
(pSatDevData->satSMARTEnabled == agTRUE)
)
{
switch ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_TEST_CODE_MASK) >> 5)
{
case 1:
pSatDevData->satBGPendingDiag = agTRUE;
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext );
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART;
fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;
fis->d.lbaLow = 0x01;
fis->d.lbaMid = 0x4F;
fis->d.lbaHigh = 0xC2;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.device = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG5(("smsatSendDiagnostic: return Table 28 case 1\n"));
return (status);
case 2:
pSatDevData->satBGPendingDiag = agTRUE;
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext );
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART;
fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;
fis->d.lbaLow = 0x02;
fis->d.lbaMid = 0x4F;
fis->d.lbaHigh = 0xC2;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.device = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG5(("smsatSendDiagnostic: return Table 28 case 2\n"));
return (status);
case 4:
if (parmLen != 0)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatSendDiagnostic: case 4, non zero ParmLen %d!!!\n", parmLen));
return SM_RC_SUCCESS;
}
if (pSatDevData->satBGPendingDiag == agTRUE)
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART;
fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;
fis->d.lbaLow = 0x7F;
fis->d.lbaMid = 0x4F;
fis->d.lbaHigh = 0xC2;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.device = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG5(("smsatSendDiagnostic: send SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE case 3\n"));
SM_DBG5(("smsatSendDiagnostic: Table 28 case 4\n"));
return (status);
}
else
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatSendDiagnostic: case 4, no pending diagnostic in background!!!\n"));
SM_DBG5(("smsatSendDiagnostic: Table 28 case 4\n"));
return SM_RC_SUCCESS;
}
break;
case 5:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART;
fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;
fis->d.lbaLow = 0x81;
fis->d.lbaMid = 0x4F;
fis->d.lbaHigh = 0xC2;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.device = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG5(("smsatSendDiagnostic: return Table 28 case 5\n"));
return (status);
case 6:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART;
fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;
fis->d.lbaLow = 0x82;
fis->d.lbaMid = 0x4F;
fis->d.lbaHigh = 0xC2;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.device = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG5(("smsatSendDiagnostic: return Table 28 case 6\n"));
return (status);
case 0:
case 3:
case 7:
default:
break;
}
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext );
SM_DBG5(("smsatSendDiagnostic: return Table 28 case 0,3,7 and default\n"));
return SM_RC_SUCCESS;
}
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext );
SM_DBG5(("smsatSendDiagnostic: return last\n"));
return SM_RC_SUCCESS;
}
osGLOBAL bit32
smsatStartStopUnit(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
smDeviceData_t *pSatDevData;
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
SM_DBG5(("smsatStartStopUnit: start\n"));
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatStartStopUnit: return control!!!\n"));
return SM_RC_SUCCESS;
}
if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
{
if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
{
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext );
SM_DBG5(("smsatStartStopUnit: return table48 case 1-1\n"));
return SM_RC_SUCCESS;
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_FLUSH_CACHE_EXT;
fis->h.features = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.lbaLow = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMid = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHigh = 0;
fis->d.lbaHighExp = 0;
fis->d.device = 0;
fis->d.control = 0;
fis->d.reserved4 = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
}
else
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_FLUSH_CACHE;
fis->h.features = 0;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.device = 0;
fis->d.control = 0;
fis->d.reserved4 = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
}
satIOContext->satCompleteCB = &smsatStartStopUnitCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG5(("smsatStartStopUnit: return table48 case 1\n"));
return (status);
}
else if ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
{
if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
{
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext );
SM_DBG5(("smsatStartStopUnit: return table48 case 2 1\n"));
return SM_RC_SUCCESS;
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = 0x01;
fis->d.lbaMid = 0x00;
fis->d.lbaHigh = 0x00;
fis->d.lbaLowExp = 0x00;
fis->d.lbaMidExp = 0x00;
fis->d.lbaHighExp = 0x00;
fis->d.featuresExp = 0;
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.device = 0x40;
fis->d.control = 0;
fis->d.reserved5 = 0;
}
else
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = 0x01;
fis->d.lbaMid = 0x00;
fis->d.lbaHigh = 0x00;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.device = 0x40;
fis->d.control = 0;
fis->d.reserved5 = 0;
}
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatStartStopUnitCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG5(("smsatStartStopUnit: return table48 case 2 2\n"));
return status;
}
else if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
{
if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
{
if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
{
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext );
SM_DBG5(("smsatStartStopUnit: return table48 case 3 1\n"));
return SM_RC_SUCCESS;
}
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_MEDIA_EJECT;
fis->h.features = 0;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.device = 0;
fis->d.control = 0;
fis->d.reserved4 = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatStartStopUnitCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
else
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG5(("smsatStartStopUnit: return Table 29 case 3 2\n"));
return SM_RC_SUCCESS;
}
}
else
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG5(("smsatStartStopUnit: return Table 29 case 4\n"));
return SM_RC_SUCCESS;
}
}
osGLOBAL bit32
smsatWriteSame10(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
smDeviceData_t *pSatDevData;
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit32 tl = 0;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
SM_DBG5(("smsatWriteSame10: start\n"));
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatWriteSame10: return control!!!\n"));
return SM_RC_SUCCESS;
}
if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
!(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
{
SM_DBG5(("smsatWriteSame10: case 1\n"));
if ( pSatDevData->sat48BitSupport != agTRUE )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatWriteSame10: return internal checking!!!\n"));
return SM_RC_SUCCESS;
}
lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
+ (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
if (lba > SAT_TR_LBA_LIMIT - 1)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatWriteSame10: return LBA out of range!!!\n"));
return SM_RC_SUCCESS;
}
}
if (lba + tl <= SAT_TR_LBA_LIMIT)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG1(("smsatWriteSame10: case 1-2 !!! error due to writesame10!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
else
{
SM_DBG1(("smsatWriteSame10: case 1-1 !!! error due to writesame10!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatWriteSame10: case 1-3\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (tl == 0)
{
if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
{
SM_DBG1(("smsatWriteSame10: case 3 !!! warning can't fit sectors!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
}
else
{
SM_DBG5(("smsatWriteSame10: case 1-4\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (tl == 0)
{
if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
{
SM_DBG1(("smsatWriteSame10: case 4 !!! warning can't fit sectors!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
}
}
if (pSatDevData->satNCQ == agTRUE)
{
if (pSatDevData->sat48BitSupport != agTRUE)
{
SM_DBG1(("smsatWriteSame10: case 1-5 !!! error NCQ but 28 bit address support!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
SM_DBG5(("smsatWriteSame10: case 1-5\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_FPDMA_QUEUED;
if (tl == 0)
{
if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
{
SM_DBG1(("smsatWriteSame10: case 4 !!! warning can't fit sectors!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
fis->h.features = 1;
fis->d.featuresExp = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
}
satIOContext->satCompleteCB = &smsatWriteSame10CB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return (status);
}
else if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG5(("smsatWriteSame10: return Table 62 case 2\n"));
return SM_RC_SUCCESS;
}
else if ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
!(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
{
SM_DBG5(("smsatWriteSame10: Table 62 case 3\n"));
}
else
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG5(("smsatWriteSame10: return Table 62 case 4\n"));
return SM_RC_SUCCESS;
}
return SM_RC_SUCCESS;
}
osGLOBAL bit32
smsatWriteSame16(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
smScsiRspSense_t *pSense;
pSense = satIOContext->pSense;
SM_DBG5(("smsatWriteSame16: start\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_NO_SENSE,
0,
SCSI_SNSCODE_NO_ADDITIONAL_INFO,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatWriteSame16: return internal checking!!!\n"));
return SM_RC_SUCCESS;
}
osGLOBAL bit32
smsatLogSense(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
smDeviceData_t *pSatDevData;
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit8 *pLogPage;
bit32 flag = 0;
bit16 AllocLen = 0;
bit8 AllLogPages[8];
bit16 lenRead = 0;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
pLogPage = (bit8 *) smScsiRequest->sglVirtualAddr;
SM_DBG5(("smsatLogSense: start\n"));
sm_memset(&AllLogPages, 0, 8);
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatLogSense: return control!!!\n"));
return SM_RC_SUCCESS;
}
AllocLen = ((scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]);
AllocLen = MIN(AllocLen, scsiCmnd->expDataLength);
if (AllocLen == 4)
{
SM_DBG1(("smsatLogSense: AllocLen is 4!!!\n"));
switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
{
case LOGSENSE_SUPPORTED_LOG_PAGES:
SM_DBG5(("smsatLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
if (pSatDevData->satSMARTFeatureSet == agTRUE)
{
flag = 1;
if (pSatDevData->satSMARTSelfTest == agTRUE)
{
flag = 2;
}
}
else
{
flag = 0;
}
lenRead = 4;
AllLogPages[0] = LOGSENSE_SUPPORTED_LOG_PAGES;
AllLogPages[1] = 0;
switch (flag)
{
case 0:
AllLogPages[2] = 0;
AllLogPages[3] = 1;
break;
case 1:
AllLogPages[2] = 0;
AllLogPages[3] = 2;
break;
case 2:
AllLogPages[2] = 0;
AllLogPages[3] = 3;
break;
default:
SM_DBG1(("smsatLogSense: error unallowed flag value %d!!!\n", flag));
break;
}
sm_memcpy(pLogPage, &AllLogPages, lenRead);
break;
case LOGSENSE_SELFTEST_RESULTS_PAGE:
SM_DBG5(("smsatLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
lenRead = 4;
AllLogPages[0] = LOGSENSE_SELFTEST_RESULTS_PAGE;
AllLogPages[1] = 0;
AllLogPages[2] = 0x01;
AllLogPages[3] = 0x90;
sm_memcpy(pLogPage, &AllLogPages, lenRead);
break;
case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
SM_DBG5(("smsatLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
lenRead = 4;
AllLogPages[0] = LOGSENSE_INFORMATION_EXCEPTIONS_PAGE;
AllLogPages[1] = 0;
AllLogPages[2] = 0;
AllLogPages[3] = INFORMATION_EXCEPTIONS_LOG_PAGE_LENGTH - 1 - 3;
sm_memcpy(pLogPage, &AllLogPages, lenRead);
break;
default:
SM_DBG1(("smsatLogSense: default Page Code 0x%x!!!\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return SM_RC_SUCCESS;
}
switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
{
case LOGSENSE_SUPPORTED_LOG_PAGES:
SM_DBG5(("smsatLogSense: case 1\n"));
if (pSatDevData->satSMARTFeatureSet == agTRUE)
{
flag = 1;
if (pSatDevData->satSMARTSelfTest == agTRUE)
{
flag = 2;
}
}
else
{
flag = 0;
}
AllLogPages[0] = 0;
AllLogPages[1] = 0;
switch (flag)
{
case 0:
AllLogPages[2] = 0;
AllLogPages[3] = 1;
AllLogPages[4] = 0x00;
lenRead = (bit8)(MIN(AllocLen, 5));
break;
case 1:
AllLogPages[2] = 0;
AllLogPages[3] = 2;
AllLogPages[4] = 0x00;
AllLogPages[5] = 0x10;
lenRead = (bit8)(MIN(AllocLen, 6));
break;
case 2:
AllLogPages[2] = 0;
AllLogPages[3] = 3;
AllLogPages[4] = 0x00;
AllLogPages[5] = 0x10;
AllLogPages[6] = 0x2F;
lenRead = (bit8)(MIN(AllocLen, 7));
break;
default:
SM_DBG1(("smsatLogSense: error unallowed flag value %d!!!\n", flag));
break;
}
sm_memcpy(pLogPage, &AllLogPages, lenRead);
if (AllocLen > lenRead )
{
SM_DBG1(("smsatLogSense: reporting underrun lenRead=0x%x AllocLen=0x%x!!!\n", lenRead, AllocLen));
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOUnderRun,
AllocLen - lenRead,
agNULL,
satIOContext->interruptContext );
}
else
{
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
}
break;
case LOGSENSE_SELFTEST_RESULTS_PAGE:
SM_DBG5(("smsatLogSense: case 2\n"));
if (pSatDevData->satSMARTSelfTest == agFALSE)
{
SM_DBG5(("smsatLogSense: case 2 no SMART Self Test\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
}
else
{
if (pSatDevData->satSMARTEnabled == agFALSE)
{
SM_DBG5(("smsatLogSense: case 2 calling satSMARTEnable\n"));
status = smsatLogSenseAllocate(smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext,
0,
LOG_SENSE_0
);
return status;
}
else
{
if ( pSatDevData->sat48BitSupport == agTRUE )
{
SM_DBG5(("smsatLogSense: case 2-1 sends READ LOG EXT\n"));
status = smsatLogSenseAllocate(smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext,
512,
LOG_SENSE_1
);
return status;
}
else
{
SM_DBG5(("smsatLogSense: case 2-2 sends SMART READ LOG\n"));
status = smsatLogSenseAllocate(smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext,
512,
LOG_SENSE_2
);
return status;
}
}
}
break;
case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
SM_DBG5(("smsatLogSense: case 3\n"));
if (pSatDevData->satSMARTFeatureSet == agFALSE)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
}
else
{
if (pSatDevData->satSMARTEnabled == agFALSE)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ABORTED_COMMAND,
0,
SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
}
else
{
SM_DBG5(("smsatLogSense: case 3 sends SMART RETURN STATUS\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART;
fis->h.features = SAT_SMART_RETURN_STATUS;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.lbaLow = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMid = 0x4F;
fis->d.lbaMidExp = 0;
fis->d.lbaHigh = 0xC2;
fis->d.lbaHighExp = 0;
fis->d.device = 0;
fis->d.control = 0;
fis->d.reserved4 = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatLogSenseCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
}
break;
default:
SM_DBG1(("smsatLogSense: default Page Code 0x%x!!!\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
break;
}
return SM_RC_SUCCESS;
}
osGLOBAL bit32
smsatLogSenseAllocate(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smSCSIRequest,
smSatIOContext_t *satIOContext,
bit32 payloadSize,
bit32 flag
)
{
smDeviceData_t *pSatDevData;
smIORequestBody_t *smIORequestBody;
smSatInternalIo_t *satIntIo = agNULL;
smSatIOContext_t *satIOContext2;
bit32 status;
SM_DBG5(("smsatLogSenseAllocate: start\n"));
pSatDevData = satIOContext->pSatDevData;
satIntIo = smsatAllocIntIoResource( smRoot,
smIORequest,
pSatDevData,
payloadSize,
satIntIo);
if (satIntIo == agNULL)
{
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOFailed,
smDetailOtherError,
agNULL,
satIOContext->interruptContext );
SM_DBG1(("smsatLogSenseAllocate: fail in allocation!!!\n"));
return SM_RC_SUCCESS;
}
satIntIo->satOrgSmIORequest = smIORequest;
smIORequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody;
satIOContext2 = &(smIORequestBody->transport.SATA.satIOContext);
satIOContext2->pSatDevData = pSatDevData;
satIOContext2->pFis = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
satIOContext2->pScsiCmnd = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
satIOContext2->pSense = &(smIORequestBody->transport.SATA.sensePayload);
satIOContext2->pSmSenseData = &(smIORequestBody->transport.SATA.smSenseData);
satIOContext2->pSmSenseData->senseData = satIOContext2->pSense;
satIOContext2->smRequestBody = satIntIo->satIntRequestBody;
satIOContext2->interruptContext = satIOContext->interruptContext;
satIOContext2->satIntIoContext = satIntIo;
satIOContext2->psmDeviceHandle = smDeviceHandle;
satIOContext2->satOrgIOContext = satIOContext;
if (flag == LOG_SENSE_0)
{
status = smsatSMARTEnable( smRoot,
&(satIntIo->satIntSmIORequest),
smDeviceHandle,
&(satIntIo->satIntSmScsiXchg),
satIOContext2);
}
else if (flag == LOG_SENSE_1)
{
status = smsatLogSense_2( smRoot,
&(satIntIo->satIntSmIORequest),
smDeviceHandle,
&(satIntIo->satIntSmScsiXchg),
satIOContext2);
}
else
{
status = smsatLogSense_3( smRoot,
&(satIntIo->satIntSmIORequest),
smDeviceHandle,
&(satIntIo->satIntSmScsiXchg),
satIOContext2);
}
if (status != SM_RC_SUCCESS)
{
smsatFreeIntIoResource( smRoot,
pSatDevData,
satIntIo);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOFailed,
smDetailOtherError,
agNULL,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
return SM_RC_SUCCESS;
}
osGLOBAL bit32
smsatSMARTEnable(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
fis = satIOContext->pFis;
SM_DBG5(("smsatSMARTEnable: start\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART;
fis->h.features = SAT_SMART_ENABLE_OPERATIONS;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0x4F;
fis->d.lbaHigh = 0xC2;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatSMARTEnableCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
osGLOBAL bit32
smsatLogSense_2(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
fis = satIOContext->pFis;
SM_DBG5(("smsatLogSense_2: start\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_LOG_EXT;
fis->h.features = 0;
fis->d.lbaLow = 0x07;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0x01;
fis->d.sectorCountExp = 0x00;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
satIOContext->satCompleteCB = &smsatLogSenseCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
osGLOBAL bit32
smsatLogSense_3(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
fis = satIOContext->pFis;
SM_DBG5(("smsatLogSense_3: start\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART;
fis->h.features = SAT_SMART_READ_LOG;
fis->d.lbaLow = 0x06;
fis->d.lbaMid = 0x4F;
fis->d.lbaHigh = 0xC2;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0x01;
fis->d.sectorCountExp = 0x00;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
satIOContext->satCompleteCB = &smsatLogSenseCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
osGLOBAL bit32
smsatModeSelect6(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
smDeviceData_t *pSatDevData;
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit8 *pLogPage;
bit32 StartingIndex = 0;
bit8 PageCode = 0;
bit32 chkCnd = agFALSE;
bit32 parameterListLen = 0;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
pLogPage = (bit8 *) smScsiRequest->sglVirtualAddr;
SM_DBG5(("smsatModeSelect6: start\n"));
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatModeSelect6: return control!!!\n"));
return SM_RC_SUCCESS;
}
if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT6_PF_MASK))
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatModeSelect6: PF bit check!!!\n"));
return SM_RC_SUCCESS;
}
parameterListLen = scsiCmnd->cdb[4];
parameterListLen = MIN(parameterListLen, scsiCmnd->expDataLength);
if ((0 == parameterListLen) || (agNULL == pLogPage))
{
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return SM_RC_SUCCESS;
}
if (pLogPage[3] == 8)
{
PageCode = (bit8)(pLogPage[12] & 0x3F);
StartingIndex = 12;
}
else if (pLogPage[3] == 0)
{
PageCode = (bit8)(pLogPage[4] & 0x3F);
StartingIndex = 4;
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return SM_RC_SUCCESS;
}
else
{
SM_DBG1(("smsatModeSelect6: return mode parameter block descriptor 0x%x!!!\n", pLogPage[3]));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_NO_SENSE,
0,
SCSI_SNSCODE_NO_ADDITIONAL_INFO,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
switch (PageCode)
{
case MODESELECT_CONTROL_PAGE:
SM_DBG1(("smsatModeSelect6: Control mode page!!!\n"));
if ( pLogPage[StartingIndex+1] != 0x0A ||
pLogPage[StartingIndex+2] != 0x02 ||
(pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
(pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
(pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 ||
(pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 ||
(pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 ||
(pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 ||
(pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 ||
(pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 ||
(pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 ||
pLogPage[StartingIndex+8] != 0xFF ||
pLogPage[StartingIndex+9] != 0xFF ||
pLogPage[StartingIndex+10] != 0x00 ||
pLogPage[StartingIndex+11] != 0x00
)
{
chkCnd = agTRUE;
}
if (chkCnd == agTRUE)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatModeSelect6: unexpected values!!!\n"));
}
else
{
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
}
return SM_RC_SUCCESS;
break;
case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
SM_DBG1(("smsatModeSelect6: Read-Write Error Recovery mode page!!!\n"));
if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_AWRE_MASK) ||
(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_RC_MASK) ||
(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_EER_MASK) ||
(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PER_MASK) ||
(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DTE_MASK) ||
(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DCR_MASK) ||
(pLogPage[StartingIndex + 10]) ||
(pLogPage[StartingIndex + 11])
)
{
SM_DBG5(("smsatModeSelect6: return check condition\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
else
{
SM_DBG5(("smsatModeSelect6: return GOOD \n"));
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return SM_RC_SUCCESS;
}
break;
case MODESELECT_CACHING:
SM_DBG5(("smsatModeSelect6: Caching mode page\n"));
if ( (pLogPage[StartingIndex + 2] & 0xFB) ||
(pLogPage[StartingIndex + 3]) ||
(pLogPage[StartingIndex + 4]) ||
(pLogPage[StartingIndex + 5]) ||
(pLogPage[StartingIndex + 6]) ||
(pLogPage[StartingIndex + 7]) ||
(pLogPage[StartingIndex + 8]) ||
(pLogPage[StartingIndex + 9]) ||
(pLogPage[StartingIndex + 10]) ||
(pLogPage[StartingIndex + 11]) ||
(pLogPage[StartingIndex + 12] & 0xC1) ||
(pLogPage[StartingIndex + 13]) ||
(pLogPage[StartingIndex + 14]) ||
(pLogPage[StartingIndex + 15])
)
{
SM_DBG1(("smsatModeSelect6: return check condition!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
else
{
if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_WCE_MASK) )
{
SM_DBG5(("smsatModeSelect6: disable write cache\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SET_FEATURES;
fis->h.features = 0x82;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
else
{
SM_DBG5(("smsatModeSelect6: enable write cache\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SET_FEATURES;
fis->h.features = 0x02;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
}
break;
case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
SM_DBG5(("smsatModeSelect6: Informational Exception Control mode page\n"));
if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PERF_MASK) ||
(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_TEST_MASK)
)
{
SM_DBG1(("smsatModeSelect6: return check condition!!! \n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
else
{
if ( !(pLogPage[StartingIndex + 2] & 0x08) )
{
SM_DBG5(("smsatModeSelect6: enable information exceptions reporting\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART;
fis->h.features = SAT_SMART_ENABLE_OPERATIONS;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0x4F;
fis->d.lbaHigh = 0xC2;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
else
{
SM_DBG5(("smsatModeSelect6: disable information exceptions reporting\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART;
fis->h.features = SAT_SMART_DISABLE_OPERATIONS;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0x4F;
fis->d.lbaHigh = 0xC2;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
}
break;
default:
SM_DBG1(("smsatModeSelect6: Error unknown page code 0x%x!!!\n", pLogPage[12]));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_NO_SENSE,
0,
SCSI_SNSCODE_NO_ADDITIONAL_INFO,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
osGLOBAL bit32
smsatModeSelect10(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
smDeviceData_t *pSatDevData;
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit8 *pLogPage;
bit16 BlkDescLen = 0;
bit32 StartingIndex = 0;
bit8 PageCode = 0;
bit32 chkCnd = agFALSE;
bit32 parameterListLen = 0;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
pLogPage = (bit8 *) smScsiRequest->sglVirtualAddr;
SM_DBG5(("smsatModeSelect10: start\n"));
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatModeSelect10: return control!!!\n"));
return SM_RC_SUCCESS;
}
if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT10_PF_MASK))
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatModeSelect10: PF bit check!!!\n"));
return SM_RC_SUCCESS;
}
parameterListLen = ((scsiCmnd->cdb[7]) << 8) + scsiCmnd->cdb[8];
parameterListLen = MIN(parameterListLen, scsiCmnd->expDataLength);
if ((0 == parameterListLen) || (agNULL == pLogPage))
{
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return SM_RC_SUCCESS;
}
BlkDescLen = (bit8)((pLogPage[6] << 8) + pLogPage[7]);
if ( (BlkDescLen == 8) && !(pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
{
PageCode = (bit8)(pLogPage[16] & 0x3F);
StartingIndex = 16;
}
else if ( (BlkDescLen == 16) && (pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
{
PageCode = (bit8)(pLogPage[24] & 0x3F);
StartingIndex = 24;
}
else if (BlkDescLen == 0)
{
PageCode = (bit8)(pLogPage[8] & 0x3F);
StartingIndex = 8;
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return SM_RC_SUCCESS;
}
else
{
SM_DBG1(("smsatModeSelect10: return mode parameter block descriptor 0x%x!!!\n", BlkDescLen));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_NO_SENSE,
0,
SCSI_SNSCODE_NO_ADDITIONAL_INFO,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
if (StartingIndex == 8)
{
smhexdump("startingindex 8", (bit8 *)pLogPage, 8);
}
else if(StartingIndex == 16)
{
if (PageCode == MODESELECT_CACHING)
{
smhexdump("startingindex 16", (bit8 *)pLogPage, 16+20);
}
else
{
smhexdump("startingindex 16", (bit8 *)pLogPage, 16+12);
}
}
else
{
if (PageCode == MODESELECT_CACHING)
{
smhexdump("startingindex 24", (bit8 *)pLogPage, 24+20);
}
else
{
smhexdump("startingindex 24", (bit8 *)pLogPage, 24+12);
}
}
switch (PageCode)
{
case MODESELECT_CONTROL_PAGE:
SM_DBG5(("smsatModeSelect10: Control mode page\n"));
if ( pLogPage[StartingIndex+1] != 0x0A ||
pLogPage[StartingIndex+2] != 0x02 ||
(pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
(pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
(pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 ||
(pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 ||
(pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 ||
(pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 ||
(pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 ||
(pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 ||
(pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 ||
pLogPage[StartingIndex+8] != 0xFF ||
pLogPage[StartingIndex+9] != 0xFF ||
pLogPage[StartingIndex+10] != 0x00 ||
pLogPage[StartingIndex+11] != 0x00
)
{
chkCnd = agTRUE;
}
if (chkCnd == agTRUE)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatModeSelect10: unexpected values!!!\n"));
}
else
{
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
}
return SM_RC_SUCCESS;
break;
case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
SM_DBG5(("smsatModeSelect10: Read-Write Error Recovery mode page\n"));
if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_AWRE_MASK) ||
(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_RC_MASK) ||
(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_EER_MASK) ||
(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PER_MASK) ||
(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DTE_MASK) ||
(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DCR_MASK) ||
(pLogPage[StartingIndex + 10]) ||
(pLogPage[StartingIndex + 11])
)
{
SM_DBG1(("smsatModeSelect10: return check condition!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
else
{
SM_DBG2(("smsatModeSelect10: return GOOD \n"));
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return SM_RC_SUCCESS;
}
break;
case MODESELECT_CACHING:
SM_DBG5(("smsatModeSelect10: Caching mode page\n"));
if ( (pLogPage[StartingIndex + 2] & 0xFB) ||
(pLogPage[StartingIndex + 3]) ||
(pLogPage[StartingIndex + 4]) ||
(pLogPage[StartingIndex + 5]) ||
(pLogPage[StartingIndex + 6]) ||
(pLogPage[StartingIndex + 7]) ||
(pLogPage[StartingIndex + 8]) ||
(pLogPage[StartingIndex + 9]) ||
(pLogPage[StartingIndex + 10]) ||
(pLogPage[StartingIndex + 11]) ||
(pLogPage[StartingIndex + 12] & 0xC1) ||
(pLogPage[StartingIndex + 13]) ||
(pLogPage[StartingIndex + 14]) ||
(pLogPage[StartingIndex + 15])
)
{
SM_DBG1(("smsatModeSelect10: return check condition!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
else
{
if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_WCE_MASK) )
{
SM_DBG5(("smsatModeSelect10: disable write cache\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SET_FEATURES;
fis->h.features = 0x82;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
else
{
SM_DBG5(("smsatModeSelect10: enable write cache\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SET_FEATURES;
fis->h.features = 0x02;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
}
break;
case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
SM_DBG5(("smsatModeSelect10: Informational Exception Control mode page\n"));
if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PERF_MASK) ||
(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_TEST_MASK)
)
{
SM_DBG1(("smsatModeSelect10: return check condition!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
else
{
if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DEXCPT_MASK) )
{
SM_DBG5(("smsatModeSelect10: enable information exceptions reporting\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART;
fis->h.features = SAT_SMART_ENABLE_OPERATIONS;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0x4F;
fis->d.lbaHigh = 0xC2;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
else
{
SM_DBG5(("smsatModeSelect10: disable information exceptions reporting\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART;
fis->h.features = SAT_SMART_DISABLE_OPERATIONS;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0x4F;
fis->d.lbaHigh = 0xC2;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
}
break;
default:
SM_DBG1(("smsatModeSelect10: Error unknown page code 0x%x!!!\n", pLogPage[12]));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_NO_SENSE,
0,
SCSI_SNSCODE_NO_ADDITIONAL_INFO,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
osGLOBAL bit32
smsatSynchronizeCache10(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
smDeviceData_t *pSatDevData;
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
SM_DBG5(("smsatSynchronizeCache10: start\n"));
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatSynchronizeCache10: return control!!!\n"));
return SM_RC_SUCCESS;
}
if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
{
SM_DBG1(("smsatSynchronizeCache10: GOOD status due to IMMED bit!!!\n"));
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE EXT\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_FLUSH_CACHE_EXT;
fis->h.features = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.lbaLow = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMid = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHigh = 0;
fis->d.lbaHighExp = 0;
fis->d.device = 0;
fis->d.control = 0;
fis->d.reserved4 = 0;
fis->d.reserved5 = 0;
}
else
{
SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_FLUSH_CACHE;
fis->h.features = 0;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.device = 0;
fis->d.control = 0;
fis->d.reserved4 = 0;
fis->d.reserved5 = 0;
}
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatSynchronizeCache10n16CB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return (status);
}
osGLOBAL bit32
smsatSynchronizeCache16(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
smDeviceData_t *pSatDevData;
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
SM_DBG5(("smsatSynchronizeCache10: start\n"));
if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatSynchronizeCache10: return control!!!\n"));
return SM_RC_SUCCESS;
}
if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
{
SM_DBG1(("smsatSynchronizeCache10: GOOD status due to IMMED bit!!!\n"));
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE EXT\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_FLUSH_CACHE_EXT;
fis->h.features = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.lbaLow = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMid = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHigh = 0;
fis->d.lbaHighExp = 0;
fis->d.device = 0;
fis->d.control = 0;
fis->d.reserved4 = 0;
fis->d.reserved5 = 0;
}
else
{
SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_FLUSH_CACHE;
fis->h.features = 0;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.device = 0;
fis->d.control = 0;
fis->d.reserved4 = 0;
fis->d.reserved5 = 0;
}
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatSynchronizeCache10n16CB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return (status);
}
osGLOBAL bit32
smsatWriteAndVerify10(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
smDeviceData_t *pSatDevData;
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[8];
bit8 TL[8];
bit32 AllChk = agFALSE;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
SM_DBG5(("smsatWriteAndVerify10: start\n"));
if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatWriteAndVerify10: BYTCHK bit checking!!!\n"));
return SM_RC_SUCCESS;
}
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatWriteAndVerify10: return control!!!\n"));
return SM_RC_SUCCESS;
}
sm_memset(LBA, 0, sizeof(LBA));
sm_memset(TL, 0, sizeof(TL));
LBA[0] = 0;
LBA[1] = 0;
LBA[2] = 0;
LBA[3] = 0;
LBA[4] = scsiCmnd->cdb[2];
LBA[5] = scsiCmnd->cdb[3];
LBA[6] = scsiCmnd->cdb[4];
LBA[7] = scsiCmnd->cdb[5];
TL[0] = 0;
TL[1] = 0;
TL[2] = 0;
TL[3] = 0;
TL[4] = 0;
TL[5] = 0;
TL[6] = scsiCmnd->cdb[7];
TL[7] = scsiCmnd->cdb[8];
lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
+ (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatWriteAndVerify10: return LBA out of range!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
else
{
AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatWriteAndVerify10: return LBA out of range, EXT!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatWriteAndVerify10: case 2\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[8];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satIOContext->ATACmd = SAT_WRITE_DMA;
}
else
{
SM_DBG5(("smsatWriteAndVerify10: case 1\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[8];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
satIOContext->ATACmd = SAT_WRITE_SECTORS;
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatWriteAndVerify10: case 3\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[8];
fis->d.sectorCountExp = scsiCmnd->cdb[7];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
}
else
{
SM_DBG5(("smsatWriteAndVerify10: case 4\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[8];
fis->d.sectorCountExp = scsiCmnd->cdb[7];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
}
}
if (pSatDevData->satNCQ == agTRUE)
{
if (pSatDevData->sat48BitSupport != agTRUE)
{
SM_DBG1(("smsatWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
SM_DBG5(("smsatWriteAndVerify10: case 5\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_FPDMA_QUEUED;
fis->h.features = scsiCmnd->cdb[8];
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK)
fis->d.device = 0xC0;
else
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = scsiCmnd->cdb[7];
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
}
satIOContext->currentLBA = lba;
satIOContext->OrgTL = tl;
if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
{
LoopNum = smsatComputeLoopNum(tl, 0xFF);
}
else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
fis->h.command == SAT_WRITE_DMA_EXT ||
fis->h.command == SAT_WRITE_DMA_FUA_EXT
)
{
LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
}
else
{
LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
SM_DBG5(("smsatWriteAndVerify10: NON CHAINED data\n"));
satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
}
else
{
SM_DBG1(("smsatWriteAndVerify10: CHAINED data!!!\n"));
if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
{
fis->d.sectorCount = 0xFF;
}
else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
fis->h.command == SAT_WRITE_DMA_EXT ||
fis->h.command == SAT_WRITE_DMA_FUA_EXT
)
{
fis->d.sectorCount = 0xFF;
fis->d.sectorCountExp = 0xFF;
}
else
{
fis->h.features = 0xFF;
fis->d.featuresExp = 0xFF;
}
satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
}
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return (status);
}
osGLOBAL bit32
smsatWriteAndVerify12(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
smDeviceData_t *pSatDevData;
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[8];
bit8 TL[8];
bit32 AllChk = agFALSE;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
SM_DBG5(("smsatWriteAndVerify12: start\n"));
if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatWriteAndVerify12: BYTCHK bit checking!!!\n"));
return SM_RC_SUCCESS;
}
if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatWriteAndVerify12: return control!!!\n"));
return SM_RC_SUCCESS;
}
sm_memset(LBA, 0, sizeof(LBA));
sm_memset(TL, 0, sizeof(TL));
LBA[0] = 0;
LBA[1] = 0;
LBA[2] = 0;
LBA[3] = 0;
LBA[4] = scsiCmnd->cdb[2];
LBA[5] = scsiCmnd->cdb[3];
LBA[6] = scsiCmnd->cdb[4];
LBA[7] = scsiCmnd->cdb[5];
TL[0] = 0;
TL[1] = 0;
TL[2] = 0;
TL[3] = 0;
TL[4] = scsiCmnd->cdb[6];
TL[5] = scsiCmnd->cdb[7];
TL[6] = scsiCmnd->cdb[8];
TL[7] = scsiCmnd->cdb[9];
lba = smsatComputeCDB12LBA(satIOContext);
tl = smsatComputeCDB12TL(satIOContext);
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatWriteAndVerify12: return LBA out of range, not EXT!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
else
{
AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatWriteAndVerify12: return LBA out of range, EXT!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatWriteAndVerify12: case 2\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[9];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satIOContext->ATACmd = SAT_WRITE_DMA;
}
else
{
SM_DBG5(("smsatWriteAndVerify12: case 1\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[9];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
satIOContext->ATACmd = SAT_WRITE_SECTORS;
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatWriteAndVerify12: case 3\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[9];
fis->d.sectorCountExp = scsiCmnd->cdb[8];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
}
else
{
SM_DBG5(("smsatWriteAndVerify12: case 4\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[9];
fis->d.sectorCountExp = scsiCmnd->cdb[8];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
}
}
if (pSatDevData->satNCQ == agTRUE)
{
if (pSatDevData->sat48BitSupport != agTRUE)
{
SM_DBG1(("smsatWriteAndVerify12: case 5 !!! error NCQ but 28 bit address support!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
SM_DBG6(("smsatWriteAndVerify12: case 5\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_FPDMA_QUEUED;
fis->h.features = scsiCmnd->cdb[9];
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
fis->d.device = 0xC0;
else
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = scsiCmnd->cdb[8];
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
}
satIOContext->currentLBA = lba;
satIOContext->OrgTL = tl;
if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
{
LoopNum = smsatComputeLoopNum(tl, 0xFF);
}
else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
fis->h.command == SAT_WRITE_DMA_EXT ||
fis->h.command == SAT_WRITE_DMA_FUA_EXT
)
{
LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
}
else
{
LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
}
satIOContext->LoopNum = LoopNum;
satIOContext->LoopNum2 = LoopNum;
if (LoopNum == 1)
{
SM_DBG5(("smsatWriteAndVerify12: NON CHAINED data\n"));
satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
}
else
{
SM_DBG1(("smsatWriteAndVerify12: CHAINED data!!!\n"));
if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
{
fis->d.sectorCount = 0xFF;
}
else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
fis->h.command == SAT_WRITE_DMA_EXT ||
fis->h.command == SAT_WRITE_DMA_FUA_EXT
)
{
fis->d.sectorCount = 0xFF;
fis->d.sectorCountExp = 0xFF;
}
else
{
fis->h.features = 0xFF;
fis->d.featuresExp = 0xFF;
}
satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
}
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return (status);
}
osGLOBAL bit32
smsatWriteAndVerify16(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
smDeviceData_t *pSatDevData;
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[8];
bit8 TL[8];
bit32 AllChk = agFALSE;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
SM_DBG5(("smsatWriteAndVerify16: start\n"));
if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatWriteAndVerify16: BYTCHK bit checking!!!\n"));
return SM_RC_SUCCESS;
}
if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatWriteAndVerify16: return control!!!\n"));
return SM_RC_SUCCESS;
}
sm_memset(LBA, 0, sizeof(LBA));
sm_memset(TL, 0, sizeof(TL));
LBA[0] = scsiCmnd->cdb[2];
LBA[1] = scsiCmnd->cdb[3];
LBA[2] = scsiCmnd->cdb[4];
LBA[3] = scsiCmnd->cdb[5];
LBA[4] = scsiCmnd->cdb[6];
LBA[5] = scsiCmnd->cdb[7];
LBA[6] = scsiCmnd->cdb[8];
LBA[7] = scsiCmnd->cdb[9];
TL[0] = 0;
TL[1] = 0;
TL[2] = 0;
TL[3] = 0;
TL[4] = scsiCmnd->cdb[10];
TL[5] = scsiCmnd->cdb[11];
TL[6] = scsiCmnd->cdb[12];
TL[7] = scsiCmnd->cdb[13];
lba = smsatComputeCDB16LBA(satIOContext);
tl = smsatComputeCDB16TL(satIOContext);
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatWriteAndVerify16: return LBA out of range, not EXT!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
else
{
AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
if (AllChk)
{
SM_DBG1(("smsatWriteAndVerify16: return LBA out of range, EXT!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatWriteAndVerify16: case 2\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[9];
fis->d.lbaMid = scsiCmnd->cdb[8];
fis->d.lbaHigh = scsiCmnd->cdb[7];
fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[13];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satIOContext->ATACmd = SAT_WRITE_DMA;
}
else
{
SM_DBG5(("smsatWriteAndVerify16: case 1\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[9];
fis->d.lbaMid = scsiCmnd->cdb[8];
fis->d.lbaHigh = scsiCmnd->cdb[7];
fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[13];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
satIOContext->ATACmd = SAT_WRITE_SECTORS;
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatWriteAndVerify16: case 3\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[9];
fis->d.lbaMid = scsiCmnd->cdb[8];
fis->d.lbaHigh = scsiCmnd->cdb[7];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[6];
fis->d.lbaMidExp = scsiCmnd->cdb[5];
fis->d.lbaHighExp = scsiCmnd->cdb[4];
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[13];
fis->d.sectorCountExp = scsiCmnd->cdb[12];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
}
else
{
SM_DBG5(("smsatWriteAndVerify16: case 4\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[9];
fis->d.lbaMid = scsiCmnd->cdb[8];
fis->d.lbaHigh = scsiCmnd->cdb[7];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[6];
fis->d.lbaMidExp = scsiCmnd->cdb[5];
fis->d.lbaHighExp = scsiCmnd->cdb[4];
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[13];
fis->d.sectorCountExp = scsiCmnd->cdb[12];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
}
}
if (pSatDevData->satNCQ == agTRUE)
{
if (pSatDevData->sat48BitSupport != agTRUE)
{
SM_DBG1(("smsatWriteAndVerify16: case 5 !!! error NCQ but 28 bit address support!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
SM_DBG6(("smsatWriteAndVerify16: case 5\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_FPDMA_QUEUED;
fis->h.features = scsiCmnd->cdb[13];
fis->d.lbaLow = scsiCmnd->cdb[9];
fis->d.lbaMid = scsiCmnd->cdb[8];
fis->d.lbaHigh = scsiCmnd->cdb[7];
if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
fis->d.device = 0xC0;
else
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[6];
fis->d.lbaMidExp = scsiCmnd->cdb[5];
fis->d.lbaHighExp = scsiCmnd->cdb[4];
fis->d.featuresExp = scsiCmnd->cdb[12];
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
}
satIOContext->currentLBA = lba;
satIOContext->OrgTL = tl;
if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
{
LoopNum = smsatComputeLoopNum(tl, 0xFF);
}
else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
fis->h.command == SAT_WRITE_DMA_EXT ||
fis->h.command == SAT_WRITE_DMA_FUA_EXT
)
{
LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
}
else
{
LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
SM_DBG5(("smsatWriteAndVerify16: NON CHAINED data\n"));
satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
}
else
{
SM_DBG1(("smsatWriteAndVerify16: CHAINED data!!!\n"));
if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
{
fis->d.sectorCount = 0xFF;
}
else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
fis->h.command == SAT_WRITE_DMA_EXT ||
fis->h.command == SAT_WRITE_DMA_FUA_EXT
)
{
fis->d.sectorCount = 0xFF;
fis->d.sectorCountExp = 0xFF;
}
else
{
fis->h.features = 0xFF;
fis->d.featuresExp = 0xFF;
}
satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
}
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return (status);
}
osGLOBAL bit32
smsatReadMediaSerialNumber(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
smDeviceData_t *pSatDevData;
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
agsaSATAIdentifyData_t *pSATAIdData;
bit8 *pSerialNumber;
bit8 MediaSerialNumber[64] = {0};
bit32 allocationLen = 0;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
pSATAIdData = &(pSatDevData->satIdentifyData);
pSerialNumber = (bit8 *) smScsiRequest->sglVirtualAddr;
SM_DBG5(("smsatReadMediaSerialNumber: start\n"));
if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatReadMediaSerialNumber: return control!!!\n"));
return SM_RC_SUCCESS;
}
allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) |
(((bit32)scsiCmnd->cdb[7]) << 16) |
(((bit32)scsiCmnd->cdb[8]) << 8 ) |
(((bit32)scsiCmnd->cdb[9]));
allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
if (allocationLen == 4)
{
if (pSATAIdData->commandSetFeatureDefault & 0x4)
{
SM_DBG1(("smsatReadMediaSerialNumber: Media serial number returning only length!!!\n"));
MediaSerialNumber[0] = 0;
MediaSerialNumber[1] = 0;
MediaSerialNumber[2] = 0;
MediaSerialNumber[3] = 0x3C;
}
else
{
MediaSerialNumber[0] = 0;
MediaSerialNumber[1] = 0;
MediaSerialNumber[2] = 0x1;
MediaSerialNumber[3] = 0xfc;
}
sm_memcpy(pSerialNumber, MediaSerialNumber, 4);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return SM_RC_SUCCESS;
}
if ( pSatDevData->IDDeviceValid == agTRUE)
{
if (pSATAIdData->commandSetFeatureDefault & 0x4)
{
#ifdef LOG_ENABLE
smhexdump("ID smsatReadMediaSerialNumber", (bit8*)pSATAIdData->currentMediaSerialNumber, 2*30);
#endif
MediaSerialNumber[0] = 0;
MediaSerialNumber[1] = 0;
MediaSerialNumber[2] = 0;
MediaSerialNumber[3] = 0x3C;
sm_memcpy(&MediaSerialNumber[4], (void *)pSATAIdData->currentMediaSerialNumber, 60);
#ifdef LOG_ENABLE
smhexdump("smsatReadMediaSerialNumber", (bit8*)MediaSerialNumber, 2*30 + 4);
#endif
sm_memcpy(pSerialNumber, MediaSerialNumber, MIN(allocationLen, 64));
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return SM_RC_SUCCESS;
}
else
{
SM_DBG1(("smsatReadMediaSerialNumber: Media serial number is NOT valid!!!\n"));
if (pSatDevData->sat48BitSupport == agTRUE)
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0x40;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
}
else
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0x40;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
}
satIOContext->satCompleteCB = &smsatReadMediaSerialNumberCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
}
else
{
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOFailed,
smDetailOtherError,
agNULL,
satIOContext->interruptContext);
return SM_RC_SUCCESS;
}
}
osGLOBAL bit32
smsatReadBuffer(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status = SM_RC_SUCCESS;
bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 bufferOffset;
bit32 tl;
bit8 mode;
bit8 bufferID;
bit8 *pBuff;
pSense = satIOContext->pSense;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
pBuff = (bit8 *) smScsiRequest->sglVirtualAddr;
SM_DBG5(("smsatReadBuffer: start\n"));
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatReadBuffer: return control!!!\n"));
return SM_RC_SUCCESS;
}
bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
tl = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
bufferID = scsiCmnd->cdb[2];
if (mode == READ_BUFFER_DATA_MODE)
{
if (bufferID == 0 && bufferOffset == 0 && tl == 512)
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_BUFFER;
fis->h.features = 0;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0x40;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
satIOContext->satCompleteCB = &smsatReadBufferCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
if (bufferID == 0 && bufferOffset == 0 && tl != 512)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatReadBuffer: allocation length is not 512; it is %d!!!\n", tl));
return SM_RC_SUCCESS;
}
if (bufferID == 0 && bufferOffset != 0)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatReadBuffer: buffer offset is not 0; it is %d!!!\n", bufferOffset));
return SM_RC_SUCCESS;
}
SM_DBG1(("smsatReadBuffer: unsupported case 1!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
else if (mode == READ_BUFFER_DESCRIPTOR_MODE)
{
if (tl < READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatReadBuffer: tl < 4; tl is %d!!!\n", tl));
return SM_RC_SUCCESS;
}
if (bufferID == 0)
{
pBuff[0] = 0xFF;
pBuff[1] = 0x00;
pBuff[2] = 0x02;
pBuff[3] = 0x00;
if (READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN < tl)
{
SM_DBG1(("smsatReadBuffer: underrun tl %d data %d!!!\n", tl, READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN));
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOUnderRun,
tl - READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN,
agNULL,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
else
{
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return SM_RC_SUCCESS;
}
}
else
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
else
{
SM_DBG1(("smsatReadBuffer: unsupported mode %d!!!\n", mode));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
osGLOBAL bit32
smsatWriteBuffer(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
#ifdef NOT_YET
bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
#endif
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
#ifdef NOT_YET
agsaFisRegHostToDevice_t *fis;
#endif
bit32 bufferOffset;
bit32 parmLen;
bit8 mode;
bit8 bufferID;
bit8 *pBuff;
pSense = satIOContext->pSense;
scsiCmnd = &smScsiRequest->scsiCmnd;
#ifdef NOT_YET
fis = satIOContext->pFis;
#endif
pBuff = (bit8 *) smScsiRequest->sglVirtualAddr;
SM_DBG5(("smsatWriteBuffer: start\n"));
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatWriteBuffer: return control!!!\n"));
return SM_RC_SUCCESS;
}
bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
parmLen = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
bufferID = scsiCmnd->cdb[2];
smhexdump("smsatWriteBuffer pBuff", (bit8 *)pBuff, 24);
if (mode == WRITE_BUFFER_DATA_MODE)
{
if (bufferID == 0 && bufferOffset == 0 && parmLen == 512)
{
SM_DBG1(("smsatWriteBuffer: sending ATA WRITE BUFFER!!!\n"));
#ifdef NOT_YET
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_BUFFER;
fis->h.features = 0;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0x40;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
satIOContext->satCompleteCB = &smsatWriteBufferCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
#endif
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return SM_RC_SUCCESS;
}
if ( (bufferID == 0 && bufferOffset != 0) ||
(bufferID == 0 && parmLen != 512)
)
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatWriteBuffer: wrong buffer offset %d or parameter length parmLen %d!!!\n", bufferOffset, parmLen));
return SM_RC_SUCCESS;
}
SM_DBG1(("smsatWriteBuffer: unsupported case 1!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
else if (mode == WRITE_BUFFER_DL_MICROCODE_SAVE_MODE)
{
SM_DBG1(("smsatWriteBuffer: not yet supported mode %d!!!\n", mode));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
else
{
SM_DBG1(("smsatWriteBuffer: unsupported mode %d!!!\n", mode));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
}
osGLOBAL bit32
smsatReassignBlocks(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
smDeviceData_t *pSatDevData;
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit8 *pParmList;
bit8 LongLBA;
bit8 LongList;
bit32 defectListLen;
bit8 LBA[8];
bit32 startingIndex;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
pParmList = (bit8 *) smScsiRequest->sglVirtualAddr;
SM_DBG5(("smsatReassignBlocks: start\n"));
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatReassignBlocks: return control!!!\n"));
return SM_RC_SUCCESS;
}
sm_memset(satIOContext->LBA, 0, 8);
satIOContext->ParmIndex = 0;
satIOContext->ParmLen = 0;
LongList = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLIST_MASK);
LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
sm_memset(LBA, 0, sizeof(LBA));
if (LongList == 0)
{
defectListLen = (pParmList[2] << 8) + pParmList[3];
}
else
{
defectListLen = (pParmList[0] << (8*3)) + (pParmList[1] << (8*2))
+ (pParmList[2] << 8) + pParmList[3];
}
satIOContext->ParmLen = defectListLen + 4 ;
startingIndex = 4;
if (LongLBA == 0)
{
LBA[4] = pParmList[startingIndex];
LBA[5] = pParmList[startingIndex+1];
LBA[6] = pParmList[startingIndex+2];
LBA[7] = pParmList[startingIndex+3];
startingIndex = startingIndex + 4;
}
else
{
LBA[0] = pParmList[startingIndex];
LBA[1] = pParmList[startingIndex+1];
LBA[2] = pParmList[startingIndex+2];
LBA[3] = pParmList[startingIndex+3];
LBA[4] = pParmList[startingIndex+4];
LBA[5] = pParmList[startingIndex+5];
LBA[6] = pParmList[startingIndex+6];
LBA[7] = pParmList[startingIndex+7];
startingIndex = startingIndex + 8;
}
smhexdump("smsatReassignBlocks Parameter list", (bit8 *)pParmList, 4 + defectListLen);
if (pSatDevData->sat48BitSupport == agTRUE)
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = LBA[7];
fis->d.lbaMid = LBA[6];
fis->d.lbaHigh = LBA[5];
fis->d.lbaLowExp = LBA[4];
fis->d.lbaMidExp = LBA[3];
fis->d.lbaHighExp = LBA[2];
fis->d.featuresExp = 0;
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.device = 0x40;
fis->d.control = 0;
fis->d.reserved5 = 0;
}
else
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = LBA[7];
fis->d.lbaMid = LBA[6];
fis->d.lbaHigh = LBA[5];
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
fis->d.control = 0;
fis->d.reserved5 = 0;
}
sm_memcpy(satIOContext->LBA, LBA, 8);
satIOContext->ParmIndex = startingIndex;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatReassignBlocksCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
osGLOBAL bit32
smsatRead_1(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
smSatIOContext_t *satOrgIOContext = agNULL;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
bit32 lba = 0;
bit32 DenomTL = 0xFF;
bit32 Remainder = 0;
bit8 LBA[4];
SM_DBG2(("smsatRead_1: start\n"));
fis = satIOContext->pFis;
satOrgIOContext = satIOContext->satOrgIOContext;
scsiCmnd = satOrgIOContext->pScsiCmnd;
sm_memset(LBA,0, sizeof(LBA));
switch (satOrgIOContext->ATACmd)
{
case SAT_READ_DMA:
DenomTL = 0x100;
break;
case SAT_READ_SECTORS:
DenomTL = 0x100;
break;
case SAT_READ_DMA_EXT:
DenomTL = 0xFFFF;
break;
case SAT_READ_SECTORS_EXT:
DenomTL = 0xFFFF;
break;
case SAT_READ_FPDMA_QUEUED:
DenomTL = 0xFFFF;
break;
default:
SM_DBG1(("smsatRead_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
return SM_RC_FAILURE;
break;
}
Remainder = satOrgIOContext->OrgTL % DenomTL;
satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
lba = satOrgIOContext->currentLBA;
LBA[0] = (bit8)((lba & 0xFF000000) >> (8 * 3));
LBA[1] = (bit8)((lba & 0xFF0000) >> (8 * 2));
LBA[2] = (bit8)((lba & 0xFF00) >> 8);
LBA[3] = (bit8)(lba & 0xFF);
switch (satOrgIOContext->ATACmd)
{
case SAT_READ_DMA:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_DMA;
fis->h.features = 0;
fis->d.lbaLow = LBA[3];
fis->d.lbaMid = LBA[2];
fis->d.lbaHigh = LBA[1];
fis->d.device =
(bit8)((0x4 << 4) | (LBA[0] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (satOrgIOContext->LoopNum == 1)
{
fis->d.sectorCount = (bit8)Remainder;
}
else
{
fis->d.sectorCount = 0x0;
}
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
break;
case SAT_READ_SECTORS:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = LBA[3];
fis->d.lbaMid = LBA[2];
fis->d.lbaHigh = LBA[1];
fis->d.device =
(bit8)((0x4 << 4) | (LBA[0] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (satOrgIOContext->LoopNum == 1)
{
fis->d.sectorCount = (bit8)Remainder;
}
else
{
fis->d.sectorCount = 0x0;
}
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
break;
case SAT_READ_DMA_EXT:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_DMA_EXT;
fis->h.features = 0;
fis->d.lbaLow = LBA[3];
fis->d.lbaMid = LBA[2];
fis->d.lbaHigh = LBA[1];
fis->d.device = 0x40;
fis->d.lbaLowExp = LBA[0];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (satOrgIOContext->LoopNum == 1)
{
fis->d.sectorCount = (bit8)(Remainder & 0xFF);
fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);
}
else
{
fis->d.sectorCount = 0xFF;
fis->d.sectorCountExp = 0xFF;
}
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
break;
case SAT_READ_SECTORS_EXT:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = LBA[3];
fis->d.lbaMid = LBA[2];
fis->d.lbaHigh = LBA[1];
fis->d.device = 0x40;
fis->d.lbaLowExp = LBA[0];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (satOrgIOContext->LoopNum == 1)
{
fis->d.sectorCount = (bit8)(Remainder & 0xFF);
fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);
}
else
{
fis->d.sectorCount = 0xFF;
fis->d.sectorCountExp = 0xFF;
}
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
break;
case SAT_READ_FPDMA_QUEUED:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_FPDMA_QUEUED;
fis->d.lbaLow = LBA[3];
fis->d.lbaMid = LBA[2];
fis->d.lbaHigh = LBA[1];
if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
fis->d.device = 0xC0;
else
fis->d.device = 0x40;
fis->d.lbaLowExp = LBA[0];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
if (satOrgIOContext->LoopNum == 1)
{
fis->h.features = (bit8)(Remainder & 0xFF);
fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8);
}
else
{
fis->h.features = 0xFF;
fis->d.featuresExp = 0xFF;
}
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
break;
default:
SM_DBG1(("smsatRead_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
return SM_RC_FAILURE;
break;
}
satIOContext->satCompleteCB = &smsatChainedDataIOCB;
if (satOrgIOContext->ATACmd == SAT_READ_DMA || satOrgIOContext->ATACmd == SAT_READ_SECTORS)
{
smsatSplitSGL(smRoot,
smIORequest,
smDeviceHandle,
(smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
satOrgIOContext,
NON_BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE,
(satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE,
agFALSE);
}
else
{
smsatSplitSGL(smRoot,
smIORequest,
smDeviceHandle,
(smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
satOrgIOContext,
BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE,
(satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE,
agFALSE);
}
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
(smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
satIOContext);
SM_DBG5(("smsatRead_1: return\n"));
return (status);
}
osGLOBAL bit32
smsatWrite_1(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
smSatIOContext_t *satOrgIOContext = agNULL;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
bit32 lba = 0;
bit32 DenomTL = 0xFF;
bit32 Remainder = 0;
bit8 LBA[4];
SM_DBG2(("smsatWrite_1: start\n"));
fis = satIOContext->pFis;
satOrgIOContext = satIOContext->satOrgIOContext;
scsiCmnd = satOrgIOContext->pScsiCmnd;
sm_memset(LBA,0, sizeof(LBA));
switch (satOrgIOContext->ATACmd)
{
case SAT_WRITE_DMA:
DenomTL = 0x100;
break;
case SAT_WRITE_SECTORS:
DenomTL = 0x100;
break;
case SAT_WRITE_DMA_EXT:
DenomTL = 0xFFFF;
break;
case SAT_WRITE_DMA_FUA_EXT:
DenomTL = 0xFFFF;
break;
case SAT_WRITE_SECTORS_EXT:
DenomTL = 0xFFFF;
break;
case SAT_WRITE_FPDMA_QUEUED:
DenomTL = 0xFFFF;
break;
default:
SM_DBG1(("smsatWrite_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
return SM_RC_FAILURE;
break;
}
Remainder = satOrgIOContext->OrgTL % DenomTL;
satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
lba = satOrgIOContext->currentLBA;
LBA[0] = (bit8)((lba & 0xFF000000) >> (8 * 3));
LBA[1] = (bit8)((lba & 0xFF0000) >> (8 * 2));
LBA[2] = (bit8)((lba & 0xFF00) >> 8);
LBA[3] = (bit8)(lba & 0xFF);
switch (satOrgIOContext->ATACmd)
{
case SAT_WRITE_DMA:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA;
fis->h.features = 0;
fis->d.lbaLow = LBA[3];
fis->d.lbaMid = LBA[2];
fis->d.lbaHigh = LBA[1];
fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (satOrgIOContext->LoopNum == 1)
{
fis->d.sectorCount = (bit8)Remainder;
}
else
{
fis->d.sectorCount = 0x0;
}
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
break;
case SAT_WRITE_SECTORS:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = LBA[3];
fis->d.lbaMid = LBA[2];
fis->d.lbaHigh = LBA[1];
fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (satOrgIOContext->LoopNum == 1)
{
fis->d.sectorCount = (bit8)Remainder;
}
else
{
fis->d.sectorCount = 0x0;
}
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
break;
case SAT_WRITE_DMA_EXT:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA_EXT;
fis->h.features = 0;
fis->d.lbaLow = LBA[3];
fis->d.lbaMid = LBA[2];
fis->d.lbaHigh = LBA[1];
fis->d.device = 0x40;
fis->d.lbaLowExp = LBA[0];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (satOrgIOContext->LoopNum == 1)
{
fis->d.sectorCount = (bit8)(Remainder & 0xFF);
fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);
}
else
{
fis->d.sectorCount = 0xFF;
fis->d.sectorCountExp = 0xFF;
}
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
break;
case SAT_WRITE_SECTORS_EXT:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = LBA[3];
fis->d.lbaMid = LBA[2];
fis->d.lbaHigh = LBA[1];
fis->d.device = 0x40;
fis->d.lbaLowExp = LBA[0];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (satOrgIOContext->LoopNum == 1)
{
fis->d.sectorCount = (bit8)(Remainder & 0xFF);
fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);
}
else
{
fis->d.sectorCount = 0xFF;
fis->d.sectorCountExp = 0xFF;
}
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
break;
case SAT_WRITE_FPDMA_QUEUED:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_FPDMA_QUEUED;
fis->d.lbaLow = LBA[3];
fis->d.lbaMid = LBA[2];
fis->d.lbaHigh = LBA[1];
if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
fis->d.device = 0xC0;
else
fis->d.device = 0x40;
fis->d.lbaLowExp = LBA[0];;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
if (satOrgIOContext->LoopNum == 1)
{
fis->h.features = (bit8)(Remainder & 0xFF);
fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8);
}
else
{
fis->h.features = 0xFF;
fis->d.featuresExp = 0xFF;
}
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
break;
default:
SM_DBG1(("smsatWrite_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
return SM_RC_FAILURE;
break;
}
satIOContext->satCompleteCB = &smsatChainedDataIOCB;
if (satOrgIOContext->ATACmd == SAT_WRITE_DMA || satOrgIOContext->ATACmd == SAT_WRITE_SECTORS)
{
smsatSplitSGL(smRoot,
smIORequest,
smDeviceHandle,
(smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
satOrgIOContext,
NON_BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE,
(satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE,
agFALSE);
}
else
{
smsatSplitSGL(smRoot,
smIORequest,
smDeviceHandle,
(smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
satOrgIOContext,
BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE,
(satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE,
agFALSE);
}
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
(smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
satIOContext);
SM_DBG5(("smsatWrite_1: return\n"));
return (status);
}
osGLOBAL bit32
smsatPassthrough(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
smScsiRspSense_t *pSense;
smIniScsiCmnd_t *scsiCmnd;
smDeviceData_t *pSatDevData;
agsaFisRegHostToDevice_t *fis;
bit32 status;
bit32 agRequestType;
smAtaPassThroughHdr_t ataPassThroughHdr;
pSense = satIOContext->pSense;
scsiCmnd = &smScsiRequest->scsiCmnd;
pSatDevData = satIOContext->pSatDevData;
fis = satIOContext->pFis;
SM_DBG1(("smsatPassthrough: START!!!\n"));
osti_memset(&ataPassThroughHdr, 0 , sizeof(smAtaPassThroughHdr_t));
ataPassThroughHdr.opc = scsiCmnd->cdb[0];
ataPassThroughHdr.mulCount = scsiCmnd->cdb[1] >> 5;
ataPassThroughHdr.proto = (scsiCmnd->cdb[1] >> 1) & 0x0F;
ataPassThroughHdr.extend = scsiCmnd->cdb[1] & 1;
ataPassThroughHdr.offline = scsiCmnd->cdb[2] >> 6;
ataPassThroughHdr.ckCond = (scsiCmnd->cdb[2] >> 5) & 1;
ataPassThroughHdr.tType = (scsiCmnd->cdb[2] >> 4) & 1;
ataPassThroughHdr.tDir = (scsiCmnd->cdb[2] >> 3) & 1;
ataPassThroughHdr.byteBlock = (scsiCmnd->cdb[2] >> 2) & 1;
ataPassThroughHdr.tlength = scsiCmnd->cdb[2] & 0x3;
switch(ataPassThroughHdr.proto)
{
case 0:
case 9:
agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET;
break;
case 1:
agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT;
break;
case 3:
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
break;
case 4:
agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
break;
case 5:
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
break;
case 6:
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
break;
case 8:
agRequestType = AGSA_SATA_ATAP_EXECDEVDIAG;
break;
case 12:
agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
break;
default:
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
break;
}
if((ataPassThroughHdr.tlength == 0) && (agRequestType != AGSA_SATA_PROTOCOL_NON_DATA))
{
SM_DBG1(("smsatPassthrough SCSI_SNSCODE_INVALID_FIELD_IN_CDB\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
if(scsiCmnd->cdb[0] == 0xA1)
{
SM_DBG1(("smsatPassthrough A1h: COMMAND: %x FEATURE: %x \n",scsiCmnd->cdb[9],scsiCmnd->cdb[3]));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.features = scsiCmnd->cdb[3];
fis->d.sectorCount = scsiCmnd->cdb[4];
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[6];
fis->d.lbaHigh = scsiCmnd->cdb[7];
fis->d.device = scsiCmnd->cdb[8];
fis->h.command = scsiCmnd->cdb[9];
fis->d.featuresExp = 0;
fis->d.sectorCountExp = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
satIOContext->satCompleteCB = &smsatPassthroughCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
else if(scsiCmnd->cdb[0] == 0x85)
{
SM_DBG1(("smsatPassthrough 85h: COMMAND: %x FEATURE: %x \n",scsiCmnd->cdb[14],scsiCmnd->cdb[4]));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
if(1 == ataPassThroughHdr.extend)
{
fis->d.featuresExp = scsiCmnd->cdb[3];
fis->d.sectorCountExp = scsiCmnd->cdb[5];
fis->d.lbaMidExp = scsiCmnd->cdb[9];
fis->d.lbaHighExp = scsiCmnd->cdb[11];
fis->d.lbaLowExp = scsiCmnd->cdb[7];
}
fis->h.features = scsiCmnd->cdb[4];
fis->d.sectorCount = scsiCmnd->cdb[6];
fis->d.lbaLow = scsiCmnd->cdb[8];
fis->d.lbaMid = scsiCmnd->cdb[10];
fis->d.lbaHigh = scsiCmnd->cdb[12];
fis->d.device = scsiCmnd->cdb[13];
fis->h.command = scsiCmnd->cdb[14];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
satIOContext->satCompleteCB = &smsatPassthroughCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
else
{
SM_DBG1(("smsatPassthrough : INVALD PASSTHROUGH!!!\n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
SM_DBG1(("smsatPassthrough : return control!!!\n"));
return SM_RC_SUCCESS;
}
}
osGLOBAL bit32
smsatNonChainedWriteNVerify_Verify(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
smDeviceData_t *pSatDevData;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
SM_DBG5(("smsatNonChainedWriteNVerify_Verify: start\n"));
if (pSatDevData->sat48BitSupport == agTRUE)
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[8];
fis->d.sectorCountExp = scsiCmnd->cdb[7];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG1(("smsatNonChainedWriteNVerify_Verify: return status %d!!!\n", status));
return (status);
}
else
{
SM_DBG1(("smsatNonChainedWriteNVerify_Verify: can't fit in SAT_READ_VERIFY_SECTORS!!!\n"));
return SM_RC_FAILURE;
}
}
osGLOBAL bit32
smsatChainedWriteNVerify_Start_Verify(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
smDeviceData_t *pSatDevData;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[4];
bit8 TL[4];
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: start\n"));
sm_memset(LBA, 0, sizeof(LBA));
sm_memset(TL, 0, sizeof(TL));
LBA[0] = scsiCmnd->cdb[2];
LBA[1] = scsiCmnd->cdb[3];
LBA[2] = scsiCmnd->cdb[4];
LBA[3] = scsiCmnd->cdb[5];
TL[0] = scsiCmnd->cdb[6];
TL[1] = scsiCmnd->cdb[7];
TL[2] = scsiCmnd->cdb[7];
TL[3] = scsiCmnd->cdb[8];
lba = smsatComputeCDB12LBA(satIOContext);
tl = smsatComputeCDB12TL(satIOContext);
if (pSatDevData->sat48BitSupport == agTRUE)
{
SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS_EXT\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = 0x40;
fis->d.lbaLowExp = scsiCmnd->cdb[2];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[8];
fis->d.sectorCountExp = scsiCmnd->cdb[7];
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
}
else
{
SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = scsiCmnd->cdb[5];
fis->d.lbaMid = scsiCmnd->cdb[4];
fis->d.lbaHigh = scsiCmnd->cdb[3];
fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = scsiCmnd->cdb[8];
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
}
satIOContext->currentLBA = lba;
satIOContext->OrgTL = tl;
if (fis->h.command == SAT_READ_VERIFY_SECTORS)
{
LoopNum = smsatComputeLoopNum(tl, 0xFF);
}
else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
{
LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
}
else
{
SM_DBG1(("smsatChainedWriteNVerify_Start_Verify: error case 1!!!\n"));
LoopNum = 1;
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: NON CHAINED data\n"));
satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
}
else
{
SM_DBG1(("smsatChainedWriteNVerify_Start_Verify: CHAINED data!!!\n"));
if (fis->h.command == SAT_READ_VERIFY_SECTORS)
{
fis->d.sectorCount = 0xFF;
}
else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
{
fis->d.sectorCount = 0xFF;
fis->d.sectorCountExp = 0xFF;
}
else
{
SM_DBG1(("smsatChainedWriteNVerify_Start_Verify: error case 2!!!\n"));
}
satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
}
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return (status);
}
osGLOBAL bit32
smsatChainedWriteNVerify_Write(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
smSatIOContext_t *satOrgIOContext = agNULL;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
bit32 lba = 0;
bit32 DenomTL = 0xFF;
bit32 Remainder = 0;
bit8 LBA[4];
SM_DBG1(("smsatChainedWriteNVerify_Write: start\n"));
fis = satIOContext->pFis;
satOrgIOContext = satIOContext->satOrgIOContext;
scsiCmnd = satOrgIOContext->pScsiCmnd;
sm_memset(LBA,0, sizeof(LBA));
switch (satOrgIOContext->ATACmd)
{
case SAT_WRITE_DMA:
DenomTL = 0xFF;
break;
case SAT_WRITE_SECTORS:
DenomTL = 0xFF;
break;
case SAT_WRITE_DMA_EXT:
DenomTL = 0xFFFF;
break;
case SAT_WRITE_DMA_FUA_EXT:
DenomTL = 0xFFFF;
break;
case SAT_WRITE_SECTORS_EXT:
DenomTL = 0xFFFF;
break;
case SAT_WRITE_FPDMA_QUEUED:
DenomTL = 0xFFFF;
break;
default:
SM_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
return SM_RC_FAILURE;
break;
}
Remainder = satOrgIOContext->OrgTL % DenomTL;
satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
lba = satOrgIOContext->currentLBA;
LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3));
LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
LBA[2] = (bit8)((lba & 0xF0) >> 8);
LBA[3] = (bit8)(lba & 0xF);
switch (satOrgIOContext->ATACmd)
{
case SAT_WRITE_DMA:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA;
fis->h.features = 0;
fis->d.lbaLow = LBA[3];
fis->d.lbaMid = LBA[2];
fis->d.lbaHigh = LBA[1];
fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (satOrgIOContext->LoopNum == 1)
{
fis->d.sectorCount = (bit8)Remainder;
}
else
{
fis->d.sectorCount = 0xFF;
}
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
break;
case SAT_WRITE_SECTORS:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = LBA[3];
fis->d.lbaMid = LBA[2];
fis->d.lbaHigh = LBA[1];
fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (satOrgIOContext->LoopNum == 1)
{
fis->d.sectorCount = (bit8)Remainder;
}
else
{
fis->d.sectorCount = 0xFF;
}
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
break;
case SAT_WRITE_DMA_EXT:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA_EXT;
fis->h.features = 0;
fis->d.lbaLow = LBA[3];
fis->d.lbaMid = LBA[2];
fis->d.lbaHigh = LBA[1];
fis->d.device = 0x40;
fis->d.lbaLowExp = LBA[0];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (satOrgIOContext->LoopNum == 1)
{
fis->d.sectorCount = (bit8)(Remainder & 0xFF);
fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);
}
else
{
fis->d.sectorCount = 0xFF;
fis->d.sectorCountExp = 0xFF;
}
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
break;
case SAT_WRITE_SECTORS_EXT:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = LBA[3];
fis->d.lbaMid = LBA[2];
fis->d.lbaHigh = LBA[1];
fis->d.device = 0x40;
fis->d.lbaLowExp = LBA[0];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (satOrgIOContext->LoopNum == 1)
{
fis->d.sectorCount = (bit8)(Remainder & 0xFF);
fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);
}
else
{
fis->d.sectorCount = 0xFF;
fis->d.sectorCountExp = 0xFF;
}
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
break;
case SAT_WRITE_FPDMA_QUEUED:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_FPDMA_QUEUED;
fis->d.lbaLow = LBA[3];
fis->d.lbaMid = LBA[2];
fis->d.lbaHigh = LBA[1];
if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
fis->d.device = 0xC0;
else
fis->d.device = 0x40;
fis->d.lbaLowExp = LBA[0];;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
if (satOrgIOContext->LoopNum == 1)
{
fis->h.features = (bit8)(Remainder & 0xFF);
fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8);
}
else
{
fis->h.features = 0xFF;
fis->d.featuresExp = 0xFF;
}
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
break;
default:
SM_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
return SM_RC_FAILURE;
break;
}
satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG5(("satChainedWriteNVerify_Write: return\n"));
return (status);
}
osGLOBAL bit32
smsatChainedWriteNVerify_Verify(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
smSatIOContext_t *satOrgIOContext = agNULL;
agsaFisRegHostToDevice_t *fis;
bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
bit32 lba = 0;
bit32 DenomTL = 0xFF;
bit32 Remainder = 0;
bit8 LBA[4];
SM_DBG2(("smsatChainedWriteNVerify_Verify: start\n"));
fis = satIOContext->pFis;
satOrgIOContext = satIOContext->satOrgIOContext;
sm_memset(LBA,0, sizeof(LBA));
switch (satOrgIOContext->ATACmd)
{
case SAT_READ_VERIFY_SECTORS:
DenomTL = 0xFF;
break;
case SAT_READ_VERIFY_SECTORS_EXT:
DenomTL = 0xFFFF;
break;
default:
SM_DBG1(("smsatChainedWriteNVerify_Verify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
return SM_RC_FAILURE;
break;
}
Remainder = satOrgIOContext->OrgTL % DenomTL;
satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
lba = satOrgIOContext->currentLBA;
LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3));
LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
LBA[2] = (bit8)((lba & 0xF0) >> 8);
LBA[3] = (bit8)(lba & 0xF);
switch (satOrgIOContext->ATACmd)
{
case SAT_READ_VERIFY_SECTORS:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = LBA[3];
fis->d.lbaMid = LBA[2];
fis->d.lbaHigh = LBA[1];
fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (satOrgIOContext->LoopNum == 1)
{
fis->d.sectorCount = (bit8)Remainder;
}
else
{
fis->d.sectorCount = 0xFF;
}
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
break;
case SAT_READ_VERIFY_SECTORS_EXT:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = LBA[3];
fis->d.lbaMid = LBA[2];
fis->d.lbaHigh = LBA[1];
fis->d.device = 0x40;
fis->d.lbaLowExp = LBA[0];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (satOrgIOContext->LoopNum == 1)
{
fis->d.sectorCount = (bit8)(Remainder & 0xFF);
fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);
}
else
{
fis->d.sectorCount = 0xFF;
fis->d.sectorCountExp = 0xFF;
}
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
break;
default:
SM_DBG1(("smsatChainedWriteNVerify_Verify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
return SM_RC_FAILURE;
break;
}
satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG5(("smsatChainedWriteNVerify_Verify: return\n"));
return (status);
}
osGLOBAL bit32
smsatChainedVerify(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
smSatIOContext_t *satOrgIOContext = agNULL;
agsaFisRegHostToDevice_t *fis;
bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
bit32 lba = 0;
bit32 DenomTL = 0xFF;
bit32 Remainder = 0;
bit8 LBA[4];
SM_DBG2(("smsatChainedVerify: start\n"));
fis = satIOContext->pFis;
satOrgIOContext = satIOContext->satOrgIOContext;
sm_memset(LBA,0, sizeof(LBA));
switch (satOrgIOContext->ATACmd)
{
case SAT_READ_VERIFY_SECTORS:
DenomTL = 0xFF;
break;
case SAT_READ_VERIFY_SECTORS_EXT:
DenomTL = 0xFFFF;
break;
default:
SM_DBG1(("satChainedVerify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
return tiError;
break;
}
Remainder = satOrgIOContext->OrgTL % DenomTL;
satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
lba = satOrgIOContext->currentLBA;
LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3));
LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
LBA[2] = (bit8)((lba & 0xF0) >> 8);
LBA[3] = (bit8)(lba & 0xF);
switch (satOrgIOContext->ATACmd)
{
case SAT_READ_VERIFY_SECTORS:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = LBA[3];
fis->d.lbaMid = LBA[2];
fis->d.lbaHigh = LBA[1];
fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (satOrgIOContext->LoopNum == 1)
{
fis->d.sectorCount = (bit8)Remainder;
}
else
{
fis->d.sectorCount = 0xFF;
}
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
break;
case SAT_READ_VERIFY_SECTORS_EXT:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = LBA[3];
fis->d.lbaMid = LBA[2];
fis->d.lbaHigh = LBA[1];
fis->d.device = 0x40;
fis->d.lbaLowExp = LBA[0];
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
if (satOrgIOContext->LoopNum == 1)
{
fis->d.sectorCount = (bit8)(Remainder & 0xFF);
fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);
}
else
{
fis->d.sectorCount = 0xFF;
fis->d.sectorCountExp = 0xFF;
}
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
break;
default:
SM_DBG1(("satChainedVerify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
return tiError;
break;
}
satIOContext->satCompleteCB = &smsatChainedVerifyCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG5(("satChainedVerify: return\n"));
return (status);
}
osGLOBAL bit32
smsatWriteSame10_1(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext,
bit32 lba
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
bit8 lba1, lba2 ,lba3, lba4;
SM_DBG5(("smsatWriteSame10_1: start\n"));
fis = satIOContext->pFis;
lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
lba4 = (bit8)(lba & 0x000000FF);
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA_EXT;
fis->h.features = 0;
fis->d.lbaLow = lba4;
fis->d.lbaMid = lba3;
fis->d.lbaHigh = lba2;
fis->d.device = 0x40;
fis->d.lbaLowExp = lba1;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satIOContext->satCompleteCB = &smsatWriteSame10CB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG5(("smsatWriteSame10_1 return status %d\n", status));
return status;
}
osGLOBAL bit32
smsatWriteSame10_2(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext,
bit32 lba
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
bit8 lba1, lba2 ,lba3, lba4;
SM_DBG5(("smsatWriteSame10_2: start\n"));
fis = satIOContext->pFis;
lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
lba4 = (bit8)(lba & 0x000000FF);
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = lba4;
fis->d.lbaMid = lba3;
fis->d.lbaHigh = lba2;
fis->d.device = 0x40;
fis->d.lbaLowExp = lba1;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
satIOContext->satCompleteCB = &smsatWriteSame10CB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG5(("smsatWriteSame10_2 return status %d\n", status));
return status;
}
osGLOBAL bit32
smsatWriteSame10_3(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext,
bit32 lba
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
bit8 lba1, lba2 ,lba3, lba4;
SM_DBG5(("smsatWriteSame10_3: start\n"));
fis = satIOContext->pFis;
lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
lba4 = (bit8)(lba & 0x000000FF);
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_FPDMA_QUEUED;
fis->h.features = 1;
fis->d.featuresExp = 0;
fis->d.lbaLow = lba4;
fis->d.lbaMid = lba3;
fis->d.lbaHigh = lba2;
fis->d.device = 0x40;
fis->d.lbaLowExp = lba1;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
satIOContext->satCompleteCB = &smsatWriteSame10CB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG5(("smsatWriteSame10_3 return status %d\n", status));
return status;
}
osGLOBAL bit32
smsatStartStopUnit_1(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
SM_DBG5(("smsatStartStopUnit_1: start\n"));
fis = satIOContext->pFis;
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_STANDBY;
fis->h.features = 0;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.device = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatStartStopUnitCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG5(("smsatStartStopUnit_1 return status %d\n", status));
return status;
}
osGLOBAL bit32
smsatSendDiagnostic_1(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
smDeviceData_t *pSatDevData;
agsaFisRegHostToDevice_t *fis;
SM_DBG5(("smsatSendDiagnostic_1: start\n"));
pSatDevData = satIOContext->pSatDevData;
fis = satIOContext->pFis;
if (pSatDevData->sat48BitSupport == agTRUE)
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = pSatDevData->satMaxLBA[7];
fis->d.lbaMid = pSatDevData->satMaxLBA[6];
fis->d.lbaHigh = pSatDevData->satMaxLBA[5];
fis->d.lbaLowExp = pSatDevData->satMaxLBA[4];
fis->d.lbaMidExp = pSatDevData->satMaxLBA[3];
fis->d.lbaHighExp = pSatDevData->satMaxLBA[2];
fis->d.featuresExp = 0;
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.device = 0x40;
fis->d.control = 0;
fis->d.reserved5 = 0;
}
else
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = pSatDevData->satMaxLBA[7];
fis->d.lbaMid = pSatDevData->satMaxLBA[6];
fis->d.lbaHigh = pSatDevData->satMaxLBA[5];
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.device = (bit8)((0x4 << 4) | (pSatDevData->satMaxLBA[4] & 0xF));
fis->d.control = 0;
fis->d.reserved5 = 0;
}
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
osGLOBAL bit32
smsatSendDiagnostic_2(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
smDeviceData_t *pSatDevData;
agsaFisRegHostToDevice_t *fis;
SM_DBG5(("smsatSendDiagnostic_2: start\n"));
pSatDevData = satIOContext->pSatDevData;
fis = satIOContext->pFis;
if (pSatDevData->sat48BitSupport == agTRUE)
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = 0x7F;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.device = 0x40;
fis->d.control = 0;
fis->d.reserved5 = 0;
}
else
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = 0x7F;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.device = 0x40;
fis->d.control = 0;
fis->d.reserved5 = 0;
}
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
osGLOBAL bit32
smsatModeSelect6n10_1(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
bit8 *pLogPage;
bit32 StartingIndex = 0;
fis = satIOContext->pFis;
pLogPage = (bit8 *) smScsiRequest->sglVirtualAddr;
SM_DBG5(("smsatModeSelect6n10_1: start\n"));
if (pLogPage[3] == 8)
{
StartingIndex = 12;
}
else
{
StartingIndex = 4;
}
if ( !(pLogPage[StartingIndex + 12] & SCSI_MODE_SELECT6_DRA_MASK) )
{
SM_DBG5(("smsatModeSelect6n10_1: enable read look-ahead feature\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SET_FEATURES;
fis->h.features = 0xAA;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
else
{
SM_DBG5(("smsatModeSelect6n10_1: disable read look-ahead feature\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SET_FEATURES;
fis->h.features = 0x55;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
}
osGLOBAL bit32
smsatLogSense_1(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
smDeviceData_t *pSatDevData;
agsaFisRegHostToDevice_t *fis;
pSatDevData = satIOContext->pSatDevData;
fis = satIOContext->pFis;
SM_DBG5(("smsatLogSense_1: start\n"));
if ( pSatDevData->sat48BitSupport == agTRUE )
{
SM_DBG5(("smsatLogSense_1: case 2-1 sends READ LOG EXT\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_LOG_EXT;
fis->h.features = 0;
fis->d.lbaLow = 0x07;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0x01;
fis->d.sectorCountExp = 0x00;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
satIOContext->satCompleteCB = &smsatLogSenseCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
else
{
SM_DBG5(("smsatLogSense_1: case 2-2 sends SMART READ LOG\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART;
fis->h.features = SAT_SMART_READ_LOG;
fis->d.lbaLow = 0x06;
fis->d.lbaMid = 0x00;
fis->d.lbaHigh = 0x00;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0x01;
fis->d.sectorCountExp = 0x00;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
satIOContext->satCompleteCB = &smsatLogSenseCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return status;
}
}
osGLOBAL bit32
smsatReassignBlocks_2(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext,
bit8 *LBA
)
{
bit32 status;
bit32 agRequestType;
smDeviceData_t *pSatDevData;
smScsiRspSense_t *pSense;
agsaFisRegHostToDevice_t *fis;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
fis = satIOContext->pFis;
SM_DBG5(("smsatReassignBlocks_2: start\n"));
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatReassignBlocks_2: case 2\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA;
fis->h.features = 0;
fis->d.lbaLow = LBA[7];
fis->d.lbaMid = LBA[6];
fis->d.lbaHigh = LBA[5];
fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satIOContext->ATACmd = SAT_WRITE_DMA;
}
else
{
SM_DBG5(("smsatReassignBlocks_2: case 1\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = LBA[7];
fis->d.lbaMid = LBA[6];
fis->d.lbaHigh = LBA[7];
fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
satIOContext->ATACmd = SAT_WRITE_SECTORS;
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
SM_DBG5(("smsatReassignBlocks_2: case 3\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_DMA_EXT;
satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
fis->h.features = 0;
fis->d.lbaLow = LBA[7];
fis->d.lbaMid = LBA[6];
fis->d.lbaHigh = LBA[5];
fis->d.device = 0x40;
fis->d.lbaLowExp = LBA[4];
fis->d.lbaMidExp = LBA[3];
fis->d.lbaHighExp = LBA[2];
fis->d.featuresExp = 0;
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
}
else
{
SM_DBG5(("smsatReassignBlocks_2: case 4\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = LBA[7];
fis->d.lbaMid = LBA[6];
fis->d.lbaHigh = LBA[5];
fis->d.device = 0x40;
fis->d.lbaLowExp = LBA[4];
fis->d.lbaMidExp = LBA[3];
fis->d.lbaHighExp = LBA[2];
fis->d.featuresExp = 0;
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
}
}
if (pSatDevData->satNCQ == agTRUE)
{
if (pSatDevData->sat48BitSupport != agTRUE)
{
SM_DBG5(("smsatReassignBlocks_2: case 5 !!! error NCQ but 28 bit address support \n"));
smsatSetSensePayload( pSense,
SCSI_SNSKEY_HARDWARE_ERROR,
0,
SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED,
satIOContext);
tdsmIOCompletedCB( smRoot,
smIORequest,
smIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pSmSenseData,
satIOContext->interruptContext );
return SM_RC_SUCCESS;
}
SM_DBG6(("satWrite10: case 5\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_WRITE_FPDMA_QUEUED;
fis->h.features = 1;
fis->d.lbaLow = LBA[7];
fis->d.lbaMid = LBA[6];
fis->d.lbaHigh = LBA[5];
fis->d.device = 0x40;
fis->d.lbaLowExp = LBA[4];
fis->d.lbaMidExp = LBA[3];
fis->d.lbaHighExp = LBA[2];
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
}
satIOContext->satCompleteCB = &smsatReassignBlocksCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return (status);
}
osGLOBAL bit32
smsatReassignBlocks_1(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext,
smSatIOContext_t *satOrgIOContext
)
{
bit32 agRequestType;
smDeviceData_t *pSatDevData;
smIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit8 *pParmList;
bit8 LongLBA;
bit8 LBA[8];
bit32 startingIndex;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &smScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
pParmList = (bit8 *) smScsiRequest->sglVirtualAddr;
SM_DBG5(("smsatReassignBlocks_1: start\n"));
LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
sm_memset(LBA, 0, sizeof(LBA));
startingIndex = satOrgIOContext->ParmIndex;
if (LongLBA == 0)
{
LBA[4] = pParmList[startingIndex];
LBA[5] = pParmList[startingIndex+1];
LBA[6] = pParmList[startingIndex+2];
LBA[7] = pParmList[startingIndex+3];
startingIndex = startingIndex + 4;
}
else
{
LBA[0] = pParmList[startingIndex];
LBA[1] = pParmList[startingIndex+1];
LBA[2] = pParmList[startingIndex+2];
LBA[3] = pParmList[startingIndex+3];
LBA[4] = pParmList[startingIndex+4];
LBA[5] = pParmList[startingIndex+5];
LBA[6] = pParmList[startingIndex+6];
LBA[7] = pParmList[startingIndex+7];
startingIndex = startingIndex + 8;
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;
fis->h.features = 0;
fis->d.lbaLow = LBA[7];
fis->d.lbaMid = LBA[6];
fis->d.lbaHigh = LBA[5];
fis->d.lbaLowExp = LBA[4];
fis->d.lbaMidExp = LBA[3];
fis->d.lbaHighExp = LBA[2];
fis->d.featuresExp = 0;
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.device = 0x40;
fis->d.control = 0;
fis->d.reserved5 = 0;
}
else
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_VERIFY_SECTORS;
fis->h.features = 0;
fis->d.lbaLow = LBA[7];
fis->d.lbaMid = LBA[6];
fis->d.lbaHigh = LBA[5];
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
fis->d.control = 0;
fis->d.reserved5 = 0;
}
sm_memcpy(satOrgIOContext->LBA, LBA, 8);
satOrgIOContext->ParmIndex = startingIndex;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatReassignBlocksCB;
satIOContext->reqType = agRequestType;
smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
return SM_RC_SUCCESS;
}
osGLOBAL bit32
smsatSendReadLogExt(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
fis = satIOContext->pFis;
SM_DBG1(("smsatSendReadLogExt: start\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_READ_LOG_EXT;
fis->h.features = 0;
fis->d.lbaLow = 0x10;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0x01;
fis->d.sectorCountExp = 0x00;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
satIOContext->satCompleteCB = &smsatReadLogExtCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG1(("smsatSendReadLogExt: end status %d!!!\n", status));
return (status);
}
osGLOBAL bit32
smsatCheckPowerMode(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
fis = satIOContext->pFis;
SM_DBG1(("smsatCheckPowerMode: start\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_CHECK_POWER_MODE;
fis->h.features = 0;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatCheckPowerModeCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG5(("smsatCheckPowerMode: return\n"));
return status;
}
osGLOBAL bit32
smsatResetDevice(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
#ifdef TD_DEBUG_ENABLE
smIORequestBody_t *smIORequestBody;
smSatInternalIo_t *satIntIoContext;
#endif
fis = satIOContext->pFis;
SM_DBG1(("smsatResetDevice: start\n"));
#ifdef TD_DEBUG_ENABLE
satIntIoContext = satIOContext->satIntIoContext;
smIORequestBody = satIntIoContext->satIntRequestBody;
#endif
SM_DBG5(("smsatResetDevice: satIOContext %p smIORequestBody %p\n", satIOContext, smIORequestBody));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0;
fis->h.command = 0;
fis->h.features = 0;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0x4;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT;
satIOContext->satCompleteCB = &smsatResetDeviceCB;
satIOContext->reqType = agRequestType;
#ifdef SM_INTERNAL_DEBUG
smhexdump("smsatResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
#ifdef TD_DEBUG_ENABLE
smhexdump("smsatResetDevice LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
#endif
#endif
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG6(("smsatResetDevice: end status %d\n", status));
return status;
}
osGLOBAL bit32
smsatDeResetDevice(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
#ifdef TD_DEBUG_ENABLE
smIORequestBody_t *smIORequestBody;
smSatInternalIo_t *satIntIoContext;
#endif
fis = satIOContext->pFis;
SM_DBG1(("smsatDeResetDevice: start\n"));
#ifdef TD_DEBUG_ENABLE
satIntIoContext = satIOContext->satIntIoContext;
smIORequestBody = satIntIoContext->satIntRequestBody;
#endif
SM_DBG5(("smsatDeResetDevice: satIOContext %p smIORequestBody %p\n", satIOContext, smIORequestBody));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0;
fis->h.command = 0;
fis->h.features = 0;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_SRST_DEASSERT;
satIOContext->satCompleteCB = &smsatDeResetDeviceCB;
satIOContext->reqType = agRequestType;
#ifdef SM_INTERNAL_DEBUG
smhexdump("smsatDeResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
#ifdef TD_DEBUG_ENABLE
smhexdump("smsatDeResetDevice LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
#endif
#endif
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
SM_DBG6(("smsatDeResetDevice: end status %d\n", status));
return status;
}
osGLOBAL bit32
smsatSetFeaturesAA(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status = SM_RC_FAILURE;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
fis = satIOContext->pFis;
SM_DBG2(("smsatSetFeaturesAA: start\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SET_FEATURES;
fis->h.features = 0x10;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0x02;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatSetFeaturesAACB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
if (smIORequest->tdData == smIORequest->smData)
{
SM_DBG1(("smsatSetFeaturesAA: incorrect smIORequest\n"));
}
SM_DBG2(("smsatSetFeatures: return\n"));
return status;
}
osGLOBAL bit32
smsatSetFeaturesDMA(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status = SM_RC_FAILURE;
bit32 agRequestType;
smDeviceData_t *pSatDevData;
agsaFisRegHostToDevice_t *fis;
pSatDevData = satIOContext->pSatDevData;
fis = satIOContext->pFis;
SM_DBG2(("smsatSetFeaturesDMA: start\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SET_FEATURES;
fis->h.features = 0x03;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0x40 |(bit8)pSatDevData->satUltraDMAMode;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatSetFeaturesDMACB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
if (smIORequest->tdData == smIORequest->smData)
{
SM_DBG1(("smsatSetFeaturesDMA: incorrect smIORequest\n"));
}
SM_DBG2(("smsatSetFeaturesDMA: return\n"));
return status;
}
osGLOBAL bit32
smsatSetFeaturesReadLookAhead(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status = SM_RC_FAILURE;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
fis = satIOContext->pFis;
SM_DBG2(("smsatSetFeaturesReadLookAhead: start\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SET_FEATURES;
fis->h.features = 0xAA;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatSetFeaturesReadLookAheadCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
if (smIORequest->tdData == smIORequest->smData)
{
SM_DBG1(("smsatSetFeaturesReadLookAhead: incorrect smIORequest\n"));
}
SM_DBG2(("smsatSetFeaturesReadLookAhead: return\n"));
return status;
}
osGLOBAL bit32
smsatSetFeaturesVolatileWriteCache(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext
)
{
bit32 status = SM_RC_FAILURE;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
fis = satIOContext->pFis;
SM_DBG2(("smsatSetFeaturesVolatileWriteCache: start\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SET_FEATURES;
fis->h.features = 0x02;
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0;
fis->d.device = 0;
fis->d.lbaLowExp = 0;
fis->d.lbaMidExp = 0;
fis->d.lbaHighExp = 0;
fis->d.featuresExp = 0;
fis->d.sectorCount = 0;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &smsatSetFeaturesVolatileWriteCacheCB;
satIOContext->reqType = agRequestType;
status = smsataLLIOStart( smRoot,
smIORequest,
smDeviceHandle,
smScsiRequest,
satIOContext);
if (smIORequest->tdData == smIORequest->smData)
{
SM_DBG1(("smsatSetFeaturesVolatileWriteCache: incorrect smIORequest\n"));
}
SM_DBG2(("smsatSetFeaturesVolatileWriteCache: return\n"));
return status;
}
osGLOBAL FORCEINLINE void
smsatBitSet(smRoot_t *smRoot, bit8 *data, bit32 index)
{
data[index>>3] |= (1 << (index&7));
}
osGLOBAL FORCEINLINE void
smsatBitClear(smRoot_t *smRoot, bit8 *data, bit32 index)
{
data[index>>3] &= ~(1 << (index&7));
}
osGLOBAL FORCEINLINE BOOLEAN
smsatBitTest(smRoot_t *smRoot, bit8 *data, bit32 index)
{
return ( (BOOLEAN)((data[index>>3] & (1 << (index&7)) ) ? 1: 0));
}
FORCEINLINE bit32
smsatTagAlloc(
smRoot_t *smRoot,
smDeviceData_t *pSatDevData,
bit8 *pTag
)
{
bit32 retCode = agFALSE;
bit32 i;
tdsmSingleThreadedEnter(smRoot, SM_NCQ_TAG_LOCK);
#ifdef CCFLAG_OPTIMIZE_SAT_LOCK
if (tdsmBitScanForward(smRoot, &i, ~(pSatDevData->freeSATAFDMATagBitmap)))
{
smsatBitSet(smRoot, (bit8*)&pSatDevData->freeSATAFDMATagBitmap, i);
*pTag = (bit8)i;
retCode = agTRUE;
}
#else
for ( i = 0; i < pSatDevData->satNCQMaxIO; i ++ )
{
if ( 0 == smsatBitTest(smRoot, (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, i) )
{
smsatBitSet(smRoot, (bit8*)&pSatDevData->freeSATAFDMATagBitmap, i);
*pTag = (bit8) i;
retCode = agTRUE;
break;
}
}
#endif
tdsmSingleThreadedLeave(smRoot, SM_NCQ_TAG_LOCK);
return retCode;
}
FORCEINLINE bit32
smsatTagRelease(
smRoot_t *smRoot,
smDeviceData_t *pSatDevData,
bit8 tag
)
{
bit32 retCode = agFALSE;
if ( tag < pSatDevData->satNCQMaxIO )
{
tdsmSingleThreadedEnter(smRoot, SM_NCQ_TAG_LOCK);
smsatBitClear(smRoot, (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, (bit32)tag);
tdsmSingleThreadedLeave(smRoot, SM_NCQ_TAG_LOCK);
retCode = agTRUE;
}
else
{
SM_DBG1(("smsatTagRelease: tag %d >= satNCQMaxIO %d!!!!\n", tag, pSatDevData->satNCQMaxIO));
}
return retCode;
}
osGLOBAL bit32
smsatComputeCDB10LBA(smSatIOContext_t *satIOContext)
{
smIniScsiCmnd_t *scsiCmnd;
smScsiInitiatorRequest_t *smScsiRequest;
bit32 lba = 0;
SM_DBG5(("smsatComputeCDB10LBA: start\n"));
smScsiRequest = satIOContext->smScsiXchg;
scsiCmnd = &(smScsiRequest->scsiCmnd);
lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
+ (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
return lba;
}
osGLOBAL bit32
smsatComputeCDB10TL(smSatIOContext_t *satIOContext)
{
smIniScsiCmnd_t *scsiCmnd;
smScsiInitiatorRequest_t *smScsiRequest;
bit32 tl = 0;
SM_DBG5(("smsatComputeCDB10TL: start\n"));
smScsiRequest = satIOContext->smScsiXchg;
scsiCmnd = &(smScsiRequest->scsiCmnd);
tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
return tl;
}
osGLOBAL bit32
smsatComputeCDB12LBA(smSatIOContext_t *satIOContext)
{
smIniScsiCmnd_t *scsiCmnd;
smScsiInitiatorRequest_t *smScsiRequest;
bit32 lba = 0;
SM_DBG5(("smsatComputeCDB12LBA: start\n"));
smScsiRequest = satIOContext->smScsiXchg;
scsiCmnd = &(smScsiRequest->scsiCmnd);
lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
+ (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
return lba;
}
osGLOBAL bit32
smsatComputeCDB12TL(smSatIOContext_t *satIOContext)
{
smIniScsiCmnd_t *scsiCmnd;
smScsiInitiatorRequest_t *smScsiRequest;
bit32 tl = 0;
SM_DBG5(("smsatComputeCDB12TL: start\n"));
smScsiRequest = satIOContext->smScsiXchg;
scsiCmnd = &(smScsiRequest->scsiCmnd);
tl = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
+ (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
return tl;
}
osGLOBAL bit32
smsatComputeCDB16LBA(smSatIOContext_t *satIOContext)
{
smIniScsiCmnd_t *scsiCmnd;
smScsiInitiatorRequest_t *smScsiRequest;
bit32 lba = 0;
SM_DBG5(("smsatComputeCDB16LBA: start\n"));
smScsiRequest = satIOContext->smScsiXchg;
scsiCmnd = &(smScsiRequest->scsiCmnd);
lba = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
+ (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
return lba;
}
osGLOBAL bit32
smsatComputeCDB16TL(smSatIOContext_t *satIOContext)
{
smIniScsiCmnd_t *scsiCmnd;
smScsiInitiatorRequest_t *smScsiRequest;
bit32 tl = 0;
SM_DBG5(("smsatComputeCDB16TL: start\n"));
smScsiRequest = satIOContext->smScsiXchg;
scsiCmnd = &(smScsiRequest->scsiCmnd);
tl = (scsiCmnd->cdb[10] << (8*3)) + (scsiCmnd->cdb[11] << (8*2))
+ (scsiCmnd->cdb[12] << 8) + scsiCmnd->cdb[13];
return tl;
}
osGLOBAL FORCEINLINE bit32
smsatComputeLoopNum(bit32 a, bit32 b)
{
bit32 LoopNum = 0;
SM_DBG5(("smsatComputeLoopNum: start\n"));
if (a < b || a == 0)
{
LoopNum = 1;
}
else
{
if (a == b || a == 0)
{
LoopNum = a/b;
}
else
{
LoopNum = a/b + 1;
}
}
return LoopNum;
}
osGLOBAL FORCEINLINE bit32
smsatCheckLimit(bit8 *lba, bit8 *tl, int flag, smDeviceData_t *pSatDevData)
{
bit32 lbaCheck = agFALSE;
int i;
bit8 limit[8];
bit32 rangeCheck = agFALSE;
bit16 ans[8];
bit8 final_ans[9];
bit8 Bit28max[8];
bit8 Bit48max[8];
bit32 ReadCapCheck = agFALSE;
bit32 ret;
bit8 final_satMaxLBA[9];
bit8 oneTL[8];
bit8 temp_satMaxLBA[8];
if (flag == agFALSE)
{
limit[0] = 0x0;
limit[1] = 0x0;
limit[2] = 0x0;
limit[3] = 0x0;
limit[4] = 0xF;
limit[5] = 0xFF;
limit[6] = 0xFF;
limit[7] = 0xFF;
}
else
{
limit[0] = 0x0;
limit[1] = 0x0;
limit[2] = 0xFF;
limit[3] = 0xFF;
limit[4] = 0xFF;
limit[5] = 0xFF;
limit[6] = 0xFF;
limit[7] = 0xFF;
}
for(i=0;i<8;i++)
{
if (lba[i] > limit[i])
{
SM_DBG1(("smsatCheckLimit: LBA check True at %d\n", i));
lbaCheck = agTRUE;
break;
}
else if (lba[i] < limit[i])
{
SM_DBG5(("smsatCheckLimit: LBA check False at %d\n", i));
lbaCheck = agFALSE;
break;
}
else
{
continue;
}
}
if (lbaCheck == agTRUE)
{
SM_DBG1(("smsatCheckLimit: return LBA check True\n"));
return agTRUE;
}
sm_memset(ans, 0, sizeof(ans));
sm_memset(final_ans, 0, sizeof(final_ans));
for(i=7;i>=0;i--)
{
ans[i] = (bit16)(lba[i] + tl[i]);
if (i != 7)
{
ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
}
}
final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
for(i=1;i<=8;i++)
{
final_ans[i] = (bit8)(ans[i-1] & 0xFF);
}
if (flag == agFALSE)
{
sm_memset(Bit28max, 0, sizeof(Bit28max));
Bit28max[4] = 0x10;
if (final_ans[0] != 0 || final_ans[1] != 0 || final_ans[2] != 0
|| final_ans[3] != 0 || final_ans[4] != 0)
{
SM_DBG1(("smsatCheckLimit: before 28Bit addressing TRUE\n"));
rangeCheck = agTRUE;
}
else
{
for(i=5;i<=8;i++)
{
if (final_ans[i] > Bit28max[i-1])
{
SM_DBG1(("smsatCheckLimit: 28Bit addressing TRUE at %d\n", i));
rangeCheck = agTRUE;
break;
}
else if (final_ans[i] < Bit28max[i-1])
{
SM_DBG5(("smsatCheckLimit: 28Bit addressing FALSE at %d\n", i));
rangeCheck = agFALSE;
break;
}
else
{
continue;
}
}
}
}
else
{
sm_memset(Bit48max, 0, sizeof(Bit48max));
Bit48max[1] = 0x1;
if (final_ans[0] != 0 || final_ans[1] != 0)
{
SM_DBG1(("smsatCheckLimit: before 48Bit addressing TRUE\n"));
rangeCheck = agTRUE;
}
else
{
for(i=2;i<=8;i++)
{
if (final_ans[i] > Bit48max[i-1])
{
SM_DBG1(("smsatCheckLimit: 48Bit addressing TRUE at %d\n", i));
rangeCheck = agTRUE;
break;
}
else if (final_ans[i] < Bit48max[i-1])
{
SM_DBG5(("smsatCheckLimit: 48Bit addressing FALSE at %d\n", i));
rangeCheck = agFALSE;
break;
}
else
{
continue;
}
}
}
}
if (rangeCheck == agTRUE)
{
SM_DBG1(("smsatCheckLimit: return rangeCheck True\n"));
return agTRUE;
}
sm_memset(temp_satMaxLBA, 0, sizeof(temp_satMaxLBA));
sm_memset(oneTL, 0, sizeof(oneTL));
sm_memset(final_satMaxLBA, 0, sizeof(final_satMaxLBA));
sm_memset(ans, 0, sizeof(ans));
sm_memcpy(&temp_satMaxLBA, &pSatDevData->satMaxLBA, sizeof(temp_satMaxLBA));
oneTL[7] = 1;
for(i=7;i>=0;i--)
{
ans[i] = (bit16)(temp_satMaxLBA[i] + oneTL[i]);
if (i != 7)
{
ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
}
}
final_satMaxLBA[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
for(i=1;i<=8;i++)
{
final_satMaxLBA[i] = (bit8)(ans[i-1] & 0xFF);
}
if ( pSatDevData->ReadCapacity == 10)
{
for (i=0;i<=8;i++)
{
if (final_ans[i] > final_satMaxLBA[i])
{
SM_DBG1(("smsatCheckLimit: Read Capacity 10 TRUE at %d\n", i));
ReadCapCheck = agTRUE;
break;
}
else if (final_ans[i] < final_satMaxLBA[i])
{
SM_DBG5(("smsatCheckLimit: Read Capacity 10 FALSE at %d\n", i));
ReadCapCheck = agFALSE;
break;
}
else
{
continue;
}
}
if ( ReadCapCheck)
{
SM_DBG1(("smsatCheckLimit: after Read Capacity 10 TRUE\n"));
}
else
{
SM_DBG5(("smsatCheckLimit: after Read Capacity 10 FALSE\n"));
}
}
else if ( pSatDevData->ReadCapacity == 16)
{
for (i=0;i<=8;i++)
{
if (final_ans[i] > final_satMaxLBA[i])
{
SM_DBG1(("smsatCheckLimit: Read Capacity 16 TRUE at %d\n", i));
ReadCapCheck = agTRUE;
break;
}
else if (final_ans[i] < final_satMaxLBA[i])
{
SM_DBG5(("smsatCheckLimit: Read Capacity 16 FALSE at %d\n", i));
ReadCapCheck = agFALSE;
break;
}
else
{
continue;
}
}
if ( ReadCapCheck)
{
SM_DBG1(("smsatCheckLimit: after Read Capacity 16 TRUE\n"));
}
else
{
SM_DBG5(("smsatCheckLimit: after Read Capacity 16 FALSE\n"));
}
}
else
{
SM_DBG5(("smsatCheckLimit: unknown pSatDevData->ReadCapacity %d\n", pSatDevData->ReadCapacity));
}
if (ReadCapCheck == agTRUE)
{
SM_DBG1(("smsatCheckLimit: return ReadCapCheck True\n"));
return agTRUE;
}
ret = (lbaCheck | rangeCheck | ReadCapCheck);
if (ret == agTRUE)
{
SM_DBG1(("smsatCheckLimit: final check TRUE\n"));
}
else
{
SM_DBG5(("smsatCheckLimit: final check FALSE\n"));
}
return ret;
}
osGLOBAL void
smsatPrintSgl(
smRoot_t *smRoot,
agsaEsgl_t *agEsgl,
bit32 idx
)
{
bit32 i=0;
#ifdef TD_DEBUG_ENABLE
agsaSgl_t *agSgl;
#endif
for (i=0;i<idx;i++)
{
#ifdef TD_DEBUG_ENABLE
agSgl = &(agEsgl->descriptor[i]);
#endif
SM_DBG3(("smsatPrintSgl: agSgl %d upperAddr 0x%08x lowerAddr 0x%08x len 0x%08x ext 0x%08x\n",
i, agSgl->sgUpper, agSgl->sgLower, agSgl->len, agSgl->extReserved));
}
return;
}
osGLOBAL void
smsatSplitSGL(
smRoot_t *smRoot,
smIORequest_t *smIORequest,
smDeviceHandle_t *smDeviceHandle,
smScsiInitiatorRequest_t *smScsiRequest,
smSatIOContext_t *satIOContext,
bit32 split,
bit32 tl,
bit32 flag
)
{
agsaSgl_t *agSgl;
agsaEsgl_t *agEsgl;
bit32 i=0;
smIniScsiCmnd_t *scsiCmnd;
bit32 totalLen=0;
bit32 splitLen=0;
bit32 splitDiffByte = 0;
bit32 splitDiffExtra = 0;
bit32 splitIdx = 0;
bit32 UpperAddr, LowerAddr;
bit32 tmpLowerAddr;
void *sglVirtualAddr;
void *sglSplitVirtualAddr;
scsiCmnd = &smScsiRequest->scsiCmnd;
SM_DBG3(("smsatSplitSGL: start\n"));
if (smScsiRequest->smSgl1.type == 0x80000000)
{
if (flag == agFALSE)
{
SM_DBG3(("smsatSplitSGL: Not first time\n"));
SM_DBG3(("smsatSplitSGL: UpperAddr 0x%08x LowerAddr 0x%08x\n", satIOContext->UpperAddr, satIOContext->LowerAddr));
SM_DBG3(("smsatSplitSGL: SplitIdx %d AdjustBytes 0x%08x\n", satIOContext->SplitIdx, satIOContext->AdjustBytes));
sglVirtualAddr = smScsiRequest->sglVirtualAddr;
agEsgl = (agsaEsgl_t *)smScsiRequest->sglVirtualAddr;
sglSplitVirtualAddr = &(agEsgl->descriptor[satIOContext->SplitIdx]);
agEsgl = (agsaEsgl_t *)sglSplitVirtualAddr;
if (agEsgl == agNULL)
{
SM_DBG1(("smsatSplitSGL: error!\n"));
return;
}
agSgl = &(agEsgl->descriptor[0]);
agSgl->sgUpper = satIOContext->UpperAddr;
agSgl->sgLower = satIOContext->LowerAddr;
agSgl->len = satIOContext->AdjustBytes;
sm_memcpy(sglVirtualAddr, sglSplitVirtualAddr, (satIOContext->EsglLen) * sizeof(agsaSgl_t));
agEsgl = (agsaEsgl_t *)smScsiRequest->sglVirtualAddr;
smsatPrintSgl(smRoot, (agsaEsgl_t *)sglVirtualAddr, satIOContext->EsglLen);
}
else
{
SM_DBG3(("smsatSplitSGL: first time\n"));
satIOContext->EsglLen = smScsiRequest->smSgl1.len;
agEsgl = (agsaEsgl_t *)smScsiRequest->sglVirtualAddr;
if (agEsgl == agNULL)
{
return;
}
smsatPrintSgl(smRoot, agEsgl, satIOContext->EsglLen);
}
if (tl > split)
{
SM_DBG3(("smsatSplitSGL: split case\n"));
i = 0;
while (1)
{
agSgl = &(agEsgl->descriptor[i]);
splitLen = splitLen + agSgl->len;
if (splitLen >= split)
{
splitDiffExtra = splitLen - split;
splitDiffByte = agSgl->len - splitDiffExtra;
splitIdx = i;
break;
}
i++;
}
SM_DBG3(("smsatSplitSGL: splitIdx %d\n", splitIdx));
SM_DBG3(("smsatSplitSGL: splitDiffByte 0x%8x\n", splitDiffByte));
SM_DBG3(("smsatSplitSGL: splitDiffExtra 0x%8x \n", splitDiffExtra));
agSgl = &(agEsgl->descriptor[splitIdx]);
UpperAddr = agSgl->sgUpper;
LowerAddr = agSgl->sgLower;
tmpLowerAddr = LowerAddr + splitDiffByte;
if (tmpLowerAddr < LowerAddr)
{
UpperAddr = UpperAddr + 1;
}
SM_DBG3(("smsatSplitSGL: UpperAddr 0x%08x tmpLowerAddr 0x%08x\n", UpperAddr, tmpLowerAddr));
agSgl->len = splitDiffByte;
smScsiRequest->smSgl1.len = splitIdx;
scsiCmnd->expDataLength = 0x20000;
satIOContext->UpperAddr = UpperAddr;
satIOContext->LowerAddr = tmpLowerAddr;
satIOContext->SplitIdx = splitIdx;
satIOContext->AdjustBytes = splitDiffExtra;
satIOContext->EsglLen = satIOContext->EsglLen - smScsiRequest->smSgl1.len;
satIOContext->OrgTL = satIOContext->OrgTL - 0x100;
}
else
{
SM_DBG3(("smsatSplitSGL: no split case\n"));
smScsiRequest->smSgl1.len = satIOContext->EsglLen;
for (i=0;i< smScsiRequest->smSgl1.len;i++)
{
agSgl = &(agEsgl->descriptor[i]);
totalLen = totalLen + (agSgl->len);
}
scsiCmnd->expDataLength = totalLen;
}
}
else
{
SM_DBG1(("not exntened esgl\n"));
}
return;
}