1285242Sachim/*******************************************************************************
2285242Sachim*Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved.
3285242Sachim*
4285242Sachim*Redistribution and use in source and binary forms, with or without modification, are permitted provided
5285242Sachim*that the following conditions are met:
6285242Sachim*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
7285242Sachim*following disclaimer.
8285242Sachim*2. Redistributions in binary form must reproduce the above copyright notice,
9285242Sachim*this list of conditions and the following disclaimer in the documentation and/or other materials provided
10285242Sachim*with the distribution.
11285242Sachim*
12285242Sachim*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13285242Sachim*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14285242Sachim*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15285242Sachim*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16285242Sachim*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17285242Sachim*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18285242Sachim*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19285242Sachim*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
20285242Sachim
21285242Sachim********************************************************************************/
22285242Sachim#include <sys/cdefs.h>
23285242Sachim__FBSDID("$FreeBSD$");
24285242Sachim#include <dev/pms/config.h>
25285242Sachim
26285242Sachim#include <dev/pms/freebsd/driver/common/osenv.h>
27285242Sachim#include <dev/pms/freebsd/driver/common/ostypes.h>
28285242Sachim#include <dev/pms/freebsd/driver/common/osdebug.h>
29285242Sachim
30285242Sachim#include <dev/pms/RefTisa/tisa/api/titypes.h>
31285242Sachim
32285242Sachim#include <dev/pms/RefTisa/sallsdk/api/sa.h>
33285242Sachim#include <dev/pms/RefTisa/sallsdk/api/saapi.h>
34285242Sachim#include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
35285242Sachim
36285242Sachim#include <dev/pms/RefTisa/sat/api/sm.h>
37285242Sachim#include <dev/pms/RefTisa/sat/api/smapi.h>
38285242Sachim#include <dev/pms/RefTisa/sat/api/tdsmapi.h>
39285242Sachim
40285242Sachim#include <dev/pms/RefTisa/sat/src/smdefs.h>
41285242Sachim#include <dev/pms/RefTisa/sat/src/smproto.h>
42285242Sachim#include <dev/pms/RefTisa/sat/src/smtypes.h>
43285242Sachim
44285242Sachim/*
45285242Sachim * This table is used to map LL Layer saSATAStart() status to TISA status.
46285242Sachim */
47285242Sachim
48285242Sachim
49285242SachimFORCEINLINE bit32
50285242SachimsmsataLLIOStart(
51285242Sachim                smRoot_t                  *smRoot,
52285242Sachim                smIORequest_t             *smIORequest,
53285242Sachim                smDeviceHandle_t          *smDeviceHandle,
54285242Sachim                smScsiInitiatorRequest_t  *smScsiRequest,
55285242Sachim                smSatIOContext_t          *satIOContext
56285242Sachim               )
57285242Sachim{
58285242Sachim  smDeviceData_t              *oneDeviceData  = (smDeviceData_t *)smDeviceHandle->smData;
59285242Sachim  smIntRoot_t                 *smIntRoot      = (smIntRoot_t *) smRoot->smData;
60285242Sachim  smIntContext_t              *smAllShared    = (smIntContext_t *)&(smIntRoot->smAllShared);
61285242Sachim  smIORequestBody_t           *smIORequestBody = (smIORequestBody_t *)satIOContext->smRequestBody;
62285242Sachim  smDeviceData_t              *pSatDevData   = satIOContext->pSatDevData;
63285242Sachim  smSatInternalIo_t           *satIntIo      = satIOContext->satIntIoContext;
64285242Sachim  agsaRoot_t                  *agRoot        = smAllShared->agRoot;
65285242Sachim  agsaIORequest_t             *agIORequest   = &(smIORequestBody->agIORequest);
66285242Sachim  agsaDevHandle_t             *agDevHandle   = oneDeviceData->agDevHandle;
67285242Sachim  agsaSATAInitiatorRequest_t  *agSATAReq     = &(smIORequestBody->transport.SATA.agSATARequestBody);
68285242Sachim  bit32                       RLERecovery    = agFALSE;
69285242Sachim  bit32                       status         = SM_RC_FAILURE;
70285242Sachim  bit32                       nQNumber       = 0;
71285242Sachim  /*
72285242Sachim   * If this is a super I/O request, check for optional settings.
73285242Sachim   * Be careful. Use the superRequest pointer for all references
74285242Sachim   * in this block of code.
75285242Sachim   */
76285242Sachim  agSATAReq->option = 0;
77285242Sachim  if (satIOContext->superIOFlag)
78285242Sachim  {
79285242Sachim    smSuperScsiInitiatorRequest_t *superRequest = (smSuperScsiInitiatorRequest_t *) smScsiRequest;
80285242Sachim
81285242Sachim    if (superRequest->flags & SM_SCSI_INITIATOR_ENCRYPT)
82285242Sachim    {
83285242Sachim      /* Copy all of the relevant encrypt information  */
84285242Sachim      agSATAReq->option |= AGSA_SATA_ENABLE_ENCRYPTION;
85285242Sachim      sm_memcpy(&agSATAReq->encrypt, &superRequest->Encrypt, sizeof(agsaEncrypt_t));
86285242Sachim    }
87285242Sachim    {
88285242Sachim      /* initialize expDataLength */
89285242Sachim      if (satIOContext->reqType == AGSA_SATA_PROTOCOL_NON_DATA ||
90285242Sachim          satIOContext->reqType == AGSA_SATA_PROTOCOL_SRST_ASSERT ||
91285242Sachim          satIOContext->reqType == AGSA_SATA_PROTOCOL_SRST_DEASSERT )
92285242Sachim      {
93285242Sachim        smIORequestBody->IOType.InitiatorRegIO.expDataLength = 0;
94285242Sachim      }
95285242Sachim      else
96285242Sachim      {
97285242Sachim        smIORequestBody->IOType.InitiatorRegIO.expDataLength = smScsiRequest->scsiCmnd.expDataLength;
98285242Sachim      }
99285242Sachim
100285242Sachim      agSATAReq->dataLength = smIORequestBody->IOType.InitiatorRegIO.expDataLength;
101285242Sachim    }
102285242Sachim  }
103285242Sachim  else
104285242Sachim  {
105285242Sachim    /* initialize expDataLength */
106285242Sachim    if (satIOContext->reqType == AGSA_SATA_PROTOCOL_NON_DATA ||
107285242Sachim        satIOContext->reqType == AGSA_SATA_PROTOCOL_SRST_ASSERT ||
108285242Sachim        satIOContext->reqType == AGSA_SATA_PROTOCOL_SRST_DEASSERT )
109285242Sachim    {
110285242Sachim      smIORequestBody->IOType.InitiatorRegIO.expDataLength = 0;
111285242Sachim    }
112285242Sachim    else
113285242Sachim    {
114285242Sachim      smIORequestBody->IOType.InitiatorRegIO.expDataLength = smScsiRequest->scsiCmnd.expDataLength;
115285242Sachim    }
116285242Sachim
117285242Sachim    agSATAReq->dataLength = smIORequestBody->IOType.InitiatorRegIO.expDataLength;
118285242Sachim  }
119285242Sachim
120285242Sachim  if ( (pSatDevData->satDriveState == SAT_DEV_STATE_IN_RECOVERY) &&
121285242Sachim       (satIOContext->pFis->h.command == SAT_READ_LOG_EXT) )
122285242Sachim  {
123285242Sachim     RLERecovery = agTRUE;
124285242Sachim  }
125285242Sachim
126285242Sachim  /* check max io, be sure to free */
127285242Sachim  if ( (pSatDevData->satDriveState != SAT_DEV_STATE_IN_RECOVERY) ||
128285242Sachim       (RLERecovery == agTRUE) )
129285242Sachim  {
130285242Sachim    if (RLERecovery == agFALSE) /* RLE is not checked against pending IO's */
131285242Sachim    {
132285242Sachim#ifdef CCFLAG_OPTIMIZE_SAT_LOCK
133285242Sachim      bit32 volatile satPendingNCQIO = 0;
134285242Sachim      bit32 volatile satPendingNONNCQIO = 0;
135285242Sachim      bit32 volatile satPendingIO = 0;
136285242Sachim
137285242Sachim      tdsmInterlockedExchange(smRoot, &satPendingNCQIO, pSatDevData->satPendingNCQIO);
138285242Sachim      tdsmInterlockedExchange(smRoot, &satPendingNONNCQIO, pSatDevData->satPendingNONNCQIO);
139285242Sachim      tdsmInterlockedExchange(smRoot, &satPendingIO, pSatDevData->satPendingIO);
140285242Sachim#endif
141285242Sachim
142285242Sachim      if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
143285242Sachim           (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
144285242Sachim      {
145285242Sachim      #ifdef CCFLAG_OPTIMIZE_SAT_LOCK
146285242Sachim        if ( satPendingNCQIO >= pSatDevData->satNCQMaxIO ||
147285242Sachim             satPendingNONNCQIO != 0)
148285242Sachim        {
149285242Sachim          SM_DBG1(("smsataLLIOStart: 1st busy did %d!!!\n", pSatDevData->id));
150285242Sachim          SM_DBG1(("smsataLLIOStart: 1st busy NCQ. NCQ Pending 0x%x NONNCQ Pending 0x%x All Pending 0x%x!!!\n", satPendingNCQIO,
151285242Sachim                    satPendingNONNCQIO, satPendingIO));
152285242Sachim          /* free resource */
153285242Sachim          smsatFreeIntIoResource( smRoot,
154285242Sachim                                  pSatDevData,
155285242Sachim                                  satIntIo);
156285242Sachim          return SM_RC_DEVICE_BUSY;
157285242Sachim        }
158285242Sachim      #else
159285242Sachim        tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
160285242Sachim        if (pSatDevData->satPendingNCQIO >= pSatDevData->satNCQMaxIO ||
161285242Sachim            pSatDevData->satPendingNONNCQIO != 0)
162285242Sachim        {
163285242Sachim          SM_DBG1(("smsataLLIOStart: 1st busy did %d!!!\n", pSatDevData->id));
164285242Sachim          SM_DBG1(("smsataLLIOStart: 1st busy NCQ. NCQ Pending 0x%x NONNCQ Pending 0x%x All Pending 0x%x!!!\n", pSatDevData->satPendingNCQIO,
165285242Sachim                    pSatDevData->satPendingNONNCQIO, pSatDevData->satPendingIO));
166285242Sachim          tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
167285242Sachim          /* free resource */
168285242Sachim          smsatFreeIntIoResource( smRoot,
169285242Sachim                                  pSatDevData,
170285242Sachim                                  satIntIo);
171285242Sachim          return SM_RC_DEVICE_BUSY;
172285242Sachim        }
173285242Sachim        tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
174285242Sachim      #endif
175285242Sachim
176285242Sachim      }
177285242Sachim      else if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_D2H_PKT) ||
178285242Sachim                (satIOContext->reqType == AGSA_SATA_PROTOCOL_H2D_PKT) ||
179285242Sachim                (satIOContext->reqType == AGSA_SATA_PROTOCOL_NON_PKT) )
180285242Sachim      {
181285242Sachim        sm_memcpy(agSATAReq->scsiCDB, smScsiRequest->scsiCmnd.cdb, 16);
182285242Sachim      #ifdef CCFLAG_OPTIMIZE_SAT_LOCK
183285242Sachim        if ( satPendingNONNCQIO >= SAT_APAPI_CMDQ_MAX ||
184285242Sachim             satPendingNCQIO != 0)
185285242Sachim        {
186285242Sachim          SM_DBG1(("smsataLLIOStart: ATAPI busy did %d!!!\n", pSatDevData->id));
187285242Sachim          SM_DBG1(("smsataLLIOStart: ATAPI busy NON-NCQ. NCQ Pending 0x%x NON-NCQ Pending 0x%x All Pending 0x%x!!!\n", satPendingNCQIO,
188285242Sachim                    satPendingNONNCQIO, satPendingIO));
189285242Sachim          /* free resource */
190285242Sachim          smsatFreeIntIoResource( smRoot,
191285242Sachim                                  pSatDevData,
192285242Sachim                                  satIntIo);
193285242Sachim          return SM_RC_DEVICE_BUSY;
194285242Sachim        }
195285242Sachim      #else
196285242Sachim        tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
197285242Sachim        if ( pSatDevData->satPendingNONNCQIO >= SAT_APAPI_CMDQ_MAX ||
198285242Sachim             pSatDevData->satPendingNCQIO != 0)
199285242Sachim        {
200285242Sachim          SM_DBG1(("smsataLLIOStart: ATAPI busy did %d!!!\n", pSatDevData->id));
201285242Sachim          SM_DBG1(("smsataLLIOStart: ATAPI busy NON-NCQ. NCQ Pending 0x%x NON-NCQ Pending 0x%x All Pending 0x%x!!!\n", pSatDevData->satPendingNCQIO,
202285242Sachim                    pSatDevData->satPendingNONNCQIO, pSatDevData->satPendingIO));
203285242Sachim          tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
204285242Sachim          /* free resource */
205285242Sachim          smsatFreeIntIoResource( smRoot,
206285242Sachim                                  pSatDevData,
207285242Sachim                                  satIntIo);
208285242Sachim          return SM_RC_DEVICE_BUSY;
209285242Sachim        }
210285242Sachim        tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
211285242Sachim      #endif
212285242Sachim
213285242Sachim      }
214285242Sachim      else
215285242Sachim      {
216285242Sachim#ifdef CCFLAG_OPTIMIZE_SAT_LOCK
217285242Sachim        if ( satPendingNONNCQIO >= SAT_NONNCQ_MAX ||
218285242Sachim             satPendingNCQIO != 0)
219285242Sachim        {
220285242Sachim          SM_DBG1(("smsataLLIOStart: 2nd busy did %d!!!\n", pSatDevData->id));
221285242Sachim          SM_DBG1(("smsataLLIOStart: 2nd busy NCQ. NCQ Pending 0x%x NONNCQ Pending 0x%x All Pending 0x%x!!!\n", satPendingNCQIO,
222285242Sachim                    satPendingNONNCQIO, satPendingIO));
223285242Sachim          /* free resource */
224285242Sachim          smsatFreeIntIoResource( smRoot,
225285242Sachim                                  pSatDevData,
226285242Sachim                                  satIntIo);
227285242Sachim          return SM_RC_DEVICE_BUSY;
228285242Sachim        }
229285242Sachim#else
230285242Sachim        tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
231285242Sachim        if (pSatDevData->satPendingNONNCQIO >= SAT_NONNCQ_MAX ||
232285242Sachim            pSatDevData->satPendingNCQIO != 0)
233285242Sachim        {
234285242Sachim          SM_DBG1(("smsataLLIOStart: 2nd busy did %d!!!\n", pSatDevData->id));
235285242Sachim          SM_DBG1(("smsataLLIOStart: 2nd busy NCQ. NCQ Pending 0x%x NONNCQ Pending 0x%x All Pending 0x%x!!!\n", pSatDevData->satPendingNCQIO,
236285242Sachim                    pSatDevData->satPendingNONNCQIO, pSatDevData->satPendingIO));
237285242Sachim          tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
238285242Sachim          /* free resource */
239285242Sachim          smsatFreeIntIoResource( smRoot,
240285242Sachim                                  pSatDevData,
241285242Sachim                                  satIntIo);
242285242Sachim          return SM_RC_DEVICE_BUSY;
243285242Sachim        }
244285242Sachim        tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
245285242Sachim#endif
246285242Sachim      }
247285242Sachim    } /* RLE */
248285242Sachim    /* for internal SATA command only */
249285242Sachim    if (satIOContext->satOrgIOContext != agNULL)
250285242Sachim    {
251285242Sachim      /* Initialize tiIORequest */
252285242Sachim      smIORequestBody->smIORequest = smIORequest;
253285242Sachim      if (smIORequest == agNULL)
254285242Sachim      {
255285242Sachim        SM_DBG1(("smsataLLIOStart: 1 check!!!\n"));
256285242Sachim      }
257285242Sachim    }
258285242Sachim    /* Initialize tiDevhandle */
259285242Sachim    smIORequestBody->smDevHandle = smDeviceHandle;
260285242Sachim
261285242Sachim    /* Initializes Scatter Gather and ESGL */
262285242Sachim    status = smsatIOPrepareSGL( smRoot,
263285242Sachim                                smIORequestBody,
264285242Sachim                                &smScsiRequest->smSgl1,
265285242Sachim                                smScsiRequest->sglVirtualAddr );
266285242Sachim
267285242Sachim    if (status != SM_RC_SUCCESS)
268285242Sachim    {
269285242Sachim      SM_DBG1(("smsataLLIOStart: can't get SGL!!!\n"));
270285242Sachim      /* free resource */
271285242Sachim      smsatFreeIntIoResource( smRoot,
272285242Sachim                              pSatDevData,
273285242Sachim                              satIntIo);
274285242Sachim      return status;
275285242Sachim    }
276285242Sachim
277285242Sachim    /* Initialize LL Layer agIORequest */
278285242Sachim    agIORequest->osData = (void *) smIORequestBody;
279285242Sachim    agIORequest->sdkData = agNULL; /* SA takes care of this */
280285242Sachim
281285242Sachim    smIORequestBody->ioStarted = agTRUE;
282285242Sachim    smIORequestBody->ioCompleted = agFALSE;
283285242Sachim
284285242Sachim    /* assign tag value for SATA */
285285242Sachim    if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
286285242Sachim         (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
287285242Sachim    {
288285242Sachim      if (agFALSE == smsatTagAlloc(smRoot, pSatDevData, &satIOContext->sataTag))
289285242Sachim      {
290285242Sachim        SM_DBG1(("smsataLLIOStart: No more NCQ tag!!!\n"));
291285242Sachim        smIORequestBody->ioStarted = agFALSE;
292285242Sachim        smIORequestBody->ioCompleted = agTRUE;
293285242Sachim        return SM_RC_DEVICE_BUSY;
294285242Sachim      }
295285242Sachim      SM_DBG3(("smsataLLIOStart: ncq tag 0x%x\n",satIOContext->sataTag));
296285242Sachim    }
297285242Sachim    else
298285242Sachim    {
299285242Sachim      satIOContext->sataTag = 0xFF;
300285242Sachim    }
301285242Sachim  }
302285242Sachim  else /* AGSA_SATA_PROTOCOL_SRST_ASSERT or AGSA_SATA_PROTOCOL_SRST_DEASSERT
303285242Sachim          or SAT_CHECK_POWER_MODE as ABORT */
304285242Sachim  {
305285242Sachim    agsaSgl_t          *agSgl;
306285242Sachim
307285242Sachim    /* for internal SATA command only */
308285242Sachim    if (satIOContext->satOrgIOContext != agNULL)
309285242Sachim    {
310285242Sachim      /* Initialize tiIORequest */
311285242Sachim      smIORequestBody->smIORequest = smIORequest;
312285242Sachim      if (smIORequest == agNULL)
313285242Sachim      {
314285242Sachim        SM_DBG1(("smsataLLIOStart: 2 check!!!\n"));
315285242Sachim      }
316285242Sachim    }
317285242Sachim    /* Initialize tiDevhandle */
318285242Sachim    smIORequestBody->smDevHandle = smDeviceHandle;
319285242Sachim
320285242Sachim
321285242Sachim    smIORequestBody->IOType.InitiatorRegIO.expDataLength = 0;
322285242Sachim    /* SGL for SATA request */
323285242Sachim    agSgl = &(smIORequestBody->transport.SATA.agSATARequestBody.agSgl);
324285242Sachim    agSgl->len = 0;
325285242Sachim
326285242Sachim    agSgl->sgUpper = 0;
327285242Sachim    agSgl->sgLower = 0;
328285242Sachim    agSgl->len = 0;
329285242Sachim    SM_CLEAR_ESGL_EXTEND(agSgl->extReserved);
330285242Sachim
331285242Sachim    /* Initialize LL Layer agIORequest */
332285242Sachim    agIORequest = &(smIORequestBody->agIORequest);
333285242Sachim    agIORequest->osData = (void *) smIORequestBody;
334285242Sachim    agIORequest->sdkData = agNULL; /* SA takes care of this */
335285242Sachim
336285242Sachim    smIORequestBody->ioStarted = agTRUE;
337285242Sachim    smIORequestBody->ioCompleted = agFALSE;
338285242Sachim
339285242Sachim    /* setting the data length */
340285242Sachim    agSATAReq->dataLength = 0;
341285242Sachim
342285242Sachim  }
343285242Sachim
344285242Sachim
345285242Sachim  smIORequestBody->reTries = 0;
346285242Sachim
347285242Sachim#ifdef TD_INTERNAL_DEBUG
348285242Sachim  smhexdump("smsataLLIOStart", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
349285242Sachim  smhexdump("smsataLLIOStart LL", (bit8 *)&agSATAReq->fis.fisRegHostToDev,
350285242Sachim            sizeof(agsaFisRegHostToDevice_t));
351285242Sachim#endif
352285242Sachim
353285242Sachim  SM_DBG6(("smsataLLIOStart: agDevHandle %p\n", agDevHandle));
354285242Sachim
355285242Sachim  /* to get better IO performance, rotate the OBQ number on main IO path */
356285242Sachim  if (smScsiRequest == agNULL)
357285242Sachim  {
358285242Sachim    nQNumber = 0;
359285242Sachim  }
360285242Sachim  else
361285242Sachim  {
362285242Sachim    switch (smScsiRequest->scsiCmnd.cdb[0])
363285242Sachim    {
364285242Sachim      case SCSIOPC_READ_10:
365285242Sachim      case SCSIOPC_WRITE_10:
366285242Sachim      case SCSIOPC_READ_6:
367285242Sachim      case SCSIOPC_WRITE_6:
368285242Sachim      case SCSIOPC_READ_12:
369285242Sachim      case SCSIOPC_WRITE_12:
370285242Sachim      case SCSIOPC_READ_16:
371285242Sachim      case SCSIOPC_WRITE_16:
372285242Sachim         nQNumber = tdsmRotateQnumber(smRoot, smDeviceHandle);
373285242Sachim         break;
374285242Sachim
375285242Sachim      default:
376285242Sachim         nQNumber = 0;
377285242Sachim         break;
378285242Sachim    }
379285242Sachim  }
380285242Sachim
381285242Sachim  SM_DBG3(("sataLLIOStart: Lock in\n"));
382285242Sachim
383285242Sachim#ifdef CCFLAG_OPTIMIZE_SAT_LOCK
384285242Sachim  if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
385285242Sachim       (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
386285242Sachim  {
387285242Sachim     tdsmInterlockedIncrement(smRoot,&pSatDevData->satPendingNCQIO);
388285242Sachim  }
389285242Sachim  else
390285242Sachim  {
391285242Sachim     tdsmInterlockedIncrement(smRoot,&pSatDevData->satPendingNONNCQIO);
392285242Sachim  }
393285242Sachim  tdsmInterlockedIncrement(smRoot,&pSatDevData->satPendingIO);
394285242Sachim#else
395285242Sachim  tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
396285242Sachim  if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
397285242Sachim       (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
398285242Sachim  {
399285242Sachim     pSatDevData->satPendingNCQIO++;
400285242Sachim  }
401285242Sachim  else
402285242Sachim  {
403285242Sachim     pSatDevData->satPendingNONNCQIO++;
404285242Sachim  }
405285242Sachim  pSatDevData->satPendingIO++;
406285242Sachim
407285242Sachim  SMLIST_INIT_ELEMENT (&satIOContext->satIoContextLink);
408285242Sachim  SMLIST_ENQUEUE_AT_TAIL (&satIOContext->satIoContextLink, &pSatDevData->satIoLinkList);
409285242Sachim  tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
410285242Sachim#endif
411285242Sachim  /* post SATA command to low level MPI */
412285242Sachim  status = saSATAStart( agRoot,
413285242Sachim                        agIORequest,
414285242Sachim                        nQNumber,
415285242Sachim                        agDevHandle,
416285242Sachim                        satIOContext->reqType,
417285242Sachim                        agSATAReq,
418285242Sachim                        satIOContext->sataTag,
419285242Sachim                        smllSATACompleted
420285242Sachim                        );
421285242Sachim
422285242Sachim  if (status != AGSA_RC_SUCCESS)
423285242Sachim  {
424285242Sachim    if (status == AGSA_RC_BUSY)
425285242Sachim    {
426285242Sachim      SM_DBG1(("smsataLLIOStart: saSATAStart busy!!!\n"));
427285242Sachim      status = SM_RC_BUSY;
428285242Sachim    }
429285242Sachim    else
430285242Sachim    {
431285242Sachim      SM_DBG1(("smsataLLIOStart: saSATAStart failed!!!\n"));
432285242Sachim      status = SM_RC_FAILURE;
433285242Sachim    }
434285242Sachim
435285242Sachim    if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
436285242Sachim         (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
437285242Sachim    {
438285242Sachim      smsatTagRelease(smRoot, pSatDevData, satIOContext->sataTag);
439285242Sachim    }
440285242Sachim
441285242Sachim#ifdef CCFLAG_OPTIMIZE_SAT_LOCK
442285242Sachim    if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
443285242Sachim         (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
444285242Sachim    {
445285242Sachim      tdsmInterlockedDecrement(smRoot,&oneDeviceData->satPendingNCQIO);
446285242Sachim    }
447285242Sachim    else
448285242Sachim    {
449285242Sachim      tdsmInterlockedDecrement(smRoot,&oneDeviceData->satPendingNONNCQIO);
450285242Sachim    }
451285242Sachim    tdsmInterlockedDecrement(smRoot,&oneDeviceData->satPendingIO);
452285242Sachim#else
453285242Sachim    if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
454285242Sachim         (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
455285242Sachim    {
456285242Sachim      tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
457285242Sachim      oneDeviceData->satPendingNCQIO--;
458285242Sachim      oneDeviceData->satPendingIO--;
459285242Sachim      SMLIST_DEQUEUE_THIS (&satIOContext->satIoContextLink);
460285242Sachim      tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
461285242Sachim    }
462285242Sachim    else
463285242Sachim    {
464285242Sachim      tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
465285242Sachim      oneDeviceData->satPendingNONNCQIO--;
466285242Sachim      oneDeviceData->satPendingIO--;
467285242Sachim      SMLIST_DEQUEUE_THIS (&satIOContext->satIoContextLink);
468285242Sachim      tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
469285242Sachim    }
470285242Sachim#endif /* CCFLAG_OPTIMIZE_SAT_LOCK */
471285242Sachim
472285242Sachim    /* Free the ESGL pages associated with this I/O */
473285242Sachim    smIORequestBody->ioStarted = agFALSE;
474285242Sachim    smIORequestBody->ioCompleted = agTRUE;
475285242Sachim    return (status);
476285242Sachim  }
477285242Sachim
478285242Sachim  return SM_RC_SUCCESS;
479285242Sachim}
480285242Sachim
481285242Sachim
482285242SachimosGLOBAL FORCEINLINE bit32
483285242SachimsmsatIOPrepareSGL(
484285242Sachim                  smRoot_t                 *smRoot,
485285242Sachim                  smIORequestBody_t        *smIORequestBody,
486285242Sachim                  smSgl_t                  *smSgl1,
487285242Sachim                  void                     *sglVirtualAddr
488285242Sachim                  )
489285242Sachim{
490285242Sachim  agsaSgl_t          *agSgl;
491285242Sachim
492285242Sachim  /* Uppper should be zero-out */
493285242Sachim  SM_DBG5(("smsatIOPrepareSGL: start\n"));
494285242Sachim
495285242Sachim  SM_DBG5(("smsatIOPrepareSGL: smSgl1->upper %d smSgl1->lower %d smSgl1->len %d\n",
496285242Sachim    smSgl1->upper, smSgl1->lower, smSgl1->len));
497285242Sachim  SM_DBG5(("smsatIOPrepareSGL: smSgl1->type %d\n", smSgl1->type));
498285242Sachim
499285242Sachim  /* SGL for SATA request */
500285242Sachim  agSgl = &(smIORequestBody->transport.SATA.agSATARequestBody.agSgl);
501285242Sachim  agSgl->len = 0;
502285242Sachim
503285242Sachim  if (smSgl1 == agNULL)
504285242Sachim  {
505285242Sachim    SM_DBG1(("smsatIOPrepareSGL: Error smSgl1 is NULL!!!\n"));
506285242Sachim    return tiError;
507285242Sachim  }
508285242Sachim
509285242Sachim  if (smIORequestBody->IOType.InitiatorRegIO.expDataLength == 0)
510285242Sachim  {
511285242Sachim    SM_DBG3(("smsatIOPrepareSGL: expDataLength is 0\n"));
512285242Sachim    agSgl->sgUpper = 0;
513285242Sachim    agSgl->sgLower = 0;
514285242Sachim    agSgl->len = 0;
515285242Sachim    SM_CLEAR_ESGL_EXTEND(agSgl->extReserved);
516285242Sachim    return SM_RC_SUCCESS;
517285242Sachim  }
518285242Sachim
519285242Sachim  agSgl->sgUpper = smSgl1->upper;
520285242Sachim  agSgl->sgLower = smSgl1->lower;
521285242Sachim  agSgl->len = smSgl1->len;
522285242Sachim  agSgl->extReserved = smSgl1->type;
523285242Sachim
524285242Sachim  return SM_RC_SUCCESS;
525285242Sachim
526285242Sachim}
527285242Sachim
528285242Sachim
529285242Sachim
530285242Sachim
531