1285809Sscottl/******************************************************************************* 2285809Sscottl*Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved. 3285809Sscottl* 4285809Sscottl*Redistribution and use in source and binary forms, with or without modification, are permitted provided 5285809Sscottl*that the following conditions are met: 6285809Sscottl*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 7285809Sscottl*following disclaimer. 8285809Sscottl*2. Redistributions in binary form must reproduce the above copyright notice, 9285809Sscottl*this list of conditions and the following disclaimer in the documentation and/or other materials provided 10285809Sscottl*with the distribution. 11285809Sscottl* 12285809Sscottl*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 13285809Sscottl*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 14285809Sscottl*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 15285809Sscottl*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 16285809Sscottl*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 17285809Sscottl*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 18285809Sscottl*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 19285809Sscottl*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 20285809Sscottl 21285809Sscottl********************************************************************************/ 22285809Sscottl/*******************************************************************************/ 23285809Sscottl/*! \file sasmp.c 24285809Sscottl * \brief The file implements the functions for SMP request/response 25285809Sscottl * 26285809Sscottl */ 27285809Sscottl/*******************************************************************************/ 28285809Sscottl#include <sys/cdefs.h> 29285809Sscottl__FBSDID("$FreeBSD$"); 30285809Sscottl#include <dev/pms/config.h> 31285809Sscottl 32285809Sscottl#include <dev/pms/RefTisa/sallsdk/spc/saglobal.h> 33285809Sscottl#ifdef SA_ENABLE_TRACE_FUNCTIONS 34285809Sscottl#ifdef siTraceFileID 35285809Sscottl#undef siTraceFileID 36285809Sscottl#endif 37285809Sscottl#define siTraceFileID 'N' 38285809Sscottl#endif 39285809Sscottl 40285809Sscottl/******************************************************************************/ 41285809Sscottl/*! \brief Start SMP request 42285809Sscottl * 43285809Sscottl * Start SMP request 44285809Sscottl * 45285809Sscottl * \param agRoot handles for this instance of SAS/SATA hardware 46285809Sscottl * \param queueNum 47285809Sscottl * \param agIORequest 48285809Sscottl * \param agDevHandle 49285809Sscottl * \param agRequestType 50285809Sscottl * \param agRequestBody 51285809Sscottl * \param agCB 52285809Sscottl * Spc - support direct mode direct response 53285809Sscottl * SpcV - support direct mode direct response 54285809Sscottl * SpcV - support indirect mode direct response 55285809Sscottl * SpcV - support indirect mode indirect response 56285809Sscottl * 57285809Sscottl * \return If request is started successfully 58285809Sscottl * - \e AGSA_RC_SUCCESS request is started successfully 59285809Sscottl * - \e AGSA_RC_BUSY No resource available, try again later 60285809Sscottl */ 61285809Sscottl/*******************************************************************************/ 62285809SscottlGLOBAL bit32 saSMPStart( 63285809Sscottl agsaRoot_t *agRoot, 64285809Sscottl agsaIORequest_t *agIORequest, 65285809Sscottl bit32 queueNum, 66285809Sscottl agsaDevHandle_t *agDevHandle, 67285809Sscottl bit32 agRequestType, 68285809Sscottl agsaSASRequestBody_t *agRequestBody, 69285809Sscottl ossaSMPCompletedCB_t agCB 70285809Sscottl ) 71285809Sscottl{ 72285809Sscottl bit32 ret = AGSA_RC_SUCCESS, retVal; 73285809Sscottl agsaLLRoot_t *saRoot = agNULL; 74285809Sscottl mpiICQueue_t *circularQ; 75285809Sscottl agsaDeviceDesc_t *pDevice; 76285809Sscottl agsaPort_t *pPort; 77285809Sscottl agsaIORequestDesc_t *pRequest; 78285809Sscottl void *pMessage; 79285809Sscottl bit8 i, inq, outq; 80285809Sscottl bit8 using_reserved = agFALSE; 81285809Sscottl bit8 *payload_ptr; 82285809Sscottl agsaSMPFrame_t *pSMPFrame; 83285809Sscottl 84285809Sscottl SA_DBG4(("saSMPStart: start\n")); 85285809Sscottl 86285809Sscottl smTraceFuncEnter(hpDBG_VERY_LOUD, "9a"); 87285809Sscottl 88285809Sscottl /* sanity check */ 89285809Sscottl SA_ASSERT((agNULL != agRoot), ""); 90285809Sscottl SA_ASSERT((agNULL != agIORequest), ""); 91285809Sscottl SA_ASSERT((agNULL != agDevHandle), ""); 92285809Sscottl SA_ASSERT((agNULL != agRequestBody), ""); 93285809Sscottl 94285809Sscottl /* sanity check */ 95285809Sscottl saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 96285809Sscottl SA_ASSERT((agNULL != saRoot), ""); 97285809Sscottl 98285809Sscottl if(saRoot == agNULL) 99285809Sscottl { 100285809Sscottl SA_DBG1(("saSMPStart : saRoot is NULL!!\n")); 101285809Sscottl return AGSA_RC_FAILURE; 102285809Sscottl } 103285809Sscottl 104285809Sscottl /* Assign inbound and outbound queue number */ 105285809Sscottl inq = (bit8)(queueNum & MPI_IB_NUM_MASK); 106285809Sscottl outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT); 107285809Sscottl SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range."); 108285809Sscottl 109285809Sscottl /* Find the outgoing port for the device */ 110285809Sscottl if (agNULL == agDevHandle->sdkData) 111285809Sscottl { 112285809Sscottl /* Device has been removed */ 113285809Sscottl SA_DBG1(("saSMPStart, Device has been removed. agDevHandle=%p\n", agDevHandle)); 114285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "9a"); 115285809Sscottl return AGSA_RC_FAILURE; 116285809Sscottl } 117285809Sscottl 118285809Sscottl pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData); 119285809Sscottl 120285809Sscottl pPort = pDevice->pPort; 121285809Sscottl 122285809Sscottl /* Get request from free IO Requests */ 123285809Sscottl ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 124285809Sscottl pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/ 125285809Sscottl 126285809Sscottl /* If no LL IO request entry available */ 127285809Sscottl if ( agNULL == pRequest ) 128285809Sscottl { 129285809Sscottl 130285809Sscottl pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests)); 131285809Sscottl 132285809Sscottl if(agNULL != pRequest) 133285809Sscottl { 134285809Sscottl using_reserved = agTRUE; 135285809Sscottl SA_DBG1(("saSMPStart, using saRoot->freeReservedRequests\n")); 136285809Sscottl } 137285809Sscottl else 138285809Sscottl { 139285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 140285809Sscottl SA_DBG1(("saSMPStart, No request from free list Not using saRoot->freeReservedRequests\n")); 141285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "9a"); 142285809Sscottl return AGSA_RC_BUSY; 143285809Sscottl } 144285809Sscottl } 145285809Sscottl 146285809Sscottl /* If free IOMB avaliable */ 147285809Sscottl /* Remove the request from free list */ 148285809Sscottl if( using_reserved ) 149285809Sscottl { 150285809Sscottl saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 151285809Sscottl } 152285809Sscottl else 153285809Sscottl { 154285809Sscottl saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 155285809Sscottl } 156285809Sscottl 157285809Sscottl /* Add the request to the pendingSMPRequests list of the device */ 158285809Sscottl saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 159285809Sscottl SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 160285809Sscottl pRequest->valid = agTRUE; 161285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 162285809Sscottl 163285809Sscottl /* set up pRequest */ 164285809Sscottl pRequest->pIORequestContext = agIORequest; 165285809Sscottl pRequest->pDevice = pDevice; 166285809Sscottl pRequest->pPort = pPort; 167285809Sscottl pRequest->requestType = agRequestType; 168285809Sscottl pRequest->startTick = saRoot->timeTick; 169285809Sscottl pRequest->completionCB = (ossaSSPCompletedCB_t)agCB; 170285809Sscottl 171285809Sscottl /* Set request to the sdkData of agIORequest */ 172285809Sscottl agIORequest->sdkData = pRequest; 173285809Sscottl 174285809Sscottl /* save tag to IOMap */ 175285809Sscottl saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 176285809Sscottl saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 177285809Sscottl 178285809Sscottl#ifdef SA_LL_IBQ_PROTECT 179285809Sscottl ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 180285809Sscottl#endif /* SA_LL_IBQ_PROTECT */ 181285809Sscottl 182285809Sscottl /* If LL IO request entry avaliable */ 183285809Sscottl /* Get a free inbound queue entry */ 184285809Sscottl circularQ = &saRoot->inboundQueue[inq]; 185285809Sscottl retVal = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage); 186285809Sscottl 187285809Sscottl if (AGSA_RC_FAILURE == retVal) 188285809Sscottl { 189285809Sscottl#ifdef SA_LL_IBQ_PROTECT 190285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 191285809Sscottl#endif /* SA_LL_IBQ_PROTECT */ 192285809Sscottl /* if not sending return to free list rare */ 193285809Sscottl ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 194285809Sscottl saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 195285809Sscottl pRequest->valid = agFALSE; 196285809Sscottl saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 197285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 198285809Sscottl 199285809Sscottl SA_DBG1(("saSMPStart, error when get free IOMB\n")); 200285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "9a"); 201285809Sscottl return AGSA_RC_FAILURE; 202285809Sscottl } 203285809Sscottl 204285809Sscottl /* return busy if inbound queue is full */ 205285809Sscottl if (AGSA_RC_BUSY == retVal) 206285809Sscottl { 207285809Sscottl#ifdef SA_LL_IBQ_PROTECT 208285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 209285809Sscottl#endif /* SA_LL_IBQ_PROTECT */ 210285809Sscottl /* if not sending return to free list rare */ 211285809Sscottl ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 212285809Sscottl saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 213285809Sscottl pRequest->valid = agFALSE; 214285809Sscottl saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 215285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 216285809Sscottl 217285809Sscottl SA_DBG1(("saSMPStart, no more IOMB\n")); 218285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "9a"); 219285809Sscottl return AGSA_RC_BUSY; 220285809Sscottl } 221285809Sscottl 222285809Sscottl /* Setup SMP Frame */ 223285809Sscottl pSMPFrame = (agsaSMPFrame_t *) &(agRequestBody->smpFrame); 224285809Sscottl 225285809Sscottl SA_DBG2(("saSMPStart:DeviceMapIndex 0x%x portId 0x%x portId 0x%x\n",pDevice->DeviceMapIndex,pPort->portId,pPort->portId)); 226285809Sscottl 227285809Sscottl#if defined(SALLSDK_DEBUG) 228285809Sscottl 229285809Sscottl SA_DBG2(("saSMPStart: outFrameBuf %p\n",pSMPFrame->outFrameBuf)); 230285809Sscottl 231285809Sscottl if(pSMPFrame->outFrameBuf ) 232285809Sscottl { 233285809Sscottl SA_DBG2(("saSMPStart: outFrameBuf 0 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+0) )); 234285809Sscottl SA_DBG2(("saSMPStart: outFrameBuf 1 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+1) )); 235285809Sscottl SA_DBG2(("saSMPStart: outFrameBuf 2 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+2) )); 236285809Sscottl SA_DBG2(("saSMPStart: outFrameBuf 3 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+3) )); 237285809Sscottl SA_DBG2(("saSMPStart: outFrameBuf 4 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+4) )); 238285809Sscottl SA_DBG2(("saSMPStart: outFrameBuf 5 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+5) )); 239285809Sscottl SA_DBG2(("saSMPStart: outFrameBuf 6 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+6) )); 240285809Sscottl SA_DBG2(("saSMPStart: outFrameBuf 7 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+7) )); 241285809Sscottl SA_DBG2(("saSMPStart: outFrameBuf 8 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+8) )); 242285809Sscottl SA_DBG2(("saSMPStart: outFrameBuf 9 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+9) )); 243285809Sscottl SA_DBG2(("saSMPStart: outFrameBuf 11 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+10) )); 244285809Sscottl SA_DBG2(("saSMPStart: outFrameBuf 11 0x%08X\n",*((bit32*)pSMPFrame->outFrameBuf+11) )); 245285809Sscottl } 246285809Sscottl SA_DBG2(("saSMPStart: outFrameAddrUpper32 0x%08X\n",pSMPFrame->outFrameAddrUpper32)); 247285809Sscottl SA_DBG2(("saSMPStart: outFrameAddrLower32 0x%08X\n",pSMPFrame->outFrameAddrLower32)); 248285809Sscottl SA_DBG2(("saSMPStart: outFrameLen 0x%08X\n",pSMPFrame->outFrameLen)); 249285809Sscottl SA_DBG2(("saSMPStart: inFrameAddrUpper32 0x%08X\n",pSMPFrame->inFrameAddrUpper32)); 250285809Sscottl SA_DBG2(("saSMPStart: inFrameAddrLower32 0x%08X\n",pSMPFrame->inFrameAddrLower32)); 251285809Sscottl SA_DBG2(("saSMPStart: inFrameLen 0x%08X\n",pSMPFrame->inFrameLen)); 252285809Sscottl SA_DBG2(("saSMPStart: expectedRespLen 0x%08X\n",pSMPFrame->expectedRespLen)); 253285809Sscottl SA_DBG2(("saSMPStart: flag 0x%08X\n",pSMPFrame->flag)); 254285809Sscottl#endif /* SALLSDK_DEBUG */ 255285809Sscottl 256285809Sscottl if(smIS_SPC(agRoot)) 257285809Sscottl // if(1) 258285809Sscottl { 259285809Sscottl agsaSMPCmd_t payload; 260285809Sscottl switch ( agRequestType ) 261285809Sscottl { 262285809Sscottl case AGSA_SMP_INIT_REQ: 263285809Sscottl { 264285809Sscottl bit32 IR_IP_OV_res_phyId_DPdLen_res = 0; 265285809Sscottl /* Prepare the payload of IOMB */ 266285809Sscottl si_memset(&payload, 0, sizeof(agsaSMPCmd_t)); 267285809Sscottl OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, tag), pRequest->HTag); 268285809Sscottl OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, deviceId), pDevice->DeviceMapIndex); 269285809Sscottl 270285809Sscottl /* check SMP Response Frame with IR mode */ 271285809Sscottl /* check if the SMP Response is indirect mode */ 272285809Sscottl if (0 == pSMPFrame->inFrameLen) 273285809Sscottl { 274285809Sscottl /* PHY override not support */ 275285809Sscottl /* Direct Response mode */ 276285809Sscottl pRequest->IRmode = DIRECT_MODE; 277285809Sscottl } 278285809Sscottl else 279285809Sscottl { 280285809Sscottl /* Indirect Response mode */ 281285809Sscottl pRequest->IRmode = INDIRECT_MODE; 282285809Sscottl IR_IP_OV_res_phyId_DPdLen_res = 1; 283285809Sscottl /* check SMP direct payload mode len */ 284285809Sscottl if (pSMPFrame->outFrameLen > 32) 285285809Sscottl { 286285809Sscottl#ifdef SA_LL_IBQ_PROTECT 287285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 288285809Sscottl#endif /* SA_LL_IBQ_PROTECT */ 289285809Sscottl /* if not sending return to free list rare */ 290285809Sscottl ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 291285809Sscottl saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 292285809Sscottl pRequest->valid = agFALSE; 293285809Sscottl saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 294285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 295285809Sscottl /* can not handle SMP frame length > 32 bytes it if IP=0 and IR=1 */ 296285809Sscottl SA_DBG1(("saSMPStart, outFrameLen > 32 bytes error.\n")); 297285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "9a"); 298285809Sscottl return AGSA_RC_FAILURE; 299285809Sscottl } 300285809Sscottl } 301285809Sscottl 302285809Sscottl /* check Direct mode or Indirect mode for IP mode */ 303285809Sscottl if ( (pSMPFrame->outFrameBuf && 304285809Sscottl (pSMPFrame->outFrameLen <= AGSA_MAX_SMPPAYLOAD_VIA_SFO)) || 305285809Sscottl ((pSMPFrame->outFrameBuf == agNULL) && 306285809Sscottl (pSMPFrame->outFrameLen == 0) ) 307285809Sscottl ) 308285809Sscottl { 309285809Sscottl SA_DBG4(("saSMPStart: DIRECT Request SMP\n")); 310285809Sscottl 311285809Sscottl IR_IP_OV_res_phyId_DPdLen_res = (DIRECT_MODE << 1) | IR_IP_OV_res_phyId_DPdLen_res; 312285809Sscottl 313285809Sscottl /* Direct payload length */ 314285809Sscottl IR_IP_OV_res_phyId_DPdLen_res |= (((pSMPFrame->outFrameLen) & 0xff) << SHIFT16); 315285809Sscottl 316285809Sscottl /* copy payload - upto 48 bytes */ 317285809Sscottl si_memcpy(&(payload.SMPCmd[0]),pSMPFrame->outFrameBuf,pSMPFrame->outFrameLen); 318285809Sscottl for ( i = 0; i < pSMPFrame->outFrameLen / sizeof(bit32)+1; i ++ ) 319285809Sscottl { 320285809Sscottl SA_DBG4(("saSMPStart: payload.SMPCmd[%d] %x\n", i, payload.SMPCmd[i])); 321285809Sscottl } 322285809Sscottl } 323285809Sscottl else 324285809Sscottl { 325285809Sscottl SA_DBG4(("saSMPStart: INDIRECT Request SMP\n")); 326285809Sscottl /* use physical address */ 327285809Sscottl IR_IP_OV_res_phyId_DPdLen_res = (INDIRECT_MODE << 1) | IR_IP_OV_res_phyId_DPdLen_res; 328285809Sscottl 329285809Sscottl /* Direct payload length = 0 */ 330285809Sscottl IR_IP_OV_res_phyId_DPdLen_res = IR_IP_OV_res_phyId_DPdLen_res & 0xff00ffff; 331285809Sscottl 332285809Sscottl /* payload */ 333285809Sscottl OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[4]), (pSMPFrame->outFrameAddrLower32)); 334285809Sscottl OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[5]), (pSMPFrame->outFrameAddrUpper32)); 335285809Sscottl OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[6]), (pSMPFrame->outFrameLen)); 336285809Sscottl } 337285809Sscottl /* Write IR_IP_OV_res_phyId_DPdLen_res field in the payload*/ 338285809Sscottl OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, IR_IP_OV_res_phyId_DPdLen_res), IR_IP_OV_res_phyId_DPdLen_res); 339285809Sscottl 340285809Sscottl /* check IR bit */ 341285809Sscottl if (IR_IP_OV_res_phyId_DPdLen_res & INDIRECT_MODE) 342285809Sscottl { 343285809Sscottl /* setup indirect response frame address */ 344285809Sscottl OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[8]), (pSMPFrame->inFrameAddrLower32)); 345285809Sscottl OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[9]), (pSMPFrame->inFrameAddrUpper32)); 346285809Sscottl OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPCmd_t, SMPCmd[10]), (pSMPFrame->inFrameLen)); 347285809Sscottl } 348285809Sscottl 349285809Sscottl /* Build IOMB command and send it to SPC */ 350285809Sscottl payload_ptr = (bit8 *)&payload; 351285809Sscottl ret = mpiSMPCmd(agRoot, pMessage, OPC_INB_SMP_REQUEST, (agsaSMPCmd_t *)payload_ptr, inq, outq); 352285809Sscottl 353285809Sscottl #ifdef SA_LL_IBQ_PROTECT 354285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 355285809Sscottl #endif /* SA_LL_IBQ_PROTECT */ 356285809Sscottl 357285809Sscottl break; 358285809Sscottl } 359285809Sscottl default: 360285809Sscottl { 361285809Sscottl SA_DBG1(("saSMPStart: SPC unknown agRequestType %x\n",agRequestType)); 362285809Sscottl break; 363285809Sscottl } 364285809Sscottl } 365285809Sscottl 366285809Sscottl#ifdef SALL_API_TEST 367285809Sscottl if (ret == AGSA_RC_SUCCESS) 368285809Sscottl saRoot->LLCounters.IOCounter.numSMPStarted++; 369285809Sscottl#endif 370285809Sscottl } 371285809Sscottl else /* IOMB is different for SPCV SMP */ 372285809Sscottl { 373285809Sscottl agsaSMPCmd_V_t vpayload; 374285809Sscottl 375285809Sscottl switch ( agRequestType ) 376285809Sscottl { 377285809Sscottl case AGSA_SMP_INIT_REQ: 378285809Sscottl { 379285809Sscottl bit32 IR_IP_OV_res_phyId_DPdLen_res = 0; 380285809Sscottl /* Prepare the payload of IOMB */ 381285809Sscottl si_memset(&vpayload, 0, sizeof(agsaSMPCmd_V_t)); 382285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, tag), pRequest->HTag); 383285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, deviceId), pDevice->DeviceMapIndex); 384285809Sscottl 385285809Sscottl /* Request header must be valid regardless of IP bit */ 386285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMPHDR ), *((bit32*)pSMPFrame->outFrameBuf+0) ); 387285809Sscottl 388285809Sscottl /* check SMP Response Frame with IR mode */ 389285809Sscottl /* check if the SMP Response is indirect mode */ 390285809Sscottl // smpFrameFlagDirectResponse smpFrameFlagDirectPayload 391285809Sscottl if ( 0 == pSMPFrame->flag && pSMPFrame->outFrameBuf ) 392285809Sscottl { 393285809Sscottl /* PHY override not support */ 394285809Sscottl /* Direct Response mode */ 395285809Sscottl pRequest->IRmode = DIRECT_MODE; 396285809Sscottl SA_DBG2(("saSMPStart:V DIRECT Request SMP\n")); 397285809Sscottl 398285809Sscottl IR_IP_OV_res_phyId_DPdLen_res = (DIRECT_MODE << 1) | IR_IP_OV_res_phyId_DPdLen_res; 399285809Sscottl 400285809Sscottl /* Direct payload length */ 401285809Sscottl IR_IP_OV_res_phyId_DPdLen_res |= (((pSMPFrame->outFrameLen) & 0xff) << SHIFT16); 402285809Sscottl /* Write IR_IP_OV_res_phyId_DPdLen_res field in the payload*/ 403285809Sscottl /* fatal error if missing */ 404285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, IR_IP_OV_res_phyId_DPdLen_res), IR_IP_OV_res_phyId_DPdLen_res); 405285809Sscottl /* fatal error if missing */ 406285809Sscottl 407285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMP3_0 ), *((bit32*)pSMPFrame->outFrameBuf+1) ); 408285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMP7_4 ), *((bit32*)pSMPFrame->outFrameBuf+2) ); 409285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMP11_8), *((bit32*)pSMPFrame->outFrameBuf+3) ); 410285809Sscottl 411285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirL_SMPRF15_12 ), *((bit32*)pSMPFrame->outFrameBuf+4) ); 412285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirH_or_SMPRF19_16 ), *((bit32*)pSMPFrame->outFrameBuf+5) ); 413285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirLen_or_SMPRF23_20 ),*((bit32*)pSMPFrame->outFrameBuf+6) ); 414285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,R_or_SMPRF27_24), *((bit32*)pSMPFrame->outFrameBuf+7) ); 415285809Sscottl 416285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,ISRAL_or_SMPRF31_28 ), *((bit32*)pSMPFrame->outFrameBuf+8) ); 417285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,ISRAH_or_SMPRF35_32 ), *((bit32*)pSMPFrame->outFrameBuf+9) ); 418285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,ISRL_or_SMPRF39_36 ), *((bit32*)pSMPFrame->outFrameBuf+10) ); 419285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,R_or_SMPRF43_40 ), *((bit32*)pSMPFrame->outFrameBuf+11) ); 420285809Sscottl 421285809Sscottl } 422285809Sscottl else if (smpFrameFlagIndirectResponse & pSMPFrame->flag && smpFrameFlagIndirectPayload & pSMPFrame->flag) /* */ 423285809Sscottl { 424285809Sscottl /* IR IP */ 425285809Sscottl SA_DBG2(("saSMPStart:V smpFrameFlagIndirectResponse smpFrameFlagIndirectPayload SMP\n")); 426285809Sscottl 427285809Sscottl pRequest->IRmode = INDIRECT_MODE; 428285809Sscottl IR_IP_OV_res_phyId_DPdLen_res = 3; 429285809Sscottl 430285809Sscottl /* Indirect payload mode */ 431285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirL_SMPRF15_12 ), pSMPFrame->outFrameAddrLower32); 432285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirH_or_SMPRF19_16 ), pSMPFrame->outFrameAddrUpper32); 433285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirLen_or_SMPRF23_20 ), pSMPFrame->outFrameLen); 434285809Sscottl /* Indirect Response mode */ 435285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRAL_or_SMPRF31_28 ), (pSMPFrame->inFrameAddrLower32)); 436285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRAH_or_SMPRF35_32 ), (pSMPFrame->inFrameAddrUpper32)); 437285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRL_or_SMPRF39_36 ), (pSMPFrame->inFrameLen)); 438285809Sscottl } 439285809Sscottl else if (smpFrameFlagIndirectPayload & pSMPFrame->flag ) /* */ 440285809Sscottl { 441285809Sscottl /* IP */ 442285809Sscottl SA_DBG2(("saSMPStart:V smpFrameFlagIndirectPayload SMP\n")); 443285809Sscottl pRequest->IRmode = DIRECT_MODE; 444285809Sscottl IR_IP_OV_res_phyId_DPdLen_res = 2; 445285809Sscottl 446285809Sscottl /* Indirect payload mode */ 447285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirL_SMPRF15_12 ), pSMPFrame->outFrameAddrLower32); 448285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirH_or_SMPRF19_16 ), pSMPFrame->outFrameAddrUpper32); 449285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirLen_or_SMPRF23_20 ), pSMPFrame->outFrameLen); 450285809Sscottl } 451285809Sscottl else if (smpFrameFlagIndirectResponse & pSMPFrame->flag ) /* */ 452285809Sscottl { 453285809Sscottl /* check IR bit */ 454285809Sscottl /* Indirect Response mode */ 455285809Sscottl pRequest->IRmode = INDIRECT_MODE; 456285809Sscottl SA_DBG2(("saSMPStart:V smpFrameFlagIndirectResponse SMP\n")); 457285809Sscottl /* use physical address */ 458285809Sscottl IR_IP_OV_res_phyId_DPdLen_res = 1; 459285809Sscottl /* Direct payload length */ 460285809Sscottl IR_IP_OV_res_phyId_DPdLen_res |= (((pSMPFrame->outFrameLen) & 0xff) << SHIFT16); 461285809Sscottl 462285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMP3_0 ), *((bit32*)pSMPFrame->outFrameBuf+1) ); 463285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMP7_4 ), *((bit32*)pSMPFrame->outFrameBuf+2) ); 464285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,SMP11_8), *((bit32*)pSMPFrame->outFrameBuf+3) ); 465285809Sscottl 466285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirL_SMPRF15_12 ), *((bit32*)pSMPFrame->outFrameBuf+4) ); 467285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirH_or_SMPRF19_16 ), *((bit32*)pSMPFrame->outFrameBuf+5) ); 468285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,IndirLen_or_SMPRF23_20 ),*((bit32*)pSMPFrame->outFrameBuf+6) ); 469285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t,R_or_SMPRF27_24), *((bit32*)pSMPFrame->outFrameBuf+7) ); 470285809Sscottl 471285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRAL_or_SMPRF31_28 ), (pSMPFrame->inFrameAddrLower32)); 472285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRAH_or_SMPRF35_32 ), (pSMPFrame->inFrameAddrUpper32)); 473285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, ISRL_or_SMPRF39_36 ), (pSMPFrame->inFrameLen)); 474285809Sscottl } 475285809Sscottl IR_IP_OV_res_phyId_DPdLen_res |= (pSMPFrame->flag & 3); 476285809Sscottl /* fatal error if missing */ 477285809Sscottl OSSA_WRITE_LE_32(agRoot, &vpayload, OSSA_OFFSET_OF(agsaSMPCmd_V_t, IR_IP_OV_res_phyId_DPdLen_res), IR_IP_OV_res_phyId_DPdLen_res); 478285809Sscottl /* fatal error if missing */ 479285809Sscottl } 480285809Sscottl /* Build IOMB command and send it to SPCv */ 481285809Sscottl payload_ptr = (bit8 *)&vpayload; 482285809Sscottl ret = mpiSMPCmd(agRoot, pMessage, OPC_INB_SMP_REQUEST, (agsaSMPCmd_t *)payload_ptr, inq, outq); 483285809Sscottl 484285809Sscottl#ifdef SA_LL_IBQ_PROTECT 485285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq); 486285809Sscottl#endif /* SA_LL_IBQ_PROTECT */ 487285809Sscottl 488285809Sscottl break; 489285809Sscottl default: 490285809Sscottl { 491285809Sscottl SA_DBG1(("saSMPStart: SPCv unknown agRequestType %x\n",agRequestType)); 492285809Sscottl break; 493285809Sscottl } 494285809Sscottl } 495285809Sscottl } 496285809Sscottl 497285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "9a"); 498285809Sscottl 499285809Sscottl /* return */ 500285809Sscottl return ret; 501285809Sscottl} 502285809Sscottl 503285809Sscottl/******************************************************************************/ 504285809Sscottl/*! \brief Abort SMP request 505285809Sscottl * 506285809Sscottl * Abort SMP request 507285809Sscottl * 508285809Sscottl * \param agRoot handles for this instance of SAS/SATA hardware 509285809Sscottl * \param queueNum 510285809Sscottl * \param agIORequest 511285809Sscottl * 512285809Sscottl * \return If request is aborted successfully 513285809Sscottl * - \e AGSA_RC_SUCCESS request is aborted successfully 514285809Sscottl * - \e AGSA_RC_FAILURE request is not aborted successfully 515285809Sscottl */ 516285809Sscottl/*******************************************************************************/ 517285809SscottlGLOBAL bit32 saSMPAbort( 518285809Sscottl agsaRoot_t *agRoot, 519285809Sscottl agsaIORequest_t *agIORequest, 520285809Sscottl bit32 queueNum, 521285809Sscottl agsaDevHandle_t *agDevHandle, 522285809Sscottl bit32 flag, 523285809Sscottl void *abortParam, 524285809Sscottl ossaGenericAbortCB_t agCB 525285809Sscottl ) 526285809Sscottl{ 527285809Sscottl bit32 ret = AGSA_RC_SUCCESS; 528285809Sscottl agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); 529285809Sscottl agsaIORequestDesc_t *pRequest; 530285809Sscottl agsaIORequestDesc_t *pRequestABT = NULL; 531285809Sscottl agsaIORequest_t *agIOToBeAborted; 532285809Sscottl agsaDeviceDesc_t *pDevice; 533285809Sscottl agsaSMPAbortCmd_t payload; 534285809Sscottl bit32 using_reserved = agFALSE; 535285809Sscottl 536285809Sscottl smTraceFuncEnter(hpDBG_VERY_LOUD,"9b"); 537285809Sscottl 538285809Sscottl /* sanity check */ 539285809Sscottl SA_ASSERT((agNULL != agRoot), ""); 540285809Sscottl SA_ASSERT((agNULL != agIORequest), ""); 541285809Sscottl SA_ASSERT((agNULL != agDevHandle), ""); 542285809Sscottl 543285809Sscottl SA_DBG3(("saSMPAbort: Aborting request %p\n", agIORequest)); 544285809Sscottl 545285809Sscottl if( ABORT_SINGLE == (flag & ABORT_MASK) ) 546285809Sscottl { 547285809Sscottl agIOToBeAborted = (agsaIORequest_t *)abortParam; 548285809Sscottl /* Get LL IORequest entry for saSMPAbort() */ 549285809Sscottl pRequestABT = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData); 550285809Sscottl if (agNULL == pRequestABT) 551285809Sscottl { 552285809Sscottl /* The IO to Be Abort is no longer exist - can not Abort */ 553285809Sscottl SA_DBG1(("saSMPAbort: pRequestABT AGSA_RC_FAILURE\n")); 554285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "9b"); 555285809Sscottl return AGSA_RC_FAILURE; 556285809Sscottl } 557285809Sscottl 558285809Sscottl /* Find the device the request Abort to */ 559285809Sscottl pDevice = pRequestABT->pDevice; 560285809Sscottl 561285809Sscottl if (agNULL == pDevice) 562285809Sscottl { 563285809Sscottl /* no deviceID - can not build IOMB */ 564285809Sscottl SA_DBG1(("saSMPAbort: pDevice AGSA_RC_FAILURE\n")); 565285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "9b"); 566285809Sscottl return AGSA_RC_FAILURE; 567285809Sscottl } 568285809Sscottl } 569285809Sscottl else 570285809Sscottl { 571285809Sscottl if (ABORT_ALL == (flag & ABORT_MASK)) 572285809Sscottl { 573285809Sscottl /* abort All with Device or Port */ 574285809Sscottl /* Find the outgoing port for the device */ 575285809Sscottl pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData); 576285809Sscottl if (agNULL == pDevice) 577285809Sscottl { 578285809Sscottl /* no deviceID - can not build IOMB */ 579285809Sscottl SA_DBG1(("saSMPAbort:ABORT_ALL pDevice AGSA_RC_FAILURE\n")); 580285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "9b"); 581285809Sscottl return AGSA_RC_FAILURE; 582285809Sscottl } 583285809Sscottl } 584285809Sscottl else 585285809Sscottl { 586285809Sscottl /* only support 00 and 01 for flag */ 587285809Sscottl SA_DBG1(("saSMPAbort:flag AGSA_RC_FAILURE\n")); 588285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "9b"); 589285809Sscottl return AGSA_RC_FAILURE; 590285809Sscottl } 591285809Sscottl } 592285809Sscottl 593285809Sscottl /* Get LL IORequest entry */ 594285809Sscottl ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 595285809Sscottl pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); 596285809Sscottl 597285809Sscottl /* If no LL IO request entry available */ 598285809Sscottl if ( agNULL == pRequest ) 599285809Sscottl { 600285809Sscottl pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests)); /**/ 601285809Sscottl /* If no LL Control request entry available */ 602285809Sscottl if(agNULL != pRequest) 603285809Sscottl { 604285809Sscottl using_reserved = agTRUE; 605285809Sscottl SA_DBG1(("saSMPAbort, using saRoot->freeReservedRequests\n")); 606285809Sscottl } 607285809Sscottl else 608285809Sscottl { 609285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 610285809Sscottl SA_DBG1(("saSMPAbort, No request from free list Not using saRoot->freeReservedRequests\n")); 611285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "9b"); 612285809Sscottl return AGSA_RC_BUSY; 613285809Sscottl } 614285809Sscottl } 615285809Sscottl 616285809Sscottl /* If free IOMB avaliable */ 617285809Sscottl /* Remove the request from free list */ 618285809Sscottl if( using_reserved ) 619285809Sscottl { 620285809Sscottl saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 621285809Sscottl } 622285809Sscottl else 623285809Sscottl { 624285809Sscottl saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode)); 625285809Sscottl } 626285809Sscottl 627285809Sscottl /* Add the request to the pendingSMPRequests list of the device */ 628285809Sscottl saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 629285809Sscottl SA_ASSERT((!pRequest->valid), "The pRequest is in use"); 630285809Sscottl pRequest->valid = agTRUE; 631285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 632285809Sscottl /* set up pRequest */ 633285809Sscottl pRequest->pIORequestContext = agIORequest; 634285809Sscottl pRequest->requestType = AGSA_SMP_REQTYPE; 635285809Sscottl pRequest->completionCB = (void*)agCB; 636285809Sscottl pRequest->pDevice = pDevice; 637285809Sscottl pRequest->startTick = saRoot->timeTick; 638285809Sscottl 639285809Sscottl /* Set request to the sdkData of agIORequest */ 640285809Sscottl agIORequest->sdkData = pRequest; 641285809Sscottl 642285809Sscottl /* save tag to IOMap */ 643285809Sscottl saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag; 644285809Sscottl saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest; 645285809Sscottl 646285809Sscottl /* setup payload */ 647285809Sscottl OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPAbortCmd_t, tag), pRequest->HTag); 648285809Sscottl 649285809Sscottl if( ABORT_SINGLE == (flag & ABORT_MASK) ) 650285809Sscottl { 651285809Sscottl if (agNULL == pRequestABT) 652285809Sscottl { 653285809Sscottl /* remove the request from IOMap */ 654285809Sscottl saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 655285809Sscottl saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 656285809Sscottl saRoot->IOMap[pRequest->HTag].agContext = agNULL; 657285809Sscottl /* Delete the request from the pendingSMPRequests */ 658285809Sscottl ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 659285809Sscottl saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 660285809Sscottl /* return the request to free pool */ 661285809Sscottl if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) 662285809Sscottl { 663285809Sscottl SA_DBG1(("saSMPAbort: saving pRequest (%p) for later use\n", pRequest)); 664285809Sscottl saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 665285809Sscottl } 666285809Sscottl else 667285809Sscottl { 668285809Sscottl /* return the request to free pool */ 669285809Sscottl saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 670285809Sscottl } 671285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 672285809Sscottl SA_DBG1(("saSMPAbort, agNULL == pRequestABT\n")); 673285809Sscottl /* The IO to Be Abort is no longer exist - can not Abort */ 674285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "9b"); 675285809Sscottl return AGSA_RC_FAILURE; 676285809Sscottl } 677285809Sscottl OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPAbortCmd_t, HTagAbort), pRequestABT->HTag); 678285809Sscottl } 679285809Sscottl else 680285809Sscottl { 681285809Sscottl /* abort all */ 682285809Sscottl OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPAbortCmd_t, HTagAbort), 0); 683285809Sscottl } 684285809Sscottl OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPAbortCmd_t, deviceId), pDevice->DeviceMapIndex); 685285809Sscottl OSSA_WRITE_LE_32(agRoot, &payload, OSSA_OFFSET_OF(agsaSMPAbortCmd_t, Scp), flag); 686285809Sscottl 687285809Sscottl SA_DBG1(("saSMPAbort, HTag 0x%x HTagABT 0x%x deviceId 0x%x\n", payload.tag, payload.HTagAbort, payload.deviceId)); 688285809Sscottl 689285809Sscottl /* build IOMB command and send to SPC */ 690285809Sscottl ret = mpiBuildCmd(agRoot, (bit32 *)&payload, MPI_CATEGORY_SAS_SATA, OPC_INB_SMP_ABORT, IOMB_SIZE64, queueNum); 691285809Sscottl if (AGSA_RC_SUCCESS != ret) 692285809Sscottl { 693285809Sscottl /* remove the request from IOMap */ 694285809Sscottl saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; 695285809Sscottl saRoot->IOMap[pRequest->HTag].IORequest = agNULL; 696285809Sscottl saRoot->IOMap[pRequest->HTag].agContext = agNULL; 697285809Sscottl /* Delete the request from the pendingSMPRequests */ 698285809Sscottl ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); 699285809Sscottl saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); 700285809Sscottl /* return the request to free pool */ 701285809Sscottl if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) 702285809Sscottl { 703285809Sscottl SA_DBG1(("saSMPAbort: saving pRequest (%p) for later use\n", pRequest)); 704285809Sscottl saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); 705285809Sscottl } 706285809Sscottl else 707285809Sscottl { 708285809Sscottl /* return the request to free pool */ 709285809Sscottl saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); 710285809Sscottl } 711285809Sscottl ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); 712285809Sscottl SA_DBG1(("saSMPAbort, sending IOMB failed\n" )); 713285809Sscottl } 714285809Sscottl#ifdef SALL_API_TEST 715285809Sscottl else 716285809Sscottl { 717285809Sscottl saRoot->LLCounters.IOCounter.numSMPAborted++; 718285809Sscottl } 719285809Sscottl#endif 720285809Sscottl 721285809Sscottl smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "9b"); 722285809Sscottl 723285809Sscottl return ret; 724285809Sscottl} 725285809Sscottl 726285809Sscottl 727285809Sscottl 728