1285242Sachim/******************************************************************************* 2285242Sachim*Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. 3285242Sachim* 4285242Sachim*Redistribution and use in source and binary forms, with or without modification, are permitted provided 5285242Sachim*that the following conditions are met: 6285242Sachim*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 7285242Sachim*following disclaimer. 8285242Sachim*2. Redistributions in binary form must reproduce the above copyright notice, 9285242Sachim*this list of conditions and the following disclaimer in the documentation and/or other materials provided 10285242Sachim*with the distribution. 11285242Sachim* 12285242Sachim*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 13285242Sachim*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 14285242Sachim*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 15285242Sachim*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 16285242Sachim*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 17285242Sachim*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 18285242Sachim*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 19285242Sachim*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 20285242Sachim 21285242Sachim********************************************************************************/ 22285242Sachim/*******************************************************************************/ 23285242Sachim/*! \file sasata.c 24285242Sachim * \brief The file implements the functions to SATA IO 25285242Sachim * 26285242Sachim */ 27285242Sachim/******************************************************************************/ 28285242Sachim#include <sys/cdefs.h> 29285242Sachim__FBSDID("$FreeBSD: releng/11.0/sys/dev/pms/RefTisa/sallsdk/spc/sasata.c 285242 2015-07-07 13:17:02Z achim $"); 30285242Sachim#include <dev/pms/config.h> 31285242Sachim 32285242Sachim#include <dev/pms/RefTisa/sallsdk/spc/saglobal.h> 33285242Sachim#ifdef SA_ENABLE_TRACE_FUNCTIONS 34285242Sachim#ifdef siTraceFileID 35285242Sachim#undef siTraceFileID 36285242Sachim#endif 37285242Sachim#define siTraceFileID 'M' 38285242Sachim#endif 39285242Sachim 40285242Sachim/******************************************************************************/ 41285242Sachim/*! \brief Start SATA command 42285242Sachim * 43285242Sachim * Start SATA command 44285242Sachim * 45285242Sachim * \param agRoot handles for this instance of SAS/SATA hardware 46285242Sachim * \param queueNum 47285242Sachim * \param agIORequest 48285242Sachim * \param agDevHandle 49285242Sachim * \param agRequestType 50285242Sachim * \param agSATAReq 51285242Sachim * \param agTag 52285242Sachim * \param agCB 53285242Sachim * 54285242Sachim * \return If command is started successfully 55285242Sachim * - \e AGSA_RC_SUCCESS command is started successfully 56285242Sachim * - \e AGSA_RC_FAILURE command is not started successfully 57285242Sachim */ 58285242Sachim/*******************************************************************************/ 59285242SachimGLOBAL bit32 saSATAStart( 60285242Sachim agsaRoot_t *agRoot, 61285242Sachim agsaIORequest_t *agIORequest, 62285242Sachim bit32 queueNum, 63285242Sachim agsaDevHandle_t *agDevHandle, 64285242Sachim bit32 agRequestType, 65285242Sachim agsaSATAInitiatorRequest_t *agSATAReq, 66285242Sachim bit8 agTag, 67285242Sachim ossaSATACompletedCB_t agCB 68285242Sachim ) 69285242Sachim 70285242Sachim{ 71285242Sachim agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 72285242Sachim mpiICQueue_t *circularQ = agNULL; 73285242Sachim agsaDeviceDesc_t *pDevice = agNULL; 74285242Sachim agsaPort_t *pPort = agNULL; 75285242Sachim agsaIORequestDesc_t *pRequest = agNULL; 76285242Sachim void *pMessage = agNULL; 77285242Sachim agsaSgl_t *pSgl = agNULL; 78285242Sachim bit32 *payload = agNULL; 79285242Sachim bit32 deviceIndex = 0; 80285242Sachim bit32 ret = AGSA_RC_SUCCESS, retVal = 0; 81285242Sachim bit32 AtapDir = 0; 82285242Sachim bit32 encryptFlags = 0; 83285242Sachim bit16 size = 0; 84285242Sachim bit16 opCode = 0; 85285242Sachim bit8 inq = 0, outq = 0; 86285242Sachim 87285242Sachim OSSA_INP_ENTER(agRoot); 88285242Sachim smTraceFuncEnter(hpDBG_VERY_LOUD, "8a"); 89285242Sachim 90285242Sachim SA_DBG3(("saSATAStart: in\n")); 91285242Sachim /* sanity check */ 92285242Sachim SA_ASSERT((agNULL != agRoot), "(saSATAStart) agRoot is NULL"); 93285242Sachim SA_ASSERT((agNULL != agIORequest), "(saSATAStart) agIORequest is NULL"); 94285242Sachim SA_ASSERT((agNULL != agDevHandle), "(saSATAStart) agDevHandle is NULL"); 95285242Sachim SA_ASSERT((agNULL != agSATAReq), "(saSATAStart) agSATAReq is NULL"); 96285242Sachim 97285242Sachim /* Assign inbound and outbound queue */ 98285242Sachim inq = (bit8)(queueNum & MPI_IB_NUM_MASK); 99285242Sachim outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT); 100285242Sachim SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range."); 101285242Sachim 102285242Sachim /* Find the outgoing port for the device */ 103285242Sachim pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData); 104285242Sachim SA_ASSERT((agNULL != pDevice), "(saSATAStart) pDevice is NULL"); 105285242Sachim 106285242Sachim pPort = pDevice->pPort; 107285242Sachim SA_ASSERT((agNULL != pPort), "(saSATAStart) pPort is NULL"); 108285242Sachim 109285242Sachim /* SATA DIF is obsolete */ 110285242Sachim if (agSATAReq->option & AGSA_SATA_ENABLE_DIF) 111285242Sachim { 112285242Sachim return AGSA_RC_FAILURE; 113285242Sachim } 114285242Sachim 115285242Sachim /* find deviceID for IOMB */ 116285242Sachim deviceIndex = pDevice->DeviceMapIndex; 117285242Sachim 118285242Sachim /* Get request from free IORequests */ 119285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 120285242Sachim pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 121285242Sachim if ( agNULL != pRequest ) 122285242Sachim { 123285242Sachim /* If free IOMB avaliable */ 124285242Sachim /* Remove the request from free list */ 125285242Sachim saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 126285242Sachim 127285242Sachim /* Add the request to the pendingSTARequests list of the device */ 128285242Sachim pRequest->valid = agTRUE; 129285242Sachim saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 130285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 131285242Sachim 132285242Sachim if ((agSATAReq->option & AGSA_SATA_ENABLE_ENCRYPTION) || 133285242Sachim (agSATAReq->option & AGSA_SATA_ENABLE_DIF)) 134285242Sachim { 135285242Sachim opCode = OPC_INB_SATA_DIF_ENC_OPSTART; 136285242Sachim size = IOMB_SIZE128; 137285242Sachim } 138285242Sachim else 139285242Sachim { 140285242Sachim opCode = OPC_INB_SATA_HOST_OPSTART; 141285242Sachim if (agRequestType == AGSA_SATA_PROTOCOL_NON_PKT || 142285242Sachim agRequestType == AGSA_SATA_PROTOCOL_H2D_PKT || 143285242Sachim agRequestType == AGSA_SATA_PROTOCOL_D2H_PKT) 144285242Sachim size = IOMB_SIZE128; 145285242Sachim else 146285242Sachim size = IOMB_SIZE64; 147285242Sachim } 148285242Sachim /* If LL IO request entry avaliable */ 149285242Sachim /* set up pRequest */ 150285242Sachim pRequest->pIORequestContext = agIORequest; 151285242Sachim pRequest->pDevice = pDevice; 152285242Sachim pRequest->pPort = pPort; 153285242Sachim pRequest->requestType = agRequestType; 154285242Sachim pRequest->startTick = saRoot->timeTick; 155285242Sachim pRequest->completionCB = (ossaSSPCompletedCB_t)agCB; 156285242Sachim /* Set request to the sdkData of agIORequest */ 157285242Sachim agIORequest->sdkData = pRequest; 158285242Sachim 159285242Sachim /* save tag and IOrequest pointer to IOMap */ 160285242Sachim saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 161285242Sachim saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 162285242Sachim 163285242Sachim#ifdef SA_LL_IBQ_PROTECT 164285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 165285242Sachim#endif /* SA_LL_IBQ_PROTECT */ 166285242Sachim 167285242Sachim /* get a free inbound queue entry */ 168285242Sachim circularQ = &saRoot->inboundQueue[inq]; 169285242Sachim retVal = mpiMsgFreeGet(circularQ, size, &pMessage); 170285242Sachim 171285242Sachim if (AGSA_RC_FAILURE == retVal) 172285242Sachim { 173285242Sachim#ifdef SA_LL_IBQ_PROTECT 174285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 175285242Sachim#endif /* SA_LL_IBQ_PROTECT */ 176285242Sachim /* if not sending return to free list rare */ 177285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 178285242Sachim saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 179285242Sachim pRequest->valid = agFALSE; 180285242Sachim saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 181285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 182285242Sachim 183285242Sachim SA_DBG3(("saSATAStart, error when get free IOMB\n")); 184285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "8a"); 185285242Sachim ret = AGSA_RC_FAILURE; 186285242Sachim goto ext; 187285242Sachim } 188285242Sachim 189285242Sachim /* return busy if inbound queue is full */ 190285242Sachim if (AGSA_RC_BUSY == retVal) 191285242Sachim { 192285242Sachim#ifdef SA_LL_IBQ_PROTECT 193285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 194285242Sachim#endif /* SA_LL_IBQ_PROTECT */ 195285242Sachim /* if not sending return to free list rare */ 196285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 197285242Sachim saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 198285242Sachim pRequest->valid = agFALSE; 199285242Sachim saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 200285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 201285242Sachim 202285242Sachim SA_DBG1(("saSATAStart, no more IOMB\n")); 203285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "8a"); 204285242Sachim ret = AGSA_RC_BUSY; 205285242Sachim goto ext; 206285242Sachim } 207285242Sachim 208285242Sachim } 209285242Sachim else /* If no LL IO request entry available */ 210285242Sachim { 211285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 212285242Sachim SA_DBG1(("saSATAStart, No request from free list\n")); 213285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "8a"); 214285242Sachim ret = AGSA_RC_BUSY; 215285242Sachim goto ext; 216285242Sachim } 217285242Sachim 218285242Sachim payload = (bit32 *)pMessage; 219285242Sachim SA_DBG4(("saSATAStart: Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage))); 220285242Sachim 221285242Sachim 222285242Sachim switch ( agRequestType ) 223285242Sachim { 224285242Sachim case AGSA_SATA_PROTOCOL_FPDMA_READ: 225285242Sachim case AGSA_SATA_PROTOCOL_FPDMA_WRITE: 226285242Sachim case AGSA_SATA_PROTOCOL_FPDMA_READ_M: 227285242Sachim case AGSA_SATA_PROTOCOL_FPDMA_WRITE_M: 228285242Sachim pSgl = &(agSATAReq->agSgl); 229285242Sachim AtapDir = agRequestType & (AGSA_DIR_MASK | AGSA_SATA_ATAP_MASK); 230285242Sachim if (agRequestType & AGSA_MSG) 231285242Sachim { 232285242Sachim /* set M bit */ 233285242Sachim AtapDir |= AGSA_MSG_BIT; 234285242Sachim } 235285242Sachim break; 236285242Sachim case AGSA_SATA_PROTOCOL_DMA_READ: 237285242Sachim case AGSA_SATA_PROTOCOL_DMA_WRITE: 238285242Sachim case AGSA_SATA_PROTOCOL_DMA_READ_M: 239285242Sachim case AGSA_SATA_PROTOCOL_DMA_WRITE_M: 240285242Sachim case AGSA_SATA_PROTOCOL_PIO_READ_M: 241285242Sachim case AGSA_SATA_PROTOCOL_PIO_WRITE_M: 242285242Sachim case AGSA_SATA_PROTOCOL_PIO_READ: 243285242Sachim case AGSA_SATA_PROTOCOL_PIO_WRITE: 244285242Sachim case AGSA_SATA_PROTOCOL_H2D_PKT: 245285242Sachim case AGSA_SATA_PROTOCOL_D2H_PKT: 246285242Sachim agTag = 0; /* agTag not valid for these requests */ 247285242Sachim pSgl = &(agSATAReq->agSgl); 248285242Sachim AtapDir = agRequestType & (AGSA_DIR_MASK | AGSA_SATA_ATAP_MASK); 249285242Sachim if (agRequestType & AGSA_MSG) 250285242Sachim { 251285242Sachim /* set M bit */ 252285242Sachim AtapDir |= AGSA_MSG_BIT; 253285242Sachim } 254285242Sachim break; 255285242Sachim 256285242Sachim case AGSA_SATA_PROTOCOL_NON_DATA: 257285242Sachim case AGSA_SATA_PROTOCOL_NON_DATA_M: 258285242Sachim case AGSA_SATA_PROTOCOL_NON_PKT: 259285242Sachim agTag = 0; /* agTag not valid for these requests */ 260285242Sachim AtapDir = agRequestType & (AGSA_DIR_MASK | AGSA_SATA_ATAP_MASK); 261285242Sachim if (agRequestType & AGSA_MSG) 262285242Sachim { 263285242Sachim /* set M bit */ 264285242Sachim AtapDir |= AGSA_MSG_BIT; 265285242Sachim } 266285242Sachim break; 267285242Sachim 268285242Sachim case AGSA_SATA_PROTOCOL_SRST_ASSERT: 269285242Sachim agTag = 0; /* agTag not valid for these requests */ 270285242Sachim AtapDir = AGSA_SATA_ATAP_SRST_ASSERT; 271285242Sachim break; 272285242Sachim 273285242Sachim case AGSA_SATA_PROTOCOL_SRST_DEASSERT: 274285242Sachim agTag = 0; /* agTag not valid for these requests */ 275285242Sachim AtapDir = AGSA_SATA_ATAP_SRST_DEASSERT; 276285242Sachim break; 277285242Sachim 278285242Sachim case AGSA_SATA_PROTOCOL_DEV_RESET: 279285242Sachim case AGSA_SATA_PROTOCOL_DEV_RESET_M: /* TestBase */ 280285242Sachim agTag = 0; /* agTag not valid for these requests */ 281285242Sachim AtapDir = AGSA_SATA_ATAP_PKT_DEVRESET; 282285242Sachim if (agRequestType & AGSA_MSG) 283285242Sachim { 284285242Sachim /* set M bit */ 285285242Sachim AtapDir |= AGSA_MSG_BIT; /* TestBase */ 286285242Sachim } 287285242Sachim break; 288285242Sachim 289285242Sachim default: 290285242Sachim SA_DBG1(("saSATAStart: (Unknown agRequestType) 0x%X \n",agRequestType)); 291285242Sachim SA_ASSERT((0), "saSATAStart: (Unknown agRequestType)"); 292285242Sachim 293285242Sachim break; 294285242Sachim } 295285242Sachim 296285242Sachim if ((AGSA_SATA_PROTOCOL_SRST_ASSERT == agRequestType) || 297285242Sachim (AGSA_SATA_PROTOCOL_SRST_DEASSERT == agRequestType) || 298285242Sachim (AGSA_SATA_PROTOCOL_DEV_RESET == agRequestType)) 299285242Sachim { 300285242Sachim 301285242Sachim SA_DBG3(("saSATAStart:AGSA_SATA_PROTOCOL_SRST_DEASSERT AGSA_SATA_PROTOCOL_SRST_ASSERT\n")); 302285242Sachim 303285242Sachim si_memset((void *)payload, 0, sizeof(agsaSATAStartCmd_t)); 304285242Sachim /* build IOMB DW 1 */ 305285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t, tag), pRequest->HTag); 306285242Sachim /* DWORD 2 */ 307285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,deviceId ), deviceIndex); 308285242Sachim /* DWORD 3 */ 309285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,dataLen ), 0 ); 310285242Sachim /* DWORD 4 */ 311285242Sachim OSSA_WRITE_LE_32(agRoot, 312285242Sachim payload, 313285242Sachim OSSA_OFFSET_OF(agsaSATAStartCmd_t,optNCQTagataProt ), 314285242Sachim (((agSATAReq->option & SATA_FIS_MASK) << SHIFT24) | 315285242Sachim (agTag << SHIFT16) | 316285242Sachim AtapDir)); 317285242Sachim 318285242Sachim si_memcpy((void *)(payload+4), (void *)&agSATAReq->fis.fisRegHostToDev, sizeof(agsaFisRegHostToDevice_t)); 319285242Sachim } 320285242Sachim else 321285242Sachim { 322285242Sachim /* build IOMB DW 1 */ 323285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t, tag), pRequest->HTag); 324285242Sachim /* DWORD 2 */ 325285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,deviceId ), deviceIndex); 326285242Sachim /* DWORD 3 */ 327285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,dataLen ), agSATAReq->dataLength ); 328285242Sachim 329285242Sachim /* Since we are writing the payload in order, check for any special modes now. */ 330285242Sachim if (agSATAReq->option & AGSA_SATA_ENABLE_ENCRYPTION) 331285242Sachim { 332285242Sachim SA_ASSERT((opCode == OPC_INB_SATA_DIF_ENC_OPSTART), "opcode"); 333285242Sachim SA_DBG4(("saSATAStart: 1 Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage))); 334285242Sachim AtapDir |= AGSA_ENCRYPT_BIT; 335285242Sachim } 336285242Sachim 337285242Sachim if (agSATAReq->option & AGSA_SATA_ENABLE_DIF) 338285242Sachim { 339285242Sachim SA_ASSERT((opCode == OPC_INB_SATA_DIF_ENC_OPSTART), "opcode"); 340285242Sachim AtapDir |= AGSA_DIF_BIT; 341285242Sachim } 342285242Sachim#ifdef CCBUILD_TEST_EPL 343285242Sachim if(agSATAReq->encrypt.enableEncryptionPerLA) 344285242Sachim AtapDir |= (1 << SHIFT4); // enable EPL 345285242Sachim#endif 346285242Sachim /* DWORD 4 */ 347285242Sachim OSSA_WRITE_LE_32(agRoot, 348285242Sachim payload, 349285242Sachim OSSA_OFFSET_OF(agsaSATAStartCmd_t,optNCQTagataProt ), 350285242Sachim (((agSATAReq->option & SATA_FIS_MASK) << SHIFT24) | 351285242Sachim (agTag << SHIFT16) | 352285242Sachim AtapDir)); 353285242Sachim 354285242Sachim /* DWORD 5 6 7 8 9 */ 355285242Sachim si_memcpy((void *)(payload+4), (void *)&agSATAReq->fis.fisRegHostToDev, sizeof(agsaFisRegHostToDevice_t)); 356285242Sachim /* DWORD 10 reserved */ 357285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,reserved1 ), 0 ); 358285242Sachim 359285242Sachim /* DWORD 11 reserved */ 360285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,reserved2 ), 0 ); 361285242Sachim 362285242Sachim SA_DBG4(("saSATAStart: 2 Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage))); 363285242Sachim } 364285242Sachim if (agSATAReq->option & AGSA_SATA_ENABLE_ENCRYPTION) 365285242Sachim { 366285242Sachim /* Write 10 dwords of zeroes as payload, skipping all DIF fields */ 367285242Sachim SA_DBG4(("saSATAStart: 2a Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage))); 368285242Sachim if (opCode == OPC_INB_SATA_DIF_ENC_OPSTART) 369285242Sachim { 370285242Sachim /* DW 11 */ 371285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Res_EPL_DESCL ),0 ); 372285242Sachim /* DW 12 */ 373285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,resSKIPBYTES ),0 ); 374285242Sachim /* DW 13 */ 375285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Res_DPL_DESCL_NDPLR ),0 ); 376285242Sachim /* DW 14 */ 377285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Res_EDPL_DESCH ),0 ); 378285242Sachim /* DW 15 */ 379285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,DIF_flags ),0 ); 380285242Sachim /* DW 16 */ 381285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,udt ),0 ); 382285242Sachim /* DW 17 */ 383285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,udtReplacementLo ),0 ); 384285242Sachim /* DW 18 */ 385285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,udtReplacementHi ),0 ); 386285242Sachim /* DW 19 */ 387285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,DIF_seed ),0 ); 388285242Sachim } 389285242Sachim 390285242Sachim if (agSATAReq->option & AGSA_SATA_ENABLE_ENCRYPTION) 391285242Sachim { 392285242Sachim SA_ASSERT((opCode == OPC_INB_SATA_DIF_ENC_OPSTART), "opcode"); 393285242Sachim 394285242Sachim SA_DBG4(("saSATAStart: 3 Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage))); 395285242Sachim /* Configure DWORD 20 */ 396285242Sachim encryptFlags = 0; 397285242Sachim 398285242Sachim if (agSATAReq->encrypt.keyTagCheck == agTRUE) 399285242Sachim { 400285242Sachim encryptFlags |= AGSA_ENCRYPT_KEY_TAG_BIT; 401285242Sachim } 402285242Sachim 403285242Sachim if( agSATAReq->encrypt.cipherMode == agsaEncryptCipherModeXTS ) 404285242Sachim { 405285242Sachim encryptFlags |= AGSA_ENCRYPT_XTS_Mode << SHIFT4; 406285242Sachim } 407285242Sachim 408285242Sachim encryptFlags |= agSATAReq->encrypt.dekInfo.dekTable << SHIFT2; 409285242Sachim 410285242Sachim encryptFlags |= (agSATAReq->encrypt.dekInfo.dekIndex & 0xFFFFFF) << SHIFT8; 411285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,encryptFlagsLo ),encryptFlags ); 412285242Sachim 413285242Sachim /* Configure DWORD 21*/ 414285242Sachim /* This information is available in the sectorSizeIndex */ 415285242Sachim encryptFlags = agSATAReq->encrypt.sectorSizeIndex; 416285242Sachim /* 417285242Sachim * Set Region0 sectors count 418285242Sachim */ 419285242Sachim if(agSATAReq->encrypt.enableEncryptionPerLA) 420285242Sachim { 421285242Sachim encryptFlags |= (agSATAReq->encrypt.EncryptionPerLRegion0SecCount << SHIFT16); 422285242Sachim } 423285242Sachim 424285242Sachim encryptFlags |= (agSATAReq->encrypt.kekIndex) << SHIFT5; 425285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,encryptFlagsHi ),encryptFlags ); 426285242Sachim 427285242Sachim /* Configure DWORD 22*/ 428285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,keyTagLo ), agSATAReq->encrypt.keyTag_W0 ); 429285242Sachim /* Configure DWORD 23 */ 430285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,keyTagHi ), agSATAReq->encrypt.keyTag_W1 ); 431285242Sachim /* Configure DWORD 24 */ 432285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W0 ), agSATAReq->encrypt.tweakVal_W0 ); 433285242Sachim /* Configure DWORD 25 */ 434285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W1 ), agSATAReq->encrypt.tweakVal_W1 ); 435285242Sachim /* Configure DWORD 26 */ 436285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W2 ), agSATAReq->encrypt.tweakVal_W2 ); 437285242Sachim /* Configure DWORD 27 */ 438285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W3 ), agSATAReq->encrypt.tweakVal_W3 ); 439285242Sachim } 440285242Sachim else 441285242Sachim { 442285242Sachim /* Write 8 dwords of zeros as payload, skipping all encryption fields */ 443285242Sachim if (opCode == OPC_INB_SATA_DIF_ENC_OPSTART) 444285242Sachim { 445285242Sachim /* Configure DWORD 22*/ 446285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,keyTagLo ), 0 ); 447285242Sachim /* Configure DWORD 23 */ 448285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,keyTagHi ), 0 ); 449285242Sachim /* Configure DWORD 24 */ 450285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W0 ), 0 ); 451285242Sachim /* Configure DWORD 25 */ 452285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W1 ), 0 ); 453285242Sachim /* Configure DWORD 26 */ 454285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W2 ), 0 ); 455285242Sachim /* Configure DWORD 27 */ 456285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W3 ), 0 ); 457285242Sachim } 458285242Sachim } 459285242Sachim 460285242Sachim SA_DBG4(("saSATAStart: 4 Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage))); 461285242Sachim 462285242Sachim /* DWORD 11 13 14*/ 463285242Sachim if(agSATAReq->encrypt.enableEncryptionPerLA) 464285242Sachim { 465285242Sachim /* DWORD 11 */ 466285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t, Res_EPL_DESCL), 467285242Sachim agSATAReq->encrypt.EncryptionPerLAAddrLo); 468285242Sachim /* DWORD 13 */ 469285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t, Res_DPL_DESCL_NDPLR), 0); 470285242Sachim /* DWORD 14 */ 471285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t, Res_EDPL_DESCH), 472285242Sachim agSATAReq->encrypt.EncryptionPerLAAddrHi); 473285242Sachim } 474285242Sachim else 475285242Sachim { 476285242Sachim /* DWORD 11 */ 477285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t, Res_EPL_DESCL),0); 478285242Sachim /* DW 13 */ 479285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t, Res_DPL_DESCL_NDPLR), 0); 480285242Sachim /* DWORD 14 */ 481285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Res_EDPL_DESCH ),0 ); 482285242Sachim } 483285242Sachim 484285242Sachim /* Configure DWORD 28 for encryption*/ 485285242Sachim if (pSgl) 486285242Sachim { 487285242Sachim /* Configure DWORD 28 */ 488285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,AddrLow0 ), pSgl->sgLower ); 489285242Sachim /* Configure DWORD 29 */ 490285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,AddrHi0 ), pSgl->sgUpper ); 491285242Sachim /* Configure DWORD 30 */ 492285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Len0 ), pSgl->len ); 493285242Sachim /* Configure DWORD 31 */ 494285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,E0 ), pSgl->extReserved ); 495285242Sachim } 496285242Sachim else 497285242Sachim { 498285242Sachim /* Configure DWORD 28 */ 499285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,AddrLow0 ), 0 ); 500285242Sachim /* Configure DWORD 29 */ 501285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,AddrHi0 ), 0 ); 502285242Sachim /* Configure DWORD 30 */ 503285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Len0 ), 0 ); 504285242Sachim /* Configure DWORD 31 */ 505285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,E0 ), 0 ); 506285242Sachim } 507285242Sachim 508285242Sachim } 509285242Sachim else 510285242Sachim { 511285242Sachim SA_ASSERT((opCode == OPC_INB_SATA_HOST_OPSTART), "opcode"); 512285242Sachim if (pSgl) 513285242Sachim { 514285242Sachim /* Configure DWORD 12 */ 515285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,AddrLow0 ), pSgl->sgLower ); 516285242Sachim /* Configure DWORD 13 */ 517285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,AddrHi0 ), pSgl->sgUpper ); 518285242Sachim /* Configure DWORD 14 */ 519285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,Len0 ), pSgl->len ); 520285242Sachim /* Configure DWORD 15 */ 521285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,E0 ), pSgl->extReserved ); 522285242Sachim } 523285242Sachim else 524285242Sachim { 525285242Sachim /* Configure DWORD 12 */ 526285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,AddrLow0 ), 0 ); 527285242Sachim /* Configure DWORD 13 */ 528285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,AddrHi0 ), 0 ); 529285242Sachim /* Configure DWORD 14 */ 530285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,Len0 ), 0 ); 531285242Sachim /* Configure DWORD 15 */ 532285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,E0 ), 0 ); 533285242Sachim } 534285242Sachim /* support ATAPI packet command */ 535285242Sachim if ((agRequestType == AGSA_SATA_PROTOCOL_NON_PKT || 536285242Sachim agRequestType == AGSA_SATA_PROTOCOL_H2D_PKT || 537285242Sachim agRequestType == AGSA_SATA_PROTOCOL_D2H_PKT)) 538285242Sachim { 539285242Sachim /*DWORD 16 - 19 as SCSI CDB for support ATAPI Packet command*/ 540285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,ATAPICDB ), 541285242Sachim (bit32)(agSATAReq->scsiCDB[0]|(agSATAReq->scsiCDB[1]<<8)|(agSATAReq->scsiCDB[2]<<16)|(agSATAReq->scsiCDB[3]<<24))); 542285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,ATAPICDB )+ 4, 543285242Sachim (bit32)(agSATAReq->scsiCDB[4]|(agSATAReq->scsiCDB[5]<<8)|(agSATAReq->scsiCDB[6]<<16)|(agSATAReq->scsiCDB[7]<<24))); 544285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,ATAPICDB )+ 8, 545285242Sachim (bit32)(agSATAReq->scsiCDB[8]|(agSATAReq->scsiCDB[9]<<8)|(agSATAReq->scsiCDB[10]<<16)|(agSATAReq->scsiCDB[11]<<24))); 546285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,ATAPICDB )+ 12, 547285242Sachim (bit32)(agSATAReq->scsiCDB[12]|(agSATAReq->scsiCDB[13]<<8)|(agSATAReq->scsiCDB[14]<<16)|(agSATAReq->scsiCDB[15]<<24))); 548285242Sachim } 549285242Sachim } 550285242Sachim 551285242Sachim /* send IOMB to SPC */ 552285242Sachim ret = mpiMsgProduce(circularQ, 553285242Sachim (void *)pMessage, 554285242Sachim MPI_CATEGORY_SAS_SATA, 555285242Sachim opCode, 556285242Sachim outq, 557285242Sachim (bit8)circularQ->priority); 558285242Sachim 559285242Sachim#ifdef SA_LL_IBQ_PROTECT 560285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 561285242Sachim#endif /* SA_LL_IBQ_PROTECT */ 562285242Sachim 563285242Sachim#ifdef SALL_API_TEST 564285242Sachim if (AGSA_RC_FAILURE != ret) 565285242Sachim { 566285242Sachim saRoot->LLCounters.IOCounter.numSataStarted++; 567285242Sachim } 568285242Sachim#endif 569285242Sachim 570285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "8a"); 571285242Sachim 572285242Sachimext: 573285242Sachim OSSA_INP_LEAVE(agRoot); 574285242Sachim return ret; 575285242Sachim} 576285242Sachim 577285242Sachim/******************************************************************************/ 578285242Sachim/*! \brief Abort SATA command 579285242Sachim * 580285242Sachim * Abort SATA command 581285242Sachim * 582285242Sachim * \param agRoot handles for this instance of SAS/SATA hardware 583285242Sachim * \param queueNum inbound/outbound queue number 584285242Sachim * \param agIORequest the IO Request descriptor 585285242Sachim * \param agIOtoBeAborted 586285242Sachim * 587285242Sachim * \return If command is aborted successfully 588285242Sachim * - \e AGSA_RC_SUCCESS command is aborted successfully 589285242Sachim * - \e AGSA_RC_FAILURE command is not aborted successfully 590285242Sachim */ 591285242Sachim/*******************************************************************************/ 592285242SachimGLOBAL bit32 saSATAAbort( 593285242Sachim agsaRoot_t *agRoot, 594285242Sachim agsaIORequest_t *agIORequest, 595285242Sachim bit32 queueNum, 596285242Sachim agsaDevHandle_t *agDevHandle, 597285242Sachim bit32 flag, 598285242Sachim void *abortParam, 599285242Sachim ossaGenericAbortCB_t agCB 600285242Sachim ) 601285242Sachim{ 602285242Sachim bit32 ret = AGSA_RC_SUCCESS, retVal; 603285242Sachim agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 604285242Sachim agsaIORequestDesc_t *pRequest; 605285242Sachim agsaIORequestDesc_t *pRequestABT = agNULL; 606285242Sachim agsaDeviceDesc_t *pDevice = agNULL; 607285242Sachim agsaDeviceDesc_t *pDeviceABT = NULL; 608285242Sachim agsaPort_t *pPort = agNULL; 609285242Sachim mpiICQueue_t *circularQ; 610285242Sachim void *pMessage; 611285242Sachim agsaSATAAbortCmd_t *payload; 612285242Sachim agsaIORequest_t *agIOToBeAborted; 613285242Sachim bit8 inq, outq; 614285242Sachim bit32 flag_copy = flag; 615285242Sachim 616285242Sachim 617285242Sachim smTraceFuncEnter(hpDBG_VERY_LOUD,"8b"); 618285242Sachim 619285242Sachim /* sanity check */ 620285242Sachim SA_ASSERT((agNULL != agRoot), ""); 621285242Sachim SA_ASSERT((agNULL != agIORequest), ""); 622285242Sachim 623285242Sachim SA_DBG3(("saSATAAbort: Aborting request %p ITtoBeAborted %p\n", agIORequest, abortParam)); 624285242Sachim 625285242Sachim /* Assign inbound and outbound Ring Buffer */ 626285242Sachim inq = (bit8)(queueNum & MPI_IB_NUM_MASK); 627285242Sachim outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT); 628285242Sachim SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range."); 629285242Sachim 630285242Sachim if( ABORT_SINGLE == (flag & ABORT_MASK) ) 631285242Sachim { 632285242Sachim agIOToBeAborted = (agsaIORequest_t *)abortParam; 633285242Sachim /* Get LL IORequest entry for saSATAAbort() */ 634285242Sachim pRequest = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData); 635285242Sachim if (agNULL == pRequest) 636285242Sachim { 637285242Sachim /* no pRequest found - can not Abort */ 638285242Sachim SA_DBG1(("saSATAAbort: pRequest AGSA_RC_FAILURE\n")); 639285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "8b"); 640285242Sachim return AGSA_RC_FAILURE; 641285242Sachim } 642285242Sachim /* Find the device the request sent to */ 643285242Sachim pDevice = pRequest->pDevice; 644285242Sachim /* Get LL IORequest entry */ 645285242Sachim pRequestABT = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData); 646285242Sachim /* Find the device the request sent to */ 647285242Sachim if (agNULL == pRequestABT) 648285242Sachim { 649285242Sachim /* no pRequestABT - can not find pDeviceABT */ 650285242Sachim SA_DBG1(("saSATAAbort: pRequestABT AGSA_RC_FAILURE\n")); 651285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "8b"); 652285242Sachim return AGSA_RC_FAILURE; 653285242Sachim } 654285242Sachim pDeviceABT = pRequestABT->pDevice; 655285242Sachim 656285242Sachim if (agNULL == pDeviceABT) 657285242Sachim { 658285242Sachim /* no deviceID - can not build IOMB */ 659285242Sachim SA_DBG1(("saSATAAbort: pDeviceABT AGSA_RC_FAILURE\n")); 660285242Sachim 661285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "8b"); 662285242Sachim return AGSA_RC_FAILURE; 663285242Sachim } 664285242Sachim 665285242Sachim if (agNULL != pDevice) 666285242Sachim { 667285242Sachim /* Find the port the request was sent to */ 668285242Sachim pPort = pDevice->pPort; 669285242Sachim } 670285242Sachim 671285242Sachim /* Get request from free IORequests */ 672285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 673285242Sachim pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 674285242Sachim } 675285242Sachim else 676285242Sachim { 677285242Sachim if (ABORT_ALL == (flag & ABORT_MASK)) 678285242Sachim { 679285242Sachim /* abort all */ 680285242Sachim /* Find the outgoing port for the device */ 681285242Sachim pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData); 682285242Sachim pPort = pDevice->pPort; 683285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 684285242Sachim pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 685285242Sachim } 686285242Sachim else 687285242Sachim { 688285242Sachim /* only support 00 and 01 for flag */ 689285242Sachim SA_DBG1(("saSATAAbort: flag AGSA_RC_FAILURE\n")); 690285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "8b"); 691285242Sachim return AGSA_RC_FAILURE; 692285242Sachim } 693285242Sachim } 694285242Sachim 695285242Sachim /* If no LL IO request entry avalable */ 696285242Sachim if ( agNULL == pRequest ) 697285242Sachim { 698285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 699285242Sachim SA_DBG1(("saSATAAbort, No request from free list\n" )); 700285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "8b"); 701285242Sachim return AGSA_RC_BUSY; 702285242Sachim } 703285242Sachim 704285242Sachim /* If free IOMB avaliable */ 705285242Sachim /* Remove the request from free list */ 706285242Sachim saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 707285242Sachim 708285242Sachim SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 709285242Sachim /* Add the request to the pendingIORequests list of the device */ 710285242Sachim pRequest->valid = agTRUE; 711285242Sachim saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 712285242Sachim /* set up pRequest */ 713285242Sachim 714285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 715285242Sachim 716285242Sachim pRequest->pIORequestContext = agIORequest; 717285242Sachim pRequest->requestType = AGSA_SATA_REQTYPE; 718285242Sachim pRequest->pDevice = pDevice; 719285242Sachim pRequest->pPort = pPort; 720285242Sachim pRequest->completionCB = (void*)agCB; 721285242Sachim/* pRequest->abortCompletionCB = agCB; */ 722285242Sachim pRequest->startTick = saRoot->timeTick; 723285242Sachim 724285242Sachim /* Set request to the sdkData of agIORequest */ 725285242Sachim agIORequest->sdkData = pRequest; 726285242Sachim 727285242Sachim /* save tag and IOrequest pointer to IOMap */ 728285242Sachim saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 729285242Sachim saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 730285242Sachim 731285242Sachim#ifdef SA_LL_IBQ_PROTECT 732285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 733285242Sachim#endif /* SA_LL_IBQ_PROTECT */ 734285242Sachim 735285242Sachim /* If LL IO request entry avaliable */ 736285242Sachim /* Get a free inbound queue entry */ 737285242Sachim circularQ = &saRoot->inboundQueue[inq]; 738285242Sachim retVal = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage); 739285242Sachim 740285242Sachim /* if message size is too large return failure */ 741285242Sachim if (AGSA_RC_FAILURE == retVal) 742285242Sachim { 743285242Sachim#ifdef SA_LL_IBQ_PROTECT 744285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 745285242Sachim#endif /* SA_LL_IBQ_PROTECT */ 746285242Sachim 747285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 748285242Sachim saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 749285242Sachim pRequest->valid = agFALSE; 750285242Sachim saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 751285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 752285242Sachim 753285242Sachim SA_DBG1(("saSATAAbort, error when get free IOMB\n")); 754285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "8b"); 755285242Sachim return AGSA_RC_FAILURE; 756285242Sachim } 757285242Sachim 758285242Sachim /* return busy if inbound queue is full */ 759285242Sachim if (AGSA_RC_BUSY == retVal) 760285242Sachim { 761285242Sachim#ifdef SA_LL_IBQ_PROTECT 762285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 763285242Sachim#endif /* SA_LL_IBQ_PROTECT */ 764285242Sachim 765285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 766285242Sachim saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 767285242Sachim pRequest->valid = agFALSE; 768285242Sachim saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 769285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 770285242Sachim 771285242Sachim SA_DBG1(("saSATASAbort, no more IOMB\n")); 772285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "8b"); 773285242Sachim return AGSA_RC_BUSY; 774285242Sachim } 775285242Sachim 776285242Sachim 777285242Sachim /* setup payload */ 778285242Sachim payload = (agsaSATAAbortCmd_t*)pMessage; 779285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, tag), pRequest->HTag); 780285242Sachim 781285242Sachim if( ABORT_SINGLE == (flag & ABORT_MASK) ) 782285242Sachim { 783285242Sachim /* If no device */ 784285242Sachim if ( agNULL == pDeviceABT ) 785285242Sachim { 786285242Sachim #ifdef SA_LL_IBQ_PROTECT 787285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 788285242Sachim #endif /* SA_LL_IBQ_PROTECT */ 789285242Sachim 790285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 791285242Sachim saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 792285242Sachim pRequest->valid = agFALSE; 793285242Sachim saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 794285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 795285242Sachim 796285242Sachim SA_DBG1(("saSATAAbort,no device\n" )); 797285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'h', "8b"); 798285242Sachim return AGSA_RC_FAILURE; 799285242Sachim } 800285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, deviceId), pDeviceABT->DeviceMapIndex); 801285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, HTagAbort), pRequestABT->HTag); 802285242Sachim } 803285242Sachim else 804285242Sachim { 805285242Sachim /* abort all */ 806285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, deviceId), pDevice->DeviceMapIndex); 807285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, HTagAbort), 0); 808285242Sachim } 809285242Sachim 810285242Sachim if(flag & ABORT_TSDK_QUARANTINE) 811285242Sachim { 812285242Sachim if(smIS_SPCV(agRoot)) 813285242Sachim { 814285242Sachim flag_copy &= ABORT_SCOPE; 815285242Sachim flag_copy |= ABORT_QUARANTINE_SPCV; 816285242Sachim } 817285242Sachim } 818285242Sachim OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, abortAll), flag_copy); 819285242Sachim 820285242Sachim 821285242Sachim 822285242Sachim SA_DBG1(("saSATAAbort, HTag 0x%x HTagABT 0x%x deviceId 0x%x\n", payload->tag, payload->HTagAbort, payload->deviceId)); 823285242Sachim 824285242Sachim /* post the IOMB to SPC */ 825285242Sachim ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SATA_ABORT, outq, (bit8)circularQ->priority); 826285242Sachim 827285242Sachim#ifdef SA_LL_IBQ_PROTECT 828285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 829285242Sachim#endif /* SA_LL_IBQ_PROTECT */ 830285242Sachim 831285242Sachim#ifdef SALL_API_TEST 832285242Sachim if (AGSA_RC_FAILURE != ret) 833285242Sachim { 834285242Sachim saRoot->LLCounters.IOCounter.numSataAborted++; 835285242Sachim } 836285242Sachim#endif 837285242Sachim 838285242Sachim siCountActiveIORequestsOnDevice( agRoot, payload->deviceId ); 839285242Sachim 840285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'i', "8b"); 841285242Sachim 842285242Sachim return ret; 843285242Sachim} 844285242Sachim 845285242Sachim/******************************************************************************/ 846285242Sachim/*! \brief Routine to handle for received SATA with data payload event 847285242Sachim * 848285242Sachim * The handle for received SATA with data payload event 849285242Sachim * 850285242Sachim * \param agRoot handles for this instance of SAS/SATA hardware 851285242Sachim * \param pRequest the IO request descriptor 852285242Sachim * \param agFirstDword pointer to the first Dword 853285242Sachim * \param pResp pointer to the rest of SATA response 854285242Sachim * \param lengthResp total length of SATA Response frame 855285242Sachim * 856285242Sachim * \return -void- 857285242Sachim */ 858285242Sachim/*******************************************************************************/ 859285242SachimGLOBAL void siEventSATAResponseWtDataRcvd( 860285242Sachim agsaRoot_t *agRoot, 861285242Sachim agsaIORequestDesc_t *pRequest, 862285242Sachim bit32 *agFirstDword, 863285242Sachim bit32 *pResp, 864285242Sachim bit32 lengthResp 865285242Sachim ) 866285242Sachim{ 867285242Sachim agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 868285242Sachim agsaDeviceDesc_t *pDevice; 869285242Sachim#if defined(SALLSDK_DEBUG) 870285242Sachim agsaFrameHandle_t frameHandle; 871285242Sachim /* get frame handle */ 872285242Sachim frameHandle = (agsaFrameHandle_t)(pResp); 873285242Sachim#endif /* SALLSDK_DEBUG */ 874285242Sachim 875285242Sachim smTraceFuncEnter(hpDBG_VERY_LOUD,"8c"); 876285242Sachim 877285242Sachim /* If the request is still valid */ 878285242Sachim if ( agTRUE == pRequest->valid ) 879285242Sachim { 880285242Sachim /* get device */ 881285242Sachim pDevice = pRequest->pDevice; 882285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 883285242Sachim 884285242Sachim /* Delete the request from the pendingIORequests */ 885285242Sachim saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 886285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 887285242Sachim 888285242Sachim (*(ossaSATACompletedCB_t)(pRequest->completionCB))(agRoot, 889285242Sachim pRequest->pIORequestContext, 890285242Sachim OSSA_IO_SUCCESS, 891285242Sachim agFirstDword, 892285242Sachim lengthResp, 893285242Sachim (void *)pResp); 894285242Sachim 895285242Sachim ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 896285242Sachim pRequest->valid = agFALSE; 897285242Sachim /* return the request to free pool */ 898285242Sachim saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 899285242Sachim ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 900285242Sachim } 901285242Sachim 902285242Sachim smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "8c"); 903285242Sachim 904285242Sachim return; 905285242Sachim} 906285242Sachim 907285242Sachim/******************************************************************************/ 908285242Sachim/*! \brief copy a SATA signature to another 909285242Sachim * 910285242Sachim * copy a SATA signature to another 911285242Sachim * 912285242Sachim * \param pDstSignature pointer to the destination signature 913285242Sachim * \param pSrcSignature pointer to the source signature 914285242Sachim * 915285242Sachim * \return If they match 916285242Sachim * - \e agTRUE match 917285242Sachim * - \e agFALSE doesn't match 918285242Sachim */ 919285242Sachim/*******************************************************************************/ 920285242SachimGLOBAL void siSATASignatureCpy( 921285242Sachim bit8 *pDstSignature, 922285242Sachim bit8 *pSrcSignature 923285242Sachim ) 924285242Sachim{ 925285242Sachim bit32 i; 926285242Sachim 927285242Sachim for ( i = 0; i < 5; i ++ ) 928285242Sachim { 929285242Sachim pDstSignature[i] = pSrcSignature[i]; 930285242Sachim } 931285242Sachim 932285242Sachim return; 933285242Sachim} 934285242Sachim 935285242Sachim 936285242Sachim 937