937 lines
34 KiB
C
937 lines
34 KiB
C
/*******************************************************************************
|
|
*Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
|
|
*
|
|
*Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
|
*that the following conditions are met:
|
|
*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
|
|
*following disclaimer.
|
|
*2. Redistributions in binary form must reproduce the above copyright notice,
|
|
*this list of conditions and the following disclaimer in the documentation and/or other materials provided
|
|
*with the distribution.
|
|
*
|
|
*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
|
|
|
|
********************************************************************************/
|
|
/*******************************************************************************/
|
|
/*! \file sasata.c
|
|
* \brief The file implements the functions to SATA IO
|
|
*
|
|
*/
|
|
/******************************************************************************/
|
|
#include <sys/cdefs.h>
|
|
__FBSDID("$FreeBSD$");
|
|
#include <dev/pms/config.h>
|
|
|
|
#include <dev/pms/RefTisa/sallsdk/spc/saglobal.h>
|
|
#ifdef SA_ENABLE_TRACE_FUNCTIONS
|
|
#ifdef siTraceFileID
|
|
#undef siTraceFileID
|
|
#endif
|
|
#define siTraceFileID 'M'
|
|
#endif
|
|
|
|
/******************************************************************************/
|
|
/*! \brief Start SATA command
|
|
*
|
|
* Start SATA command
|
|
*
|
|
* \param agRoot handles for this instance of SAS/SATA hardware
|
|
* \param queueNum
|
|
* \param agIORequest
|
|
* \param agDevHandle
|
|
* \param agRequestType
|
|
* \param agSATAReq
|
|
* \param agTag
|
|
* \param agCB
|
|
*
|
|
* \return If command is started successfully
|
|
* - \e AGSA_RC_SUCCESS command is started successfully
|
|
* - \e AGSA_RC_FAILURE command is not started successfully
|
|
*/
|
|
/*******************************************************************************/
|
|
GLOBAL bit32 saSATAStart(
|
|
agsaRoot_t *agRoot,
|
|
agsaIORequest_t *agIORequest,
|
|
bit32 queueNum,
|
|
agsaDevHandle_t *agDevHandle,
|
|
bit32 agRequestType,
|
|
agsaSATAInitiatorRequest_t *agSATAReq,
|
|
bit8 agTag,
|
|
ossaSATACompletedCB_t agCB
|
|
)
|
|
|
|
{
|
|
agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
|
|
mpiICQueue_t *circularQ = agNULL;
|
|
agsaDeviceDesc_t *pDevice = agNULL;
|
|
agsaPort_t *pPort = agNULL;
|
|
agsaIORequestDesc_t *pRequest = agNULL;
|
|
void *pMessage = agNULL;
|
|
agsaSgl_t *pSgl = agNULL;
|
|
bit32 *payload = agNULL;
|
|
bit32 deviceIndex = 0;
|
|
bit32 ret = AGSA_RC_SUCCESS, retVal = 0;
|
|
bit32 AtapDir = 0;
|
|
bit32 encryptFlags = 0;
|
|
bit16 size = 0;
|
|
bit16 opCode = 0;
|
|
bit8 inq = 0, outq = 0;
|
|
|
|
OSSA_INP_ENTER(agRoot);
|
|
smTraceFuncEnter(hpDBG_VERY_LOUD, "8a");
|
|
|
|
SA_DBG3(("saSATAStart: in\n"));
|
|
/* sanity check */
|
|
SA_ASSERT((agNULL != agRoot), "(saSATAStart) agRoot is NULL");
|
|
SA_ASSERT((agNULL != agIORequest), "(saSATAStart) agIORequest is NULL");
|
|
SA_ASSERT((agNULL != agDevHandle), "(saSATAStart) agDevHandle is NULL");
|
|
SA_ASSERT((agNULL != agSATAReq), "(saSATAStart) agSATAReq is NULL");
|
|
|
|
/* Assign inbound and outbound queue */
|
|
inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
|
|
outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
|
|
SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
|
|
|
|
/* Find the outgoing port for the device */
|
|
pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
|
|
SA_ASSERT((agNULL != pDevice), "(saSATAStart) pDevice is NULL");
|
|
|
|
pPort = pDevice->pPort;
|
|
SA_ASSERT((agNULL != pPort), "(saSATAStart) pPort is NULL");
|
|
|
|
/* SATA DIF is obsolete */
|
|
if (agSATAReq->option & AGSA_SATA_ENABLE_DIF)
|
|
{
|
|
return AGSA_RC_FAILURE;
|
|
}
|
|
|
|
/* find deviceID for IOMB */
|
|
deviceIndex = pDevice->DeviceMapIndex;
|
|
|
|
/* Get request from free IORequests */
|
|
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
|
|
pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
|
|
if ( agNULL != pRequest )
|
|
{
|
|
/* If free IOMB avaliable */
|
|
/* Remove the request from free list */
|
|
saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
|
|
|
|
/* Add the request to the pendingSTARequests list of the device */
|
|
pRequest->valid = agTRUE;
|
|
saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode));
|
|
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
|
|
|
|
if ((agSATAReq->option & AGSA_SATA_ENABLE_ENCRYPTION) ||
|
|
(agSATAReq->option & AGSA_SATA_ENABLE_DIF))
|
|
{
|
|
opCode = OPC_INB_SATA_DIF_ENC_OPSTART;
|
|
size = IOMB_SIZE128;
|
|
}
|
|
else
|
|
{
|
|
opCode = OPC_INB_SATA_HOST_OPSTART;
|
|
if (agRequestType == AGSA_SATA_PROTOCOL_NON_PKT ||
|
|
agRequestType == AGSA_SATA_PROTOCOL_H2D_PKT ||
|
|
agRequestType == AGSA_SATA_PROTOCOL_D2H_PKT)
|
|
size = IOMB_SIZE128;
|
|
else
|
|
size = IOMB_SIZE64;
|
|
}
|
|
/* If LL IO request entry avaliable */
|
|
/* set up pRequest */
|
|
pRequest->pIORequestContext = agIORequest;
|
|
pRequest->pDevice = pDevice;
|
|
pRequest->pPort = pPort;
|
|
pRequest->requestType = agRequestType;
|
|
pRequest->startTick = saRoot->timeTick;
|
|
pRequest->completionCB = (ossaSSPCompletedCB_t)agCB;
|
|
/* Set request to the sdkData of agIORequest */
|
|
agIORequest->sdkData = pRequest;
|
|
|
|
/* save tag and IOrequest pointer to IOMap */
|
|
saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
|
|
saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
|
|
|
|
#ifdef SA_LL_IBQ_PROTECT
|
|
ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
|
|
#endif /* SA_LL_IBQ_PROTECT */
|
|
|
|
/* get a free inbound queue entry */
|
|
circularQ = &saRoot->inboundQueue[inq];
|
|
retVal = mpiMsgFreeGet(circularQ, size, &pMessage);
|
|
|
|
if (AGSA_RC_FAILURE == retVal)
|
|
{
|
|
#ifdef SA_LL_IBQ_PROTECT
|
|
ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
|
|
#endif /* SA_LL_IBQ_PROTECT */
|
|
/* if not sending return to free list rare */
|
|
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
|
|
saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
|
|
pRequest->valid = agFALSE;
|
|
saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
|
|
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
|
|
|
|
SA_DBG3(("saSATAStart, error when get free IOMB\n"));
|
|
smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "8a");
|
|
ret = AGSA_RC_FAILURE;
|
|
goto ext;
|
|
}
|
|
|
|
/* return busy if inbound queue is full */
|
|
if (AGSA_RC_BUSY == retVal)
|
|
{
|
|
#ifdef SA_LL_IBQ_PROTECT
|
|
ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
|
|
#endif /* SA_LL_IBQ_PROTECT */
|
|
/* if not sending return to free list rare */
|
|
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
|
|
saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
|
|
pRequest->valid = agFALSE;
|
|
saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
|
|
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
|
|
|
|
SA_DBG1(("saSATAStart, no more IOMB\n"));
|
|
smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "8a");
|
|
ret = AGSA_RC_BUSY;
|
|
goto ext;
|
|
}
|
|
|
|
}
|
|
else /* If no LL IO request entry available */
|
|
{
|
|
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
|
|
SA_DBG1(("saSATAStart, No request from free list\n"));
|
|
smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "8a");
|
|
ret = AGSA_RC_BUSY;
|
|
goto ext;
|
|
}
|
|
|
|
payload = (bit32 *)pMessage;
|
|
SA_DBG4(("saSATAStart: Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage)));
|
|
|
|
|
|
switch ( agRequestType )
|
|
{
|
|
case AGSA_SATA_PROTOCOL_FPDMA_READ:
|
|
case AGSA_SATA_PROTOCOL_FPDMA_WRITE:
|
|
case AGSA_SATA_PROTOCOL_FPDMA_READ_M:
|
|
case AGSA_SATA_PROTOCOL_FPDMA_WRITE_M:
|
|
pSgl = &(agSATAReq->agSgl);
|
|
AtapDir = agRequestType & (AGSA_DIR_MASK | AGSA_SATA_ATAP_MASK);
|
|
if (agRequestType & AGSA_MSG)
|
|
{
|
|
/* set M bit */
|
|
AtapDir |= AGSA_MSG_BIT;
|
|
}
|
|
break;
|
|
case AGSA_SATA_PROTOCOL_DMA_READ:
|
|
case AGSA_SATA_PROTOCOL_DMA_WRITE:
|
|
case AGSA_SATA_PROTOCOL_DMA_READ_M:
|
|
case AGSA_SATA_PROTOCOL_DMA_WRITE_M:
|
|
case AGSA_SATA_PROTOCOL_PIO_READ_M:
|
|
case AGSA_SATA_PROTOCOL_PIO_WRITE_M:
|
|
case AGSA_SATA_PROTOCOL_PIO_READ:
|
|
case AGSA_SATA_PROTOCOL_PIO_WRITE:
|
|
case AGSA_SATA_PROTOCOL_H2D_PKT:
|
|
case AGSA_SATA_PROTOCOL_D2H_PKT:
|
|
agTag = 0; /* agTag not valid for these requests */
|
|
pSgl = &(agSATAReq->agSgl);
|
|
AtapDir = agRequestType & (AGSA_DIR_MASK | AGSA_SATA_ATAP_MASK);
|
|
if (agRequestType & AGSA_MSG)
|
|
{
|
|
/* set M bit */
|
|
AtapDir |= AGSA_MSG_BIT;
|
|
}
|
|
break;
|
|
|
|
case AGSA_SATA_PROTOCOL_NON_DATA:
|
|
case AGSA_SATA_PROTOCOL_NON_DATA_M:
|
|
case AGSA_SATA_PROTOCOL_NON_PKT:
|
|
agTag = 0; /* agTag not valid for these requests */
|
|
AtapDir = agRequestType & (AGSA_DIR_MASK | AGSA_SATA_ATAP_MASK);
|
|
if (agRequestType & AGSA_MSG)
|
|
{
|
|
/* set M bit */
|
|
AtapDir |= AGSA_MSG_BIT;
|
|
}
|
|
break;
|
|
|
|
case AGSA_SATA_PROTOCOL_SRST_ASSERT:
|
|
agTag = 0; /* agTag not valid for these requests */
|
|
AtapDir = AGSA_SATA_ATAP_SRST_ASSERT;
|
|
break;
|
|
|
|
case AGSA_SATA_PROTOCOL_SRST_DEASSERT:
|
|
agTag = 0; /* agTag not valid for these requests */
|
|
AtapDir = AGSA_SATA_ATAP_SRST_DEASSERT;
|
|
break;
|
|
|
|
case AGSA_SATA_PROTOCOL_DEV_RESET:
|
|
case AGSA_SATA_PROTOCOL_DEV_RESET_M: /* TestBase */
|
|
agTag = 0; /* agTag not valid for these requests */
|
|
AtapDir = AGSA_SATA_ATAP_PKT_DEVRESET;
|
|
if (agRequestType & AGSA_MSG)
|
|
{
|
|
/* set M bit */
|
|
AtapDir |= AGSA_MSG_BIT; /* TestBase */
|
|
}
|
|
break;
|
|
|
|
default:
|
|
SA_DBG1(("saSATAStart: (Unknown agRequestType) 0x%X \n",agRequestType));
|
|
SA_ASSERT((0), "saSATAStart: (Unknown agRequestType)");
|
|
|
|
break;
|
|
}
|
|
|
|
if ((AGSA_SATA_PROTOCOL_SRST_ASSERT == agRequestType) ||
|
|
(AGSA_SATA_PROTOCOL_SRST_DEASSERT == agRequestType) ||
|
|
(AGSA_SATA_PROTOCOL_DEV_RESET == agRequestType))
|
|
{
|
|
|
|
SA_DBG3(("saSATAStart:AGSA_SATA_PROTOCOL_SRST_DEASSERT AGSA_SATA_PROTOCOL_SRST_ASSERT\n"));
|
|
|
|
si_memset((void *)payload, 0, sizeof(agsaSATAStartCmd_t));
|
|
/* build IOMB DW 1 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t, tag), pRequest->HTag);
|
|
/* DWORD 2 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,deviceId ), deviceIndex);
|
|
/* DWORD 3 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,dataLen ), 0 );
|
|
/* DWORD 4 */
|
|
OSSA_WRITE_LE_32(agRoot,
|
|
payload,
|
|
OSSA_OFFSET_OF(agsaSATAStartCmd_t,optNCQTagataProt ),
|
|
(((agSATAReq->option & SATA_FIS_MASK) << SHIFT24) |
|
|
(agTag << SHIFT16) |
|
|
AtapDir));
|
|
|
|
si_memcpy((void *)(payload+4), (void *)&agSATAReq->fis.fisRegHostToDev, sizeof(agsaFisRegHostToDevice_t));
|
|
}
|
|
else
|
|
{
|
|
/* build IOMB DW 1 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t, tag), pRequest->HTag);
|
|
/* DWORD 2 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,deviceId ), deviceIndex);
|
|
/* DWORD 3 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,dataLen ), agSATAReq->dataLength );
|
|
|
|
/* Since we are writing the payload in order, check for any special modes now. */
|
|
if (agSATAReq->option & AGSA_SATA_ENABLE_ENCRYPTION)
|
|
{
|
|
SA_ASSERT((opCode == OPC_INB_SATA_DIF_ENC_OPSTART), "opcode");
|
|
SA_DBG4(("saSATAStart: 1 Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage)));
|
|
AtapDir |= AGSA_ENCRYPT_BIT;
|
|
}
|
|
|
|
if (agSATAReq->option & AGSA_SATA_ENABLE_DIF)
|
|
{
|
|
SA_ASSERT((opCode == OPC_INB_SATA_DIF_ENC_OPSTART), "opcode");
|
|
AtapDir |= AGSA_DIF_BIT;
|
|
}
|
|
#ifdef CCBUILD_TEST_EPL
|
|
if(agSATAReq->encrypt.enableEncryptionPerLA)
|
|
AtapDir |= (1 << SHIFT4); // enable EPL
|
|
#endif
|
|
/* DWORD 4 */
|
|
OSSA_WRITE_LE_32(agRoot,
|
|
payload,
|
|
OSSA_OFFSET_OF(agsaSATAStartCmd_t,optNCQTagataProt ),
|
|
(((agSATAReq->option & SATA_FIS_MASK) << SHIFT24) |
|
|
(agTag << SHIFT16) |
|
|
AtapDir));
|
|
|
|
/* DWORD 5 6 7 8 9 */
|
|
si_memcpy((void *)(payload+4), (void *)&agSATAReq->fis.fisRegHostToDev, sizeof(agsaFisRegHostToDevice_t));
|
|
/* DWORD 10 reserved */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,reserved1 ), 0 );
|
|
|
|
/* DWORD 11 reserved */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,reserved2 ), 0 );
|
|
|
|
SA_DBG4(("saSATAStart: 2 Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage)));
|
|
}
|
|
if (agSATAReq->option & AGSA_SATA_ENABLE_ENCRYPTION)
|
|
{
|
|
/* Write 10 dwords of zeroes as payload, skipping all DIF fields */
|
|
SA_DBG4(("saSATAStart: 2a Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage)));
|
|
if (opCode == OPC_INB_SATA_DIF_ENC_OPSTART)
|
|
{
|
|
/* DW 11 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Res_EPL_DESCL ),0 );
|
|
/* DW 12 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,resSKIPBYTES ),0 );
|
|
/* DW 13 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Res_DPL_DESCL_NDPLR ),0 );
|
|
/* DW 14 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Res_EDPL_DESCH ),0 );
|
|
/* DW 15 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,DIF_flags ),0 );
|
|
/* DW 16 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,udt ),0 );
|
|
/* DW 17 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,udtReplacementLo ),0 );
|
|
/* DW 18 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,udtReplacementHi ),0 );
|
|
/* DW 19 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,DIF_seed ),0 );
|
|
}
|
|
|
|
if (agSATAReq->option & AGSA_SATA_ENABLE_ENCRYPTION)
|
|
{
|
|
SA_ASSERT((opCode == OPC_INB_SATA_DIF_ENC_OPSTART), "opcode");
|
|
|
|
SA_DBG4(("saSATAStart: 3 Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage)));
|
|
/* Configure DWORD 20 */
|
|
encryptFlags = 0;
|
|
|
|
if (agSATAReq->encrypt.keyTagCheck == agTRUE)
|
|
{
|
|
encryptFlags |= AGSA_ENCRYPT_KEY_TAG_BIT;
|
|
}
|
|
|
|
if( agSATAReq->encrypt.cipherMode == agsaEncryptCipherModeXTS )
|
|
{
|
|
encryptFlags |= AGSA_ENCRYPT_XTS_Mode << SHIFT4;
|
|
}
|
|
|
|
encryptFlags |= agSATAReq->encrypt.dekInfo.dekTable << SHIFT2;
|
|
|
|
encryptFlags |= (agSATAReq->encrypt.dekInfo.dekIndex & 0xFFFFFF) << SHIFT8;
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,encryptFlagsLo ),encryptFlags );
|
|
|
|
/* Configure DWORD 21*/
|
|
/* This information is available in the sectorSizeIndex */
|
|
encryptFlags = agSATAReq->encrypt.sectorSizeIndex;
|
|
/*
|
|
* Set Region0 sectors count
|
|
*/
|
|
if(agSATAReq->encrypt.enableEncryptionPerLA)
|
|
{
|
|
encryptFlags |= (agSATAReq->encrypt.EncryptionPerLRegion0SecCount << SHIFT16);
|
|
}
|
|
|
|
encryptFlags |= (agSATAReq->encrypt.kekIndex) << SHIFT5;
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,encryptFlagsHi ),encryptFlags );
|
|
|
|
/* Configure DWORD 22*/
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,keyTagLo ), agSATAReq->encrypt.keyTag_W0 );
|
|
/* Configure DWORD 23 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,keyTagHi ), agSATAReq->encrypt.keyTag_W1 );
|
|
/* Configure DWORD 24 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W0 ), agSATAReq->encrypt.tweakVal_W0 );
|
|
/* Configure DWORD 25 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W1 ), agSATAReq->encrypt.tweakVal_W1 );
|
|
/* Configure DWORD 26 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W2 ), agSATAReq->encrypt.tweakVal_W2 );
|
|
/* Configure DWORD 27 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W3 ), agSATAReq->encrypt.tweakVal_W3 );
|
|
}
|
|
else
|
|
{
|
|
/* Write 8 dwords of zeros as payload, skipping all encryption fields */
|
|
if (opCode == OPC_INB_SATA_DIF_ENC_OPSTART)
|
|
{
|
|
/* Configure DWORD 22*/
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,keyTagLo ), 0 );
|
|
/* Configure DWORD 23 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,keyTagHi ), 0 );
|
|
/* Configure DWORD 24 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W0 ), 0 );
|
|
/* Configure DWORD 25 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W1 ), 0 );
|
|
/* Configure DWORD 26 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W2 ), 0 );
|
|
/* Configure DWORD 27 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W3 ), 0 );
|
|
}
|
|
}
|
|
|
|
SA_DBG4(("saSATAStart: 4 Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage)));
|
|
|
|
/* DWORD 11 13 14*/
|
|
if(agSATAReq->encrypt.enableEncryptionPerLA)
|
|
{
|
|
/* DWORD 11 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t, Res_EPL_DESCL),
|
|
agSATAReq->encrypt.EncryptionPerLAAddrLo);
|
|
/* DWORD 13 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t, Res_DPL_DESCL_NDPLR), 0);
|
|
/* DWORD 14 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t, Res_EDPL_DESCH),
|
|
agSATAReq->encrypt.EncryptionPerLAAddrHi);
|
|
}
|
|
else
|
|
{
|
|
/* DWORD 11 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t, Res_EPL_DESCL),0);
|
|
/* DW 13 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t, Res_DPL_DESCL_NDPLR), 0);
|
|
/* DWORD 14 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Res_EDPL_DESCH ),0 );
|
|
}
|
|
|
|
/* Configure DWORD 28 for encryption*/
|
|
if (pSgl)
|
|
{
|
|
/* Configure DWORD 28 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,AddrLow0 ), pSgl->sgLower );
|
|
/* Configure DWORD 29 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,AddrHi0 ), pSgl->sgUpper );
|
|
/* Configure DWORD 30 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Len0 ), pSgl->len );
|
|
/* Configure DWORD 31 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,E0 ), pSgl->extReserved );
|
|
}
|
|
else
|
|
{
|
|
/* Configure DWORD 28 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,AddrLow0 ), 0 );
|
|
/* Configure DWORD 29 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,AddrHi0 ), 0 );
|
|
/* Configure DWORD 30 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Len0 ), 0 );
|
|
/* Configure DWORD 31 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,E0 ), 0 );
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
SA_ASSERT((opCode == OPC_INB_SATA_HOST_OPSTART), "opcode");
|
|
if (pSgl)
|
|
{
|
|
/* Configure DWORD 12 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,AddrLow0 ), pSgl->sgLower );
|
|
/* Configure DWORD 13 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,AddrHi0 ), pSgl->sgUpper );
|
|
/* Configure DWORD 14 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,Len0 ), pSgl->len );
|
|
/* Configure DWORD 15 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,E0 ), pSgl->extReserved );
|
|
}
|
|
else
|
|
{
|
|
/* Configure DWORD 12 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,AddrLow0 ), 0 );
|
|
/* Configure DWORD 13 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,AddrHi0 ), 0 );
|
|
/* Configure DWORD 14 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,Len0 ), 0 );
|
|
/* Configure DWORD 15 */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,E0 ), 0 );
|
|
}
|
|
/* support ATAPI packet command */
|
|
if ((agRequestType == AGSA_SATA_PROTOCOL_NON_PKT ||
|
|
agRequestType == AGSA_SATA_PROTOCOL_H2D_PKT ||
|
|
agRequestType == AGSA_SATA_PROTOCOL_D2H_PKT))
|
|
{
|
|
/*DWORD 16 - 19 as SCSI CDB for support ATAPI Packet command*/
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,ATAPICDB ),
|
|
(bit32)(agSATAReq->scsiCDB[0]|(agSATAReq->scsiCDB[1]<<8)|(agSATAReq->scsiCDB[2]<<16)|(agSATAReq->scsiCDB[3]<<24)));
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,ATAPICDB )+ 4,
|
|
(bit32)(agSATAReq->scsiCDB[4]|(agSATAReq->scsiCDB[5]<<8)|(agSATAReq->scsiCDB[6]<<16)|(agSATAReq->scsiCDB[7]<<24)));
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,ATAPICDB )+ 8,
|
|
(bit32)(agSATAReq->scsiCDB[8]|(agSATAReq->scsiCDB[9]<<8)|(agSATAReq->scsiCDB[10]<<16)|(agSATAReq->scsiCDB[11]<<24)));
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,ATAPICDB )+ 12,
|
|
(bit32)(agSATAReq->scsiCDB[12]|(agSATAReq->scsiCDB[13]<<8)|(agSATAReq->scsiCDB[14]<<16)|(agSATAReq->scsiCDB[15]<<24)));
|
|
}
|
|
}
|
|
|
|
/* send IOMB to SPC */
|
|
ret = mpiMsgProduce(circularQ,
|
|
(void *)pMessage,
|
|
MPI_CATEGORY_SAS_SATA,
|
|
opCode,
|
|
outq,
|
|
(bit8)circularQ->priority);
|
|
|
|
#ifdef SA_LL_IBQ_PROTECT
|
|
ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
|
|
#endif /* SA_LL_IBQ_PROTECT */
|
|
|
|
#ifdef SALL_API_TEST
|
|
if (AGSA_RC_FAILURE != ret)
|
|
{
|
|
saRoot->LLCounters.IOCounter.numSataStarted++;
|
|
}
|
|
#endif
|
|
|
|
smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "8a");
|
|
|
|
ext:
|
|
OSSA_INP_LEAVE(agRoot);
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/*! \brief Abort SATA command
|
|
*
|
|
* Abort SATA command
|
|
*
|
|
* \param agRoot handles for this instance of SAS/SATA hardware
|
|
* \param queueNum inbound/outbound queue number
|
|
* \param agIORequest the IO Request descriptor
|
|
* \param agIOtoBeAborted
|
|
*
|
|
* \return If command is aborted successfully
|
|
* - \e AGSA_RC_SUCCESS command is aborted successfully
|
|
* - \e AGSA_RC_FAILURE command is not aborted successfully
|
|
*/
|
|
/*******************************************************************************/
|
|
GLOBAL bit32 saSATAAbort(
|
|
agsaRoot_t *agRoot,
|
|
agsaIORequest_t *agIORequest,
|
|
bit32 queueNum,
|
|
agsaDevHandle_t *agDevHandle,
|
|
bit32 flag,
|
|
void *abortParam,
|
|
ossaGenericAbortCB_t agCB
|
|
)
|
|
{
|
|
bit32 ret = AGSA_RC_SUCCESS, retVal;
|
|
agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
|
|
agsaIORequestDesc_t *pRequest;
|
|
agsaIORequestDesc_t *pRequestABT = agNULL;
|
|
agsaDeviceDesc_t *pDevice = agNULL;
|
|
agsaDeviceDesc_t *pDeviceABT = NULL;
|
|
agsaPort_t *pPort = agNULL;
|
|
mpiICQueue_t *circularQ;
|
|
void *pMessage;
|
|
agsaSATAAbortCmd_t *payload;
|
|
agsaIORequest_t *agIOToBeAborted;
|
|
bit8 inq, outq;
|
|
bit32 flag_copy = flag;
|
|
|
|
|
|
smTraceFuncEnter(hpDBG_VERY_LOUD,"8b");
|
|
|
|
/* sanity check */
|
|
SA_ASSERT((agNULL != agRoot), "");
|
|
SA_ASSERT((agNULL != agIORequest), "");
|
|
|
|
SA_DBG3(("saSATAAbort: Aborting request %p ITtoBeAborted %p\n", agIORequest, abortParam));
|
|
|
|
/* Assign inbound and outbound Ring Buffer */
|
|
inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
|
|
outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
|
|
SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
|
|
|
|
if( ABORT_SINGLE == (flag & ABORT_MASK) )
|
|
{
|
|
agIOToBeAborted = (agsaIORequest_t *)abortParam;
|
|
/* Get LL IORequest entry for saSATAAbort() */
|
|
pRequest = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData);
|
|
if (agNULL == pRequest)
|
|
{
|
|
/* no pRequest found - can not Abort */
|
|
SA_DBG1(("saSATAAbort: pRequest AGSA_RC_FAILURE\n"));
|
|
smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "8b");
|
|
return AGSA_RC_FAILURE;
|
|
}
|
|
/* Find the device the request sent to */
|
|
pDevice = pRequest->pDevice;
|
|
/* Get LL IORequest entry */
|
|
pRequestABT = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData);
|
|
/* Find the device the request sent to */
|
|
if (agNULL == pRequestABT)
|
|
{
|
|
/* no pRequestABT - can not find pDeviceABT */
|
|
SA_DBG1(("saSATAAbort: pRequestABT AGSA_RC_FAILURE\n"));
|
|
smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "8b");
|
|
return AGSA_RC_FAILURE;
|
|
}
|
|
pDeviceABT = pRequestABT->pDevice;
|
|
|
|
if (agNULL == pDeviceABT)
|
|
{
|
|
/* no deviceID - can not build IOMB */
|
|
SA_DBG1(("saSATAAbort: pDeviceABT AGSA_RC_FAILURE\n"));
|
|
|
|
smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "8b");
|
|
return AGSA_RC_FAILURE;
|
|
}
|
|
|
|
if (agNULL != pDevice)
|
|
{
|
|
/* Find the port the request was sent to */
|
|
pPort = pDevice->pPort;
|
|
}
|
|
|
|
/* Get request from free IORequests */
|
|
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
|
|
pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
|
|
}
|
|
else
|
|
{
|
|
if (ABORT_ALL == (flag & ABORT_MASK))
|
|
{
|
|
/* abort all */
|
|
/* Find the outgoing port for the device */
|
|
pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
|
|
pPort = pDevice->pPort;
|
|
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
|
|
pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
|
|
}
|
|
else
|
|
{
|
|
/* only support 00 and 01 for flag */
|
|
SA_DBG1(("saSATAAbort: flag AGSA_RC_FAILURE\n"));
|
|
smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "8b");
|
|
return AGSA_RC_FAILURE;
|
|
}
|
|
}
|
|
|
|
/* If no LL IO request entry avalable */
|
|
if ( agNULL == pRequest )
|
|
{
|
|
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
|
|
SA_DBG1(("saSATAAbort, No request from free list\n" ));
|
|
smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "8b");
|
|
return AGSA_RC_BUSY;
|
|
}
|
|
|
|
/* If free IOMB avaliable */
|
|
/* Remove the request from free list */
|
|
saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
|
|
|
|
SA_ASSERT((!pRequest->valid), "The pRequest is in use");
|
|
/* Add the request to the pendingIORequests list of the device */
|
|
pRequest->valid = agTRUE;
|
|
saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode));
|
|
/* set up pRequest */
|
|
|
|
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
|
|
|
|
pRequest->pIORequestContext = agIORequest;
|
|
pRequest->requestType = AGSA_SATA_REQTYPE;
|
|
pRequest->pDevice = pDevice;
|
|
pRequest->pPort = pPort;
|
|
pRequest->completionCB = (void*)agCB;
|
|
/* pRequest->abortCompletionCB = agCB; */
|
|
pRequest->startTick = saRoot->timeTick;
|
|
|
|
/* Set request to the sdkData of agIORequest */
|
|
agIORequest->sdkData = pRequest;
|
|
|
|
/* save tag and IOrequest pointer to IOMap */
|
|
saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
|
|
saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
|
|
|
|
#ifdef SA_LL_IBQ_PROTECT
|
|
ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
|
|
#endif /* SA_LL_IBQ_PROTECT */
|
|
|
|
/* If LL IO request entry avaliable */
|
|
/* Get a free inbound queue entry */
|
|
circularQ = &saRoot->inboundQueue[inq];
|
|
retVal = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage);
|
|
|
|
/* if message size is too large return failure */
|
|
if (AGSA_RC_FAILURE == retVal)
|
|
{
|
|
#ifdef SA_LL_IBQ_PROTECT
|
|
ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
|
|
#endif /* SA_LL_IBQ_PROTECT */
|
|
|
|
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
|
|
saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
|
|
pRequest->valid = agFALSE;
|
|
saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
|
|
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
|
|
|
|
SA_DBG1(("saSATAAbort, error when get free IOMB\n"));
|
|
smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "8b");
|
|
return AGSA_RC_FAILURE;
|
|
}
|
|
|
|
/* return busy if inbound queue is full */
|
|
if (AGSA_RC_BUSY == retVal)
|
|
{
|
|
#ifdef SA_LL_IBQ_PROTECT
|
|
ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
|
|
#endif /* SA_LL_IBQ_PROTECT */
|
|
|
|
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
|
|
saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
|
|
pRequest->valid = agFALSE;
|
|
saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
|
|
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
|
|
|
|
SA_DBG1(("saSATASAbort, no more IOMB\n"));
|
|
smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "8b");
|
|
return AGSA_RC_BUSY;
|
|
}
|
|
|
|
|
|
/* setup payload */
|
|
payload = (agsaSATAAbortCmd_t*)pMessage;
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, tag), pRequest->HTag);
|
|
|
|
if( ABORT_SINGLE == (flag & ABORT_MASK) )
|
|
{
|
|
/* If no device */
|
|
if ( agNULL == pDeviceABT )
|
|
{
|
|
#ifdef SA_LL_IBQ_PROTECT
|
|
ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
|
|
#endif /* SA_LL_IBQ_PROTECT */
|
|
|
|
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
|
|
saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
|
|
pRequest->valid = agFALSE;
|
|
saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
|
|
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
|
|
|
|
SA_DBG1(("saSATAAbort,no device\n" ));
|
|
smTraceFuncExit(hpDBG_VERY_LOUD, 'h', "8b");
|
|
return AGSA_RC_FAILURE;
|
|
}
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, deviceId), pDeviceABT->DeviceMapIndex);
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, HTagAbort), pRequestABT->HTag);
|
|
}
|
|
else
|
|
{
|
|
/* abort all */
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, deviceId), pDevice->DeviceMapIndex);
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, HTagAbort), 0);
|
|
}
|
|
|
|
if(flag & ABORT_TSDK_QUARANTINE)
|
|
{
|
|
if(smIS_SPCV(agRoot))
|
|
{
|
|
flag_copy &= ABORT_SCOPE;
|
|
flag_copy |= ABORT_QUARANTINE_SPCV;
|
|
}
|
|
}
|
|
OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, abortAll), flag_copy);
|
|
|
|
|
|
|
|
SA_DBG1(("saSATAAbort, HTag 0x%x HTagABT 0x%x deviceId 0x%x\n", payload->tag, payload->HTagAbort, payload->deviceId));
|
|
|
|
/* post the IOMB to SPC */
|
|
ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SATA_ABORT, outq, (bit8)circularQ->priority);
|
|
|
|
#ifdef SA_LL_IBQ_PROTECT
|
|
ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
|
|
#endif /* SA_LL_IBQ_PROTECT */
|
|
|
|
#ifdef SALL_API_TEST
|
|
if (AGSA_RC_FAILURE != ret)
|
|
{
|
|
saRoot->LLCounters.IOCounter.numSataAborted++;
|
|
}
|
|
#endif
|
|
|
|
siCountActiveIORequestsOnDevice( agRoot, payload->deviceId );
|
|
|
|
smTraceFuncExit(hpDBG_VERY_LOUD, 'i', "8b");
|
|
|
|
return ret;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/*! \brief Routine to handle for received SATA with data payload event
|
|
*
|
|
* The handle for received SATA with data payload event
|
|
*
|
|
* \param agRoot handles for this instance of SAS/SATA hardware
|
|
* \param pRequest the IO request descriptor
|
|
* \param agFirstDword pointer to the first Dword
|
|
* \param pResp pointer to the rest of SATA response
|
|
* \param lengthResp total length of SATA Response frame
|
|
*
|
|
* \return -void-
|
|
*/
|
|
/*******************************************************************************/
|
|
GLOBAL void siEventSATAResponseWtDataRcvd(
|
|
agsaRoot_t *agRoot,
|
|
agsaIORequestDesc_t *pRequest,
|
|
bit32 *agFirstDword,
|
|
bit32 *pResp,
|
|
bit32 lengthResp
|
|
)
|
|
{
|
|
agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
|
|
agsaDeviceDesc_t *pDevice;
|
|
#if defined(SALLSDK_DEBUG)
|
|
agsaFrameHandle_t frameHandle;
|
|
/* get frame handle */
|
|
frameHandle = (agsaFrameHandle_t)(pResp);
|
|
#endif /* SALLSDK_DEBUG */
|
|
|
|
smTraceFuncEnter(hpDBG_VERY_LOUD,"8c");
|
|
|
|
/* If the request is still valid */
|
|
if ( agTRUE == pRequest->valid )
|
|
{
|
|
/* get device */
|
|
pDevice = pRequest->pDevice;
|
|
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
|
|
|
|
/* Delete the request from the pendingIORequests */
|
|
saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
|
|
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
|
|
|
|
(*(ossaSATACompletedCB_t)(pRequest->completionCB))(agRoot,
|
|
pRequest->pIORequestContext,
|
|
OSSA_IO_SUCCESS,
|
|
agFirstDword,
|
|
lengthResp,
|
|
(void *)pResp);
|
|
|
|
ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
|
|
pRequest->valid = agFALSE;
|
|
/* return the request to free pool */
|
|
saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
|
|
ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
|
|
}
|
|
|
|
smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "8c");
|
|
|
|
return;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/*! \brief copy a SATA signature to another
|
|
*
|
|
* copy a SATA signature to another
|
|
*
|
|
* \param pDstSignature pointer to the destination signature
|
|
* \param pSrcSignature pointer to the source signature
|
|
*
|
|
* \return If they match
|
|
* - \e agTRUE match
|
|
* - \e agFALSE doesn't match
|
|
*/
|
|
/*******************************************************************************/
|
|
GLOBAL void siSATASignatureCpy(
|
|
bit8 *pDstSignature,
|
|
bit8 *pSrcSignature
|
|
)
|
|
{
|
|
bit32 i;
|
|
|
|
for ( i = 0; i < 5; i ++ )
|
|
{
|
|
pDstSignature[i] = pSrcSignature[i];
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|