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