1*4e1bc9a0SAchim Leubner /*******************************************************************************
2*4e1bc9a0SAchim Leubner *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
3*4e1bc9a0SAchim Leubner *
4*4e1bc9a0SAchim Leubner *Redistribution and use in source and binary forms, with or without modification, are permitted provided
5*4e1bc9a0SAchim Leubner *that the following conditions are met:
6*4e1bc9a0SAchim Leubner *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
7*4e1bc9a0SAchim Leubner *following disclaimer.
8*4e1bc9a0SAchim Leubner *2. Redistributions in binary form must reproduce the above copyright notice,
9*4e1bc9a0SAchim Leubner *this list of conditions and the following disclaimer in the documentation and/or other materials provided
10*4e1bc9a0SAchim Leubner *with the distribution.
11*4e1bc9a0SAchim Leubner *
12*4e1bc9a0SAchim Leubner *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13*4e1bc9a0SAchim Leubner *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14*4e1bc9a0SAchim Leubner *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15*4e1bc9a0SAchim Leubner *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16*4e1bc9a0SAchim Leubner *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17*4e1bc9a0SAchim Leubner *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18*4e1bc9a0SAchim Leubner *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19*4e1bc9a0SAchim Leubner *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
20*4e1bc9a0SAchim Leubner
21*4e1bc9a0SAchim Leubner ********************************************************************************/
22*4e1bc9a0SAchim Leubner #include <sys/cdefs.h>
23*4e1bc9a0SAchim Leubner #include <dev/pms/config.h>
24*4e1bc9a0SAchim Leubner
25*4e1bc9a0SAchim Leubner #include <dev/pms/freebsd/driver/common/osenv.h>
26*4e1bc9a0SAchim Leubner #include <dev/pms/freebsd/driver/common/ostypes.h>
27*4e1bc9a0SAchim Leubner #include <dev/pms/freebsd/driver/common/osdebug.h>
28*4e1bc9a0SAchim Leubner
29*4e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/tisa/api/titypes.h>
30*4e1bc9a0SAchim Leubner
31*4e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/sallsdk/api/sa.h>
32*4e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/sallsdk/api/saapi.h>
33*4e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
34*4e1bc9a0SAchim Leubner
35*4e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/sat/api/sm.h>
36*4e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/sat/api/smapi.h>
37*4e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/sat/api/tdsmapi.h>
38*4e1bc9a0SAchim Leubner
39*4e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/sat/src/smdefs.h>
40*4e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/sat/src/smproto.h>
41*4e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/sat/src/smtypes.h>
42*4e1bc9a0SAchim Leubner
43*4e1bc9a0SAchim Leubner /*
44*4e1bc9a0SAchim Leubner * This table is used to map LL Layer saSATAStart() status to TISA status.
45*4e1bc9a0SAchim Leubner */
46*4e1bc9a0SAchim Leubner
47*4e1bc9a0SAchim Leubner
48*4e1bc9a0SAchim Leubner FORCEINLINE bit32
smsataLLIOStart(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)49*4e1bc9a0SAchim Leubner smsataLLIOStart(
50*4e1bc9a0SAchim Leubner smRoot_t *smRoot,
51*4e1bc9a0SAchim Leubner smIORequest_t *smIORequest,
52*4e1bc9a0SAchim Leubner smDeviceHandle_t *smDeviceHandle,
53*4e1bc9a0SAchim Leubner smScsiInitiatorRequest_t *smScsiRequest,
54*4e1bc9a0SAchim Leubner smSatIOContext_t *satIOContext
55*4e1bc9a0SAchim Leubner )
56*4e1bc9a0SAchim Leubner {
57*4e1bc9a0SAchim Leubner smDeviceData_t *oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
58*4e1bc9a0SAchim Leubner smIntRoot_t *smIntRoot = (smIntRoot_t *) smRoot->smData;
59*4e1bc9a0SAchim Leubner smIntContext_t *smAllShared = (smIntContext_t *)&(smIntRoot->smAllShared);
60*4e1bc9a0SAchim Leubner smIORequestBody_t *smIORequestBody = (smIORequestBody_t *)satIOContext->smRequestBody;
61*4e1bc9a0SAchim Leubner smDeviceData_t *pSatDevData = satIOContext->pSatDevData;
62*4e1bc9a0SAchim Leubner smSatInternalIo_t *satIntIo = satIOContext->satIntIoContext;
63*4e1bc9a0SAchim Leubner agsaRoot_t *agRoot = smAllShared->agRoot;
64*4e1bc9a0SAchim Leubner agsaIORequest_t *agIORequest = &(smIORequestBody->agIORequest);
65*4e1bc9a0SAchim Leubner agsaDevHandle_t *agDevHandle = oneDeviceData->agDevHandle;
66*4e1bc9a0SAchim Leubner agsaSATAInitiatorRequest_t *agSATAReq = &(smIORequestBody->transport.SATA.agSATARequestBody);
67*4e1bc9a0SAchim Leubner bit32 RLERecovery = agFALSE;
68*4e1bc9a0SAchim Leubner bit32 status = SM_RC_FAILURE;
69*4e1bc9a0SAchim Leubner bit32 nQNumber = 0;
70*4e1bc9a0SAchim Leubner /*
71*4e1bc9a0SAchim Leubner * If this is a super I/O request, check for optional settings.
72*4e1bc9a0SAchim Leubner * Be careful. Use the superRequest pointer for all references
73*4e1bc9a0SAchim Leubner * in this block of code.
74*4e1bc9a0SAchim Leubner */
75*4e1bc9a0SAchim Leubner agSATAReq->option = 0;
76*4e1bc9a0SAchim Leubner if (satIOContext->superIOFlag)
77*4e1bc9a0SAchim Leubner {
78*4e1bc9a0SAchim Leubner smSuperScsiInitiatorRequest_t *superRequest = (smSuperScsiInitiatorRequest_t *) smScsiRequest;
79*4e1bc9a0SAchim Leubner
80*4e1bc9a0SAchim Leubner if (superRequest->flags & SM_SCSI_INITIATOR_ENCRYPT)
81*4e1bc9a0SAchim Leubner {
82*4e1bc9a0SAchim Leubner /* Copy all of the relevant encrypt information */
83*4e1bc9a0SAchim Leubner agSATAReq->option |= AGSA_SATA_ENABLE_ENCRYPTION;
84*4e1bc9a0SAchim Leubner sm_memcpy(&agSATAReq->encrypt, &superRequest->Encrypt, sizeof(agsaEncrypt_t));
85*4e1bc9a0SAchim Leubner }
86*4e1bc9a0SAchim Leubner {
87*4e1bc9a0SAchim Leubner /* initialize expDataLength */
88*4e1bc9a0SAchim Leubner if (satIOContext->reqType == AGSA_SATA_PROTOCOL_NON_DATA ||
89*4e1bc9a0SAchim Leubner satIOContext->reqType == AGSA_SATA_PROTOCOL_SRST_ASSERT ||
90*4e1bc9a0SAchim Leubner satIOContext->reqType == AGSA_SATA_PROTOCOL_SRST_DEASSERT )
91*4e1bc9a0SAchim Leubner {
92*4e1bc9a0SAchim Leubner smIORequestBody->IOType.InitiatorRegIO.expDataLength = 0;
93*4e1bc9a0SAchim Leubner }
94*4e1bc9a0SAchim Leubner else
95*4e1bc9a0SAchim Leubner {
96*4e1bc9a0SAchim Leubner smIORequestBody->IOType.InitiatorRegIO.expDataLength = smScsiRequest->scsiCmnd.expDataLength;
97*4e1bc9a0SAchim Leubner }
98*4e1bc9a0SAchim Leubner
99*4e1bc9a0SAchim Leubner agSATAReq->dataLength = smIORequestBody->IOType.InitiatorRegIO.expDataLength;
100*4e1bc9a0SAchim Leubner }
101*4e1bc9a0SAchim Leubner }
102*4e1bc9a0SAchim Leubner else
103*4e1bc9a0SAchim Leubner {
104*4e1bc9a0SAchim Leubner /* initialize expDataLength */
105*4e1bc9a0SAchim Leubner if (satIOContext->reqType == AGSA_SATA_PROTOCOL_NON_DATA ||
106*4e1bc9a0SAchim Leubner satIOContext->reqType == AGSA_SATA_PROTOCOL_SRST_ASSERT ||
107*4e1bc9a0SAchim Leubner satIOContext->reqType == AGSA_SATA_PROTOCOL_SRST_DEASSERT )
108*4e1bc9a0SAchim Leubner {
109*4e1bc9a0SAchim Leubner smIORequestBody->IOType.InitiatorRegIO.expDataLength = 0;
110*4e1bc9a0SAchim Leubner }
111*4e1bc9a0SAchim Leubner else
112*4e1bc9a0SAchim Leubner {
113*4e1bc9a0SAchim Leubner smIORequestBody->IOType.InitiatorRegIO.expDataLength = smScsiRequest->scsiCmnd.expDataLength;
114*4e1bc9a0SAchim Leubner }
115*4e1bc9a0SAchim Leubner
116*4e1bc9a0SAchim Leubner agSATAReq->dataLength = smIORequestBody->IOType.InitiatorRegIO.expDataLength;
117*4e1bc9a0SAchim Leubner }
118*4e1bc9a0SAchim Leubner
119*4e1bc9a0SAchim Leubner if ( (pSatDevData->satDriveState == SAT_DEV_STATE_IN_RECOVERY) &&
120*4e1bc9a0SAchim Leubner (satIOContext->pFis->h.command == SAT_READ_LOG_EXT) )
121*4e1bc9a0SAchim Leubner {
122*4e1bc9a0SAchim Leubner RLERecovery = agTRUE;
123*4e1bc9a0SAchim Leubner }
124*4e1bc9a0SAchim Leubner
125*4e1bc9a0SAchim Leubner /* check max io, be sure to free */
126*4e1bc9a0SAchim Leubner if ( (pSatDevData->satDriveState != SAT_DEV_STATE_IN_RECOVERY) ||
127*4e1bc9a0SAchim Leubner (RLERecovery == agTRUE) )
128*4e1bc9a0SAchim Leubner {
129*4e1bc9a0SAchim Leubner if (RLERecovery == agFALSE) /* RLE is not checked against pending IO's */
130*4e1bc9a0SAchim Leubner {
131*4e1bc9a0SAchim Leubner #ifdef CCFLAG_OPTIMIZE_SAT_LOCK
132*4e1bc9a0SAchim Leubner bit32 volatile satPendingNCQIO = 0;
133*4e1bc9a0SAchim Leubner bit32 volatile satPendingNONNCQIO = 0;
134*4e1bc9a0SAchim Leubner bit32 volatile satPendingIO = 0;
135*4e1bc9a0SAchim Leubner
136*4e1bc9a0SAchim Leubner tdsmInterlockedExchange(smRoot, &satPendingNCQIO, pSatDevData->satPendingNCQIO);
137*4e1bc9a0SAchim Leubner tdsmInterlockedExchange(smRoot, &satPendingNONNCQIO, pSatDevData->satPendingNONNCQIO);
138*4e1bc9a0SAchim Leubner tdsmInterlockedExchange(smRoot, &satPendingIO, pSatDevData->satPendingIO);
139*4e1bc9a0SAchim Leubner #endif
140*4e1bc9a0SAchim Leubner
141*4e1bc9a0SAchim Leubner if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
142*4e1bc9a0SAchim Leubner (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
143*4e1bc9a0SAchim Leubner {
144*4e1bc9a0SAchim Leubner #ifdef CCFLAG_OPTIMIZE_SAT_LOCK
145*4e1bc9a0SAchim Leubner if ( satPendingNCQIO >= pSatDevData->satNCQMaxIO ||
146*4e1bc9a0SAchim Leubner satPendingNONNCQIO != 0)
147*4e1bc9a0SAchim Leubner {
148*4e1bc9a0SAchim Leubner SM_DBG1(("smsataLLIOStart: 1st busy did %d!!!\n", pSatDevData->id));
149*4e1bc9a0SAchim Leubner SM_DBG1(("smsataLLIOStart: 1st busy NCQ. NCQ Pending 0x%x NONNCQ Pending 0x%x All Pending 0x%x!!!\n", satPendingNCQIO,
150*4e1bc9a0SAchim Leubner satPendingNONNCQIO, satPendingIO));
151*4e1bc9a0SAchim Leubner /* free resource */
152*4e1bc9a0SAchim Leubner smsatFreeIntIoResource( smRoot,
153*4e1bc9a0SAchim Leubner pSatDevData,
154*4e1bc9a0SAchim Leubner satIntIo);
155*4e1bc9a0SAchim Leubner return SM_RC_DEVICE_BUSY;
156*4e1bc9a0SAchim Leubner }
157*4e1bc9a0SAchim Leubner #else
158*4e1bc9a0SAchim Leubner tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
159*4e1bc9a0SAchim Leubner if (pSatDevData->satPendingNCQIO >= pSatDevData->satNCQMaxIO ||
160*4e1bc9a0SAchim Leubner pSatDevData->satPendingNONNCQIO != 0)
161*4e1bc9a0SAchim Leubner {
162*4e1bc9a0SAchim Leubner SM_DBG1(("smsataLLIOStart: 1st busy did %d!!!\n", pSatDevData->id));
163*4e1bc9a0SAchim Leubner SM_DBG1(("smsataLLIOStart: 1st busy NCQ. NCQ Pending 0x%x NONNCQ Pending 0x%x All Pending 0x%x!!!\n", pSatDevData->satPendingNCQIO,
164*4e1bc9a0SAchim Leubner pSatDevData->satPendingNONNCQIO, pSatDevData->satPendingIO));
165*4e1bc9a0SAchim Leubner tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
166*4e1bc9a0SAchim Leubner /* free resource */
167*4e1bc9a0SAchim Leubner smsatFreeIntIoResource( smRoot,
168*4e1bc9a0SAchim Leubner pSatDevData,
169*4e1bc9a0SAchim Leubner satIntIo);
170*4e1bc9a0SAchim Leubner return SM_RC_DEVICE_BUSY;
171*4e1bc9a0SAchim Leubner }
172*4e1bc9a0SAchim Leubner tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
173*4e1bc9a0SAchim Leubner #endif
174*4e1bc9a0SAchim Leubner
175*4e1bc9a0SAchim Leubner }
176*4e1bc9a0SAchim Leubner else if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_D2H_PKT) ||
177*4e1bc9a0SAchim Leubner (satIOContext->reqType == AGSA_SATA_PROTOCOL_H2D_PKT) ||
178*4e1bc9a0SAchim Leubner (satIOContext->reqType == AGSA_SATA_PROTOCOL_NON_PKT) )
179*4e1bc9a0SAchim Leubner {
180*4e1bc9a0SAchim Leubner sm_memcpy(agSATAReq->scsiCDB, smScsiRequest->scsiCmnd.cdb, 16);
181*4e1bc9a0SAchim Leubner #ifdef CCFLAG_OPTIMIZE_SAT_LOCK
182*4e1bc9a0SAchim Leubner if ( satPendingNONNCQIO >= SAT_APAPI_CMDQ_MAX ||
183*4e1bc9a0SAchim Leubner satPendingNCQIO != 0)
184*4e1bc9a0SAchim Leubner {
185*4e1bc9a0SAchim Leubner SM_DBG1(("smsataLLIOStart: ATAPI busy did %d!!!\n", pSatDevData->id));
186*4e1bc9a0SAchim Leubner SM_DBG1(("smsataLLIOStart: ATAPI busy NON-NCQ. NCQ Pending 0x%x NON-NCQ Pending 0x%x All Pending 0x%x!!!\n", satPendingNCQIO,
187*4e1bc9a0SAchim Leubner satPendingNONNCQIO, satPendingIO));
188*4e1bc9a0SAchim Leubner /* free resource */
189*4e1bc9a0SAchim Leubner smsatFreeIntIoResource( smRoot,
190*4e1bc9a0SAchim Leubner pSatDevData,
191*4e1bc9a0SAchim Leubner satIntIo);
192*4e1bc9a0SAchim Leubner return SM_RC_DEVICE_BUSY;
193*4e1bc9a0SAchim Leubner }
194*4e1bc9a0SAchim Leubner #else
195*4e1bc9a0SAchim Leubner tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
196*4e1bc9a0SAchim Leubner if ( pSatDevData->satPendingNONNCQIO >= SAT_APAPI_CMDQ_MAX ||
197*4e1bc9a0SAchim Leubner pSatDevData->satPendingNCQIO != 0)
198*4e1bc9a0SAchim Leubner {
199*4e1bc9a0SAchim Leubner SM_DBG1(("smsataLLIOStart: ATAPI busy did %d!!!\n", pSatDevData->id));
200*4e1bc9a0SAchim Leubner SM_DBG1(("smsataLLIOStart: ATAPI busy NON-NCQ. NCQ Pending 0x%x NON-NCQ Pending 0x%x All Pending 0x%x!!!\n", pSatDevData->satPendingNCQIO,
201*4e1bc9a0SAchim Leubner pSatDevData->satPendingNONNCQIO, pSatDevData->satPendingIO));
202*4e1bc9a0SAchim Leubner tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
203*4e1bc9a0SAchim Leubner /* free resource */
204*4e1bc9a0SAchim Leubner smsatFreeIntIoResource( smRoot,
205*4e1bc9a0SAchim Leubner pSatDevData,
206*4e1bc9a0SAchim Leubner satIntIo);
207*4e1bc9a0SAchim Leubner return SM_RC_DEVICE_BUSY;
208*4e1bc9a0SAchim Leubner }
209*4e1bc9a0SAchim Leubner tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
210*4e1bc9a0SAchim Leubner #endif
211*4e1bc9a0SAchim Leubner
212*4e1bc9a0SAchim Leubner }
213*4e1bc9a0SAchim Leubner else
214*4e1bc9a0SAchim Leubner {
215*4e1bc9a0SAchim Leubner #ifdef CCFLAG_OPTIMIZE_SAT_LOCK
216*4e1bc9a0SAchim Leubner if ( satPendingNONNCQIO >= SAT_NONNCQ_MAX ||
217*4e1bc9a0SAchim Leubner satPendingNCQIO != 0)
218*4e1bc9a0SAchim Leubner {
219*4e1bc9a0SAchim Leubner SM_DBG1(("smsataLLIOStart: 2nd busy did %d!!!\n", pSatDevData->id));
220*4e1bc9a0SAchim Leubner SM_DBG1(("smsataLLIOStart: 2nd busy NCQ. NCQ Pending 0x%x NONNCQ Pending 0x%x All Pending 0x%x!!!\n", satPendingNCQIO,
221*4e1bc9a0SAchim Leubner satPendingNONNCQIO, satPendingIO));
222*4e1bc9a0SAchim Leubner /* free resource */
223*4e1bc9a0SAchim Leubner smsatFreeIntIoResource( smRoot,
224*4e1bc9a0SAchim Leubner pSatDevData,
225*4e1bc9a0SAchim Leubner satIntIo);
226*4e1bc9a0SAchim Leubner return SM_RC_DEVICE_BUSY;
227*4e1bc9a0SAchim Leubner }
228*4e1bc9a0SAchim Leubner #else
229*4e1bc9a0SAchim Leubner tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
230*4e1bc9a0SAchim Leubner if (pSatDevData->satPendingNONNCQIO >= SAT_NONNCQ_MAX ||
231*4e1bc9a0SAchim Leubner pSatDevData->satPendingNCQIO != 0)
232*4e1bc9a0SAchim Leubner {
233*4e1bc9a0SAchim Leubner SM_DBG1(("smsataLLIOStart: 2nd busy did %d!!!\n", pSatDevData->id));
234*4e1bc9a0SAchim Leubner SM_DBG1(("smsataLLIOStart: 2nd busy NCQ. NCQ Pending 0x%x NONNCQ Pending 0x%x All Pending 0x%x!!!\n", pSatDevData->satPendingNCQIO,
235*4e1bc9a0SAchim Leubner pSatDevData->satPendingNONNCQIO, pSatDevData->satPendingIO));
236*4e1bc9a0SAchim Leubner tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
237*4e1bc9a0SAchim Leubner /* free resource */
238*4e1bc9a0SAchim Leubner smsatFreeIntIoResource( smRoot,
239*4e1bc9a0SAchim Leubner pSatDevData,
240*4e1bc9a0SAchim Leubner satIntIo);
241*4e1bc9a0SAchim Leubner return SM_RC_DEVICE_BUSY;
242*4e1bc9a0SAchim Leubner }
243*4e1bc9a0SAchim Leubner tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
244*4e1bc9a0SAchim Leubner #endif
245*4e1bc9a0SAchim Leubner }
246*4e1bc9a0SAchim Leubner } /* RLE */
247*4e1bc9a0SAchim Leubner /* for internal SATA command only */
248*4e1bc9a0SAchim Leubner if (satIOContext->satOrgIOContext != agNULL)
249*4e1bc9a0SAchim Leubner {
250*4e1bc9a0SAchim Leubner /* Initialize tiIORequest */
251*4e1bc9a0SAchim Leubner smIORequestBody->smIORequest = smIORequest;
252*4e1bc9a0SAchim Leubner if (smIORequest == agNULL)
253*4e1bc9a0SAchim Leubner {
254*4e1bc9a0SAchim Leubner SM_DBG1(("smsataLLIOStart: 1 check!!!\n"));
255*4e1bc9a0SAchim Leubner }
256*4e1bc9a0SAchim Leubner }
257*4e1bc9a0SAchim Leubner /* Initialize tiDevhandle */
258*4e1bc9a0SAchim Leubner smIORequestBody->smDevHandle = smDeviceHandle;
259*4e1bc9a0SAchim Leubner
260*4e1bc9a0SAchim Leubner /* Initializes Scatter Gather and ESGL */
261*4e1bc9a0SAchim Leubner status = smsatIOPrepareSGL( smRoot,
262*4e1bc9a0SAchim Leubner smIORequestBody,
263*4e1bc9a0SAchim Leubner &smScsiRequest->smSgl1,
264*4e1bc9a0SAchim Leubner smScsiRequest->sglVirtualAddr );
265*4e1bc9a0SAchim Leubner
266*4e1bc9a0SAchim Leubner if (status != SM_RC_SUCCESS)
267*4e1bc9a0SAchim Leubner {
268*4e1bc9a0SAchim Leubner SM_DBG1(("smsataLLIOStart: can't get SGL!!!\n"));
269*4e1bc9a0SAchim Leubner /* free resource */
270*4e1bc9a0SAchim Leubner smsatFreeIntIoResource( smRoot,
271*4e1bc9a0SAchim Leubner pSatDevData,
272*4e1bc9a0SAchim Leubner satIntIo);
273*4e1bc9a0SAchim Leubner return status;
274*4e1bc9a0SAchim Leubner }
275*4e1bc9a0SAchim Leubner
276*4e1bc9a0SAchim Leubner /* Initialize LL Layer agIORequest */
277*4e1bc9a0SAchim Leubner agIORequest->osData = (void *) smIORequestBody;
278*4e1bc9a0SAchim Leubner agIORequest->sdkData = agNULL; /* SA takes care of this */
279*4e1bc9a0SAchim Leubner
280*4e1bc9a0SAchim Leubner smIORequestBody->ioStarted = agTRUE;
281*4e1bc9a0SAchim Leubner smIORequestBody->ioCompleted = agFALSE;
282*4e1bc9a0SAchim Leubner
283*4e1bc9a0SAchim Leubner /* assign tag value for SATA */
284*4e1bc9a0SAchim Leubner if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
285*4e1bc9a0SAchim Leubner (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
286*4e1bc9a0SAchim Leubner {
287*4e1bc9a0SAchim Leubner if (agFALSE == smsatTagAlloc(smRoot, pSatDevData, &satIOContext->sataTag))
288*4e1bc9a0SAchim Leubner {
289*4e1bc9a0SAchim Leubner SM_DBG1(("smsataLLIOStart: No more NCQ tag!!!\n"));
290*4e1bc9a0SAchim Leubner smIORequestBody->ioStarted = agFALSE;
291*4e1bc9a0SAchim Leubner smIORequestBody->ioCompleted = agTRUE;
292*4e1bc9a0SAchim Leubner return SM_RC_DEVICE_BUSY;
293*4e1bc9a0SAchim Leubner }
294*4e1bc9a0SAchim Leubner SM_DBG3(("smsataLLIOStart: ncq tag 0x%x\n",satIOContext->sataTag));
295*4e1bc9a0SAchim Leubner }
296*4e1bc9a0SAchim Leubner else
297*4e1bc9a0SAchim Leubner {
298*4e1bc9a0SAchim Leubner satIOContext->sataTag = 0xFF;
299*4e1bc9a0SAchim Leubner }
300*4e1bc9a0SAchim Leubner }
301*4e1bc9a0SAchim Leubner else /* AGSA_SATA_PROTOCOL_SRST_ASSERT or AGSA_SATA_PROTOCOL_SRST_DEASSERT
302*4e1bc9a0SAchim Leubner or SAT_CHECK_POWER_MODE as ABORT */
303*4e1bc9a0SAchim Leubner {
304*4e1bc9a0SAchim Leubner agsaSgl_t *agSgl;
305*4e1bc9a0SAchim Leubner
306*4e1bc9a0SAchim Leubner /* for internal SATA command only */
307*4e1bc9a0SAchim Leubner if (satIOContext->satOrgIOContext != agNULL)
308*4e1bc9a0SAchim Leubner {
309*4e1bc9a0SAchim Leubner /* Initialize tiIORequest */
310*4e1bc9a0SAchim Leubner smIORequestBody->smIORequest = smIORequest;
311*4e1bc9a0SAchim Leubner if (smIORequest == agNULL)
312*4e1bc9a0SAchim Leubner {
313*4e1bc9a0SAchim Leubner SM_DBG1(("smsataLLIOStart: 2 check!!!\n"));
314*4e1bc9a0SAchim Leubner }
315*4e1bc9a0SAchim Leubner }
316*4e1bc9a0SAchim Leubner /* Initialize tiDevhandle */
317*4e1bc9a0SAchim Leubner smIORequestBody->smDevHandle = smDeviceHandle;
318*4e1bc9a0SAchim Leubner
319*4e1bc9a0SAchim Leubner
320*4e1bc9a0SAchim Leubner smIORequestBody->IOType.InitiatorRegIO.expDataLength = 0;
321*4e1bc9a0SAchim Leubner /* SGL for SATA request */
322*4e1bc9a0SAchim Leubner agSgl = &(smIORequestBody->transport.SATA.agSATARequestBody.agSgl);
323*4e1bc9a0SAchim Leubner agSgl->len = 0;
324*4e1bc9a0SAchim Leubner
325*4e1bc9a0SAchim Leubner agSgl->sgUpper = 0;
326*4e1bc9a0SAchim Leubner agSgl->sgLower = 0;
327*4e1bc9a0SAchim Leubner agSgl->len = 0;
328*4e1bc9a0SAchim Leubner SM_CLEAR_ESGL_EXTEND(agSgl->extReserved);
329*4e1bc9a0SAchim Leubner
330*4e1bc9a0SAchim Leubner /* Initialize LL Layer agIORequest */
331*4e1bc9a0SAchim Leubner agIORequest = &(smIORequestBody->agIORequest);
332*4e1bc9a0SAchim Leubner agIORequest->osData = (void *) smIORequestBody;
333*4e1bc9a0SAchim Leubner agIORequest->sdkData = agNULL; /* SA takes care of this */
334*4e1bc9a0SAchim Leubner
335*4e1bc9a0SAchim Leubner smIORequestBody->ioStarted = agTRUE;
336*4e1bc9a0SAchim Leubner smIORequestBody->ioCompleted = agFALSE;
337*4e1bc9a0SAchim Leubner
338*4e1bc9a0SAchim Leubner /* setting the data length */
339*4e1bc9a0SAchim Leubner agSATAReq->dataLength = 0;
340*4e1bc9a0SAchim Leubner
341*4e1bc9a0SAchim Leubner }
342*4e1bc9a0SAchim Leubner
343*4e1bc9a0SAchim Leubner
344*4e1bc9a0SAchim Leubner smIORequestBody->reTries = 0;
345*4e1bc9a0SAchim Leubner
346*4e1bc9a0SAchim Leubner #ifdef TD_INTERNAL_DEBUG
347*4e1bc9a0SAchim Leubner smhexdump("smsataLLIOStart", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
348*4e1bc9a0SAchim Leubner smhexdump("smsataLLIOStart LL", (bit8 *)&agSATAReq->fis.fisRegHostToDev,
349*4e1bc9a0SAchim Leubner sizeof(agsaFisRegHostToDevice_t));
350*4e1bc9a0SAchim Leubner #endif
351*4e1bc9a0SAchim Leubner
352*4e1bc9a0SAchim Leubner SM_DBG6(("smsataLLIOStart: agDevHandle %p\n", agDevHandle));
353*4e1bc9a0SAchim Leubner
354*4e1bc9a0SAchim Leubner /* to get better IO performance, rotate the OBQ number on main IO path */
355*4e1bc9a0SAchim Leubner if (smScsiRequest == agNULL)
356*4e1bc9a0SAchim Leubner {
357*4e1bc9a0SAchim Leubner nQNumber = 0;
358*4e1bc9a0SAchim Leubner }
359*4e1bc9a0SAchim Leubner else
360*4e1bc9a0SAchim Leubner {
361*4e1bc9a0SAchim Leubner switch (smScsiRequest->scsiCmnd.cdb[0])
362*4e1bc9a0SAchim Leubner {
363*4e1bc9a0SAchim Leubner case SCSIOPC_READ_10:
364*4e1bc9a0SAchim Leubner case SCSIOPC_WRITE_10:
365*4e1bc9a0SAchim Leubner case SCSIOPC_READ_6:
366*4e1bc9a0SAchim Leubner case SCSIOPC_WRITE_6:
367*4e1bc9a0SAchim Leubner case SCSIOPC_READ_12:
368*4e1bc9a0SAchim Leubner case SCSIOPC_WRITE_12:
369*4e1bc9a0SAchim Leubner case SCSIOPC_READ_16:
370*4e1bc9a0SAchim Leubner case SCSIOPC_WRITE_16:
371*4e1bc9a0SAchim Leubner nQNumber = tdsmRotateQnumber(smRoot, smDeviceHandle);
372*4e1bc9a0SAchim Leubner break;
373*4e1bc9a0SAchim Leubner
374*4e1bc9a0SAchim Leubner default:
375*4e1bc9a0SAchim Leubner nQNumber = 0;
376*4e1bc9a0SAchim Leubner break;
377*4e1bc9a0SAchim Leubner }
378*4e1bc9a0SAchim Leubner }
379*4e1bc9a0SAchim Leubner
380*4e1bc9a0SAchim Leubner SM_DBG3(("sataLLIOStart: Lock in\n"));
381*4e1bc9a0SAchim Leubner
382*4e1bc9a0SAchim Leubner #ifdef CCFLAG_OPTIMIZE_SAT_LOCK
383*4e1bc9a0SAchim Leubner if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
384*4e1bc9a0SAchim Leubner (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
385*4e1bc9a0SAchim Leubner {
386*4e1bc9a0SAchim Leubner tdsmInterlockedIncrement(smRoot,&pSatDevData->satPendingNCQIO);
387*4e1bc9a0SAchim Leubner }
388*4e1bc9a0SAchim Leubner else
389*4e1bc9a0SAchim Leubner {
390*4e1bc9a0SAchim Leubner tdsmInterlockedIncrement(smRoot,&pSatDevData->satPendingNONNCQIO);
391*4e1bc9a0SAchim Leubner }
392*4e1bc9a0SAchim Leubner tdsmInterlockedIncrement(smRoot,&pSatDevData->satPendingIO);
393*4e1bc9a0SAchim Leubner #else
394*4e1bc9a0SAchim Leubner tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
395*4e1bc9a0SAchim Leubner if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
396*4e1bc9a0SAchim Leubner (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
397*4e1bc9a0SAchim Leubner {
398*4e1bc9a0SAchim Leubner pSatDevData->satPendingNCQIO++;
399*4e1bc9a0SAchim Leubner }
400*4e1bc9a0SAchim Leubner else
401*4e1bc9a0SAchim Leubner {
402*4e1bc9a0SAchim Leubner pSatDevData->satPendingNONNCQIO++;
403*4e1bc9a0SAchim Leubner }
404*4e1bc9a0SAchim Leubner pSatDevData->satPendingIO++;
405*4e1bc9a0SAchim Leubner
406*4e1bc9a0SAchim Leubner SMLIST_INIT_ELEMENT (&satIOContext->satIoContextLink);
407*4e1bc9a0SAchim Leubner SMLIST_ENQUEUE_AT_TAIL (&satIOContext->satIoContextLink, &pSatDevData->satIoLinkList);
408*4e1bc9a0SAchim Leubner tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
409*4e1bc9a0SAchim Leubner #endif
410*4e1bc9a0SAchim Leubner /* post SATA command to low level MPI */
411*4e1bc9a0SAchim Leubner status = saSATAStart( agRoot,
412*4e1bc9a0SAchim Leubner agIORequest,
413*4e1bc9a0SAchim Leubner nQNumber,
414*4e1bc9a0SAchim Leubner agDevHandle,
415*4e1bc9a0SAchim Leubner satIOContext->reqType,
416*4e1bc9a0SAchim Leubner agSATAReq,
417*4e1bc9a0SAchim Leubner satIOContext->sataTag,
418*4e1bc9a0SAchim Leubner smllSATACompleted
419*4e1bc9a0SAchim Leubner );
420*4e1bc9a0SAchim Leubner
421*4e1bc9a0SAchim Leubner if (status != AGSA_RC_SUCCESS)
422*4e1bc9a0SAchim Leubner {
423*4e1bc9a0SAchim Leubner if (status == AGSA_RC_BUSY)
424*4e1bc9a0SAchim Leubner {
425*4e1bc9a0SAchim Leubner SM_DBG1(("smsataLLIOStart: saSATAStart busy!!!\n"));
426*4e1bc9a0SAchim Leubner status = SM_RC_BUSY;
427*4e1bc9a0SAchim Leubner }
428*4e1bc9a0SAchim Leubner else
429*4e1bc9a0SAchim Leubner {
430*4e1bc9a0SAchim Leubner SM_DBG1(("smsataLLIOStart: saSATAStart failed!!!\n"));
431*4e1bc9a0SAchim Leubner status = SM_RC_FAILURE;
432*4e1bc9a0SAchim Leubner }
433*4e1bc9a0SAchim Leubner
434*4e1bc9a0SAchim Leubner if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
435*4e1bc9a0SAchim Leubner (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
436*4e1bc9a0SAchim Leubner {
437*4e1bc9a0SAchim Leubner smsatTagRelease(smRoot, pSatDevData, satIOContext->sataTag);
438*4e1bc9a0SAchim Leubner }
439*4e1bc9a0SAchim Leubner
440*4e1bc9a0SAchim Leubner #ifdef CCFLAG_OPTIMIZE_SAT_LOCK
441*4e1bc9a0SAchim Leubner if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
442*4e1bc9a0SAchim Leubner (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
443*4e1bc9a0SAchim Leubner {
444*4e1bc9a0SAchim Leubner tdsmInterlockedDecrement(smRoot,&oneDeviceData->satPendingNCQIO);
445*4e1bc9a0SAchim Leubner }
446*4e1bc9a0SAchim Leubner else
447*4e1bc9a0SAchim Leubner {
448*4e1bc9a0SAchim Leubner tdsmInterlockedDecrement(smRoot,&oneDeviceData->satPendingNONNCQIO);
449*4e1bc9a0SAchim Leubner }
450*4e1bc9a0SAchim Leubner tdsmInterlockedDecrement(smRoot,&oneDeviceData->satPendingIO);
451*4e1bc9a0SAchim Leubner #else
452*4e1bc9a0SAchim Leubner if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
453*4e1bc9a0SAchim Leubner (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
454*4e1bc9a0SAchim Leubner {
455*4e1bc9a0SAchim Leubner tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
456*4e1bc9a0SAchim Leubner oneDeviceData->satPendingNCQIO--;
457*4e1bc9a0SAchim Leubner oneDeviceData->satPendingIO--;
458*4e1bc9a0SAchim Leubner SMLIST_DEQUEUE_THIS (&satIOContext->satIoContextLink);
459*4e1bc9a0SAchim Leubner tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
460*4e1bc9a0SAchim Leubner }
461*4e1bc9a0SAchim Leubner else
462*4e1bc9a0SAchim Leubner {
463*4e1bc9a0SAchim Leubner tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
464*4e1bc9a0SAchim Leubner oneDeviceData->satPendingNONNCQIO--;
465*4e1bc9a0SAchim Leubner oneDeviceData->satPendingIO--;
466*4e1bc9a0SAchim Leubner SMLIST_DEQUEUE_THIS (&satIOContext->satIoContextLink);
467*4e1bc9a0SAchim Leubner tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
468*4e1bc9a0SAchim Leubner }
469*4e1bc9a0SAchim Leubner #endif /* CCFLAG_OPTIMIZE_SAT_LOCK */
470*4e1bc9a0SAchim Leubner
471*4e1bc9a0SAchim Leubner /* Free the ESGL pages associated with this I/O */
472*4e1bc9a0SAchim Leubner smIORequestBody->ioStarted = agFALSE;
473*4e1bc9a0SAchim Leubner smIORequestBody->ioCompleted = agTRUE;
474*4e1bc9a0SAchim Leubner return (status);
475*4e1bc9a0SAchim Leubner }
476*4e1bc9a0SAchim Leubner
477*4e1bc9a0SAchim Leubner return SM_RC_SUCCESS;
478*4e1bc9a0SAchim Leubner }
479*4e1bc9a0SAchim Leubner
480*4e1bc9a0SAchim Leubner
481*4e1bc9a0SAchim Leubner osGLOBAL FORCEINLINE bit32
smsatIOPrepareSGL(smRoot_t * smRoot,smIORequestBody_t * smIORequestBody,smSgl_t * smSgl1,void * sglVirtualAddr)482*4e1bc9a0SAchim Leubner smsatIOPrepareSGL(
483*4e1bc9a0SAchim Leubner smRoot_t *smRoot,
484*4e1bc9a0SAchim Leubner smIORequestBody_t *smIORequestBody,
485*4e1bc9a0SAchim Leubner smSgl_t *smSgl1,
486*4e1bc9a0SAchim Leubner void *sglVirtualAddr
487*4e1bc9a0SAchim Leubner )
488*4e1bc9a0SAchim Leubner {
489*4e1bc9a0SAchim Leubner agsaSgl_t *agSgl;
490*4e1bc9a0SAchim Leubner
491*4e1bc9a0SAchim Leubner /* Uppper should be zero-out */
492*4e1bc9a0SAchim Leubner SM_DBG5(("smsatIOPrepareSGL: start\n"));
493*4e1bc9a0SAchim Leubner
494*4e1bc9a0SAchim Leubner SM_DBG5(("smsatIOPrepareSGL: smSgl1->upper %d smSgl1->lower %d smSgl1->len %d\n",
495*4e1bc9a0SAchim Leubner smSgl1->upper, smSgl1->lower, smSgl1->len));
496*4e1bc9a0SAchim Leubner SM_DBG5(("smsatIOPrepareSGL: smSgl1->type %d\n", smSgl1->type));
497*4e1bc9a0SAchim Leubner
498*4e1bc9a0SAchim Leubner /* SGL for SATA request */
499*4e1bc9a0SAchim Leubner agSgl = &(smIORequestBody->transport.SATA.agSATARequestBody.agSgl);
500*4e1bc9a0SAchim Leubner agSgl->len = 0;
501*4e1bc9a0SAchim Leubner
502*4e1bc9a0SAchim Leubner if (smSgl1 == agNULL)
503*4e1bc9a0SAchim Leubner {
504*4e1bc9a0SAchim Leubner SM_DBG1(("smsatIOPrepareSGL: Error smSgl1 is NULL!!!\n"));
505*4e1bc9a0SAchim Leubner return tiError;
506*4e1bc9a0SAchim Leubner }
507*4e1bc9a0SAchim Leubner
508*4e1bc9a0SAchim Leubner if (smIORequestBody->IOType.InitiatorRegIO.expDataLength == 0)
509*4e1bc9a0SAchim Leubner {
510*4e1bc9a0SAchim Leubner SM_DBG3(("smsatIOPrepareSGL: expDataLength is 0\n"));
511*4e1bc9a0SAchim Leubner agSgl->sgUpper = 0;
512*4e1bc9a0SAchim Leubner agSgl->sgLower = 0;
513*4e1bc9a0SAchim Leubner agSgl->len = 0;
514*4e1bc9a0SAchim Leubner SM_CLEAR_ESGL_EXTEND(agSgl->extReserved);
515*4e1bc9a0SAchim Leubner return SM_RC_SUCCESS;
516*4e1bc9a0SAchim Leubner }
517*4e1bc9a0SAchim Leubner
518*4e1bc9a0SAchim Leubner agSgl->sgUpper = smSgl1->upper;
519*4e1bc9a0SAchim Leubner agSgl->sgLower = smSgl1->lower;
520*4e1bc9a0SAchim Leubner agSgl->len = smSgl1->len;
521*4e1bc9a0SAchim Leubner agSgl->extReserved = smSgl1->type;
522*4e1bc9a0SAchim Leubner
523*4e1bc9a0SAchim Leubner return SM_RC_SUCCESS;
524*4e1bc9a0SAchim Leubner
525*4e1bc9a0SAchim Leubner }
526*4e1bc9a0SAchim Leubner
527*4e1bc9a0SAchim Leubner
528*4e1bc9a0SAchim Leubner
529*4e1bc9a0SAchim Leubner
530