xref: /freebsd/sys/dev/pms/RefTisa/sallsdk/spc/sassp.c (revision 685dc743dc3b5645e34836464128e1c0558b404b)
1*4e1bc9a0SAchim Leubner /*******************************************************************************
2*4e1bc9a0SAchim Leubner **
3*4e1bc9a0SAchim Leubner *Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved.
4*4e1bc9a0SAchim Leubner *
5*4e1bc9a0SAchim Leubner *Redistribution and use in source and binary forms, with or without modification, are permitted provided
6*4e1bc9a0SAchim Leubner *that the following conditions are met:
7*4e1bc9a0SAchim Leubner *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
8*4e1bc9a0SAchim Leubner *following disclaimer.
9*4e1bc9a0SAchim Leubner *2. Redistributions in binary form must reproduce the above copyright notice,
10*4e1bc9a0SAchim Leubner *this list of conditions and the following disclaimer in the documentation and/or other materials provided
11*4e1bc9a0SAchim Leubner *with the distribution.
12*4e1bc9a0SAchim Leubner *
13*4e1bc9a0SAchim Leubner *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
14*4e1bc9a0SAchim Leubner *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
15*4e1bc9a0SAchim Leubner *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16*4e1bc9a0SAchim Leubner *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
17*4e1bc9a0SAchim Leubner *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
18*4e1bc9a0SAchim Leubner *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
19*4e1bc9a0SAchim Leubner *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
20*4e1bc9a0SAchim Leubner *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
21*4e1bc9a0SAchim Leubner 
22*4e1bc9a0SAchim Leubner ********************************************************************************/
23*4e1bc9a0SAchim Leubner /*******************************************************************************/
24*4e1bc9a0SAchim Leubner /*! \file sassp.c
25*4e1bc9a0SAchim Leubner  *  \brief The file implements the functions for SSP request/response
26*4e1bc9a0SAchim Leubner  *
27*4e1bc9a0SAchim Leubner  */
28*4e1bc9a0SAchim Leubner /*******************************************************************************/
29*4e1bc9a0SAchim Leubner #include <sys/cdefs.h>
30*4e1bc9a0SAchim Leubner #include <dev/pms/config.h>
31*4e1bc9a0SAchim Leubner 
32*4e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/sallsdk/spc/saglobal.h>
33*4e1bc9a0SAchim Leubner #ifdef SA_ENABLE_TRACE_FUNCTIONS
34*4e1bc9a0SAchim Leubner #ifdef siTraceFileID
35*4e1bc9a0SAchim Leubner #undef siTraceFileID
36*4e1bc9a0SAchim Leubner #endif
37*4e1bc9a0SAchim Leubner #define siTraceFileID 'O'
38*4e1bc9a0SAchim Leubner #endif
39*4e1bc9a0SAchim Leubner 
40*4e1bc9a0SAchim Leubner #ifdef LOOPBACK_MPI
41*4e1bc9a0SAchim Leubner extern int loopback;
42*4e1bc9a0SAchim Leubner #endif
43*4e1bc9a0SAchim Leubner 
44*4e1bc9a0SAchim Leubner #ifdef SALLSDK_DEBUG
45*4e1bc9a0SAchim Leubner LOCAL void siDumpSSPStartIu(
46*4e1bc9a0SAchim Leubner   agsaDevHandle_t       *agDevHandle,
47*4e1bc9a0SAchim Leubner   bit32                 agRequestType,
48*4e1bc9a0SAchim Leubner   agsaSASRequestBody_t  *agRequestBody
49*4e1bc9a0SAchim Leubner   );
50*4e1bc9a0SAchim Leubner #endif
51*4e1bc9a0SAchim Leubner 
52*4e1bc9a0SAchim Leubner #ifdef FAST_IO_TEST
saGetIBQPI(agsaRoot_t * agRoot,bit32 queueNum)53*4e1bc9a0SAchim Leubner LOCAL bit32 saGetIBQPI(agsaRoot_t *agRoot,
54*4e1bc9a0SAchim Leubner                        bit32 queueNum)
55*4e1bc9a0SAchim Leubner {
56*4e1bc9a0SAchim Leubner   bit8         inq;
57*4e1bc9a0SAchim Leubner   mpiICQueue_t *circularQ;
58*4e1bc9a0SAchim Leubner   agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
59*4e1bc9a0SAchim Leubner 
60*4e1bc9a0SAchim Leubner   inq = INQ(queueNum);
61*4e1bc9a0SAchim Leubner   circularQ = &saRoot->inboundQueue[inq];
62*4e1bc9a0SAchim Leubner   return circularQ->producerIdx;
63*4e1bc9a0SAchim Leubner }
64*4e1bc9a0SAchim Leubner 
saSetIBQPI(agsaRoot_t * agRoot,bit32 queueNum,bit32 pi)65*4e1bc9a0SAchim Leubner LOCAL void saSetIBQPI(agsaRoot_t *agRoot,
66*4e1bc9a0SAchim Leubner                       bit32      queueNum,
67*4e1bc9a0SAchim Leubner                       bit32      pi)
68*4e1bc9a0SAchim Leubner {
69*4e1bc9a0SAchim Leubner   bit8         inq;
70*4e1bc9a0SAchim Leubner   mpiICQueue_t *circularQ;
71*4e1bc9a0SAchim Leubner   agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
72*4e1bc9a0SAchim Leubner 
73*4e1bc9a0SAchim Leubner   inq = INQ(queueNum);
74*4e1bc9a0SAchim Leubner   circularQ = &saRoot->inboundQueue[inq];
75*4e1bc9a0SAchim Leubner   circularQ->producerIdx = pi;
76*4e1bc9a0SAchim Leubner }
77*4e1bc9a0SAchim Leubner 
78*4e1bc9a0SAchim Leubner osLOCAL void*
siFastSSPReqAlloc(agsaRoot_t * agRoot)79*4e1bc9a0SAchim Leubner siFastSSPReqAlloc(agsaRoot_t *agRoot)
80*4e1bc9a0SAchim Leubner {
81*4e1bc9a0SAchim Leubner   int             idx;
82*4e1bc9a0SAchim Leubner   agsaLLRoot_t    *saRoot = (agsaLLRoot_t*)(agRoot->sdkData);
83*4e1bc9a0SAchim Leubner   saFastRequest_t *fr;
84*4e1bc9a0SAchim Leubner 
85*4e1bc9a0SAchim Leubner   if (!saRoot->freeFastIdx)
86*4e1bc9a0SAchim Leubner   {
87*4e1bc9a0SAchim Leubner     SA_DBG1(("saSuperSSPReqAlloc: no memory ERROR\n"));
88*4e1bc9a0SAchim Leubner     SA_ASSERT((0), "");
89*4e1bc9a0SAchim Leubner     return 0;
90*4e1bc9a0SAchim Leubner   }
91*4e1bc9a0SAchim Leubner 
92*4e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_FAST_IO_LOCK);
93*4e1bc9a0SAchim Leubner   saRoot->freeFastIdx--;
94*4e1bc9a0SAchim Leubner   idx = saRoot->freeFastIdx;
95*4e1bc9a0SAchim Leubner   ossaSingleThreadedLeave(agRoot, LL_FAST_IO_LOCK);
96*4e1bc9a0SAchim Leubner 
97*4e1bc9a0SAchim Leubner   fr = saRoot->freeFastReq[idx];
98*4e1bc9a0SAchim Leubner   SA_ASSERT((fr), "");
99*4e1bc9a0SAchim Leubner   fr->valid = 1;
100*4e1bc9a0SAchim Leubner 
101*4e1bc9a0SAchim Leubner   return fr;
102*4e1bc9a0SAchim Leubner }
103*4e1bc9a0SAchim Leubner 
104*4e1bc9a0SAchim Leubner LOCAL void
siFastSSPReqFree(agsaRoot_t * agRoot,void * freq)105*4e1bc9a0SAchim Leubner siFastSSPReqFree(
106*4e1bc9a0SAchim Leubner              agsaRoot_t *agRoot,
107*4e1bc9a0SAchim Leubner              void       *freq)
108*4e1bc9a0SAchim Leubner {
109*4e1bc9a0SAchim Leubner   agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
110*4e1bc9a0SAchim Leubner   saFastRequest_t *fr = (saFastRequest_t*)freq;
111*4e1bc9a0SAchim Leubner 
112*4e1bc9a0SAchim Leubner   SA_DBG2(("siFastSSPReqFree: enter\n"));
113*4e1bc9a0SAchim Leubner   SA_ASSERT((fr->valid), "");
114*4e1bc9a0SAchim Leubner   if (saRoot->freeFastIdx >= sizeof(saRoot->freeFastReq) /
115*4e1bc9a0SAchim Leubner                              sizeof(saRoot->freeFastReq[0]))
116*4e1bc9a0SAchim Leubner   {
117*4e1bc9a0SAchim Leubner     SA_DBG1(("siFastSSPReqFree: too many handles %d / %d ERROR\n",
118*4e1bc9a0SAchim Leubner              saRoot->freeFastIdx, (int)(sizeof(saRoot->freeFastReq) /
119*4e1bc9a0SAchim Leubner              sizeof(saRoot->freeFastReq[0]))));
120*4e1bc9a0SAchim Leubner     SA_ASSERT((0), "");
121*4e1bc9a0SAchim Leubner     return;
122*4e1bc9a0SAchim Leubner   }
123*4e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_FAST_IO_LOCK);
124*4e1bc9a0SAchim Leubner   /* not need if only one entry */
125*4e1bc9a0SAchim Leubner   /* saRoot->freeFastReq[saRoot->freeFastIdx] = freq;  */
126*4e1bc9a0SAchim Leubner   saRoot->freeFastIdx++;
127*4e1bc9a0SAchim Leubner   ossaSingleThreadedLeave(agRoot, LL_FAST_IO_LOCK);
128*4e1bc9a0SAchim Leubner 
129*4e1bc9a0SAchim Leubner   fr->valid = 0;
130*4e1bc9a0SAchim Leubner   SA_DBG6(("siFastSSPReqFree: leave\n"));
131*4e1bc9a0SAchim Leubner }
132*4e1bc9a0SAchim Leubner 
siFastSSPResAlloc(agsaRoot_t * agRoot,bit32 queueNum,bit32 agRequestType,agsaDeviceDesc_t * pDevice,agsaIORequestDesc_t ** pRequest,void ** pPayload)133*4e1bc9a0SAchim Leubner LOCAL bit32 siFastSSPResAlloc(
134*4e1bc9a0SAchim Leubner   agsaRoot_t             *agRoot,
135*4e1bc9a0SAchim Leubner   bit32                  queueNum,
136*4e1bc9a0SAchim Leubner   bit32                  agRequestType,
137*4e1bc9a0SAchim Leubner   agsaDeviceDesc_t       *pDevice,
138*4e1bc9a0SAchim Leubner   agsaIORequestDesc_t    **pRequest,
139*4e1bc9a0SAchim Leubner   void                   **pPayload
140*4e1bc9a0SAchim Leubner   )
141*4e1bc9a0SAchim Leubner {
142*4e1bc9a0SAchim Leubner   agsaLLRoot_t *saRoot = (agsaLLRoot_t*)(agRoot->sdkData);
143*4e1bc9a0SAchim Leubner   mpiICQueue_t *circularQ;
144*4e1bc9a0SAchim Leubner   bit8  inq;
145*4e1bc9a0SAchim Leubner   bit16 size = IOMB_SIZE64;
146*4e1bc9a0SAchim Leubner   bit32 ret = AGSA_RC_SUCCESS, retVal;
147*4e1bc9a0SAchim Leubner 
148*4e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"2D");
149*4e1bc9a0SAchim Leubner 
150*4e1bc9a0SAchim Leubner   SA_DBG4(("Entering function siFastSSPResAlloc:\n"));
151*4e1bc9a0SAchim Leubner 
152*4e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
153*4e1bc9a0SAchim Leubner   *pRequest = (agsaIORequestDesc_t*)saLlistIOGetHead(&saRoot->freeIORequests);
154*4e1bc9a0SAchim Leubner 
155*4e1bc9a0SAchim Leubner   /* If no LL IO request entry available */
156*4e1bc9a0SAchim Leubner   if (agNULL == *pRequest )
157*4e1bc9a0SAchim Leubner   {
158*4e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
159*4e1bc9a0SAchim Leubner     SA_DBG1(("siFastSSPResAlloc: No request from free list\n" ));
160*4e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2D");
161*4e1bc9a0SAchim Leubner     ret = AGSA_RC_BUSY;
162*4e1bc9a0SAchim Leubner     goto ext;
163*4e1bc9a0SAchim Leubner   }
164*4e1bc9a0SAchim Leubner 
165*4e1bc9a0SAchim Leubner   /* Get IO request from free IORequests */
166*4e1bc9a0SAchim Leubner   /* Assign inbound and outbound Buffer */
167*4e1bc9a0SAchim Leubner   inq = INQ(queueNum);
168*4e1bc9a0SAchim Leubner   SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
169*4e1bc9a0SAchim Leubner 
170*4e1bc9a0SAchim Leubner   /* SSP_INI_IO_START_EXT IOMB need at least 80 bytes to support 32 CDB */
171*4e1bc9a0SAchim Leubner   if (agRequestType & AGSA_SSP_EXT_BIT)
172*4e1bc9a0SAchim Leubner   {
173*4e1bc9a0SAchim Leubner     size = IOMB_SIZE96;
174*4e1bc9a0SAchim Leubner   }
175*4e1bc9a0SAchim Leubner   /* If LL IO request entry avaliable */
176*4e1bc9a0SAchim Leubner   /* Get a free inbound queue entry */
177*4e1bc9a0SAchim Leubner   circularQ = &saRoot->inboundQueue[inq];
178*4e1bc9a0SAchim Leubner   retVal = mpiMsgFreeGet(circularQ, size, pPayload);
179*4e1bc9a0SAchim Leubner 
180*4e1bc9a0SAchim Leubner   /* if message size is too large return failure */
181*4e1bc9a0SAchim Leubner   if (AGSA_RC_SUCCESS != retVal)
182*4e1bc9a0SAchim Leubner   {
183*4e1bc9a0SAchim Leubner     if (AGSA_RC_FAILURE == retVal)
184*4e1bc9a0SAchim Leubner     {
185*4e1bc9a0SAchim Leubner       SA_DBG1(("siFastSSPResAlloc: error when get free IOMB\n"));
186*4e1bc9a0SAchim Leubner       smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2D");
187*4e1bc9a0SAchim Leubner     }
188*4e1bc9a0SAchim Leubner 
189*4e1bc9a0SAchim Leubner     /* return busy if inbound queue is full */
190*4e1bc9a0SAchim Leubner     if (AGSA_RC_BUSY == retVal)
191*4e1bc9a0SAchim Leubner     {
192*4e1bc9a0SAchim Leubner       SA_DBG3(("siFastSSPResAlloc: no more IOMB\n"));
193*4e1bc9a0SAchim Leubner       smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2D");
194*4e1bc9a0SAchim Leubner     }
195*4e1bc9a0SAchim Leubner     ret = retVal;
196*4e1bc9a0SAchim Leubner     goto ext;
197*4e1bc9a0SAchim Leubner   }
198*4e1bc9a0SAchim Leubner 
199*4e1bc9a0SAchim Leubner   /* But add it to the pending queue during FastStart */
200*4e1bc9a0SAchim Leubner   /* If free IOMB avaliable */
201*4e1bc9a0SAchim Leubner   /* Remove the request from free list */
202*4e1bc9a0SAchim Leubner   saLlistIORemove(&saRoot->freeIORequests, &(*pRequest)->linkNode);
203*4e1bc9a0SAchim Leubner 
204*4e1bc9a0SAchim Leubner   /* Add the request to the pendingIORequests list of the device */
205*4e1bc9a0SAchim Leubner   saLlistIOAdd(&pDevice->pendingIORequests, &(*pRequest)->linkNode);
206*4e1bc9a0SAchim Leubner 
207*4e1bc9a0SAchim Leubner ext:
208*4e1bc9a0SAchim Leubner   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
209*4e1bc9a0SAchim Leubner 
210*4e1bc9a0SAchim Leubner   if (AGSA_RC_SUCCESS == ret)
211*4e1bc9a0SAchim Leubner   {
212*4e1bc9a0SAchim Leubner     /* save tag and IOrequest pointer to IOMap */
213*4e1bc9a0SAchim Leubner     saRoot->IOMap[(*pRequest)->HTag].Tag = (*pRequest)->HTag;
214*4e1bc9a0SAchim Leubner     saRoot->IOMap[(*pRequest)->HTag].IORequest = (void *)*pRequest;
215*4e1bc9a0SAchim Leubner   }
216*4e1bc9a0SAchim Leubner 
217*4e1bc9a0SAchim Leubner   return ret;
218*4e1bc9a0SAchim Leubner } /* siFastSSPResAlloc */
219*4e1bc9a0SAchim Leubner 
220*4e1bc9a0SAchim Leubner 
saFastSSPCancel(void * ioHandle)221*4e1bc9a0SAchim Leubner GLOBAL bit32 saFastSSPCancel(void *ioHandle)
222*4e1bc9a0SAchim Leubner {
223*4e1bc9a0SAchim Leubner   agsaRoot_t      *agRoot;
224*4e1bc9a0SAchim Leubner   agsaLLRoot_t    *saRoot;
225*4e1bc9a0SAchim Leubner   saFastRequest_t *fr;
226*4e1bc9a0SAchim Leubner   bit32            i;
227*4e1bc9a0SAchim Leubner   agsaIORequestDesc_t *ior;
228*4e1bc9a0SAchim Leubner 
229*4e1bc9a0SAchim Leubner   SA_ASSERT((ioHandle), "");
230*4e1bc9a0SAchim Leubner   fr = (saFastRequest_t*)ioHandle;
231*4e1bc9a0SAchim Leubner   SA_ASSERT((fr->valid), "");
232*4e1bc9a0SAchim Leubner   agRoot = (agsaRoot_t*)fr->agRoot;
233*4e1bc9a0SAchim Leubner   SA_ASSERT((agRoot), "");
234*4e1bc9a0SAchim Leubner   saRoot = (agsaLLRoot_t*)(agRoot->sdkData);
235*4e1bc9a0SAchim Leubner   SA_ASSERT((saRoot), "");
236*4e1bc9a0SAchim Leubner 
237*4e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"2E");
238*4e1bc9a0SAchim Leubner 
239*4e1bc9a0SAchim Leubner   /* rollback the previously set IBQ PI */
240*4e1bc9a0SAchim Leubner   for (i = 0; i < fr->inqMax - 1; i++)
241*4e1bc9a0SAchim Leubner     saSetIBQPI(agRoot, fr->inqList[i], fr->beforePI[fr->inqList[i]]);
242*4e1bc9a0SAchim Leubner 
243*4e1bc9a0SAchim Leubner   /* free all the previous Fast IO Requests */
244*4e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
245*4e1bc9a0SAchim Leubner   /* at least one entry, no need to check for NULL saLlistIOGetHead() */
246*4e1bc9a0SAchim Leubner   ior = (agsaIORequestDesc_t*)((char*)saLlistIOGetHead(&fr->requests) -
247*4e1bc9a0SAchim Leubner                               OSSA_OFFSET_OF(agsaIORequestDesc_t, fastLink));
248*4e1bc9a0SAchim Leubner   do
249*4e1bc9a0SAchim Leubner   {
250*4e1bc9a0SAchim Leubner     agsaDeviceDesc_t *pDevice;
251*4e1bc9a0SAchim Leubner     void             *tmp;
252*4e1bc9a0SAchim Leubner 
253*4e1bc9a0SAchim Leubner     pDevice = ior->pDevice;
254*4e1bc9a0SAchim Leubner     saLlistIORemove(&pDevice->pendingIORequests, &ior->linkNode);
255*4e1bc9a0SAchim Leubner     saLlistIOAdd(&saRoot->freeIORequests, &ior->linkNode);
256*4e1bc9a0SAchim Leubner 
257*4e1bc9a0SAchim Leubner     tmp = (void*)saLlistGetNext(&fr->requests, &ior->fastLink);
258*4e1bc9a0SAchim Leubner     if (!tmp)
259*4e1bc9a0SAchim Leubner     {
260*4e1bc9a0SAchim Leubner       break; /* end of list */
261*4e1bc9a0SAchim Leubner     }
262*4e1bc9a0SAchim Leubner     ior = (agsaIORequestDesc_t*)((char*)tmp -
263*4e1bc9a0SAchim Leubner                                  OSSA_OFFSET_OF(agsaIORequestDesc_t, fastLink));
264*4e1bc9a0SAchim Leubner   } while (1);
265*4e1bc9a0SAchim Leubner 
266*4e1bc9a0SAchim Leubner   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
267*4e1bc9a0SAchim Leubner 
268*4e1bc9a0SAchim Leubner   /* free the IBQ PI tracking struct */
269*4e1bc9a0SAchim Leubner   siFastSSPReqFree(agRoot, fr);
270*4e1bc9a0SAchim Leubner 
271*4e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2E");
272*4e1bc9a0SAchim Leubner   return AGSA_RC_SUCCESS;
273*4e1bc9a0SAchim Leubner } /* saFastSSPCancel */
274*4e1bc9a0SAchim Leubner 
saFastSSPPrepare(void * ioh,agsaFastCommand_t * fc,ossaSSPCompletedCB_t cb,void * cbArg)275*4e1bc9a0SAchim Leubner GLOBAL void *saFastSSPPrepare(
276*4e1bc9a0SAchim Leubner                  void                 *ioh,
277*4e1bc9a0SAchim Leubner                  agsaFastCommand_t    *fc,
278*4e1bc9a0SAchim Leubner                  ossaSSPCompletedCB_t cb,
279*4e1bc9a0SAchim Leubner                  void                 *cbArg)
280*4e1bc9a0SAchim Leubner {
281*4e1bc9a0SAchim Leubner   bit32            ret = AGSA_RC_SUCCESS;
282*4e1bc9a0SAchim Leubner   agsaRoot_t       *agRoot;
283*4e1bc9a0SAchim Leubner   agsaLLRoot_t     *saRoot;
284*4e1bc9a0SAchim Leubner   mpiICQueue_t     *circularQ;
285*4e1bc9a0SAchim Leubner   agsaDeviceDesc_t *pDevice;
286*4e1bc9a0SAchim Leubner   agsaSgl_t        *pSgl;
287*4e1bc9a0SAchim Leubner   bit32            Dir = 0;
288*4e1bc9a0SAchim Leubner   bit8             inq, outq;
289*4e1bc9a0SAchim Leubner   saFastRequest_t  *fr;
290*4e1bc9a0SAchim Leubner   void             *pMessage;
291*4e1bc9a0SAchim Leubner   agsaIORequestDesc_t *pRequest;
292*4e1bc9a0SAchim Leubner   bit16            opCode;
293*4e1bc9a0SAchim Leubner   bitptr           offsetTag;
294*4e1bc9a0SAchim Leubner   bitptr           offsetDeviceId;
295*4e1bc9a0SAchim Leubner   bitptr           offsetDataLen;
296*4e1bc9a0SAchim Leubner   bitptr           offsetDir;
297*4e1bc9a0SAchim Leubner 
298*4e1bc9a0SAchim Leubner   agRoot = (agsaRoot_t*)fc->agRoot;
299*4e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"2G");
300*4e1bc9a0SAchim Leubner 
301*4e1bc9a0SAchim Leubner   OSSA_INP_ENTER(agRoot);
302*4e1bc9a0SAchim Leubner 
303*4e1bc9a0SAchim Leubner   saRoot = (agsaLLRoot_t*)(agRoot->sdkData);
304*4e1bc9a0SAchim Leubner   /* sanity check */
305*4e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != saRoot), "");
306*4e1bc9a0SAchim Leubner 
307*4e1bc9a0SAchim Leubner   SA_DBG4(("Entering function saFastSSPPrepare:\n"));
308*4e1bc9a0SAchim Leubner 
309*4e1bc9a0SAchim Leubner   fr = (saFastRequest_t*)ioh;
310*4e1bc9a0SAchim Leubner   if (!fr)
311*4e1bc9a0SAchim Leubner   {
312*4e1bc9a0SAchim Leubner     int i;
313*4e1bc9a0SAchim Leubner     fr = siFastSSPReqAlloc(agRoot);
314*4e1bc9a0SAchim Leubner     if (!fr)
315*4e1bc9a0SAchim Leubner     {
316*4e1bc9a0SAchim Leubner       SA_ASSERT((0), "");
317*4e1bc9a0SAchim Leubner       goto ext;
318*4e1bc9a0SAchim Leubner     }
319*4e1bc9a0SAchim Leubner 
320*4e1bc9a0SAchim Leubner     saLlistIOInitialize(&fr->requests);
321*4e1bc9a0SAchim Leubner     for (i = 0; i < AGSA_MAX_INBOUND_Q; i++)
322*4e1bc9a0SAchim Leubner       fr->beforePI[i] = (bit32)-1;
323*4e1bc9a0SAchim Leubner 
324*4e1bc9a0SAchim Leubner     fr->inqMax = 0;
325*4e1bc9a0SAchim Leubner     fr->agRoot = agRoot;
326*4e1bc9a0SAchim Leubner     ioh = fr;
327*4e1bc9a0SAchim Leubner   }
328*4e1bc9a0SAchim Leubner 
329*4e1bc9a0SAchim Leubner   /* Find the outgoing port for the device */
330*4e1bc9a0SAchim Leubner   pDevice = (agsaDeviceDesc_t*)(((agsaDevHandle_t*)fc->devHandle)->sdkData);
331*4e1bc9a0SAchim Leubner 
332*4e1bc9a0SAchim Leubner   ret = siFastSSPResAlloc(agRoot, fc->queueNum, fc->agRequestType,
333*4e1bc9a0SAchim Leubner                           pDevice, &pRequest, &pMessage);
334*4e1bc9a0SAchim Leubner   if (ret != AGSA_RC_SUCCESS)
335*4e1bc9a0SAchim Leubner   {
336*4e1bc9a0SAchim Leubner     SA_ASSERT((0), "");
337*4e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2G");
338*4e1bc9a0SAchim Leubner     goto ext;
339*4e1bc9a0SAchim Leubner   }
340*4e1bc9a0SAchim Leubner 
341*4e1bc9a0SAchim Leubner   /* Assign inbound and outbound Buffer */
342*4e1bc9a0SAchim Leubner   inq = INQ(fc->queueNum);
343*4e1bc9a0SAchim Leubner   outq = OUQ(fc->queueNum);
344*4e1bc9a0SAchim Leubner   circularQ = &saRoot->inboundQueue[inq];
345*4e1bc9a0SAchim Leubner 
346*4e1bc9a0SAchim Leubner   SA_DBG3(("saFastSSPPrepare: deviceId %d\n", pDevice->DeviceMapIndex));
347*4e1bc9a0SAchim Leubner 
348*4e1bc9a0SAchim Leubner   /* set up pRequest */
349*4e1bc9a0SAchim Leubner   pRequest->valid = agTRUE;
350*4e1bc9a0SAchim Leubner   pRequest->pDevice = pDevice;
351*4e1bc9a0SAchim Leubner   pRequest->requestType = fc->agRequestType;
352*4e1bc9a0SAchim Leubner 
353*4e1bc9a0SAchim Leubner   pRequest->completionCB = cb;
354*4e1bc9a0SAchim Leubner   pRequest->pIORequestContext = (agsaIORequest_t*)cbArg;
355*4e1bc9a0SAchim Leubner 
356*4e1bc9a0SAchim Leubner   pSgl = fc->agSgl;
357*4e1bc9a0SAchim Leubner 
358*4e1bc9a0SAchim Leubner   switch (fc->agRequestType)
359*4e1bc9a0SAchim Leubner   {
360*4e1bc9a0SAchim Leubner     /* case AGSA_SSP_INIT_NONDATA: */
361*4e1bc9a0SAchim Leubner     case AGSA_SSP_INIT_READ:
362*4e1bc9a0SAchim Leubner     case AGSA_SSP_INIT_WRITE:
363*4e1bc9a0SAchim Leubner     case AGSA_SSP_INIT_READ_M:
364*4e1bc9a0SAchim Leubner     case AGSA_SSP_INIT_WRITE_M:
365*4e1bc9a0SAchim Leubner     {
366*4e1bc9a0SAchim Leubner       agsaSSPIniIOStartCmd_t *pPayload = (agsaSSPIniIOStartCmd_t *)pMessage;
367*4e1bc9a0SAchim Leubner       agsaSSPCmdInfoUnit_t   *piu;
368*4e1bc9a0SAchim Leubner 
369*4e1bc9a0SAchim Leubner       /* SSPIU less equal 28 bytes */
370*4e1bc9a0SAchim Leubner       offsetTag = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, tag);
371*4e1bc9a0SAchim Leubner       offsetDeviceId = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, deviceId);
372*4e1bc9a0SAchim Leubner       offsetDataLen = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dataLen);
373*4e1bc9a0SAchim Leubner       offsetDir = OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dirMTlr);
374*4e1bc9a0SAchim Leubner 
375*4e1bc9a0SAchim Leubner       piu = &pPayload->SSPInfoUnit;
376*4e1bc9a0SAchim Leubner 
377*4e1bc9a0SAchim Leubner       si_memcpy(piu->lun, fc->lun, sizeof(piu->lun));
378*4e1bc9a0SAchim Leubner       si_memcpy(piu->cdb, fc->cdb, sizeof(piu->cdb));
379*4e1bc9a0SAchim Leubner       piu->efb_tp_taskAttribute = fc->taskAttribute;
380*4e1bc9a0SAchim Leubner       piu->additionalCdbLen = fc->additionalCdbLen;
381*4e1bc9a0SAchim Leubner 
382*4e1bc9a0SAchim Leubner       /* Mask DIR for Read/Write command */
383*4e1bc9a0SAchim Leubner       Dir = fc->agRequestType & AGSA_DIR_MASK;
384*4e1bc9a0SAchim Leubner 
385*4e1bc9a0SAchim Leubner       /* set TLR */
386*4e1bc9a0SAchim Leubner       Dir |= fc->flag & TLR_MASK;
387*4e1bc9a0SAchim Leubner       if (fc->agRequestType & AGSA_MSG)
388*4e1bc9a0SAchim Leubner       {
389*4e1bc9a0SAchim Leubner         /* set M bit */
390*4e1bc9a0SAchim Leubner         Dir |= AGSA_MSG_BIT;
391*4e1bc9a0SAchim Leubner       }
392*4e1bc9a0SAchim Leubner 
393*4e1bc9a0SAchim Leubner       /* Setup SGL */
394*4e1bc9a0SAchim Leubner       if (fc->dataLength)
395*4e1bc9a0SAchim Leubner       {
396*4e1bc9a0SAchim Leubner         SA_DBG5(("saFastSSPPrepare: agSgl %08x:%08x (%x/%x)\n",
397*4e1bc9a0SAchim Leubner                  pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved));
398*4e1bc9a0SAchim Leubner         /*
399*4e1bc9a0SAchim Leubner         pPayload->AddrLow0 = pSgl->sgLower;
400*4e1bc9a0SAchim Leubner         pPayload->AddrHi0 = pSgl->sgUpper;
401*4e1bc9a0SAchim Leubner         pPayload->Len0 = pSgl->len;
402*4e1bc9a0SAchim Leubner         pPayload->E0 = pSgl->extReserved;
403*4e1bc9a0SAchim Leubner         */
404*4e1bc9a0SAchim Leubner         si_memcpy(&pPayload->AddrLow0, pSgl, sizeof(*pSgl));
405*4e1bc9a0SAchim Leubner       }
406*4e1bc9a0SAchim Leubner       else
407*4e1bc9a0SAchim Leubner       {
408*4e1bc9a0SAchim Leubner         /* no data transfer */
409*4e1bc9a0SAchim Leubner         si_memset(&pPayload->AddrLow0, 0, sizeof(*pSgl));
410*4e1bc9a0SAchim Leubner       }
411*4e1bc9a0SAchim Leubner 
412*4e1bc9a0SAchim Leubner       opCode = OPC_INB_SSPINIIOSTART;
413*4e1bc9a0SAchim Leubner       break;
414*4e1bc9a0SAchim Leubner     }
415*4e1bc9a0SAchim Leubner 
416*4e1bc9a0SAchim Leubner     case AGSA_SSP_INIT_READ_EXT:
417*4e1bc9a0SAchim Leubner     case AGSA_SSP_INIT_WRITE_EXT:
418*4e1bc9a0SAchim Leubner     case AGSA_SSP_INIT_READ_EXT_M:
419*4e1bc9a0SAchim Leubner     case AGSA_SSP_INIT_WRITE_EXT_M:
420*4e1bc9a0SAchim Leubner     {
421*4e1bc9a0SAchim Leubner       agsaSSPIniExtIOStartCmd_t *pPayload =
422*4e1bc9a0SAchim Leubner                                     (agsaSSPIniExtIOStartCmd_t *)pMessage;
423*4e1bc9a0SAchim Leubner       agsaSSPCmdInfoUnitExt_t   *piu;
424*4e1bc9a0SAchim Leubner       bit32 sspiul;
425*4e1bc9a0SAchim Leubner 
426*4e1bc9a0SAchim Leubner       /* CDB > 16 bytes */
427*4e1bc9a0SAchim Leubner       offsetTag = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, tag);
428*4e1bc9a0SAchim Leubner       offsetDeviceId = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, deviceId);
429*4e1bc9a0SAchim Leubner       offsetDataLen = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, dataLen);
430*4e1bc9a0SAchim Leubner       offsetDir = OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, SSPIuLendirMTlr);
431*4e1bc9a0SAchim Leubner 
432*4e1bc9a0SAchim Leubner       /* dword (bit7-bit2) ==> bytes (bit7-bit0) */
433*4e1bc9a0SAchim Leubner       /* setup standard CDB bytes + additional CDB bytes in length field */
434*4e1bc9a0SAchim Leubner       sspiul = sizeof(agsaSSPCmdInfoUnit_t) + (fc->additionalCdbLen & 0xFC);
435*4e1bc9a0SAchim Leubner 
436*4e1bc9a0SAchim Leubner       Dir = sspiul << 16;
437*4e1bc9a0SAchim Leubner       piu = (agsaSSPCmdInfoUnitExt_t*)pPayload->SSPIu;
438*4e1bc9a0SAchim Leubner 
439*4e1bc9a0SAchim Leubner       si_memcpy(piu->lun, fc->lun, sizeof(piu->lun));
440*4e1bc9a0SAchim Leubner       si_memcpy(piu->cdb, fc->cdb, MIN(sizeof(piu->cdb),
441*4e1bc9a0SAchim Leubner                                        16 + fc->additionalCdbLen));
442*4e1bc9a0SAchim Leubner       piu->efb_tp_taskAttribute = fc->taskAttribute;
443*4e1bc9a0SAchim Leubner       piu->additionalCdbLen = fc->additionalCdbLen;
444*4e1bc9a0SAchim Leubner 
445*4e1bc9a0SAchim Leubner       /* Mask DIR for Read/Write command */
446*4e1bc9a0SAchim Leubner       Dir |= fc->agRequestType & AGSA_DIR_MASK;
447*4e1bc9a0SAchim Leubner 
448*4e1bc9a0SAchim Leubner       /* set TLR */
449*4e1bc9a0SAchim Leubner       Dir |= fc->flag & TLR_MASK;
450*4e1bc9a0SAchim Leubner       if (fc->agRequestType & AGSA_MSG)
451*4e1bc9a0SAchim Leubner       {
452*4e1bc9a0SAchim Leubner         /* set M bit */
453*4e1bc9a0SAchim Leubner         Dir |= AGSA_MSG_BIT;
454*4e1bc9a0SAchim Leubner       }
455*4e1bc9a0SAchim Leubner 
456*4e1bc9a0SAchim Leubner       /* Setup SGL */
457*4e1bc9a0SAchim Leubner       if (fc->dataLength)
458*4e1bc9a0SAchim Leubner       {
459*4e1bc9a0SAchim Leubner         SA_DBG5(("saSuperSSPSend: Ext mode, agSgl %08x:%08x (%x/%x)\n",
460*4e1bc9a0SAchim Leubner           pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved));
461*4e1bc9a0SAchim Leubner 
462*4e1bc9a0SAchim Leubner         si_memcpy((&(pPayload->SSPIu[0]) + sspiul), pSgl, sizeof(*pSgl));
463*4e1bc9a0SAchim Leubner       }
464*4e1bc9a0SAchim Leubner       else //?
465*4e1bc9a0SAchim Leubner       {
466*4e1bc9a0SAchim Leubner         /* no data transfer */
467*4e1bc9a0SAchim Leubner         //pPayload->dataLen = 0;
468*4e1bc9a0SAchim Leubner         si_memset((&(pPayload->SSPIu[0]) + sspiul), 0, sizeof(*pSgl));
469*4e1bc9a0SAchim Leubner       }
470*4e1bc9a0SAchim Leubner       SA_ASSERT((smIS_SPC(agRoot)), "smIS_SPC");
471*4e1bc9a0SAchim Leubner       opCode = OPC_INB_SSPINIEXTIOSTART;
472*4e1bc9a0SAchim Leubner       break;
473*4e1bc9a0SAchim Leubner     }
474*4e1bc9a0SAchim Leubner 
475*4e1bc9a0SAchim Leubner     default:
476*4e1bc9a0SAchim Leubner     {
477*4e1bc9a0SAchim Leubner       SA_DBG1(("saSuperSSPSend: Unsupported Request IOMB\n"));
478*4e1bc9a0SAchim Leubner       ret = AGSA_RC_FAILURE;
479*4e1bc9a0SAchim Leubner       SA_ASSERT((0), "");
480*4e1bc9a0SAchim Leubner       smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2G");
481*4e1bc9a0SAchim Leubner       goto ext;
482*4e1bc9a0SAchim Leubner     }
483*4e1bc9a0SAchim Leubner   }
484*4e1bc9a0SAchim Leubner 
485*4e1bc9a0SAchim Leubner   OSSA_WRITE_LE_32(agRoot, pMessage, offsetTag, pRequest->HTag);
486*4e1bc9a0SAchim Leubner   OSSA_WRITE_LE_32(agRoot, pMessage, offsetDeviceId, pDevice->DeviceMapIndex);
487*4e1bc9a0SAchim Leubner   OSSA_WRITE_LE_32(agRoot, pMessage, offsetDataLen, fc->dataLength);
488*4e1bc9a0SAchim Leubner   OSSA_WRITE_LE_32(agRoot, pMessage, offsetDir, Dir);
489*4e1bc9a0SAchim Leubner 
490*4e1bc9a0SAchim Leubner   if (fr->beforePI[inq] == -1)
491*4e1bc9a0SAchim Leubner   {
492*4e1bc9a0SAchim Leubner     /* save the new IBQ' PI */
493*4e1bc9a0SAchim Leubner     fr->beforePI[inq] = saGetIBQPI(agRoot, inq);
494*4e1bc9a0SAchim Leubner     fr->inqList[fr->inqMax++] = inq;
495*4e1bc9a0SAchim Leubner   }
496*4e1bc9a0SAchim Leubner 
497*4e1bc9a0SAchim Leubner   /* post the IOMB to SPC */
498*4e1bc9a0SAchim Leubner   ret = mpiMsgPrepare(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA,
499*4e1bc9a0SAchim Leubner                       opCode, outq, 0);
500*4e1bc9a0SAchim Leubner   if (AGSA_RC_SUCCESS != ret)
501*4e1bc9a0SAchim Leubner   {
502*4e1bc9a0SAchim Leubner     SA_ASSERT((0), "");
503*4e1bc9a0SAchim Leubner     ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
504*4e1bc9a0SAchim Leubner     /* Remove the request from pendingIORequests list */
505*4e1bc9a0SAchim Leubner     saLlistIORemove(&pDevice->pendingIORequests, &pRequest->linkNode);
506*4e1bc9a0SAchim Leubner 
507*4e1bc9a0SAchim Leubner     /* Add the request to the free list of the device */
508*4e1bc9a0SAchim Leubner     saLlistIOAdd(&saRoot->freeIORequests, &pRequest->linkNode);
509*4e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
510*4e1bc9a0SAchim Leubner 
511*4e1bc9a0SAchim Leubner     SA_DBG1(("saFastSSPPrepare: error when post SSP IOMB\n"));
512*4e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "2G");
513*4e1bc9a0SAchim Leubner     goto ext;
514*4e1bc9a0SAchim Leubner   }
515*4e1bc9a0SAchim Leubner 
516*4e1bc9a0SAchim Leubner   /* Add the request to the pendingFastIORequests list of the device */
517*4e1bc9a0SAchim Leubner   saLlistIOAdd(&fr->requests, &pRequest->fastLink);
518*4e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "2G");
519*4e1bc9a0SAchim Leubner 
520*4e1bc9a0SAchim Leubner ext:
521*4e1bc9a0SAchim Leubner   if (fr && ret != AGSA_RC_SUCCESS)
522*4e1bc9a0SAchim Leubner   {
523*4e1bc9a0SAchim Leubner     saFastSSPCancel(fr);
524*4e1bc9a0SAchim Leubner     ioh = 0;
525*4e1bc9a0SAchim Leubner   }
526*4e1bc9a0SAchim Leubner   OSSA_INP_LEAVE(agRoot);
527*4e1bc9a0SAchim Leubner   return ioh;
528*4e1bc9a0SAchim Leubner } /* saFastSSPPrepare */
529*4e1bc9a0SAchim Leubner 
saFastSSPSend(void * ioHandle)530*4e1bc9a0SAchim Leubner GLOBAL bit32 saFastSSPSend(void *ioHandle)
531*4e1bc9a0SAchim Leubner {
532*4e1bc9a0SAchim Leubner   bit8            inq;
533*4e1bc9a0SAchim Leubner   agsaRoot_t      *agRoot;
534*4e1bc9a0SAchim Leubner   agsaLLRoot_t    *saRoot;
535*4e1bc9a0SAchim Leubner   saFastRequest_t *fr;
536*4e1bc9a0SAchim Leubner   bit32           i;
537*4e1bc9a0SAchim Leubner 
538*4e1bc9a0SAchim Leubner   SA_ASSERT((ioHandle), "");
539*4e1bc9a0SAchim Leubner   fr = (saFastRequest_t*)ioHandle;
540*4e1bc9a0SAchim Leubner   agRoot = (agsaRoot_t*)fr->agRoot;
541*4e1bc9a0SAchim Leubner   SA_ASSERT((agRoot), "");
542*4e1bc9a0SAchim Leubner   saRoot = (agsaLLRoot_t*)agRoot->sdkData;
543*4e1bc9a0SAchim Leubner   SA_ASSERT((saRoot), "");
544*4e1bc9a0SAchim Leubner 
545*4e1bc9a0SAchim Leubner   SA_DBG4(("Entering function saFastSSPSend:\n"));
546*4e1bc9a0SAchim Leubner 
547*4e1bc9a0SAchim Leubner   for (i = 0; i < fr->inqMax; i++)
548*4e1bc9a0SAchim Leubner   {
549*4e1bc9a0SAchim Leubner     inq = INQ(fr->inqList[i]);
550*4e1bc9a0SAchim Leubner     /* FW interrupt */
551*4e1bc9a0SAchim Leubner     mpiIBQMsgSend(&saRoot->inboundQueue[inq]);
552*4e1bc9a0SAchim Leubner   }
553*4e1bc9a0SAchim Leubner   /* IORequests are freed in siIODone() */
554*4e1bc9a0SAchim Leubner 
555*4e1bc9a0SAchim Leubner   siFastSSPReqFree(agRoot, fr);
556*4e1bc9a0SAchim Leubner   return AGSA_RC_SUCCESS;
557*4e1bc9a0SAchim Leubner } /* saFastSSPSend */
558*4e1bc9a0SAchim Leubner #endif
559*4e1bc9a0SAchim Leubner 
560*4e1bc9a0SAchim Leubner /******************************************************************************/
561*4e1bc9a0SAchim Leubner /*! \brief Start SSP request
562*4e1bc9a0SAchim Leubner  *
563*4e1bc9a0SAchim Leubner  *  Start SSP request
564*4e1bc9a0SAchim Leubner  *
565*4e1bc9a0SAchim Leubner  *  \param agRoot handles for this instance of SAS/SATA LLL
566*4e1bc9a0SAchim Leubner  *  \param queueNum
567*4e1bc9a0SAchim Leubner  *  \param agIORequest
568*4e1bc9a0SAchim Leubner  *  \param agDevHandle
569*4e1bc9a0SAchim Leubner  *  \param agRequestType
570*4e1bc9a0SAchim Leubner  *  \param agRequestBody
571*4e1bc9a0SAchim Leubner  *  \param agTMRequest valid for task management
572*4e1bc9a0SAchim Leubner  *  \param agCB
573*4e1bc9a0SAchim Leubner  *
574*4e1bc9a0SAchim Leubner  *  \return If request is started successfully
575*4e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS request is started successfully
576*4e1bc9a0SAchim Leubner  *          - \e AGSA_RC_BUSY request is not started successfully
577*4e1bc9a0SAchim Leubner  */
578*4e1bc9a0SAchim Leubner /******************************************************************************/
saSSPStart(agsaRoot_t * agRoot,agsaIORequest_t * agIORequest,bit32 queueNum,agsaDevHandle_t * agDevHandle,bit32 agRequestType,agsaSASRequestBody_t * agRequestBody,agsaIORequest_t * agTMRequest,ossaSSPCompletedCB_t agCB)579*4e1bc9a0SAchim Leubner GLOBAL bit32 saSSPStart(
580*4e1bc9a0SAchim Leubner   agsaRoot_t            *agRoot,
581*4e1bc9a0SAchim Leubner   agsaIORequest_t       *agIORequest,
582*4e1bc9a0SAchim Leubner   bit32                 queueNum,
583*4e1bc9a0SAchim Leubner   agsaDevHandle_t       *agDevHandle,
584*4e1bc9a0SAchim Leubner   bit32                 agRequestType,
585*4e1bc9a0SAchim Leubner   agsaSASRequestBody_t  *agRequestBody,
586*4e1bc9a0SAchim Leubner   agsaIORequest_t       *agTMRequest,
587*4e1bc9a0SAchim Leubner   ossaSSPCompletedCB_t  agCB)
588*4e1bc9a0SAchim Leubner {
589*4e1bc9a0SAchim Leubner   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
590*4e1bc9a0SAchim Leubner #ifdef LOOPBACK_MPI
591*4e1bc9a0SAchim Leubner   mpiOCQueue_t        *circularOQ = agNULL;
592*4e1bc9a0SAchim Leubner #endif
593*4e1bc9a0SAchim Leubner   mpiICQueue_t        *circularQ  = agNULL;
594*4e1bc9a0SAchim Leubner   agsaDeviceDesc_t    *pDevice    = agNULL;
595*4e1bc9a0SAchim Leubner   agsaPort_t          *pPort      = agNULL;
596*4e1bc9a0SAchim Leubner   agsaIORequestDesc_t *pRequest   = agNULL;
597*4e1bc9a0SAchim Leubner   agsaSgl_t           *pSgl       = agNULL;
598*4e1bc9a0SAchim Leubner   void                *pMessage   = agNULL;
599*4e1bc9a0SAchim Leubner   bit32               ret = AGSA_RC_SUCCESS, retVal = 0;
600*4e1bc9a0SAchim Leubner   bit32               DirDW4 = 0;    /* no data and no AutoGR */
601*4e1bc9a0SAchim Leubner   bit32               encryptFlags = 0;
602*4e1bc9a0SAchim Leubner   bit16               size = 0;
603*4e1bc9a0SAchim Leubner   bit16               opCode = 0;
604*4e1bc9a0SAchim Leubner   bit8                inq = 0, outq = 0;
605*4e1bc9a0SAchim Leubner 
606*4e1bc9a0SAchim Leubner 
607*4e1bc9a0SAchim Leubner   OSSA_INP_ENTER(agRoot);
608*4e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"Sa");
609*4e1bc9a0SAchim Leubner 
610*4e1bc9a0SAchim Leubner   /* sanity check */
611*4e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
612*4e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agIORequest), "");
613*4e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agDevHandle), "");
614*4e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRequestBody), "");
615*4e1bc9a0SAchim Leubner 
616*4e1bc9a0SAchim Leubner   DBG_DUMP_SSPSTART_CMDIU(agDevHandle,agRequestType,agRequestBody);
617*4e1bc9a0SAchim Leubner 
618*4e1bc9a0SAchim Leubner   /* Find the outgoing port for the device */
619*4e1bc9a0SAchim Leubner   pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
620*4e1bc9a0SAchim Leubner 
621*4e1bc9a0SAchim Leubner   if(pDevice == agNULL )
622*4e1bc9a0SAchim Leubner   {
623*4e1bc9a0SAchim Leubner     SA_ASSERT((pDevice), "pDevice");
624*4e1bc9a0SAchim Leubner     ret = AGSA_RC_FAILURE;
625*4e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "Sa");
626*4e1bc9a0SAchim Leubner     goto ext;
627*4e1bc9a0SAchim Leubner   }
628*4e1bc9a0SAchim Leubner 
629*4e1bc9a0SAchim Leubner   pPort = pDevice->pPort;
630*4e1bc9a0SAchim Leubner   /* Assign inbound and outbound Buffer */
631*4e1bc9a0SAchim Leubner   inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
632*4e1bc9a0SAchim Leubner   outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
633*4e1bc9a0SAchim Leubner   SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
634*4e1bc9a0SAchim Leubner 
635*4e1bc9a0SAchim Leubner   SA_DBG3(("saSSPStart: inq %d outq %d deviceId 0x%x\n", inq,outq,pDevice->DeviceMapIndex));
636*4e1bc9a0SAchim Leubner 
637*4e1bc9a0SAchim Leubner   /* Get request from free IORequests */
638*4e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
639*4e1bc9a0SAchim Leubner   pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests));
640*4e1bc9a0SAchim Leubner 
641*4e1bc9a0SAchim Leubner   /* If no LL IO request entry available */
642*4e1bc9a0SAchim Leubner   if ( agNULL == pRequest )
643*4e1bc9a0SAchim Leubner   {
644*4e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
645*4e1bc9a0SAchim Leubner     SA_DBG1(("saSSPStart, No request from free list\n" ));
646*4e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "Sa");
647*4e1bc9a0SAchim Leubner     ret = AGSA_RC_BUSY;
648*4e1bc9a0SAchim Leubner     goto ext;
649*4e1bc9a0SAchim Leubner   }
650*4e1bc9a0SAchim Leubner   /* If LL IO request entry avaliable */
651*4e1bc9a0SAchim Leubner   else
652*4e1bc9a0SAchim Leubner   {
653*4e1bc9a0SAchim Leubner     /* Remove the request from free list */
654*4e1bc9a0SAchim Leubner     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
655*4e1bc9a0SAchim Leubner     /* Add the request to the pendingIORequests list of the device */
656*4e1bc9a0SAchim Leubner     saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode));
657*4e1bc9a0SAchim Leubner 
658*4e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
659*4e1bc9a0SAchim Leubner 
660*4e1bc9a0SAchim Leubner     SA_ASSERT((!pRequest->valid), "The pRequest is in use");
661*4e1bc9a0SAchim Leubner 
662*4e1bc9a0SAchim Leubner     SA_DBG3(("saSSPStart, request %p\n", pRequest ));
663*4e1bc9a0SAchim Leubner 
664*4e1bc9a0SAchim Leubner     /* Decode the flag settings in the standard I/O requests to  decide what size we need. */
665*4e1bc9a0SAchim Leubner     /* All other requests will be fine with only 64 byte messages. */
666*4e1bc9a0SAchim Leubner     switch ( agRequestType )
667*4e1bc9a0SAchim Leubner     {
668*4e1bc9a0SAchim Leubner     case AGSA_SSP_INIT_READ:
669*4e1bc9a0SAchim Leubner     case AGSA_SSP_INIT_WRITE:
670*4e1bc9a0SAchim Leubner     case AGSA_SSP_INIT_NONDATA:
671*4e1bc9a0SAchim Leubner     case AGSA_SSP_INIT_READ_M:
672*4e1bc9a0SAchim Leubner     case AGSA_SSP_INIT_WRITE_M:
673*4e1bc9a0SAchim Leubner         {
674*4e1bc9a0SAchim Leubner             agsaSSPInitiatorRequest_t *pIRequest = &(agRequestBody->sspInitiatorReq);
675*4e1bc9a0SAchim Leubner 
676*4e1bc9a0SAchim Leubner             if ((pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION)   ||
677*4e1bc9a0SAchim Leubner #ifdef SAFLAG_USE_DIF_ENC_IOMB
678*4e1bc9a0SAchim Leubner                (pIRequest->flag & AGSA_SAS_USE_DIF_ENC_OPSTART)  ||
679*4e1bc9a0SAchim Leubner #endif /* SAFLAG_USE_DIF_ENC_IOMB */
680*4e1bc9a0SAchim Leubner                 (pIRequest->flag & AGSA_SAS_ENABLE_DIF) )
681*4e1bc9a0SAchim Leubner             {
682*4e1bc9a0SAchim Leubner                 opCode = OPC_INB_SSP_DIF_ENC_OPSTART;
683*4e1bc9a0SAchim Leubner                 size = IOMB_SIZE128;
684*4e1bc9a0SAchim Leubner             }
685*4e1bc9a0SAchim Leubner             else
686*4e1bc9a0SAchim Leubner             {
687*4e1bc9a0SAchim Leubner                 opCode = OPC_INB_SSPINIIOSTART;
688*4e1bc9a0SAchim Leubner                 size = IOMB_SIZE64;
689*4e1bc9a0SAchim Leubner             }
690*4e1bc9a0SAchim Leubner             break;
691*4e1bc9a0SAchim Leubner         }
692*4e1bc9a0SAchim Leubner     case AGSA_SSP_INIT_READ_EXT:
693*4e1bc9a0SAchim Leubner     case AGSA_SSP_INIT_WRITE_EXT:
694*4e1bc9a0SAchim Leubner     case AGSA_SSP_INIT_READ_EXT_M:
695*4e1bc9a0SAchim Leubner     case AGSA_SSP_INIT_WRITE_EXT_M:
696*4e1bc9a0SAchim Leubner         {
697*4e1bc9a0SAchim Leubner           agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt);
698*4e1bc9a0SAchim Leubner 
699*4e1bc9a0SAchim Leubner           if ((pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION)   ||
700*4e1bc9a0SAchim Leubner               (pIRequest->flag & AGSA_SAS_ENABLE_DIF)          ||
701*4e1bc9a0SAchim Leubner #ifdef SAFLAG_USE_DIF_ENC_IOMB
702*4e1bc9a0SAchim Leubner               (pIRequest->flag & AGSA_SAS_USE_DIF_ENC_OPSTART) ||
703*4e1bc9a0SAchim Leubner #endif /* SAFLAG_USE_DIF_ENC_IOMB */
704*4e1bc9a0SAchim Leubner               (pIRequest->flag & AGSA_SAS_ENABLE_SKIP_MASK))
705*4e1bc9a0SAchim Leubner           {
706*4e1bc9a0SAchim Leubner               opCode = OPC_INB_SSP_DIF_ENC_OPSTART;
707*4e1bc9a0SAchim Leubner               size = IOMB_SIZE128;
708*4e1bc9a0SAchim Leubner           }
709*4e1bc9a0SAchim Leubner           else
710*4e1bc9a0SAchim Leubner           {
711*4e1bc9a0SAchim Leubner               SA_ASSERT((smIS_SPC(agRoot)), "smIS_SPC");
712*4e1bc9a0SAchim Leubner               opCode = OPC_INB_SSPINIEXTIOSTART;
713*4e1bc9a0SAchim Leubner               size = IOMB_SIZE96;
714*4e1bc9a0SAchim Leubner           }
715*4e1bc9a0SAchim Leubner           break;
716*4e1bc9a0SAchim Leubner       }
717*4e1bc9a0SAchim Leubner       case  AGSA_SSP_INIT_READ_INDIRECT:
718*4e1bc9a0SAchim Leubner       case  AGSA_SSP_INIT_WRITE_INDIRECT:
719*4e1bc9a0SAchim Leubner       case  AGSA_SSP_INIT_READ_INDIRECT_M:
720*4e1bc9a0SAchim Leubner       case  AGSA_SSP_INIT_WRITE_INDIRECT_M:
721*4e1bc9a0SAchim Leubner           {
722*4e1bc9a0SAchim Leubner             SA_DBG3(("saSSPStart: agRequestType  0x%X INDIRECT\n", agRequestType));
723*4e1bc9a0SAchim Leubner             opCode = OPC_INB_SSP_DIF_ENC_OPSTART;
724*4e1bc9a0SAchim Leubner             size = IOMB_SIZE128;
725*4e1bc9a0SAchim Leubner             break;
726*4e1bc9a0SAchim Leubner           }
727*4e1bc9a0SAchim Leubner       case (AGSA_SSP_REQTYPE | AGSA_SSP_TASK_MGNT):
728*4e1bc9a0SAchim Leubner       case AGSA_SSP_TASK_MGNT_REQ_M:
729*4e1bc9a0SAchim Leubner       case AGSA_SSP_TGT_READ_DATA:
730*4e1bc9a0SAchim Leubner       case AGSA_SSP_TGT_READ_GOOD_RESP:
731*4e1bc9a0SAchim Leubner       case AGSA_SSP_TGT_WRITE_DATA:
732*4e1bc9a0SAchim Leubner       case AGSA_SSP_TGT_WRITE_GOOD_RESP:
733*4e1bc9a0SAchim Leubner       case AGSA_SSP_TGT_CMD_OR_TASK_RSP:
734*4e1bc9a0SAchim Leubner 
735*4e1bc9a0SAchim Leubner         SA_DBG3(("saSSPStart: agRequestType  0x%X (was default)\n", agRequestType));
736*4e1bc9a0SAchim Leubner         opCode = OPC_INB_SSPINIIOSTART;
737*4e1bc9a0SAchim Leubner         size = IOMB_SIZE64;
738*4e1bc9a0SAchim Leubner          break;
739*4e1bc9a0SAchim Leubner     default:
740*4e1bc9a0SAchim Leubner         SA_DBG1(("saSSPStart: agRequestType UNKNOWN 0x%X\n", agRequestType));
741*4e1bc9a0SAchim Leubner         /* OpCode is not used in this case, but Linux complains if it is not initialized. */
742*4e1bc9a0SAchim Leubner         opCode = OPC_INB_SSPINIIOSTART;
743*4e1bc9a0SAchim Leubner         size = IOMB_SIZE64;
744*4e1bc9a0SAchim Leubner         break;
745*4e1bc9a0SAchim Leubner     }
746*4e1bc9a0SAchim Leubner 
747*4e1bc9a0SAchim Leubner     /* If free IOMB avaliable,  set up pRequest*/
748*4e1bc9a0SAchim Leubner     pRequest->valid = agTRUE;
749*4e1bc9a0SAchim Leubner     pRequest->pIORequestContext = agIORequest;
750*4e1bc9a0SAchim Leubner     pRequest->pDevice = pDevice;
751*4e1bc9a0SAchim Leubner     pRequest->requestType = agRequestType;
752*4e1bc9a0SAchim Leubner     pRequest->pPort = pPort;
753*4e1bc9a0SAchim Leubner     pRequest->startTick = saRoot->timeTick;
754*4e1bc9a0SAchim Leubner     pRequest->completionCB = agCB;
755*4e1bc9a0SAchim Leubner 
756*4e1bc9a0SAchim Leubner     /* Set request to the sdkData of agIORequest */
757*4e1bc9a0SAchim Leubner     agIORequest->sdkData = pRequest;
758*4e1bc9a0SAchim Leubner 
759*4e1bc9a0SAchim Leubner     /* save tag and IOrequest pointer to IOMap */
760*4e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
761*4e1bc9a0SAchim Leubner     saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
762*4e1bc9a0SAchim Leubner 
763*4e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
764*4e1bc9a0SAchim Leubner     ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
765*4e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
766*4e1bc9a0SAchim Leubner 
767*4e1bc9a0SAchim Leubner     /* Get a free inbound queue entry */
768*4e1bc9a0SAchim Leubner #ifdef LOOPBACK_MPI
769*4e1bc9a0SAchim Leubner     if (loopback)
770*4e1bc9a0SAchim Leubner     {
771*4e1bc9a0SAchim Leubner       SA_DBG2(("saSSPStart: did %d ioq %d / %d tag %d\n", pDevice->DeviceMapIndex, inq, outq, pRequest->HTag));
772*4e1bc9a0SAchim Leubner       circularOQ = &saRoot->outboundQueue[outq];
773*4e1bc9a0SAchim Leubner       retVal = mpiMsgFreeGetOQ(circularOQ, size, &pMessage);
774*4e1bc9a0SAchim Leubner     }
775*4e1bc9a0SAchim Leubner     else
776*4e1bc9a0SAchim Leubner #endif /* LOOPBACK_MPI */
777*4e1bc9a0SAchim Leubner     {
778*4e1bc9a0SAchim Leubner       circularQ = &saRoot->inboundQueue[inq];
779*4e1bc9a0SAchim Leubner       retVal = mpiMsgFreeGet(circularQ, size, &pMessage);
780*4e1bc9a0SAchim Leubner     }
781*4e1bc9a0SAchim Leubner 
782*4e1bc9a0SAchim Leubner     /* if message size is too large return failure */
783*4e1bc9a0SAchim Leubner     if (AGSA_RC_FAILURE == retVal)
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       /* if not sending return to free list rare */
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(("saSSPStart, error when get free IOMB\n"));
796*4e1bc9a0SAchim Leubner       smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "Sa");
797*4e1bc9a0SAchim Leubner       ret = AGSA_RC_FAILURE;
798*4e1bc9a0SAchim Leubner       goto ext;
799*4e1bc9a0SAchim Leubner     }
800*4e1bc9a0SAchim Leubner 
801*4e1bc9a0SAchim Leubner     /* return busy if inbound queue is full */
802*4e1bc9a0SAchim Leubner     if (AGSA_RC_BUSY == retVal)
803*4e1bc9a0SAchim Leubner     {
804*4e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
805*4e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
806*4e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
807*4e1bc9a0SAchim Leubner       /* if not sending return to free list rare */
808*4e1bc9a0SAchim Leubner       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
809*4e1bc9a0SAchim Leubner       saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
810*4e1bc9a0SAchim Leubner       pRequest->valid = agFALSE;
811*4e1bc9a0SAchim Leubner       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
812*4e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
813*4e1bc9a0SAchim Leubner 
814*4e1bc9a0SAchim Leubner       SA_DBG1(("saSSPStart, no more IOMB\n"));
815*4e1bc9a0SAchim Leubner       smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "Sa");
816*4e1bc9a0SAchim Leubner       ret = AGSA_RC_BUSY;
817*4e1bc9a0SAchim Leubner       goto ext;
818*4e1bc9a0SAchim Leubner     }
819*4e1bc9a0SAchim Leubner     SA_DBG3(("saSSPStart:agRequestType %X\n" ,agRequestType));
820*4e1bc9a0SAchim Leubner 
821*4e1bc9a0SAchim Leubner     switch ( agRequestType )
822*4e1bc9a0SAchim Leubner     {
823*4e1bc9a0SAchim Leubner       case AGSA_SSP_INIT_READ:
824*4e1bc9a0SAchim Leubner       case AGSA_SSP_INIT_WRITE:
825*4e1bc9a0SAchim Leubner       case AGSA_SSP_INIT_NONDATA:
826*4e1bc9a0SAchim Leubner       case AGSA_SSP_INIT_READ_EXT:
827*4e1bc9a0SAchim Leubner       case AGSA_SSP_INIT_WRITE_EXT:
828*4e1bc9a0SAchim Leubner       case AGSA_SSP_INIT_READ_M:
829*4e1bc9a0SAchim Leubner       case AGSA_SSP_INIT_WRITE_M:
830*4e1bc9a0SAchim Leubner       case AGSA_SSP_INIT_READ_EXT_M:
831*4e1bc9a0SAchim Leubner       case AGSA_SSP_INIT_WRITE_EXT_M:
832*4e1bc9a0SAchim Leubner       case AGSA_SSP_INIT_READ_INDIRECT:
833*4e1bc9a0SAchim Leubner       case AGSA_SSP_INIT_WRITE_INDIRECT:
834*4e1bc9a0SAchim Leubner       case AGSA_SSP_INIT_READ_INDIRECT_M:
835*4e1bc9a0SAchim Leubner       case AGSA_SSP_INIT_WRITE_INDIRECT_M:
836*4e1bc9a0SAchim Leubner       {
837*4e1bc9a0SAchim Leubner         if (!(agRequestType & AGSA_SSP_EXT_BIT))
838*4e1bc9a0SAchim Leubner         {
839*4e1bc9a0SAchim Leubner           agsaSSPInitiatorRequest_t     *pIRequest = &(agRequestBody->sspInitiatorReq);
840*4e1bc9a0SAchim Leubner           agsaSSPIniIOStartCmd_t        *pPayload = (agsaSSPIniIOStartCmd_t *)pMessage;
841*4e1bc9a0SAchim Leubner           agsaSSPIniEncryptIOStartCmd_t *pEncryptPayload = (agsaSSPIniEncryptIOStartCmd_t *)pMessage;
842*4e1bc9a0SAchim Leubner 
843*4e1bc9a0SAchim Leubner           /* Most fields for the SAS IOMB have the same offset regardless of the actual IOMB used. */
844*4e1bc9a0SAchim Leubner           /* Be careful with the scatter/gather lists, encryption and DIF options. */
845*4e1bc9a0SAchim Leubner 
846*4e1bc9a0SAchim Leubner /*          if( pIRequest->sspCmdIU.cdb[ 0] ==  0x28 || pIRequest->sspCmdIU.cdb[0]== 0x2A)
847*4e1bc9a0SAchim Leubner           {
848*4e1bc9a0SAchim Leubner             pRequest->requestBlock = ((pIRequest->sspCmdIU.cdb[2] << 24 ) |
849*4e1bc9a0SAchim Leubner                             (pIRequest->sspCmdIU.cdb[3] << 16 ) |
850*4e1bc9a0SAchim Leubner                             (pIRequest->sspCmdIU.cdb[4] <<  8 ) |
851*4e1bc9a0SAchim Leubner                             (pIRequest->sspCmdIU.cdb[5] ) );
852*4e1bc9a0SAchim Leubner           }
853*4e1bc9a0SAchim Leubner */
854*4e1bc9a0SAchim Leubner #ifdef LOOPBACK_MPI
855*4e1bc9a0SAchim Leubner           if (loopback)
856*4e1bc9a0SAchim Leubner           {
857*4e1bc9a0SAchim Leubner           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, tag), pRequest->HTag);
858*4e1bc9a0SAchim Leubner           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, status), OSSA_IO_SUCCESS);
859*4e1bc9a0SAchim Leubner           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, param), 0);
860*4e1bc9a0SAchim Leubner           //OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, SSPTag), 0);
861*4e1bc9a0SAchim Leubner           }
862*4e1bc9a0SAchim Leubner           else
863*4e1bc9a0SAchim Leubner #endif /* LOOPBACK_MPI */
864*4e1bc9a0SAchim Leubner           {
865*4e1bc9a0SAchim Leubner             /* SSPIU less equal 28 bytes */
866*4e1bc9a0SAchim Leubner             /* Configure DWORD 1 */
867*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, tag), pRequest->HTag);
868*4e1bc9a0SAchim Leubner             /* Configure DWORD 2 */
869*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, deviceId), pDevice->DeviceMapIndex);
870*4e1bc9a0SAchim Leubner             /* Configure DWORD 3 */
871*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dataLen), pIRequest->dataLength);
872*4e1bc9a0SAchim Leubner           }
873*4e1bc9a0SAchim Leubner 
874*4e1bc9a0SAchim Leubner #ifdef SA_TESTBASE_EXTRA
875*4e1bc9a0SAchim Leubner           /* TestBase - Set the host BST entry  */
876*4e1bc9a0SAchim Leubner           DirDW4 |= ((UINT32)pIRequest->bstIndex) << 16;
877*4e1bc9a0SAchim Leubner #endif /*  SA_TESTBASE_EXTRA */
878*4e1bc9a0SAchim Leubner 
879*4e1bc9a0SAchim Leubner           if (!(agRequestType & AGSA_SSP_INDIRECT_BIT))
880*4e1bc9a0SAchim Leubner           {
881*4e1bc9a0SAchim Leubner             /* Configure DWORD 5-12  */
882*4e1bc9a0SAchim Leubner             si_memcpy(&pPayload->SSPInfoUnit, &pIRequest->sspCmdIU, sizeof(pPayload->SSPInfoUnit));
883*4e1bc9a0SAchim Leubner             pPayload->dirMTlr     = 0;
884*4e1bc9a0SAchim Leubner             /* Mask DIR for Read/Write command */
885*4e1bc9a0SAchim Leubner             /* Configure DWORD 4 bit 8-9 */
886*4e1bc9a0SAchim Leubner             DirDW4 |= agRequestType & AGSA_DIR_MASK;
887*4e1bc9a0SAchim Leubner           }
888*4e1bc9a0SAchim Leubner           else /* AGSA_SSP_INDIRECT_BIT was set */
889*4e1bc9a0SAchim Leubner           {
890*4e1bc9a0SAchim Leubner 
891*4e1bc9a0SAchim Leubner             agsaSSPInitiatorRequestIndirect_t *pIndRequest = &(agRequestBody->sspInitiatorReqIndirect);
892*4e1bc9a0SAchim Leubner 
893*4e1bc9a0SAchim Leubner             /* Configure DWORD 5 */
894*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_0_3_indcdbalL ),pIndRequest->sspInitiatorReqAddrLower32);
895*4e1bc9a0SAchim Leubner             /* Configure DWORD 6 */
896*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_4_7_indcdbalH ),pIndRequest->sspInitiatorReqAddrUpper32 );
897*4e1bc9a0SAchim Leubner             /* Configure DWORD 7 */
898*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_8_11 ), 0);
899*4e1bc9a0SAchim Leubner             /* Configure DWORD 8 */
900*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_12_15 ), 0);
901*4e1bc9a0SAchim Leubner             /* Configure DWORD 9 */
902*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_16_19 ), 0);
903*4e1bc9a0SAchim Leubner             /* Configure DWORD 10 */
904*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_19_23), 0);
905*4e1bc9a0SAchim Leubner             /* Configure DWORD 11 */
906*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,sspiu_24_27 ), 0);
907*4e1bc9a0SAchim Leubner             /* Mask DIR for Read/Write command */
908*4e1bc9a0SAchim Leubner             /* Configure DWORD 4 bit 8-9 */
909*4e1bc9a0SAchim Leubner             DirDW4 |= agRequestType & AGSA_DIR_MASK;
910*4e1bc9a0SAchim Leubner             /* Configure DWORD 4 bit 24-31 */
911*4e1bc9a0SAchim Leubner             DirDW4 |= ((pIndRequest->sspInitiatorReqLen >> 2) & 0xFF) << SHIFT24;
912*4e1bc9a0SAchim Leubner             /* Configure DWORD 4 bit 4 */
913*4e1bc9a0SAchim Leubner             DirDW4 |= 1 << SHIFT3;
914*4e1bc9a0SAchim Leubner           }
915*4e1bc9a0SAchim Leubner 
916*4e1bc9a0SAchim Leubner           /* set TLR */
917*4e1bc9a0SAchim Leubner           DirDW4 |= pIRequest->flag & TLR_MASK;
918*4e1bc9a0SAchim Leubner           if (agRequestType & AGSA_MSG)
919*4e1bc9a0SAchim Leubner           {
920*4e1bc9a0SAchim Leubner             /* set M bit */
921*4e1bc9a0SAchim Leubner             DirDW4 |= AGSA_MSG_BIT;
922*4e1bc9a0SAchim Leubner           }
923*4e1bc9a0SAchim Leubner 
924*4e1bc9a0SAchim Leubner           /* check for skipmask operation */
925*4e1bc9a0SAchim Leubner           if (pIRequest->flag & AGSA_SAS_ENABLE_SKIP_MASK)
926*4e1bc9a0SAchim Leubner           {
927*4e1bc9a0SAchim Leubner             DirDW4 |= AGSA_SKIP_MASK_BIT;
928*4e1bc9a0SAchim Leubner             /* agsaSSPInitiatorRequestIndirect_t skip mask in flag is offset 5  */
929*4e1bc9a0SAchim Leubner             DirDW4 |= (pIRequest->flag & AGSA_SAS_SKIP_MASK_OFFSET) << SHIFT8;
930*4e1bc9a0SAchim Leubner           }
931*4e1bc9a0SAchim Leubner 
932*4e1bc9a0SAchim Leubner 
933*4e1bc9a0SAchim Leubner          /* Configure DWORDS 12-14 */
934*4e1bc9a0SAchim Leubner          if( pIRequest->encrypt.enableEncryptionPerLA && pIRequest->dif.enableDIFPerLA)
935*4e1bc9a0SAchim Leubner          {
936*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 12 */
937*4e1bc9a0SAchim Leubner                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ),
938*4e1bc9a0SAchim Leubner                              pIRequest->encrypt.EncryptionPerLAAddrLo );
939*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 13 */
940*4e1bc9a0SAchim Leubner                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ),
941*4e1bc9a0SAchim Leubner                              pIRequest->dif.DIFPerLAAddrLo );
942*4e1bc9a0SAchim Leubner 
943*4e1bc9a0SAchim Leubner             SA_ASSERT(pIRequest->encrypt.EncryptionPerLAAddrHi == pIRequest->dif.DIFPerLAAddrHi, "EPL DPL hi region must be equal");
944*4e1bc9a0SAchim Leubner 
945*4e1bc9a0SAchim Leubner             if( pIRequest->encrypt.EncryptionPerLAAddrHi != pIRequest->dif.DIFPerLAAddrHi )
946*4e1bc9a0SAchim Leubner             {
947*4e1bc9a0SAchim Leubner 
948*4e1bc9a0SAchim Leubner               SA_DBG1(("saSSPStart: EPL DPL hi region must be equal AGSA_RC_FAILURE\n" ));
949*4e1bc9a0SAchim Leubner               smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "Sa");
950*4e1bc9a0SAchim Leubner               ret = AGSA_RC_FAILURE;
951*4e1bc9a0SAchim Leubner               goto ext;
952*4e1bc9a0SAchim Leubner             }
953*4e1bc9a0SAchim Leubner 
954*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 14 */
955*4e1bc9a0SAchim Leubner                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ),
956*4e1bc9a0SAchim Leubner                              pIRequest->encrypt.EncryptionPerLAAddrHi );
957*4e1bc9a0SAchim Leubner           }
958*4e1bc9a0SAchim Leubner           else if( pIRequest->encrypt.enableEncryptionPerLA)
959*4e1bc9a0SAchim Leubner           {
960*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 12 */
961*4e1bc9a0SAchim Leubner                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ),
962*4e1bc9a0SAchim Leubner                              pIRequest->encrypt.EncryptionPerLAAddrLo );
963*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 13 */
964*4e1bc9a0SAchim Leubner                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ),
965*4e1bc9a0SAchim Leubner                              0);
966*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 14 */
967*4e1bc9a0SAchim Leubner                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ),
968*4e1bc9a0SAchim Leubner                              pIRequest->encrypt.EncryptionPerLAAddrHi );
969*4e1bc9a0SAchim Leubner           }
970*4e1bc9a0SAchim Leubner           else if (pIRequest->dif.enableDIFPerLA) /* configure DIF */
971*4e1bc9a0SAchim Leubner           {
972*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 12 */
973*4e1bc9a0SAchim Leubner                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ),
974*4e1bc9a0SAchim Leubner                              0);
975*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 13 */
976*4e1bc9a0SAchim Leubner                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ),
977*4e1bc9a0SAchim Leubner                              pIRequest->dif.DIFPerLAAddrLo );
978*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 14 */
979*4e1bc9a0SAchim Leubner                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ),
980*4e1bc9a0SAchim Leubner                              pIRequest->dif.DIFPerLAAddrHi);
981*4e1bc9a0SAchim Leubner           }
982*4e1bc9a0SAchim Leubner           else /* Not EPL or DPL  */
983*4e1bc9a0SAchim Leubner           {
984*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 12 */
985*4e1bc9a0SAchim Leubner                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,epl_descL ),
986*4e1bc9a0SAchim Leubner                              0);
987*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 13 */
988*4e1bc9a0SAchim Leubner                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,dpl_descL ),
989*4e1bc9a0SAchim Leubner                              0);
990*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload,                      /* DWORD 14 */
991*4e1bc9a0SAchim Leubner                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t,edpl_descH ),
992*4e1bc9a0SAchim Leubner                              0);
993*4e1bc9a0SAchim Leubner           }
994*4e1bc9a0SAchim Leubner 
995*4e1bc9a0SAchim Leubner           if (pIRequest->flag & AGSA_SAS_ENABLE_DIF)
996*4e1bc9a0SAchim Leubner           {
997*4e1bc9a0SAchim Leubner             bit32 UDTR1_UDTR0_UDT1_UDT0  =  0;
998*4e1bc9a0SAchim Leubner             bit32 UDT5_UDT4_UDT3_UDT2     = 0;
999*4e1bc9a0SAchim Leubner             bit32 UDTR5_UDTR4_UDTR3_UDTR2 = 0;
1000*4e1bc9a0SAchim Leubner 
1001*4e1bc9a0SAchim Leubner             SA_DBG3(("saSSPStart,DIF enableRefBlockCount ref %d enableRefBlockCount  %d enableCrc  %d enableCrcInversion %d\n",
1002*4e1bc9a0SAchim Leubner                 pIRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0,
1003*4e1bc9a0SAchim Leubner                 pIRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0,
1004*4e1bc9a0SAchim Leubner                 pIRequest->dif.flags & DIF_FLAG_BITS_CRC_VER           ? 1 : 0,
1005*4e1bc9a0SAchim Leubner                 pIRequest->dif.flags & DIF_FLAG_BITS_CRC_INV           ? 1 : 0  ));
1006*4e1bc9a0SAchim Leubner 
1007*4e1bc9a0SAchim Leubner             SA_DBG3(("saSSPStart,DIF initialIOSeed %X lbSize %X difAction %X\n",
1008*4e1bc9a0SAchim Leubner                 pIRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? 1 : 0,
1009*4e1bc9a0SAchim Leubner                 (pIRequest->dif.flags & DIF_FLAG_BITS_BLOCKSIZE_MASK) >> DIF_FLAG_BITS_BLOCKSIZE_SHIFT,
1010*4e1bc9a0SAchim Leubner                 pIRequest->dif.flags & DIF_FLAG_BITS_ACTION  ));
1011*4e1bc9a0SAchim Leubner 
1012*4e1bc9a0SAchim Leubner             SA_DBG3(("saSSPStart,DIF udtArray %2X %2X %2X %2X %2X %2X\n",
1013*4e1bc9a0SAchim Leubner                 pIRequest->dif.udtArray[0],
1014*4e1bc9a0SAchim Leubner                 pIRequest->dif.udtArray[1],
1015*4e1bc9a0SAchim Leubner                 pIRequest->dif.udtArray[2],
1016*4e1bc9a0SAchim Leubner                 pIRequest->dif.udtArray[3],
1017*4e1bc9a0SAchim Leubner                 pIRequest->dif.udtArray[4],
1018*4e1bc9a0SAchim Leubner                 pIRequest->dif.udtArray[5]));
1019*4e1bc9a0SAchim Leubner 
1020*4e1bc9a0SAchim Leubner             SA_DBG3(("saSSPStart,DIF udrtArray %2X %2X %2X %2X %2X %2X\n",
1021*4e1bc9a0SAchim Leubner                 pIRequest->dif.udrtArray[0],
1022*4e1bc9a0SAchim Leubner                 pIRequest->dif.udrtArray[1],
1023*4e1bc9a0SAchim Leubner                 pIRequest->dif.udrtArray[2],
1024*4e1bc9a0SAchim Leubner                 pIRequest->dif.udrtArray[3],
1025*4e1bc9a0SAchim Leubner                 pIRequest->dif.udrtArray[4],
1026*4e1bc9a0SAchim Leubner                 pIRequest->dif.udrtArray[5]));
1027*4e1bc9a0SAchim Leubner 
1028*4e1bc9a0SAchim Leubner             SA_DBG3(("saSSPStart,DIF tagUpdateMask %X tagVerifyMask %X DIFPerLAAddrLo %X DIFPerLAAddrHi %X\n",
1029*4e1bc9a0SAchim Leubner                 (pIRequest->dif.flags & DIF_FLAG_BITS_UDTVMASK) >> DIF_FLAG_BITS_UDTV_SHIFT,
1030*4e1bc9a0SAchim Leubner                 (pIRequest->dif.flags & DIF_FLAG_BITS_UDTUPMASK) >> DIF_FLAG_BITS_UDTUPSHIFT,
1031*4e1bc9a0SAchim Leubner                 pIRequest->dif.DIFPerLAAddrLo,
1032*4e1bc9a0SAchim Leubner                 pIRequest->dif.DIFPerLAAddrHi));
1033*4e1bc9a0SAchim Leubner 
1034*4e1bc9a0SAchim Leubner             DirDW4 |= AGSA_DIF_BIT;
1035*4e1bc9a0SAchim Leubner 
1036*4e1bc9a0SAchim Leubner             /* DWORD 15 */
1037*4e1bc9a0SAchim Leubner             SA_DBG3(("saSSPStart, DW 15 DIF_flags 0x%08X\n", pIRequest->dif.flags ));
1038*4e1bc9a0SAchim Leubner 
1039*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload,
1040*4e1bc9a0SAchim Leubner                                OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_flags),
1041*4e1bc9a0SAchim Leubner                                pIRequest->dif.flags);
1042*4e1bc9a0SAchim Leubner 
1043*4e1bc9a0SAchim Leubner             /* Populate the UDT and UDTR bytes as necessary. */
1044*4e1bc9a0SAchim Leubner             if ((pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) != AGSA_DIF_INSERT)
1045*4e1bc9a0SAchim Leubner             {
1046*4e1bc9a0SAchim Leubner                 UDTR1_UDTR0_UDT1_UDT0 = (pIRequest->dif.udtArray[1] << SHIFT8 |
1047*4e1bc9a0SAchim Leubner                                          pIRequest->dif.udtArray[0]);
1048*4e1bc9a0SAchim Leubner                 UDT5_UDT4_UDT3_UDT2   = (pIRequest->dif.udtArray[5] << SHIFT24 |
1049*4e1bc9a0SAchim Leubner                                          pIRequest->dif.udtArray[4] << SHIFT16 |
1050*4e1bc9a0SAchim Leubner                                          pIRequest->dif.udtArray[3] << SHIFT8  |
1051*4e1bc9a0SAchim Leubner                                          pIRequest->dif.udtArray[2]);
1052*4e1bc9a0SAchim Leubner             }
1053*4e1bc9a0SAchim Leubner 
1054*4e1bc9a0SAchim Leubner             if ((pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_INSERT ||
1055*4e1bc9a0SAchim Leubner                 (pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_VERIFY_REPLACE ||
1056*4e1bc9a0SAchim Leubner                 (pIRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_REPLACE_UDT_REPLACE_CRC)
1057*4e1bc9a0SAchim Leubner             {
1058*4e1bc9a0SAchim Leubner                 UDTR1_UDTR0_UDT1_UDT0 |= (pIRequest->dif.udrtArray[1] << SHIFT24 |
1059*4e1bc9a0SAchim Leubner                                           pIRequest->dif.udrtArray[0] << SHIFT16 );
1060*4e1bc9a0SAchim Leubner                 UDTR5_UDTR4_UDTR3_UDTR2 = (pIRequest->dif.udrtArray[5] << SHIFT24 |
1061*4e1bc9a0SAchim Leubner                                            pIRequest->dif.udrtArray[4] << SHIFT16 |
1062*4e1bc9a0SAchim Leubner                                            pIRequest->dif.udrtArray[3] << SHIFT8  |
1063*4e1bc9a0SAchim Leubner                                            pIRequest->dif.udrtArray[2]);
1064*4e1bc9a0SAchim Leubner             }
1065*4e1bc9a0SAchim Leubner 
1066*4e1bc9a0SAchim Leubner             /* DWORD 16 is UDT3, UDT2, UDT1 and UDT0 */
1067*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload,
1068*4e1bc9a0SAchim Leubner                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, udt),
1069*4e1bc9a0SAchim Leubner                              UDTR1_UDTR0_UDT1_UDT0);
1070*4e1bc9a0SAchim Leubner 
1071*4e1bc9a0SAchim Leubner             /* DWORD 17 is UDT5, UDT4, UDT3 and UDT2 */
1072*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload,
1073*4e1bc9a0SAchim Leubner                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, udtReplacementLo),
1074*4e1bc9a0SAchim Leubner                              UDT5_UDT4_UDT3_UDT2);
1075*4e1bc9a0SAchim Leubner 
1076*4e1bc9a0SAchim Leubner             /* DWORD 18 is UDTR5, UDTR4, UDTR3 and UDTR2 */
1077*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload,
1078*4e1bc9a0SAchim Leubner                              OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, udtReplacementHi),
1079*4e1bc9a0SAchim Leubner                              UDTR5_UDTR4_UDTR3_UDTR2);
1080*4e1bc9a0SAchim Leubner 
1081*4e1bc9a0SAchim Leubner             /* DWORD 19 */
1082*4e1bc9a0SAchim Leubner             /* Get IOS IOSeed enable bit */
1083*4e1bc9a0SAchim Leubner             if( pIRequest->dif.enableDIFPerLA ||
1084*4e1bc9a0SAchim Leubner                (pIRequest->dif.flags & DIF_FLAG_BITS_CUST_APP_TAG) )
1085*4e1bc9a0SAchim Leubner             {
1086*4e1bc9a0SAchim Leubner                 OSSA_WRITE_LE_32(agRoot, pPayload,
1087*4e1bc9a0SAchim Leubner                                  OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_seed),
1088*4e1bc9a0SAchim Leubner                                 ((pIRequest->dif.DIFPerLARegion0SecCount << SHIFT16) |
1089*4e1bc9a0SAchim Leubner                                  (pIRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? pIRequest->dif.initialIOSeed : 0 )));
1090*4e1bc9a0SAchim Leubner             }
1091*4e1bc9a0SAchim Leubner             else
1092*4e1bc9a0SAchim Leubner             {
1093*4e1bc9a0SAchim Leubner               if (pIRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED)
1094*4e1bc9a0SAchim Leubner               {
1095*4e1bc9a0SAchim Leubner                 OSSA_WRITE_LE_32(agRoot, pPayload,
1096*4e1bc9a0SAchim Leubner                                  OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_seed),
1097*4e1bc9a0SAchim Leubner                                  pIRequest->dif.initialIOSeed );
1098*4e1bc9a0SAchim Leubner               }
1099*4e1bc9a0SAchim Leubner               else
1100*4e1bc9a0SAchim Leubner               {
1101*4e1bc9a0SAchim Leubner                 OSSA_WRITE_LE_32(agRoot, pPayload,
1102*4e1bc9a0SAchim Leubner                                  OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, DIF_seed),  0 );
1103*4e1bc9a0SAchim Leubner               }
1104*4e1bc9a0SAchim Leubner             }
1105*4e1bc9a0SAchim Leubner           }
1106*4e1bc9a0SAchim Leubner 
1107*4e1bc9a0SAchim Leubner           /* configure encryption */
1108*4e1bc9a0SAchim Leubner           if (pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION)
1109*4e1bc9a0SAchim Leubner           {
1110*4e1bc9a0SAchim Leubner 
1111*4e1bc9a0SAchim Leubner             SA_DBG3(("saSSPStart,ENC dekTable 0x%08X dekIndex 0x%08X\n",
1112*4e1bc9a0SAchim Leubner                 pIRequest->encrypt.dekInfo.dekTable,
1113*4e1bc9a0SAchim Leubner                 pIRequest->encrypt.dekInfo.dekIndex));
1114*4e1bc9a0SAchim Leubner 
1115*4e1bc9a0SAchim Leubner             SA_DBG3(("saSSPStart,ENC kekIndex 0x%08X sectorSizeIndex 0x%08X cipherMode 0x%08X\n",
1116*4e1bc9a0SAchim Leubner                 pIRequest->encrypt.kekIndex,
1117*4e1bc9a0SAchim Leubner                 pIRequest->encrypt.sectorSizeIndex,
1118*4e1bc9a0SAchim Leubner                 pIRequest->encrypt.cipherMode));
1119*4e1bc9a0SAchim Leubner 
1120*4e1bc9a0SAchim Leubner             SA_DBG3(("saSSPStart,ENC keyTag_W0 0x%08X keyTag_W1 0x%08X\n",
1121*4e1bc9a0SAchim Leubner                 pIRequest->encrypt.keyTag_W0,
1122*4e1bc9a0SAchim Leubner                 pIRequest->encrypt.keyTag_W1));
1123*4e1bc9a0SAchim Leubner             SA_DBG3(("saSSPStart,ENC tweakVal_W0 0x%08X tweakVal_W1 0x%08X\n",
1124*4e1bc9a0SAchim Leubner                 pIRequest->encrypt.tweakVal_W0,
1125*4e1bc9a0SAchim Leubner                 pIRequest->encrypt.tweakVal_W1));
1126*4e1bc9a0SAchim Leubner             SA_DBG3(("saSSPStart,ENC tweakVal_W2 0x%08X tweakVal_W3 0x%08X\n",
1127*4e1bc9a0SAchim Leubner                 pIRequest->encrypt.tweakVal_W2,
1128*4e1bc9a0SAchim Leubner                 pIRequest->encrypt.tweakVal_W3));
1129*4e1bc9a0SAchim Leubner 
1130*4e1bc9a0SAchim Leubner               DirDW4 |= AGSA_ENCRYPT_BIT;
1131*4e1bc9a0SAchim Leubner 
1132*4e1bc9a0SAchim Leubner               encryptFlags = 0;
1133*4e1bc9a0SAchim Leubner 
1134*4e1bc9a0SAchim Leubner               if (pIRequest->encrypt.keyTagCheck == agTRUE)
1135*4e1bc9a0SAchim Leubner               {
1136*4e1bc9a0SAchim Leubner                  encryptFlags |= AGSA_ENCRYPT_KEY_TAG_BIT;
1137*4e1bc9a0SAchim Leubner               }
1138*4e1bc9a0SAchim Leubner 
1139*4e1bc9a0SAchim Leubner               if( pIRequest->encrypt.cipherMode == agsaEncryptCipherModeXTS )
1140*4e1bc9a0SAchim Leubner               {
1141*4e1bc9a0SAchim Leubner                 encryptFlags |= AGSA_ENCRYPT_XTS_Mode << SHIFT4;
1142*4e1bc9a0SAchim Leubner               }
1143*4e1bc9a0SAchim Leubner 
1144*4e1bc9a0SAchim Leubner               encryptFlags |= pIRequest->encrypt.dekInfo.dekTable << SHIFT2;
1145*4e1bc9a0SAchim Leubner 
1146*4e1bc9a0SAchim Leubner               /* Always use encryption for DIF fields, skip SKPD */
1147*4e1bc9a0SAchim Leubner 
1148*4e1bc9a0SAchim Leubner               encryptFlags |= (pIRequest->encrypt.dekInfo.dekIndex & 0xFFFFFF) << SHIFT8;
1149*4e1bc9a0SAchim Leubner               /* Configure DWORD 20 */
1150*4e1bc9a0SAchim Leubner               OSSA_WRITE_LE_32(agRoot, pPayload,
1151*4e1bc9a0SAchim Leubner                                OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, encryptFlagsLo),
1152*4e1bc9a0SAchim Leubner                                encryptFlags);
1153*4e1bc9a0SAchim Leubner 
1154*4e1bc9a0SAchim Leubner               encryptFlags = pIRequest->encrypt.sectorSizeIndex;
1155*4e1bc9a0SAchim Leubner 
1156*4e1bc9a0SAchim Leubner               encryptFlags |= (pIRequest->encrypt.kekIndex) << SHIFT5;
1157*4e1bc9a0SAchim Leubner 
1158*4e1bc9a0SAchim Leubner               encryptFlags |= (pIRequest->encrypt.EncryptionPerLRegion0SecCount) << SHIFT16;
1159*4e1bc9a0SAchim Leubner               /* Configure DWORD 21 */
1160*4e1bc9a0SAchim Leubner               OSSA_WRITE_LE_32(agRoot, pPayload,
1161*4e1bc9a0SAchim Leubner                                OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, encryptFlagsHi),
1162*4e1bc9a0SAchim Leubner                                encryptFlags);
1163*4e1bc9a0SAchim Leubner 
1164*4e1bc9a0SAchim Leubner               /* Configure DWORD 22 */
1165*4e1bc9a0SAchim Leubner               OSSA_WRITE_LE_32(agRoot, pPayload,
1166*4e1bc9a0SAchim Leubner                                OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, keyTag_W0),
1167*4e1bc9a0SAchim Leubner                                pIRequest->encrypt.keyTag_W0);
1168*4e1bc9a0SAchim Leubner               /* Configure DWORD 23 */
1169*4e1bc9a0SAchim Leubner               OSSA_WRITE_LE_32(agRoot, pPayload,
1170*4e1bc9a0SAchim Leubner                                OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, keyTag_W1),
1171*4e1bc9a0SAchim Leubner                                pIRequest->encrypt.keyTag_W1);
1172*4e1bc9a0SAchim Leubner 
1173*4e1bc9a0SAchim Leubner               /* Configure DWORD 24 */
1174*4e1bc9a0SAchim Leubner               OSSA_WRITE_LE_32(agRoot, pPayload,
1175*4e1bc9a0SAchim Leubner                                OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W0),
1176*4e1bc9a0SAchim Leubner                                pIRequest->encrypt.tweakVal_W0);
1177*4e1bc9a0SAchim Leubner               /* Configure DWORD 25 */
1178*4e1bc9a0SAchim Leubner               OSSA_WRITE_LE_32(agRoot, pPayload,
1179*4e1bc9a0SAchim Leubner                                OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W1),
1180*4e1bc9a0SAchim Leubner                                pIRequest->encrypt.tweakVal_W1);
1181*4e1bc9a0SAchim Leubner               /* Configure DWORD 26 */
1182*4e1bc9a0SAchim Leubner               OSSA_WRITE_LE_32(agRoot, pPayload,
1183*4e1bc9a0SAchim Leubner                                OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W2),
1184*4e1bc9a0SAchim Leubner                                pIRequest->encrypt.tweakVal_W2);
1185*4e1bc9a0SAchim Leubner               /* Configure DWORD 27 */
1186*4e1bc9a0SAchim Leubner               OSSA_WRITE_LE_32(agRoot, pPayload,
1187*4e1bc9a0SAchim Leubner                                OSSA_OFFSET_OF(agsaSSPIniEncryptIOStartCmd_t, tweakVal_W3),
1188*4e1bc9a0SAchim Leubner                                pIRequest->encrypt.tweakVal_W3);
1189*4e1bc9a0SAchim Leubner           }
1190*4e1bc9a0SAchim Leubner 
1191*4e1bc9a0SAchim Leubner           /* Setup SGL */
1192*4e1bc9a0SAchim Leubner           if (pIRequest->dataLength)
1193*4e1bc9a0SAchim Leubner           {
1194*4e1bc9a0SAchim Leubner             pSgl = &(pIRequest->agSgl);
1195*4e1bc9a0SAchim Leubner 
1196*4e1bc9a0SAchim Leubner             SA_DBG3(("saSSPStart:opCode %X agSgl %08x:%08x (%x/%x)\n",opCode,
1197*4e1bc9a0SAchim Leubner                 pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved));
1198*4e1bc9a0SAchim Leubner 
1199*4e1bc9a0SAchim Leubner             /* Get DIF PER LA flag */
1200*4e1bc9a0SAchim Leubner             DirDW4 |= (pIRequest->dif.enableDIFPerLA ? (1 << SHIFT7) : 0);
1201*4e1bc9a0SAchim Leubner             DirDW4 |= (pIRequest->encrypt.enableEncryptionPerLA ? ( 1 << SHIFT12 ) : 0);
1202*4e1bc9a0SAchim Leubner             /* Configure DWORD 4 */
1203*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dirMTlr), DirDW4);
1204*4e1bc9a0SAchim Leubner 
1205*4e1bc9a0SAchim Leubner             if (opCode == OPC_INB_SSP_DIF_ENC_OPSTART)
1206*4e1bc9a0SAchim Leubner             {
1207*4e1bc9a0SAchim Leubner               /* Configure DWORD 28 */
1208*4e1bc9a0SAchim Leubner               pEncryptPayload->AddrLow0 = pSgl->sgLower;
1209*4e1bc9a0SAchim Leubner               /* Configure DWORD 29 */
1210*4e1bc9a0SAchim Leubner               pEncryptPayload->AddrHi0 = pSgl->sgUpper;
1211*4e1bc9a0SAchim Leubner               /* Configure DWORD 30 */
1212*4e1bc9a0SAchim Leubner               pEncryptPayload->Len0 = pSgl->len;
1213*4e1bc9a0SAchim Leubner               /* Configure DWORD 31 */
1214*4e1bc9a0SAchim Leubner               pEncryptPayload->E0 = pSgl->extReserved;
1215*4e1bc9a0SAchim Leubner             }
1216*4e1bc9a0SAchim Leubner             else
1217*4e1bc9a0SAchim Leubner             {
1218*4e1bc9a0SAchim Leubner               pPayload->AddrLow0 = pSgl->sgLower;
1219*4e1bc9a0SAchim Leubner               pPayload->AddrHi0 = pSgl->sgUpper;
1220*4e1bc9a0SAchim Leubner               pPayload->Len0 = pSgl->len;
1221*4e1bc9a0SAchim Leubner               pPayload->E0 = pSgl->extReserved;
1222*4e1bc9a0SAchim Leubner             }
1223*4e1bc9a0SAchim Leubner           }
1224*4e1bc9a0SAchim Leubner           else
1225*4e1bc9a0SAchim Leubner           {
1226*4e1bc9a0SAchim Leubner             /* no data transfer */
1227*4e1bc9a0SAchim Leubner             /* Configure DWORD 4 */
1228*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniIOStartCmd_t, dirMTlr), DirDW4);
1229*4e1bc9a0SAchim Leubner 
1230*4e1bc9a0SAchim Leubner             if (opCode == OPC_INB_SSP_DIF_ENC_OPSTART)
1231*4e1bc9a0SAchim Leubner             {
1232*4e1bc9a0SAchim Leubner                   pEncryptPayload = (agsaSSPIniEncryptIOStartCmd_t *) pPayload;
1233*4e1bc9a0SAchim Leubner 
1234*4e1bc9a0SAchim Leubner                   pEncryptPayload->AddrLow0 = 0;
1235*4e1bc9a0SAchim Leubner                   pEncryptPayload->AddrHi0 = 0;
1236*4e1bc9a0SAchim Leubner                   pEncryptPayload->Len0 = 0;
1237*4e1bc9a0SAchim Leubner                   pEncryptPayload->E0 = 0;
1238*4e1bc9a0SAchim Leubner             }
1239*4e1bc9a0SAchim Leubner             else
1240*4e1bc9a0SAchim Leubner             {
1241*4e1bc9a0SAchim Leubner                 pPayload->AddrLow0 = 0;
1242*4e1bc9a0SAchim Leubner                 pPayload->AddrHi0 = 0;
1243*4e1bc9a0SAchim Leubner                 pPayload->Len0 = 0;
1244*4e1bc9a0SAchim Leubner                 pPayload->E0 = 0;
1245*4e1bc9a0SAchim Leubner             }
1246*4e1bc9a0SAchim Leubner           }
1247*4e1bc9a0SAchim Leubner 
1248*4e1bc9a0SAchim Leubner           /* post the IOMB to SPC */
1249*4e1bc9a0SAchim Leubner #ifdef LOOPBACK_MPI
1250*4e1bc9a0SAchim Leubner           if (loopback)
1251*4e1bc9a0SAchim Leubner             ret = mpiMsgProduceOQ(circularOQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_OUB_SSP_COMP, outq, (bit8)circularQ->priority);
1252*4e1bc9a0SAchim Leubner           else
1253*4e1bc9a0SAchim Leubner #endif /* LOOPBACK_MPI */
1254*4e1bc9a0SAchim Leubner           ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, opCode, outq, (bit8)circularQ->priority);
1255*4e1bc9a0SAchim Leubner           if (AGSA_RC_FAILURE == ret)
1256*4e1bc9a0SAchim Leubner           {
1257*4e1bc9a0SAchim Leubner             SA_DBG1(("saSSPStart, error when post SSP IOMB\n"));
1258*4e1bc9a0SAchim Leubner             ret = AGSA_RC_FAILURE;
1259*4e1bc9a0SAchim Leubner           }
1260*4e1bc9a0SAchim Leubner         }
1261*4e1bc9a0SAchim Leubner         else
1262*4e1bc9a0SAchim Leubner         {
1263*4e1bc9a0SAchim Leubner           /* additionalCdbLen is not zero and type is Ext - use EXT mode */
1264*4e1bc9a0SAchim Leubner           agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt);
1265*4e1bc9a0SAchim Leubner           agsaSSPIniExtIOStartCmd_t *pPayload = (agsaSSPIniExtIOStartCmd_t *)pMessage;
1266*4e1bc9a0SAchim Leubner           bit32 sspiul;
1267*4e1bc9a0SAchim Leubner 
1268*4e1bc9a0SAchim Leubner           /*
1269*4e1bc9a0SAchim Leubner            * Most fields for the SAS IOMB have the same offset regardless of the actual IOMB used.
1270*4e1bc9a0SAchim Leubner            * Be careful with the scatter/gather lists, encryption and DIF options.
1271*4e1bc9a0SAchim Leubner            */
1272*4e1bc9a0SAchim Leubner           /* CDB > 16 bytes */
1273*4e1bc9a0SAchim Leubner           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, tag), pRequest->HTag);
1274*4e1bc9a0SAchim Leubner           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, deviceId), pDevice->DeviceMapIndex);
1275*4e1bc9a0SAchim Leubner           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, dataLen), pIRequest->dataLength);
1276*4e1bc9a0SAchim Leubner           /* dword (bit7-bit2) ==> bytes (bit7-bit0) */
1277*4e1bc9a0SAchim Leubner           /* setup standard CDB bytes + additional CDB bytes in length field */
1278*4e1bc9a0SAchim Leubner           sspiul = sizeof(agsaSSPCmdInfoUnit_t) +
1279*4e1bc9a0SAchim Leubner                     (pIRequest->sspCmdIUExt.additionalCdbLen & 0xFC);
1280*4e1bc9a0SAchim Leubner           DirDW4 = sspiul << 16;
1281*4e1bc9a0SAchim Leubner           si_memcpy(&pPayload->SSPIu[0], &pIRequest->sspCmdIUExt, sspiul);
1282*4e1bc9a0SAchim Leubner           pPayload->SSPIuLendirMTlr = 0;
1283*4e1bc9a0SAchim Leubner 
1284*4e1bc9a0SAchim Leubner           /* Mask DIR for Read/Write command */
1285*4e1bc9a0SAchim Leubner           DirDW4 |= agRequestType & AGSA_DIR_MASK;
1286*4e1bc9a0SAchim Leubner 
1287*4e1bc9a0SAchim Leubner           /* set TLR */
1288*4e1bc9a0SAchim Leubner           DirDW4 |= pIRequest->flag & TLR_MASK;
1289*4e1bc9a0SAchim Leubner           if (agRequestType & AGSA_MSG)
1290*4e1bc9a0SAchim Leubner           {
1291*4e1bc9a0SAchim Leubner             /* set M bit */
1292*4e1bc9a0SAchim Leubner             DirDW4 |= AGSA_MSG_BIT;
1293*4e1bc9a0SAchim Leubner           }
1294*4e1bc9a0SAchim Leubner 
1295*4e1bc9a0SAchim Leubner           /* check for skipmask operation */
1296*4e1bc9a0SAchim Leubner           if (pIRequest->flag & AGSA_SAS_ENABLE_SKIP_MASK)
1297*4e1bc9a0SAchim Leubner           {
1298*4e1bc9a0SAchim Leubner             SA_ASSERT(0, "Mode not supported");
1299*4e1bc9a0SAchim Leubner           }
1300*4e1bc9a0SAchim Leubner 
1301*4e1bc9a0SAchim Leubner           /* configure DIF */
1302*4e1bc9a0SAchim Leubner           if (pIRequest->flag & AGSA_SAS_ENABLE_DIF)
1303*4e1bc9a0SAchim Leubner           {
1304*4e1bc9a0SAchim Leubner             SA_ASSERT(0, "Mode not supported");
1305*4e1bc9a0SAchim Leubner           }
1306*4e1bc9a0SAchim Leubner 
1307*4e1bc9a0SAchim Leubner           /* configure encryption */
1308*4e1bc9a0SAchim Leubner           if (pIRequest->flag & AGSA_SAS_ENABLE_ENCRYPTION)
1309*4e1bc9a0SAchim Leubner           {
1310*4e1bc9a0SAchim Leubner             SA_ASSERT(0, "Mode not supported");
1311*4e1bc9a0SAchim Leubner           }
1312*4e1bc9a0SAchim Leubner           /* Setup SGL */
1313*4e1bc9a0SAchim Leubner           if (pIRequest->dataLength)
1314*4e1bc9a0SAchim Leubner           {
1315*4e1bc9a0SAchim Leubner             pSgl = &(pIRequest->agSgl);
1316*4e1bc9a0SAchim Leubner 
1317*4e1bc9a0SAchim Leubner             SA_DBG3(("saSSPStart: Ext mode, agSgl %08x:%08x (%x/%x)\n",
1318*4e1bc9a0SAchim Leubner               pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved));
1319*4e1bc9a0SAchim Leubner 
1320*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, SSPIuLendirMTlr), DirDW4);
1321*4e1bc9a0SAchim Leubner 
1322*4e1bc9a0SAchim Leubner              if (opCode == OPC_INB_SSP_DIF_ENC_OPSTART)
1323*4e1bc9a0SAchim Leubner             {
1324*4e1bc9a0SAchim Leubner                 si_memcpy((&((agsaSSPIniEncryptIOStartCmd_t *)(pPayload))->AddrLow0), pSgl, sizeof(agsaSgl_t));
1325*4e1bc9a0SAchim Leubner             }
1326*4e1bc9a0SAchim Leubner             else
1327*4e1bc9a0SAchim Leubner             {
1328*4e1bc9a0SAchim Leubner                 si_memcpy((&(pPayload->SSPIu[0]) + sspiul), pSgl, sizeof(agsaSgl_t));
1329*4e1bc9a0SAchim Leubner             }
1330*4e1bc9a0SAchim Leubner           }
1331*4e1bc9a0SAchim Leubner           else
1332*4e1bc9a0SAchim Leubner           {
1333*4e1bc9a0SAchim Leubner             /* no data transfer */
1334*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniExtIOStartCmd_t, SSPIuLendirMTlr), DirDW4);
1335*4e1bc9a0SAchim Leubner             pPayload->dataLen = 0;
1336*4e1bc9a0SAchim Leubner           }
1337*4e1bc9a0SAchim Leubner 
1338*4e1bc9a0SAchim Leubner           /* post the IOMB to SPC */
1339*4e1bc9a0SAchim Leubner           if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, opCode, outq,(bit8)circularQ->priority ))
1340*4e1bc9a0SAchim Leubner           {
1341*4e1bc9a0SAchim Leubner             SA_DBG1(("saSSPStart, error when post SSP Ext IOMB\n"));
1342*4e1bc9a0SAchim Leubner             ret = AGSA_RC_FAILURE;
1343*4e1bc9a0SAchim Leubner           }
1344*4e1bc9a0SAchim Leubner         }
1345*4e1bc9a0SAchim Leubner         break;
1346*4e1bc9a0SAchim Leubner       }
1347*4e1bc9a0SAchim Leubner       case AGSA_SSP_TASK_MGNT_REQ:
1348*4e1bc9a0SAchim Leubner       case AGSA_SSP_TASK_MGNT_REQ_M:
1349*4e1bc9a0SAchim Leubner       {
1350*4e1bc9a0SAchim Leubner         agsaIORequestDesc_t *pTMRequestToAbort = agNULL;
1351*4e1bc9a0SAchim Leubner         agsaSSPIniTMStartCmd_t *pPayload = (agsaSSPIniTMStartCmd_t *)pMessage;
1352*4e1bc9a0SAchim Leubner 
1353*4e1bc9a0SAchim Leubner         if (agRequestType & AGSA_MSG)
1354*4e1bc9a0SAchim Leubner         {
1355*4e1bc9a0SAchim Leubner           /* set M bit */
1356*4e1bc9a0SAchim Leubner           DirDW4 = AGSA_MSG_BIT;
1357*4e1bc9a0SAchim Leubner         }
1358*4e1bc9a0SAchim Leubner 
1359*4e1bc9a0SAchim Leubner         /* set DS and ADS bit */
1360*4e1bc9a0SAchim Leubner         DirDW4 |= (agRequestBody->sspTaskMgntReq.tmOption & 0x3) << 3;
1361*4e1bc9a0SAchim Leubner 
1362*4e1bc9a0SAchim Leubner         /* Prepare the SSP TASK Management payload */
1363*4e1bc9a0SAchim Leubner         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, tag), pRequest->HTag);
1364*4e1bc9a0SAchim Leubner         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, deviceId), pDevice->DeviceMapIndex);
1365*4e1bc9a0SAchim Leubner         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, relatedTag), agRequestBody->sspTaskMgntReq.tagOfTaskToBeManaged);
1366*4e1bc9a0SAchim Leubner         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, TMfunction), agRequestBody->sspTaskMgntReq.taskMgntFunction);
1367*4e1bc9a0SAchim Leubner         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, dsAdsMReport), DirDW4);
1368*4e1bc9a0SAchim Leubner         pPayload->lun[0] = agRequestBody->sspTaskMgntReq.lun[0];
1369*4e1bc9a0SAchim Leubner         pPayload->lun[1] = agRequestBody->sspTaskMgntReq.lun[1];
1370*4e1bc9a0SAchim Leubner         pPayload->lun[2] = agRequestBody->sspTaskMgntReq.lun[2];
1371*4e1bc9a0SAchim Leubner         pPayload->lun[3] = agRequestBody->sspTaskMgntReq.lun[3];
1372*4e1bc9a0SAchim Leubner         pPayload->lun[4] = agRequestBody->sspTaskMgntReq.lun[4];
1373*4e1bc9a0SAchim Leubner         pPayload->lun[5] = agRequestBody->sspTaskMgntReq.lun[5];
1374*4e1bc9a0SAchim Leubner         pPayload->lun[6] = agRequestBody->sspTaskMgntReq.lun[6];
1375*4e1bc9a0SAchim Leubner         pPayload->lun[7] = agRequestBody->sspTaskMgntReq.lun[7];
1376*4e1bc9a0SAchim Leubner 
1377*4e1bc9a0SAchim Leubner         if (agTMRequest)
1378*4e1bc9a0SAchim Leubner         {
1379*4e1bc9a0SAchim Leubner           pTMRequestToAbort = (agsaIORequestDesc_t *)agTMRequest->sdkData;
1380*4e1bc9a0SAchim Leubner           if (pTMRequestToAbort)
1381*4e1bc9a0SAchim Leubner           {
1382*4e1bc9a0SAchim Leubner             OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPIniTMStartCmd_t, relatedTag), pTMRequestToAbort->HTag);
1383*4e1bc9a0SAchim Leubner           }
1384*4e1bc9a0SAchim Leubner         }
1385*4e1bc9a0SAchim Leubner 
1386*4e1bc9a0SAchim Leubner         SA_DBG1(("saSSPStart, HTAG 0x%x TM function 0x%x Tag-to-be-aborted 0x%x deviceId 0x%x\n",
1387*4e1bc9a0SAchim Leubner                   pPayload->tag, pPayload->TMfunction, pPayload->relatedTag, pPayload->deviceId));
1388*4e1bc9a0SAchim Leubner 
1389*4e1bc9a0SAchim Leubner         siDumpActiveIORequests(agRoot, saRoot->swConfig.maxActiveIOs);
1390*4e1bc9a0SAchim Leubner 
1391*4e1bc9a0SAchim Leubner         /* post the IOMB to SPC */
1392*4e1bc9a0SAchim Leubner         if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSPINITMSTART, outq, (bit8)circularQ->priority))
1393*4e1bc9a0SAchim Leubner         {
1394*4e1bc9a0SAchim Leubner           SA_DBG1(("saSSPStart, error when post TM IOMB\n"));
1395*4e1bc9a0SAchim Leubner           ret = AGSA_RC_FAILURE;
1396*4e1bc9a0SAchim Leubner         }
1397*4e1bc9a0SAchim Leubner 
1398*4e1bc9a0SAchim Leubner         break;
1399*4e1bc9a0SAchim Leubner       }
1400*4e1bc9a0SAchim Leubner       case AGSA_SSP_TGT_READ_DATA:
1401*4e1bc9a0SAchim Leubner       case AGSA_SSP_TGT_READ_GOOD_RESP:
1402*4e1bc9a0SAchim Leubner       case AGSA_SSP_TGT_WRITE_DATA:
1403*4e1bc9a0SAchim Leubner       case AGSA_SSP_TGT_WRITE_GOOD_RESP:
1404*4e1bc9a0SAchim Leubner       {
1405*4e1bc9a0SAchim Leubner         agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq);
1406*4e1bc9a0SAchim Leubner         agsaSSPTgtIOStartCmd_t *pPayload = (agsaSSPTgtIOStartCmd_t *)pMessage;
1407*4e1bc9a0SAchim Leubner         bit32 DirDW5 = 0;
1408*4e1bc9a0SAchim Leubner         /* Prepare the SSP TGT IO Start payload */
1409*4e1bc9a0SAchim Leubner         /* Configure DWORD 1 */
1410*4e1bc9a0SAchim Leubner         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, tag), pRequest->HTag);
1411*4e1bc9a0SAchim Leubner         /* Configure DWORD 2 */
1412*4e1bc9a0SAchim Leubner         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, deviceId), pDevice->DeviceMapIndex);
1413*4e1bc9a0SAchim Leubner         /* Configure DWORD 3 */
1414*4e1bc9a0SAchim Leubner         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, dataLen), pTRequest->dataLength);
1415*4e1bc9a0SAchim Leubner         /* Configure DWORD 4 */
1416*4e1bc9a0SAchim Leubner         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, dataOffset), pTRequest->offset);
1417*4e1bc9a0SAchim Leubner 
1418*4e1bc9a0SAchim Leubner         SA_DBG3(("saSSPStart, sspOption %08X\n", pTRequest->sspOption ));
1419*4e1bc9a0SAchim Leubner 
1420*4e1bc9a0SAchim Leubner         /* Mask DIR and AutoGR bits for Read/Write command */
1421*4e1bc9a0SAchim Leubner         DirDW5 = (agRequestType & (AGSA_DIR_MASK | AGSA_AUTO_MASK)) | (pTRequest->agTag << 16);
1422*4e1bc9a0SAchim Leubner 
1423*4e1bc9a0SAchim Leubner         if (pTRequest->sspOption & SSP_OPTION_DIF )
1424*4e1bc9a0SAchim Leubner         {
1425*4e1bc9a0SAchim Leubner           bit32 UDTR1_UDTR0_UDT1_UDT0   = 0;
1426*4e1bc9a0SAchim Leubner           bit32 UDT5_UDT4_UDT3_UDT2     = 0;
1427*4e1bc9a0SAchim Leubner           bit32 UDTR5_UDTR4_UDTR3_UDTR2 = 0;
1428*4e1bc9a0SAchim Leubner           SA_DBG3(("saSSPStart,tgt DIF enableRefBlockCount ref %d enableRefBlockCount  %d enableCrc  %d enableCrcInversion %d\n",
1429*4e1bc9a0SAchim Leubner               pTRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0,
1430*4e1bc9a0SAchim Leubner               pTRequest->dif.flags & DIF_FLAG_BITS_UDTR_REF_BLKCOUNT ? 1 : 0,
1431*4e1bc9a0SAchim Leubner               pTRequest->dif.flags & DIF_FLAG_BITS_CRC_VER           ? 1 : 0,
1432*4e1bc9a0SAchim Leubner               pTRequest->dif.flags & DIF_FLAG_BITS_CRC_INV           ? 1 : 0  ));
1433*4e1bc9a0SAchim Leubner 
1434*4e1bc9a0SAchim Leubner           SA_DBG3(("saSSPStart,tgt DIF initialIOSeed %X lbSize %X difAction %X\n",
1435*4e1bc9a0SAchim Leubner               pTRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? 1 : 0,
1436*4e1bc9a0SAchim Leubner               (pTRequest->dif.flags & DIF_FLAG_BITS_BLOCKSIZE_MASK ) >> DIF_FLAG_BITS_BLOCKSIZE_SHIFT,
1437*4e1bc9a0SAchim Leubner               pTRequest->dif.flags & DIF_FLAG_BITS_ACTION  ));
1438*4e1bc9a0SAchim Leubner 
1439*4e1bc9a0SAchim Leubner           SA_DBG3(("saSSPStart,tgt DIF udtArray %2X %2X %2X %2X %2X %2X\n",
1440*4e1bc9a0SAchim Leubner               pTRequest->dif.udtArray[0],
1441*4e1bc9a0SAchim Leubner               pTRequest->dif.udtArray[1],
1442*4e1bc9a0SAchim Leubner               pTRequest->dif.udtArray[2],
1443*4e1bc9a0SAchim Leubner               pTRequest->dif.udtArray[3],
1444*4e1bc9a0SAchim Leubner               pTRequest->dif.udtArray[4],
1445*4e1bc9a0SAchim Leubner               pTRequest->dif.udtArray[5]));
1446*4e1bc9a0SAchim Leubner 
1447*4e1bc9a0SAchim Leubner           SA_DBG3(("saSSPStart,tgt DIF udrtArray %2X %2X %2X %2X %2X %2X\n",
1448*4e1bc9a0SAchim Leubner               pTRequest->dif.udrtArray[0],
1449*4e1bc9a0SAchim Leubner               pTRequest->dif.udrtArray[1],
1450*4e1bc9a0SAchim Leubner               pTRequest->dif.udrtArray[2],
1451*4e1bc9a0SAchim Leubner               pTRequest->dif.udrtArray[3],
1452*4e1bc9a0SAchim Leubner               pTRequest->dif.udrtArray[4],
1453*4e1bc9a0SAchim Leubner               pTRequest->dif.udrtArray[5]));
1454*4e1bc9a0SAchim Leubner 
1455*4e1bc9a0SAchim Leubner           SA_DBG3(("saSSPStart,tgt DIF tagUpdateMask %X tagVerifyMask %X DIFPerLAAddrLo %X DIFPerLAAddrHi %X\n",
1456*4e1bc9a0SAchim Leubner               (pTRequest->dif.flags & DIF_FLAG_BITS_UDTVMASK) >> DIF_FLAG_BITS_UDTV_SHIFT,
1457*4e1bc9a0SAchim Leubner               (pTRequest->dif.flags & DIF_FLAG_BITS_UDTUPMASK) >> DIF_FLAG_BITS_UDTUPSHIFT,
1458*4e1bc9a0SAchim Leubner               pTRequest->dif.DIFPerLAAddrLo,
1459*4e1bc9a0SAchim Leubner               pTRequest->dif.DIFPerLAAddrHi));
1460*4e1bc9a0SAchim Leubner 
1461*4e1bc9a0SAchim Leubner           DirDW5 |= AGSA_SSP_TGT_BITS_DEE_DIF;
1462*4e1bc9a0SAchim Leubner 
1463*4e1bc9a0SAchim Leubner 
1464*4e1bc9a0SAchim Leubner           SA_DBG3(("saSSPStart,tgt  DW 15 DIF_flags 0x%08X\n", pTRequest->dif.flags ));
1465*4e1bc9a0SAchim Leubner 
1466*4e1bc9a0SAchim Leubner           OSSA_WRITE_LE_32(agRoot, pPayload,
1467*4e1bc9a0SAchim Leubner                              OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_flags),
1468*4e1bc9a0SAchim Leubner                              pTRequest->dif.flags);
1469*4e1bc9a0SAchim Leubner 
1470*4e1bc9a0SAchim Leubner             /* Populate the UDT and UDTR bytes as necessary. */
1471*4e1bc9a0SAchim Leubner             if ((pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) != AGSA_DIF_INSERT)
1472*4e1bc9a0SAchim Leubner             {
1473*4e1bc9a0SAchim Leubner                 UDTR1_UDTR0_UDT1_UDT0 = (pTRequest->dif.udtArray[1] << SHIFT8 |
1474*4e1bc9a0SAchim Leubner                                          pTRequest->dif.udtArray[0]);
1475*4e1bc9a0SAchim Leubner                 UDT5_UDT4_UDT3_UDT2   = (pTRequest->dif.udtArray[5] << SHIFT24 |
1476*4e1bc9a0SAchim Leubner                                          pTRequest->dif.udtArray[4] << SHIFT16 |
1477*4e1bc9a0SAchim Leubner                                          pTRequest->dif.udtArray[3] << SHIFT8  |
1478*4e1bc9a0SAchim Leubner                                          pTRequest->dif.udtArray[2]);
1479*4e1bc9a0SAchim Leubner             }
1480*4e1bc9a0SAchim Leubner 
1481*4e1bc9a0SAchim Leubner             if ((pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_INSERT ||
1482*4e1bc9a0SAchim Leubner                 (pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_VERIFY_REPLACE ||
1483*4e1bc9a0SAchim Leubner                 (pTRequest->dif.flags & DIF_FLAG_BITS_ACTION) == AGSA_DIF_REPLACE_UDT_REPLACE_CRC)
1484*4e1bc9a0SAchim Leubner             {
1485*4e1bc9a0SAchim Leubner                 UDTR1_UDTR0_UDT1_UDT0 |= (pTRequest->dif.udrtArray[1] << SHIFT24 |
1486*4e1bc9a0SAchim Leubner                                           pTRequest->dif.udrtArray[0] << SHIFT16 );
1487*4e1bc9a0SAchim Leubner                 UDTR5_UDTR4_UDTR3_UDTR2 = (pTRequest->dif.udrtArray[5] << SHIFT24 |
1488*4e1bc9a0SAchim Leubner                                            pTRequest->dif.udrtArray[4] << SHIFT16 |
1489*4e1bc9a0SAchim Leubner                                            pTRequest->dif.udrtArray[3] << SHIFT8  |
1490*4e1bc9a0SAchim Leubner                                            pTRequest->dif.udrtArray[2]);
1491*4e1bc9a0SAchim Leubner             }
1492*4e1bc9a0SAchim Leubner           /* DWORD 8 is UDTR1, UDTR0, UDT1 and UDT0 */
1493*4e1bc9a0SAchim Leubner           OSSA_WRITE_LE_32(agRoot, pPayload,
1494*4e1bc9a0SAchim Leubner                            OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, udt),
1495*4e1bc9a0SAchim Leubner                            UDTR1_UDTR0_UDT1_UDT0);
1496*4e1bc9a0SAchim Leubner 
1497*4e1bc9a0SAchim Leubner           /* DWORD 9 is UDT5, UDT4, UDT3 and UDT2 */
1498*4e1bc9a0SAchim Leubner           OSSA_WRITE_LE_32(agRoot, pPayload,
1499*4e1bc9a0SAchim Leubner                            OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, udtReplacementLo),
1500*4e1bc9a0SAchim Leubner                            UDT5_UDT4_UDT3_UDT2);
1501*4e1bc9a0SAchim Leubner 
1502*4e1bc9a0SAchim Leubner           /* DWORD 10 is UDTR5, UDTR4, UDTR3 and UDTR2 */
1503*4e1bc9a0SAchim Leubner           OSSA_WRITE_LE_32(agRoot, pPayload,
1504*4e1bc9a0SAchim Leubner                            OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, udtReplacementHi),
1505*4e1bc9a0SAchim Leubner                            UDTR5_UDTR4_UDTR3_UDTR2);
1506*4e1bc9a0SAchim Leubner           /* DWORD 11 */
1507*4e1bc9a0SAchim Leubner           /* Get IOS IOSeed enable bit */
1508*4e1bc9a0SAchim Leubner           if( pTRequest->dif.flags & DIF_FLAG_BITS_CUST_APP_TAG)
1509*4e1bc9a0SAchim Leubner           {
1510*4e1bc9a0SAchim Leubner               OSSA_WRITE_LE_32(agRoot, pPayload,
1511*4e1bc9a0SAchim Leubner                                OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_seed),
1512*4e1bc9a0SAchim Leubner                                ((pTRequest->dif.DIFPerLARegion0SecCount << SHIFT16) |
1513*4e1bc9a0SAchim Leubner                                (pTRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED ? pTRequest->dif.initialIOSeed : 0 )));
1514*4e1bc9a0SAchim Leubner           }
1515*4e1bc9a0SAchim Leubner           else
1516*4e1bc9a0SAchim Leubner           {
1517*4e1bc9a0SAchim Leubner               /* Get IOS IOSeed enable bit */
1518*4e1bc9a0SAchim Leubner               if (pTRequest->dif.flags & DIF_FLAG_BITS_CRC_SEED)
1519*4e1bc9a0SAchim Leubner               {
1520*4e1bc9a0SAchim Leubner                   OSSA_WRITE_LE_32(agRoot, pPayload,
1521*4e1bc9a0SAchim Leubner                                    OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_seed),
1522*4e1bc9a0SAchim Leubner                                    pTRequest->dif.initialIOSeed );
1523*4e1bc9a0SAchim Leubner               }
1524*4e1bc9a0SAchim Leubner               else
1525*4e1bc9a0SAchim Leubner               {
1526*4e1bc9a0SAchim Leubner                   OSSA_WRITE_LE_32(agRoot, pPayload,
1527*4e1bc9a0SAchim Leubner                                    OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, DIF_seed),  0 );
1528*4e1bc9a0SAchim Leubner               }
1529*4e1bc9a0SAchim Leubner           }
1530*4e1bc9a0SAchim Leubner         }
1531*4e1bc9a0SAchim Leubner 
1532*4e1bc9a0SAchim Leubner         /* Mask DIR and AutoGR bits for Read/Write command */
1533*4e1bc9a0SAchim Leubner         if(pTRequest->sspOption & SSP_OPTION_AUTO_GOOD_RESPONSE)
1534*4e1bc9a0SAchim Leubner         {
1535*4e1bc9a0SAchim Leubner           DirDW5 |= AGSA_SSP_TGT_BITS_AGR;
1536*4e1bc9a0SAchim Leubner         }
1537*4e1bc9a0SAchim Leubner 
1538*4e1bc9a0SAchim Leubner         /* AN, RTE, RDF bits */
1539*4e1bc9a0SAchim Leubner         DirDW5 |= (pTRequest->sspOption & SSP_OPTION_BITS) << 2;
1540*4e1bc9a0SAchim Leubner 
1541*4e1bc9a0SAchim Leubner         /* ODS */
1542*4e1bc9a0SAchim Leubner         if(pTRequest->sspOption & SSP_OPTION_ODS)
1543*4e1bc9a0SAchim Leubner         {
1544*4e1bc9a0SAchim Leubner           DirDW5 |= AGSA_SSP_TGT_BITS_ODS;
1545*4e1bc9a0SAchim Leubner         }
1546*4e1bc9a0SAchim Leubner 
1547*4e1bc9a0SAchim Leubner         /* Setup SGL */
1548*4e1bc9a0SAchim Leubner         if (pTRequest->dataLength)
1549*4e1bc9a0SAchim Leubner         {
1550*4e1bc9a0SAchim Leubner           pSgl = &(pTRequest->agSgl);
1551*4e1bc9a0SAchim Leubner 
1552*4e1bc9a0SAchim Leubner           SA_DBG5(("saSSPStart: agSgl %08x:%08x (%x/%x)\n",
1553*4e1bc9a0SAchim Leubner           pSgl->sgUpper, pSgl->sgLower, pSgl->len, pSgl->extReserved));
1554*4e1bc9a0SAchim Leubner 
1555*4e1bc9a0SAchim Leubner           /* set up dir on the payload */
1556*4e1bc9a0SAchim Leubner           /* Configure DWORD 5 */
1557*4e1bc9a0SAchim Leubner           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, INITagAgrDir), DirDW5);
1558*4e1bc9a0SAchim Leubner 
1559*4e1bc9a0SAchim Leubner           pPayload->AddrLow0 = pSgl->sgLower;
1560*4e1bc9a0SAchim Leubner           pPayload->AddrHi0 = pSgl->sgUpper;
1561*4e1bc9a0SAchim Leubner           pPayload->Len0 = pSgl->len;
1562*4e1bc9a0SAchim Leubner           pPayload->E0 = pSgl->extReserved;
1563*4e1bc9a0SAchim Leubner         }
1564*4e1bc9a0SAchim Leubner         else
1565*4e1bc9a0SAchim Leubner         {
1566*4e1bc9a0SAchim Leubner           /* no data transfer */
1567*4e1bc9a0SAchim Leubner           /* Configure DWORD 5 */
1568*4e1bc9a0SAchim Leubner           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t, INITagAgrDir), DirDW5);
1569*4e1bc9a0SAchim Leubner           pPayload->AddrLow0 = 0;
1570*4e1bc9a0SAchim Leubner           pPayload->AddrHi0 = 0;
1571*4e1bc9a0SAchim Leubner           pPayload->Len0 = 0;
1572*4e1bc9a0SAchim Leubner         }
1573*4e1bc9a0SAchim Leubner         /* Configure DWORD 6 */
1574*4e1bc9a0SAchim Leubner         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtIOStartCmd_t,reserved ), 0);
1575*4e1bc9a0SAchim Leubner 
1576*4e1bc9a0SAchim Leubner         /* Build TGT IO START command and send it to SPC */
1577*4e1bc9a0SAchim Leubner         if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSPTGTIOSTART, outq, (bit8)circularQ->priority))
1578*4e1bc9a0SAchim Leubner         {
1579*4e1bc9a0SAchim Leubner           SA_DBG1(("saSSPStart, error when post TGT IOMB\n"));
1580*4e1bc9a0SAchim Leubner           ret = AGSA_RC_FAILURE;
1581*4e1bc9a0SAchim Leubner         }
1582*4e1bc9a0SAchim Leubner 
1583*4e1bc9a0SAchim Leubner         break;
1584*4e1bc9a0SAchim Leubner       }
1585*4e1bc9a0SAchim Leubner       case AGSA_SSP_TGT_CMD_OR_TASK_RSP:
1586*4e1bc9a0SAchim Leubner       {
1587*4e1bc9a0SAchim Leubner         agsaSSPTargetResponse_t *pTResponse = &(agRequestBody->sspTargetResponse);
1588*4e1bc9a0SAchim Leubner         agsaSSPTgtRspStartCmd_t *pPayload = (agsaSSPTgtRspStartCmd_t *)pMessage;
1589*4e1bc9a0SAchim Leubner         bit32 ip, an, ods;
1590*4e1bc9a0SAchim Leubner 
1591*4e1bc9a0SAchim Leubner         if (pTResponse->frameBuf && (pTResponse->respBufLength <= AGSA_MAX_SSPPAYLOAD_VIA_SFO))
1592*4e1bc9a0SAchim Leubner         {
1593*4e1bc9a0SAchim Leubner           ip = 1;
1594*4e1bc9a0SAchim Leubner           si_memcpy(pPayload->reserved, pTResponse->frameBuf, pTResponse->respBufLength);
1595*4e1bc9a0SAchim Leubner         }
1596*4e1bc9a0SAchim Leubner         else
1597*4e1bc9a0SAchim Leubner         {
1598*4e1bc9a0SAchim Leubner           ip = 0;
1599*4e1bc9a0SAchim Leubner           /* NOTE:
1600*4e1bc9a0SAchim Leubner            * 1. reserved field must be ZEROED out. FW depends on it
1601*4e1bc9a0SAchim Leubner            * 2. trusted interface. indirect response buffer must be valid.
1602*4e1bc9a0SAchim Leubner            */
1603*4e1bc9a0SAchim Leubner           si_memset(pPayload->reserved, 0, sizeof(pPayload->reserved));
1604*4e1bc9a0SAchim Leubner           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, AddrLow0), pTResponse->respBufLower);
1605*4e1bc9a0SAchim Leubner           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, AddrHi0), pTResponse->respBufUpper);
1606*4e1bc9a0SAchim Leubner           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, Len0), pTResponse->respBufLength);
1607*4e1bc9a0SAchim Leubner           OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, E0), 0);
1608*4e1bc9a0SAchim Leubner         }
1609*4e1bc9a0SAchim Leubner 
1610*4e1bc9a0SAchim Leubner         /* TLR setting */
1611*4e1bc9a0SAchim Leubner         an = (pTResponse->respOption & RESP_OPTION_BITS);
1612*4e1bc9a0SAchim Leubner         /* ODS */
1613*4e1bc9a0SAchim Leubner         ods = (pTResponse->respOption & RESP_OPTION_ODS);
1614*4e1bc9a0SAchim Leubner 
1615*4e1bc9a0SAchim Leubner         /* Prepare the SSP TGT RESPONSE Start payload */
1616*4e1bc9a0SAchim Leubner         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, tag), pRequest->HTag);
1617*4e1bc9a0SAchim Leubner         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, deviceId), pDevice->DeviceMapIndex);
1618*4e1bc9a0SAchim Leubner         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, RspLen), pTResponse->respBufLength);
1619*4e1bc9a0SAchim Leubner         OSSA_WRITE_LE_32(agRoot, pPayload, OSSA_OFFSET_OF(agsaSSPTgtRspStartCmd_t, INITag_IP_AN),
1620*4e1bc9a0SAchim Leubner           (pTResponse->agTag << SHIFT16) | ods | (ip << SHIFT10) | (an << SHIFT2));
1621*4e1bc9a0SAchim Leubner 
1622*4e1bc9a0SAchim Leubner         /* Build TGT RESPONSE START command and send it to SPC */
1623*4e1bc9a0SAchim Leubner         if (AGSA_RC_FAILURE == mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSPTGTRSPSTART, outq, (bit8)circularQ->priority))
1624*4e1bc9a0SAchim Leubner         {
1625*4e1bc9a0SAchim Leubner           SA_DBG1(("saSSPStart, error when post TGT RSP IOMB\n"));
1626*4e1bc9a0SAchim Leubner           ret = AGSA_RC_FAILURE;
1627*4e1bc9a0SAchim Leubner         }
1628*4e1bc9a0SAchim Leubner 
1629*4e1bc9a0SAchim Leubner         break;
1630*4e1bc9a0SAchim Leubner       }
1631*4e1bc9a0SAchim Leubner       default:
1632*4e1bc9a0SAchim Leubner       {
1633*4e1bc9a0SAchim Leubner         SA_DBG1(("saSSPStart, Unsupported Request IOMB\n"));
1634*4e1bc9a0SAchim Leubner         ret = AGSA_RC_FAILURE;
1635*4e1bc9a0SAchim Leubner         break;
1636*4e1bc9a0SAchim Leubner       }
1637*4e1bc9a0SAchim Leubner     }
1638*4e1bc9a0SAchim Leubner 
1639*4e1bc9a0SAchim Leubner   } /* LL IOrequest available */
1640*4e1bc9a0SAchim Leubner 
1641*4e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
1642*4e1bc9a0SAchim Leubner   ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
1643*4e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
1644*4e1bc9a0SAchim Leubner 
1645*4e1bc9a0SAchim Leubner #ifdef SALL_API_TEST
1646*4e1bc9a0SAchim Leubner   if (ret == AGSA_RC_SUCCESS)
1647*4e1bc9a0SAchim Leubner     saRoot->LLCounters.IOCounter.numSSPStarted++;
1648*4e1bc9a0SAchim Leubner #endif /*SALL_API_TEST  */
1649*4e1bc9a0SAchim Leubner 
1650*4e1bc9a0SAchim Leubner #ifdef LOOPBACK_MPI
1651*4e1bc9a0SAchim Leubner   if (loopback)
1652*4e1bc9a0SAchim Leubner     saRoot->interruptVecIndexBitMap[0] |= (1 << outq);
1653*4e1bc9a0SAchim Leubner #endif /* LOOPBACK_MPI */
1654*4e1bc9a0SAchim Leubner   /* goto have leave and trace point info */
1655*4e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "Sa");
1656*4e1bc9a0SAchim Leubner ext:
1657*4e1bc9a0SAchim Leubner 
1658*4e1bc9a0SAchim Leubner   OSSA_INP_LEAVE(agRoot);
1659*4e1bc9a0SAchim Leubner   return ret;
1660*4e1bc9a0SAchim Leubner }
1661*4e1bc9a0SAchim Leubner 
1662*4e1bc9a0SAchim Leubner /******************************************************************************/
1663*4e1bc9a0SAchim Leubner /*! \brief Abort SSP request
1664*4e1bc9a0SAchim Leubner  *
1665*4e1bc9a0SAchim Leubner  *  Abort SSP request
1666*4e1bc9a0SAchim Leubner  *
1667*4e1bc9a0SAchim Leubner  *  \param agRoot handles for this instance of SAS/SATA LLL
1668*4e1bc9a0SAchim Leubner  *  \param queueNum
1669*4e1bc9a0SAchim Leubner  *  \param agIORequest
1670*4e1bc9a0SAchim Leubner  *  \param agIOToBeAborted
1671*4e1bc9a0SAchim Leubner  *
1672*4e1bc9a0SAchim Leubner  *  \return If request is aborted successfully
1673*4e1bc9a0SAchim Leubner  *          - \e AGSA_RC_SUCCESS request is aborted successfully
1674*4e1bc9a0SAchim Leubner  *          - \e AGSA_RC_FAILURE request is not aborted successfully
1675*4e1bc9a0SAchim Leubner  */
1676*4e1bc9a0SAchim Leubner /*******************************************************************************/
saSSPAbort(agsaRoot_t * agRoot,agsaIORequest_t * agIORequest,bit32 queueNum,agsaDevHandle_t * agDevHandle,bit32 flag,void * abortParam,ossaGenericAbortCB_t agCB)1677*4e1bc9a0SAchim Leubner GLOBAL bit32 saSSPAbort(
1678*4e1bc9a0SAchim Leubner   agsaRoot_t        *agRoot,
1679*4e1bc9a0SAchim Leubner   agsaIORequest_t   *agIORequest,
1680*4e1bc9a0SAchim Leubner   bit32             queueNum,
1681*4e1bc9a0SAchim Leubner   agsaDevHandle_t   *agDevHandle,
1682*4e1bc9a0SAchim Leubner   bit32             flag,
1683*4e1bc9a0SAchim Leubner   void              *abortParam,
1684*4e1bc9a0SAchim Leubner   ossaGenericAbortCB_t  agCB
1685*4e1bc9a0SAchim Leubner   )
1686*4e1bc9a0SAchim Leubner {
1687*4e1bc9a0SAchim Leubner   bit32 ret = AGSA_RC_SUCCESS, retVal;
1688*4e1bc9a0SAchim Leubner   agsaLLRoot_t        *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
1689*4e1bc9a0SAchim Leubner   agsaIORequestDesc_t *pRequest;
1690*4e1bc9a0SAchim Leubner   agsaIORequestDesc_t *pRequestABT = NULL;
1691*4e1bc9a0SAchim Leubner   agsaDeviceDesc_t    *pDevice = NULL;
1692*4e1bc9a0SAchim Leubner   agsaDeviceDesc_t    *pDeviceABT = NULL;
1693*4e1bc9a0SAchim Leubner   agsaPort_t          *pPort = NULL;
1694*4e1bc9a0SAchim Leubner   mpiICQueue_t        *circularQ;
1695*4e1bc9a0SAchim Leubner   void                *pMessage;
1696*4e1bc9a0SAchim Leubner   agsaSSPAbortCmd_t   *payload;
1697*4e1bc9a0SAchim Leubner   agsaIORequest_t     *agIOToBeAborted;
1698*4e1bc9a0SAchim Leubner   bit8                inq, outq;
1699*4e1bc9a0SAchim Leubner   bit32               using_reserved = agFALSE;
1700*4e1bc9a0SAchim Leubner   bit32               flag_copy = flag;
1701*4e1bc9a0SAchim Leubner   smTraceFuncEnter(hpDBG_VERY_LOUD,"Sb");
1702*4e1bc9a0SAchim Leubner 
1703*4e1bc9a0SAchim Leubner   /* sanity check */
1704*4e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agRoot), "");
1705*4e1bc9a0SAchim Leubner   SA_ASSERT((agNULL != agIORequest), "");
1706*4e1bc9a0SAchim Leubner 
1707*4e1bc9a0SAchim Leubner   SA_DBG2(("saSSPAbort: agIORequest %p agDevHandle %p abortParam %p flag 0x%x\n", agIORequest,agDevHandle,abortParam,flag));
1708*4e1bc9a0SAchim Leubner 
1709*4e1bc9a0SAchim Leubner   /* Assign inbound and outbound Buffer */
1710*4e1bc9a0SAchim Leubner   inq = (bit8)(queueNum & MPI_IB_NUM_MASK);
1711*4e1bc9a0SAchim Leubner   outq = (bit8)((queueNum & MPI_OB_NUM_MASK) >> MPI_OB_SHIFT);
1712*4e1bc9a0SAchim Leubner   SA_ASSERT((AGSA_MAX_INBOUND_Q > inq), "The IBQ Number is out of range.");
1713*4e1bc9a0SAchim Leubner 
1714*4e1bc9a0SAchim Leubner #ifdef SA_PRINTOUT_IN_WINDBG
1715*4e1bc9a0SAchim Leubner #ifndef DBG
1716*4e1bc9a0SAchim Leubner         DbgPrint("saSSPAbort flag %d\n", flag );
1717*4e1bc9a0SAchim Leubner #endif /* DBG  */
1718*4e1bc9a0SAchim Leubner #endif /* SA_PRINTOUT_IN_WINDBG  */
1719*4e1bc9a0SAchim Leubner 
1720*4e1bc9a0SAchim Leubner   if( ABORT_SINGLE == (flag & ABORT_MASK) )
1721*4e1bc9a0SAchim Leubner   {
1722*4e1bc9a0SAchim Leubner     agIOToBeAborted = (agsaIORequest_t *)abortParam;
1723*4e1bc9a0SAchim Leubner     /* Get LL IORequest entry for saSSPAbort() */
1724*4e1bc9a0SAchim Leubner     pRequest = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData);
1725*4e1bc9a0SAchim Leubner     if (agNULL == pRequest)
1726*4e1bc9a0SAchim Leubner     {
1727*4e1bc9a0SAchim Leubner       /* no pRequest found - can not Abort */
1728*4e1bc9a0SAchim Leubner       SA_DBG1(("saSSPAbort: ABORT_ALL no pRequest\n"));
1729*4e1bc9a0SAchim Leubner       smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "Sb");
1730*4e1bc9a0SAchim Leubner       return AGSA_RC_FAILURE;
1731*4e1bc9a0SAchim Leubner     }
1732*4e1bc9a0SAchim Leubner     /* Find the device the request sent to */
1733*4e1bc9a0SAchim Leubner     pDevice = pRequest->pDevice;
1734*4e1bc9a0SAchim Leubner     /* Get LL IORequest entry for IOToBeAborted */
1735*4e1bc9a0SAchim Leubner     pRequestABT = (agsaIORequestDesc_t *) (agIOToBeAborted->sdkData);
1736*4e1bc9a0SAchim Leubner     if (agNULL == pRequestABT)
1737*4e1bc9a0SAchim Leubner     {
1738*4e1bc9a0SAchim Leubner       /* The IO to Be Abort is no longer exist */
1739*4e1bc9a0SAchim Leubner       SA_DBG1(("saSSPAbort: ABORT_ALL no pRequestABT\n"));
1740*4e1bc9a0SAchim Leubner       smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "Sb");
1741*4e1bc9a0SAchim Leubner       return AGSA_RC_FAILURE;
1742*4e1bc9a0SAchim Leubner     }
1743*4e1bc9a0SAchim Leubner     /* Find the device the request Abort to */
1744*4e1bc9a0SAchim Leubner     pDeviceABT = pRequestABT->pDevice;
1745*4e1bc9a0SAchim Leubner 
1746*4e1bc9a0SAchim Leubner     if (agNULL == pDeviceABT)
1747*4e1bc9a0SAchim Leubner     {
1748*4e1bc9a0SAchim Leubner       /* no deviceID - can not build IOMB */
1749*4e1bc9a0SAchim Leubner       SA_DBG1(("saSSPAbort: ABORT_ALL no pRequestABT->deviceID\n"));
1750*4e1bc9a0SAchim Leubner       smTraceFuncExit(hpDBG_VERY_LOUD, 'c', "Sb");
1751*4e1bc9a0SAchim Leubner       return AGSA_RC_FAILURE;
1752*4e1bc9a0SAchim Leubner     }
1753*4e1bc9a0SAchim Leubner 
1754*4e1bc9a0SAchim Leubner     if (agNULL != pDevice)
1755*4e1bc9a0SAchim Leubner     {
1756*4e1bc9a0SAchim Leubner       /* Find the port the request was sent to */
1757*4e1bc9a0SAchim Leubner       pPort = pDevice->pPort;
1758*4e1bc9a0SAchim Leubner     }
1759*4e1bc9a0SAchim Leubner     else
1760*4e1bc9a0SAchim Leubner     {
1761*4e1bc9a0SAchim Leubner       /* no deviceID - can not build IOMB */
1762*4e1bc9a0SAchim Leubner       SA_DBG1(("saSSPAbort: ABORT_ALL no deviceID\n"));
1763*4e1bc9a0SAchim Leubner       smTraceFuncExit(hpDBG_VERY_LOUD, 'd', "Sb");
1764*4e1bc9a0SAchim Leubner       return AGSA_RC_FAILURE;
1765*4e1bc9a0SAchim Leubner     }
1766*4e1bc9a0SAchim Leubner 
1767*4e1bc9a0SAchim Leubner     /* Get request from free IORequests */
1768*4e1bc9a0SAchim Leubner     ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1769*4e1bc9a0SAchim Leubner     pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/
1770*4e1bc9a0SAchim Leubner   }
1771*4e1bc9a0SAchim Leubner   else
1772*4e1bc9a0SAchim Leubner   {
1773*4e1bc9a0SAchim Leubner     if (ABORT_ALL == (flag & ABORT_MASK))
1774*4e1bc9a0SAchim Leubner     {
1775*4e1bc9a0SAchim Leubner       /* abort All with Device or Port */
1776*4e1bc9a0SAchim Leubner       /* Find the outgoing port for the device */
1777*4e1bc9a0SAchim Leubner       if (agDevHandle == agNULL)
1778*4e1bc9a0SAchim Leubner       {
1779*4e1bc9a0SAchim Leubner         /* no deviceID - can not build IOMB */
1780*4e1bc9a0SAchim Leubner         SA_DBG1(("saSSPAbort: agDevHandle == agNULL!!!\n"));
1781*4e1bc9a0SAchim Leubner         return AGSA_RC_FAILURE;
1782*4e1bc9a0SAchim Leubner       }
1783*4e1bc9a0SAchim Leubner       pDevice = (agsaDeviceDesc_t *) (agDevHandle->sdkData);
1784*4e1bc9a0SAchim Leubner       if (agNULL == pDevice)
1785*4e1bc9a0SAchim Leubner       {
1786*4e1bc9a0SAchim Leubner         /* no deviceID - can not build IOMB */
1787*4e1bc9a0SAchim Leubner         SA_DBG1(("saSSPAbort: ABORT_ALL agNULL == pDevice\n"));
1788*4e1bc9a0SAchim Leubner         return AGSA_RC_FAILURE;
1789*4e1bc9a0SAchim Leubner       }
1790*4e1bc9a0SAchim Leubner       pPort = pDevice->pPort;
1791*4e1bc9a0SAchim Leubner       ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1792*4e1bc9a0SAchim Leubner       pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeIORequests)); /**/
1793*4e1bc9a0SAchim Leubner     }
1794*4e1bc9a0SAchim Leubner     else
1795*4e1bc9a0SAchim Leubner     {
1796*4e1bc9a0SAchim Leubner       /* only support 00, 01 and 02 for flag */
1797*4e1bc9a0SAchim Leubner       SA_DBG1(("saSSPAbort: ABORT_ALL type not supported 0x%X\n",flag));
1798*4e1bc9a0SAchim Leubner       smTraceFuncExit(hpDBG_VERY_LOUD, 'e', "Sb");
1799*4e1bc9a0SAchim Leubner       return AGSA_RC_FAILURE;
1800*4e1bc9a0SAchim Leubner     }
1801*4e1bc9a0SAchim Leubner   }
1802*4e1bc9a0SAchim Leubner 
1803*4e1bc9a0SAchim Leubner   if ( agNULL == pRequest )
1804*4e1bc9a0SAchim Leubner   {
1805*4e1bc9a0SAchim Leubner     pRequest = (agsaIORequestDesc_t *)saLlistIOGetHead(&(saRoot->freeReservedRequests));
1806*4e1bc9a0SAchim Leubner     if(agNULL != pRequest)
1807*4e1bc9a0SAchim Leubner     {
1808*4e1bc9a0SAchim Leubner       using_reserved = agTRUE;
1809*4e1bc9a0SAchim Leubner       SA_DBG2(("saSSPAbort: using saRoot->freeReservedRequests\n"));
1810*4e1bc9a0SAchim Leubner     }
1811*4e1bc9a0SAchim Leubner     else
1812*4e1bc9a0SAchim Leubner     {
1813*4e1bc9a0SAchim Leubner       ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1814*4e1bc9a0SAchim Leubner       /* If no LL IO request entry available */
1815*4e1bc9a0SAchim Leubner       SA_DBG1(("saSSPAbort: No request from free list Not using saRoot->freeReservedRequests\n"));
1816*4e1bc9a0SAchim Leubner       smTraceFuncExit(hpDBG_VERY_LOUD, 'f', "Sb");
1817*4e1bc9a0SAchim Leubner       return AGSA_RC_BUSY;
1818*4e1bc9a0SAchim Leubner     }
1819*4e1bc9a0SAchim Leubner   }
1820*4e1bc9a0SAchim Leubner 
1821*4e1bc9a0SAchim Leubner   /* If free IOMB avaliable */
1822*4e1bc9a0SAchim Leubner   /* Remove the request from free list */
1823*4e1bc9a0SAchim Leubner   if( using_reserved )
1824*4e1bc9a0SAchim Leubner   {
1825*4e1bc9a0SAchim Leubner     saLlistIORemove(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1826*4e1bc9a0SAchim Leubner   }
1827*4e1bc9a0SAchim Leubner   else
1828*4e1bc9a0SAchim Leubner   {
1829*4e1bc9a0SAchim Leubner     saLlistIORemove(&(saRoot->freeIORequests), &(pRequest->linkNode));
1830*4e1bc9a0SAchim Leubner   }
1831*4e1bc9a0SAchim Leubner 
1832*4e1bc9a0SAchim Leubner   /* Add the request to the pendingIORequests list of the device */
1833*4e1bc9a0SAchim Leubner   pRequest->valid = agTRUE;
1834*4e1bc9a0SAchim Leubner   saLlistIOAdd(&(pDevice->pendingIORequests), &(pRequest->linkNode));
1835*4e1bc9a0SAchim Leubner 
1836*4e1bc9a0SAchim Leubner   ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1837*4e1bc9a0SAchim Leubner 
1838*4e1bc9a0SAchim Leubner   /* set up pRequest */
1839*4e1bc9a0SAchim Leubner   pRequest->pIORequestContext = agIORequest;
1840*4e1bc9a0SAchim Leubner   pRequest->requestType = AGSA_SSP_REQTYPE;
1841*4e1bc9a0SAchim Leubner   pRequest->pDevice = pDevice;
1842*4e1bc9a0SAchim Leubner   pRequest->pPort = pPort;
1843*4e1bc9a0SAchim Leubner   pRequest->completionCB = (void*)agCB;
1844*4e1bc9a0SAchim Leubner /*  pRequest->abortCompletionCB = agCB;*/
1845*4e1bc9a0SAchim Leubner   pRequest->startTick = saRoot->timeTick;
1846*4e1bc9a0SAchim Leubner 
1847*4e1bc9a0SAchim Leubner   /* Set request to the sdkData of agIORequest */
1848*4e1bc9a0SAchim Leubner   agIORequest->sdkData = pRequest;
1849*4e1bc9a0SAchim Leubner 
1850*4e1bc9a0SAchim Leubner   /* save tag and IOrequest pointer to IOMap */
1851*4e1bc9a0SAchim Leubner   saRoot->IOMap[pRequest->HTag].Tag = pRequest->HTag;
1852*4e1bc9a0SAchim Leubner   saRoot->IOMap[pRequest->HTag].IORequest = (void *)pRequest;
1853*4e1bc9a0SAchim Leubner 
1854*4e1bc9a0SAchim Leubner 
1855*4e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
1856*4e1bc9a0SAchim Leubner   ossaSingleThreadedEnter(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
1857*4e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
1858*4e1bc9a0SAchim Leubner 
1859*4e1bc9a0SAchim Leubner   /* If LL IO request entry avaliable */
1860*4e1bc9a0SAchim Leubner   /* Get a free inbound queue entry */
1861*4e1bc9a0SAchim Leubner   circularQ = &saRoot->inboundQueue[inq];
1862*4e1bc9a0SAchim Leubner   retVal    = mpiMsgFreeGet(circularQ, IOMB_SIZE64, &pMessage);
1863*4e1bc9a0SAchim Leubner 
1864*4e1bc9a0SAchim Leubner   /* if message size is too large return failure */
1865*4e1bc9a0SAchim Leubner   if (AGSA_RC_FAILURE == retVal)
1866*4e1bc9a0SAchim Leubner   {
1867*4e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
1868*4e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
1869*4e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
1870*4e1bc9a0SAchim Leubner 
1871*4e1bc9a0SAchim Leubner     ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1872*4e1bc9a0SAchim Leubner     saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
1873*4e1bc9a0SAchim Leubner     pRequest->valid = agFALSE;
1874*4e1bc9a0SAchim Leubner     if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
1875*4e1bc9a0SAchim Leubner     {
1876*4e1bc9a0SAchim Leubner       SA_DBG1(("saSSPAbort: saving pRequest (%p) for later use\n", pRequest));
1877*4e1bc9a0SAchim Leubner       saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1878*4e1bc9a0SAchim Leubner     }
1879*4e1bc9a0SAchim Leubner     else
1880*4e1bc9a0SAchim Leubner     {
1881*4e1bc9a0SAchim Leubner       /* return the request to free pool */
1882*4e1bc9a0SAchim Leubner       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1883*4e1bc9a0SAchim Leubner     }
1884*4e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1885*4e1bc9a0SAchim Leubner 
1886*4e1bc9a0SAchim Leubner     SA_DBG1(("saSSPAbort: error when get free IOMB\n"));
1887*4e1bc9a0SAchim Leubner 
1888*4e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'g', "Sb");
1889*4e1bc9a0SAchim Leubner     return AGSA_RC_FAILURE;
1890*4e1bc9a0SAchim Leubner   }
1891*4e1bc9a0SAchim Leubner 
1892*4e1bc9a0SAchim Leubner   /* return busy if inbound queue is full */
1893*4e1bc9a0SAchim Leubner   if (AGSA_RC_BUSY == retVal)
1894*4e1bc9a0SAchim Leubner   {
1895*4e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
1896*4e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
1897*4e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
1898*4e1bc9a0SAchim Leubner 
1899*4e1bc9a0SAchim Leubner     ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1900*4e1bc9a0SAchim Leubner     saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode));
1901*4e1bc9a0SAchim Leubner     pRequest->valid = agFALSE;
1902*4e1bc9a0SAchim Leubner     if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT)
1903*4e1bc9a0SAchim Leubner     {
1904*4e1bc9a0SAchim Leubner       SA_DBG1(("saSSPAbort: saving pRequest (%p) for later use\n", pRequest));
1905*4e1bc9a0SAchim Leubner       saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode));
1906*4e1bc9a0SAchim Leubner     }
1907*4e1bc9a0SAchim Leubner     else
1908*4e1bc9a0SAchim Leubner     {
1909*4e1bc9a0SAchim Leubner       /* return the request to free pool */
1910*4e1bc9a0SAchim Leubner       saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode));
1911*4e1bc9a0SAchim Leubner     }
1912*4e1bc9a0SAchim Leubner     ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK);
1913*4e1bc9a0SAchim Leubner 
1914*4e1bc9a0SAchim Leubner     SA_DBG1(("saSSPAbort: no more IOMB\n"));
1915*4e1bc9a0SAchim Leubner     smTraceFuncExit(hpDBG_VERY_LOUD, 'h', "Sb");
1916*4e1bc9a0SAchim Leubner     return AGSA_RC_BUSY;
1917*4e1bc9a0SAchim Leubner   }
1918*4e1bc9a0SAchim Leubner 
1919*4e1bc9a0SAchim Leubner   /* setup payload */
1920*4e1bc9a0SAchim Leubner   payload = (agsaSSPAbortCmd_t*)pMessage;
1921*4e1bc9a0SAchim Leubner   OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, tag), pRequest->HTag);
1922*4e1bc9a0SAchim Leubner 
1923*4e1bc9a0SAchim Leubner   if( ABORT_SINGLE == (flag & ABORT_MASK) )
1924*4e1bc9a0SAchim Leubner   {
1925*4e1bc9a0SAchim Leubner     if ( agNULL == pDeviceABT )
1926*4e1bc9a0SAchim Leubner     {
1927*4e1bc9a0SAchim Leubner       SA_DBG1(("saSSPSAbort: no device\n" ));
1928*4e1bc9a0SAchim Leubner       smTraceFuncExit(hpDBG_VERY_LOUD, 'i', "Sb");
1929*4e1bc9a0SAchim Leubner       return AGSA_RC_FAILURE;
1930*4e1bc9a0SAchim Leubner     }
1931*4e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, deviceId), pDeviceABT->DeviceMapIndex);
1932*4e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, HTagAbort), pRequestABT->HTag);
1933*4e1bc9a0SAchim Leubner   }
1934*4e1bc9a0SAchim Leubner   else
1935*4e1bc9a0SAchim Leubner   {
1936*4e1bc9a0SAchim Leubner     /* abort all */
1937*4e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, deviceId), pDevice->DeviceMapIndex);
1938*4e1bc9a0SAchim Leubner     OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, HTagAbort), 0);
1939*4e1bc9a0SAchim Leubner   }
1940*4e1bc9a0SAchim Leubner 
1941*4e1bc9a0SAchim Leubner   if(flag & ABORT_TSDK_QUARANTINE)
1942*4e1bc9a0SAchim Leubner   {
1943*4e1bc9a0SAchim Leubner     if(smIS_SPCV(agRoot))
1944*4e1bc9a0SAchim Leubner     {
1945*4e1bc9a0SAchim Leubner       flag_copy &= ABORT_SCOPE;
1946*4e1bc9a0SAchim Leubner       flag_copy |= ABORT_QUARANTINE_SPCV;
1947*4e1bc9a0SAchim Leubner     }
1948*4e1bc9a0SAchim Leubner   }
1949*4e1bc9a0SAchim Leubner   OSSA_WRITE_LE_32(agRoot, payload, OSSA_OFFSET_OF(agsaSSPAbortCmd_t, abortAll), flag_copy);
1950*4e1bc9a0SAchim Leubner 
1951*4e1bc9a0SAchim Leubner   SA_DBG1(("saSSPAbort: HTag 0x%x HTagABT 0x%x deviceId 0x%x flag 0x%x\n", payload->tag, payload->HTagAbort, payload->deviceId,flag));
1952*4e1bc9a0SAchim Leubner 
1953*4e1bc9a0SAchim Leubner   siCountActiveIORequestsOnDevice( agRoot,   payload->deviceId );
1954*4e1bc9a0SAchim Leubner 
1955*4e1bc9a0SAchim Leubner   /* post the IOMB to SPC */
1956*4e1bc9a0SAchim Leubner   ret = mpiMsgProduce(circularQ, (void *)pMessage, MPI_CATEGORY_SAS_SATA, OPC_INB_SSP_ABORT, outq, (bit8)circularQ->priority);
1957*4e1bc9a0SAchim Leubner 
1958*4e1bc9a0SAchim Leubner #ifdef SA_LL_IBQ_PROTECT
1959*4e1bc9a0SAchim Leubner   ossaSingleThreadedLeave(agRoot, LL_IOREQ_IBQ0_LOCK + inq);
1960*4e1bc9a0SAchim Leubner #endif /* SA_LL_IBQ_PROTECT */
1961*4e1bc9a0SAchim Leubner 
1962*4e1bc9a0SAchim Leubner #ifdef SALL_API_TEST
1963*4e1bc9a0SAchim Leubner   if (AGSA_RC_SUCCESS == ret)
1964*4e1bc9a0SAchim Leubner   {
1965*4e1bc9a0SAchim Leubner     saRoot->LLCounters.IOCounter.numSSPAborted++;
1966*4e1bc9a0SAchim Leubner   }
1967*4e1bc9a0SAchim Leubner #endif
1968*4e1bc9a0SAchim Leubner 
1969*4e1bc9a0SAchim Leubner   smTraceFuncExit(hpDBG_VERY_LOUD, 'j', "Sb");
1970*4e1bc9a0SAchim Leubner 
1971*4e1bc9a0SAchim Leubner   return ret;
1972*4e1bc9a0SAchim Leubner }
1973*4e1bc9a0SAchim Leubner 
1974*4e1bc9a0SAchim Leubner 
1975*4e1bc9a0SAchim Leubner #if defined(SALLSDK_DEBUG)
1976*4e1bc9a0SAchim Leubner /******************************************************************************/
1977*4e1bc9a0SAchim Leubner /*! \brief
1978*4e1bc9a0SAchim Leubner  *
1979*4e1bc9a0SAchim Leubner  *  Dump StartSSP information
1980*4e1bc9a0SAchim Leubner  *
1981*4e1bc9a0SAchim Leubner  *  Debug helper routine
1982*4e1bc9a0SAchim Leubner  *
1983*4e1bc9a0SAchim Leubner  *  \return -none -
1984*4e1bc9a0SAchim Leubner  */
1985*4e1bc9a0SAchim Leubner /*******************************************************************************/
siDumpSSPStartIu(agsaDevHandle_t * agDevHandle,bit32 agRequestType,agsaSASRequestBody_t * agRequestBody)1986*4e1bc9a0SAchim Leubner LOCAL void siDumpSSPStartIu(
1987*4e1bc9a0SAchim Leubner   agsaDevHandle_t       *agDevHandle,
1988*4e1bc9a0SAchim Leubner   bit32                 agRequestType,
1989*4e1bc9a0SAchim Leubner   agsaSASRequestBody_t  *agRequestBody
1990*4e1bc9a0SAchim Leubner   )
1991*4e1bc9a0SAchim Leubner  {
1992*4e1bc9a0SAchim Leubner   switch ( agRequestType )
1993*4e1bc9a0SAchim Leubner   {
1994*4e1bc9a0SAchim Leubner     case AGSA_SSP_INIT_READ:
1995*4e1bc9a0SAchim Leubner     case AGSA_SSP_INIT_WRITE:
1996*4e1bc9a0SAchim Leubner     {
1997*4e1bc9a0SAchim Leubner       agsaSSPInitiatorRequest_t *pIRequest = &(agRequestBody->sspInitiatorReq);
1998*4e1bc9a0SAchim Leubner 
1999*4e1bc9a0SAchim Leubner       SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - len=%x - attr=%x - CDB:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
2000*4e1bc9a0SAchim Leubner         agDevHandle,
2001*4e1bc9a0SAchim Leubner         (agRequestType==AGSA_SSP_INIT_READ)? "AGSA_SSP_INIT_READ" : "AGSA_SSP_INIT_WRITE",
2002*4e1bc9a0SAchim Leubner         pIRequest->dataLength,
2003*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIU.efb_tp_taskAttribute,
2004*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIU.cdb[0],
2005*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIU.cdb[1],
2006*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIU.cdb[2],
2007*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIU.cdb[3],
2008*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIU.cdb[4],
2009*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIU.cdb[5],
2010*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIU.cdb[6],
2011*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIU.cdb[7],
2012*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIU.cdb[8],
2013*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIU.cdb[9]
2014*4e1bc9a0SAchim Leubner         ));
2015*4e1bc9a0SAchim Leubner       break;
2016*4e1bc9a0SAchim Leubner     }
2017*4e1bc9a0SAchim Leubner 
2018*4e1bc9a0SAchim Leubner     case  AGSA_SSP_INIT_READ_EXT:
2019*4e1bc9a0SAchim Leubner     case  AGSA_SSP_INIT_WRITE_EXT:
2020*4e1bc9a0SAchim Leubner     {
2021*4e1bc9a0SAchim Leubner       agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt);
2022*4e1bc9a0SAchim Leubner 
2023*4e1bc9a0SAchim Leubner       SA_DBG3(("siDumpSSPStartIu: dev=%p - %s - len=%x - attr=%x - CDB:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
2024*4e1bc9a0SAchim Leubner         agDevHandle,
2025*4e1bc9a0SAchim Leubner         (agRequestType==AGSA_SSP_INIT_READ_EXT)? "AGSA_SSP_INIT_READ_EXT" : "AGSA_SSP_INIT_WRITE_EXT",
2026*4e1bc9a0SAchim Leubner         pIRequest->dataLength,
2027*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.efb_tp_taskAttribute,
2028*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.cdb[0],
2029*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.cdb[1],
2030*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.cdb[2],
2031*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.cdb[3],
2032*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.cdb[4],
2033*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.cdb[5],
2034*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.cdb[6],
2035*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.cdb[7],
2036*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.cdb[8],
2037*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.cdb[9]
2038*4e1bc9a0SAchim Leubner         ));
2039*4e1bc9a0SAchim Leubner       break;
2040*4e1bc9a0SAchim Leubner     }
2041*4e1bc9a0SAchim Leubner 
2042*4e1bc9a0SAchim Leubner     case  AGSA_SSP_INIT_READ_EXT_M:
2043*4e1bc9a0SAchim Leubner     case  AGSA_SSP_INIT_WRITE_EXT_M:
2044*4e1bc9a0SAchim Leubner     {
2045*4e1bc9a0SAchim Leubner       agsaSSPInitiatorRequestExt_t *pIRequest = &(agRequestBody->sspInitiatorReqExt);
2046*4e1bc9a0SAchim Leubner 
2047*4e1bc9a0SAchim Leubner       SA_DBG3(("siDumpSSPStartIu: dev=%p - %s - len=%x - attr=%x - CDB:%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
2048*4e1bc9a0SAchim Leubner         agDevHandle,
2049*4e1bc9a0SAchim Leubner         (agRequestType==AGSA_SSP_INIT_READ_EXT_M)? "AGSA_SSP_INIT_READ_EXT_M" : "AGSA_SSP_INIT_WRITE_EXT_M",
2050*4e1bc9a0SAchim Leubner         pIRequest->dataLength,
2051*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.efb_tp_taskAttribute,
2052*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.cdb[0],
2053*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.cdb[1],
2054*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.cdb[2],
2055*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.cdb[3],
2056*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.cdb[4],
2057*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.cdb[5],
2058*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.cdb[6],
2059*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.cdb[7],
2060*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.cdb[8],
2061*4e1bc9a0SAchim Leubner         pIRequest->sspCmdIUExt.cdb[9]
2062*4e1bc9a0SAchim Leubner         ));
2063*4e1bc9a0SAchim Leubner       break;
2064*4e1bc9a0SAchim Leubner     }
2065*4e1bc9a0SAchim Leubner 
2066*4e1bc9a0SAchim Leubner     case  AGSA_SSP_INIT_READ_INDIRECT:
2067*4e1bc9a0SAchim Leubner     case  AGSA_SSP_INIT_WRITE_INDIRECT:
2068*4e1bc9a0SAchim Leubner     case  AGSA_SSP_INIT_READ_INDIRECT_M:
2069*4e1bc9a0SAchim Leubner     case  AGSA_SSP_INIT_WRITE_INDIRECT_M:
2070*4e1bc9a0SAchim Leubner     {
2071*4e1bc9a0SAchim Leubner      agsaSSPInitiatorRequestIndirect_t *pIRequest = &(agRequestBody->sspInitiatorReqIndirect);
2072*4e1bc9a0SAchim Leubner 
2073*4e1bc9a0SAchim Leubner       SA_DBG3(("siDumpSSPStartIu: dev=%p - %s - len=%x - cdblen=%d CDB:U %08x L %08x\n",
2074*4e1bc9a0SAchim Leubner         agDevHandle,
2075*4e1bc9a0SAchim Leubner         (agRequestType==AGSA_SSP_INIT_READ_INDIRECT ||
2076*4e1bc9a0SAchim Leubner          agRequestType==AGSA_SSP_INIT_READ_INDIRECT_M) ? "AGSA_SSP_INIT_READ_INDIRECT" : "AGSA_SSP_INIT_WRITE_INDIRECT",
2077*4e1bc9a0SAchim Leubner         pIRequest->dataLength,
2078*4e1bc9a0SAchim Leubner         pIRequest->sspInitiatorReqLen,
2079*4e1bc9a0SAchim Leubner         pIRequest->sspInitiatorReqAddrUpper32,
2080*4e1bc9a0SAchim Leubner         pIRequest->sspInitiatorReqAddrLower32 ));
2081*4e1bc9a0SAchim Leubner       break;
2082*4e1bc9a0SAchim Leubner     }
2083*4e1bc9a0SAchim Leubner 
2084*4e1bc9a0SAchim Leubner 
2085*4e1bc9a0SAchim Leubner     case AGSA_SSP_TASK_MGNT_REQ:
2086*4e1bc9a0SAchim Leubner     {
2087*4e1bc9a0SAchim Leubner       agsaSSPScsiTaskMgntReq_t  *pTaskCmd =&agRequestBody->sspTaskMgntReq;
2088*4e1bc9a0SAchim Leubner       /* copy payload */
2089*4e1bc9a0SAchim Leubner 
2090*4e1bc9a0SAchim Leubner       SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - Task Function=%x - Tag to managed=%x",
2091*4e1bc9a0SAchim Leubner         agDevHandle,
2092*4e1bc9a0SAchim Leubner         "AGSA_SSP_TASK_MGNT_REQ",
2093*4e1bc9a0SAchim Leubner         pTaskCmd->taskMgntFunction,
2094*4e1bc9a0SAchim Leubner         pTaskCmd->tagOfTaskToBeManaged
2095*4e1bc9a0SAchim Leubner         ));
2096*4e1bc9a0SAchim Leubner       break;
2097*4e1bc9a0SAchim Leubner     }
2098*4e1bc9a0SAchim Leubner     case AGSA_SSP_TGT_READ_DATA:
2099*4e1bc9a0SAchim Leubner     {
2100*4e1bc9a0SAchim Leubner       agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq);
2101*4e1bc9a0SAchim Leubner 
2102*4e1bc9a0SAchim Leubner       SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n",
2103*4e1bc9a0SAchim Leubner                   agDevHandle,
2104*4e1bc9a0SAchim Leubner                   "AGSA_SSP_TGT_READ_DATA",
2105*4e1bc9a0SAchim Leubner                   pTRequest->dataLength,
2106*4e1bc9a0SAchim Leubner                   pTRequest->offset ));
2107*4e1bc9a0SAchim Leubner       break;
2108*4e1bc9a0SAchim Leubner     }
2109*4e1bc9a0SAchim Leubner     case AGSA_SSP_TGT_READ_GOOD_RESP:
2110*4e1bc9a0SAchim Leubner     {
2111*4e1bc9a0SAchim Leubner       agsaSSPTargetRequest_t *pTRequest = &(agRequestBody->sspTargetReq);
2112*4e1bc9a0SAchim Leubner 
2113*4e1bc9a0SAchim Leubner       SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n",
2114*4e1bc9a0SAchim Leubner                   agDevHandle,
2115*4e1bc9a0SAchim Leubner                   "AGSA_SSP_TGT_READ_GOOD_RESP",
2116*4e1bc9a0SAchim Leubner                   pTRequest->dataLength,
2117*4e1bc9a0SAchim Leubner                   pTRequest->offset));
2118*4e1bc9a0SAchim Leubner       break;
2119*4e1bc9a0SAchim Leubner     }
2120*4e1bc9a0SAchim Leubner     case AGSA_SSP_TGT_WRITE_GOOD_RESP:
2121*4e1bc9a0SAchim Leubner     {
2122*4e1bc9a0SAchim Leubner       agsaSSPTargetRequest_t  *pTRequest = &(agRequestBody->sspTargetReq);
2123*4e1bc9a0SAchim Leubner       SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n",
2124*4e1bc9a0SAchim Leubner                   agDevHandle,
2125*4e1bc9a0SAchim Leubner                   "AGSA_SSP_TGT_WRITE_GOOD_RESP",
2126*4e1bc9a0SAchim Leubner                   pTRequest->dataLength,
2127*4e1bc9a0SAchim Leubner                   pTRequest->offset ));
2128*4e1bc9a0SAchim Leubner 
2129*4e1bc9a0SAchim Leubner       break;
2130*4e1bc9a0SAchim Leubner     }
2131*4e1bc9a0SAchim Leubner     case AGSA_SSP_TGT_WRITE_DATA:
2132*4e1bc9a0SAchim Leubner     {
2133*4e1bc9a0SAchim Leubner       agsaSSPTargetRequest_t  *pTRequest = &(agRequestBody->sspTargetReq);
2134*4e1bc9a0SAchim Leubner 
2135*4e1bc9a0SAchim Leubner       SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - dmaSize=%x dmaOffset=%x\n",
2136*4e1bc9a0SAchim Leubner         agDevHandle,
2137*4e1bc9a0SAchim Leubner         "AGSA_SSP_TGT_WRITE_DATA",
2138*4e1bc9a0SAchim Leubner         pTRequest->dataLength,
2139*4e1bc9a0SAchim Leubner         pTRequest->offset ));
2140*4e1bc9a0SAchim Leubner       break;
2141*4e1bc9a0SAchim Leubner     }
2142*4e1bc9a0SAchim Leubner     case AGSA_SSP_TGT_CMD_OR_TASK_RSP:
2143*4e1bc9a0SAchim Leubner     {
2144*4e1bc9a0SAchim Leubner       agsaSSPTargetResponse_t *pTResponse = &(agRequestBody->sspTargetResponse);
2145*4e1bc9a0SAchim Leubner 
2146*4e1bc9a0SAchim Leubner       SA_DBG5(("siDumpSSPStartIu: dev=%p - %s - len=%x PAddr=%08x:%08x  Tag=%x\n",
2147*4e1bc9a0SAchim Leubner         agDevHandle,
2148*4e1bc9a0SAchim Leubner         "AGSA_SSP_TGT_CMD_OR_TASK_RSP",
2149*4e1bc9a0SAchim Leubner         pTResponse->respBufLength,
2150*4e1bc9a0SAchim Leubner         pTResponse->respBufUpper,
2151*4e1bc9a0SAchim Leubner         pTResponse->respBufLower,
2152*4e1bc9a0SAchim Leubner         pTResponse->agTag  ));
2153*4e1bc9a0SAchim Leubner       break;
2154*4e1bc9a0SAchim Leubner     }
2155*4e1bc9a0SAchim Leubner 
2156*4e1bc9a0SAchim Leubner     default:
2157*4e1bc9a0SAchim Leubner     {
2158*4e1bc9a0SAchim Leubner       SA_DBG1(("siDumpSSPStartIu: dev=%p - %s %X\n",
2159*4e1bc9a0SAchim Leubner         agDevHandle,
2160*4e1bc9a0SAchim Leubner         "Unknown SSP cmd type",
2161*4e1bc9a0SAchim Leubner         agRequestType
2162*4e1bc9a0SAchim Leubner         ));
2163*4e1bc9a0SAchim Leubner       break;
2164*4e1bc9a0SAchim Leubner     }
2165*4e1bc9a0SAchim Leubner   }
2166*4e1bc9a0SAchim Leubner   return;
2167*4e1bc9a0SAchim Leubner }
2168*4e1bc9a0SAchim Leubner #endif /* SALLSDK_DEBUG */
2169