1*4e1bc9a0SAchim Leubner /*******************************************************************************
2*4e1bc9a0SAchim Leubner *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
3*4e1bc9a0SAchim Leubner *
4*4e1bc9a0SAchim Leubner *Redistribution and use in source and binary forms, with or without modification, are permitted provided
5*4e1bc9a0SAchim Leubner *that the following conditions are met:
6*4e1bc9a0SAchim Leubner *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
7*4e1bc9a0SAchim Leubner *following disclaimer.
8*4e1bc9a0SAchim Leubner *2. Redistributions in binary form must reproduce the above copyright notice,
9*4e1bc9a0SAchim Leubner *this list of conditions and the following disclaimer in the documentation and/or other materials provided
10*4e1bc9a0SAchim Leubner *with the distribution.
11*4e1bc9a0SAchim Leubner *
12*4e1bc9a0SAchim Leubner *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13*4e1bc9a0SAchim Leubner *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14*4e1bc9a0SAchim Leubner *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15*4e1bc9a0SAchim Leubner *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16*4e1bc9a0SAchim Leubner *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17*4e1bc9a0SAchim Leubner *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18*4e1bc9a0SAchim Leubner *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19*4e1bc9a0SAchim Leubner *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
20*4e1bc9a0SAchim Leubner
21*4e1bc9a0SAchim Leubner ********************************************************************************/
22*4e1bc9a0SAchim Leubner /*******************************************************************************/
23*4e1bc9a0SAchim Leubner /*! \file sasata.c
24*4e1bc9a0SAchim Leubner * \brief The file implements the functions to SATA IO
25*4e1bc9a0SAchim Leubner *
26*4e1bc9a0SAchim Leubner */
27*4e1bc9a0SAchim Leubner /******************************************************************************/
28*4e1bc9a0SAchim Leubner #include <sys/cdefs.h>
29*4e1bc9a0SAchim Leubner #include <dev/pms/config.h>
30*4e1bc9a0SAchim Leubner
31*4e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/sallsdk/spc/saglobal.h>
32*4e1bc9a0SAchim Leubner #ifdef SA_ENABLE_TRACE_FUNCTIONS
33*4e1bc9a0SAchim Leubner #ifdef siTraceFileID
34*4e1bc9a0SAchim Leubner #undef siTraceFileID
35*4e1bc9a0SAchim Leubner #endif
36*4e1bc9a0SAchim Leubner #define siTraceFileID 'M'
37*4e1bc9a0SAchim Leubner #endif
38*4e1bc9a0SAchim Leubner
39*4e1bc9a0SAchim Leubner /******************************************************************************/
40*4e1bc9a0SAchim Leubner /*! \brief Start SATA command
41*4e1bc9a0SAchim Leubner *
42*4e1bc9a0SAchim Leubner * Start SATA command
43*4e1bc9a0SAchim Leubner *
44*4e1bc9a0SAchim Leubner * \param agRoot handles for this instance of SAS/SATA hardware
45*4e1bc9a0SAchim Leubner * \param queueNum
46*4e1bc9a0SAchim Leubner * \param agIORequest
47*4e1bc9a0SAchim Leubner * \param agDevHandle
48*4e1bc9a0SAchim Leubner * \param agRequestType
49*4e1bc9a0SAchim Leubner * \param agSATAReq
50*4e1bc9a0SAchim Leubner * \param agTag
51*4e1bc9a0SAchim Leubner * \param agCB
52*4e1bc9a0SAchim Leubner *
53*4e1bc9a0SAchim Leubner * \return If command is started successfully
54*4e1bc9a0SAchim Leubner * - \e AGSA_RC_SUCCESS command is started successfully
55*4e1bc9a0SAchim Leubner * - \e AGSA_RC_FAILURE command is not started successfully
56*4e1bc9a0SAchim Leubner */
57*4e1bc9a0SAchim Leubner /*******************************************************************************/
saSATAStart(agsaRoot_t * agRoot,agsaIORequest_t * agIORequest,bit32 queueNum,agsaDevHandle_t * agDevHandle,bit32 agRequestType,agsaSATAInitiatorRequest_t * agSATAReq,bit8 agTag,ossaSATACompletedCB_t agCB)58*4e1bc9a0SAchim Leubner GLOBAL bit32 saSATAStart(
59*4e1bc9a0SAchim Leubner agsaRoot_t *agRoot,
60*4e1bc9a0SAchim Leubner agsaIORequest_t *agIORequest,
61*4e1bc9a0SAchim Leubner bit32 queueNum,
62*4e1bc9a0SAchim Leubner agsaDevHandle_t *agDevHandle,
63*4e1bc9a0SAchim Leubner bit32 agRequestType,
64*4e1bc9a0SAchim Leubner agsaSATAInitiatorRequest_t *agSATAReq,
65*4e1bc9a0SAchim Leubner bit8 agTag,
66*4e1bc9a0SAchim Leubner ossaSATACompletedCB_t agCB
67*4e1bc9a0SAchim Leubner )
68*4e1bc9a0SAchim Leubner
69*4e1bc9a0SAchim Leubner {
70*4e1bc9a0SAchim Leubner agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
71*4e1bc9a0SAchim Leubner mpiICQueue_t *circularQ = agNULL;
72*4e1bc9a0SAchim Leubner agsaDeviceDesc_t *pDevice = agNULL;
73*4e1bc9a0SAchim Leubner agsaPort_t *pPort = agNULL;
74*4e1bc9a0SAchim Leubner agsaIORequestDesc_t *pRequest = agNULL;
75*4e1bc9a0SAchim Leubner void *pMessage = agNULL;
76*4e1bc9a0SAchim Leubner agsaSgl_t *pSgl = agNULL;
77*4e1bc9a0SAchim Leubner bit32 *payload = agNULL;
78*4e1bc9a0SAchim Leubner bit32 deviceIndex = 0;
79*4e1bc9a0SAchim Leubner bit32 ret = AGSA_RC_SUCCESS, retVal = 0;
80*4e1bc9a0SAchim Leubner bit32 AtapDir = 0;
81*4e1bc9a0SAchim Leubner bit32 encryptFlags = 0;
82*4e1bc9a0SAchim Leubner bit16 size = 0;
83*4e1bc9a0SAchim Leubner bit16 opCode = 0;
84*4e1bc9a0SAchim Leubner bit8 inq = 0, outq = 0;
85*4e1bc9a0SAchim Leubner
86*4e1bc9a0SAchim Leubner OSSA_INP_ENTER(agRoot);
87*4e1bc9a0SAchim Leubner smTraceFuncEnter(hpDBG_VERY_LOUD, "8a");
88*4e1bc9a0SAchim Leubner
89*4e1bc9a0SAchim Leubner SA_DBG3(("saSATAStart: in\n"));
90*4e1bc9a0SAchim Leubner /* sanity check */
91*4e1bc9a0SAchim Leubner SA_ASSERT((agNULL != agRoot), "(saSATAStart) agRoot is NULL");
92*4e1bc9a0SAchim Leubner SA_ASSERT((agNULL != agIORequest), "(saSATAStart) agIORequest is NULL");
93*4e1bc9a0SAchim Leubner SA_ASSERT((agNULL != agDevHandle), "(saSATAStart) agDevHandle is NULL");
94*4e1bc9a0SAchim Leubner SA_ASSERT((agNULL != agSATAReq), "(saSATAStart) agSATAReq is NULL");
95*4e1bc9a0SAchim Leubner
96*4e1bc9a0SAchim Leubner /* Assign inbound and outbound queue */
97*4e1bc9a0SAchim Leubner inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
98*4e1bc9a0SAchim Leubner outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
99*4e1bc9a0SAchim Leubner SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
100*4e1bc9a0SAchim Leubner
101*4e1bc9a0SAchim Leubner /* Find the outgoing port for the device */
102*4e1bc9a0SAchim Leubner pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
103*4e1bc9a0SAchim Leubner SA_ASSERT((agNULL != pDevice), "(saSATAStart) pDevice is NULL");
104*4e1bc9a0SAchim Leubner
105*4e1bc9a0SAchim Leubner pPort = pDevice->pPort;
106*4e1bc9a0SAchim Leubner SA_ASSERT((agNULL != pPort), "(saSATAStart) pPort is NULL");
107*4e1bc9a0SAchim Leubner
108*4e1bc9a0SAchim Leubner /* SATA DIF is obsolete */
109*4e1bc9a0SAchim Leubner if (agSATAReq->option & AGSA_SATA_ENABLE_DIF)
110*4e1bc9a0SAchim Leubner {
111*4e1bc9a0SAchim Leubner return AGSA_RC_FAILURE;
112*4e1bc9a0SAchim Leubner }
113*4e1bc9a0SAchim Leubner
114*4e1bc9a0SAchim Leubner /* find deviceID for IOMB */
115*4e1bc9a0SAchim Leubner deviceIndex = pDevice->DeviceMapIndex;
116*4e1bc9a0SAchim Leubner
117*4e1bc9a0SAchim Leubner /* Get request from free IORequests */
118*4e1bc9a0SAchim Leubner ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
119*4e1bc9a0SAchim Leubner pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
120*4e1bc9a0SAchim Leubner if ( agNULL != pRequest )
121*4e1bc9a0SAchim Leubner {
122*4e1bc9a0SAchim Leubner /* If free IOMB avaliable */
123*4e1bc9a0SAchim Leubner /* Remove the request from free list */
124*4e1bc9a0SAchim Leubner saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
125*4e1bc9a0SAchim Leubner
126*4e1bc9a0SAchim Leubner /* Add the request to the pendingSTARequests list of the device */
127*4e1bc9a0SAchim Leubner pRequest->valid = agTRUE;
128*4e1bc9a0SAchim Leubner saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode));
129*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
130*4e1bc9a0SAchim Leubner
131*4e1bc9a0SAchim Leubner if ((agSATAReq->option & AGSA_SATA_ENABLE_ENCRYPTION) ||
132*4e1bc9a0SAchim Leubner (agSATAReq->option & AGSA_SATA_ENABLE_DIF))
133*4e1bc9a0SAchim Leubner {
134*4e1bc9a0SAchim Leubner opCode = OPC_INB_SATA_DIF_ENC_OPSTART;
135*4e1bc9a0SAchim Leubner size = IOMB_SIZE128;
136*4e1bc9a0SAchim Leubner }
137*4e1bc9a0SAchim Leubner else
138*4e1bc9a0SAchim Leubner {
139*4e1bc9a0SAchim Leubner opCode = OPC_INB_SATA_HOST_OPSTART;
140*4e1bc9a0SAchim Leubner if (agRequestType == AGSA_SATA_PROTOCOL_NON_PKT ||
141*4e1bc9a0SAchim Leubner agRequestType == AGSA_SATA_PROTOCOL_H2D_PKT ||
142*4e1bc9a0SAchim Leubner agRequestType == AGSA_SATA_PROTOCOL_D2H_PKT)
143*4e1bc9a0SAchim Leubner size = IOMB_SIZE128;
144*4e1bc9a0SAchim Leubner else
145*4e1bc9a0SAchim Leubner size = IOMB_SIZE64;
146*4e1bc9a0SAchim Leubner }
147*4e1bc9a0SAchim Leubner /* If LL IO request entry avaliable */
148*4e1bc9a0SAchim Leubner /* set up pRequest */
149*4e1bc9a0SAchim Leubner pRequest->pIORequestContext = agIORequest;
150*4e1bc9a0SAchim Leubner pRequest->pDevice = pDevice;
151*4e1bc9a0SAchim Leubner pRequest->pPort = pPort;
152*4e1bc9a0SAchim Leubner pRequest->requestType = agRequestType;
153*4e1bc9a0SAchim Leubner pRequest->startTick = saRoot->timeTick;
154*4e1bc9a0SAchim Leubner pRequest->completionCB = (ossaSSPCompletedCB_t)agCB;
155*4e1bc9a0SAchim Leubner /* Set request to the sdkData of agIORequest */
156*4e1bc9a0SAchim Leubner agIORequest->sdkData = pRequest;
157*4e1bc9a0SAchim Leubner
158*4e1bc9a0SAchim Leubner /* save tag and IOrequest pointer to IOMap */
159*4e1bc9a0SAchim Leubner saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
160*4e1bc9a0SAchim Leubner saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
161*4e1bc9a0SAchim Leubner
162*4e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
163*4e1bc9a0SAchim Leubner ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
164*4e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
165*4e1bc9a0SAchim Leubner
166*4e1bc9a0SAchim Leubner /* get a free inbound queue entry */
167*4e1bc9a0SAchim Leubner circularQ = &saRoot->inboundQueue[inq];
168*4e1bc9a0SAchim Leubner retVal = mpiMsgFreeGet(circularQ, size, &pMessage);
169*4e1bc9a0SAchim Leubner
170*4e1bc9a0SAchim Leubner if (AGSA_RC_FAILURE == retVal)
171*4e1bc9a0SAchim Leubner {
172*4e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
173*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
174*4e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
175*4e1bc9a0SAchim Leubner /* if not sending return to free list rare */
176*4e1bc9a0SAchim Leubner ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
177*4e1bc9a0SAchim Leubner saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
178*4e1bc9a0SAchim Leubner pRequest->valid = agFALSE;
179*4e1bc9a0SAchim Leubner saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
180*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
181*4e1bc9a0SAchim Leubner
182*4e1bc9a0SAchim Leubner SA_DBG3(("saSATAStart, error when get free IOMB\n"));
183*4e1bc9a0SAchim Leubner smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "8a");
184*4e1bc9a0SAchim Leubner ret = AGSA_RC_FAILURE;
185*4e1bc9a0SAchim Leubner goto ext;
186*4e1bc9a0SAchim Leubner }
187*4e1bc9a0SAchim Leubner
188*4e1bc9a0SAchim Leubner /* return busy if inbound queue is full */
189*4e1bc9a0SAchim Leubner if (AGSA_RC_BUSY == retVal)
190*4e1bc9a0SAchim Leubner {
191*4e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
192*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
193*4e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
194*4e1bc9a0SAchim Leubner /* if not sending return to free list rare */
195*4e1bc9a0SAchim Leubner ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
196*4e1bc9a0SAchim Leubner saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
197*4e1bc9a0SAchim Leubner pRequest->valid = agFALSE;
198*4e1bc9a0SAchim Leubner saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
199*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
200*4e1bc9a0SAchim Leubner
201*4e1bc9a0SAchim Leubner SA_DBG1(("saSATAStart, no more IOMB\n"));
202*4e1bc9a0SAchim Leubner smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "8a");
203*4e1bc9a0SAchim Leubner ret = AGSA_RC_BUSY;
204*4e1bc9a0SAchim Leubner goto ext;
205*4e1bc9a0SAchim Leubner }
206*4e1bc9a0SAchim Leubner
207*4e1bc9a0SAchim Leubner }
208*4e1bc9a0SAchim Leubner else /* If no LL IO request entry available */
209*4e1bc9a0SAchim Leubner {
210*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
211*4e1bc9a0SAchim Leubner SA_DBG1(("saSATAStart, No request from free list\n"));
212*4e1bc9a0SAchim Leubner smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "8a");
213*4e1bc9a0SAchim Leubner ret = AGSA_RC_BUSY;
214*4e1bc9a0SAchim Leubner goto ext;
215*4e1bc9a0SAchim Leubner }
216*4e1bc9a0SAchim Leubner
217*4e1bc9a0SAchim Leubner payload = (bit32 *)pMessage;
218*4e1bc9a0SAchim Leubner SA_DBG4(("saSATAStart: Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage)));
219*4e1bc9a0SAchim Leubner
220*4e1bc9a0SAchim Leubner
221*4e1bc9a0SAchim Leubner switch ( agRequestType )
222*4e1bc9a0SAchim Leubner {
223*4e1bc9a0SAchim Leubner case AGSA_SATA_PROTOCOL_FPDMA_READ:
224*4e1bc9a0SAchim Leubner case AGSA_SATA_PROTOCOL_FPDMA_WRITE:
225*4e1bc9a0SAchim Leubner case AGSA_SATA_PROTOCOL_FPDMA_READ_M:
226*4e1bc9a0SAchim Leubner case AGSA_SATA_PROTOCOL_FPDMA_WRITE_M:
227*4e1bc9a0SAchim Leubner pSgl = &(agSATAReq->agSgl);
228*4e1bc9a0SAchim Leubner AtapDir = agRequestType & (AGSA_DIR_MASK | AGSA_SATA_ATAP_MASK);
229*4e1bc9a0SAchim Leubner if (agRequestType & AGSA_MSG)
230*4e1bc9a0SAchim Leubner {
231*4e1bc9a0SAchim Leubner /* set M bit */
232*4e1bc9a0SAchim Leubner AtapDir |= AGSA_MSG_BIT;
233*4e1bc9a0SAchim Leubner }
234*4e1bc9a0SAchim Leubner break;
235*4e1bc9a0SAchim Leubner case AGSA_SATA_PROTOCOL_DMA_READ:
236*4e1bc9a0SAchim Leubner case AGSA_SATA_PROTOCOL_DMA_WRITE:
237*4e1bc9a0SAchim Leubner case AGSA_SATA_PROTOCOL_DMA_READ_M:
238*4e1bc9a0SAchim Leubner case AGSA_SATA_PROTOCOL_DMA_WRITE_M:
239*4e1bc9a0SAchim Leubner case AGSA_SATA_PROTOCOL_PIO_READ_M:
240*4e1bc9a0SAchim Leubner case AGSA_SATA_PROTOCOL_PIO_WRITE_M:
241*4e1bc9a0SAchim Leubner case AGSA_SATA_PROTOCOL_PIO_READ:
242*4e1bc9a0SAchim Leubner case AGSA_SATA_PROTOCOL_PIO_WRITE:
243*4e1bc9a0SAchim Leubner case AGSA_SATA_PROTOCOL_H2D_PKT:
244*4e1bc9a0SAchim Leubner case AGSA_SATA_PROTOCOL_D2H_PKT:
245*4e1bc9a0SAchim Leubner agTag = 0; /* agTag not valid for these requests */
246*4e1bc9a0SAchim Leubner pSgl = &(agSATAReq->agSgl);
247*4e1bc9a0SAchim Leubner AtapDir = agRequestType & (AGSA_DIR_MASK | AGSA_SATA_ATAP_MASK);
248*4e1bc9a0SAchim Leubner if (agRequestType & AGSA_MSG)
249*4e1bc9a0SAchim Leubner {
250*4e1bc9a0SAchim Leubner /* set M bit */
251*4e1bc9a0SAchim Leubner AtapDir |= AGSA_MSG_BIT;
252*4e1bc9a0SAchim Leubner }
253*4e1bc9a0SAchim Leubner break;
254*4e1bc9a0SAchim Leubner
255*4e1bc9a0SAchim Leubner case AGSA_SATA_PROTOCOL_NON_DATA:
256*4e1bc9a0SAchim Leubner case AGSA_SATA_PROTOCOL_NON_DATA_M:
257*4e1bc9a0SAchim Leubner case AGSA_SATA_PROTOCOL_NON_PKT:
258*4e1bc9a0SAchim Leubner agTag = 0; /* agTag not valid for these requests */
259*4e1bc9a0SAchim Leubner AtapDir = agRequestType & (AGSA_DIR_MASK | AGSA_SATA_ATAP_MASK);
260*4e1bc9a0SAchim Leubner if (agRequestType & AGSA_MSG)
261*4e1bc9a0SAchim Leubner {
262*4e1bc9a0SAchim Leubner /* set M bit */
263*4e1bc9a0SAchim Leubner AtapDir |= AGSA_MSG_BIT;
264*4e1bc9a0SAchim Leubner }
265*4e1bc9a0SAchim Leubner break;
266*4e1bc9a0SAchim Leubner
267*4e1bc9a0SAchim Leubner case AGSA_SATA_PROTOCOL_SRST_ASSERT:
268*4e1bc9a0SAchim Leubner agTag = 0; /* agTag not valid for these requests */
269*4e1bc9a0SAchim Leubner AtapDir = AGSA_SATA_ATAP_SRST_ASSERT;
270*4e1bc9a0SAchim Leubner break;
271*4e1bc9a0SAchim Leubner
272*4e1bc9a0SAchim Leubner case AGSA_SATA_PROTOCOL_SRST_DEASSERT:
273*4e1bc9a0SAchim Leubner agTag = 0; /* agTag not valid for these requests */
274*4e1bc9a0SAchim Leubner AtapDir = AGSA_SATA_ATAP_SRST_DEASSERT;
275*4e1bc9a0SAchim Leubner break;
276*4e1bc9a0SAchim Leubner
277*4e1bc9a0SAchim Leubner case AGSA_SATA_PROTOCOL_DEV_RESET:
278*4e1bc9a0SAchim Leubner case AGSA_SATA_PROTOCOL_DEV_RESET_M: /* TestBase */
279*4e1bc9a0SAchim Leubner agTag = 0; /* agTag not valid for these requests */
280*4e1bc9a0SAchim Leubner AtapDir = AGSA_SATA_ATAP_PKT_DEVRESET;
281*4e1bc9a0SAchim Leubner if (agRequestType & AGSA_MSG)
282*4e1bc9a0SAchim Leubner {
283*4e1bc9a0SAchim Leubner /* set M bit */
284*4e1bc9a0SAchim Leubner AtapDir |= AGSA_MSG_BIT; /* TestBase */
285*4e1bc9a0SAchim Leubner }
286*4e1bc9a0SAchim Leubner break;
287*4e1bc9a0SAchim Leubner
288*4e1bc9a0SAchim Leubner default:
289*4e1bc9a0SAchim Leubner SA_DBG1(("saSATAStart: (Unknown agRequestType) 0x%X \n",agRequestType));
290*4e1bc9a0SAchim Leubner SA_ASSERT((0), "saSATAStart: (Unknown agRequestType)");
291*4e1bc9a0SAchim Leubner
292*4e1bc9a0SAchim Leubner break;
293*4e1bc9a0SAchim Leubner }
294*4e1bc9a0SAchim Leubner
295*4e1bc9a0SAchim Leubner if ((AGSA_SATA_PROTOCOL_SRST_ASSERT == agRequestType) ||
296*4e1bc9a0SAchim Leubner (AGSA_SATA_PROTOCOL_SRST_DEASSERT == agRequestType) ||
297*4e1bc9a0SAchim Leubner (AGSA_SATA_PROTOCOL_DEV_RESET == agRequestType))
298*4e1bc9a0SAchim Leubner {
299*4e1bc9a0SAchim Leubner
300*4e1bc9a0SAchim Leubner SA_DBG3(("saSATAStart:AGSA_SATA_PROTOCOL_SRST_DEASSERT AGSA_SATA_PROTOCOL_SRST_ASSERT\n"));
301*4e1bc9a0SAchim Leubner
302*4e1bc9a0SAchim Leubner si_memset((void *)payload, 0, sizeof(agsaSATAStartCmd_t));
303*4e1bc9a0SAchim Leubner /* build IOMB DW 1 */
304*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t, tag), pRequest->HTag);
305*4e1bc9a0SAchim Leubner /* DWORD 2 */
306*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,deviceId ), deviceIndex);
307*4e1bc9a0SAchim Leubner /* DWORD 3 */
308*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,dataLen ), 0 );
309*4e1bc9a0SAchim Leubner /* DWORD 4 */
310*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot,
311*4e1bc9a0SAchim Leubner payload,
312*4e1bc9a0SAchim Leubner OSSA_OFFSET_OF(agsaSATAStartCmd_t,optNCQTagataProt ),
313*4e1bc9a0SAchim Leubner (((agSATAReq->option & SATA_FIS_MASK) << SHIFT24) |
314*4e1bc9a0SAchim Leubner (agTag << SHIFT16) |
315*4e1bc9a0SAchim Leubner AtapDir));
316*4e1bc9a0SAchim Leubner
317*4e1bc9a0SAchim Leubner si_memcpy((void *)(payload+4), (void *)&agSATAReq->fis.fisRegHostToDev, sizeof(agsaFisRegHostToDevice_t));
318*4e1bc9a0SAchim Leubner }
319*4e1bc9a0SAchim Leubner else
320*4e1bc9a0SAchim Leubner {
321*4e1bc9a0SAchim Leubner /* build IOMB DW 1 */
322*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t, tag), pRequest->HTag);
323*4e1bc9a0SAchim Leubner /* DWORD 2 */
324*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,deviceId ), deviceIndex);
325*4e1bc9a0SAchim Leubner /* DWORD 3 */
326*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,dataLen ), agSATAReq->dataLength );
327*4e1bc9a0SAchim Leubner
328*4e1bc9a0SAchim Leubner /* Since we are writing the payload in order, check for any special modes now. */
329*4e1bc9a0SAchim Leubner if (agSATAReq->option & AGSA_SATA_ENABLE_ENCRYPTION)
330*4e1bc9a0SAchim Leubner {
331*4e1bc9a0SAchim Leubner SA_ASSERT((opCode == OPC_INB_SATA_DIF_ENC_OPSTART), "opcode");
332*4e1bc9a0SAchim Leubner SA_DBG4(("saSATAStart: 1 Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage)));
333*4e1bc9a0SAchim Leubner AtapDir |= AGSA_ENCRYPT_BIT;
334*4e1bc9a0SAchim Leubner }
335*4e1bc9a0SAchim Leubner
336*4e1bc9a0SAchim Leubner if (agSATAReq->option & AGSA_SATA_ENABLE_DIF)
337*4e1bc9a0SAchim Leubner {
338*4e1bc9a0SAchim Leubner SA_ASSERT((opCode == OPC_INB_SATA_DIF_ENC_OPSTART), "opcode");
339*4e1bc9a0SAchim Leubner AtapDir |= AGSA_DIF_BIT;
340*4e1bc9a0SAchim Leubner }
341*4e1bc9a0SAchim Leubner #ifdef CCBUILD_TEST_EPL
342*4e1bc9a0SAchim Leubner if(agSATAReq->encrypt.enableEncryptionPerLA)
343*4e1bc9a0SAchim Leubner AtapDir |= (1 << SHIFT4); // enable EPL
344*4e1bc9a0SAchim Leubner #endif
345*4e1bc9a0SAchim Leubner /* DWORD 4 */
346*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot,
347*4e1bc9a0SAchim Leubner payload,
348*4e1bc9a0SAchim Leubner OSSA_OFFSET_OF(agsaSATAStartCmd_t,optNCQTagataProt ),
349*4e1bc9a0SAchim Leubner (((agSATAReq->option & SATA_FIS_MASK) << SHIFT24) |
350*4e1bc9a0SAchim Leubner (agTag << SHIFT16) |
351*4e1bc9a0SAchim Leubner AtapDir));
352*4e1bc9a0SAchim Leubner
353*4e1bc9a0SAchim Leubner /* DWORD 5 6 7 8 9 */
354*4e1bc9a0SAchim Leubner si_memcpy((void *)(payload+4), (void *)&agSATAReq->fis.fisRegHostToDev, sizeof(agsaFisRegHostToDevice_t));
355*4e1bc9a0SAchim Leubner /* DWORD 10 reserved */
356*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,reserved1 ), 0 );
357*4e1bc9a0SAchim Leubner
358*4e1bc9a0SAchim Leubner /* DWORD 11 reserved */
359*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,reserved2 ), 0 );
360*4e1bc9a0SAchim Leubner
361*4e1bc9a0SAchim Leubner SA_DBG4(("saSATAStart: 2 Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage)));
362*4e1bc9a0SAchim Leubner }
363*4e1bc9a0SAchim Leubner if (agSATAReq->option & AGSA_SATA_ENABLE_ENCRYPTION)
364*4e1bc9a0SAchim Leubner {
365*4e1bc9a0SAchim Leubner /* Write 10 dwords of zeroes as payload, skipping all DIF fields */
366*4e1bc9a0SAchim Leubner SA_DBG4(("saSATAStart: 2a Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage)));
367*4e1bc9a0SAchim Leubner if (opCode == OPC_INB_SATA_DIF_ENC_OPSTART)
368*4e1bc9a0SAchim Leubner {
369*4e1bc9a0SAchim Leubner /* DW 11 */
370*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Res_EPL_DESCL ),0 );
371*4e1bc9a0SAchim Leubner /* DW 12 */
372*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,resSKIPBYTES ),0 );
373*4e1bc9a0SAchim Leubner /* DW 13 */
374*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Res_DPL_DESCL_NDPLR ),0 );
375*4e1bc9a0SAchim Leubner /* DW 14 */
376*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Res_EDPL_DESCH ),0 );
377*4e1bc9a0SAchim Leubner /* DW 15 */
378*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,DIF_flags ),0 );
379*4e1bc9a0SAchim Leubner /* DW 16 */
380*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,udt ),0 );
381*4e1bc9a0SAchim Leubner /* DW 17 */
382*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,udtReplacementLo ),0 );
383*4e1bc9a0SAchim Leubner /* DW 18 */
384*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,udtReplacementHi ),0 );
385*4e1bc9a0SAchim Leubner /* DW 19 */
386*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,DIF_seed ),0 );
387*4e1bc9a0SAchim Leubner }
388*4e1bc9a0SAchim Leubner
389*4e1bc9a0SAchim Leubner if (agSATAReq->option & AGSA_SATA_ENABLE_ENCRYPTION)
390*4e1bc9a0SAchim Leubner {
391*4e1bc9a0SAchim Leubner SA_ASSERT((opCode == OPC_INB_SATA_DIF_ENC_OPSTART), "opcode");
392*4e1bc9a0SAchim Leubner
393*4e1bc9a0SAchim Leubner SA_DBG4(("saSATAStart: 3 Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage)));
394*4e1bc9a0SAchim Leubner /* Configure DWORD 20 */
395*4e1bc9a0SAchim Leubner encryptFlags = 0;
396*4e1bc9a0SAchim Leubner
397*4e1bc9a0SAchim Leubner if (agSATAReq->encrypt.keyTagCheck == agTRUE)
398*4e1bc9a0SAchim Leubner {
399*4e1bc9a0SAchim Leubner encryptFlags |= AGSA_ENCRYPT_KEY_TAG_BIT;
400*4e1bc9a0SAchim Leubner }
401*4e1bc9a0SAchim Leubner
402*4e1bc9a0SAchim Leubner if( agSATAReq->encrypt.cipherMode == agsaEncryptCipherModeXTS )
403*4e1bc9a0SAchim Leubner {
404*4e1bc9a0SAchim Leubner encryptFlags |= AGSA_ENCRYPT_XTS_Mode << SHIFT4;
405*4e1bc9a0SAchim Leubner }
406*4e1bc9a0SAchim Leubner
407*4e1bc9a0SAchim Leubner encryptFlags |= agSATAReq->encrypt.dekInfo.dekTable << SHIFT2;
408*4e1bc9a0SAchim Leubner
409*4e1bc9a0SAchim Leubner encryptFlags |= (agSATAReq->encrypt.dekInfo.dekIndex & 0xFFFFFF) << SHIFT8;
410*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,encryptFlagsLo ),encryptFlags );
411*4e1bc9a0SAchim Leubner
412*4e1bc9a0SAchim Leubner /* Configure DWORD 21*/
413*4e1bc9a0SAchim Leubner /* This information is available in the sectorSizeIndex */
414*4e1bc9a0SAchim Leubner encryptFlags = agSATAReq->encrypt.sectorSizeIndex;
415*4e1bc9a0SAchim Leubner /*
416*4e1bc9a0SAchim Leubner * Set Region0 sectors count
417*4e1bc9a0SAchim Leubner */
418*4e1bc9a0SAchim Leubner if(agSATAReq->encrypt.enableEncryptionPerLA)
419*4e1bc9a0SAchim Leubner {
420*4e1bc9a0SAchim Leubner encryptFlags |= (agSATAReq->encrypt.EncryptionPerLRegion0SecCount << SHIFT16);
421*4e1bc9a0SAchim Leubner }
422*4e1bc9a0SAchim Leubner
423*4e1bc9a0SAchim Leubner encryptFlags |= (agSATAReq->encrypt.kekIndex) << SHIFT5;
424*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,encryptFlagsHi ),encryptFlags );
425*4e1bc9a0SAchim Leubner
426*4e1bc9a0SAchim Leubner /* Configure DWORD 22*/
427*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,keyTagLo ), agSATAReq->encrypt.keyTag_W0 );
428*4e1bc9a0SAchim Leubner /* Configure DWORD 23 */
429*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,keyTagHi ), agSATAReq->encrypt.keyTag_W1 );
430*4e1bc9a0SAchim Leubner /* Configure DWORD 24 */
431*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W0 ), agSATAReq->encrypt.tweakVal_W0 );
432*4e1bc9a0SAchim Leubner /* Configure DWORD 25 */
433*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W1 ), agSATAReq->encrypt.tweakVal_W1 );
434*4e1bc9a0SAchim Leubner /* Configure DWORD 26 */
435*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W2 ), agSATAReq->encrypt.tweakVal_W2 );
436*4e1bc9a0SAchim Leubner /* Configure DWORD 27 */
437*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W3 ), agSATAReq->encrypt.tweakVal_W3 );
438*4e1bc9a0SAchim Leubner }
439*4e1bc9a0SAchim Leubner else
440*4e1bc9a0SAchim Leubner {
441*4e1bc9a0SAchim Leubner /* Write 8 dwords of zeros as payload, skipping all encryption fields */
442*4e1bc9a0SAchim Leubner if (opCode == OPC_INB_SATA_DIF_ENC_OPSTART)
443*4e1bc9a0SAchim Leubner {
444*4e1bc9a0SAchim Leubner /* Configure DWORD 22*/
445*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,keyTagLo ), 0 );
446*4e1bc9a0SAchim Leubner /* Configure DWORD 23 */
447*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,keyTagHi ), 0 );
448*4e1bc9a0SAchim Leubner /* Configure DWORD 24 */
449*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W0 ), 0 );
450*4e1bc9a0SAchim Leubner /* Configure DWORD 25 */
451*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W1 ), 0 );
452*4e1bc9a0SAchim Leubner /* Configure DWORD 26 */
453*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W2 ), 0 );
454*4e1bc9a0SAchim Leubner /* Configure DWORD 27 */
455*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,tweakVal_W3 ), 0 );
456*4e1bc9a0SAchim Leubner }
457*4e1bc9a0SAchim Leubner }
458*4e1bc9a0SAchim Leubner
459*4e1bc9a0SAchim Leubner SA_DBG4(("saSATAStart: 4 Payload offset 0x%X\n", (unsigned int)(payload - (bit32 *)pMessage)));
460*4e1bc9a0SAchim Leubner
461*4e1bc9a0SAchim Leubner /* DWORD 11 13 14*/
462*4e1bc9a0SAchim Leubner if(agSATAReq->encrypt.enableEncryptionPerLA)
463*4e1bc9a0SAchim Leubner {
464*4e1bc9a0SAchim Leubner /* DWORD 11 */
465*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t, Res_EPL_DESCL),
466*4e1bc9a0SAchim Leubner agSATAReq->encrypt.EncryptionPerLAAddrLo);
467*4e1bc9a0SAchim Leubner /* DWORD 13 */
468*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t, Res_DPL_DESCL_NDPLR), 0);
469*4e1bc9a0SAchim Leubner /* DWORD 14 */
470*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t, Res_EDPL_DESCH),
471*4e1bc9a0SAchim Leubner agSATAReq->encrypt.EncryptionPerLAAddrHi);
472*4e1bc9a0SAchim Leubner }
473*4e1bc9a0SAchim Leubner else
474*4e1bc9a0SAchim Leubner {
475*4e1bc9a0SAchim Leubner /* DWORD 11 */
476*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t, Res_EPL_DESCL),0);
477*4e1bc9a0SAchim Leubner /* DW 13 */
478*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t, Res_DPL_DESCL_NDPLR), 0);
479*4e1bc9a0SAchim Leubner /* DWORD 14 */
480*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Res_EDPL_DESCH ),0 );
481*4e1bc9a0SAchim Leubner }
482*4e1bc9a0SAchim Leubner
483*4e1bc9a0SAchim Leubner /* Configure DWORD 28 for encryption*/
484*4e1bc9a0SAchim Leubner if (pSgl)
485*4e1bc9a0SAchim Leubner {
486*4e1bc9a0SAchim Leubner /* Configure DWORD 28 */
487*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,AddrLow0 ), pSgl->sgLower );
488*4e1bc9a0SAchim Leubner /* Configure DWORD 29 */
489*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,AddrHi0 ), pSgl->sgUpper );
490*4e1bc9a0SAchim Leubner /* Configure DWORD 30 */
491*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Len0 ), pSgl->len );
492*4e1bc9a0SAchim Leubner /* Configure DWORD 31 */
493*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,E0 ), pSgl->extReserved );
494*4e1bc9a0SAchim Leubner }
495*4e1bc9a0SAchim Leubner else
496*4e1bc9a0SAchim Leubner {
497*4e1bc9a0SAchim Leubner /* Configure DWORD 28 */
498*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,AddrLow0 ), 0 );
499*4e1bc9a0SAchim Leubner /* Configure DWORD 29 */
500*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,AddrHi0 ), 0 );
501*4e1bc9a0SAchim Leubner /* Configure DWORD 30 */
502*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,Len0 ), 0 );
503*4e1bc9a0SAchim Leubner /* Configure DWORD 31 */
504*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAEncryptStartCmd_t,E0 ), 0 );
505*4e1bc9a0SAchim Leubner }
506*4e1bc9a0SAchim Leubner
507*4e1bc9a0SAchim Leubner }
508*4e1bc9a0SAchim Leubner else
509*4e1bc9a0SAchim Leubner {
510*4e1bc9a0SAchim Leubner SA_ASSERT((opCode == OPC_INB_SATA_HOST_OPSTART), "opcode");
511*4e1bc9a0SAchim Leubner if (pSgl)
512*4e1bc9a0SAchim Leubner {
513*4e1bc9a0SAchim Leubner /* Configure DWORD 12 */
514*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,AddrLow0 ), pSgl->sgLower );
515*4e1bc9a0SAchim Leubner /* Configure DWORD 13 */
516*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,AddrHi0 ), pSgl->sgUpper );
517*4e1bc9a0SAchim Leubner /* Configure DWORD 14 */
518*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,Len0 ), pSgl->len );
519*4e1bc9a0SAchim Leubner /* Configure DWORD 15 */
520*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,E0 ), pSgl->extReserved );
521*4e1bc9a0SAchim Leubner }
522*4e1bc9a0SAchim Leubner else
523*4e1bc9a0SAchim Leubner {
524*4e1bc9a0SAchim Leubner /* Configure DWORD 12 */
525*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,AddrLow0 ), 0 );
526*4e1bc9a0SAchim Leubner /* Configure DWORD 13 */
527*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,AddrHi0 ), 0 );
528*4e1bc9a0SAchim Leubner /* Configure DWORD 14 */
529*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,Len0 ), 0 );
530*4e1bc9a0SAchim Leubner /* Configure DWORD 15 */
531*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,E0 ), 0 );
532*4e1bc9a0SAchim Leubner }
533*4e1bc9a0SAchim Leubner /* support ATAPI packet command */
534*4e1bc9a0SAchim Leubner if ((agRequestType == AGSA_SATA_PROTOCOL_NON_PKT ||
535*4e1bc9a0SAchim Leubner agRequestType == AGSA_SATA_PROTOCOL_H2D_PKT ||
536*4e1bc9a0SAchim Leubner agRequestType == AGSA_SATA_PROTOCOL_D2H_PKT))
537*4e1bc9a0SAchim Leubner {
538*4e1bc9a0SAchim Leubner /*DWORD 16 - 19 as SCSI CDB for support ATAPI Packet command*/
539*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,ATAPICDB ),
540*4e1bc9a0SAchim Leubner (bit32)(agSATAReq->scsiCDB[0]|(agSATAReq->scsiCDB[1]<<8)|(agSATAReq->scsiCDB[2]<<16)|(agSATAReq->scsiCDB[3]<<24)));
541*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,ATAPICDB )+ 4,
542*4e1bc9a0SAchim Leubner (bit32)(agSATAReq->scsiCDB[4]|(agSATAReq->scsiCDB[5]<<8)|(agSATAReq->scsiCDB[6]<<16)|(agSATAReq->scsiCDB[7]<<24)));
543*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,ATAPICDB )+ 8,
544*4e1bc9a0SAchim Leubner (bit32)(agSATAReq->scsiCDB[8]|(agSATAReq->scsiCDB[9]<<8)|(agSATAReq->scsiCDB[10]<<16)|(agSATAReq->scsiCDB[11]<<24)));
545*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAStartCmd_t,ATAPICDB )+ 12,
546*4e1bc9a0SAchim Leubner (bit32)(agSATAReq->scsiCDB[12]|(agSATAReq->scsiCDB[13]<<8)|(agSATAReq->scsiCDB[14]<<16)|(agSATAReq->scsiCDB[15]<<24)));
547*4e1bc9a0SAchim Leubner }
548*4e1bc9a0SAchim Leubner }
549*4e1bc9a0SAchim Leubner
550*4e1bc9a0SAchim Leubner /* send IOMB to SPC */
551*4e1bc9a0SAchim Leubner ret = mpiMsgProduce(circularQ,
552*4e1bc9a0SAchim Leubner (void *)pMessage,
553*4e1bc9a0SAchim Leubner MPI_CATEGORY_SAS_SATA,
554*4e1bc9a0SAchim Leubner opCode,
555*4e1bc9a0SAchim Leubner outq,
556*4e1bc9a0SAchim Leubner (bit8)circularQ->priority);
557*4e1bc9a0SAchim Leubner
558*4e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
559*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
560*4e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
561*4e1bc9a0SAchim Leubner
562*4e1bc9a0SAchim Leubner #ifdef SALL_API_TEST
563*4e1bc9a0SAchim Leubner if (AGSA_RC_FAILURE != ret)
564*4e1bc9a0SAchim Leubner {
565*4e1bc9a0SAchim Leubner saRoot->LLCounters.IOCounter.numSataStarted++;
566*4e1bc9a0SAchim Leubner }
567*4e1bc9a0SAchim Leubner #endif
568*4e1bc9a0SAchim Leubner
569*4e1bc9a0SAchim Leubner smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "8a");
570*4e1bc9a0SAchim Leubner
571*4e1bc9a0SAchim Leubner ext:
572*4e1bc9a0SAchim Leubner OSSA_INP_LEAVE(agRoot);
573*4e1bc9a0SAchim Leubner return ret;
574*4e1bc9a0SAchim Leubner }
575*4e1bc9a0SAchim Leubner
576*4e1bc9a0SAchim Leubner /******************************************************************************/
577*4e1bc9a0SAchim Leubner /*! \brief Abort SATA command
578*4e1bc9a0SAchim Leubner *
579*4e1bc9a0SAchim Leubner * Abort SATA command
580*4e1bc9a0SAchim Leubner *
581*4e1bc9a0SAchim Leubner * \param agRoot handles for this instance of SAS/SATA hardware
582*4e1bc9a0SAchim Leubner * \param queueNum inbound/outbound queue number
583*4e1bc9a0SAchim Leubner * \param agIORequest the IO Request descriptor
584*4e1bc9a0SAchim Leubner * \param agIOtoBeAborted
585*4e1bc9a0SAchim Leubner *
586*4e1bc9a0SAchim Leubner * \return If command is aborted successfully
587*4e1bc9a0SAchim Leubner * - \e AGSA_RC_SUCCESS command is aborted successfully
588*4e1bc9a0SAchim Leubner * - \e AGSA_RC_FAILURE command is not aborted successfully
589*4e1bc9a0SAchim Leubner */
590*4e1bc9a0SAchim Leubner /*******************************************************************************/
saSATAAbort(agsaRoot_t * agRoot,agsaIORequest_t * agIORequest,bit32 queueNum,agsaDevHandle_t * agDevHandle,bit32 flag,void * abortParam,ossaGenericAbortCB_t agCB)591*4e1bc9a0SAchim Leubner GLOBAL bit32 saSATAAbort(
592*4e1bc9a0SAchim Leubner agsaRoot_t *agRoot,
593*4e1bc9a0SAchim Leubner agsaIORequest_t *agIORequest,
594*4e1bc9a0SAchim Leubner bit32 queueNum,
595*4e1bc9a0SAchim Leubner agsaDevHandle_t *agDevHandle,
596*4e1bc9a0SAchim Leubner bit32 flag,
597*4e1bc9a0SAchim Leubner void *abortParam,
598*4e1bc9a0SAchim Leubner ossaGenericAbortCB_t agCB
599*4e1bc9a0SAchim Leubner )
600*4e1bc9a0SAchim Leubner {
601*4e1bc9a0SAchim Leubner bit32 ret = AGSA_RC_SUCCESS, retVal;
602*4e1bc9a0SAchim Leubner agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
603*4e1bc9a0SAchim Leubner agsaIORequestDesc_t *pRequest;
604*4e1bc9a0SAchim Leubner agsaIORequestDesc_t *pRequestABT = agNULL;
605*4e1bc9a0SAchim Leubner agsaDeviceDesc_t *pDevice = agNULL;
606*4e1bc9a0SAchim Leubner agsaDeviceDesc_t *pDeviceABT = NULL;
607*4e1bc9a0SAchim Leubner agsaPort_t *pPort = agNULL;
608*4e1bc9a0SAchim Leubner mpiICQueue_t *circularQ;
609*4e1bc9a0SAchim Leubner void *pMessage;
610*4e1bc9a0SAchim Leubner agsaSATAAbortCmd_t *payload;
611*4e1bc9a0SAchim Leubner agsaIORequest_t *agIOToBeAborted;
612*4e1bc9a0SAchim Leubner bit8 inq, outq;
613*4e1bc9a0SAchim Leubner bit32 flag_copy = flag;
614*4e1bc9a0SAchim Leubner
615*4e1bc9a0SAchim Leubner
616*4e1bc9a0SAchim Leubner smTraceFuncEnter(hpDBG_VERY_LOUD,"8b");
617*4e1bc9a0SAchim Leubner
618*4e1bc9a0SAchim Leubner /* sanity check */
619*4e1bc9a0SAchim Leubner SA_ASSERT((agNULL != agRoot), "");
620*4e1bc9a0SAchim Leubner SA_ASSERT((agNULL != agIORequest), "");
621*4e1bc9a0SAchim Leubner
622*4e1bc9a0SAchim Leubner SA_DBG3(("saSATAAbort: Aborting request %p ITtoBeAborted %p\n", agIORequest, abortParam));
623*4e1bc9a0SAchim Leubner
624*4e1bc9a0SAchim Leubner /* Assign inbound and outbound Ring Buffer */
625*4e1bc9a0SAchim Leubner inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
626*4e1bc9a0SAchim Leubner outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
627*4e1bc9a0SAchim Leubner SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
628*4e1bc9a0SAchim Leubner
629*4e1bc9a0SAchim Leubner if( ABORT_SINGLE == (flag & ABORT_MASK) )
630*4e1bc9a0SAchim Leubner {
631*4e1bc9a0SAchim Leubner agIOToBeAborted = (agsaIORequest_t *)abortParam;
632*4e1bc9a0SAchim Leubner /* Get LL IORequest entry for saSATAAbort() */
633*4e1bc9a0SAchim Leubner pRequest = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData);
634*4e1bc9a0SAchim Leubner if (agNULL == pRequest)
635*4e1bc9a0SAchim Leubner {
636*4e1bc9a0SAchim Leubner /* no pRequest found - can not Abort */
637*4e1bc9a0SAchim Leubner SA_DBG1(("saSATAAbort: pRequest AGSA_RC_FAILURE\n"));
638*4e1bc9a0SAchim Leubner smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "8b");
639*4e1bc9a0SAchim Leubner return AGSA_RC_FAILURE;
640*4e1bc9a0SAchim Leubner }
641*4e1bc9a0SAchim Leubner /* Find the device the request sent to */
642*4e1bc9a0SAchim Leubner pDevice = pRequest->pDevice;
643*4e1bc9a0SAchim Leubner /* Get LL IORequest entry */
644*4e1bc9a0SAchim Leubner pRequestABT = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData);
645*4e1bc9a0SAchim Leubner /* Find the device the request sent to */
646*4e1bc9a0SAchim Leubner if (agNULL == pRequestABT)
647*4e1bc9a0SAchim Leubner {
648*4e1bc9a0SAchim Leubner /* no pRequestABT - can not find pDeviceABT */
649*4e1bc9a0SAchim Leubner SA_DBG1(("saSATAAbort: pRequestABT AGSA_RC_FAILURE\n"));
650*4e1bc9a0SAchim Leubner smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "8b");
651*4e1bc9a0SAchim Leubner return AGSA_RC_FAILURE;
652*4e1bc9a0SAchim Leubner }
653*4e1bc9a0SAchim Leubner pDeviceABT = pRequestABT->pDevice;
654*4e1bc9a0SAchim Leubner
655*4e1bc9a0SAchim Leubner if (agNULL == pDeviceABT)
656*4e1bc9a0SAchim Leubner {
657*4e1bc9a0SAchim Leubner /* no deviceID - can not build IOMB */
658*4e1bc9a0SAchim Leubner SA_DBG1(("saSATAAbort: pDeviceABT AGSA_RC_FAILURE\n"));
659*4e1bc9a0SAchim Leubner
660*4e1bc9a0SAchim Leubner smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "8b");
661*4e1bc9a0SAchim Leubner return AGSA_RC_FAILURE;
662*4e1bc9a0SAchim Leubner }
663*4e1bc9a0SAchim Leubner
664*4e1bc9a0SAchim Leubner if (agNULL != pDevice)
665*4e1bc9a0SAchim Leubner {
666*4e1bc9a0SAchim Leubner /* Find the port the request was sent to */
667*4e1bc9a0SAchim Leubner pPort = pDevice->pPort;
668*4e1bc9a0SAchim Leubner }
669*4e1bc9a0SAchim Leubner
670*4e1bc9a0SAchim Leubner /* Get request from free IORequests */
671*4e1bc9a0SAchim Leubner ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
672*4e1bc9a0SAchim Leubner pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
673*4e1bc9a0SAchim Leubner }
674*4e1bc9a0SAchim Leubner else
675*4e1bc9a0SAchim Leubner {
676*4e1bc9a0SAchim Leubner if (ABORT_ALL == (flag & ABORT_MASK))
677*4e1bc9a0SAchim Leubner {
678*4e1bc9a0SAchim Leubner /* abort all */
679*4e1bc9a0SAchim Leubner /* Find the outgoing port for the device */
680*4e1bc9a0SAchim Leubner pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
681*4e1bc9a0SAchim Leubner pPort = pDevice->pPort;
682*4e1bc9a0SAchim Leubner ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
683*4e1bc9a0SAchim Leubner pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
684*4e1bc9a0SAchim Leubner }
685*4e1bc9a0SAchim Leubner else
686*4e1bc9a0SAchim Leubner {
687*4e1bc9a0SAchim Leubner /* only support 00 and 01 for flag */
688*4e1bc9a0SAchim Leubner SA_DBG1(("saSATAAbort: flag AGSA_RC_FAILURE\n"));
689*4e1bc9a0SAchim Leubner smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "8b");
690*4e1bc9a0SAchim Leubner return AGSA_RC_FAILURE;
691*4e1bc9a0SAchim Leubner }
692*4e1bc9a0SAchim Leubner }
693*4e1bc9a0SAchim Leubner
694*4e1bc9a0SAchim Leubner /* If no LL IO request entry avalable */
695*4e1bc9a0SAchim Leubner if ( agNULL == pRequest )
696*4e1bc9a0SAchim Leubner {
697*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
698*4e1bc9a0SAchim Leubner SA_DBG1(("saSATAAbort, No request from free list\n" ));
699*4e1bc9a0SAchim Leubner smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "8b");
700*4e1bc9a0SAchim Leubner return AGSA_RC_BUSY;
701*4e1bc9a0SAchim Leubner }
702*4e1bc9a0SAchim Leubner
703*4e1bc9a0SAchim Leubner /* If free IOMB avaliable */
704*4e1bc9a0SAchim Leubner /* Remove the request from free list */
705*4e1bc9a0SAchim Leubner saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
706*4e1bc9a0SAchim Leubner
707*4e1bc9a0SAchim Leubner SA_ASSERT((!pRequest->valid), "The pRequest is in use");
708*4e1bc9a0SAchim Leubner /* Add the request to the pendingIORequests list of the device */
709*4e1bc9a0SAchim Leubner pRequest->valid = agTRUE;
710*4e1bc9a0SAchim Leubner saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode));
711*4e1bc9a0SAchim Leubner /* set up pRequest */
712*4e1bc9a0SAchim Leubner
713*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
714*4e1bc9a0SAchim Leubner
715*4e1bc9a0SAchim Leubner pRequest->pIORequestContext = agIORequest;
716*4e1bc9a0SAchim Leubner pRequest->requestType = AGSA_SATA_REQTYPE;
717*4e1bc9a0SAchim Leubner pRequest->pDevice = pDevice;
718*4e1bc9a0SAchim Leubner pRequest->pPort = pPort;
719*4e1bc9a0SAchim Leubner pRequest->completionCB = (void*)agCB;
720*4e1bc9a0SAchim Leubner /* pRequest->abortCompletionCB = agCB; */
721*4e1bc9a0SAchim Leubner pRequest->startTick = saRoot->timeTick;
722*4e1bc9a0SAchim Leubner
723*4e1bc9a0SAchim Leubner /* Set request to the sdkData of agIORequest */
724*4e1bc9a0SAchim Leubner agIORequest->sdkData = pRequest;
725*4e1bc9a0SAchim Leubner
726*4e1bc9a0SAchim Leubner /* save tag and IOrequest pointer to IOMap */
727*4e1bc9a0SAchim Leubner saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
728*4e1bc9a0SAchim Leubner saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
729*4e1bc9a0SAchim Leubner
730*4e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
731*4e1bc9a0SAchim Leubner ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
732*4e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
733*4e1bc9a0SAchim Leubner
734*4e1bc9a0SAchim Leubner /* If LL IO request entry avaliable */
735*4e1bc9a0SAchim Leubner /* Get a free inbound queue entry */
736*4e1bc9a0SAchim Leubner circularQ = &saRoot->inboundQueue[inq];
737*4e1bc9a0SAchim Leubner retVal = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage);
738*4e1bc9a0SAchim Leubner
739*4e1bc9a0SAchim Leubner /* if message size is too large return failure */
740*4e1bc9a0SAchim Leubner if (AGSA_RC_FAILURE == retVal)
741*4e1bc9a0SAchim Leubner {
742*4e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
743*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
744*4e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
745*4e1bc9a0SAchim Leubner
746*4e1bc9a0SAchim Leubner ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
747*4e1bc9a0SAchim Leubner saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
748*4e1bc9a0SAchim Leubner pRequest->valid = agFALSE;
749*4e1bc9a0SAchim Leubner saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
750*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
751*4e1bc9a0SAchim Leubner
752*4e1bc9a0SAchim Leubner SA_DBG1(("saSATAAbort, error when get free IOMB\n"));
753*4e1bc9a0SAchim Leubner smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "8b");
754*4e1bc9a0SAchim Leubner return AGSA_RC_FAILURE;
755*4e1bc9a0SAchim Leubner }
756*4e1bc9a0SAchim Leubner
757*4e1bc9a0SAchim Leubner /* return busy if inbound queue is full */
758*4e1bc9a0SAchim Leubner if (AGSA_RC_BUSY == retVal)
759*4e1bc9a0SAchim Leubner {
760*4e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
761*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
762*4e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
763*4e1bc9a0SAchim Leubner
764*4e1bc9a0SAchim Leubner ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
765*4e1bc9a0SAchim Leubner saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
766*4e1bc9a0SAchim Leubner pRequest->valid = agFALSE;
767*4e1bc9a0SAchim Leubner saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
768*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
769*4e1bc9a0SAchim Leubner
770*4e1bc9a0SAchim Leubner SA_DBG1(("saSATASAbort, no more IOMB\n"));
771*4e1bc9a0SAchim Leubner smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "8b");
772*4e1bc9a0SAchim Leubner return AGSA_RC_BUSY;
773*4e1bc9a0SAchim Leubner }
774*4e1bc9a0SAchim Leubner
775*4e1bc9a0SAchim Leubner
776*4e1bc9a0SAchim Leubner /* setup payload */
777*4e1bc9a0SAchim Leubner payload = (agsaSATAAbortCmd_t*)pMessage;
778*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, tag), pRequest->HTag);
779*4e1bc9a0SAchim Leubner
780*4e1bc9a0SAchim Leubner if( ABORT_SINGLE == (flag & ABORT_MASK) )
781*4e1bc9a0SAchim Leubner {
782*4e1bc9a0SAchim Leubner /* If no device */
783*4e1bc9a0SAchim Leubner if ( agNULL == pDeviceABT )
784*4e1bc9a0SAchim Leubner {
785*4e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
786*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
787*4e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
788*4e1bc9a0SAchim Leubner
789*4e1bc9a0SAchim Leubner ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
790*4e1bc9a0SAchim Leubner saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
791*4e1bc9a0SAchim Leubner pRequest->valid = agFALSE;
792*4e1bc9a0SAchim Leubner saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
793*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
794*4e1bc9a0SAchim Leubner
795*4e1bc9a0SAchim Leubner SA_DBG1(("saSATAAbort,no device\n" ));
796*4e1bc9a0SAchim Leubner smTraceFuncExit(hpDBG_VERY_LOUD, 'h', "8b");
797*4e1bc9a0SAchim Leubner return AGSA_RC_FAILURE;
798*4e1bc9a0SAchim Leubner }
799*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, deviceId), pDeviceABT->DeviceMapIndex);
800*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, HTagAbort), pRequestABT->HTag);
801*4e1bc9a0SAchim Leubner }
802*4e1bc9a0SAchim Leubner else
803*4e1bc9a0SAchim Leubner {
804*4e1bc9a0SAchim Leubner /* abort all */
805*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, deviceId), pDevice->DeviceMapIndex);
806*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, HTagAbort), 0);
807*4e1bc9a0SAchim Leubner }
808*4e1bc9a0SAchim Leubner
809*4e1bc9a0SAchim Leubner if(flag & ABORT_TSDK_QUARANTINE)
810*4e1bc9a0SAchim Leubner {
811*4e1bc9a0SAchim Leubner if(smIS_SPCV(agRoot))
812*4e1bc9a0SAchim Leubner {
813*4e1bc9a0SAchim Leubner flag_copy &= ABORT_SCOPE;
814*4e1bc9a0SAchim Leubner flag_copy |= ABORT_QUARANTINE_SPCV;
815*4e1bc9a0SAchim Leubner }
816*4e1bc9a0SAchim Leubner }
817*4e1bc9a0SAchim Leubner OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSATAAbortCmd_t, abortAll), flag_copy);
818*4e1bc9a0SAchim Leubner
819*4e1bc9a0SAchim Leubner
820*4e1bc9a0SAchim Leubner
821*4e1bc9a0SAchim Leubner SA_DBG1(("saSATAAbort, HTag 0x%x HTagABT 0x%x deviceId 0x%x\n", payload->tag, payload->HTagAbort, payload->deviceId));
822*4e1bc9a0SAchim Leubner
823*4e1bc9a0SAchim Leubner /* post the IOMB to SPC */
824*4e1bc9a0SAchim Leubner ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SATA_ABORT, outq, (bit8)circularQ->priority);
825*4e1bc9a0SAchim Leubner
826*4e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
827*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
828*4e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
829*4e1bc9a0SAchim Leubner
830*4e1bc9a0SAchim Leubner #ifdef SALL_API_TEST
831*4e1bc9a0SAchim Leubner if (AGSA_RC_FAILURE != ret)
832*4e1bc9a0SAchim Leubner {
833*4e1bc9a0SAchim Leubner saRoot->LLCounters.IOCounter.numSataAborted++;
834*4e1bc9a0SAchim Leubner }
835*4e1bc9a0SAchim Leubner #endif
836*4e1bc9a0SAchim Leubner
837*4e1bc9a0SAchim Leubner siCountActiveIORequestsOnDevice( agRoot, payload->deviceId );
838*4e1bc9a0SAchim Leubner
839*4e1bc9a0SAchim Leubner smTraceFuncExit(hpDBG_VERY_LOUD, 'i', "8b");
840*4e1bc9a0SAchim Leubner
841*4e1bc9a0SAchim Leubner return ret;
842*4e1bc9a0SAchim Leubner }
843*4e1bc9a0SAchim Leubner
844*4e1bc9a0SAchim Leubner /******************************************************************************/
845*4e1bc9a0SAchim Leubner /*! \brief Routine to handle for received SATA with data payload event
846*4e1bc9a0SAchim Leubner *
847*4e1bc9a0SAchim Leubner * The handle for received SATA with data payload event
848*4e1bc9a0SAchim Leubner *
849*4e1bc9a0SAchim Leubner * \param agRoot handles for this instance of SAS/SATA hardware
850*4e1bc9a0SAchim Leubner * \param pRequest the IO request descriptor
851*4e1bc9a0SAchim Leubner * \param agFirstDword pointer to the first Dword
852*4e1bc9a0SAchim Leubner * \param pResp pointer to the rest of SATA response
853*4e1bc9a0SAchim Leubner * \param lengthResp total length of SATA Response frame
854*4e1bc9a0SAchim Leubner *
855*4e1bc9a0SAchim Leubner * \return -void-
856*4e1bc9a0SAchim Leubner */
857*4e1bc9a0SAchim Leubner /*******************************************************************************/
siEventSATAResponseWtDataRcvd(agsaRoot_t * agRoot,agsaIORequestDesc_t * pRequest,bit32 * agFirstDword,bit32 * pResp,bit32 lengthResp)858*4e1bc9a0SAchim Leubner GLOBAL void siEventSATAResponseWtDataRcvd(
859*4e1bc9a0SAchim Leubner agsaRoot_t *agRoot,
860*4e1bc9a0SAchim Leubner agsaIORequestDesc_t *pRequest,
861*4e1bc9a0SAchim Leubner bit32 *agFirstDword,
862*4e1bc9a0SAchim Leubner bit32 *pResp,
863*4e1bc9a0SAchim Leubner bit32 lengthResp
864*4e1bc9a0SAchim Leubner )
865*4e1bc9a0SAchim Leubner {
866*4e1bc9a0SAchim Leubner agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
867*4e1bc9a0SAchim Leubner agsaDeviceDesc_t *pDevice;
868*4e1bc9a0SAchim Leubner #if defined(SALLSDK_DEBUG)
869*4e1bc9a0SAchim Leubner agsaFrameHandle_t frameHandle;
870*4e1bc9a0SAchim Leubner /* get frame handle */
871*4e1bc9a0SAchim Leubner frameHandle = (agsaFrameHandle_t)(pResp);
872*4e1bc9a0SAchim Leubner #endif /* SALLSDK_DEBUG */
873*4e1bc9a0SAchim Leubner
874*4e1bc9a0SAchim Leubner smTraceFuncEnter(hpDBG_VERY_LOUD,"8c");
875*4e1bc9a0SAchim Leubner
876*4e1bc9a0SAchim Leubner /* If the request is still valid */
877*4e1bc9a0SAchim Leubner if ( agTRUE == pRequest->valid )
878*4e1bc9a0SAchim Leubner {
879*4e1bc9a0SAchim Leubner /* get device */
880*4e1bc9a0SAchim Leubner pDevice = pRequest->pDevice;
881*4e1bc9a0SAchim Leubner ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
882*4e1bc9a0SAchim Leubner
883*4e1bc9a0SAchim Leubner /* Delete the request from the pendingIORequests */
884*4e1bc9a0SAchim Leubner saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
885*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
886*4e1bc9a0SAchim Leubner
887*4e1bc9a0SAchim Leubner (*(ossaSATACompletedCB_t)(pRequest->completionCB))(agRoot,
888*4e1bc9a0SAchim Leubner pRequest->pIORequestContext,
889*4e1bc9a0SAchim Leubner OSSA_IO_SUCCESS,
890*4e1bc9a0SAchim Leubner agFirstDword,
891*4e1bc9a0SAchim Leubner lengthResp,
892*4e1bc9a0SAchim Leubner (void *)pResp);
893*4e1bc9a0SAchim Leubner
894*4e1bc9a0SAchim Leubner ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
895*4e1bc9a0SAchim Leubner pRequest->valid = agFALSE;
896*4e1bc9a0SAchim Leubner /* return the request to free pool */
897*4e1bc9a0SAchim Leubner saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
898*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
899*4e1bc9a0SAchim Leubner }
900*4e1bc9a0SAchim Leubner
901*4e1bc9a0SAchim Leubner smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "8c");
902*4e1bc9a0SAchim Leubner
903*4e1bc9a0SAchim Leubner return;
904*4e1bc9a0SAchim Leubner }
905*4e1bc9a0SAchim Leubner
906*4e1bc9a0SAchim Leubner /******************************************************************************/
907*4e1bc9a0SAchim Leubner /*! \brief copy a SATA signature to another
908*4e1bc9a0SAchim Leubner *
909*4e1bc9a0SAchim Leubner * copy a SATA signature to another
910*4e1bc9a0SAchim Leubner *
911*4e1bc9a0SAchim Leubner * \param pDstSignature pointer to the destination signature
912*4e1bc9a0SAchim Leubner * \param pSrcSignature pointer to the source signature
913*4e1bc9a0SAchim Leubner *
914*4e1bc9a0SAchim Leubner * \return If they match
915*4e1bc9a0SAchim Leubner * - \e agTRUE match
916*4e1bc9a0SAchim Leubner * - \e agFALSE doesn't match
917*4e1bc9a0SAchim Leubner */
918*4e1bc9a0SAchim Leubner /*******************************************************************************/
siSATASignatureCpy(bit8 * pDstSignature,bit8 * pSrcSignature)919*4e1bc9a0SAchim Leubner GLOBAL void siSATASignatureCpy(
920*4e1bc9a0SAchim Leubner bit8 *pDstSignature,
921*4e1bc9a0SAchim Leubner bit8 *pSrcSignature
922*4e1bc9a0SAchim Leubner )
923*4e1bc9a0SAchim Leubner {
924*4e1bc9a0SAchim Leubner bit32 i;
925*4e1bc9a0SAchim Leubner
926*4e1bc9a0SAchim Leubner for ( i = 0; i < 5; i ++ )
927*4e1bc9a0SAchim Leubner {
928*4e1bc9a0SAchim Leubner pDstSignature[i] = pSrcSignature[i];
929*4e1bc9a0SAchim Leubner }
930*4e1bc9a0SAchim Leubner
931*4e1bc9a0SAchim Leubner return;
932*4e1bc9a0SAchim Leubner }
933*4e1bc9a0SAchim Leubner
934*4e1bc9a0SAchim Leubner
935*4e1bc9a0SAchim Leubner
936