#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>
#ifdef SATA_ENABLE
#include <dev/pms/RefTisa/sallsdk/api/sa.h>
#include <dev/pms/RefTisa/sallsdk/api/saapi.h>
#include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
#include <dev/pms/RefTisa/tisa/api/titypes.h>
#include <dev/pms/RefTisa/tisa/api/ostiapi.h>
#include <dev/pms/RefTisa/tisa/api/tiapi.h>
#include <dev/pms/RefTisa/tisa/api/tiglobal.h>
#ifdef FDS_SM
#include <dev/pms/RefTisa/sat/api/sm.h>
#include <dev/pms/RefTisa/sat/api/smapi.h>
#include <dev/pms/RefTisa/sat/api/tdsmapi.h>
#endif
#ifdef FDS_DM
#include <dev/pms/RefTisa/discovery/api/dm.h>
#include <dev/pms/RefTisa/discovery/api/dmapi.h>
#include <dev/pms/RefTisa/discovery/api/tddmapi.h>
#endif
#include <dev/pms/RefTisa/tisa/sassata/sas/common/tdtypes.h>
#include <dev/pms/freebsd/driver/common/osstring.h>
#include <dev/pms/RefTisa/tisa/sassata/common/tdutil.h>
#ifdef INITIATOR_DRIVER
#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdtypes.h>
#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itddefs.h>
#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdglobl.h>
#endif
#ifdef TARGET_DRIVER
#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdglobl.h>
#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdxchg.h>
#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdtypes.h>
#endif
#include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h>
#include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h>
#include <dev/pms/RefTisa/tisa/sassata/sata/host/sat.h>
#include <dev/pms/RefTisa/tisa/sassata/sata/host/satproto.h>
GLOBAL bit32 satIOStart(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext
)
{
bit32 retVal = tiSuccess;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
tiLUN_t *pLun;
satInternalIo_t *pSatIntIo;
#ifdef TD_DEBUG_ENABLE
tdsaDeviceData_t *oneDeviceData;
#endif
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
pLun = &scsiCmnd->lun;
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)
)
{
TI_DBG1(("satIOStart: *** REJECT *** LUN not zero, cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n",
scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_NOT_SUPPORTED,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
retVal = tiSuccess;
goto ext;
}
TI_DBG6(("satIOStart: satPendingIO %d satNCQMaxIO %d\n",pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
if (pSatDevData->IDDeviceValid == agFALSE && (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY))
{
#ifdef TD_DEBUG_ENABLE
oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
#endif
TI_DBG1(("satIOStart: invalid identify device data did %d\n", oneDeviceData->id));
retVal = tiIONoDevice;
goto ext;
}
if (pSatDevData->satDriveState == SAT_DEV_STATE_IN_RECOVERY)
{
#ifdef TD_DEBUG_ENABLE
oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
#endif
TI_DBG1(("satIOStart: IN RECOVERY STATE cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n",
scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle));
TI_DBG1(("satIOStart: IN RECOVERY STATE did %d\n", oneDeviceData->id));
TI_DBG1(("satIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
TI_DBG1(("satIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
retVal = tiError;
goto ext;
}
if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
{
if (scsiCmnd->cdb[0] == SCSIOPC_REPORT_LUN)
{
return satReportLun(tiRoot, tiIORequest, tiDeviceHandle, tiScsiRequest, satIOContext);
}
else
{
return satPacket(tiRoot, tiIORequest, tiDeviceHandle, tiScsiRequest, satIOContext);
}
}
else
{
switch(scsiCmnd->cdb[0])
{
case SCSIOPC_READ_6:
retVal = satRead6( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_READ_10:
retVal = satRead10( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_READ_12:
TI_DBG5(("satIOStart: SCSIOPC_READ_12\n"));
retVal = satRead12( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_READ_16:
retVal = satRead16( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_WRITE_6:
retVal = satWrite6( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_WRITE_10:
retVal = satWrite10( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_WRITE_12:
TI_DBG5(("satIOStart: SCSIOPC_WRITE_12 \n"));
retVal = satWrite12( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_WRITE_16:
TI_DBG5(("satIOStart: SCSIOPC_WRITE_16\n"));
retVal = satWrite16( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_VERIFY_10:
retVal = satVerify10( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_VERIFY_12:
TI_DBG5(("satIOStart: SCSIOPC_VERIFY_12\n"));
retVal = satVerify12( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_VERIFY_16:
TI_DBG5(("satIOStart: SCSIOPC_VERIFY_16\n"));
retVal = satVerify16( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_TEST_UNIT_READY:
retVal = satTestUnitReady( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_INQUIRY:
retVal = satInquiry( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_REQUEST_SENSE:
retVal = satRequestSense( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_MODE_SENSE_6:
retVal = satModeSense6( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_MODE_SENSE_10:
retVal = satModeSense10( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_READ_CAPACITY_10:
retVal = satReadCapacity10( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_READ_CAPACITY_16:
retVal = satReadCapacity16( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_REPORT_LUN:
retVal = satReportLun( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_FORMAT_UNIT:
TI_DBG5(("satIOStart: SCSIOPC_FORMAT_UNIT\n"));
retVal = satFormatUnit( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_SEND_DIAGNOSTIC:
TI_DBG5(("satIOStart: SCSIOPC_SEND_DIAGNOSTIC\n"));
retVal = satSendDiagnostic( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_START_STOP_UNIT:
TI_DBG5(("satIOStart: SCSIOPC_START_STOP_UNIT\n"));
retVal = satStartStopUnit( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_WRITE_SAME_10:
TI_DBG5(("satIOStart: SCSIOPC_WRITE_SAME_10\n"));
retVal = satWriteSame10( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_WRITE_SAME_16:
TI_DBG5(("satIOStart: SCSIOPC_WRITE_SAME_16\n"));
retVal = satWriteSame16( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_LOG_SENSE:
TI_DBG5(("satIOStart: SCSIOPC_LOG_SENSE\n"));
retVal = satLogSense( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_MODE_SELECT_6:
TI_DBG5(("satIOStart: SCSIOPC_MODE_SELECT_6\n"));
retVal = satModeSelect6( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_MODE_SELECT_10:
TI_DBG5(("satIOStart: SCSIOPC_MODE_SELECT_10\n"));
retVal = satModeSelect10( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_SYNCHRONIZE_CACHE_10:
TI_DBG5(("satIOStart: SCSIOPC_SYNCHRONIZE_CACHE_10\n"));
retVal = satSynchronizeCache10( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_SYNCHRONIZE_CACHE_16:
TI_DBG5(("satIOStart: SCSIOPC_SYNCHRONIZE_CACHE_16\n"));
retVal = satSynchronizeCache16( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_WRITE_AND_VERIFY_10:
TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_10\n"));
retVal = satWriteAndVerify10( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_WRITE_AND_VERIFY_12:
TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_12\n"));
retVal = satWriteAndVerify12( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_WRITE_AND_VERIFY_16:
TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_16\n"));
retVal = satWriteAndVerify16( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_READ_MEDIA_SERIAL_NUMBER:
TI_DBG5(("satIOStart: SCSIOPC_READ_MEDIA_SERIAL_NUMBER\n"));
retVal = satReadMediaSerialNumber( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_READ_BUFFER:
TI_DBG5(("satIOStart: SCSIOPC_READ_BUFFER\n"));
retVal = satReadBuffer( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_WRITE_BUFFER:
TI_DBG5(("satIOStart: SCSIOPC_WRITE_BUFFER\n"));
retVal = satWriteBuffer( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
case SCSIOPC_REASSIGN_BLOCKS:
TI_DBG5(("satIOStart: SCSIOPC_REASSIGN_BLOCKS\n"));
retVal = satReassignBlocks( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
break;
default:
TI_DBG1(("satIOStart: unsupported SCSI cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n",
scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
retVal = tiSuccess;
break;
}
}
if (retVal == tiBusy)
{
#ifdef TD_DEBUG_ENABLE
oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
#endif
TI_DBG1(("satIOStart: BUSY did %d\n", oneDeviceData->id));
TI_DBG3(("satIOStart: LL is busy or target queue is full\n"));
TI_DBG3(("satIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
TI_DBG3(("satIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
pSatIntIo = satIOContext->satIntIoContext;
satFreeIntIoResource( tiRoot,
pSatDevData,
pSatIntIo);
}
ext:
return retVal;
}
void satSetSensePayload( scsiRspSense_t *pSense,
bit8 SnsKey,
bit32 SnsInfo,
bit16 SnsCode,
satIOContext_t *satIOContext
)
{
bit32 i;
bit32 senseLength;
TI_DBG5(("satSetSensePayload: start\n"));
senseLength = sizeof(scsiRspSense_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->pTiSenseData->senseLen = 18;
}
else
{
TI_DBG1(("satSetSensePayload: satIOContext is NULL\n"));
}
}
void satSetDeferredSensePayload( scsiRspSense_t *pSense,
bit8 SnsKey,
bit32 SnsInfo,
bit16 SnsCode,
satIOContext_t *satIOContext
)
{
bit32 i;
bit32 senseLength;
senseLength = sizeof(scsiRspSense_t);
for (i=0;i< senseLength;i++)
{
((bit8*)pSense)[i] = 0;
}
pSense->snsRespCode = 0x71;
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->pTiSenseData->senseLen = 18;
}
else
{
TI_DBG1(("satSetDeferredSensePayload: satIOContext is NULL\n"));
}
}
GLOBAL bit32 satPacket(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
satDeviceData_t *pSatDevData;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG3(("satPacket: 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 = (tiScsiRequest->dataDirection == tiDirectionIn)? 0x04 : 0;
}
else
{
fis->h.features = 0;
}
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 (tiScsiRequest->dataDirection == tiDirectionIn)
{
agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
}
else
{
agRequestType = AGSA_SATA_PROTOCOL_H2D_PKT;
}
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
fis->h.features |= 0x01;
}
else
{
fis->h.features |= 0x0;
}
satIOContext->satCompleteCB = &satPacketCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satPacket: return\n"));
return (status);
}
GLOBAL bit32 satSetFeatures(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext,
bit8 bIsDMAMode
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
fis = satIOContext->pFis;
TI_DBG3(("satSetFeatures: 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;
if (bIsDMAMode)
{
fis->d.sectorCount = 0x45;
}
else
{
fis->d.sectorCount = 0x0C;
}
satIOContext->satCompleteCB = &satSetFeaturesCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satSetFeatures: return\n"));
return status;
}
GLOBAL bit32 satRequestSenseForATAPI(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
satDeviceData_t *pSatDevData;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->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] = SENSE_DATA_LENGTH;
scsiCmnd->cdb[5] = 0;
TI_DBG3(("satRequestSenseForATAPI: 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 = (tiScsiRequest->dataDirection == tiDirectionIn)? 0x04 : 0;
}
else
{
fis->h.features = 0;
}
fis->d.lbaLow = 0;
fis->d.lbaMid = 0;
fis->d.lbaHigh = 0x20;
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 = (bit32)(scsiCmnd->cdb[0]|(scsiCmnd->cdb[1]<<8)|(scsiCmnd->cdb[2]<<16)|(scsiCmnd->cdb[3]<<24));
satIOContext->ATACmd = SAT_PACKET;
agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
fis->h.features |= 0x01;
}
else
{
fis->h.features |= 0x0;
}
}
satIOContext->satCompleteCB = &satRequestSenseForATAPICB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satRequestSenseForATAPI: return\n"));
return (status);
}
GLOBAL bit32 satDeviceReset(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
fis = satIOContext->pFis;
TI_DBG3(("satDeviceReset: 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 = &satDeviceResetCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG3(("satDeviceReset: return\n"));
return status;
}
GLOBAL bit32 satExecuteDeviceDiagnostic(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
fis = satIOContext->pFis;
TI_DBG3(("satExecuteDeviceDiagnostic: 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 = &satExecuteDeviceDiagnosticCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satExecuteDeviceDiagnostic: return\n"));
return status;
}
GLOBAL bit32 satRead10(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[4];
bit8 TL[4];
bit32 rangeChk = agFALSE;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG5(("satRead10: start\n"));
TI_DBG5(("satRead10: pSatDevData=%p\n", pSatDevData));
if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satRead10: return FUA_NV\n"));
return tiSuccess;
}
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satRead10: return control\n"));
return tiSuccess;
}
osti_memset(LBA, 0, sizeof(LBA));
osti_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] = 0;
TL[1] = 0;
TL[2] = scsiCmnd->cdb[7];
TL[3] = scsiCmnd->cdb[8];
rangeChk = satAddNComparebit32(LBA, TL);
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];
TI_DBG5(("satRead10: lba %d functioned lba %d\n", lba, satComputeCDB10LBA(satIOContext)));
TI_DBG5(("satRead10: lba 0x%x functioned lba 0x%x\n", lba, satComputeCDB10LBA(satIOContext)));
TI_DBG5(("satRead10: tl %d functioned tl %d\n", tl, satComputeCDB10TL(satIOContext)));
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
if (lba > SAT_TR_LBA_LIMIT - 1)
{
TI_DBG1(("satRead10: return LBA out of range, not EXT\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
if (rangeChk)
{
TI_DBG1(("satRead10: return LBA+TL out of range, not EXT\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
}
if (!rangeChk)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
TI_DBG5(("satRead10: 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
{
TI_DBG5(("satRead10: 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;
}
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
TI_DBG5(("satRead10: 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
{
TI_DBG5(("satRead10: case 4\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
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;
}
}
if (pSatDevData->satNCQ == agTRUE)
{
if (pSatDevData->sat48BitSupport != agTRUE)
{
TI_DBG5(("satRead10: case 5 !!! error NCQ but 28 bit address support \n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
TI_DBG6(("satRead10: 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;
}
satIOContext->currentLBA = lba;
satIOContext->OrgTL = tl;
if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
{
LoopNum = satComputeLoopNum(tl, 0xFF);
}
else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
{
LoopNum = satComputeLoopNum(tl, 0xFFFF);
}
else
{
LoopNum = satComputeLoopNum(tl, 0xFFFF);
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
TI_DBG5(("satRead10: NON CHAINED data\n"));
satIOContext->satCompleteCB = &satNonChainedDataIOCB;
}
else
{
TI_DBG1(("satRead10: 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 = &satChainedDataIOCB;
}
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satRead10: return\n"));
return (status);
}
GLOBAL bit32 satRead_1(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
satIOContext_t *satOrgIOContext = agNULL;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
bit32 lba = 0;
bit32 DenomTL = 0xFF;
bit32 Remainder = 0;
bit8 LBA[4];
TI_DBG2(("satRead_1: start\n"));
fis = satIOContext->pFis;
satOrgIOContext = satIOContext->satOrgIOContext;
scsiCmnd = satOrgIOContext->pScsiCmnd;
osti_memset(LBA,0, sizeof(LBA));
switch (satOrgIOContext->ATACmd)
{
case SAT_READ_DMA:
DenomTL = 0xFF;
break;
case SAT_READ_SECTORS:
DenomTL = 0xFF;
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:
TI_DBG1(("satRead_1: 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_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 = 0xFF;
}
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 = 0xFF;
}
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:
TI_DBG1(("satRead_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
return tiError;
break;
}
satIOContext->satCompleteCB = &satChainedDataIOCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satRead_1: return\n"));
return (status);
}
GLOBAL bit32 satRead12(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[4];
bit8 TL[4];
bit32 rangeChk = agFALSE;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG5(("satRead12: start\n"));
if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satRead12: return FUA_NV\n"));
return tiSuccess;
}
if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG2(("satRead12: return control\n"));
return tiSuccess;
}
osti_memset(LBA, 0, sizeof(LBA));
osti_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[8];
TL[3] = scsiCmnd->cdb[9];
rangeChk = satAddNComparebit32(LBA, TL);
lba = satComputeCDB12LBA(satIOContext);
tl = satComputeCDB12TL(satIOContext);
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
if (lba > SAT_TR_LBA_LIMIT - 1)
{
TI_DBG1(("satRead12: return LBA out of range, not EXT\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
if (rangeChk)
{
TI_DBG1(("satRead12: return LBA+TL out of range, not EXT\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
}
if (!rangeChk)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
TI_DBG5(("satRead12: 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
{
TI_DBG5(("satRead12: 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)
{
TI_DBG5(("satRead12: 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
{
TI_DBG5(("satRead12: case 4\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
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)
{
TI_DBG5(("satRead12: case 5 !!! error NCQ but 28 bit address support \n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
TI_DBG6(("satRead12: 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 = satComputeLoopNum(tl, 0xFF);
}
else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
{
LoopNum = satComputeLoopNum(tl, 0xFFFF);
}
else
{
LoopNum = satComputeLoopNum(tl, 0xFFFF);
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
TI_DBG5(("satRead12: NON CHAINED data\n"));
satIOContext->satCompleteCB = &satNonChainedDataIOCB;
}
else
{
TI_DBG1(("satRead12: 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 = &satChainedDataIOCB;
}
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satRead12: return\n"));
return (status);
}
GLOBAL bit32 satRead16(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[8];
bit8 TL[8];
bit32 rangeChk = agFALSE;
bit32 limitChk = agFALSE;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG5(("satRead16: start\n"));
if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satRead16: return FUA_NV\n"));
return tiSuccess;
}
if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satRead16: return control\n"));
return tiSuccess;
}
osti_memset(LBA, 0, sizeof(LBA));
osti_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];
rangeChk = satAddNComparebit64(LBA, TL);
limitChk = satCompareLBALimitbit(LBA);
lba = satComputeCDB16LBA(satIOContext);
tl = satComputeCDB16TL(satIOContext);
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
if (limitChk)
{
TI_DBG1(("satRead16: return LBA out of range, not EXT\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
if (rangeChk)
{
TI_DBG1(("satRead16: return LBA+TL out of range, not EXT\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
}
if (!rangeChk)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
TI_DBG5(("satRead16: 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
{
TI_DBG5(("satRead16: 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)
{
TI_DBG5(("satRead16: 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
{
TI_DBG5(("satRead16: case 4\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
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)
{
TI_DBG5(("satRead16: case 5 !!! error NCQ but 28 bit address support \n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
TI_DBG6(("satRead16: 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 = satComputeLoopNum(tl, 0xFF);
}
else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
{
LoopNum = satComputeLoopNum(tl, 0xFFFF);
}
else
{
LoopNum = satComputeLoopNum(tl, 0xFFFF);
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
TI_DBG5(("satRead16: NON CHAINED data\n"));
satIOContext->satCompleteCB = &satNonChainedDataIOCB;
}
else
{
TI_DBG1(("satRead16: 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 = &satChainedDataIOCB;
}
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satRead16: return\n"));
return (status);
}
GLOBAL bit32 satRead6(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit16 tl = 0;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG5(("satRead6: start\n"));
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG2(("satRead6: return control\n"));
return tiSuccess;
}
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)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satRead6: return LBA out of range\n"));
return tiSuccess;
}
}
if (lba + tl <= SAT_TR_LBA_LIMIT)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
TI_DBG5(("satRead6: 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
{
TI_DBG5(("satRead6: 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)
{
TI_DBG5(("satRead6: 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
{
TI_DBG5(("satRead6: 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)
{
TI_DBG5(("satRead6: case 5 !!! error NCQ but 28 bit address support \n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
TI_DBG5(("satRead6: 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 = &satNonChainedDataIOCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return (status);
}
GLOBAL bit32 satWrite16(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[8];
bit8 TL[8];
bit32 rangeChk = agFALSE;
bit32 limitChk = agFALSE;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG5(("satWrite16: start\n"));
if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWrite16: return FUA_NV\n"));
return tiSuccess;
}
if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWrite16: return control\n"));
return tiSuccess;
}
osti_memset(LBA, 0, sizeof(LBA));
osti_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];
rangeChk = satAddNComparebit64(LBA, TL);
limitChk = satCompareLBALimitbit(LBA);
lba = satComputeCDB16LBA(satIOContext);
tl = satComputeCDB16TL(satIOContext);
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
if (limitChk)
{
TI_DBG1(("satWrite16: return LBA out of range, not EXT\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
if (rangeChk)
{
TI_DBG1(("satWrite16: return LBA+TL out of range, not EXT\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
}
if (!rangeChk)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
TI_DBG5(("satWrite16: 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
{
TI_DBG5(("satWrite16: 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)
{
TI_DBG5(("satWrite16: 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
{
TI_DBG5(("satWrite16: 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)
{
TI_DBG5(("satWrite16: case 5 !!! error NCQ but 28 bit address support \n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
TI_DBG6(("satWrite16: 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 = satComputeLoopNum(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 = satComputeLoopNum(tl, 0xFFFF);
}
else
{
LoopNum = satComputeLoopNum(tl, 0xFFFF);
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
TI_DBG5(("satWrite16: NON CHAINED data\n"));
satIOContext->satCompleteCB = &satNonChainedDataIOCB;
}
else
{
TI_DBG1(("satWrite16: 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 = &satChainedDataIOCB;
}
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return (status);
}
GLOBAL bit32 satWrite12(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[4];
bit8 TL[4];
bit32 rangeChk = agFALSE;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG5(("satWrite12: start\n"));
if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWrite12: return FUA_NV\n"));
return tiSuccess;
}
if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWrite12: return control\n"));
return tiSuccess;
}
osti_memset(LBA, 0, sizeof(LBA));
osti_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[8];
TL[3] = scsiCmnd->cdb[9];
rangeChk = satAddNComparebit32(LBA, TL);
lba = satComputeCDB12LBA(satIOContext);
tl = satComputeCDB12TL(satIOContext);
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
if (lba > SAT_TR_LBA_LIMIT - 1)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWrite12: return LBA out of range, not EXT\n"));
return tiSuccess;
}
if (rangeChk)
{
TI_DBG1(("satWrite12: return LBA+TL out of range, not EXT\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
}
if (!rangeChk)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
TI_DBG5(("satWrite12: 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
{
TI_DBG5(("satWrite12: 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)
{
TI_DBG5(("satWrite12: 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
{
TI_DBG5(("satWrite12: 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)
{
TI_DBG5(("satWrite12: case 5 !!! error NCQ but 28 bit address support \n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
TI_DBG6(("satWrite12: 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 = satComputeLoopNum(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 = satComputeLoopNum(tl, 0xFFFF);
}
else
{
LoopNum = satComputeLoopNum(tl, 0xFFFF);
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
TI_DBG5(("satWrite12: NON CHAINED data\n"));
satIOContext->satCompleteCB = &satNonChainedDataIOCB;
}
else
{
TI_DBG1(("satWrite12: 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 = &satChainedDataIOCB;
}
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return (status);
}
GLOBAL bit32 satWrite10(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[4];
bit8 TL[4];
bit32 rangeChk = agFALSE;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG5(("satWrite10: start\n"));
if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWrite10: return FUA_NV\n"));
return tiSuccess;
}
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWrite10: return control\n"));
return tiSuccess;
}
osti_memset(LBA, 0, sizeof(LBA));
osti_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] = 0;
TL[1] = 0;
TL[2] = scsiCmnd->cdb[7];
TL[3] = scsiCmnd->cdb[8];
rangeChk = satAddNComparebit32(LBA, TL);
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];
TI_DBG5(("satWrite10: lba %d functioned lba %d\n", lba, satComputeCDB10LBA(satIOContext)));
TI_DBG5(("satWrite10: tl %d functioned tl %d\n", tl, satComputeCDB10TL(satIOContext)));
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
if (lba > SAT_TR_LBA_LIMIT - 1)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWrite10: return LBA out of range, not EXT\n"));
TI_DBG1(("satWrite10: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
TI_DBG1(("satWrite10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT));
return tiSuccess;
}
if (rangeChk)
{
TI_DBG1(("satWrite10: return LBA+TL out of range, not EXT\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
}
if (!rangeChk)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
TI_DBG5(("satWrite10: 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
{
TI_DBG5(("satWrite10: 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)
{
TI_DBG5(("satWrite10: 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
{
TI_DBG5(("satWrite10: 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)
{
TI_DBG5(("satWrite10: case 5 !!! error NCQ but 28 bit address support \n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
TI_DBG6(("satWrite10: 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;
}
satIOContext->currentLBA = lba;
satIOContext->OrgTL = tl;
if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
{
LoopNum = satComputeLoopNum(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 = satComputeLoopNum(tl, 0xFFFF);
}
else
{
LoopNum = satComputeLoopNum(tl, 0xFFFF);
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
TI_DBG5(("satWrite10: NON CHAINED data\n"));
satIOContext->satCompleteCB = &satNonChainedDataIOCB;
}
else
{
TI_DBG1(("satWrite10: 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 = &satChainedDataIOCB;
}
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return (status);
}
GLOBAL bit32 satWrite_1(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
satIOContext_t *satOrgIOContext = agNULL;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
bit32 lba = 0;
bit32 DenomTL = 0xFF;
bit32 Remainder = 0;
bit8 LBA[4];
TI_DBG2(("satWrite_1: start\n"));
fis = satIOContext->pFis;
satOrgIOContext = satIOContext->satOrgIOContext;
scsiCmnd = satOrgIOContext->pScsiCmnd;
osti_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:
TI_DBG1(("satWrite_1: 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_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:
TI_DBG1(("satWrite_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
return tiError;
break;
}
satIOContext->satCompleteCB = &satChainedDataIOCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satWrite_1: return\n"));
return (status);
}
GLOBAL bit32 satWrite6(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit16 tl = 0;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG5(("satWrite6: start\n"));
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWrite6: return control\n"));
return tiSuccess;
}
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)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWrite6: return LBA out of range\n"));
return tiSuccess;
}
}
if (lba + tl <= SAT_TR_LBA_LIMIT)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
TI_DBG5(("satWrite6: 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
{
TI_DBG5(("satWrite6: 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)
{
TI_DBG5(("satWrite6: 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
{
TI_DBG5(("satWrite6: 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)
{
TI_DBG5(("satWrite6: case 5 !!! error NCQ but 28 bit address support \n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
TI_DBG5(("satWrite6: 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 = &satNonChainedDataIOCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return (status);
}
GLOBAL bit32 satTestUnitReady(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG6(("satTestUnitReady: entry tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satTestUnitReady: return control\n"));
return tiSuccess;
}
if (pSatDevData->satStopState == agTRUE)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_NOT_READY,
0,
SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satTestUnitReady: stop state\n"));
return tiSuccess;
}
if (pSatDevData->satDriveState == SAT_DEV_STATE_FORMAT_IN_PROGRESS)
{
TI_DBG1(("satTestUnitReady() FORMAT_IN_PROGRESS tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
satSetSensePayload( pSense,
SCSI_SNSKEY_NOT_READY,
0,
SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_FORMAT_IN_PROGRESS,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satTestUnitReady: format in progress\n"));
return tiSuccess;
}
if (pSatDevData->satPendingIO != 0)
{
if (pSatDevData->satDeviceFaultState == agTRUE)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_HARDWARE_ERROR,
0,
SCSI_SNSCODE_LOGICAL_UNIT_FAILURE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satTestUnitReady: previous command ended in error\n"));
return tiSuccess;
}
}
if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
{
TI_DBG5(("satTestUnitReady: 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 = &satTestUnitReadyCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return (status);
}
TI_DBG5(("satTestUnitReady: sending check power mode cmnd\n"));
status = satTestUnitReady_1( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return (status);
}
GLOBAL bit32 satTestUnitReady_1(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
fis = satIOContext->pFis;
TI_DBG5(("satTestUnitReady_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 = &satTestUnitReadyCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satTestUnitReady_1: return\n"));
return status;
}
GLOBAL bit32 satReportLun(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
scsiRspSense_t *pSense;
bit32 allocationLen;
bit32 reportLunLen;
scsiReportLun_t *pReportLun;
tiIniScsiCmnd_t *scsiCmnd;
TI_DBG5(("satReportLun entry: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
pSense = satIOContext->pSense;
pReportLun = (scsiReportLun_t *) tiScsiRequest->sglVirtualAddr;
scsiCmnd = &tiScsiRequest->scsiCmnd;
allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) |
(((bit32)scsiCmnd->cdb[7]) << 16) |
(((bit32)scsiCmnd->cdb[8]) << 8 ) |
(((bit32)scsiCmnd->cdb[9]) );
reportLunLen = 16;
if (allocationLen < reportLunLen)
{
TI_DBG1(("satReportLun *** ERROR *** insufficient len=0x%x tiDeviceHandle=%p tiIORequest=%p\n",
reportLunLen, tiDeviceHandle, tiIORequest));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
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;
if (allocationLen > reportLunLen)
{
TI_DBG1(("satReportLun reporting underrun reportLunLen=0x%x allocationLen=0x%x \n", reportLunLen, allocationLen));
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOUnderRun,
allocationLen - reportLunLen,
agNULL,
satIOContext->interruptContext );
}
else
{
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
}
return tiSuccess;
}
GLOBAL bit32 satRequestSense(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
scsiRspSense_t *pSense;
satDeviceData_t *pSatDevData;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
tdIORequestBody_t *tdIORequestBody;
satInternalIo_t *satIntIo = agNULL;
satIOContext_t *satIOContext2;
TI_DBG4(("satRequestSense entry: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
pSense = (scsiRspSense_t *) tiScsiRequest->sglVirtualAddr;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG4(("satRequestSense: pSatDevData=%p\n", pSatDevData));
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satRequestSense: return control\n"));
return tiSuccess;
}
if ( scsiCmnd->cdb[1] & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satRequestSense: DESC bit is set, which we don't support\n"));
return tiSuccess;
}
if (pSatDevData->satSMARTEnabled == agTRUE)
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART_RETURN_STATUS;
fis->h.features = 0xDA;
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 = &satRequestSenseCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG4(("satRequestSense: if return, status %d\n", status));
return (status);
}
else
{
TI_DBG4(("satRequestSense: before satIntIo %p\n", satIntIo));
satIntIo = satAllocIntIoResource( tiRoot,
tiIORequest,
pSatDevData,
tiScsiRequest->scsiCmnd.expDataLength,
satIntIo);
TI_DBG4(("satRequestSense: after satIntIo %p\n", satIntIo));
if (satIntIo == agNULL)
{
satFreeIntIoResource( tiRoot,
pSatDevData,
satIntIo);
satSetSensePayload( pSense,
SCSI_SNSKEY_NO_SENSE,
0,
SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext );
TI_DBG4(("satRequestSense: else fail 1\n"));
return tiSuccess;
}
if (satIntIo == agNULL)
{
TI_DBG4(("satRequestSense: satIntIo is NULL\n"));
}
else
{
TI_DBG4(("satRequestSense: satIntIo is NOT NULL\n"));
}
satIntIo->satOrgTiIORequest = tiIORequest;
tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext);
satIOContext2->pSatDevData = pSatDevData;
satIOContext2->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
satIOContext2->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
satIOContext2->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
satIOContext2->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
satIOContext2->pTiSenseData->senseData = satIOContext2->pSense;
satIOContext2->tiRequestBody = satIntIo->satIntRequestBody;
satIOContext2->interruptContext = satIOContext->interruptContext;
satIOContext2->satIntIoContext = satIntIo;
satIOContext2->ptiDeviceHandle = tiDeviceHandle;
satIOContext2->satOrgIOContext = satIOContext;
TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.len %d\n", satIntIo->satIntTiScsiXchg.agSgl1.len));
TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.upper %d\n", satIntIo->satIntTiScsiXchg.agSgl1.upper));
TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.lower %d\n", satIntIo->satIntTiScsiXchg.agSgl1.lower));
TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.type %d\n", satIntIo->satIntTiScsiXchg.agSgl1.type));
status = satRequestSense_1( tiRoot,
&(satIntIo->satIntTiIORequest),
tiDeviceHandle,
&(satIntIo->satIntTiScsiXchg),
satIOContext2);
if (status != tiSuccess)
{
satFreeIntIoResource( tiRoot,
pSatDevData,
satIntIo);
satSetSensePayload( pSense,
SCSI_SNSKEY_NO_SENSE,
0,
SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
agNULL,
satIOContext->interruptContext );
TI_DBG1(("satRequestSense: else fail 2\n"));
return tiSuccess;
}
TI_DBG4(("satRequestSense: else return success\n"));
return tiSuccess;
}
}
GLOBAL bit32 satRequestSense_1(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
TI_DBG4(("satRequestSense_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
fis = satIOContext->pFis;
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 = &satRequestSenseCB;
satIOContext->reqType = agRequestType;
TI_DBG4(("satRequestSense_1: agSgl1.len %d\n", tiScsiRequest->agSgl1.len));
TI_DBG4(("satRequestSense_1: agSgl1.upper %d\n", tiScsiRequest->agSgl1.upper));
TI_DBG4(("satRequestSense_1: agSgl1.lower %d\n", tiScsiRequest->agSgl1.lower));
TI_DBG4(("satRequestSense_1: agSgl1.type %d\n", tiScsiRequest->agSgl1.type));
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
GLOBAL bit32 satInquiry(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
satDeviceData_t *pSatDevData;
bit32 status;
TI_DBG5(("satInquiry: start\n"));
TI_DBG5(("satInquiry entry: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
pSense = satIOContext->pSense;
scsiCmnd = &tiScsiRequest->scsiCmnd;
pSatDevData = satIOContext->pSatDevData;
TI_DBG5(("satInquiry: pSatDevData=%p\n", pSatDevData));
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG2(("satInquiry: return control\n"));
return tiSuccess;
}
if ( !(scsiCmnd->cdb[1] & SCSI_EVPD_MASK) &&
(scsiCmnd->cdb[2] != 0)
)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satInquiry: return EVPD and PAGE CODE\n"));
return tiSuccess;
}
TI_DBG6(("satInquiry: 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 = satStartIDDev(
tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext
);
TI_DBG6(("satInquiry: end status %d\n", status));
return status;
}
else
{
TI_DBG6(("satInquiry: calling satInquiryIntCB\n"));
satInquiryIntCB(
tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext
);
return tiSuccess;
}
}
GLOBAL bit32 satReadCapacity10(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
bit8 *pVirtAddr;
satDeviceData_t *pSatDevData;
agsaSATAIdentifyData_t *pSATAIdData;
bit32 lastLba;
bit32 word117_118;
bit32 word117;
bit32 word118;
TI_DBG5(("satReadCapacity10: start: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
pSense = satIOContext->pSense;
pVirtAddr = (bit8 *) tiScsiRequest->sglVirtualAddr;
scsiCmnd = &tiScsiRequest->scsiCmnd;
pSatDevData = satIOContext->pSatDevData;
pSATAIdData = &pSatDevData->satIdentifyData;
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satReadCapacity10: return control\n"));
return tiSuccess;
}
if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]))
{
TI_DBG1(("satReadCapacity10 *** ERROR *** logical address non zero, tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
if ( ((scsiCmnd->cdb[8]) & SCSI_READ_CAPACITY10_PMI_MASK) != 0 )
{
TI_DBG1(("satReadCapacity10 *** ERROR *** PMI is not zero, tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
if ( (pSATAIdData->maxLBA32_47 != 0 ) || (pSATAIdData->maxLBA48_63 != 0))
{
pVirtAddr[0] = 0xFF;
pVirtAddr[1] = 0xFF;
pVirtAddr[2] = 0xFF;
pVirtAddr[3] = 0xFF;
TI_DBG1(("satReadCapacity10: returns 0xFFFFFFFF\n"));
}
else
{
lastLba = (((pSATAIdData->maxLBA16_31) << 16) ) |
(pSATAIdData->maxLBA0_15);
lastLba = lastLba - 1;
pVirtAddr[0] = (bit8)((lastLba >> 24) & 0xFF);
pVirtAddr[1] = (bit8)((lastLba >> 16) & 0xFF);
pVirtAddr[2] = (bit8)((lastLba >> 8) & 0xFF);
pVirtAddr[3] = (bit8)((lastLba ) & 0xFF);
TI_DBG3(("satReadCapacity10: lastLba is 0x%x %d\n", lastLba, lastLba));
TI_DBG3(("satReadCapacity10: LBA 0 is 0x%x %d\n", pVirtAddr[0], pVirtAddr[0]));
TI_DBG3(("satReadCapacity10: LBA 1 is 0x%x %d\n", pVirtAddr[1], pVirtAddr[1]));
TI_DBG3(("satReadCapacity10: LBA 2 is 0x%x %d\n", pVirtAddr[2], pVirtAddr[2]));
TI_DBG3(("satReadCapacity10: LBA 3 is 0x%x %d\n", pVirtAddr[3], pVirtAddr[3]));
}
}
else
{
lastLba = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
(pSATAIdData->numOfUserAddressableSectorsLo);
lastLba = lastLba - 1;
pVirtAddr[0] = (bit8)((lastLba >> 24) & 0xFF);
pVirtAddr[1] = (bit8)((lastLba >> 16) & 0xFF);
pVirtAddr[2] = (bit8)((lastLba >> 8) & 0xFF);
pVirtAddr[3] = (bit8)((lastLba ) & 0xFF);
}
if (((pSATAIdData->word104_107[2]) & 0x1000) == 0)
{
TI_DBG5(("satReadCapacity10: Default Block Length is 512\n"));
pVirtAddr[4] = 0x00;
pVirtAddr[5] = 0x00;
pVirtAddr[6] = 0x02;
pVirtAddr[7] = 0x00;
}
else
{
word118 = pSATAIdData->word112_126[6];
word117 = pSATAIdData->word112_126[5];
word117_118 = (word118 << 16) + word117;
word117_118 = word117_118 * 2;
pVirtAddr[4] = (bit8)((word117_118 >> 24) & 0xFF);
pVirtAddr[5] = (bit8)((word117_118 >> 16) & 0xFF);
pVirtAddr[6] = (bit8)((word117_118 >> 8) & 0xFF);
pVirtAddr[7] = (bit8)(word117_118 & 0xFF);
TI_DBG1(("satReadCapacity10: Nondefault word118 %d 0x%x \n", word118, word118));
TI_DBG1(("satReadCapacity10: Nondefault word117 %d 0x%x \n", word117, word117));
TI_DBG1(("satReadCapacity10: 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] = pVirtAddr[0];
pSatDevData->satMaxLBA[5] = pVirtAddr[1];
pSatDevData->satMaxLBA[6] = pVirtAddr[2];
pSatDevData->satMaxLBA[7] = pVirtAddr[3];
TI_DBG4(("satReadCapacity10 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , tiDeviceHandle=%p tiIORequest=%p\n",
pVirtAddr[0], pVirtAddr[1], pVirtAddr[2], pVirtAddr[3],
pVirtAddr[4], pVirtAddr[5], pVirtAddr[6], pVirtAddr[7],
tiDeviceHandle, tiIORequest));
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return tiSuccess;
}
GLOBAL bit32 satReadCapacity16(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
bit8 *pVirtAddr;
satDeviceData_t *pSatDevData;
agsaSATAIdentifyData_t *pSATAIdData;
bit32 lastLbaLo;
bit32 allocationLen;
bit32 readCapacityLen = 32;
bit32 i = 0;
TI_DBG5(("satReadCapacity16 start: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
pSense = satIOContext->pSense;
pVirtAddr = (bit8 *) tiScsiRequest->sglVirtualAddr;
scsiCmnd = &tiScsiRequest->scsiCmnd;
pSatDevData = satIOContext->pSatDevData;
pSATAIdData = &pSatDevData->satIdentifyData;
allocationLen = (((bit32)scsiCmnd->cdb[10]) << 24) |
(((bit32)scsiCmnd->cdb[11]) << 16) |
(((bit32)scsiCmnd->cdb[12]) << 8 ) |
(((bit32)scsiCmnd->cdb[13]) );
if (allocationLen < readCapacityLen)
{
TI_DBG1(("satReadCapacity16 *** ERROR *** insufficient len=0x%x readCapacityLen=0x%x\n", allocationLen, readCapacityLen));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satReadCapacity16: return control\n"));
return tiSuccess;
}
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]) )
{
TI_DBG1(("satReadCapacity16 *** ERROR *** logical address non zero, tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
if ( ((scsiCmnd->cdb[14]) & SCSI_READ_CAPACITY16_PMI_MASK) != 0 )
{
TI_DBG1(("satReadCapacity16 *** ERROR *** PMI is not zero, tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
pVirtAddr[0] = (bit8)(((pSATAIdData->maxLBA48_63) >> 8) & 0xff);
pVirtAddr[1] = (bit8)((pSATAIdData->maxLBA48_63) & 0xff);
pVirtAddr[2] = (bit8)(((pSATAIdData->maxLBA32_47) >> 8) & 0xff);
pVirtAddr[3] = (bit8)((pSATAIdData->maxLBA32_47) & 0xff);
lastLbaLo = (((pSATAIdData->maxLBA16_31) << 16) ) | (pSATAIdData->maxLBA0_15);
lastLbaLo = lastLbaLo - 1;
pVirtAddr[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
pVirtAddr[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
pVirtAddr[6] = (bit8)((lastLbaLo >> 8) & 0xFF);
pVirtAddr[7] = (bit8)((lastLbaLo ) & 0xFF);
}
else
{
pVirtAddr[0] = 0;
pVirtAddr[1] = 0;
pVirtAddr[2] = 0;
pVirtAddr[3] = 0;
lastLbaLo = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
(pSATAIdData->numOfUserAddressableSectorsLo);
lastLbaLo = lastLbaLo - 1;
pVirtAddr[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
pVirtAddr[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
pVirtAddr[6] = (bit8)((lastLbaLo >> 8) & 0xFF);
pVirtAddr[7] = (bit8)((lastLbaLo ) & 0xFF);
}
pVirtAddr[8] = 0x00;
pVirtAddr[9] = 0x00;
pVirtAddr[10] = 0x02;
pVirtAddr[11] = 0x00;
pSatDevData->satMaxLBA[0] = pVirtAddr[0];
pSatDevData->satMaxLBA[1] = pVirtAddr[1];
pSatDevData->satMaxLBA[2] = pVirtAddr[2];
pSatDevData->satMaxLBA[3] = pVirtAddr[3];
pSatDevData->satMaxLBA[4] = pVirtAddr[4];
pSatDevData->satMaxLBA[5] = pVirtAddr[5];
pSatDevData->satMaxLBA[6] = pVirtAddr[6];
pSatDevData->satMaxLBA[7] = pVirtAddr[7];
TI_DBG5(("satReadCapacity16 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , tiDeviceHandle=%p tiIORequest=%p\n",
pVirtAddr[0], pVirtAddr[1], pVirtAddr[2], pVirtAddr[3],
pVirtAddr[4], pVirtAddr[5], pVirtAddr[6], pVirtAddr[7],
pVirtAddr[8], pVirtAddr[9], pVirtAddr[10], pVirtAddr[11],
tiDeviceHandle, tiIORequest));
for(i=12;i<=31;i++)
{
pVirtAddr[i] = 0x00;
}
if (allocationLen > readCapacityLen)
{
TI_DBG1(("satReadCapacity16 reporting underrun readCapacityLen=0x%x allocationLen=0x%x \n", readCapacityLen, allocationLen));
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOUnderRun,
allocationLen - readCapacityLen,
agNULL,
satIOContext->interruptContext );
}
else
{
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
}
return tiSuccess;
}
GLOBAL bit32 satModeSense6(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
scsiRspSense_t *pSense;
bit32 requestLen;
tiIniScsiCmnd_t *scsiCmnd;
bit32 pageSupported;
bit8 page;
bit8 *pModeSense;
satDeviceData_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;
TI_DBG5(("satModeSense6 entry: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
pSense = satIOContext->pSense;
scsiCmnd = &tiScsiRequest->scsiCmnd;
pModeSense = (bit8 *) tiScsiRequest->sglVirtualAddr;
pSatDevData = satIOContext->pSatDevData;
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG2(("satModeSense6: return control\n"));
return tiSuccess;
}
PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PC_MASK);
if (PC != 0)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satModeSense6: return due to PC value pc 0x%x\n", PC >> 6));
return tiSuccess;
}
page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PAGE_CODE_MASK);
TI_DBG5(("satModeSense6: page=0x%x, tiDeviceHandle=%p tiIORequest=%p\n",
page, tiDeviceHandle, tiIORequest));
requestLen = scsiCmnd->cdb[4];
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)
{
TI_DBG1(("satModeSense6 *** ERROR *** not supported page 0x%x tiDeviceHandle=%p tiIORequest=%p\n",
page, tiDeviceHandle, tiIORequest));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
switch(page)
{
case MODESENSE_RETURN_ALL_PAGES:
lenRead = (bit8)MIN(requestLen, MODE_SENSE6_RETURN_ALL_PAGES_LEN);
break;
case MODESENSE_CONTROL_PAGE:
lenRead = (bit8)MIN(requestLen, MODE_SENSE6_CONTROL_PAGE_LEN);
break;
case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE:
lenRead = (bit8)MIN(requestLen, MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
break;
case MODESENSE_CACHING:
lenRead = (bit8)MIN(requestLen, MODE_SENSE6_CACHING_LEN);
break;
case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE:
lenRead = (bit8)MIN(requestLen, MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
break;
default:
TI_DBG1(("satModeSense6: default error page %d\n", page));
break;
}
if (page == MODESENSE_RETURN_ALL_PAGES)
{
TI_DBG5(("satModeSense6: 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;
#ifdef NOT_YET
if (pSatDevData->satWriteCacheEnabled == agTRUE)
{
AllPages[26] = 0x04;
}
else
{
AllPages[26] = 0x00;
}
#endif
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;
osti_memcpy(pModeSense, &AllPages, lenRead);
}
else if (page == MODESENSE_CONTROL_PAGE)
{
TI_DBG5(("satModeSense6: 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;
osti_memcpy(pModeSense, &Control, lenRead);
}
else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
{
TI_DBG5(("satModeSense6: 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;
osti_memcpy(pModeSense, &RWErrorRecovery, lenRead);
}
else if (page == MODESENSE_CACHING)
{
TI_DBG5(("satModeSense6: MODESENSE_CACHING\n"));
if (requestLen == 4 && page == MODESENSE_CACHING)
{
TI_DBG5(("satModeSense6: linux 2.6.8.24 support\n"));
pModeSense[0] = 0x20 - 1;
pModeSense[1] = 0x00;
pModeSense[2] = 0x00;
pModeSense[3] = 0x08;
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return tiSuccess;
}
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;
#ifdef NOT_YET
if (pSatDevData->satWriteCacheEnabled == agTRUE)
{
Caching[14] = 0x04;
}
else
{
Caching[14] = 0x00;
}
#endif
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;
osti_memcpy(pModeSense, &Caching, lenRead);
}
else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
{
TI_DBG5(("satModeSense6: 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;
osti_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
}
else
{
TI_DBG1(("satModeSense6: Error page %d\n", page));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
if (requestLen > lenRead)
{
TI_DBG6(("satModeSense6 reporting underrun lenRead=0x%x requestLen=0x%x tiIORequest=%p\n", lenRead, requestLen, tiIORequest));
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOUnderRun,
requestLen - lenRead,
agNULL,
satIOContext->interruptContext );
}
else
{
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
}
return tiSuccess;
}
GLOBAL bit32 satModeSense10(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
scsiRspSense_t *pSense;
bit32 requestLen;
tiIniScsiCmnd_t *scsiCmnd;
bit32 pageSupported;
bit8 page;
bit8 *pModeSense;
satDeviceData_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;
TI_DBG5(("satModeSense10 entry: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
pSense = satIOContext->pSense;
scsiCmnd = &tiScsiRequest->scsiCmnd;
pModeSense = (bit8 *) tiScsiRequest->sglVirtualAddr;
pSatDevData = satIOContext->pSatDevData;
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG2(("satModeSense10: return control\n"));
return tiSuccess;
}
PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PC_MASK);
if (PC != 0)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satModeSense10: return due to PC value pc 0x%x\n", PC));
return tiSuccess;
}
LLBAA = (bit8)((scsiCmnd->cdb[1]) & SCSI_MODE_SENSE10_LLBAA_MASK);
page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PAGE_CODE_MASK);
TI_DBG5(("satModeSense10: page=0x%x, tiDeviceHandle=%p tiIORequest=%p\n",
page, tiDeviceHandle, tiIORequest));
requestLen = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
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)
{
TI_DBG1(("satModeSense10 *** ERROR *** not supported page 0x%x tiDeviceHandle=%p tiIORequest=%p\n",
page, tiDeviceHandle, tiIORequest));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
switch(page)
{
case MODESENSE_RETURN_ALL_PAGES:
if (LLBAA)
{
lenRead = (bit8)MIN(requestLen, MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN);
}
else
{
lenRead = (bit8)MIN(requestLen, MODE_SENSE10_RETURN_ALL_PAGES_LEN);
}
break;
case MODESENSE_CONTROL_PAGE:
if (LLBAA)
{
lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN);
}
else
{
lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CONTROL_PAGE_LEN);
}
break;
case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE:
if (LLBAA)
{
lenRead = (bit8)MIN(requestLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN);
}
else
{
lenRead = (bit8)MIN(requestLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
}
break;
case MODESENSE_CACHING:
if (LLBAA)
{
lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CACHING_LLBAA_LEN);
}
else
{
lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CACHING_LEN);
}
break;
case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE:
if (LLBAA)
{
lenRead = (bit8)MIN(requestLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN);
}
else
{
lenRead = (bit8)MIN(requestLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
}
break;
default:
TI_DBG1(("satModeSense10: default error page %d\n", page));
break;
}
if (page == MODESENSE_RETURN_ALL_PAGES)
{
TI_DBG5(("satModeSense10: 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;
#ifdef NOT_YET
if (pSatDevData->satWriteCacheEnabled == agTRUE)
{
AllPages[index+14] = 0x04;
}
else
{
AllPages[index+14] = 0x00;
}
#endif
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;
osti_memcpy(pModeSense, &AllPages, lenRead);
}
else if (page == MODESENSE_CONTROL_PAGE)
{
TI_DBG5(("satModeSense10: 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;
osti_memcpy(pModeSense, &Control, lenRead);
}
else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
{
TI_DBG5(("satModeSense10: 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;
osti_memcpy(pModeSense, &RWErrorRecovery, lenRead);
}
else if (page == MODESENSE_CACHING)
{
TI_DBG5(("satModeSense10: 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;
#ifdef NOT_YET
if (pSatDevData->satWriteCacheEnabled == agTRUE)
{
Caching[index+2] = 0x04;
}
else
{
Caching[index+2] = 0x00;
}
#endif
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;
osti_memcpy(pModeSense, &Caching, lenRead);
}
else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
{
TI_DBG5(("satModeSense10: 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;
osti_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
}
else
{
TI_DBG1(("satModeSense10: Error page %d\n", page));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
if (requestLen > lenRead)
{
TI_DBG1(("satModeSense10 reporting underrun lenRead=0x%x requestLen=0x%x tiIORequest=%p\n", lenRead, requestLen, tiIORequest));
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOUnderRun,
requestLen - lenRead,
agNULL,
satIOContext->interruptContext );
}
else
{
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
}
return tiSuccess;
}
GLOBAL bit32 satVerify10(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
satDeviceData_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[4];
bit8 TL[4];
bit32 rangeChk = agFALSE;
TI_DBG5(("satVerify10 entry: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
pSense = satIOContext->pSense;
scsiCmnd = &tiScsiRequest->scsiCmnd;
pSatDevData = satIOContext->pSatDevData;
fis = satIOContext->pFis;
if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satVerify10: no byte checking \n"));
return tiSuccess;
}
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG2(("satVerify10: return control\n"));
return tiSuccess;
}
osti_memset(LBA, 0, sizeof(LBA));
osti_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] = 0;
TL[1] = 0;
TL[2] = scsiCmnd->cdb[7];
TL[3] = scsiCmnd->cdb[8];
rangeChk = satAddNComparebit32(LBA, TL);
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)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satVerify10: return LBA out of range, not EXT\n"));
TI_DBG1(("satVerify10: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
TI_DBG1(("satVerify10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT));
return tiSuccess;
}
if (rangeChk)
{
TI_DBG1(("satVerify10: return LBA+TL out of range, not EXT\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
TI_DBG5(("satVerify10: 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
{
TI_DBG5(("satVerify10: 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 = satComputeLoopNum(tl, 0xFF);
}
else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
{
LoopNum = satComputeLoopNum(tl, 0xFFFF);
}
else
{
TI_DBG1(("satVerify10: error case 1!!!\n"));
LoopNum = 1;
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
TI_DBG5(("satVerify10: NON CHAINED data\n"));
satIOContext->satCompleteCB = &satNonChainedVerifyCB;
}
else
{
TI_DBG1(("satVerify10: 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
{
TI_DBG1(("satVerify10: error case 2!!!\n"));
}
satIOContext->satCompleteCB = &satChainedVerifyCB;
}
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return (status);
}
GLOBAL bit32 satChainedVerify(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
satIOContext_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];
TI_DBG2(("satChainedVerify: start\n"));
fis = satIOContext->pFis;
satOrgIOContext = satIOContext->satOrgIOContext;
osti_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:
TI_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:
TI_DBG1(("satChainedVerify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
return tiError;
break;
}
satIOContext->satCompleteCB = &satChainedVerifyCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satChainedVerify: return\n"));
return (status);
}
GLOBAL bit32 satVerify12(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
satDeviceData_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[4];
bit8 TL[4];
bit32 rangeChk = agFALSE;
TI_DBG5(("satVerify12 entry: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
pSense = satIOContext->pSense;
scsiCmnd = &tiScsiRequest->scsiCmnd;
pSatDevData = satIOContext->pSatDevData;
fis = satIOContext->pFis;
if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satVerify12: no byte checking \n"));
return tiSuccess;
}
if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satVerify12: return control\n"));
return tiSuccess;
}
osti_memset(LBA, 0, sizeof(LBA));
osti_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];
rangeChk = satAddNComparebit32(LBA, TL);
lba = satComputeCDB12LBA(satIOContext);
tl = satComputeCDB12TL(satIOContext);
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
if (lba > SAT_TR_LBA_LIMIT - 1)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satVerify12: return LBA out of range, not EXT\n"));
TI_DBG1(("satVerify12: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
TI_DBG1(("satVerify12: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT));
return tiSuccess;
}
if (rangeChk)
{
TI_DBG1(("satVerify12: return LBA+TL out of range, not EXT\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
TI_DBG5(("satVerify12: 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
{
TI_DBG5(("satVerify12: 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 = satComputeLoopNum(tl, 0xFF);
}
else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
{
LoopNum = satComputeLoopNum(tl, 0xFFFF);
}
else
{
TI_DBG1(("satVerify12: error case 1!!!\n"));
LoopNum = 1;
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
TI_DBG5(("satVerify12: NON CHAINED data\n"));
satIOContext->satCompleteCB = &satNonChainedVerifyCB;
}
else
{
TI_DBG1(("satVerify12: 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
{
TI_DBG1(("satVerify10: error case 2!!!\n"));
}
satIOContext->satCompleteCB = &satChainedVerifyCB;
}
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return (status);
}
GLOBAL bit32 satVerify16(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
satDeviceData_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 rangeChk = agFALSE;
bit32 limitChk = agFALSE;
TI_DBG5(("satVerify16 entry: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
pSense = satIOContext->pSense;
scsiCmnd = &tiScsiRequest->scsiCmnd;
pSatDevData = satIOContext->pSatDevData;
fis = satIOContext->pFis;
if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satVerify16: no byte checking \n"));
return tiSuccess;
}
if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG2(("satVerify16: return control\n"));
return tiSuccess;
}
osti_memset(LBA, 0, sizeof(LBA));
osti_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];
rangeChk = satAddNComparebit64(LBA, TL);
limitChk = satCompareLBALimitbit(LBA);
lba = satComputeCDB16LBA(satIOContext);
tl = satComputeCDB16TL(satIOContext);
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
if (limitChk)
{
TI_DBG1(("satVerify16: return LBA out of range, not EXT\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
if (rangeChk)
{
TI_DBG1(("satVerify16: return LBA+TL out of range, not EXT\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
TI_DBG5(("satVerify16: 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
{
TI_DBG5(("satVerify12: 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 = satComputeLoopNum(tl, 0xFF);
}
else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
{
LoopNum = satComputeLoopNum(tl, 0xFFFF);
}
else
{
TI_DBG1(("satVerify12: error case 1!!!\n"));
LoopNum = 1;
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
TI_DBG5(("satVerify12: NON CHAINED data\n"));
satIOContext->satCompleteCB = &satNonChainedVerifyCB;
}
else
{
TI_DBG1(("satVerify12: 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
{
TI_DBG1(("satVerify10: error case 2!!!\n"));
}
satIOContext->satCompleteCB = &satChainedVerifyCB;
}
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return (status);
}
GLOBAL bit32 satFormatUnit(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
bit32 index = 0;
pSense = satIOContext->pSense;
scsiCmnd = &tiScsiRequest->scsiCmnd;
TI_DBG5(("satFormatUnit: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))
)
{
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
TI_DBG2(("satFormatUnit: return opcode\n"));
return tiSuccess;
}
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))
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satFormatUnit: return defect list format\n"));
return tiSuccess;
}
}
if ( (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
(scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_CMPLIST_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satFormatUnit: return cmplist\n"));
return tiSuccess;
}
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satFormatUnit: return control\n"));
return tiSuccess;
}
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))
)
{
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
TI_DBG5(("satFormatUnit: return defect list case 1\n"));
return tiSuccess;
}
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) )
)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG5(("satFormatUnit: return defect list case 2\n"));
return tiSuccess;
}
}
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
TI_DBG5(("satFormatUnit: return last\n"));
return tiSuccess;
}
GLOBAL bit32 satSendDiagnostic(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 parmLen;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG5(("satSendDiagnostic: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) )
)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satSendDiagnostic: return PF, DEVOFFL, UNITOFFL, PARAM LIST\n"));
return tiSuccess;
}
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG2(("satSendDiagnostic: return control\n"));
return tiSuccess;
}
parmLen = (scsiCmnd->cdb[3] << 8) + scsiCmnd->cdb[4];
if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
(pSatDevData->satSMARTSelfTest == agFALSE)
)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satSendDiagnostic: return Table 29 case 1\n"));
return tiSuccess;
}
if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
(pSatDevData->satSMARTSelfTest == agTRUE) &&
(pSatDevData->satSMARTEnabled == agFALSE)
)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ABORTED_COMMAND,
0,
SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG5(("satSendDiagnostic: return Table 29 case 2\n"));
return tiSuccess;
}
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 = &satSendDiagnosticCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satSendDiagnostic: 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_EXEUTE_OFF_LINE_IMMEDIATE;
fis->h.features = 0xD4;
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 = &satSendDiagnosticCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satSendDiagnostic: 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;
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext );
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;
fis->h.features = 0xD4;
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 = &satSendDiagnosticCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satSendDiagnostic: return Table 28 case 1\n"));
return (status);
case 2:
pSatDevData->satBGPendingDiag = agTRUE;
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext );
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;
fis->h.features = 0xD4;
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 = &satSendDiagnosticCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satSendDiagnostic: return Table 28 case 2\n"));
return (status);
case 4:
if (parmLen != 0)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satSendDiagnostic: case 4, non zero ParmLen %d\n", parmLen));
return tiSuccess;
}
if (pSatDevData->satBGPendingDiag == agTRUE)
{
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;
fis->h.features = 0xD4;
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 = &satSendDiagnosticCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satSendDiagnostic: send SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE case 3\n"));
TI_DBG5(("satSendDiagnostic: Table 28 case 4\n"));
return (status);
}
else
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satSendDiagnostic: case 4, no pending diagnostic in background\n"));
TI_DBG5(("satSendDiagnostic: Table 28 case 4\n"));
return tiSuccess;
}
break;
case 5:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;
fis->h.features = 0xD4;
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 = &satSendDiagnosticCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satSendDiagnostic: return Table 28 case 5\n"));
return (status);
case 6:
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;
fis->h.features = 0xD4;
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 = &satSendDiagnosticCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satSendDiagnostic: return Table 28 case 6\n"));
return (status);
case 0:
case 3:
case 7:
default:
break;
}
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext );
TI_DBG5(("satSendDiagnostic: return Table 28 case 0,3,7 and default\n"));
return tiSuccess;
}
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext );
TI_DBG5(("satSendDiagnostic: return last\n"));
return tiSuccess;
}
GLOBAL bit32 satSendDiagnostic_1(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
satDeviceData_t *pSatDevData;
agsaFisRegHostToDevice_t *fis;
TI_DBG5(("satSendDiagnostic_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
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 = &satSendDiagnosticCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
GLOBAL bit32 satSendDiagnostic_2(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
satDeviceData_t *pSatDevData;
agsaFisRegHostToDevice_t *fis;
TI_DBG5(("satSendDiagnostic_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
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 = &satSendDiagnosticCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
GLOBAL bit32 satStartStopUnit(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG5(("satStartStopUnit:start\n"));
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satStartStopUnit: return control\n"));
return tiSuccess;
}
if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
{
if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
{
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext );
TI_DBG5(("satStartStopUnit: return table48 case 1-1\n"));
return tiSuccess;
}
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 = &satStartStopUnitCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satStartStopUnit: 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) )
{
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext );
TI_DBG5(("satStartStopUnit: return table48 case 2 1\n"));
return tiSuccess;
}
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 = &satStartStopUnitCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satStartStopUnit: 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) )
{
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext );
TI_DBG5(("satStartStopUnit: return table48 case 3 1\n"));
return tiSuccess;
}
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 = &satStartStopUnitCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
else
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG5(("satStartStopUnit: return Table 29 case 3 2\n"));
return tiSuccess;
}
}
else
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG5(("satStartStopUnit: return Table 29 case 4\n"));
return tiSuccess;
}
}
GLOBAL bit32 satStartStopUnit_1(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
TI_DBG5(("satStartStopUnit_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
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 = &satStartStopUnitCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satStartStopUnit_1 return status %d\n", status));
return status;
}
GLOBAL bit32 satRead10_2(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
satDeviceData_t *pSatDevData;
agsaFisRegHostToDevice_t *fis;
pSatDevData = satIOContext->pSatDevData;
fis = satIOContext->pFis;
TI_DBG5(("satReadVerifySectorsNoChain: start\n"));
pSatDevData->satVerifyState = 0xFFFFFFFF;
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 = 0x4F;
fis->d.lbaHigh = 0x00;
fis->d.lbaLowExp = 0xF1;
fis->d.lbaMidExp = 0x5F;
fis->d.lbaHighExp = 0xFF;
fis->d.featuresExp = 0;
fis->d.sectorCount = 1;
fis->d.sectorCountExp = 0;
fis->d.reserved4 = 0;
fis->d.device = 0x4E;
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 = 0x7F;
fis->d.lbaMid = 0x4F;
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 = 0x4E;
fis->d.control = 0;
fis->d.reserved5 = 0;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
}
satIOContext->satCompleteCB = &satNonDataIOCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satReadVerifySectorsNoChain: return last\n"));
return status;
}
GLOBAL bit32 satWriteSame10(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit32 tl = 0;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG5(("satWriteSame10: start\n"));
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWriteSame10: return control\n"));
return tiSuccess;
}
if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
!(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
{
TI_DBG5(("satWriteSame10: case 1\n"));
if ( pSatDevData->sat48BitSupport != agTRUE )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWriteSame10: return internal checking\n"));
return tiSuccess;
}
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)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWriteSame10: return LBA out of range\n"));
return tiSuccess;
}
}
if (lba + tl <= SAT_TR_LBA_LIMIT)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
TI_DBG5(("satWriteSame10: case 1-2 !!! error due to writeSame10\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
else
{
TI_DBG5(("satWriteSame10: case 1-1 !!! error due to writesame10\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
TI_DBG5(("satWriteSame10: 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)
{
TI_DBG5(("satWriteSame10: case 3 !!! warning can't fit sectors\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
}
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
{
TI_DBG5(("satWriteSame10: 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)
{
TI_DBG5(("satWriteSame10: case 4 !!! warning can't fit sectors\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
}
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)
{
TI_DBG5(("satWriteSame10: case 1-5 !!! error NCQ but 28 bit address support \n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
TI_DBG5(("satWriteSame10: 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)
{
TI_DBG5(("satWriteSame10: case 4 !!! warning can't fit sectors\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
}
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 = &satWriteSame10CB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return (status);
}
else if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG5(("satWriteSame10: return Table 62 case 2\n"));
return tiSuccess;
}
else if ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
!(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
{
TI_DBG5(("satWriteSame10: Table 62 case 3\n"));
}
else
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG5(("satWriteSame10: return Table 62 case 4\n"));
return tiSuccess;
}
return tiSuccess;
}
GLOBAL bit32 satWriteSame10_1(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext,
bit32 lba
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
bit8 lba1, lba2 ,lba3, lba4;
TI_DBG5(("satWriteSame10_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
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 = &satWriteSame10CB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satWriteSame10_1 return status %d\n", status));
return status;
}
GLOBAL bit32 satWriteSame10_2(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext,
bit32 lba
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
bit8 lba1, lba2 ,lba3, lba4;
TI_DBG5(("satWriteSame10_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
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 = &satWriteSame10CB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satWriteSame10_2 return status %d\n", status));
return status;
}
GLOBAL bit32 satWriteSame10_3(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext,
bit32 lba
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
bit8 lba1, lba2 ,lba3, lba4;
TI_DBG5(("satWriteSame10_3 entry: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
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 = &satWriteSame10CB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satWriteSame10_2 return status %d\n", status));
return status;
}
GLOBAL bit32 satWriteSame16(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
scsiRspSense_t *pSense;
pSense = satIOContext->pSense;
TI_DBG5(("satWriteSame16:start\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_NO_SENSE,
0,
SCSI_SNSCODE_NO_ADDITIONAL_INFO,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG5(("satWriteSame16: return internal checking\n"));
return tiSuccess;
}
GLOBAL bit32 satLogSense_1(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
satDeviceData_t *pSatDevData;
agsaFisRegHostToDevice_t *fis;
pSatDevData = satIOContext->pSatDevData;
fis = satIOContext->pFis;
TI_DBG5(("satLogSense_1: start\n"));
if ( pSatDevData->sat48BitSupport == agTRUE )
{
TI_DBG5(("satLogSense_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 = &satLogSenseCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
else
{
TI_DBG5(("satLogSense_1: case 2-2 sends SMART READ LOG\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART_READ_LOG;
fis->h.features = 0x00;
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 = &satLogSenseCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
}
GLOBAL bit32 satSMARTEnable(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
TI_DBG4(("satSMARTEnable entry: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
fis = satIOContext->pFis;
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART_ENABLE_OPERATIONS;
fis->h.features = 0xD8;
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 = &satSMARTEnableCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
GLOBAL bit32 satLogSense_3(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
TI_DBG4(("satLogSense_3 entry: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
fis = satIOContext->pFis;
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART_READ_LOG;
fis->h.features = 0xD5;
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 = &satLogSenseCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
GLOBAL bit32 satLogSense_2(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
TI_DBG4(("satLogSense_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
fis = satIOContext->pFis;
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 = &satLogSenseCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
GLOBAL bit32 satLogSenseAllocate(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext,
bit32 payloadSize,
bit32 flag
)
{
satDeviceData_t *pSatDevData;
tdIORequestBody_t *tdIORequestBody;
satInternalIo_t *satIntIo = agNULL;
satIOContext_t *satIOContext2;
bit32 status;
TI_DBG4(("satLogSense_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
pSatDevData = satIOContext->pSatDevData;
satIntIo = satAllocIntIoResource( tiRoot,
tiIORequest,
pSatDevData,
payloadSize,
satIntIo);
if (satIntIo == agNULL)
{
satFreeIntIoResource( tiRoot,
pSatDevData,
satIntIo);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOFailed,
tiDetailOtherError,
agNULL,
satIOContext->interruptContext );
TI_DBG4(("satLogSense_2: fail in allocation\n"));
return tiSuccess;
}
satIntIo->satOrgTiIORequest = tiIORequest;
tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext);
satIOContext2->pSatDevData = pSatDevData;
satIOContext2->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
satIOContext2->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
satIOContext2->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
satIOContext2->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
satIOContext2->pTiSenseData->senseData = satIOContext2->pSense;
satIOContext2->tiRequestBody = satIntIo->satIntRequestBody;
satIOContext2->interruptContext = satIOContext->interruptContext;
satIOContext2->satIntIoContext = satIntIo;
satIOContext2->ptiDeviceHandle = tiDeviceHandle;
satIOContext2->satOrgIOContext = satIOContext;
if (flag == LOG_SENSE_0)
{
status = satSMARTEnable( tiRoot,
&(satIntIo->satIntTiIORequest),
tiDeviceHandle,
&(satIntIo->satIntTiScsiXchg),
satIOContext2);
}
else if (flag == LOG_SENSE_1)
{
status = satLogSense_2( tiRoot,
&(satIntIo->satIntTiIORequest),
tiDeviceHandle,
&(satIntIo->satIntTiScsiXchg),
satIOContext2);
}
else
{
status = satLogSense_3( tiRoot,
&(satIntIo->satIntTiIORequest),
tiDeviceHandle,
&(satIntIo->satIntTiScsiXchg),
satIOContext2);
}
if (status != tiSuccess)
{
satFreeIntIoResource( tiRoot,
pSatDevData,
satIntIo);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOFailed,
tiDetailOtherError,
agNULL,
satIOContext->interruptContext );
return tiSuccess;
}
return tiSuccess;
}
GLOBAL bit32 satLogSense(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_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 = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr;
TI_DBG5(("satLogSense: start\n"));
osti_memset(&AllLogPages, 0, 8);
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG2(("satLogSense: return control\n"));
return tiSuccess;
}
AllocLen = (bit8)((scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]);
if (AllocLen == 4)
{
TI_DBG1(("satLogSense: AllocLen is 4\n"));
switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
{
case LOGSENSE_SUPPORTED_LOG_PAGES:
TI_DBG5(("satLogSense: 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:
TI_DBG1(("satLogSense: error unallowed flag value %d\n", flag));
break;
}
osti_memcpy(pLogPage, &AllLogPages, lenRead);
break;
case LOGSENSE_SELFTEST_RESULTS_PAGE:
TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
lenRead = 4;
AllLogPages[0] = LOGSENSE_SELFTEST_RESULTS_PAGE;
AllLogPages[1] = 0;
AllLogPages[2] = 0x01;
AllLogPages[3] = 0x90;
osti_memcpy(pLogPage, &AllLogPages, lenRead);
break;
case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
TI_DBG5(("satLogSense: 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;
osti_memcpy(pLogPage, &AllLogPages, lenRead);
break;
default:
TI_DBG1(("satLogSense: default Page Code 0x%x\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return tiSuccess;
}
switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
{
case LOGSENSE_SUPPORTED_LOG_PAGES:
TI_DBG5(("satLogSense: 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:
TI_DBG1(("satLogSense: error unallowed flag value %d\n", flag));
break;
}
osti_memcpy(pLogPage, &AllLogPages, lenRead);
if (AllocLen > lenRead )
{
TI_DBG1(("satLogSense reporting underrun lenRead=0x%x AllocLen=0x%x tiIORequest=%p\n", lenRead, AllocLen, tiIORequest));
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOUnderRun,
AllocLen - lenRead,
agNULL,
satIOContext->interruptContext );
}
else
{
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
}
break;
case LOGSENSE_SELFTEST_RESULTS_PAGE:
TI_DBG5(("satLogSense: case 2\n"));
if (pSatDevData->satSMARTSelfTest == agFALSE)
{
TI_DBG5(("satLogSense: case 2 no SMART Self Test\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
}
else
{
if (pSatDevData->satSMARTEnabled == agFALSE)
{
TI_DBG5(("satLogSense: case 2 calling satSMARTEnable\n"));
status = satLogSenseAllocate(tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext,
0,
LOG_SENSE_0
);
return status;
}
else
{
if ( pSatDevData->sat48BitSupport == agTRUE )
{
TI_DBG5(("satLogSense: case 2-1 sends READ LOG EXT\n"));
status = satLogSenseAllocate(tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext,
512,
LOG_SENSE_1
);
return status;
}
else
{
TI_DBG5(("satLogSense: case 2-2 sends SMART READ LOG\n"));
status = satLogSenseAllocate(tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext,
512,
LOG_SENSE_2
);
return status;
}
}
}
break;
case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
TI_DBG5(("satLogSense: case 3\n"));
if (pSatDevData->satSMARTFeatureSet == agFALSE)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
}
else
{
if (pSatDevData->satSMARTEnabled == agFALSE)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ABORTED_COMMAND,
0,
SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
}
else
{
TI_DBG5(("satLogSense: case 3 sends SMART RETURN STATUS\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART_RETURN_STATUS;
fis->h.features = 0xDA;
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 = &satLogSenseCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
}
break;
default:
TI_DBG1(("satLogSense: default Page Code 0x%x\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
break;
}
return tiSuccess;
}
GLOBAL bit32 satModeSelect6(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit8 *pLogPage;
bit32 StartingIndex = 0;
bit8 PageCode = 0;
bit32 chkCnd = agFALSE;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr;
TI_DBG5(("satModeSelect6: start\n"));
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG2(("satModeSelect6: return control\n"));
return tiSuccess;
}
if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT6_PF_MASK))
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satModeSelect6: PF bit check \n"));
return tiSuccess;
}
if (pLogPage[3] == 8)
{
PageCode = (bit8)(pLogPage[12] & 0x3F);
StartingIndex = 12;
}
else if (pLogPage[3] == 0)
{
PageCode = (bit8)(pLogPage[4] & 0x3F);
StartingIndex = 4;
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return tiSuccess;
}
else
{
TI_DBG1(("satModeSelect6: return mode parameter block descriptor 0x%x\n", pLogPage[3]));
satSetSensePayload( pSense,
SCSI_SNSKEY_NO_SENSE,
0,
SCSI_SNSCODE_NO_ADDITIONAL_INFO,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
switch (PageCode)
{
case MODESELECT_CONTROL_PAGE:
TI_DBG1(("satModeSelect6: 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)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satModeSelect10: unexpected values\n"));
}
else
{
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
}
return tiSuccess;
break;
case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
TI_DBG1(("satModeSelect6: 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])
)
{
TI_DBG5(("satModeSelect6: return check condition \n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
else
{
TI_DBG5(("satModeSelect6: return GOOD \n"));
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return tiSuccess;
}
break;
case MODESELECT_CACHING:
TI_DBG5(("satModeSelect6: 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])
)
{
TI_DBG1(("satModeSelect6: return check condition \n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
else
{
if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_WCE_MASK) )
{
TI_DBG5(("satModeSelect6: 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 = &satModeSelect6n10CB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
else
{
TI_DBG5(("satModeSelect6: 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 = &satModeSelect6n10CB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
}
break;
case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
TI_DBG5(("satModeSelect6: Informational Exception Control mode page\n"));
if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PERF_MASK) ||
(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_TEST_MASK)
)
{
TI_DBG1(("satModeSelect6: return check condition \n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
else
{
if ( !(pLogPage[StartingIndex + 2] & 0x08) )
{
TI_DBG5(("satModeSelect6: enable information exceptions reporting\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART_ENABLE_OPERATIONS;
fis->h.features = 0xD8;
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 = &satModeSelect6n10CB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
else
{
TI_DBG5(("satModeSelect6: disable information exceptions reporting\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART_DISABLE_OPERATIONS;
fis->h.features = 0xD9;
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 = &satModeSelect6n10CB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
}
break;
default:
TI_DBG1(("satModeSelect6: Error unknown page code 0x%x\n", pLogPage[12]));
satSetSensePayload( pSense,
SCSI_SNSKEY_NO_SENSE,
0,
SCSI_SNSCODE_NO_ADDITIONAL_INFO,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
}
GLOBAL bit32 satModeSelect6n10_1(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
bit8 *pLogPage;
bit32 StartingIndex = 0;
fis = satIOContext->pFis;
pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr;
TI_DBG5(("satModeSelect6_1: start\n"));
if (pLogPage[3] == 8)
{
StartingIndex = 12;
}
else
{
StartingIndex = 4;
}
if ( !(pLogPage[StartingIndex + 12] & SCSI_MODE_SELECT6_DRA_MASK) )
{
TI_DBG5(("satModeSelect6_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 = &satModeSelect6n10CB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
else
{
TI_DBG5(("satModeSelect6_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 = &satModeSelect6n10CB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
}
GLOBAL bit32 satModeSelect10(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit8 *pLogPage;
bit16 BlkDescLen = 0;
bit32 StartingIndex = 0;
bit8 PageCode = 0;
bit32 chkCnd = agFALSE;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr;
TI_DBG5(("satModeSelect10: start\n"));
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG2(("satModeSelect10: return control\n"));
return tiSuccess;
}
if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT10_PF_MASK))
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satModeSelect10: PF bit check \n"));
return tiSuccess;
}
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;
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return tiSuccess;
}
else
{
TI_DBG1(("satModeSelect10: return mode parameter block descriptor 0x%x\n", BlkDescLen));
satSetSensePayload( pSense,
SCSI_SNSKEY_NO_SENSE,
0,
SCSI_SNSCODE_NO_ADDITIONAL_INFO,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
if (StartingIndex == 8)
{
tdhexdump("startingindex 8", (bit8 *)pLogPage, 8);
}
else if(StartingIndex == 16)
{
if (PageCode == MODESELECT_CACHING)
{
tdhexdump("startingindex 16", (bit8 *)pLogPage, 16+20);
}
else
{
tdhexdump("startingindex 16", (bit8 *)pLogPage, 16+12);
}
}
else
{
if (PageCode == MODESELECT_CACHING)
{
tdhexdump("startingindex 24", (bit8 *)pLogPage, 24+20);
}
else
{
tdhexdump("startingindex 24", (bit8 *)pLogPage, 24+12);
}
}
switch (PageCode)
{
case MODESELECT_CONTROL_PAGE:
TI_DBG5(("satModeSelect10: 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)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satModeSelect10: unexpected values\n"));
}
else
{
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
}
return tiSuccess;
break;
case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
TI_DBG5(("satModeSelect10: 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])
)
{
TI_DBG1(("satModeSelect10: return check condition \n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
else
{
TI_DBG2(("satModeSelect10: return GOOD \n"));
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return tiSuccess;
}
break;
case MODESELECT_CACHING:
TI_DBG5(("satModeSelect10: 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])
)
{
TI_DBG1(("satModeSelect10: return check condition \n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
else
{
if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_WCE_MASK) )
{
TI_DBG5(("satModeSelect10: 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 = &satModeSelect6n10CB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
else
{
TI_DBG5(("satModeSelect10: 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 = &satModeSelect6n10CB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
}
break;
case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
TI_DBG5(("satModeSelect10: Informational Exception Control mode page\n"));
if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PERF_MASK) ||
(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_TEST_MASK)
)
{
TI_DBG1(("satModeSelect10: return check condition \n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
else
{
if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DEXCPT_MASK) )
{
TI_DBG5(("satModeSelect10: enable information exceptions reporting\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART_ENABLE_OPERATIONS;
fis->h.features = 0xD8;
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 = &satModeSelect6n10CB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
else
{
TI_DBG5(("satModeSelect10: disable information exceptions reporting\n"));
fis->h.fisType = 0x27;
fis->h.c_pmPort = 0x80;
fis->h.command = SAT_SMART_DISABLE_OPERATIONS;
fis->h.features = 0xD9;
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 = &satModeSelect6n10CB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
}
break;
default:
TI_DBG1(("satModeSelect10: Error unknown page code 0x%x\n", pLogPage[12]));
satSetSensePayload( pSense,
SCSI_SNSKEY_NO_SENSE,
0,
SCSI_SNSCODE_NO_ADDITIONAL_INFO,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
}
GLOBAL bit32 satSynchronizeCache10(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG5(("satSynchronizeCache10: start\n"));
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG2(("satSynchronizeCache10: return control\n"));
return tiSuccess;
}
if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
{
TI_DBG1(("satSynchronizeCache10: GOOD status due to IMMED bit\n"));
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
TI_DBG5(("satSynchronizeCache10: 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
{
TI_DBG5(("satSynchronizeCache10: 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 = &satSynchronizeCache10n16CB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return (status);
}
GLOBAL bit32 satSynchronizeCache16(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG5(("satSynchronizeCache16: start\n"));
if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satSynchronizeCache16: return control\n"));
return tiSuccess;
}
if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
{
TI_DBG1(("satSynchronizeCache16: GOOD status due to IMMED bit\n"));
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
}
if (pSatDevData->sat48BitSupport == agTRUE)
{
TI_DBG5(("satSynchronizeCache16: 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
{
TI_DBG5(("satSynchronizeCache16: 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 = &satSynchronizeCache10n16CB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return (status);
}
GLOBAL bit32 satWriteAndVerify10(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[4];
bit8 TL[4];
bit32 rangeChk = agFALSE;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG5(("satWriteAndVerify10: start\n"));
if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWriteAndVerify10: BYTCHK bit checking \n"));
return tiSuccess;
}
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWriteAndVerify10: return control\n"));
return tiSuccess;
}
osti_memset(LBA, 0, sizeof(LBA));
osti_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] = 0;
TL[1] = 0;
TL[2] = scsiCmnd->cdb[7];
TL[3] = scsiCmnd->cdb[8];
rangeChk = satAddNComparebit32(LBA, TL);
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)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWriteAndVerify10: return LBA out of range\n"));
return tiSuccess;
}
if (rangeChk)
{
TI_DBG1(("satWrite10: return LBA+TL out of range, not EXT\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
}
if (!rangeChk)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
TI_DBG5(("satWriteAndVerify10: 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
{
TI_DBG5(("satWriteAndVerify10: 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)
{
TI_DBG5(("satWriteAndVerify10: 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
{
TI_DBG5(("satWriteAndVerify10: 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)
{
TI_DBG5(("satWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support \n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
TI_DBG5(("satWriteAndVerify10: 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 = satComputeLoopNum(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 = satComputeLoopNum(tl, 0xFFFF);
}
else
{
LoopNum = satComputeLoopNum(tl, 0xFFFF);
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
TI_DBG5(("satWriteAndVerify10: NON CHAINED data\n"));
satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
}
else
{
TI_DBG1(("satWriteAndVerify10: 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 = &satChainedWriteNVerifyCB;
}
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return (status);
}
#ifdef REMOVED
GLOBAL bit32 satWriteAndVerify10(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit32 tl = 0;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG5(("satWriteAndVerify10: start\n"));
if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWriteAndVerify10: BYTCHK bit checking \n"));
return tiSuccess;
}
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG2(("satWriteAndVerify10: return control\n"));
return tiSuccess;
}
if ( pSatDevData->sat48BitSupport != agTRUE )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWriteAndVerify10: return internal checking\n"));
return tiSuccess;
}
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)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWriteAndVerify10: return LBA out of range\n"));
return tiSuccess;
}
}
if (lba + tl <= SAT_TR_LBA_LIMIT)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
TI_DBG5(("satWriteAndVerify10: 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 = (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
{
TI_DBG5(("satWriteAndVerify10: 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 = (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)
{
TI_DBG5(("satWriteAndVerify10: 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;
}
else
{
TI_DBG5(("satWriteAndVerify10: 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;
}
}
if (pSatDevData->satNCQ == agTRUE)
{
if (pSatDevData->sat48BitSupport != agTRUE)
{
TI_DBG5(("satWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support \n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
TI_DBG5(("satWriteAndVerify10: 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->satCompleteCB = &satWriteAndVerify10CB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return (status);
}
#endif
#ifdef REMOVED
GLOBAL bit32 satWriteAndVerify10_1(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG5(("satWriteAndVerify10_1: 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 = &satWriteAndVerify10CB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG1(("satWriteAndVerify10_1: return status %d\n", status));
return (status);
}
else
{
TI_DBG1(("satWriteAndVerify10_1: can't fit in SAT_READ_VERIFY_SECTORS\n"));
return tiError;
}
return tiSuccess;
}
#endif
GLOBAL bit32 satWriteAndVerify12(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[4];
bit8 TL[4];
bit32 rangeChk = agFALSE;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG5(("satWriteAndVerify12: start\n"));
if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWriteAndVerify12: BYTCHK bit checking \n"));
return tiSuccess;
}
if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG2(("satWriteAndVerify12: return control\n"));
return tiSuccess;
}
osti_memset(LBA, 0, sizeof(LBA));
osti_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];
rangeChk = satAddNComparebit32(LBA, TL);
lba = satComputeCDB12LBA(satIOContext);
tl = satComputeCDB12TL(satIOContext);
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
if (lba > SAT_TR_LBA_LIMIT - 1)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWriteAndVerify12: return LBA out of range, not EXT\n"));
return tiSuccess;
}
if (rangeChk)
{
TI_DBG1(("satWriteAndVerify12: return LBA+TL out of range, not EXT\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
}
if (!rangeChk)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
TI_DBG5(("satWriteAndVerify12: 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
{
TI_DBG5(("satWriteAndVerify12: 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)
{
TI_DBG5(("satWriteAndVerify12: 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
{
TI_DBG5(("satWriteAndVerify12: 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)
{
TI_DBG5(("satWriteAndVerify12: case 5 !!! error NCQ but 28 bit address support \n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
TI_DBG6(("satWriteAndVerify12: 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 = satComputeLoopNum(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 = satComputeLoopNum(tl, 0xFFFF);
}
else
{
LoopNum = satComputeLoopNum(tl, 0xFFFF);
}
satIOContext->LoopNum = LoopNum;
satIOContext->LoopNum2 = LoopNum;
if (LoopNum == 1)
{
TI_DBG5(("satWriteAndVerify12: NON CHAINED data\n"));
satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
}
else
{
TI_DBG1(("satWriteAndVerify12: 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 = &satChainedWriteNVerifyCB;
}
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return (status);
}
GLOBAL bit32 satNonChainedWriteNVerify_Verify(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satDeviceData_t *pSatDevData;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG5(("satNonChainedWriteNVerify_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 = &satNonChainedWriteNVerifyCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG1(("satNonChainedWriteNVerify_Verify: return status %d\n", status));
return (status);
}
else
{
TI_DBG1(("satNonChainedWriteNVerify_Verify: can't fit in SAT_READ_VERIFY_SECTORS\n"));
return tiError;
}
}
GLOBAL bit32 satChainedWriteNVerify_Write(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
satIOContext_t *satOrgIOContext = agNULL;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
bit32 lba = 0;
bit32 DenomTL = 0xFF;
bit32 Remainder = 0;
bit8 LBA[4];
TI_DBG1(("satChainedWriteNVerify_Write: start\n"));
fis = satIOContext->pFis;
satOrgIOContext = satIOContext->satOrgIOContext;
scsiCmnd = satOrgIOContext->pScsiCmnd;
osti_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:
TI_DBG1(("satChainedWriteNVerify_Write: 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_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:
TI_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
return tiError;
break;
}
satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satChainedWriteNVerify_Write: return\n"));
return (status);
}
GLOBAL bit32 satChainedWriteNVerify_Start_Verify(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satDeviceData_t *pSatDevData;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[4];
bit8 TL[4];
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG5(("satChainedWriteNVerify_Start_Verify: start\n"));
osti_memset(LBA, 0, sizeof(LBA));
osti_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 = satComputeCDB12LBA(satIOContext);
tl = satComputeCDB12TL(satIOContext);
if (pSatDevData->sat48BitSupport == agTRUE)
{
TI_DBG5(("satChainedWriteNVerify_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
{
TI_DBG5(("satChainedWriteNVerify_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 = satComputeLoopNum(tl, 0xFF);
}
else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
{
LoopNum = satComputeLoopNum(tl, 0xFFFF);
}
else
{
TI_DBG1(("satChainedWriteNVerify_Start_Verify: error case 1!!!\n"));
LoopNum = 1;
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
TI_DBG5(("satChainedWriteNVerify_Start_Verify: NON CHAINED data\n"));
satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
}
else
{
TI_DBG1(("satChainedWriteNVerify_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
{
TI_DBG1(("satChainedWriteNVerify_Start_Verify: error case 2!!!\n"));
}
satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
}
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return (status);
}
GLOBAL bit32 satChainedWriteNVerify_Verify(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
satIOContext_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];
TI_DBG2(("satChainedWriteNVerify_Verify: start\n"));
fis = satIOContext->pFis;
satOrgIOContext = satIOContext->satOrgIOContext;
osti_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:
TI_DBG1(("satChainedWriteNVerify_Verify: 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:
TI_DBG1(("satChainedWriteNVerify_Verify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
return tiError;
break;
}
satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satChainedWriteNVerify_Verify: return\n"));
return (status);
}
GLOBAL bit32 satWriteAndVerify16(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 lba = 0;
bit32 tl = 0;
bit32 LoopNum = 1;
bit8 LBA[8];
bit8 TL[8];
bit32 rangeChk = agFALSE;
bit32 limitChk = agFALSE;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
TI_DBG5(("satWriteAndVerify16:start\n"));
if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWriteAndVerify16: BYTCHK bit checking \n"));
return tiSuccess;
}
if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG2(("satWriteAndVerify16: return control\n"));
return tiSuccess;
}
osti_memset(LBA, 0, sizeof(LBA));
osti_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];
rangeChk = satAddNComparebit64(LBA, TL);
limitChk = satCompareLBALimitbit(LBA);
lba = satComputeCDB16LBA(satIOContext);
tl = satComputeCDB16TL(satIOContext);
if (pSatDevData->satNCQ != agTRUE &&
pSatDevData->sat48BitSupport != agTRUE
)
{
if (limitChk)
{
TI_DBG1(("satWriteAndVerify16: return LBA out of range, not EXT\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
if (rangeChk)
{
TI_DBG1(("satWriteAndVerify16: return LBA+TL out of range, not EXT\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
}
if (!rangeChk)
{
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
TI_DBG5(("satWriteAndVerify16: 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
{
TI_DBG5(("satWriteAndVerify16: 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)
{
TI_DBG5(("satWriteAndVerify16: 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
{
TI_DBG5(("satWriteAndVerify16: 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)
{
TI_DBG5(("satWriteAndVerify16: case 5 !!! error NCQ but 28 bit address support \n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
TI_DBG6(("satWriteAndVerify16: 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 = satComputeLoopNum(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 = satComputeLoopNum(tl, 0xFFFF);
}
else
{
LoopNum = satComputeLoopNum(tl, 0xFFFF);
}
satIOContext->LoopNum = LoopNum;
if (LoopNum == 1)
{
TI_DBG5(("satWriteAndVerify16: NON CHAINED data\n"));
satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
}
else
{
TI_DBG1(("satWriteAndVerify16: 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 = &satChainedWriteNVerifyCB;
}
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return (status);
}
GLOBAL bit32 satReadMediaSerialNumber(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
agsaSATAIdentifyData_t *pSATAIdData;
bit8 *pSerialNumber;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
pSATAIdData = &(pSatDevData->satIdentifyData);
pSerialNumber = (bit8 *) tiScsiRequest->sglVirtualAddr;
TI_DBG1(("satReadMediaSerialNumber: start\n"));
if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satReadMediaSerialNumber: return control\n"));
return tiSuccess;
}
if (tiScsiRequest->scsiCmnd.expDataLength == 4)
{
if (pSATAIdData->commandSetFeatureDefault & 0x4)
{
TI_DBG1(("satReadMediaSerialNumber: Media serial number returning only length\n"));
pSerialNumber[0] = 0;
pSerialNumber[1] = 0;
pSerialNumber[2] = 0;
pSerialNumber[3] = 0x3C;
}
else
{
pSerialNumber[0] = 0;
pSerialNumber[1] = 0;
pSerialNumber[2] = 0x1;
pSerialNumber[3] = 0xfc;
}
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return tiSuccess;
}
if ( pSatDevData->IDDeviceValid == agTRUE)
{
if (pSATAIdData->commandSetFeatureDefault & 0x4)
{
tdhexdump("ID satReadMediaSerialNumber", (bit8*)pSATAIdData->currentMediaSerialNumber, 2*30);
pSerialNumber[0] = 0;
pSerialNumber[1] = 0;
pSerialNumber[2] = 0;
pSerialNumber[3] = 0x3C;
osti_memcpy(&pSerialNumber[4], (void *)pSATAIdData->currentMediaSerialNumber, 60);
tdhexdump("satReadMediaSerialNumber", (bit8*)pSerialNumber, 2*30 + 4);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return tiSuccess;
}
else
{
TI_DBG1(("satReadMediaSerialNumber: 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 = &satReadMediaSerialNumberCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
}
else
{
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOFailed,
tiDetailOtherError,
agNULL,
satIOContext->interruptContext);
return tiSuccess;
}
}
GLOBAL bit32 satReadBuffer(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status = tiSuccess;
bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit32 bufferOffset;
bit32 tl;
bit8 mode;
bit8 bufferID;
bit8 *pBuff;
pSense = satIOContext->pSense;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
pBuff = (bit8 *) tiScsiRequest->sglVirtualAddr;
TI_DBG2(("satReadBuffer: start\n"));
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satReadBuffer: return control\n"));
return tiSuccess;
}
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 = &satReadBufferCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
if (bufferID == 0 && bufferOffset == 0 && tl != 512)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satReadBuffer: allocation length is not 512; it is %d\n", tl));
return tiSuccess;
}
if (bufferID == 0 && bufferOffset != 0)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satReadBuffer: buffer offset is not 0; it is %d\n", bufferOffset));
return tiSuccess;
}
TI_DBG1(("satReadBuffer: unsupported case 1\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
else if (mode == READ_BUFFER_DESCRIPTOR_MODE)
{
if (tl < READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satReadBuffer: tl < 4; tl is %d\n", tl));
return tiSuccess;
}
if (bufferID == 0)
{
pBuff[0] = 0xFF;
pBuff[1] = 0x00;
pBuff[2] = 0x02;
pBuff[3] = 0x00;
if (READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN < tl)
{
TI_DBG1(("satReadBuffer: underrun tl %d data %d\n", tl, READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN));
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOUnderRun,
tl - READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN,
agNULL,
satIOContext->interruptContext );
return tiSuccess;
}
else
{
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return tiSuccess;
}
}
else
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
}
else
{
TI_DBG1(("satReadBuffer: unsupported mode %d\n", mode));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
}
GLOBAL bit32 satWriteBuffer(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
#ifdef NOT_YET
bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
#endif
scsiRspSense_t *pSense;
tiIniScsiCmnd_t *scsiCmnd;
bit32 bufferOffset;
bit32 parmLen;
bit8 mode;
bit8 bufferID;
bit8 *pBuff;
pSense = satIOContext->pSense;
scsiCmnd = &tiScsiRequest->scsiCmnd;
pBuff = (bit8 *) tiScsiRequest->sglVirtualAddr;
TI_DBG2(("satWriteBuffer: start\n"));
if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWriteBuffer: return control\n"));
return tiSuccess;
}
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];
tdhexdump("satWriteBuffer pBuff", (bit8 *)pBuff, 24);
if (mode == WRITE_BUFFER_DATA_MODE)
{
if (bufferID == 0 && bufferOffset == 0 && parmLen == 512)
{
TI_DBG1(("satWriteBuffer: 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 = &satWriteBufferCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
#endif
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_GOOD,
agNULL,
satIOContext->interruptContext);
return tiSuccess;
}
if ( (bufferID == 0 && bufferOffset != 0) ||
(bufferID == 0 && parmLen != 512)
)
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satWriteBuffer: wrong buffer offset %d or parameter length parmLen %d\n", bufferOffset, parmLen));
return tiSuccess;
}
TI_DBG1(("satWriteBuffer: unsupported case 1\n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
else if (mode == WRITE_BUFFER_DL_MICROCODE_SAVE_MODE)
{
TI_DBG1(("satWriteBuffer: not yet supported mode %d\n", mode));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
else
{
TI_DBG1(("satWriteBuffer: unsupported mode %d\n", mode));
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_COMMAND,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
}
GLOBAL bit32 satReassignBlocks(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
tiIniScsiCmnd_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 = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
pParmList = (bit8 *) tiScsiRequest->sglVirtualAddr;
TI_DBG5(("satReassignBlocks: start\n"));
if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_ILLEGAL_REQUEST,
0,
SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
TI_DBG1(("satReassignBlocks: return control\n"));
return tiSuccess;
}
osti_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);
osti_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;
}
tdhexdump("satReassignBlocks 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;
}
osti_memcpy(satIOContext->LBA, LBA, 8);
satIOContext->ParmIndex = startingIndex;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &satReassignBlocksCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return status;
}
GLOBAL bit32 satReassignBlocks_1(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext,
satIOContext_t *satOrgIOContext
)
{
bit32 agRequestType;
satDeviceData_t *pSatDevData;
tiIniScsiCmnd_t *scsiCmnd;
agsaFisRegHostToDevice_t *fis;
bit8 *pParmList;
bit8 LongLBA;
bit8 LBA[8];
bit32 startingIndex;
pSatDevData = satIOContext->pSatDevData;
scsiCmnd = &tiScsiRequest->scsiCmnd;
fis = satIOContext->pFis;
pParmList = (bit8 *) tiScsiRequest->sglVirtualAddr;
TI_DBG5(("satReassignBlocks_1: start\n"));
LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
osti_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;
}
osti_memcpy(satOrgIOContext->LBA, LBA, 8);
satOrgIOContext->ParmIndex = startingIndex;
agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
satIOContext->satCompleteCB = &satReassignBlocksCB;
satIOContext->reqType = agRequestType;
sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext );
return tiSuccess;
}
GLOBAL bit32 satReassignBlocks_2(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext,
bit8 *LBA
)
{
bit32 status;
bit32 agRequestType;
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
agsaFisRegHostToDevice_t *fis;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
fis = satIOContext->pFis;
if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
{
TI_DBG5(("satReassignBlocks_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
{
TI_DBG5(("satReassignBlocks_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)
{
TI_DBG5(("satReassignBlocks_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
{
TI_DBG5(("satReassignBlocks_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)
{
TI_DBG5(("satReassignBlocks_2: case 5 !!! error NCQ but 28 bit address support \n"));
satSetSensePayload( pSense,
SCSI_SNSKEY_HARDWARE_ERROR,
0,
SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
satIOContext->interruptContext );
return tiSuccess;
}
TI_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 = &satReassignBlocksCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
return (status);
}
GLOBAL satIOContext_t *satPrepareNewIO(
satInternalIo_t *satNewIntIo,
tiIORequest_t *tiOrgIORequest,
satDeviceData_t *satDevData,
tiIniScsiCmnd_t *scsiCmnd,
satIOContext_t *satOrgIOContext
)
{
satIOContext_t *satNewIOContext;
tdIORequestBody_t *tdNewIORequestBody;
TI_DBG2(("satPrepareNewIO: start\n"));
satNewIntIo->satOrgTiIORequest = tiOrgIORequest;
tdNewIORequestBody = (tdIORequestBody_t *)satNewIntIo->satIntRequestBody;
satNewIOContext = &(tdNewIORequestBody->transport.SATA.satIOContext);
satNewIOContext->pSatDevData = satDevData;
satNewIOContext->pFis = &(tdNewIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
satNewIOContext->pScsiCmnd = &(satNewIntIo->satIntTiScsiXchg.scsiCmnd);
if (scsiCmnd != agNULL)
{
osti_memcpy(satNewIOContext->pScsiCmnd->cdb, scsiCmnd->cdb, 16);
}
satNewIOContext->pSense = &(tdNewIORequestBody->transport.SATA.sensePayload);
satNewIOContext->pTiSenseData = &(tdNewIORequestBody->transport.SATA.tiSenseData);
satNewIOContext->pTiSenseData->senseData = satNewIOContext->pSense;
satNewIOContext->tiRequestBody = satNewIntIo->satIntRequestBody;
satNewIOContext->interruptContext = satNewIOContext->interruptContext;
satNewIOContext->satIntIoContext = satNewIntIo;
satNewIOContext->ptiDeviceHandle = satOrgIOContext->ptiDeviceHandle;
satNewIOContext->satOrgIOContext = satOrgIOContext;
satNewIOContext->tiScsiXchg = satOrgIOContext->tiScsiXchg;
return satNewIOContext;
}
GLOBAL bit32 satIOAbort(
tiRoot_t *tiRoot,
tiIORequest_t *taskTag )
{
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
agsaRoot_t *agRoot;
tdIORequestBody_t *tdIORequestBody;
tdIORequestBody_t *tdIONewRequestBody;
agsaIORequest_t *agIORequest;
bit32 status;
agsaIORequest_t *agAbortIORequest;
tdIORequestBody_t *tdAbortIORequestBody;
bit32 PhysUpper32;
bit32 PhysLower32;
bit32 memAllocStatus;
void *osMemHandle;
satIOContext_t *satIOContext;
satInternalIo_t *satIntIo;
TI_DBG2(("satIOAbort: start\n"));
agRoot = &(tdsaAllShared->agRootNonInt);
tdIORequestBody = (tdIORequestBody_t *)taskTag->tdData;
satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
satIntIo = satIOContext->satIntIoContext;
if (satIntIo == agNULL)
{
TI_DBG1(("satIOAbort: External, OS generated\n"));
agIORequest = &(tdIORequestBody->agIORequest);
}
else
{
TI_DBG1(("satIOAbort: Internal, TD generated\n"));
tdIONewRequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
agIORequest = &(tdIONewRequestBody->agIORequest);
}
memAllocStatus = ostiAllocMemory(
tiRoot,
&osMemHandle,
(void **)&tdAbortIORequestBody,
&PhysUpper32,
&PhysLower32,
8,
sizeof(tdIORequestBody_t),
agTRUE
);
if (memAllocStatus != tiSuccess)
{
TI_DBG1(("satIOAbort: ostiAllocMemory failed...\n"));
return tiError;
}
if (tdAbortIORequestBody == agNULL)
{
TI_DBG1(("satIOAbort: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
return tiError;
}
tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
tdAbortIORequestBody->tiDevHandle = tdIORequestBody->tiDevHandle;
agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
agAbortIORequest->osData = (void *) tdAbortIORequestBody;
agAbortIORequest->sdkData = agNULL;
tdAbortIORequestBody->tiIOToBeAbortedRequest = taskTag;
status = saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agIORequest, agNULL );
TI_DBG5(("satIOAbort: return status=0x%x\n", status));
if (status == AGSA_RC_SUCCESS)
return tiSuccess;
else
return tiError;
}
osGLOBAL bit32 satTM(
tiRoot_t *tiRoot,
tiDeviceHandle_t *tiDeviceHandle,
bit32 task,
tiLUN_t *lun,
tiIORequest_t *taskTag,
tiIORequest_t *currentTaskTag,
tdIORequestBody_t *tiRequestBody,
bit32 NotifyOS
)
{
tdIORequestBody_t *tdIORequestBody = agNULL;
satIOContext_t *satIOContext = agNULL;
tdsaDeviceData_t *oneDeviceData = agNULL;
bit32 status;
TI_DBG3(("satTM: tiDeviceHandle=%p task=0x%x\n", tiDeviceHandle, task ));
oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
satIOContext->pSatDevData = &oneDeviceData->satDevData;
satIOContext->pFis =
&tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
satIOContext->tiRequestBody = tiRequestBody;
satIOContext->ptiDeviceHandle = tiDeviceHandle;
satIOContext->satIntIoContext = agNULL;
satIOContext->satOrgIOContext = agNULL;
satIOContext->currentLBA = 0;
satIOContext->OrgTL = 0;
satIOContext->TMF = task;
satIOContext->satToBeAbortedIOContext = agNULL;
if (NotifyOS == agTRUE)
{
satIOContext->NotifyOS = agTRUE;
}
else
{
satIOContext->NotifyOS = agFALSE;
}
if (task == AG_LOGICAL_UNIT_RESET)
{
status = satTmResetLUN( tiRoot,
currentTaskTag,
tiDeviceHandle,
agNULL,
satIOContext,
lun);
return status;
}
#ifdef TO_BE_REMOVED
else if (task == AG_TARGET_WARM_RESET)
{
status = satTmWarmReset( tiRoot,
currentTaskTag,
tiDeviceHandle,
agNULL,
satIOContext);
return status;
}
#endif
else if (task == AG_ABORT_TASK)
{
status = satTmAbortTask( tiRoot,
currentTaskTag,
tiDeviceHandle,
agNULL,
satIOContext,
taskTag);
return status;
}
else if (task == TD_INTERNAL_TM_RESET)
{
status = satTDInternalTmReset( tiRoot,
currentTaskTag,
tiDeviceHandle,
agNULL,
satIOContext);
return status;
}
else
{
TI_DBG1(("satTM: tiDeviceHandle=%p UNSUPPORTED TM task=0x%x\n",
tiDeviceHandle, task ));
ostiFreeMemory(
tiRoot,
tiRequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
return tiError;
}
}
osGLOBAL bit32 satTmResetLUN(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext,
tiLUN_t *lun)
{
tdsaDeviceData_t *tdsaDeviceData;
satDeviceData_t *satDevData;
tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
satDevData = &tdsaDeviceData->satDevData;
TI_DBG1(("satTmResetLUN: tiDeviceHandle=%p.\n", tiDeviceHandle ));
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 )
{
TI_DBG1(("satTmResetLUN: *** REJECT *** LUN not zero, tiDeviceHandle=%p\n",
tiDeviceHandle));
return tiError;
}
if (satDevData->satTmTaskTag != agNULL)
{
TI_DBG1(("satTmResetLUN: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
tiDeviceHandle));
return tiError;
}
satDevData->satTmTaskTag = tiIORequest;
satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
satDevData->satAbortAfterReset = agFALSE;
satStartResetDevice(
tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext
);
return tiSuccess;
}
osGLOBAL bit32 satTmWarmReset(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
tdsaDeviceData_t *tdsaDeviceData;
satDeviceData_t *satDevData;
tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
satDevData = &tdsaDeviceData->satDevData;
TI_DBG1(("satTmWarmReset: tiDeviceHandle=%p.\n", tiDeviceHandle ));
if (satDevData->satTmTaskTag != agNULL)
{
TI_DBG1(("satTmWarmReset: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
tiDeviceHandle));
return tiError;
}
satDevData->satTmTaskTag = tiIORequest;
satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
satDevData->satAbortAfterReset = agFALSE;
satStartResetDevice(
tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext
);
return tiSuccess;
}
osGLOBAL bit32 satTDInternalTmReset(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
tdsaDeviceData_t *tdsaDeviceData;
satDeviceData_t *satDevData;
tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
satDevData = &tdsaDeviceData->satDevData;
TI_DBG1(("satTmWarmReset: tiDeviceHandle=%p.\n", tiDeviceHandle ));
if (satDevData->satTmTaskTag != agNULL)
{
TI_DBG1(("satTmWarmReset: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
tiDeviceHandle));
return tiError;
}
satDevData->satTmTaskTag = tiIORequest;
satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
satDevData->satAbortAfterReset = agFALSE;
satStartResetDevice(
tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext
);
return tiSuccess;
}
osGLOBAL bit32 satTmAbortTask(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext,
tiIORequest_t *taskTag)
{
tdsaDeviceData_t *tdsaDeviceData;
satDeviceData_t *satDevData;
satIOContext_t *satTempIOContext = agNULL;
tdIORequestBody_t *tdIORequestBody;
tdIORequestBody_t *TMtdIORequestBody;
tdList_t *elementHdr;
bit32 found = agFALSE;
tiIORequest_t *tiIOReq;
tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
satDevData = &tdsaDeviceData->satDevData;
TMtdIORequestBody = (tdIORequestBody_t *)tiIORequest->tdData;
TI_DBG1(("satTmAbortTask: tiDeviceHandle=%p taskTag=%p.\n", tiDeviceHandle, taskTag ));
if (satDevData->satTmTaskTag != agNULL)
{
TI_DBG1(("satTmAbortTask: REJECT other TM pending, tiDeviceHandle=%p\n",
tiDeviceHandle));
ostiFreeMemory(
tiRoot,
TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
return tiError;
}
#ifdef REMOVED
if (satDevData->satPendingIO > 0)
{
TI_DBG1(("satTmAbortTask: REJECT num pending I/O, tiDeviceHandle=%p, satPendingIO=0x%x\n",
tiDeviceHandle, satDevData->satPendingIO));
ostiFreeMemory(
tiRoot,
TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
return tiError;
}
#endif
elementHdr = satDevData->satIoLinkList.flink;
while (elementHdr != &satDevData->satIoLinkList)
{
satTempIOContext = TDLIST_OBJECT_BASE( satIOContext_t,
satIoContextLink,
elementHdr );
tdIORequestBody = (tdIORequestBody_t *) satTempIOContext->tiRequestBody;
tiIOReq = tdIORequestBody->tiIORequest;
elementHdr = elementHdr->flink;
if ( tiIOReq == taskTag)
{
found = agTRUE;
satIOContext->satToBeAbortedIOContext = satTempIOContext;
TI_DBG1(("satTmAbortTask: found matching tag.\n"));
break;
}
}
if (found == agFALSE )
{
TI_DBG1(("satTmAbortTask: *** REJECT *** no match, tiDeviceHandle=%p\n",
tiDeviceHandle ));
ostiFreeMemory(
tiRoot,
TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
return tiError;
}
satDevData->satTmTaskTag = tiIORequest;
satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
satDevData->satAbortAfterReset = agTRUE;
if ( (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
(satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ)
)
{
TI_DBG1(("satTmAbortTask: calling satStartCheckPowerMode\n"));
satStartCheckPowerMode(
tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext
);
}
else
{
TI_DBG1(("satTmAbortTask: calling satStartResetDevice\n"));
satStartResetDevice(
tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext
);
}
return tiSuccess;
}
osGLOBAL void osSatResetCB(
tiRoot_t *tiRoot,
tiDeviceHandle_t *tiDeviceHandle,
bit32 resetStatus,
void *respFis)
{
agsaRoot_t *agRoot;
tdsaDeviceData_t *tdsaDeviceData;
satDeviceData_t *satDevData;
satIOContext_t *satIOContext;
tdIORequestBody_t *tdIORequestBodyTmp;
tdList_t *elementHdr;
agsaIORequest_t *agAbortIORequest;
tdIORequestBody_t *tdAbortIORequestBody;
bit32 PhysUpper32;
bit32 PhysLower32;
bit32 memAllocStatus;
void *osMemHandle;
tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
agRoot = tdsaDeviceData->agRoot;
satDevData = &tdsaDeviceData->satDevData;
TI_DBG5(("osSatResetCB: tiDeviceHandle=%p resetStatus=0x%x\n",
tiDeviceHandle, resetStatus ));
if ( satDevData->satAbortAfterReset == agTRUE )
{
elementHdr = satDevData->satIoLinkList.flink;
while (elementHdr != &satDevData->satIoLinkList)
{
satIOContext = TDLIST_OBJECT_BASE( satIOContext_t,
satIoContextLink,
elementHdr );
tdIORequestBodyTmp = (tdIORequestBody_t *)satIOContext->tiRequestBody;
TI_DBG5(("osSatResetCB: issuing ABORT tiDeviceHandle=%p agIORequest=%p\n",
tiDeviceHandle, &tdIORequestBodyTmp->agIORequest ));
memAllocStatus = ostiAllocMemory(
tiRoot,
&osMemHandle,
(void **)&tdAbortIORequestBody,
&PhysUpper32,
&PhysLower32,
8,
sizeof(tdIORequestBody_t),
agTRUE
);
if (memAllocStatus != tiSuccess)
{
TI_DBG1(("osSatResetCB: ostiAllocMemory failed...\n"));
return;
}
if (tdAbortIORequestBody == agNULL)
{
TI_DBG1(("osSatResetCB: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
return;
}
tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
tdAbortIORequestBody->tiDevHandle = tiDeviceHandle;
agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
agAbortIORequest->osData = (void *) tdAbortIORequestBody;
agAbortIORequest->sdkData = agNULL;
saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, &(tdIORequestBodyTmp->agIORequest), agNULL );
elementHdr = elementHdr->flink;
}
satDevData->satAbortAfterReset = agFALSE;
}
if ( satDevData->satTmTaskTag != agNULL )
{
TI_DBG5(("osSatResetCB: calling TM completion tiDeviceHandle=%p satTmTaskTag=%p\n",
tiDeviceHandle, satDevData->satTmTaskTag ));
ostiInitiatorEvent( tiRoot,
agNULL,
tiDeviceHandle,
tiIntrEventTypeTaskManagement,
tiTMOK,
satDevData->satTmTaskTag);
satDevData->satTmTaskTag = agNULL;
}
}
osGLOBAL void osSatIOCompleted(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
agsaFisHeader_t *agFirstDword,
bit32 respFisLen,
agsaFrameHandle_t agFrameHandle,
satIOContext_t *satIOContext,
bit32 interruptContext)
{
satDeviceData_t *pSatDevData;
scsiRspSense_t *pSense;
#ifdef TD_DEBUG_ENABLE
tiIniScsiCmnd_t *pScsiCmnd;
#endif
agsaFisRegHostToDevice_t *hostToDevFis = agNULL;
bit32 ataStatus = 0;
bit32 ataError;
satInternalIo_t *satIntIo = agNULL;
bit32 status;
tiDeviceHandle_t *tiDeviceHandle;
satIOContext_t *satIOContext2;
tdIORequestBody_t *tdIORequestBody;
agsaFisRegD2HHeader_t *statDevToHostFisHeader = agNULL;
agsaFisSetDevBitsHeader_t *statSetDevBitFisHeader = agNULL;
tiIORequest_t tiIORequestTMP;
pSense = satIOContext->pSense;
pSatDevData = satIOContext->pSatDevData;
#ifdef TD_DEBUG_ENABLE
pScsiCmnd = satIOContext->pScsiCmnd;
#endif
hostToDevFis = satIOContext->pFis;
tiDeviceHandle = &((tdsaDeviceData_t *)(pSatDevData->satSaDeviceData))->tiDeviceHandle;
statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
ataStatus = statDevToHostFisHeader->status;
ataError = statDevToHostFisHeader->error;
TI_DBG1(("osSatIOCompleted: H to D command 0x%x\n", hostToDevFis->h.command));
TI_DBG1(("osSatIOCompleted: D to H fistype 0x%x\n", statDevToHostFisHeader->fisType));
if (statDevToHostFisHeader->fisType == SET_DEV_BITS_FIS)
{
statSetDevBitFisHeader = (agsaFisSetDevBitsHeader_t *)&(agFirstDword->D2H);
ataStatus = (statSetDevBitFisHeader->statusHi_Lo & 0x70);
ataStatus = ataStatus | (statSetDevBitFisHeader->statusHi_Lo & 0x07);
ataError = statSetDevBitFisHeader->error;
statDevToHostFisHeader = agNULL;
}
else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
{
TI_DBG1(("osSatIOCompleted: *** UNEXPECTED RESP FIS TYPE 0x%x *** tiIORequest=%p\n",
statDevToHostFisHeader->fisType, tiIORequest));
satSetSensePayload( pSense,
SCSI_SNSKEY_HARDWARE_ERROR,
0,
SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
interruptContext );
return;
}
if ( ataStatus & DF_ATA_STATUS_MASK )
{
pSatDevData->satDeviceFaultState = agTRUE;
}
else
{
pSatDevData->satDeviceFaultState = agFALSE;
}
TI_DBG5(("osSatIOCompleted: tiIORequest=%p CDB=0x%x ATA CMD =0x%x\n",
tiIORequest, pScsiCmnd->cdb[0], hostToDevFis->h.command));
switch(hostToDevFis->h.command)
{
case SAT_READ_FPDMA_QUEUED:
case SAT_WRITE_FPDMA_QUEUED:
TI_DBG1(("osSatIOCompleted: NCQ ERROR tiIORequest=%p ataStatus=0x%x ataError=0x%x\n",
tiIORequest, ataStatus, ataError ));
pSatDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
osSatDefaultTranslation( tiRoot,
tiIORequest,
satIOContext,
pSense,
(bit8)ataStatus,
(bit8)ataError,
interruptContext );
satIntIo = satAllocIntIoResource( tiRoot,
&(tiIORequestTMP),
pSatDevData,
sizeof (satReadLogExtPage10h_t),
satIntIo);
if (satIntIo == agNULL)
{
TI_DBG1(("osSatIOCompleted: can't send RLE due to resource lack\n"));
pSatDevData->satAbortAfterReset = agTRUE;
#ifdef NOT_YET
satSubTM(tiRoot,
tiDeviceHandle,
TD_INTERNAL_TM_RESET,
agNULL,
agNULL,
agNULL,
agFALSE);
#endif
TI_DBG1(("osSatIOCompleted: calling saSATADeviceReset 1\n"));
return;
}
satIntIo->satIntFlag = AG_SAT_INT_IO_FLAG_ORG_IO_COMPLETED;
tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext);
satIOContext2->pSatDevData = pSatDevData;
satIOContext2->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
satIOContext2->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
satIOContext2->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
satIOContext2->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
satIOContext2->pTiSenseData->senseData = satIOContext2->pSense;
satIOContext2->tiRequestBody = satIntIo->satIntRequestBody;
satIOContext2->interruptContext = interruptContext;
satIOContext2->satIntIoContext = satIntIo;
satIOContext2->ptiDeviceHandle = tiDeviceHandle;
satIOContext2->satOrgIOContext = agNULL;
satIOContext2->tiScsiXchg = agNULL;
status = satSendReadLogExt( tiRoot,
&satIntIo->satIntTiIORequest,
tiDeviceHandle,
&satIntIo->satIntTiScsiXchg,
satIOContext2);
if (status != tiSuccess)
{
TI_DBG1(("osSatIOCompleted: can't send RLE due to LL api failure\n"));
satFreeIntIoResource( tiRoot,
pSatDevData,
satIntIo);
pSatDevData->satAbortAfterReset = agTRUE;
#ifdef NOT_YET
satSubTM(tiRoot,
tiDeviceHandle,
TD_INTERNAL_TM_RESET,
agNULL,
agNULL,
agNULL,
agFALSE);
#endif
TI_DBG1(("osSatIOCompleted: calling saSATADeviceReset 2\n"));
return;
}
break;
case SAT_READ_DMA_EXT:
case SAT_READ_DMA:
default:
osSatDefaultTranslation( tiRoot,
tiIORequest,
satIOContext,
pSense,
(bit8)ataStatus,
(bit8)ataError,
interruptContext );
break;
}
}
GLOBAL void satInquiryStandard(
bit8 *pInquiry,
agsaSATAIdentifyData_t *pSATAIdData,
tiIniScsiCmnd_t *scsiCmnd
)
{
tiLUN_t *pLun;
pLun = &scsiCmnd->lun;
TI_DBG5(("satInquiryStandard: start\n"));
if (pInquiry == agNULL)
{
TI_DBG1(("satInquiryStandard: pInquiry is NULL, wrong\n"));
return;
}
else
{
TI_DBG5(("satInquiryStandard: 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;
}
osti_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] == 0x00 ) &&
(pSATAIdData->firmwareVersion[6] == 0x20 ) &&
(pSATAIdData->firmwareVersion[7] == 0x00 )
)
{
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] == 0x00 ) &&
(pSATAIdData->firmwareVersion[6] == 0x20 ) &&
(pSATAIdData->firmwareVersion[7] == 0x00 )
)
{
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
TI_DBG5(("satInquiryStandard: end\n"));
}
GLOBAL void satInquiryPage0(
bit8 *pInquiry,
agsaSATAIdentifyData_t *pSATAIdData)
{
TI_DBG5(("satInquiryPage0: entry\n"));
pInquiry[0] = 0x00;
pInquiry[1] = 0x00;
pInquiry[2] = 0x00;
pInquiry[3] = 7 - 3;
pInquiry[4] = 0x00;
pInquiry[5] = 0x80;
pInquiry[6] = 0x83;
pInquiry[7] = 0x89;
}
GLOBAL void satInquiryPage83(
bit8 *pInquiry,
agsaSATAIdentifyData_t *pSATAIdData,
satDeviceData_t *pSatDevData)
{
satSimpleSATAIdentifyData_t *pSimpleData;
pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
TI_DBG5(("satInquiryPage83: entry\n"));
pInquiry[0] = 0x00;
pInquiry[1] = 0x83;
pInquiry[2] = 0;
if ( pSatDevData->satWWNSupport)
{
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] = 72;
pInquiry[4] = 0x02;
pInquiry[5] = 0x01;
pInquiry[6] = 0x00;
pInquiry[7] = 0x44;
osti_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);
}
}
GLOBAL void satInquiryPage89(
bit8 *pInquiry,
agsaSATAIdentifyData_t *pSATAIdData,
satDeviceData_t *pSatDevData)
{
satSimpleSATAIdentifyData_t *pSimpleData;
pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
TI_DBG5(("satInquiryPage89: 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;
osti_strncpy((char*)&pInquiry[8], "PMC-SIERRA", 8);
osti_strncpy((char*)&pInquiry[16], "Tachyon-SPC ", 16);
osti_strncpy((char*)&pInquiry[32], "01", 4);
pInquiry[36] = 0x34;
if (pSatDevData->satDeviceType == SATA_ATA_DEVICE)
{
pInquiry[37] = (bit8)((pSatDevData->satPMField) >> (4 * 7));
}
else
{
pInquiry[37] = (bit8)(0x40 + (bit8)(((pSatDevData->satPMField) >> (4 * 7))));
}
pInquiry[38] = 0;
pInquiry[39] = 0;
if (pSatDevData->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 (pSatDevData->satDeviceType == SATA_ATA_DEVICE)
{
pInquiry[56] = 0xEC;
}
else
{
pInquiry[56] = 0xA1;
}
pInquiry[57] = 0x0;
pInquiry[58] = 0x0;
pInquiry[59] = 0x0;
osti_memcpy(&pInquiry[60], pSimpleData, sizeof(satSimpleSATAIdentifyData_t));
return;
}
GLOBAL void satInquiryPage80(
bit8 *pInquiry,
agsaSATAIdentifyData_t *pSATAIdData)
{
TI_DBG5(("satInquiryPage80: entry\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];
}
GLOBAL bit32 satSendReadLogExt(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
fis = satIOContext->pFis;
TI_DBG1(("satSendReadLogExt: tiDeviceHandle=%p tiIORequest=%p\n",
tiDeviceHandle, tiIORequest));
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 = &satReadLogExtCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG1(("satSendReadLogExt: end status %d\n", status));
return (status);
}
GLOBAL void osSatDefaultTranslation(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
satIOContext_t *satIOContext,
scsiRspSense_t *pSense,
bit8 ataStatus,
bit8 ataError,
bit32 interruptContext )
{
if ( ataStatus & DF_ATA_STATUS_MASK )
{
satSetSensePayload( pSense,
SCSI_SNSKEY_HARDWARE_ERROR,
0,
SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
interruptContext );
return;
}
if ( ataStatus & ERR_ATA_STATUS_MASK )
{
if ( ataError & NM_ATA_ERROR_MASK )
{
TI_DBG1(("osSatDefaultTranslation: NM_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
ataError, tiIORequest));
satSetSensePayload( pSense,
SCSI_SNSKEY_NOT_READY,
0,
SCSI_SNSCODE_MEDIUM_NOT_PRESENT,
satIOContext);
}
else if (ataError & UNC_ATA_ERROR_MASK)
{
TI_DBG1(("osSatDefaultTranslation: UNC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
ataError, tiIORequest));
satSetSensePayload( pSense,
SCSI_SNSKEY_MEDIUM_ERROR,
0,
SCSI_SNSCODE_UNRECOVERED_READ_ERROR,
satIOContext);
}
else if (ataError & IDNF_ATA_ERROR_MASK)
{
TI_DBG1(("osSatDefaultTranslation: IDNF_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
ataError, tiIORequest));
satSetSensePayload( pSense,
SCSI_SNSKEY_MEDIUM_ERROR,
0,
SCSI_SNSCODE_RECORD_NOT_FOUND,
satIOContext);
}
else if (ataError & MC_ATA_ERROR_MASK)
{
TI_DBG1(("osSatDefaultTranslation: MC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
ataError, tiIORequest));
satSetSensePayload( pSense,
SCSI_SNSKEY_UNIT_ATTENTION,
0,
SCSI_SNSCODE_NOT_READY_TO_READY_CHANGE,
satIOContext);
}
else if (ataError & MCR_ATA_ERROR_MASK)
{
TI_DBG1(("osSatDefaultTranslation: MCR_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
ataError, tiIORequest));
satSetSensePayload( pSense,
SCSI_SNSKEY_UNIT_ATTENTION,
0,
SCSI_SNSCODE_OPERATOR_MEDIUM_REMOVAL_REQUEST,
satIOContext);
}
else if (ataError & ICRC_ATA_ERROR_MASK)
{
TI_DBG1(("osSatDefaultTranslation: ICRC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
ataError, tiIORequest));
satSetSensePayload( pSense,
SCSI_SNSKEY_ABORTED_COMMAND,
0,
SCSI_SNSCODE_INFORMATION_UNIT_CRC_ERROR,
satIOContext);
}
else if (ataError & ABRT_ATA_ERROR_MASK)
{
TI_DBG1(("osSatDefaultTranslation: ABRT_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
ataError, tiIORequest));
satSetSensePayload( pSense,
SCSI_SNSKEY_ABORTED_COMMAND,
0,
SCSI_SNSCODE_NO_ADDITIONAL_INFO,
satIOContext);
}
else
{
TI_DBG1(("osSatDefaultTranslation: **** UNEXPECTED ATA_ERROR **** ataError= 0x%x, tiIORequest=%p\n",
ataError, tiIORequest));
satSetSensePayload( pSense,
SCSI_SNSKEY_HARDWARE_ERROR,
0,
SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
satIOContext);
}
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
interruptContext );
return;
}
else
{
TI_DBG1(("osSatDefaultTranslation: *** UNEXPECTED ATA status 0x%x *** tiIORequest=%p\n",
ataStatus, tiIORequest));
satSetSensePayload( pSense,
SCSI_SNSKEY_HARDWARE_ERROR,
0,
SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
satIOContext);
ostiInitiatorIOCompleted( tiRoot,
tiIORequest,
tiIOSuccess,
SCSI_STAT_CHECK_CONDITION,
satIOContext->pTiSenseData,
interruptContext );
return;
}
}
GLOBAL satInternalIo_t * satAllocIntIoResource(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
satDeviceData_t *satDevData,
bit32 dmaAllocLength,
satInternalIo_t *satIntIo)
{
tdList_t *tdList = agNULL;
bit32 memAllocStatus;
TI_DBG1(("satAllocIntIoResource: start\n"));
TI_DBG6(("satAllocIntIoResource: satIntIo %p\n", satIntIo));
if (satDevData == agNULL)
{
TI_DBG1(("satAllocIntIoResource: ***** ASSERT satDevData is null\n"));
return agNULL;
}
tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
if (!TDLIST_EMPTY(&(satDevData->satFreeIntIoLinkList)))
{
TDLIST_DEQUEUE_FROM_HEAD(&tdList, &(satDevData->satFreeIntIoLinkList));
}
else
{
tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
TI_DBG1(("satAllocIntIoResource() no more internal free link.\n"));
return agNULL;
}
if (tdList == agNULL)
{
tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
TI_DBG1(("satAllocIntIoResource() FAIL to alloc satIntIo.\n"));
return agNULL;
}
satIntIo = TDLIST_OBJECT_BASE( satInternalIo_t, satIntIoLink, tdList);
TI_DBG6(("satAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
TDLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
TDLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satActiveIntIoLinkList));
tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
#ifdef REMOVED
tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
TDLIST_DEQUEUE_THIS (tdList);
TDLIST_ENQUEUE_AT_TAIL (tdList, &(satDevData->satActiveIntIoLinkList));
tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
satIntIo = TDLIST_OBJECT_BASE( satInternalIo_t, satIntIoLink, tdList);
TI_DBG6(("satAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
#endif
satIntIo->satIntReqBodyMem.totalLength = sizeof(tdIORequestBody_t);
memAllocStatus = ostiAllocMemory( tiRoot,
&satIntIo->satIntReqBodyMem.osHandle,
(void **)&satIntIo->satIntRequestBody,
&satIntIo->satIntReqBodyMem.physAddrUpper,
&satIntIo->satIntReqBodyMem.physAddrLower,
8,
satIntIo->satIntReqBodyMem.totalLength,
agTRUE );
if (memAllocStatus != tiSuccess)
{
TI_DBG1(("satAllocIntIoResource() FAIL to alloc mem for Req Body.\n"));
tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
TDLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
TDLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
return agNULL;
}
if (dmaAllocLength != 0)
{
satIntIo->satIntDmaMem.totalLength = dmaAllocLength;
memAllocStatus = ostiAllocMemory( tiRoot,
&satIntIo->satIntDmaMem.osHandle,
(void **)&satIntIo->satIntDmaMem.virtPtr,
&satIntIo->satIntDmaMem.physAddrUpper,
&satIntIo->satIntDmaMem.physAddrLower,
8,
satIntIo->satIntDmaMem.totalLength,
agFALSE);
TI_DBG6(("satAllocIntIoResource: len %d \n", satIntIo->satIntDmaMem.totalLength));
TI_DBG6(("satAllocIntIoResource: pointer %p \n", satIntIo->satIntDmaMem.osHandle));
if (memAllocStatus != tiSuccess)
{
TI_DBG1(("satAllocIntIoResource() FAIL to alloc mem for DMA mem.\n"));
tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
TDLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
TDLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
ostiFreeMemory( tiRoot,
satIntIo->satIntReqBodyMem.osHandle,
satIntIo->satIntReqBodyMem.totalLength);
return agNULL;
}
}
satIntIo->satIntTiIORequest.osData = agNULL;
satIntIo->satIntTiIORequest.tdData = satIntIo->satIntRequestBody;
satIntIo->satOrgTiIORequest = tiIORequest;
if (dmaAllocLength != 0)
{
satIntIo->satIntTiScsiXchg.sglVirtualAddr = satIntIo->satIntDmaMem.virtPtr;
OSSA_WRITE_LE_32(agNULL, &satIntIo->satIntTiScsiXchg.agSgl1.len, 0,
satIntIo->satIntDmaMem.totalLength);
satIntIo->satIntTiScsiXchg.agSgl1.lower = satIntIo->satIntDmaMem.physAddrLower;
satIntIo->satIntTiScsiXchg.agSgl1.upper = satIntIo->satIntDmaMem.physAddrUpper;
satIntIo->satIntTiScsiXchg.agSgl1.type = tiSgl;
satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = satIntIo->satIntDmaMem.totalLength;
}
else
{
satIntIo->satIntTiScsiXchg.sglVirtualAddr = agNULL;
satIntIo->satIntTiScsiXchg.agSgl1.len = 0;
satIntIo->satIntTiScsiXchg.agSgl1.lower = 0;
satIntIo->satIntTiScsiXchg.agSgl1.upper = 0;
satIntIo->satIntTiScsiXchg.agSgl1.type = tiSgl;
satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = 0;
}
TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.len %d\n", satIntIo->satIntTiScsiXchg.agSgl1.len));
TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.upper %d\n", satIntIo->satIntTiScsiXchg.agSgl1.upper));
TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.lower %d\n", satIntIo->satIntTiScsiXchg.agSgl1.lower));
TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.type %d\n", satIntIo->satIntTiScsiXchg.agSgl1.type));
TI_DBG5(("satAllocIntIoResource: return satIntIo %p\n", satIntIo));
return satIntIo;
}
GLOBAL void satFreeIntIoResource(
tiRoot_t *tiRoot,
satDeviceData_t *satDevData,
satInternalIo_t *satIntIo)
{
TI_DBG6(("satFreeIntIoResource: start\n"));
if (satIntIo == agNULL)
{
TI_DBG6(("satFreeIntIoResource: allowed call\n"));
return;
}
satIntIo->satOrgTiIORequest = agNULL;
if (satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength != 0)
{
TI_DBG1(("satFreeIntIoResource: DMA len %d\n", satIntIo->satIntDmaMem.totalLength));
TI_DBG6(("satFreeIntIoResource: pointer %p\n", satIntIo->satIntDmaMem.osHandle));
ostiFreeMemory( tiRoot,
satIntIo->satIntDmaMem.osHandle,
satIntIo->satIntDmaMem.totalLength);
satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = 0;
}
if (satIntIo->satIntReqBodyMem.totalLength != 0)
{
TI_DBG1(("satFreeIntIoResource: req body len %d\n", satIntIo->satIntReqBodyMem.totalLength));
ostiFreeMemory( tiRoot,
satIntIo->satIntReqBodyMem.osHandle,
satIntIo->satIntReqBodyMem.totalLength);
satIntIo->satIntReqBodyMem.totalLength = 0;
}
TI_DBG6(("satFreeIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
TDLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
TDLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satFreeIntIoLinkList));
tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
}
GLOBAL bit32 satSendIDDev(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
satDeviceData_t *pSatDevData;
agsaFisRegHostToDevice_t *fis;
#ifdef TD_DEBUG_ENABLE
satInternalIo_t *satIntIoContext;
tdsaDeviceData_t *oneDeviceData;
tdIORequestBody_t *tdIORequestBody;
#endif
pSatDevData = satIOContext->pSatDevData;
fis = satIOContext->pFis;
TI_DBG5(("satSendIDDev: start\n"));
#ifdef TD_DEBUG_ENABLE
oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
#endif
TI_DBG5(("satSendIDDev: did %d\n", oneDeviceData->id));
#ifdef TD_DEBUG_ENABLE
satIntIoContext = satIOContext->satIntIoContext;
tdIORequestBody = satIntIoContext->satIntRequestBody;
#endif
TI_DBG5(("satSendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
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 = &satInquiryCB;
satIOContext->reqType = agRequestType;
#ifdef TD_INTERNAL_DEBUG
tdhexdump("satSendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
#ifdef TD_DEBUG_ENABLE
tdhexdump("satSendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
#endif
#endif
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG6(("satSendIDDev: end status %d\n", status));
return status;
}
GLOBAL bit32 satStartIDDev(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext
)
{
satInternalIo_t *satIntIo = agNULL;
satDeviceData_t *satDevData = agNULL;
tdIORequestBody_t *tdIORequestBody;
satIOContext_t *satNewIOContext;
bit32 status;
TI_DBG6(("satStartIDDev: start\n"));
satDevData = satIOContext->pSatDevData;
TI_DBG6(("satStartIDDev: before alloc\n"));
satIntIo = satAllocIntIoResource( tiRoot,
tiIORequest,
satDevData,
sizeof(agsaSATAIdentifyData_t),
satIntIo);
TI_DBG6(("satStartIDDev: before after\n"));
if (satIntIo == agNULL)
{
TI_DBG1(("satStartIDDev: can't alloacate\n"));
#if 0
ostiInitiatorIOCompleted (
tiRoot,
tiIORequest,
tiIOFailed,
tiDetailOtherError,
agNULL,
satIOContext->interruptContext
);
#endif
return tiError;
}
satIntIo->satOrgTiIORequest = tiIORequest;
tdIORequestBody = satIntIo->satIntRequestBody;
satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
satNewIOContext->pSatDevData = satDevData;
satNewIOContext->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
satNewIOContext->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
satNewIOContext->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
satNewIOContext->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody;
satNewIOContext->interruptContext = tiInterruptContext;
satNewIOContext->satIntIoContext = satIntIo;
satNewIOContext->ptiDeviceHandle = agNULL;
satNewIOContext->satOrgIOContext = satIOContext;
satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg);
TI_DBG6(("satStartIDDev: OS satIOContext %p \n", satIOContext));
TI_DBG6(("satStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
TI_DBG6(("satStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
TI_DBG6(("satStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
TI_DBG1(("satStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody));
status = satSendIDDev( tiRoot,
&satIntIo->satIntTiIORequest,
tiDeviceHandle,
satNewIOContext->tiScsiXchg,
satNewIOContext);
if (status != tiSuccess)
{
TI_DBG1(("satStartIDDev: failed in sending\n"));
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
#if 0
ostiInitiatorIOCompleted (
tiRoot,
tiIORequest,
tiIOFailed,
tiDetailOtherError,
agNULL,
satIOContext->interruptContext
);
#endif
return tiError;
}
TI_DBG6(("satStartIDDev: end\n"));
return status;
}
bit32 satComputeCDB10LBA(satIOContext_t *satIOContext)
{
tiIniScsiCmnd_t *scsiCmnd;
tiScsiInitiatorRequest_t *tiScsiRequest;
bit32 lba = 0;
TI_DBG5(("satComputeCDB10LBA: start\n"));
tiScsiRequest = satIOContext->tiScsiXchg;
scsiCmnd = &(tiScsiRequest->scsiCmnd);
lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
+ (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
return lba;
}
bit32 satComputeCDB10TL(satIOContext_t *satIOContext)
{
tiIniScsiCmnd_t *scsiCmnd;
tiScsiInitiatorRequest_t *tiScsiRequest;
bit32 tl = 0;
TI_DBG5(("satComputeCDB10TL: start\n"));
tiScsiRequest = satIOContext->tiScsiXchg;
scsiCmnd = &(tiScsiRequest->scsiCmnd);
tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
return tl;
}
bit32 satComputeCDB12LBA(satIOContext_t *satIOContext)
{
tiIniScsiCmnd_t *scsiCmnd;
tiScsiInitiatorRequest_t *tiScsiRequest;
bit32 lba = 0;
TI_DBG5(("satComputeCDB10LBA: start\n"));
tiScsiRequest = satIOContext->tiScsiXchg;
scsiCmnd = &(tiScsiRequest->scsiCmnd);
lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
+ (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
return lba;
}
bit32 satComputeCDB12TL(satIOContext_t *satIOContext)
{
tiIniScsiCmnd_t *scsiCmnd;
tiScsiInitiatorRequest_t *tiScsiRequest;
bit32 tl = 0;
TI_DBG5(("satComputeCDB10TL: start\n"));
tiScsiRequest = satIOContext->tiScsiXchg;
scsiCmnd = &(tiScsiRequest->scsiCmnd);
tl = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
+ (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
return tl;
}
bit32 satComputeCDB16LBA(satIOContext_t *satIOContext)
{
tiIniScsiCmnd_t *scsiCmnd;
tiScsiInitiatorRequest_t *tiScsiRequest;
bit32 lba = 0;
TI_DBG5(("satComputeCDB10LBA: start\n"));
tiScsiRequest = satIOContext->tiScsiXchg;
scsiCmnd = &(tiScsiRequest->scsiCmnd);
lba = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
+ (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
return lba;
}
bit32 satComputeCDB16TL(satIOContext_t *satIOContext)
{
tiIniScsiCmnd_t *scsiCmnd;
tiScsiInitiatorRequest_t *tiScsiRequest;
bit32 tl = 0;
TI_DBG5(("satComputeCDB10TL: start\n"));
tiScsiRequest = satIOContext->tiScsiXchg;
scsiCmnd = &(tiScsiRequest->scsiCmnd);
tl = (scsiCmnd->cdb[10] << (8*3)) + (scsiCmnd->cdb[11] << (8*2))
+ (scsiCmnd->cdb[12] << 8) + scsiCmnd->cdb[13];
return tl;
}
bit32 satComputeLoopNum(bit32 a, bit32 b)
{
bit32 quo = 0, rem = 0;
bit32 LoopNum = 0;
TI_DBG5(("satComputeLoopNum: start\n"));
quo = a/b;
if (quo == 0)
{
LoopNum = 1;
}
else
{
rem = a % b;
if (rem == 0)
{
LoopNum = quo;
}
else
{
LoopNum = quo + 1;
}
}
return LoopNum;
}
bit32 satAddNComparebit64(bit8 *a, bit8 *b)
{
bit16 ans[8];
bit8 final_ans[9];
bit8 max[9];
int i;
TI_DBG5(("satAddNComparebit64: start\n"));
osti_memset(ans, 0, sizeof(ans));
osti_memset(final_ans, 0, sizeof(final_ans));
osti_memset(max, 0, sizeof(max));
max[0] = 0x1;
for(i=7;i>=0;i--)
{
ans[i] = (bit16)(a[i] + b[i]);
if (i != 7)
{
ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
}
}
final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
final_ans[1] = (bit8)(ans[0] & 0xFF);
for(i=2;i<=8;i++)
{
final_ans[i] = (bit8)(ans[i-1] & 0xFF);
}
for(i=0;i<=8;i++)
{
if (final_ans[i] > max[i])
{
TI_DBG5(("satAddNComparebit64: yes at %d\n", i));
return agTRUE;
}
else if (final_ans[i] < max[i])
{
TI_DBG5(("satAddNComparebit64: no at %d\n", i));
return agFALSE;
}
else
{
continue;
}
}
return agFALSE;
}
bit32 satAddNComparebit32(bit8 *a, bit8 *b)
{
bit16 ans[4];
bit8 final_ans[5];
bit8 max[4];
int i;
TI_DBG5(("satAddNComparebit32: start\n"));
osti_memset(ans, 0, sizeof(ans));
osti_memset(final_ans, 0, sizeof(final_ans));
osti_memset(max, 0, sizeof(max));
max[0] = 0x10;
for(i=3;i>=0;i--)
{
ans[i] = (bit16)(a[i] + b[i]);
if (i != 3)
{
ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
}
}
final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
final_ans[1] = (bit8)(ans[0] & 0xFF);
for(i=2;i<=4;i++)
{
final_ans[i] = (bit8)(ans[i-1] & 0xFF);
}
if (final_ans[0] != 0)
{
TI_DBG5(("satAddNComparebit32: yes bigger and out of range\n"));
return agTRUE;
}
for(i=1;i<=4;i++)
{
if (final_ans[i] > max[i-1])
{
TI_DBG5(("satAddNComparebit32: yes at %d\n", i));
return agTRUE;
}
else if (final_ans[i] < max[i-1])
{
TI_DBG5(("satAddNComparebit32: no at %d\n", i));
return agFALSE;
}
else
{
continue;
}
}
return agFALSE;
}
bit32 satCompareLBALimitbit(bit8 *lba)
{
bit32 i;
bit8 limit[8];
limit[0] = 0x0;
limit[1] = 0x0;
limit[2] = 0x0;
limit[3] = 0x0;
limit[4] = 0xF;
limit[5] = 0xFF;
limit[6] = 0xFF;
limit[7] = 0xFF;
for(i=0;i<8;i++)
{
if (lba[i] > limit[i])
{
TI_DBG5(("satCompareLBALimitbit64: yes at %d\n", i));
return agTRUE;
}
else if (lba[i] < limit[i])
{
TI_DBG5(("satCompareLBALimitbit64: no at %d\n", i));
return agFALSE;
}
else
{
continue;
}
}
return agFALSE;
}
GLOBAL void
satBitSet(bit8 *data, bit32 index)
{
data[index/8] |= (1 << (index%8));
}
GLOBAL void
satBitClear(bit8 *data, bit32 index)
{
data[index/8] &= ~(1 << (index%8));
}
GLOBAL agBOOLEAN
satBitTest(bit8 *data, bit32 index)
{
return ( (BOOLEAN)((data[index/8] & (1 << (index%8)) ) ? 1: 0));
}
GLOBAL bit32 satTagAlloc(
tiRoot_t *tiRoot,
satDeviceData_t *pSatDevData,
bit8 *pTag
)
{
bit32 retCode = agFALSE;
bit32 i;
tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
for ( i = 0; i < pSatDevData->satNCQMaxIO; i ++ )
{
if ( 0 == satBitTest((bit8 *)&pSatDevData->freeSATAFDMATagBitmap, i) )
{
satBitSet((bit8*)&pSatDevData->freeSATAFDMATagBitmap, i);
*pTag = (bit8) i;
retCode = agTRUE;
break;
}
}
tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
return retCode;
}
GLOBAL bit32 satTagRelease(
tiRoot_t *tiRoot,
satDeviceData_t *pSatDevData,
bit8 tag
)
{
bit32 retCode = agFALSE;
tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
if ( tag < pSatDevData->satNCQMaxIO )
{
satBitClear( (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, (bit32)tag);
retCode = agTRUE;
}
tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
return retCode;
}
osGLOBAL bit32 satSubTM(
tiRoot_t *tiRoot,
tiDeviceHandle_t *tiDeviceHandle,
bit32 task,
tiLUN_t *lun,
tiIORequest_t *taskTag,
tiIORequest_t *currentTaskTag,
bit32 NotifyOS
)
{
void *osMemHandle;
tdIORequestBody_t *TMtdIORequestBody;
bit32 PhysUpper32;
bit32 PhysLower32;
bit32 memAllocStatus;
agsaIORequest_t *agIORequest = agNULL;
TI_DBG6(("satSubTM: start\n"));
memAllocStatus = ostiAllocMemory(
tiRoot,
&osMemHandle,
(void **)&TMtdIORequestBody,
&PhysUpper32,
&PhysLower32,
8,
sizeof(tdIORequestBody_t),
agTRUE
);
if (memAllocStatus != tiSuccess)
{
TI_DBG1(("satSubTM: ostiAllocMemory failed... \n"));
return tiError;
}
if (TMtdIORequestBody == agNULL)
{
TI_DBG1(("satSubTM: ostiAllocMemory returned NULL TMIORequestBody\n"));
return tiError;
}
TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
TMtdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = agNULL;
TMtdIORequestBody->IOType.InitiatorTMIO.TaskTag = agNULL;
TMtdIORequestBody->tiDevHandle = tiDeviceHandle;
TMtdIORequestBody->tiIORequest = agNULL;
agIORequest = &(TMtdIORequestBody->agIORequest);
agIORequest->osData = (void *) TMtdIORequestBody;
agIORequest->sdkData = agNULL;
satTM(tiRoot,
tiDeviceHandle,
task,
agNULL,
agNULL,
agNULL,
TMtdIORequestBody,
agFALSE);
return tiSuccess;
}
GLOBAL bit32
satStartResetDevice(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext
)
{
satInternalIo_t *satIntIo = agNULL;
satDeviceData_t *satDevData = agNULL;
satIOContext_t *satNewIOContext;
bit32 status;
tiIORequest_t *currentTaskTag = agNULL;
TI_DBG1(("satStartResetDevice: start\n"));
currentTaskTag = tiIORequest;
satDevData = satIOContext->pSatDevData;
TI_DBG6(("satStartResetDevice: before alloc\n"));
satIntIo = satAllocIntIoResource( tiRoot,
tiIORequest,
satDevData,
0,
satIntIo);
TI_DBG6(("satStartResetDevice: before after\n"));
if (satIntIo == agNULL)
{
TI_DBG1(("satStartResetDevice: can't alloacate\n"));
if (satIOContext->NotifyOS)
{
ostiInitiatorEvent( tiRoot,
NULL,
NULL,
tiIntrEventTypeTaskManagement,
tiTMFailed,
currentTaskTag );
}
return tiError;
}
satNewIOContext = satPrepareNewIO(satIntIo,
tiIORequest,
satDevData,
agNULL,
satIOContext);
TI_DBG6(("satStartResetDevice: OS satIOContext %p \n", satIOContext));
TI_DBG6(("satStartResetDevice: TD satNewIOContext %p \n", satNewIOContext));
TI_DBG6(("satStartResetDevice: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
TI_DBG6(("satStartResetDevice: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
TI_DBG6(("satStartResetDevice: satNewIOContext %p \n", satNewIOContext));
if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
{
status = satDeviceReset(tiRoot,
&satIntIo->satIntTiIORequest,
tiDeviceHandle,
satNewIOContext->tiScsiXchg,
satNewIOContext);
}
else
{
status = satResetDevice(tiRoot,
&satIntIo->satIntTiIORequest,
tiDeviceHandle,
satNewIOContext->tiScsiXchg,
satNewIOContext);
}
if (status != tiSuccess)
{
TI_DBG1(("satStartResetDevice: failed in sending\n"));
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
if (satIOContext->NotifyOS)
{
ostiInitiatorEvent( tiRoot,
NULL,
NULL,
tiIntrEventTypeTaskManagement,
tiTMFailed,
currentTaskTag );
}
return tiError;
}
TI_DBG6(("satStartResetDevice: end\n"));
return status;
}
GLOBAL bit32
satResetDevice(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
#ifdef TD_DEBUG_ENABLE
tdIORequestBody_t *tdIORequestBody;
satInternalIo_t *satIntIoContext;
#endif
fis = satIOContext->pFis;
TI_DBG2(("satResetDevice: start\n"));
#ifdef TD_DEBUG_ENABLE
satIntIoContext = satIOContext->satIntIoContext;
tdIORequestBody = satIntIoContext->satIntRequestBody;
#endif
TI_DBG5(("satResetDevice: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
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 = &satResetDeviceCB;
satIOContext->reqType = agRequestType;
#ifdef TD_INTERNAL_DEBUG
tdhexdump("satResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
#ifdef TD_DEBUG_ENABLE
tdhexdump("satResetDevice LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
#endif
#endif
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG6(("satResetDevice: end status %d\n", status));
return status;
}
GLOBAL void satResetDeviceCB(
agsaRoot_t *agRoot,
agsaIORequest_t *agIORequest,
bit32 agIOStatus,
agsaFisHeader_t *agFirstDword,
bit32 agIOInfoLen,
agsaFrameHandle_t agFrameHandle,
void *ioContext
)
{
tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
tdIORequestBody_t *tdIORequestBody;
tdIORequestBody_t *tdOrgIORequestBody;
satIOContext_t *satIOContext;
satIOContext_t *satOrgIOContext;
satIOContext_t *satNewIOContext;
satInternalIo_t *satIntIo;
satInternalIo_t *satNewIntIo = agNULL;
satDeviceData_t *satDevData;
tiIORequest_t *tiOrgIORequest;
#ifdef TD_DEBUG_ENABLE
bit32 ataStatus = 0;
bit32 ataError;
agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL;
#endif
bit32 status;
TI_DBG1(("satResetDeviceCB: start\n"));
TI_DBG6(("satResetDeviceCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
satIOContext = (satIOContext_t *) ioContext;
satIntIo = satIOContext->satIntIoContext;
satDevData = satIOContext->pSatDevData;
if (satIntIo == agNULL)
{
TI_DBG6(("satResetDeviceCB: External, OS generated\n"));
satOrgIOContext = satIOContext;
tiOrgIORequest = tdIORequestBody->tiIORequest;
}
else
{
TI_DBG6(("satResetDeviceCB: Internal, TD generated\n"));
satOrgIOContext = satIOContext->satOrgIOContext;
if (satOrgIOContext == agNULL)
{
TI_DBG6(("satResetDeviceCB: satOrgIOContext is NULL, wrong\n"));
return;
}
else
{
TI_DBG6(("satResetDeviceCB: satOrgIOContext is NOT NULL\n"));
}
tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
tiOrgIORequest = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest;
}
tdIORequestBody->ioCompleted = agTRUE;
tdIORequestBody->ioStarted = agFALSE;
if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
{
TI_DBG1(("satResetDeviceCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
if (satOrgIOContext->NotifyOS == agTRUE)
{
ostiInitiatorEvent( tiRoot,
NULL,
NULL,
tiIntrEventTypeTaskManagement,
tiTMFailed,
tiOrgIORequest );
}
satDevData->satTmTaskTag = agNULL;
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
return;
}
if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
)
{
TI_DBG1(("satResetDeviceCB: OSSA_IO_OPEN_CNX_ERROR\n"));
if (satOrgIOContext->NotifyOS == agTRUE)
{
ostiInitiatorEvent( tiRoot,
NULL,
NULL,
tiIntrEventTypeTaskManagement,
tiTMFailed,
tiOrgIORequest );
}
satDevData->satTmTaskTag = agNULL;
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
return;
}
if (agIOStatus != OSSA_IO_SUCCESS)
{
#ifdef TD_DEBUG_ENABLE
satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
ataStatus = satPIOSetupHeader->status;
ataError = satPIOSetupHeader->error;
#endif
TI_DBG1(("satResetDeviceCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
if (satOrgIOContext->NotifyOS == agTRUE)
{
ostiInitiatorEvent( tiRoot,
NULL,
NULL,
tiIntrEventTypeTaskManagement,
tiTMFailed,
tiOrgIORequest );
}
satDevData->satTmTaskTag = agNULL;
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
return;
}
satNewIntIo = satAllocIntIoResource( tiRoot,
tiOrgIORequest,
satDevData,
0,
satNewIntIo);
if (satNewIntIo == agNULL)
{
satDevData->satTmTaskTag = agNULL;
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satNewIntIo);
if (satOrgIOContext->NotifyOS == agTRUE)
{
ostiInitiatorEvent( tiRoot,
NULL,
NULL,
tiIntrEventTypeTaskManagement,
tiTMFailed,
tiOrgIORequest );
}
TI_DBG1(("satResetDeviceCB: momory allocation fails\n"));
return;
}
satNewIOContext = satPrepareNewIO(
satNewIntIo,
tiOrgIORequest,
satDevData,
agNULL,
satOrgIOContext
);
status = satDeResetDevice(tiRoot,
tiOrgIORequest,
satOrgIOContext->ptiDeviceHandle,
agNULL,
satNewIOContext
);
if (status != tiSuccess)
{
if (satOrgIOContext->NotifyOS == agTRUE)
{
ostiInitiatorEvent( tiRoot,
NULL,
NULL,
tiIntrEventTypeTaskManagement,
tiTMFailed,
tiOrgIORequest );
}
satDevData->satTmTaskTag = agNULL;
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satNewIntIo);
return;
}
satDevData->satTmTaskTag = agNULL;
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
TI_DBG5(("satResetDeviceCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO));
TI_DBG6(("satResetDeviceCB: end\n"));
return;
}
GLOBAL bit32 satDeResetDevice(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
#ifdef TD_DEBUG_ENABLE
tdIORequestBody_t *tdIORequestBody;
satInternalIo_t *satIntIoContext;
#endif
fis = satIOContext->pFis;
TI_DBG6(("satDeResetDevice: start\n"));
#ifdef TD_DEBUG_ENABLE
satIntIoContext = satIOContext->satIntIoContext;
tdIORequestBody = satIntIoContext->satIntRequestBody;
TI_DBG5(("satDeResetDevice: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
#endif
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 = &satDeResetDeviceCB;
satIOContext->reqType = agRequestType;
#ifdef TD_INTERNAL_DEBUG
tdhexdump("satDeResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
#ifdef TD_DEBUG_ENABLE
tdhexdump("satDeResetDevice LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
#endif
#endif
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG6(("satDeResetDevice: end status %d\n", status));
return status;
}
GLOBAL void satDeResetDeviceCB(
agsaRoot_t *agRoot,
agsaIORequest_t *agIORequest,
bit32 agIOStatus,
agsaFisHeader_t *agFirstDword,
bit32 agIOInfoLen,
agsaFrameHandle_t agFrameHandle,
void *ioContext
)
{
tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
tdIORequestBody_t *tdIORequestBody;
tdIORequestBody_t *tdOrgIORequestBody = agNULL;
satIOContext_t *satIOContext;
satIOContext_t *satOrgIOContext;
satInternalIo_t *satIntIo;
satDeviceData_t *satDevData;
tiIORequest_t *tiOrgIORequest;
#ifdef TD_DEBUG_ENABLE
bit32 ataStatus = 0;
bit32 ataError;
agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL;
#endif
bit32 report = agFALSE;
bit32 AbortTM = agFALSE;
TI_DBG1(("satDeResetDeviceCB: start\n"));
TI_DBG6(("satDeResetDeviceCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
satIOContext = (satIOContext_t *) ioContext;
satIntIo = satIOContext->satIntIoContext;
satDevData = satIOContext->pSatDevData;
if (satIntIo == agNULL)
{
TI_DBG6(("satDeResetDeviceCB: External, OS generated\n"));
satOrgIOContext = satIOContext;
tiOrgIORequest = tdIORequestBody->tiIORequest;
}
else
{
TI_DBG6(("satDeResetDeviceCB: Internal, TD generated\n"));
satOrgIOContext = satIOContext->satOrgIOContext;
if (satOrgIOContext == agNULL)
{
TI_DBG6(("satDeResetDeviceCB: satOrgIOContext is NULL, wrong\n"));
return;
}
else
{
TI_DBG6(("satDeResetDeviceCB: satOrgIOContext is NOT NULL\n"));
}
tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
tiOrgIORequest = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest;
}
tdIORequestBody->ioCompleted = agTRUE;
tdIORequestBody->ioStarted = agFALSE;
if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
{
TI_DBG1(("satDeResetDeviceCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
if (satOrgIOContext->NotifyOS == agTRUE)
{
ostiInitiatorEvent( tiRoot,
NULL,
NULL,
tiIntrEventTypeTaskManagement,
tiTMFailed,
tiOrgIORequest );
}
satDevData->satTmTaskTag = agNULL;
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
return;
}
if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
)
{
TI_DBG1(("satDeResetDeviceCB: OSSA_IO_OPEN_CNX_ERROR\n"));
if (satOrgIOContext->NotifyOS == agTRUE)
{
ostiInitiatorEvent( tiRoot,
NULL,
NULL,
tiIntrEventTypeTaskManagement,
tiTMFailed,
tiOrgIORequest );
}
satDevData->satTmTaskTag = agNULL;
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
return;
}
if (agIOStatus != OSSA_IO_SUCCESS)
{
#ifdef TD_DEBUG_ENABLE
satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
ataStatus = satPIOSetupHeader->status;
ataError = satPIOSetupHeader->error;
#endif
TI_DBG1(("satDeResetDeviceCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
if (satOrgIOContext->NotifyOS == agTRUE)
{
ostiInitiatorEvent( tiRoot,
NULL,
NULL,
tiIntrEventTypeTaskManagement,
tiTMFailed,
tiOrgIORequest );
}
satDevData->satTmTaskTag = agNULL;
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
return;
}
TI_DBG1(("satDeResetDeviceCB: success \n"));
TI_DBG1(("satDeResetDeviceCB: TMF %d\n", satOrgIOContext->TMF));
if (satOrgIOContext->TMF == AG_ABORT_TASK)
{
AbortTM = agTRUE;
}
if (satOrgIOContext->NotifyOS == agTRUE)
{
report = agTRUE;
}
if (AbortTM == agTRUE)
{
TI_DBG1(("satDeResetDeviceCB: calling satAbort\n"));
satAbort(agRoot, satOrgIOContext->satToBeAbortedIOContext);
}
satDevData->satTmTaskTag = agNULL;
satDevData->satDriveState = SAT_DEV_STATE_NORMAL;
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
TI_DBG1(("satDeResetDeviceCB: satPendingIO %d satNCQMaxIO %d\n", satDevData->satPendingIO, satDevData->satNCQMaxIO ));
TI_DBG1(("satDeResetDeviceCB: satPendingNCQIO %d satPendingNONNCQIO %d\n", satDevData->satPendingNCQIO, satDevData->satPendingNONNCQIO));
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
if (tdOrgIORequestBody != agNULL)
{
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
}
else
{
TI_DBG1(("satDeResetDeviceCB: tdOrgIORequestBody is NULL, wrong\n"));
}
if (report)
{
ostiInitiatorEvent( tiRoot,
NULL,
NULL,
tiIntrEventTypeTaskManagement,
tiTMOK,
tiOrgIORequest );
}
TI_DBG5(("satDeResetDeviceCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO));
TI_DBG6(("satDeResetDeviceCB: end\n"));
return;
}
GLOBAL bit32 satStartCheckPowerMode(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext
)
{
satInternalIo_t *satIntIo = agNULL;
satDeviceData_t *satDevData = agNULL;
satIOContext_t *satNewIOContext;
bit32 status;
tiIORequest_t *currentTaskTag = agNULL;
TI_DBG6(("satStartCheckPowerMode: start\n"));
currentTaskTag = tiIORequest;
satDevData = satIOContext->pSatDevData;
TI_DBG6(("satStartCheckPowerMode: before alloc\n"));
satIntIo = satAllocIntIoResource( tiRoot,
tiIORequest,
satDevData,
0,
satIntIo);
TI_DBG6(("satStartCheckPowerMode: before after\n"));
if (satIntIo == agNULL)
{
TI_DBG1(("satStartCheckPowerMode: can't alloacate\n"));
if (satIOContext->NotifyOS)
{
ostiInitiatorEvent( tiRoot,
NULL,
NULL,
tiIntrEventTypeTaskManagement,
tiTMFailed,
currentTaskTag );
}
return tiError;
}
satNewIOContext = satPrepareNewIO(satIntIo,
tiIORequest,
satDevData,
agNULL,
satIOContext);
TI_DBG6(("satStartCheckPowerMode: OS satIOContext %p \n", satIOContext));
TI_DBG6(("satStartCheckPowerMode: TD satNewIOContext %p \n", satNewIOContext));
TI_DBG6(("satStartCheckPowerMode: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
TI_DBG6(("satStartCheckPowerMode: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
TI_DBG1(("satStartCheckPowerMode: satNewIOContext %p \n", satNewIOContext));
status = satCheckPowerMode(tiRoot,
&satIntIo->satIntTiIORequest,
tiDeviceHandle,
satNewIOContext->tiScsiXchg,
satNewIOContext);
if (status != tiSuccess)
{
TI_DBG1(("satStartCheckPowerMode: failed in sending\n"));
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
if (satIOContext->NotifyOS)
{
ostiInitiatorEvent( tiRoot,
NULL,
NULL,
tiIntrEventTypeTaskManagement,
tiTMFailed,
currentTaskTag );
}
return tiError;
}
TI_DBG6(("satStartCheckPowerMode: end\n"));
return status;
}
GLOBAL bit32 satCheckPowerMode(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
agsaFisRegHostToDevice_t *fis;
fis = satIOContext->pFis;
TI_DBG5(("satCheckPowerMode: 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 = &satCheckPowerModeCB;
satIOContext->reqType = agRequestType;
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG5(("satCheckPowerMode: return\n"));
return status;
}
GLOBAL void satCheckPowerModeCB(
agsaRoot_t *agRoot,
agsaIORequest_t *agIORequest,
bit32 agIOStatus,
agsaFisHeader_t *agFirstDword,
bit32 agIOInfoLen,
agsaFrameHandle_t agFrameHandle,
void *ioContext
)
{
tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
tdIORequestBody_t *tdIORequestBody;
tdIORequestBody_t *tdOrgIORequestBody = agNULL;
satIOContext_t *satIOContext;
satIOContext_t *satOrgIOContext;
satInternalIo_t *satIntIo;
satDeviceData_t *satDevData;
tiIORequest_t *tiOrgIORequest;
#ifdef TD_DEBUG_ENABLE
bit32 ataStatus = 0;
bit32 ataError;
agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL;
#endif
bit32 report = agFALSE;
bit32 AbortTM = agFALSE;
TI_DBG1(("satCheckPowerModeCB: start\n"));
TI_DBG1(("satCheckPowerModeCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
satIOContext = (satIOContext_t *) ioContext;
satIntIo = satIOContext->satIntIoContext;
satDevData = satIOContext->pSatDevData;
if (satIntIo == agNULL)
{
TI_DBG6(("satCheckPowerModeCB: External, OS generated\n"));
satOrgIOContext = satIOContext;
tiOrgIORequest = tdIORequestBody->tiIORequest;
}
else
{
TI_DBG6(("satCheckPowerModeCB: Internal, TD generated\n"));
satOrgIOContext = satIOContext->satOrgIOContext;
if (satOrgIOContext == agNULL)
{
TI_DBG6(("satCheckPowerModeCB: satOrgIOContext is NULL, wrong\n"));
return;
}
else
{
TI_DBG6(("satCheckPowerModeCB: satOrgIOContext is NOT NULL\n"));
}
tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
tiOrgIORequest = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest;
}
tdIORequestBody->ioCompleted = agTRUE;
tdIORequestBody->ioStarted = agFALSE;
if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
{
TI_DBG1(("satCheckPowerModeCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
if (satOrgIOContext->NotifyOS == agTRUE)
{
ostiInitiatorEvent( tiRoot,
NULL,
NULL,
tiIntrEventTypeTaskManagement,
tiTMFailed,
tiOrgIORequest );
}
satDevData->satTmTaskTag = agNULL;
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
return;
}
if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
)
{
TI_DBG1(("satCheckPowerModeCB: OSSA_IO_OPEN_CNX_ERROR\n"));
if (satOrgIOContext->NotifyOS == agTRUE)
{
ostiInitiatorEvent( tiRoot,
NULL,
NULL,
tiIntrEventTypeTaskManagement,
tiTMFailed,
tiOrgIORequest );
}
satDevData->satTmTaskTag = agNULL;
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
return;
}
if (agIOStatus != OSSA_IO_SUCCESS)
{
#ifdef TD_DEBUG_ENABLE
satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
ataStatus = satPIOSetupHeader->status;
ataError = satPIOSetupHeader->error;
#endif
TI_DBG1(("satCheckPowerModeCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
if (satOrgIOContext->NotifyOS == agTRUE)
{
ostiInitiatorEvent( tiRoot,
NULL,
NULL,
tiIntrEventTypeTaskManagement,
tiTMFailed,
tiOrgIORequest );
}
satDevData->satTmTaskTag = agNULL;
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
return;
}
TI_DBG1(("satCheckPowerModeCB: success\n"));
TI_DBG1(("satCheckPowerModeCB: TMF %d\n", satOrgIOContext->TMF));
if (satOrgIOContext->TMF == AG_ABORT_TASK)
{
AbortTM = agTRUE;
}
if (satOrgIOContext->NotifyOS == agTRUE)
{
report = agTRUE;
}
if (AbortTM == agTRUE)
{
TI_DBG1(("satCheckPowerModeCB: calling satAbort\n"));
satAbort(agRoot, satOrgIOContext->satToBeAbortedIOContext);
}
satDevData->satTmTaskTag = agNULL;
satDevData->satDriveState = SAT_DEV_STATE_NORMAL;
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
TI_DBG1(("satCheckPowerModeCB: satPendingIO %d satNCQMaxIO %d\n", satDevData->satPendingIO, satDevData->satNCQMaxIO ));
TI_DBG1(("satCheckPowerModeCB: satPendingNCQIO %d satPendingNONNCQIO %d\n", satDevData->satPendingNCQIO, satDevData->satPendingNONNCQIO));
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
if (tdOrgIORequestBody != agNULL)
{
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
}
else
{
TI_DBG1(("satCheckPowerModeCB: tdOrgIORequestBody is NULL, wrong\n"));
}
if (report)
{
ostiInitiatorEvent( tiRoot,
NULL,
NULL,
tiIntrEventTypeTaskManagement,
tiTMOK,
tiOrgIORequest );
}
TI_DBG5(("satCheckPowerModeCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO));
TI_DBG2(("satCheckPowerModeCB: end\n"));
return;
}
GLOBAL bit32 satAddSATAStartIDDev(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext
)
{
satInternalIo_t *satIntIo = agNULL;
satDeviceData_t *satDevData = agNULL;
tdIORequestBody_t *tdIORequestBody;
satIOContext_t *satNewIOContext;
bit32 status;
TI_DBG2(("satAddSATAStartIDDev: start\n"));
satDevData = satIOContext->pSatDevData;
TI_DBG2(("satAddSATAStartIDDev: before alloc\n"));
satIntIo = satAllocIntIoResource( tiRoot,
tiIORequest,
satDevData,
sizeof(agsaSATAIdentifyData_t),
satIntIo);
TI_DBG2(("satAddSATAStartIDDev: after alloc\n"));
if (satIntIo == agNULL)
{
TI_DBG1(("satAddSATAStartIDDev: can't alloacate\n"));
return tiError;
}
satIntIo->satOrgTiIORequest = tiIORequest;
tdIORequestBody = satIntIo->satIntRequestBody;
satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
satNewIOContext->pSatDevData = satDevData;
satNewIOContext->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
satNewIOContext->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
satNewIOContext->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
satNewIOContext->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody;
satNewIOContext->interruptContext = tiInterruptContext;
satNewIOContext->satIntIoContext = satIntIo;
satNewIOContext->ptiDeviceHandle = agNULL;
satNewIOContext->satOrgIOContext = satIOContext;
satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg);
TI_DBG6(("satAddSATAStartIDDev: OS satIOContext %p \n", satIOContext));
TI_DBG6(("satAddSATAStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
TI_DBG6(("satAddSATAStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
TI_DBG6(("satAddSATAStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
TI_DBG2(("satAddSATAStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody));
status = satAddSATASendIDDev( tiRoot,
&satIntIo->satIntTiIORequest,
tiDeviceHandle,
satNewIOContext->tiScsiXchg,
satNewIOContext);
if (status != tiSuccess)
{
TI_DBG1(("satAddSATAStartIDDev: failed in sending\n"));
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
return tiError;
}
TI_DBG6(("satAddSATAStartIDDev: end\n"));
return status;
}
GLOBAL bit32 satAddSATASendIDDev(
tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext)
{
bit32 status;
bit32 agRequestType;
satDeviceData_t *pSatDevData;
agsaFisRegHostToDevice_t *fis;
#ifdef TD_DEBUG_ENABLE
tdIORequestBody_t *tdIORequestBody;
satInternalIo_t *satIntIoContext;
#endif
pSatDevData = satIOContext->pSatDevData;
fis = satIOContext->pFis;
TI_DBG2(("satAddSATASendIDDev: start\n"));
#ifdef TD_DEBUG_ENABLE
satIntIoContext = satIOContext->satIntIoContext;
tdIORequestBody = satIntIoContext->satIntRequestBody;
#endif
TI_DBG5(("satAddSATASendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
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 = &satAddSATAIDDevCB;
satIOContext->reqType = agRequestType;
#ifdef TD_INTERNAL_DEBUG
tdhexdump("satAddSATASendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
#ifdef TD_DEBUG_ENABLE
tdhexdump("satAddSATASendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
#endif
#endif
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG2(("satAddSATASendIDDev: end status %d\n", status));
return status;
}
void satAddSATAIDDevCB(
agsaRoot_t *agRoot,
agsaIORequest_t *agIORequest,
bit32 agIOStatus,
agsaFisHeader_t *agFirstDword,
bit32 agIOInfoLen,
void *agParam,
void *ioContext
)
{
tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
tdIORequestBody_t *tdIORequestBody;
tdIORequestBody_t *tdOrgIORequestBody;
satIOContext_t *satIOContext;
satIOContext_t *satOrgIOContext;
satIOContext_t *satNewIOContext;
satInternalIo_t *satIntIo;
satInternalIo_t *satNewIntIo = agNULL;
satDeviceData_t *satDevData;
tiIORequest_t *tiOrgIORequest = agNULL;
agsaSATAIdentifyData_t *pSATAIdData;
bit16 *tmpptr, tmpptr_tmp;
bit32 x;
tdsaDeviceData_t *NewOneDeviceData = agNULL;
tdsaDeviceData_t *oneDeviceData = agNULL;
tdList_t *DeviceListList;
int new_device = agTRUE;
bit8 PhyID;
void *sglVirtualAddr;
bit32 retry_status;
agsaContext_t *agContext;
tdsaPortContext_t *onePortContext;
bit32 status = 0;
TI_DBG2(("satAddSATAIDDevCB: start\n"));
TI_DBG6(("satAddSATAIDDevCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
satIOContext = (satIOContext_t *) ioContext;
satIntIo = satIOContext->satIntIoContext;
satDevData = satIOContext->pSatDevData;
NewOneDeviceData = (tdsaDeviceData_t *)tdIORequestBody->tiDevHandle->tdData;
TI_DBG2(("satAddSATAIDDevCB: NewOneDeviceData %p did %d\n", NewOneDeviceData, NewOneDeviceData->id));
PhyID = NewOneDeviceData->phyID;
TI_DBG2(("satAddSATAIDDevCB: phyID %d\n", PhyID));
agContext = &(NewOneDeviceData->agDeviceResetContext);
agContext->osData = agNULL;
if (satIntIo == agNULL)
{
TI_DBG1(("satAddSATAIDDevCB: External, OS generated\n"));
TI_DBG1(("satAddSATAIDDevCB: Not possible case\n"));
satOrgIOContext = satIOContext;
tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData);
osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink));
TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
ostiPortEvent (
tiRoot,
tiPortLinkUp,
tiSuccess,
(void *)tdsaAllShared->Ports[PhyID].tiPortalContext
);
#ifdef INITIATOR_DRIVER
ostiPortEvent(
tiRoot,
tiPortDiscoveryReady,
tiSuccess,
(void *) tdsaAllShared->Ports[PhyID].tiPortalContext
);
#endif
return;
}
else
{
TI_DBG1(("satAddSATAIDDevCB: Internal, TD generated\n"));
satOrgIOContext = satIOContext->satOrgIOContext;
if (satOrgIOContext == agNULL)
{
TI_DBG6(("satAddSATAIDDevCB: satOrgIOContext is NULL\n"));
return;
}
else
{
TI_DBG6(("satAddSATAIDDevCB: satOrgIOContext is NOT NULL\n"));
tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
sglVirtualAddr = satIntIo->satIntTiScsiXchg.sglVirtualAddr;
}
}
tiOrgIORequest = tdIORequestBody->tiIORequest;
tdIORequestBody->ioCompleted = agTRUE;
tdIORequestBody->ioStarted = agFALSE;
TI_DBG2(("satAddSATAIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
if (satOrgIOContext->pid != tdsaAllShared->Ports[PhyID].portContext->id)
{
TI_DBG2(("satAddSATAIDDevCB: incorrect pid\n"));
TI_DBG2(("satAddSATAIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
TI_DBG2(("satAddSATAIDDevCB: tiPortalContext pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id));
tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData);
osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink));
TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
return;
}
onePortContext = NewOneDeviceData->tdPortContext;
if (onePortContext != agNULL)
{
if (onePortContext->valid == agFALSE)
{
TI_DBG1(("satAddSATAIDDevCB: portcontext is invalid\n"));
TI_DBG1(("satAddSATAIDDevCB: onePortContext->id pid %d\n", onePortContext->id));
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
return;
}
}
else
{
TI_DBG1(("satAddSATAIDDevCB: onePortContext is NULL!!!\n"));
return;
}
if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
{
TI_DBG1(("satAddSATAIDDevCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
{
satDevData->satPendingNONNCQIO--;
satDevData->satPendingIO--;
retry_status = sataLLIOStart(tiRoot,
&satIntIo->satIntTiIORequest,
&(NewOneDeviceData->tiDeviceHandle),
satIOContext->tiScsiXchg,
satIOContext);
if (retry_status != tiSuccess)
{
satDevData->ID_Retries = 0;
satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
return;
}
satDevData->ID_Retries++;
tdIORequestBody->ioCompleted = agFALSE;
tdIORequestBody->ioStarted = agTRUE;
return;
}
else
{
if (tdsaAllShared->ResetInDiscovery == 0)
{
satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
}
else
{
if (satDevData->NumOfIDRetries <= 0)
{
satDevData->NumOfIDRetries++;
satDevData->ID_Retries = 0;
satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
saLocalPhyControl(agRoot,
agContext,
tdsaRotateQnumber(tiRoot, NewOneDeviceData),
PhyID,
AGSA_PHY_HARD_RESET,
agNULL);
}
else
{
satDevData->ID_Retries = 0;
satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
}
}
return;
}
}
if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
)
{
TI_DBG1(("satAddSATAIDDevCB: OSSA_IO_OPEN_CNX_ERROR\n"));
if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
{
satDevData->satPendingNONNCQIO--;
satDevData->satPendingIO--;
retry_status = sataLLIOStart(tiRoot,
&satIntIo->satIntTiIORequest,
&(NewOneDeviceData->tiDeviceHandle),
satIOContext->tiScsiXchg,
satIOContext);
if (retry_status != tiSuccess)
{
satDevData->ID_Retries = 0;
satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
return;
}
satDevData->ID_Retries++;
tdIORequestBody->ioCompleted = agFALSE;
tdIORequestBody->ioStarted = agTRUE;
return;
}
else
{
if (tdsaAllShared->ResetInDiscovery == 0)
{
satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
}
else
{
if (satDevData->NumOfIDRetries <= 0)
{
satDevData->NumOfIDRetries++;
satDevData->ID_Retries = 0;
satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
saLocalPhyControl(agRoot,
agContext,
tdsaRotateQnumber(tiRoot, NewOneDeviceData),
PhyID,
AGSA_PHY_HARD_RESET,
agNULL);
}
else
{
satDevData->ID_Retries = 0;
satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
}
}
return;
}
}
if ( agIOStatus != OSSA_IO_SUCCESS ||
(agIOStatus == OSSA_IO_SUCCESS && agFirstDword != agNULL && agIOInfoLen != 0)
)
{
if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
{
satIOContext->pSatDevData->satPendingNONNCQIO--;
satIOContext->pSatDevData->satPendingIO--;
retry_status = sataLLIOStart(tiRoot,
&satIntIo->satIntTiIORequest,
&(NewOneDeviceData->tiDeviceHandle),
satIOContext->tiScsiXchg,
satIOContext);
if (retry_status != tiSuccess)
{
satDevData->ID_Retries = 0;
satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
return;
}
satDevData->ID_Retries++;
tdIORequestBody->ioCompleted = agFALSE;
tdIORequestBody->ioStarted = agTRUE;
return;
}
else
{
if (tdsaAllShared->ResetInDiscovery == 0)
{
satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
}
else
{
if (satDevData->NumOfIDRetries <= 0)
{
satDevData->NumOfIDRetries++;
satDevData->ID_Retries = 0;
satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
saLocalPhyControl(agRoot,
agContext,
tdsaRotateQnumber(tiRoot, NewOneDeviceData),
PhyID,
AGSA_PHY_HARD_RESET,
agNULL);
}
else
{
satDevData->ID_Retries = 0;
satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
}
}
return;
}
}
TI_DBG2(("satAddSATAIDDevCB: Success\n"));
tmpptr = (bit16*)sglVirtualAddr;
for (x=0; x < sizeof(agsaSATAIdentifyData_t)/sizeof(bit16); x++)
{
OSSA_READ_LE_16(AGROOT, &tmpptr_tmp, tmpptr, 0);
*tmpptr = tmpptr_tmp;
tmpptr++;
}
pSATAIdData = (agsaSATAIdentifyData_t *)sglVirtualAddr;
TI_DBG5(("satAddSATAIDDevCB: OS satOrgIOContext %p \n", satOrgIOContext));
TI_DBG5(("satAddSATAIDDevCB: TD satIOContext %p \n", satIOContext));
TI_DBG5(("satAddSATAIDDevCB: OS tiScsiXchg %p \n", satOrgIOContext->tiScsiXchg));
TI_DBG5(("satAddSATAIDDevCB: TD tiScsiXchg %p \n", satIOContext->tiScsiXchg));
DeviceListList = tdsaAllShared->MainDeviceList.flink;
while (DeviceListList != &(tdsaAllShared->MainDeviceList))
{
oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
TI_DBG1(("satAddSATAIDDevCB: LOOP oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
if ( oneDeviceData->DeviceType == TD_SATA_DEVICE &&
(osti_memcmp (oneDeviceData->satDevData.satIdentifyData.serialNumber,
pSATAIdData->serialNumber,
20) == 0) &&
(osti_memcmp (oneDeviceData->satDevData.satIdentifyData.firmwareVersion,
pSATAIdData->firmwareVersion,
8) == 0) &&
(osti_memcmp (oneDeviceData->satDevData.satIdentifyData.modelNumber,
pSATAIdData->modelNumber,
40) == 0)
)
{
TI_DBG2(("satAddSATAIDDevCB: did %d\n", oneDeviceData->id));
new_device = agFALSE;
break;
}
DeviceListList = DeviceListList->flink;
}
if (new_device == agFALSE)
{
TI_DBG2(("satAddSATAIDDevCB: old device data\n"));
oneDeviceData->valid = agTRUE;
oneDeviceData->valid2 = agTRUE;
oneDeviceData->agRoot = agRoot;
oneDeviceData->agDevHandle = NewOneDeviceData->agDevHandle;
oneDeviceData->agDevHandle->osData = oneDeviceData;
oneDeviceData->tdPortContext = NewOneDeviceData->tdPortContext;
oneDeviceData->phyID = NewOneDeviceData->phyID;
saDeregisterDeviceHandle(agRoot, agNULL, NewOneDeviceData->agDevHandle, 0);
if (oneDeviceData->registered == agFALSE)
{
TI_DBG2(("satAddSATAIDDevCB: re-registering old device data\n"));
saRegisterNewDevice(
agRoot,
&oneDeviceData->agContext,
tdsaRotateQnumber(tiRoot, oneDeviceData),
&oneDeviceData->agDeviceInfo,
oneDeviceData->tdPortContext->agPortContext,
0
);
}
osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink));
TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
{
satNewIntIo = satAllocIntIoResource( tiRoot,
tiOrgIORequest,
satDevData,
0,
satNewIntIo);
if (satNewIntIo == agNULL)
{
TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n"));
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
return;
}
satNewIOContext = satPrepareNewIO(satNewIntIo,
tiOrgIORequest,
satDevData,
agNULL,
satOrgIOContext
);
status = satSetFeatures(tiRoot,
&satNewIntIo->satIntTiIORequest,
satNewIOContext->ptiDeviceHandle,
&satNewIntIo->satIntTiScsiXchg,
satNewIOContext,
agFALSE);
if (status != tiSuccess)
{
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
}
}
else
{
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
TI_DBG2(("satAddSATAIDDevCB: pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id));
ostiPortEvent(
tiRoot,
tiPortLinkUp,
tiSuccess,
(void *)tdsaAllShared->Ports[PhyID].tiPortalContext
);
#ifdef INITIATOR_DRIVER
ostiPortEvent(
tiRoot,
tiPortDiscoveryReady,
tiSuccess,
(void *) tdsaAllShared->Ports[PhyID].tiPortalContext
);
#endif
}
return;
}
TI_DBG2(("satAddSATAIDDevCB: new device data\n"));
satDevData->satIdentifyData = *pSATAIdData;
satDevData->IDDeviceValid = agTRUE;
#ifdef TD_INTERNAL_DEBUG
tdhexdump("satAddSATAIDDevCB ID Dev data",(bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
tdhexdump("satAddSATAIDDevCB Device ID Dev data",(bit8 *)&satDevData->satIdentifyData, sizeof(agsaSATAIdentifyData_t));
#endif
satSetDevInfo(satDevData,pSATAIdData);
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
{
satNewIntIo = satAllocIntIoResource( tiRoot,
tiOrgIORequest,
satDevData,
0,
satNewIntIo);
if (satNewIntIo == agNULL)
{
TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n"));
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
return;
}
satNewIOContext = satPrepareNewIO(satNewIntIo,
tiOrgIORequest,
satDevData,
agNULL,
satOrgIOContext
);
status = satSetFeatures(tiRoot,
&satNewIntIo->satIntTiIORequest,
satNewIOContext->ptiDeviceHandle,
&satNewIntIo->satIntTiScsiXchg,
satNewIOContext,
agFALSE);
if (status != tiSuccess)
{
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
}
}
else
{
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
TI_DBG2(("satAddSATAIDDevCB: pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id));
ostiPortEvent (
tiRoot,
tiPortLinkUp,
tiSuccess,
(void *)tdsaAllShared->Ports[PhyID].tiPortalContext
);
#ifdef INITIATOR_DRIVER
ostiPortEvent(
tiRoot,
tiPortDiscoveryReady,
tiSuccess,
(void *) tdsaAllShared->Ports[PhyID].tiPortalContext
);
#endif
}
TI_DBG2(("satAddSATAIDDevCB: end\n"));
return;
}
void satAddSATAIDDevCBReset(
agsaRoot_t *agRoot,
tdsaDeviceData_t *oneDeviceData,
satIOContext_t *satIOContext,
tdIORequestBody_t *tdIORequestBody
)
{
tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
satInternalIo_t *satIntIo;
satDeviceData_t *satDevData;
TI_DBG2(("satAddSATAIDDevCBReset: start\n"));
satIntIo = satIOContext->satIntIoContext;
satDevData = satIOContext->pSatDevData;
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
ostiFreeMemory(
tiRoot,
tdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
return;
}
void satAddSATAIDDevCBCleanup(
agsaRoot_t *agRoot,
tdsaDeviceData_t *oneDeviceData,
satIOContext_t *satIOContext,
tdIORequestBody_t *tdIORequestBody
)
{
tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
satInternalIo_t *satIntIo;
satDeviceData_t *satDevData;
bit8 PhyID;
TI_DBG2(("satAddSATAIDDevCBCleanup: start\n"));
satIntIo = satIOContext->satIntIoContext;
satDevData = satIOContext->pSatDevData;
PhyID = oneDeviceData->phyID;
tdsaAbortAll(tiRoot, agRoot, oneDeviceData);
osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
TDLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink));
TDLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
ostiFreeMemory(
tiRoot,
tdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
ostiPortEvent (
tiRoot,
tiPortLinkUp,
tiSuccess,
(void *)tdsaAllShared->Ports[PhyID].tiPortalContext
);
#ifdef INITIATOR_DRIVER
ostiPortEvent(
tiRoot,
tiPortDiscoveryReady,
tiSuccess,
(void *) tdsaAllShared->Ports[PhyID].tiPortalContext
);
#endif
return;
}
GLOBAL bit32
tdsaDiscoveryStartIDDev(tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
tdsaDeviceData_t *oneDeviceData
)
{
void *osMemHandle;
tdIORequestBody_t *tdIORequestBody;
bit32 PhysUpper32;
bit32 PhysLower32;
bit32 memAllocStatus;
agsaIORequest_t *agIORequest = agNULL;
satIOContext_t *satIOContext = agNULL;
bit32 status;
TI_DBG3(("tdsaDiscoveryStartIDDev: start\n"));
TI_DBG3(("tdsaDiscoveryStartIDDev: did %d\n", oneDeviceData->id));
memAllocStatus = ostiAllocMemory(
tiRoot,
&osMemHandle,
(void **)&tdIORequestBody,
&PhysUpper32,
&PhysLower32,
8,
sizeof(tdIORequestBody_t),
agTRUE
);
if (memAllocStatus != tiSuccess)
{
TI_DBG1(("tdsaDiscoveryStartIDDev: ostiAllocMemory failed... loc 1\n"));
return tiError;
}
if (tdIORequestBody == agNULL)
{
TI_DBG1(("tdsaDiscoveryStartIDDev: ostiAllocMemory returned NULL tdIORequestBody loc 2\n"));
return tiError;
}
tdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
tdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = agNULL;
tdIORequestBody->IOType.InitiatorTMIO.TaskTag = agNULL;
tdIORequestBody->tiDevHandle = &(oneDeviceData->tiDeviceHandle);
tdIORequestBody->tiDevHandle->tdData = oneDeviceData;
tdIORequestBody->tiIORequest = agNULL;
agIORequest = &(tdIORequestBody->agIORequest);
agIORequest->osData = (void *) tdIORequestBody;
agIORequest->sdkData = agNULL;
satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
satIOContext->pSatDevData = &(oneDeviceData->satDevData);
satIOContext->pFis =
&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
satIOContext->tiRequestBody = tdIORequestBody;
satIOContext->ptiDeviceHandle = &(oneDeviceData->tiDeviceHandle);
satIOContext->tiScsiXchg = agNULL;
satIOContext->satIntIoContext = agNULL;
satIOContext->satOrgIOContext = agNULL;
satIOContext->currentLBA = 0;
satIOContext->OrgTL = 0;
satIOContext->satToBeAbortedIOContext = agNULL;
satIOContext->NotifyOS = agFALSE;
satIOContext->pid = oneDeviceData->tdPortContext->id;
osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0x0, sizeof(agsaSATAIdentifyData_t));
status = tdsaDiscoveryIntStartIDDev(tiRoot,
tiIORequest,
tiDeviceHandle,
agNULL,
satIOContext
);
if (status != tiSuccess)
{
TI_DBG1(("tdsaDiscoveryStartIDDev: failed in sending %d\n", status));
ostiFreeMemory(tiRoot, osMemHandle, sizeof(tdIORequestBody_t));
}
return status;
}
GLOBAL bit32
tdsaDiscoveryIntStartIDDev(tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext
)
{
satInternalIo_t *satIntIo = agNULL;
satDeviceData_t *satDevData = agNULL;
tdIORequestBody_t *tdIORequestBody;
satIOContext_t *satNewIOContext;
bit32 status;
TI_DBG3(("tdsaDiscoveryIntStartIDDev: start\n"));
satDevData = satIOContext->pSatDevData;
satIntIo = satAllocIntIoResource( tiRoot,
tiIORequest,
satDevData,
sizeof(agsaSATAIdentifyData_t),
satIntIo);
if (satIntIo == agNULL)
{
TI_DBG2(("tdsaDiscoveryIntStartIDDev: can't alloacate\n"));
return tiError;
}
satIntIo->satOrgTiIORequest = tiIORequest;
tdIORequestBody = satIntIo->satIntRequestBody;
satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
satNewIOContext->pSatDevData = satDevData;
satNewIOContext->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
satNewIOContext->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
satNewIOContext->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
satNewIOContext->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody;
satNewIOContext->interruptContext = tiInterruptContext;
satNewIOContext->satIntIoContext = satIntIo;
satNewIOContext->ptiDeviceHandle = agNULL;
satNewIOContext->satOrgIOContext = satIOContext;
satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg);
TI_DBG6(("tdsaDiscoveryIntStartIDDev: OS satIOContext %p \n", satIOContext));
TI_DBG6(("tdsaDiscoveryIntStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
TI_DBG6(("tdsaDiscoveryIntStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
TI_DBG6(("tdsaDiscoveryIntStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
TI_DBG3(("tdsaDiscoveryIntStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody));
status = tdsaDiscoverySendIDDev(tiRoot,
&satIntIo->satIntTiIORequest,
tiDeviceHandle,
satNewIOContext->tiScsiXchg,
satNewIOContext);
if (status != tiSuccess)
{
TI_DBG1(("tdsaDiscoveryIntStartIDDev: failed in sending %d\n", status));
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
return tiError;
}
TI_DBG6(("tdsaDiscoveryIntStartIDDev: end\n"));
return status;
}
GLOBAL bit32
tdsaDiscoverySendIDDev(tiRoot_t *tiRoot,
tiIORequest_t *tiIORequest,
tiDeviceHandle_t *tiDeviceHandle,
tiScsiInitiatorRequest_t *tiScsiRequest,
satIOContext_t *satIOContext
)
{
bit32 status;
bit32 agRequestType;
satDeviceData_t *pSatDevData;
agsaFisRegHostToDevice_t *fis;
#ifdef TD_DEBUG_ENABLE
tdIORequestBody_t *tdIORequestBody;
satInternalIo_t *satIntIoContext;
#endif
pSatDevData = satIOContext->pSatDevData;
fis = satIOContext->pFis;
TI_DBG3(("tdsaDiscoverySendIDDev: start\n"));
#ifdef TD_DEBUG_ENABLE
satIntIoContext = satIOContext->satIntIoContext;
tdIORequestBody = satIntIoContext->satIntRequestBody;
#endif
TI_DBG5(("tdsaDiscoverySendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
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 = &tdsaDiscoveryStartIDDevCB;
satIOContext->reqType = agRequestType;
#ifdef TD_INTERNAL_DEBUG
tdhexdump("tdsaDiscoverySendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
#ifdef TD_DEBUG_ENABLE
tdhexdump("tdsaDiscoverySendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
#endif
#endif
status = sataLLIOStart( tiRoot,
tiIORequest,
tiDeviceHandle,
tiScsiRequest,
satIOContext);
TI_DBG3(("tdsaDiscoverySendIDDev: end status %d\n", status));
return status;
}
void tdsaDiscoveryStartIDDevCB(
agsaRoot_t *agRoot,
agsaIORequest_t *agIORequest,
bit32 agIOStatus,
agsaFisHeader_t *agFirstDword,
bit32 agIOInfoLen,
void *agParam,
void *ioContext
)
{
tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
tdIORequestBody_t *tdIORequestBody;
tdIORequestBody_t *tdOrgIORequestBody;
satIOContext_t *satIOContext;
satIOContext_t *satOrgIOContext;
satIOContext_t *satNewIOContext;
satInternalIo_t *satIntIo;
satInternalIo_t *satNewIntIo = agNULL;
satDeviceData_t *satDevData;
tiIORequest_t *tiOrgIORequest = agNULL;
#ifdef TD_DEBUG_ENABLE
bit32 ataStatus = 0;
bit32 ataError;
agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL;
#endif
agsaSATAIdentifyData_t *pSATAIdData;
bit16 *tmpptr, tmpptr_tmp;
bit32 x;
tdsaDeviceData_t *oneDeviceData = agNULL;
void *sglVirtualAddr;
tdsaPortContext_t *onePortContext = agNULL;
tiPortalContext_t *tiPortalContext = agNULL;
bit32 retry_status;
TI_DBG3(("tdsaDiscoveryStartIDDevCB: start\n"));
tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
satIOContext = (satIOContext_t *) ioContext;
satIntIo = satIOContext->satIntIoContext;
satDevData = satIOContext->pSatDevData;
oneDeviceData = (tdsaDeviceData_t *)tdIORequestBody->tiDevHandle->tdData;
TI_DBG3(("tdsaDiscoveryStartIDDevCB: did %d\n", oneDeviceData->id));
onePortContext = oneDeviceData->tdPortContext;
if (onePortContext == agNULL)
{
TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext is NULL\n"));
return;
}
tiPortalContext= onePortContext->tiPortalContext;
satDevData->IDDeviceValid = agFALSE;
if (satIntIo == agNULL)
{
TI_DBG1(("tdsaDiscoveryStartIDDevCB: External, OS generated\n"));
TI_DBG1(("tdsaDiscoveryStartIDDevCB: Not possible case\n"));
satOrgIOContext = satIOContext;
tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
return;
}
else
{
TI_DBG3(("tdsaDiscoveryStartIDDevCB: Internal, TD generated\n"));
satOrgIOContext = satIOContext->satOrgIOContext;
if (satOrgIOContext == agNULL)
{
TI_DBG6(("tdsaDiscoveryStartIDDevCB: satOrgIOContext is NULL\n"));
return;
}
else
{
TI_DBG6(("tdsaDiscoveryStartIDDevCB: satOrgIOContext is NOT NULL\n"));
tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
sglVirtualAddr = satIntIo->satIntTiScsiXchg.sglVirtualAddr;
}
}
tiOrgIORequest = tdIORequestBody->tiIORequest;
tdIORequestBody->ioCompleted = agTRUE;
tdIORequestBody->ioStarted = agFALSE;
TI_DBG3(("tdsaDiscoveryStartIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
if (satOrgIOContext->pid != oneDeviceData->tdPortContext->id)
{
TI_DBG3(("tdsaDiscoveryStartIDDevCB: incorrect pid\n"));
TI_DBG3(("tdsaDiscoveryStartIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
TI_DBG3(("tdsaDiscoveryStartIDDevCB: tiPortalContext pid %d\n", oneDeviceData->tdPortContext->id));
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
return;
}
if (onePortContext != agNULL)
{
if (onePortContext->valid == agFALSE)
{
TI_DBG1(("tdsaDiscoveryStartIDDevCB: portcontext is invalid\n"));
TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext->id pid %d\n", onePortContext->id));
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
return;
}
}
if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
{
TI_DBG1(("tdsaDiscoveryStartIDDevCB: agFirstDword is NULL when error, status %d\n", agIOStatus));
TI_DBG1(("tdsaDiscoveryStartIDDevCB: did %d\n", oneDeviceData->id));
if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
{
satIOContext->pSatDevData->satPendingNONNCQIO--;
satIOContext->pSatDevData->satPendingIO--;
retry_status = sataLLIOStart(tiRoot,
&satIntIo->satIntTiIORequest,
&(oneDeviceData->tiDeviceHandle),
satIOContext->tiScsiXchg,
satIOContext);
if (retry_status != tiSuccess)
{
satDevData->ID_Retries = 0;
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
return;
}
satDevData->ID_Retries++;
tdIORequestBody->ioCompleted = agFALSE;
tdIORequestBody->ioStarted = agTRUE;
return;
}
else
{
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
if (tdsaAllShared->ResetInDiscovery != 0)
{
if (satDevData->NumOfIDRetries <= 0)
{
satDevData->NumOfIDRetries++;
satDevData->ID_Retries = 0;
tdsaPhyControlSend(tiRoot,
oneDeviceData,
SMP_PHY_CONTROL_HARD_RESET,
agNULL,
tdsaRotateQnumber(tiRoot, oneDeviceData)
);
}
}
return;
}
}
if (agIOStatus == OSSA_IO_ABORTED ||
agIOStatus == OSSA_IO_UNDERFLOW ||
agIOStatus == OSSA_IO_XFER_ERROR_BREAK ||
agIOStatus == OSSA_IO_XFER_ERROR_PHY_NOT_READY ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
agIOStatus == OSSA_IO_XFER_ERROR_NAK_RECEIVED ||
agIOStatus == OSSA_IO_XFER_ERROR_DMA ||
agIOStatus == OSSA_IO_XFER_ERROR_SATA_LINK_TIMEOUT ||
agIOStatus == OSSA_IO_XFER_ERROR_REJECTED_NCQ_MODE ||
agIOStatus == OSSA_IO_XFER_OPEN_RETRY_TIMEOUT ||
agIOStatus == OSSA_IO_NO_DEVICE ||
agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
agIOStatus == OSSA_IO_PORT_IN_RESET ||
agIOStatus == OSSA_IO_DS_NON_OPERATIONAL ||
agIOStatus == OSSA_IO_DS_IN_RECOVERY ||
agIOStatus == OSSA_IO_DS_IN_ERROR
)
{
TI_DBG1(("tdsaDiscoveryStartIDDevCB: OSSA_IO_OPEN_CNX_ERROR 0x%x\n", agIOStatus));
if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
{
satIOContext->pSatDevData->satPendingNONNCQIO--;
satIOContext->pSatDevData->satPendingIO--;
retry_status = sataLLIOStart(tiRoot,
&satIntIo->satIntTiIORequest,
&(oneDeviceData->tiDeviceHandle),
satIOContext->tiScsiXchg,
satIOContext);
if (retry_status != tiSuccess)
{
satDevData->ID_Retries = 0;
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
return;
}
satDevData->ID_Retries++;
tdIORequestBody->ioCompleted = agFALSE;
tdIORequestBody->ioStarted = agTRUE;
return;
}
else
{
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
if (tdsaAllShared->ResetInDiscovery != 0)
{
if (satDevData->NumOfIDRetries <= 0)
{
satDevData->NumOfIDRetries++;
satDevData->ID_Retries = 0;
tdsaPhyControlSend(tiRoot,
oneDeviceData,
SMP_PHY_CONTROL_HARD_RESET,
agNULL,
tdsaRotateQnumber(tiRoot, oneDeviceData)
);
}
}
return;
}
}
if ( agIOStatus != OSSA_IO_SUCCESS ||
(agIOStatus == OSSA_IO_SUCCESS && agFirstDword != agNULL && agIOInfoLen != 0)
)
{
#ifdef TD_DEBUG_ENABLE
satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
ataStatus = satPIOSetupHeader->status;
ataError = satPIOSetupHeader->error;
#endif
TI_DBG1(("tdsaDiscoveryStartIDDevCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
{
satIOContext->pSatDevData->satPendingNONNCQIO--;
satIOContext->pSatDevData->satPendingIO--;
retry_status = sataLLIOStart(tiRoot,
&satIntIo->satIntTiIORequest,
&(oneDeviceData->tiDeviceHandle),
satIOContext->tiScsiXchg,
satIOContext);
if (retry_status != tiSuccess)
{
satDevData->ID_Retries = 0;
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
return;
}
satDevData->ID_Retries++;
tdIORequestBody->ioCompleted = agFALSE;
tdIORequestBody->ioStarted = agTRUE;
return;
}
else
{
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
if (tdsaAllShared->ResetInDiscovery != 0)
{
if (satDevData->NumOfIDRetries <= 0)
{
satDevData->NumOfIDRetries++;
satDevData->ID_Retries = 0;
tdsaPhyControlSend(tiRoot,
oneDeviceData,
SMP_PHY_CONTROL_HARD_RESET,
agNULL,
tdsaRotateQnumber(tiRoot, oneDeviceData)
);
}
}
return;
}
}
TI_DBG3(("tdsaDiscoveryStartIDDevCB: Success\n"));
TI_DBG3(("tdsaDiscoveryStartIDDevCB: Success did %d\n", oneDeviceData->id));
tmpptr = (bit16*)sglVirtualAddr;
for (x=0; x < sizeof(agsaSATAIdentifyData_t)/sizeof(bit16); x++)
{
OSSA_READ_LE_16(AGROOT, &tmpptr_tmp, tmpptr, 0);
*tmpptr = tmpptr_tmp;
tmpptr++;
}
pSATAIdData = (agsaSATAIdentifyData_t *)sglVirtualAddr;
TI_DBG5(("tdsaDiscoveryStartIDDevCB: OS satOrgIOContext %p \n", satOrgIOContext));
TI_DBG5(("tdsaDiscoveryStartIDDevCB: TD satIOContext %p \n", satIOContext));
TI_DBG5(("tdsaDiscoveryStartIDDevCB: OS tiScsiXchg %p \n", satOrgIOContext->tiScsiXchg));
TI_DBG5(("tdsaDiscoveryStartIDDevCB: TD tiScsiXchg %p \n", satIOContext->tiScsiXchg));
satDevData->satIdentifyData = *pSATAIdData;
satDevData->IDDeviceValid = agTRUE;
#ifdef TD_INTERNAL_DEBUG
tdhexdump("tdsaDiscoveryStartIDDevCB ID Dev data",(bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
tdhexdump("tdsaDiscoveryStartIDDevCB Device ID Dev data",(bit8 *)&satDevData->satIdentifyData, sizeof(agsaSATAIdentifyData_t));
#endif
satSetDevInfo(satDevData,pSATAIdData);
satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
satFreeIntIoResource( tiRoot,
satDevData,
satIntIo);
if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
{
satNewIntIo = satAllocIntIoResource( tiRoot,
tiOrgIORequest,
satDevData,
0,
satNewIntIo);
if (satNewIntIo == agNULL)
{
TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n"));
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
return;
}
satNewIOContext = satPrepareNewIO(satNewIntIo,
tiOrgIORequest,
satDevData,
agNULL,
satOrgIOContext
);
retry_status = satSetFeatures(tiRoot,
&satNewIntIo->satIntTiIORequest,
satNewIOContext->ptiDeviceHandle,
&satNewIntIo->satIntTiScsiXchg,
satNewIOContext,
agFALSE);
if (retry_status != tiSuccess)
{
satFreeIntIoResource(tiRoot, satDevData, satIntIo);
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
}
}
else
{
ostiFreeMemory(
tiRoot,
tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
sizeof(tdIORequestBody_t)
);
if (onePortContext != agNULL)
{
if (onePortContext->DiscoveryState == ITD_DSTATE_COMPLETED)
{
TI_DBG1(("tdsaDiscoveryStartIDDevCB: ID completed after discovery is done; tiDeviceArrival\n"));
ostiInitiatorEvent(
tiRoot,
tiPortalContext,
agNULL,
tiIntrEventTypeDeviceChange,
tiDeviceArrival,
agNULL
);
}
}
else
{
TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext is NULL, wrong\n"));
}
}
TI_DBG3(("tdsaDiscoveryStartIDDevCB: end\n"));
return;
}
GLOBAL void satAbort(agsaRoot_t *agRoot,
satIOContext_t *satIOContext)
{
tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
tdIORequestBody_t *tdIORequestBody;
tdIORequestBody_t *tdAbortIORequestBody;
agsaIORequest_t *agToBeAbortedIORequest;
agsaIORequest_t *agAbortIORequest;
bit32 PhysUpper32;
bit32 PhysLower32;
bit32 memAllocStatus;
void *osMemHandle;
TI_DBG1(("satAbort: start\n"));
if (satIOContext == agNULL)
{
TI_DBG1(("satAbort: satIOContext is NULL, wrong\n"));
return;
}
tdIORequestBody = (tdIORequestBody_t *)satIOContext->tiRequestBody;
agToBeAbortedIORequest = (agsaIORequest_t *)&(tdIORequestBody->agIORequest);
memAllocStatus = ostiAllocMemory(
tiRoot,
&osMemHandle,
(void **)&tdAbortIORequestBody,
&PhysUpper32,
&PhysLower32,
8,
sizeof(tdIORequestBody_t),
agTRUE
);
if (memAllocStatus != tiSuccess)
{
TI_DBG1(("satAbort: ostiAllocMemory failed...\n"));
return;
}
if (tdAbortIORequestBody == agNULL)
{
TI_DBG1(("satAbort: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
return;
}
tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
tdAbortIORequestBody->tiDevHandle = tdIORequestBody->tiDevHandle;
agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
agAbortIORequest->osData = (void *) tdAbortIORequestBody;
agAbortIORequest->sdkData = agNULL;
saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agToBeAbortedIORequest, agNULL );
TI_DBG1(("satAbort: end\n"));
return;
}
osGLOBAL void
satSATADeviceReset( tiRoot_t *tiRoot,
tdsaDeviceData_t *oneDeviceData,
bit32 flag)
{
agsaRoot_t *agRoot;
tdsaPortContext_t *onePortContext;
bit32 i;
TI_DBG1(("satSATADeviceReset: start\n"));
agRoot = oneDeviceData->agRoot;
onePortContext = oneDeviceData->tdPortContext;
if (agRoot == agNULL)
{
TI_DBG1(("satSATADeviceReset: Error!!! agRoot is NULL\n"));
return;
}
if (onePortContext == agNULL)
{
TI_DBG1(("satSATADeviceReset: Error!!! onePortContext is NULL\n"));
return;
}
for(i=0;i<TD_MAX_NUM_PHYS;i++)
{
if (onePortContext->PhyIDList[i] == agTRUE)
{
saLocalPhyControl(agRoot, agNULL, tdsaRotateQnumber(tiRoot, agNULL), i, flag, agNULL);
}
}
return;
}
#endif