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$");
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